initial support for nil, make-list
unfinished, but usable.. still 0 is false in libs and code
This commit is contained in:
parent
46b29fc229
commit
8586a66285
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
### TODO
|
### TODO
|
||||||
- test whether AIG,,,10 csv row is parsed
|
- test whether AIG,,,10 csv row is parsed
|
||||||
- support for (), nil, t
|
- support for (), nil, t, in lsp code replace 0 by nil in logicals
|
||||||
- print-table
|
- print-table
|
||||||
- download 10 years of data from api.nasdaq.com into test dir
|
- download 10 years of data from api.nasdaq.com into test dir
|
||||||
- documentation
|
- documentation
|
||||||
|
|
|
||||||
|
|
@ -24,4 +24,9 @@
|
||||||
|
|
||||||
(print (string-lpad "lpad" 10 "x"))
|
(print (string-lpad "lpad" 10 "x"))
|
||||||
|
|
||||||
|
(print nil)
|
||||||
|
(print ())
|
||||||
|
|
||||||
|
(print (make-list 5))
|
||||||
|
|
||||||
(print "Debug ends")
|
(print "Debug ends")
|
||||||
|
|
|
||||||
37
ml.cpp
37
ml.cpp
|
|
@ -30,7 +30,6 @@
|
||||||
#define INVALID_ORDER "cannot order expression"
|
#define INVALID_ORDER "cannot order expression"
|
||||||
#define BAD_CAST "cannot cast"
|
#define BAD_CAST "cannot cast"
|
||||||
#define ATOM_NOT_DEFINED "atom not defined"
|
#define ATOM_NOT_DEFINED "atom not defined"
|
||||||
#define EVAL_EMPTY_LIST "evaluated empty list"
|
|
||||||
#define INTERNAL_ERROR "internal virtual machine error"
|
#define INTERNAL_ERROR "internal virtual machine error"
|
||||||
#define INDEX_OUT_OF_RANGE "index out of range"
|
#define INDEX_OUT_OF_RANGE "index out of range"
|
||||||
#define MALFORMED_PROGRAM "malformed program"
|
#define MALFORMED_PROGRAM "malformed program"
|
||||||
|
|
@ -40,6 +39,7 @@
|
||||||
#define INT_TYPE "int"
|
#define INT_TYPE "int"
|
||||||
#define FLOAT_TYPE "float"
|
#define FLOAT_TYPE "float"
|
||||||
#define UNIT_TYPE "unit"
|
#define UNIT_TYPE "unit"
|
||||||
|
#define NIL_TYPE "nil"
|
||||||
#define FUNCTION_TYPE "function"
|
#define FUNCTION_TYPE "function"
|
||||||
#define ATOM_TYPE "atom"
|
#define ATOM_TYPE "atom"
|
||||||
#define QUOTE_TYPE "quote"
|
#define QUOTE_TYPE "quote"
|
||||||
|
|
@ -93,6 +93,12 @@ MlValue MlValue::string(const std::string &s) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MlValue MlValue::nil() {
|
||||||
|
MlValue result;
|
||||||
|
result.type = NIL;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
// Construct a lambda function
|
// Construct a lambda function
|
||||||
MlValue::MlValue(const std::vector<MlValue> ¶ms, MlValue ret, MlEnvironment const &env) : type(LAMBDA) {
|
MlValue::MlValue(const std::vector<MlValue> ¶ms, MlValue ret, MlEnvironment const &env) : type(LAMBDA) {
|
||||||
// We store the params and the result in the list member
|
// We store the params and the result in the list member
|
||||||
|
|
@ -162,7 +168,7 @@ bool MlValue::is_number() const {
|
||||||
|
|
||||||
// Get the "truthy" boolean value of this value.
|
// Get the "truthy" boolean value of this value.
|
||||||
bool MlValue::as_bool() const {
|
bool MlValue::as_bool() const {
|
||||||
return *this != MlValue(0);
|
return type != NIL && *this != MlValue(0); // TODO remove 0 as false
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get this item's integer value
|
// Get this item's integer value
|
||||||
|
|
@ -281,6 +287,8 @@ bool MlValue::operator==(MlValue other) const {
|
||||||
// The values for quotes are stored in the
|
// The values for quotes are stored in the
|
||||||
// first slot of the list member.
|
// first slot of the list member.
|
||||||
return list[0] == other.list[0];
|
return list[0] == other.list[0];
|
||||||
|
case NIL:
|
||||||
|
return other.type == NIL;
|
||||||
default:
|
default:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -516,6 +524,8 @@ std::string MlValue::get_type_name() {
|
||||||
return FUNCTION_TYPE;
|
return FUNCTION_TYPE;
|
||||||
case UNIT:
|
case UNIT:
|
||||||
return UNIT_TYPE;
|
return UNIT_TYPE;
|
||||||
|
case NIL:
|
||||||
|
return NIL_TYPE;
|
||||||
default:
|
default:
|
||||||
// We don't know the name of this type.
|
// We don't know the name of this type.
|
||||||
// This isn't the users fault, this is just unhandled.
|
// This isn't the users fault, this is just unhandled.
|
||||||
|
|
@ -553,6 +563,8 @@ std::string MlValue::display() const {
|
||||||
return "<" + str + " at " + to_string(long(stack_data.b)) + ">";
|
return "<" + str + " at " + to_string(long(stack_data.b)) + ">";
|
||||||
case UNIT:
|
case UNIT:
|
||||||
return "@";
|
return "@";
|
||||||
|
case NIL:
|
||||||
|
return "nil";
|
||||||
default:
|
default:
|
||||||
// We don't know how to display whatever type this is.
|
// We don't know how to display whatever type this is.
|
||||||
// This isn't the users fault, this is just unhandled.
|
// This isn't the users fault, this is just unhandled.
|
||||||
|
|
@ -594,6 +606,8 @@ std::string MlValue::debug() const {
|
||||||
return "<" + str + " at " + to_string(long(stack_data.b)) + ">";
|
return "<" + str + " at " + to_string(long(stack_data.b)) + ">";
|
||||||
case UNIT:
|
case UNIT:
|
||||||
return "@";
|
return "@";
|
||||||
|
case NIL:
|
||||||
|
return "nil";
|
||||||
default:
|
default:
|
||||||
// We don't know how to debug whatever type this is.
|
// We don't know how to debug whatever type this is.
|
||||||
// This isn't the users fault, this is just unhandled.
|
// This isn't the users fault, this is just unhandled.
|
||||||
|
|
@ -621,8 +635,7 @@ MlError::~MlError() {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string MlError::description() {
|
std::string MlError::description() {
|
||||||
return "error: the expression `" + cause->debug() + "` failed in scope " + to_string(env) + " with message \"" +
|
return "error: the expression `" + cause->debug() + "` failed in scope " + to_string(env) + " with message \"" + msg + "\"";
|
||||||
msg + "\"";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void MlEnvironment::combine(MlEnvironment const &other) {
|
void MlEnvironment::combine(MlEnvironment const &other) {
|
||||||
|
|
@ -657,9 +670,7 @@ MlValue MlValue::apply(std::vector<MlValue> args, MlEnvironment &env) {
|
||||||
// Get the list of parameter atoms
|
// Get the list of parameter atoms
|
||||||
params = list[0].list;
|
params = list[0].list;
|
||||||
if (params.size() != args.size())
|
if (params.size() != args.size())
|
||||||
throw MlError(MlValue(args), env, args.size() > params.size() ?
|
throw MlError(MlValue(args), env, args.size() > params.size() ? TOO_MANY_ARGS : TOO_FEW_ARGS);
|
||||||
TOO_MANY_ARGS : TOO_FEW_ARGS
|
|
||||||
);
|
|
||||||
|
|
||||||
// Get the captured scope from the lambda
|
// Get the captured scope from the lambda
|
||||||
e = lambda_scope;
|
e = lambda_scope;
|
||||||
|
|
@ -701,7 +712,7 @@ MlValue MlValue::eval(MlEnvironment &env) {
|
||||||
return env.get(str);
|
return env.get(str);
|
||||||
case LIST:
|
case LIST:
|
||||||
if (list.size() < 1)
|
if (list.size() < 1)
|
||||||
throw MlError(*this, env, EVAL_EMPTY_LIST);
|
return MlValue::nil();
|
||||||
|
|
||||||
args = std::vector<MlValue>(list.begin() + 1, list.end());
|
args = std::vector<MlValue>(list.begin() + 1, list.end());
|
||||||
|
|
||||||
|
|
@ -747,6 +758,7 @@ MlValue parse(std::string &s, int &ptr) {
|
||||||
|
|
||||||
if (s == "") {
|
if (s == "") {
|
||||||
return MlValue();
|
return MlValue();
|
||||||
|
|
||||||
} else if (s[ptr] == '\'') {
|
} else if (s[ptr] == '\'') {
|
||||||
// If this is a quote
|
// If this is a quote
|
||||||
ptr++;
|
ptr++;
|
||||||
|
|
@ -807,6 +819,7 @@ MlValue parse(std::string &s, int &ptr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return MlValue::string(x);
|
return MlValue::string(x);
|
||||||
|
|
||||||
} else if (s[ptr] == '@') {
|
} else if (s[ptr] == '@') {
|
||||||
ptr++;
|
ptr++;
|
||||||
skip_whitespace(s, ptr);
|
skip_whitespace(s, ptr);
|
||||||
|
|
@ -822,7 +835,11 @@ MlValue parse(std::string &s, int &ptr) {
|
||||||
std::string x = s.substr(ptr, n);
|
std::string x = s.substr(ptr, n);
|
||||||
ptr += n;
|
ptr += n;
|
||||||
skip_whitespace(s, ptr);
|
skip_whitespace(s, ptr);
|
||||||
return MlValue::atom(x);
|
if (x == "nil")
|
||||||
|
return MlValue::nil();
|
||||||
|
else
|
||||||
|
return MlValue::atom(x);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
throw std::runtime_error(MALFORMED_PROGRAM);
|
throw std::runtime_error(MALFORMED_PROGRAM);
|
||||||
}
|
}
|
||||||
|
|
@ -1765,7 +1782,7 @@ int main(int argc, const char **argv) {
|
||||||
try {
|
try {
|
||||||
load_std_lib(env);
|
load_std_lib(env);
|
||||||
// for xcode profiling
|
// for xcode profiling
|
||||||
// run(read_file_contents("/Users/vaclavt/Development/mlisp/tests/test.lsp"), env);
|
run(read_file_contents("/Users/vaclavt/Development/mlisp/tests/test.lsp"), env);
|
||||||
|
|
||||||
if (argc == 1 || (argc == 2 && std::string(argv[1]) == "-i"))
|
if (argc == 1 || (argc == 2 && std::string(argv[1]) == "-i"))
|
||||||
repl(env);
|
repl(env);
|
||||||
|
|
|
||||||
6
ml.h
6
ml.h
|
|
@ -98,6 +98,9 @@ public:
|
||||||
// Construct a string
|
// Construct a string
|
||||||
static MlValue string(const std::string &s);
|
static MlValue string(const std::string &s);
|
||||||
|
|
||||||
|
// Construct a nil
|
||||||
|
static MlValue nil();
|
||||||
|
|
||||||
// Construct a lambda function
|
// Construct a lambda function
|
||||||
MlValue(const std::vector<MlValue> ¶ms, MlValue ret, MlEnvironment const &env);
|
MlValue(const std::vector<MlValue> ¶ms, MlValue ret, MlEnvironment const &env);
|
||||||
|
|
||||||
|
|
@ -197,7 +200,8 @@ private:
|
||||||
STRING,
|
STRING,
|
||||||
LAMBDA,
|
LAMBDA,
|
||||||
BUILTIN,
|
BUILTIN,
|
||||||
UNIT
|
UNIT,
|
||||||
|
NIL
|
||||||
} type;
|
} type;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
|
|
|
||||||
|
|
@ -69,6 +69,19 @@
|
||||||
0)
|
0)
|
||||||
))
|
))
|
||||||
|
|
||||||
|
(defun make-list-of (size val)
|
||||||
|
(do
|
||||||
|
(define lst '())
|
||||||
|
(define i 0)
|
||||||
|
(while (< i size)
|
||||||
|
(define lst (push lst val))
|
||||||
|
(define i (inc i)))
|
||||||
|
lst
|
||||||
|
))
|
||||||
|
|
||||||
|
(defun make-list (size)
|
||||||
|
(make-list-of size nil))
|
||||||
|
|
||||||
|
|
||||||
; quicksort
|
; quicksort
|
||||||
(defun quick-sort-by (l cmp)
|
(defun quick-sort-by (l cmp)
|
||||||
|
|
|
||||||
|
|
@ -14,6 +14,9 @@
|
||||||
(print "(member '(1 2 3) 3:" (member '(1 2 3) 3))
|
(print "(member '(1 2 3) 3:" (member '(1 2 3) 3))
|
||||||
(print "(member '(1 2 3) 30:" (member '(1 2 3) 30))
|
(print "(member '(1 2 3) 30:" (member '(1 2 3) 30))
|
||||||
|
|
||||||
|
(print "(make-list 3) :" (make-list 3))
|
||||||
|
(print "(make-list-of 3) :" (make-list-of 3 999))
|
||||||
|
|
||||||
|
|
||||||
(defun fact (n)
|
(defun fact (n)
|
||||||
(if (<= n 1)
|
(if (<= n 1)
|
||||||
|
|
@ -45,7 +48,7 @@
|
||||||
(print "sorted: " (quick-sort '(1 2 3 4 5 6 7 8 9 10)))
|
(print "sorted: " (quick-sort '(1 2 3 4 5 6 7 8 9 10)))
|
||||||
(print "sorted by: " (quick-sort-by '(10 9 8 7 6 5 4 3 2 1) (lambda (a b) (> a b)) ))
|
(print "sorted by: " (quick-sort-by '(10 9 8 7 6 5 4 3 2 1) (lambda (a b) (> a b)) ))
|
||||||
(print "sorted by: " (quick-sort-by '(1 2 3 4 5 6 7 8 9 10) (lambda (a b) (> a b)) ))
|
(print "sorted by: " (quick-sort-by '(1 2 3 4 5 6 7 8 9 10) (lambda (a b) (> a b)) ))
|
||||||
(print "sorted by: " (quick-sort-by '(1 2 3 4 5 6 7 8 9 10) (lambda (a b) (< a b)) ))
|
(print "sorted by desc: " (quick-sort-by '(1 2 3 4 5 6 7 8 9 10) (lambda (a b) (< a b)) ))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue