block with function do.

main
bog 2024-03-30 20:04:07 +01:00
parent 61303f6825
commit b8fa1df563
6 changed files with 93 additions and 2 deletions

18
features/do.mk Normal file
View File

@ -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)

View File

@ -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; i<args->size; 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)

View File

@ -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);

View File

@ -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)

View File

@ -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;
}

View File

@ -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