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:
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));
}