summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lisp.c49
-rw-r--r--lisp.h1
-rw-r--r--main.c1
3 files changed, 48 insertions, 3 deletions
diff --git a/lisp.c b/lisp.c
index da0a5f6..5f5a6fb 100644
--- a/lisp.c
+++ b/lisp.c
@@ -35,10 +35,13 @@ value *make_string(const char *s) {
return val;
}
+value *NIL = NULL;
value *make_nil() {
- value *val = malloc(sizeof(value));
- val->type = VT_NIL;
- return val;
+ if (!NIL) {
+ NIL = malloc(sizeof(value));
+ NIL->type = VT_NIL;
+ }
+ return NIL;
}
value *make_lambda(env *e, value *params, value *body) {
@@ -312,6 +315,46 @@ value *builtin_isnull(env *e, value *args) {
return make_nil();
}
+int value_eq(value *a, value *b) {
+ if(a->type != b->type){
+ return 0;
+ }
+ if(a == b){
+ return 1;
+ }
+ switch (a->type) {
+ case VT_INT: return a->as.i == b->as.i;
+ case VT_DOUBLE: return a->as.d == b->as.d;
+ case VT_SYMBOL: return !strcmp(a->as.sym, b->as.sym);
+ case VT_STRING: return !strcmp(a->as.sym, b->as.sym);
+ case VT_NIL: return 1;
+ case VT_PAIR:
+ return value_eq(car(a), car(b)) &&
+ value_eq(cdr(a), cdr(b));
+ case VT_LAMBDA:
+ case VT_BUILTIN:
+ default:
+ return 0;
+ }
+ return 1;
+}
+
+value *builtin_eq(env *e, value *args) {
+ value *v_prev = eval(e, car(args));
+
+ args = cdr(args);
+ while (args->type == VT_PAIR) {
+ value *v_cur = eval(e, car(args));
+ if (!value_eq(v_prev, v_cur)) {
+ return make_nil();
+ }
+ v_prev = v_cur;
+ args = cdr(args);
+ }
+
+ return make_int(1);
+}
+
value *apply_to_nums(env *e, value *args, double (*fn)(double, double)) {
double result;
value *v = eval(e, car(args));
diff --git a/lisp.h b/lisp.h
index 5abdfd4..7c9dd79 100644
--- a/lisp.h
+++ b/lisp.h
@@ -74,6 +74,7 @@ value *builtin_cons(env *e, value *args);
value *builtin_car(env *e, value *args);
value *builtin_cdr(env *e, value *args);
value *builtin_isnull(env *e, value *args);
+value *builtin_eq(env *e, value *args);
value *builtin_add(env *e, value *args);
value *builtin_sub(env *e, value *args);
value *builtin_mul(env *e, value *args);
diff --git a/main.c b/main.c
index 2b0c00f..4f00b5d 100644
--- a/main.c
+++ b/main.c
@@ -32,6 +32,7 @@ int main(int argc, char **argv) {
env_define(global_env, "car", make_builtin(builtin_car));
env_define(global_env, "cdr", make_builtin(builtin_cdr));
env_define(global_env, "null?", make_builtin(builtin_isnull));
+ env_define(global_env, "eq?", make_builtin(builtin_eq));
env_define(global_env, "+", make_builtin(builtin_add));
env_define(global_env, "-", make_builtin(builtin_sub));
env_define(global_env, "*", make_builtin(builtin_mul));