✨ block with function do.
parent
61303f6825
commit
b8fa1df563
|
@ -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)
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue