diff options
| author | Felix Perktold <Felix.Perktold@student.uibk.ac.at> | 2025-12-22 01:42:34 +0100 |
|---|---|---|
| committer | Felix Perktold <Felix.Perktold@student.uibk.ac.at> | 2025-12-22 01:42:34 +0100 |
| commit | 60f27a19aee04582339b312f1c3032009f5560de (patch) | |
| tree | b375644bc0d275af07b97b615cbccf98a3ab9683 | |
| parent | a7a070371bcc10d0dbf94e503650856ac37ed81d (diff) | |
add eq?, make make_nil() function singleton
| -rw-r--r-- | lisp.c | 49 | ||||
| -rw-r--r-- | lisp.h | 1 | ||||
| -rw-r--r-- | main.c | 1 |
3 files changed, 48 insertions, 3 deletions
@@ -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)); @@ -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); @@ -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)); |
