diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/builtins.c | 78 | ||||
| -rw-r--r-- | src/builtins.h | 14 | ||||
| -rw-r--r-- | src/interp.c | 12 | ||||
| -rw-r--r-- | src/prelude.c | 2 | ||||
| -rw-r--r-- | src/prelude.lisp | 6 | ||||
| -rw-r--r-- | src/primitives.c | 2 |
6 files changed, 96 insertions, 18 deletions
diff --git a/src/builtins.c b/src/builtins.c index 48cb4f0..04afbcb 100644 --- a/src/builtins.c +++ b/src/builtins.c @@ -6,6 +6,84 @@ #include <float.h> #include <math.h> +SExpRef builtin_set_car(Interp *interp, SExpRef args) { + if (LENGTH(args) != 2) { + return new_error(interp, "set-car: args num error.\n"); + } + SExpRef lst = CAR(args), elem = CADR(args); + if (VALTYPE(lst) != kPairSExp) { + return new_error(interp, "set-car: type error."); + } + REF(lst)->pair.car = elem; + return NIL; +} + +SExpRef builtin_set_cdr(Interp *interp, SExpRef args) { + if (LENGTH(args) != 2) { + return new_error(interp, "set-cdr: args num error.\n"); + } + SExpRef lst = CAR(args), elem = CADR(args); + if (VALTYPE(lst) != kPairSExp) { + return new_error(interp, "set-cdr: type error."); + } + REF(lst)->pair.cdr = elem; + return NIL; +} + +SExpRef builtin_length(Interp *interp, SExpRef args) { + if (LENGTH(args) != 1) { + return new_error(interp, "length: args num error.\n"); + } + int len = LENGTH(CAR(args)); + if (len < 0) { + return new_error(interp, "length: type error.\n"); + } + return new_integer(interp, len); +} + +SExpRef builtin_nth(Interp *interp, SExpRef args) { + if (LENGTH(args) != 2) { + return new_error(interp, "nth: args num error.\n"); + } + SExpRef n = CAR(args), lst = CADR(args); + if (VALTYPE(n) != kIntegerSExp) return new_error(interp, "nth: type error.\n"); + if (VALTYPE(lst) == kPairSExp) { + if (REF(n)->integer >= LENGTH(lst)) { + return new_error(interp, "nth: out of bound.\n"); + } + for (int i = 0; i < REF(n)->integer; i++) { + lst = CDR(lst); + } + return CAR(lst); + } else if (VALTYPE(lst) == kStringSExp) { + if (REF(n)->integer >= strlen(REF(lst)->str)) { + return new_error(interp, "nth: out of bound\n"); + } + return new_char(interp, REF(lst)->str[REF(n)->integer]); + } else { + return new_error(interp, "nth: type error.\n"); + } +} + +SExpRef builtin_nthcdr(Interp *interp, SExpRef args) { + if (LENGTH(args) != 2) { + return new_error(interp, "nth: args num error.\n"); + } + SExpRef n = CAR(args), lst = CADR(args); + if (VALTYPE(n) != kIntegerSExp) return new_error(interp, "nth: type error.\n"); + if (VALTYPE(lst) == kPairSExp) { + if (REF(n)->integer >= LENGTH(lst)) { + return new_error(interp, "nth: out of bound.\n"); + } + for (int i = 0; i < REF(n)->integer; i++) { + lst = CDR(lst); + } + return CDR(lst); + } else { + return new_error(interp, "nth: type error.\n"); + } +} + SExpRef builtin_string(Interp *interp, SExpRef args) { for (SExpRef i = args; !NILP(i); i = CDR(i)) { SExpRef x = CAR(i); diff --git a/src/builtins.h b/src/builtins.h index 608df98..3832afb 100644 --- a/src/builtins.h +++ b/src/builtins.h @@ -3,15 +3,11 @@ #include "interp.h" -// - char= -// - char> -// - char< -// - char>= -// - char<= -// - char/= -// - ord -// - chr - +SExpRef builtin_set_car(Interp *interp, SExpRef args); +SExpRef builtin_set_cdr(Interp *interp, SExpRef args); +SExpRef builtin_length(Interp *interp, SExpRef args); +SExpRef builtin_nth(Interp *interp, SExpRef args); +SExpRef builtin_nthcdr(Interp *interp, SExpRef args); SExpRef builtin_string(Interp *interp, SExpRef args); SExpRef builtin_string_eq(Interp *interp, SExpRef args); SExpRef builtin_string_gt(Interp *interp, SExpRef args); diff --git a/src/interp.c b/src/interp.c index 15aabdb..80ddfed 100644 --- a/src/interp.c +++ b/src/interp.c @@ -102,7 +102,7 @@ void Interp_init(Interp *self) { Interp_add_userfunc(self, "sqrt", builtin_sqrt); Interp_add_userfunc(self, "cbrt", builtin_cbrt); Interp_add_userfunc(self, "log10", builtin_log10); - Interp_add_userfunc(self, "eq", builtin_eq); + Interp_add_userfunc(self, "eq?", builtin_eq); Interp_add_userfunc(self, "ln", builtin_ln); Interp_add_userfunc(self, "=", builtin_num_equal); Interp_add_userfunc(self, "/=", builtin_num_neq); @@ -138,7 +138,7 @@ void Interp_init(Interp *self) { Interp_add_userfunc(self, "not", builtin_not); Interp_add_userfunc(self, "cos", builtin_cos); Interp_add_userfunc(self, "princ", builtin_princ); - Interp_add_userfunc(self, "equal", builtin_equal); + Interp_add_userfunc(self, "equal?", builtin_equal); Interp_add_userfunc(self, "atan", builtin_atan); Interp_add_userfunc(self, "cons", builtin_cons); Interp_add_userfunc(self, "cdr", builtin_cdr); @@ -147,7 +147,11 @@ void Interp_init(Interp *self) { Interp_add_userfunc(self, "floor", builtin_floor); Interp_add_userfunc(self, "min", builtin_min); Interp_add_userfunc(self, "error", builtin_error); - + Interp_add_userfunc(self, "set-car", builtin_set_car); + Interp_add_userfunc(self, "set-cdr", builtin_set_cdr); + Interp_add_userfunc(self, "length", builtin_length); + Interp_add_userfunc(self, "nth", builtin_nth); + Interp_add_userfunc(self, "nthcdr", builtin_nthcdr); Interp_add_userfunc(self, "_gcstat", builtin_gcstat); Interp_add_userfunc(self, "_alwaysgc", builtin_alwaysgc); @@ -399,7 +403,7 @@ void lisp_to_string_impl(str_builder_t *sb, Int2IntHashTable *visited, Interp *i } else if (pe->type == kRealSExp) { str_builder_append(sb, "%lg", pe->real); } else if (pe->type == kCharSExp) { - str_builder_append(sb, "#\%c", pe->character); + str_builder_append(sb, "#\\%c", pe->character); } else if (pe->type == kBooleanSExp) { if (pe->boolean) str_builder_append(sb, "#t"); else str_builder_append(sb, "#f"); diff --git a/src/prelude.c b/src/prelude.c index ca9109d..8baca6b 100644 --- a/src/prelude.c +++ b/src/prelude.c @@ -1,6 +1,6 @@ #include "prelude.h" -const char *bamboo_lisp_prelude = "(defvar nil \'())\n\n(defvar pi 3.1415926)\n(defvar e 2.718281828)\n\n(defmacro incq (i)\n `(setq ,i (+ ,i 1)))\n\n(defmacro decq (i)\n `(setq ,i (- ,i 1)))\n\n(defun zerop (x) (= x 0))\n(defun plusp (x) (> x 0))\n(defun minusp (x) (< x 0))\n\n(defmacro when (pred . body)\n `(if ,pred\n (progn ,@body)\n nil))\n\n(defmacro unless (pred . body)\n `(if ,pred\n nil\n (progn ,@body)))\n"; +const char *bamboo_lisp_prelude = "(defvar nil \'())\n\n(defvar pi 3.1415926)\n(defvar e 2.718281828)\n\n(defmacro incq (i)\n `(setq ,i (+ ,i 1)))\n\n(defmacro decq (i)\n `(setq ,i (- ,i 1)))\n\n(defun zero? (x) (= x 0))\n(defun plus? (x) (> x 0))\n(defun minus? (x) (< x 0))\n\n(defmacro when (pred . body)\n `(if ,pred\n (progn ,@body)\n nil))\n\n(defmacro unless (pred . body)\n `(if ,pred\n nil\n (progn ,@body)))\n"; diff --git a/src/prelude.lisp b/src/prelude.lisp index 7e9992b..c65380a 100644 --- a/src/prelude.lisp +++ b/src/prelude.lisp @@ -9,9 +9,9 @@ (defmacro decq (i) `(setq ,i (- ,i 1))) -(defun zerop (x) (= x 0)) -(defun plusp (x) (> x 0)) -(defun minusp (x) (< x 0)) +(defun zero? (x) (= x 0)) +(defun plus? (x) (> x 0)) +(defun minus? (x) (< x 0)) (defmacro when (pred . body) `(if ,pred diff --git a/src/primitives.c b/src/primitives.c index 899cbdd..5f70f09 100644 --- a/src/primitives.c +++ b/src/primitives.c @@ -64,7 +64,7 @@ SExpRef primitive_assert(Interp *interp, SExpRef args, bool istail) { if (LENGTH(args) != 1) { return new_error(interp, "assert: expect 1 arg.\n"); } - if (TRUEP(CAR(eargs))) { + if (TRUEP(CAR(eargs)) && !CTL_FL(CAR(eargs))) { return interp->t; } else { const char *expstr = lisp_to_string(interp, CAR(args)); |
