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 /lisp.c | |
| parent | a7a070371bcc10d0dbf94e503650856ac37ed81d (diff) | |
add eq?, make make_nil() function singleton
Diffstat (limited to 'lisp.c')
| -rw-r--r-- | lisp.c | 49 |
1 files changed, 46 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)); |
