tisp

tiny lisp
git clone git://edryd.org/tisp
Log | Files | Refs | LICENSE

commit 0a79a514a0e4fc5bfccb611cfd4522f422318e02
parent 4f5daf62aa855fbcd1b36f8538d75e80a8ce3fb7
Author: Ed van Bruggen <edvb@uw.edu>
Date:   Wed, 21 Nov 2018 16:44:52 -0800

Add *,/,mod math functions, only allow 2 arguments

Arbitrary number of arguments should be handled by another function, not
the primitives

Diffstat:
t/math/add.expect | 7++-----
t/math/add.tsp | 7++-----
t/math/sub.expect | 1-
t/math/sub.tsp | 1-
t/prim/lambda.expect | 2+-
t/prim/lambda.tsp | 2+-
t/simple/comments.expect | 2+-
t/simple/comments.tsp | 2+-
tib/math.c | 85+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
9 files changed, 63 insertions(+), 46 deletions(-)

diff --git a/t/math/add.expect b/t/math/add.expect @@ -1,6 +1,3 @@ 2 -6 -6 -6 -6 -4369 +4 +1312 diff --git a/t/math/add.tsp b/t/math/add.tsp @@ -1,6 +1,3 @@ (+ 1 1) -(+ 1 2 3) -(+ 1 2 (+ 1 2)) -(+ 1 (+ 1 2) 2) -(+ (+ 1 2) 1 2) -(+ 1029 283 1928 28 189 912) +(+ 1 (+ 1 2)) +(+ 1029 283) diff --git a/t/math/sub.expect b/t/math/sub.expect @@ -2,5 +2,4 @@ -3 289 1 -5 -35 diff --git a/t/math/sub.tsp b/t/math/sub.tsp @@ -2,5 +2,4 @@ (- +3) (- -289) (- 5 4) -(- 40 20 15) (- 53 88) diff --git a/t/prim/lambda.expect b/t/prim/lambda.expect @@ -1,5 +1,5 @@ 3 -6 +3 9 4 5 diff --git a/t/prim/lambda.tsp b/t/prim/lambda.tsp @@ -1,5 +1,5 @@ ((lambda (x) x) 3) -((lambda (x) x) (+ 1 2 3)) +((lambda (x) x) (+ 1 2)) ((lambda (x) (+ x 1)) 8) ((lambda (a b) (+ a b)) 2 2) ((lambda () 5)) diff --git a/t/simple/comments.expect b/t/simple/comments.expect @@ -1,2 +1,2 @@ -3 +2 4 diff --git a/t/simple/comments.tsp b/t/simple/comments.tsp @@ -1,6 +1,6 @@ ; commment ; (+ 1 1) -(+ 1 1 ; more comments +(+ 1 ; more comments 1) ; white space too diff --git a/tib/math.c b/tib/math.c @@ -15,39 +15,61 @@ } while(0) -#define INC(SIGN, FUNC) do { \ - if (car(v)->t == INTEGER) \ - i = i SIGN car(v)->v.i; \ - else \ - warnf(FUNC ": expected integer, recieved type [%s]", type_str(car(v)->t)); \ -} while (0) +#define PRIM_OP(NAME, OP, FUNC) \ +static Val \ +prim_##NAME(Env env, Val args) \ +{ \ + Val a, b; \ + int len = list_len(args); \ + if (len != 2) \ + warnf(FUNC ": expected 2 arguments, recieved %d", len); \ + if (!(a = tisp_eval(env, car(args))) || !(b = tisp_eval(env, car(cdr(args))))) \ + return NULL; \ + if (a->t != INTEGER) \ + warnf(FUNC ": expected integer, recieved type [%s]", type_str(a->t)); \ + if (b->t != INTEGER) \ + warnf(FUNC ": expected integer, recieved type [%s]", type_str(b->t)); \ + return mk_int(a->v.i OP b->v.i); \ +} + +PRIM_OP(add, +, "+") +PRIM_OP(mul, *, "*") +PRIM_OP(mod, %, "mod") static Val -prim_add(Env env, Val args) +prim_sub(Env env, Val args) { - Val v; - int i = 0; - if (!(v = tisp_eval_list(env, args))) + Val a, b; + int len = list_len(args); + if (len != 2 && len != 1) + warnf("-: expected 1 or 2 arguments, recieved %d", len); + if (!(a = tisp_eval(env, car(args)))) + return NULL; + if (a->t != INTEGER) + warnf("-: expected integer, recieved type [%s]", type_str(a->t)); + if (len == 1) + return mk_int(-a->v.i); + if (!(b = tisp_eval(env, car(cdr(args))))) return NULL; - for (; !nilp(v); v = cdr(v)) - INC(+, "+"); - return mk_int(i); + if (b->t != INTEGER) + warnf("-: expected integer, recieved type [%s]", type_str(b->t)); + return mk_int(a->v.i - b->v.i); } static Val -prim_sub(Env env, Val args) +prim_div(Env env, Val args) { - Val v; - int i = 0; - if (!(v = tisp_eval_list(env, args))) + Val a, b; + int len = list_len(args); + if (len != 2) + warnf("/: expected 2 arguments, recieved %d", len); + if (!(a = tisp_eval(env, car(args))) || !(b = tisp_eval(env, car(cdr(args))))) return NULL; - INC(+, "-"); - v = cdr(v); - if (nilp(v)) - return mk_int(-i); - for (; !nilp(v); v = cdr(v)) - INC(-, "-"); - return mk_int(i); + if (a->t != INTEGER) + warnf("/: expected integer, recieved type [%s]", type_str(a->t)); + if (b->t != INTEGER) + warnf("/: expected integer, recieved type [%s]", type_str(b->t)); + return mk_rat(a->v.i, b->v.i); } #define INT_TEST(V, FUNC) do { \ @@ -77,10 +99,13 @@ PRIM_COMPARE(gte, >=, ">=") void tib_env_math(Env env) { - tisp_env_add(env, "+", mk_prim(prim_add)); - tisp_env_add(env, "-", mk_prim(prim_sub)); - tisp_env_add(env, "<", mk_prim(prim_lt)); - tisp_env_add(env, ">", mk_prim(prim_gt)); - tisp_env_add(env, "<=", mk_prim(prim_lte)); - tisp_env_add(env, ">=", mk_prim(prim_gte)); + tisp_env_add(env, "+", mk_prim(prim_add)); + tisp_env_add(env, "-", mk_prim(prim_sub)); + tisp_env_add(env, "*", mk_prim(prim_mul)); + tisp_env_add(env, "/", mk_prim(prim_div)); + tisp_env_add(env, "mod", mk_prim(prim_mod)); + tisp_env_add(env, "<", mk_prim(prim_lt)); + tisp_env_add(env, ">", mk_prim(prim_gt)); + tisp_env_add(env, "<=", mk_prim(prim_lte)); + tisp_env_add(env, ">=", mk_prim(prim_gte)); }