From b8fa1df563efe876c2f6311da14dbe8a60d8f937 Mon Sep 17 00:00:00 2001 From: bog Date: Sat, 30 Mar 2024 20:04:07 +0100 Subject: [PATCH] :sparkles: block with function do. --- features/do.mk | 18 ++++++++++++++++++ lib/builtins.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ lib/builtins.h | 3 +++ lib/moka.c | 4 ++-- lib/symtable.c | 22 ++++++++++++++++++++++ lib/symtable.h | 3 +++ 6 files changed, 93 insertions(+), 2 deletions(-) create mode 100644 features/do.mk diff --git a/features/do.mk b/features/do.mk new file mode 100644 index 0000000..a0b1a3b --- /dev/null +++ b/features/do.mk @@ -0,0 +1,18 @@ +(define a 4) + +(do + (assert-eqv! 4 a) + (define a 'hello) + (assert-eqv! 'hello a) + + (set! a 28) + (assert-eqv! 28 a) +) + +(assert-eqv! 4 a) + +(do + (set! a -63) +) + +(assert-eqv! -63 a) diff --git a/lib/builtins.c b/lib/builtins.c index 33d1dac..4743fde 100644 --- a/lib/builtins.c +++ b/lib/builtins.c @@ -12,6 +12,9 @@ void register_builtins(struct moka* moka) moka_decl_native(moka, "array", mk_array, -1); moka_decl_native(moka, "assert-eqv!", mk_assert_eqv_mut, 2); + moka_decl_native(moka, "do", mk_do, -1); + moka_decl_native(moka, "set!", mk_set_mut, 2); + moka_decl_native(moka, "<", mk_lt, 2); moka_decl_native(moka, "<=", mk_le, 2); moka_decl_native(moka, ">", mk_gt, 2); @@ -108,6 +111,48 @@ MOKA mk_assert_eqv_mut(struct moka* moka, struct vec* args) return moka_push_bool(moka, true, line); } +MOKA mk_do(struct moka* moka, struct vec* args) +{ + assert(moka); + assert(args); + + MOKA value = 0; + + symtable_open_scope(&moka->symtable); + + for (size_t i=0; isize; i++) + { + value = MK_EVAL((MOKA) args->data[i]); + } + + symtable_close_scope(&moka->symtable); + + return value; +} + +MOKA mk_set_mut(struct moka* moka, struct vec* args) +{ + assert(moka); + assert(args); + + MOKA mk_name = (MOKA) args->data[0]; + MOKA value = MK_EVAL((MOKA)args->data[1]); + + struct frame* frame = moka_frame(moka); + + struct value* name = frame->local_values.data[mk_name]; + struct node* node = name->data.lazy; + struct entry* entry = symtable_try_get( + &moka->symtable, + node->token->value + ); + + moka_push(moka, value); + entry->addr = frame->local_values.size - 1; + + return value; +} + // Comparisons // =========== MOKA mk_lt(struct moka* moka, struct vec* args) diff --git a/lib/builtins.h b/lib/builtins.h index e2f8b2e..2b00e4e 100644 --- a/lib/builtins.h +++ b/lib/builtins.h @@ -13,6 +13,9 @@ MOKA mk_define(struct moka* moka, struct vec* args); MOKA mk_array(struct moka* moka, struct vec* args); MOKA mk_assert_eqv_mut(struct moka* moka, struct vec* args); +MOKA mk_do(struct moka* moka, struct vec* args); +MOKA mk_set_mut(struct moka* moka, struct vec* args); + // Comparisons // =========== MOKA mk_lt(struct moka* moka, struct vec* args); diff --git a/lib/moka.c b/lib/moka.c index f62dc53..f3f42f8 100644 --- a/lib/moka.c +++ b/lib/moka.c @@ -401,7 +401,7 @@ MOKA moka_sub(struct moka* self, int count) : -value->data.real; } } - + vec_free(&args); if (count == 1) @@ -491,7 +491,7 @@ MOKA moka_div(struct moka* self, int count) is_int = false; } } - + vec_free(&args); if (count == 1) diff --git a/lib/symtable.c b/lib/symtable.c index c76af11..11d60b9 100644 --- a/lib/symtable.c +++ b/lib/symtable.c @@ -99,3 +99,25 @@ struct entry* symtable_try_get(struct symtable* self, char* name) return env_try_get(self->root, name); } + +void symtable_open_scope(struct symtable* self) +{ + struct env* env = malloc(sizeof(struct env)); + env_init(env, self->root); + + self->root = env; +} + +void symtable_close_scope(struct symtable* self) +{ + assert(self); + assert(self->root); + + struct env* env = self->root->parent; + self->root->parent = NULL; + + env_free(self->root); + free(self->root); + + self->root = env; +} diff --git a/lib/symtable.h b/lib/symtable.h index d3c162e..05892c5 100644 --- a/lib/symtable.h +++ b/lib/symtable.h @@ -42,4 +42,7 @@ void symtable_declare(struct symtable* self, struct entry* symtable_try_get(struct symtable* self, char* name); +void symtable_open_scope(struct symtable* self); +void symtable_close_scope(struct symtable* self); + #endif