Compare commits
2 Commits
1c5ad117d8
...
b8fa1df563
Author | SHA1 | Date |
---|---|---|
bog | b8fa1df563 | |
bog | 61303f6825 |
|
@ -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)
|
|
@ -0,0 +1,24 @@
|
||||||
|
(assert-eqv! 0 (+))
|
||||||
|
(assert-eqv! 5 (+ 5))
|
||||||
|
(assert-eqv! 8 (+ 5 3))
|
||||||
|
(assert-eqv! 17 (+ 5 3 9))
|
||||||
|
|
||||||
|
(assert-eqv! 0 (-))
|
||||||
|
(assert-eqv! -5 (- 5))
|
||||||
|
(assert-eqv! 2 (- 5 3))
|
||||||
|
(assert-eqv! -7 (- 5 3 9))
|
||||||
|
|
||||||
|
(assert-eqv! 1 (*))
|
||||||
|
(assert-eqv! 2 (* 2))
|
||||||
|
(assert-eqv! 42 (* 6 7))
|
||||||
|
(assert-eqv! 24 (* 2 3 4))
|
||||||
|
|
||||||
|
(assert-eqv! 1 (/))
|
||||||
|
(assert-eqv! 0.5 (/ 2.0))
|
||||||
|
(assert-eqv! 0 (/ 2))
|
||||||
|
(assert-eqv! 6 (/ 36 6))
|
||||||
|
(assert-eqv! 3 (/ 36 6 2))
|
||||||
|
|
||||||
|
(assert-eqv! 8 (^ 2 3))
|
||||||
|
(assert-eqv! 1.5 (% 7.5 2.0))
|
||||||
|
|
|
@ -30,6 +30,10 @@ target_compile_options(moka-core
|
||||||
PUBLIC -Wall -Wextra -g -fPIC
|
PUBLIC -Wall -Wextra -g -fPIC
|
||||||
)
|
)
|
||||||
|
|
||||||
|
target_link_options(moka-core
|
||||||
|
PUBLIC -lm
|
||||||
|
)
|
||||||
|
|
||||||
target_include_directories(moka-core
|
target_include_directories(moka-core
|
||||||
PUBLIC ${CMAKE_SOURCE_DIR}/lib
|
PUBLIC ${CMAKE_SOURCE_DIR}/lib
|
||||||
)
|
)
|
||||||
|
|
136
lib/builtins.c
136
lib/builtins.c
|
@ -12,12 +12,22 @@ void register_builtins(struct moka* moka)
|
||||||
moka_decl_native(moka, "array", mk_array, -1);
|
moka_decl_native(moka, "array", mk_array, -1);
|
||||||
moka_decl_native(moka, "assert-eqv!", mk_assert_eqv_mut, 2);
|
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_lt, 2);
|
||||||
moka_decl_native(moka, "<=", mk_le, 2);
|
moka_decl_native(moka, "<=", mk_le, 2);
|
||||||
moka_decl_native(moka, ">", mk_gt, 2);
|
moka_decl_native(moka, ">", mk_gt, 2);
|
||||||
moka_decl_native(moka, ">=", mk_ge, 2);
|
moka_decl_native(moka, ">=", mk_ge, 2);
|
||||||
moka_decl_native(moka, "eqv?", mk_is_eqv, 2);
|
moka_decl_native(moka, "eqv?", mk_is_eqv, 2);
|
||||||
moka_decl_native(moka, "nev?", mk_is_nev, 2);
|
moka_decl_native(moka, "nev?", mk_is_nev, 2);
|
||||||
|
|
||||||
|
moka_decl_native(moka, "+", mk_add, -1);
|
||||||
|
moka_decl_native(moka, "-", mk_sub, -1);
|
||||||
|
moka_decl_native(moka, "*", mk_mul, -1);
|
||||||
|
moka_decl_native(moka, "/", mk_div, -1);
|
||||||
|
moka_decl_native(moka, "%", mk_mod, 2);
|
||||||
|
moka_decl_native(moka, "^", mk_pow, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
MOKA mk_println(struct moka* moka, struct vec* args)
|
MOKA mk_println(struct moka* moka, struct vec* args)
|
||||||
|
@ -101,6 +111,48 @@ MOKA mk_assert_eqv_mut(struct moka* moka, struct vec* args)
|
||||||
return moka_push_bool(moka, true, line);
|
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
|
// Comparisons
|
||||||
// ===========
|
// ===========
|
||||||
MOKA mk_lt(struct moka* moka, struct vec* args)
|
MOKA mk_lt(struct moka* moka, struct vec* args)
|
||||||
|
@ -186,3 +238,87 @@ MOKA mk_is_nev(struct moka* moka, struct vec* args)
|
||||||
moka_line(moka, lhs)
|
moka_line(moka, lhs)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MOKA mk_add(struct moka* moka, struct vec* args)
|
||||||
|
{
|
||||||
|
assert(moka);
|
||||||
|
assert(args);
|
||||||
|
|
||||||
|
for (size_t i=0; i<args->size; i++)
|
||||||
|
{
|
||||||
|
MOKA arg = MK_EVAL((MOKA) args->data[i]);
|
||||||
|
moka_push(moka, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return moka_add(moka, args->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOKA mk_sub(struct moka* moka, struct vec* args)
|
||||||
|
{
|
||||||
|
assert(moka);
|
||||||
|
assert(args);
|
||||||
|
|
||||||
|
for (size_t i=0; i<args->size; i++)
|
||||||
|
{
|
||||||
|
MOKA arg = MK_EVAL((MOKA) args->data[i]);
|
||||||
|
moka_push(moka, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return moka_sub(moka, args->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOKA mk_mul(struct moka* moka, struct vec* args)
|
||||||
|
{
|
||||||
|
assert(moka);
|
||||||
|
assert(args);
|
||||||
|
|
||||||
|
for (size_t i=0; i<args->size; i++)
|
||||||
|
{
|
||||||
|
MOKA arg = MK_EVAL((MOKA) args->data[i]);
|
||||||
|
moka_push(moka, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return moka_mul(moka, args->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOKA mk_div(struct moka* moka, struct vec* args)
|
||||||
|
{
|
||||||
|
assert(moka);
|
||||||
|
assert(args);
|
||||||
|
|
||||||
|
for (size_t i=0; i<args->size; i++)
|
||||||
|
{
|
||||||
|
MOKA arg = MK_EVAL((MOKA) args->data[i]);
|
||||||
|
moka_push(moka, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return moka_div(moka, args->size);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOKA mk_mod(struct moka* moka, struct vec* args)
|
||||||
|
{
|
||||||
|
assert(moka);
|
||||||
|
assert(args);
|
||||||
|
|
||||||
|
for (size_t i=0; i<args->size; i++)
|
||||||
|
{
|
||||||
|
MOKA arg = MK_EVAL((MOKA) args->data[i]);
|
||||||
|
moka_push(moka, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return moka_mod(moka);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOKA mk_pow(struct moka* moka, struct vec* args)
|
||||||
|
{
|
||||||
|
assert(moka);
|
||||||
|
assert(args);
|
||||||
|
|
||||||
|
for (size_t i=0; i<args->size; i++)
|
||||||
|
{
|
||||||
|
MOKA arg = MK_EVAL((MOKA) args->data[i]);
|
||||||
|
moka_push(moka, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
return moka_pow(moka);
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,9 @@ MOKA mk_define(struct moka* moka, struct vec* args);
|
||||||
MOKA mk_array(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_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
|
// Comparisons
|
||||||
// ===========
|
// ===========
|
||||||
MOKA mk_lt(struct moka* moka, struct vec* args);
|
MOKA mk_lt(struct moka* moka, struct vec* args);
|
||||||
|
@ -22,4 +25,13 @@ MOKA mk_ge(struct moka* moka, struct vec* args);
|
||||||
MOKA mk_is_eqv(struct moka* moka, struct vec* args);
|
MOKA mk_is_eqv(struct moka* moka, struct vec* args);
|
||||||
MOKA mk_is_nev(struct moka* moka, struct vec* args);
|
MOKA mk_is_nev(struct moka* moka, struct vec* args);
|
||||||
|
|
||||||
|
// Num Arithmetic
|
||||||
|
// ==============
|
||||||
|
MOKA mk_add(struct moka* moka, struct vec* args);
|
||||||
|
MOKA mk_sub(struct moka* moka, struct vec* args);
|
||||||
|
MOKA mk_mul(struct moka* moka, struct vec* args);
|
||||||
|
MOKA mk_div(struct moka* moka, struct vec* args);
|
||||||
|
MOKA mk_mod(struct moka* moka, struct vec* args);
|
||||||
|
MOKA mk_pow(struct moka* moka, struct vec* args);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
typedef size_t MOKA;
|
typedef size_t MOKA;
|
||||||
|
|
||||||
|
|
215
lib/moka.c
215
lib/moka.c
|
@ -328,6 +328,221 @@ bool moka_is_eqv(struct moka* self, MOKA mk_lhs, MOKA mk_rhs)
|
||||||
return value_is_eqv(lhs, rhs, self);
|
return value_is_eqv(lhs, rhs, self);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MOKA moka_add(struct moka* self, int count)
|
||||||
|
{
|
||||||
|
assert(self);
|
||||||
|
struct frame* frame = moka_frame(self);
|
||||||
|
|
||||||
|
float base = 0.0f;
|
||||||
|
bool is_int = true;
|
||||||
|
int line = 0;
|
||||||
|
|
||||||
|
for (int i=0; i<count; i++)
|
||||||
|
{
|
||||||
|
MOKA arg = moka_pop(self);
|
||||||
|
|
||||||
|
struct value* value = frame->local_values.data[arg];
|
||||||
|
line = value->line;
|
||||||
|
|
||||||
|
if (value->type == TY_INT)
|
||||||
|
{
|
||||||
|
base += value->data.integer;
|
||||||
|
}
|
||||||
|
else if (value->type == TY_FLOAT)
|
||||||
|
{
|
||||||
|
base += value->data.real;
|
||||||
|
is_int = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_int)
|
||||||
|
{
|
||||||
|
return moka_push_int(self, (int) base, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
return moka_push_float(self, base, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOKA moka_sub(struct moka* self, int count)
|
||||||
|
{
|
||||||
|
assert(self);
|
||||||
|
struct frame* frame = moka_frame(self);
|
||||||
|
|
||||||
|
float base = 0.0f;
|
||||||
|
bool is_int = true;
|
||||||
|
int line = 0;
|
||||||
|
|
||||||
|
struct vec args;
|
||||||
|
vec_init(&args);
|
||||||
|
|
||||||
|
for (int i=0; i<count; i++)
|
||||||
|
{
|
||||||
|
MOKA arg = moka_pop(self);
|
||||||
|
vec_push(&args, (void*) arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<count; i++)
|
||||||
|
{
|
||||||
|
MOKA arg = (MOKA) args.data[count - 1 - i];
|
||||||
|
|
||||||
|
struct value* value = frame->local_values.data[arg];
|
||||||
|
line = value->line;
|
||||||
|
|
||||||
|
if (value->type == TY_INT)
|
||||||
|
{
|
||||||
|
base += i == 0
|
||||||
|
? value->data.integer
|
||||||
|
: -value->data.integer;;
|
||||||
|
}
|
||||||
|
else if (value->type == TY_FLOAT)
|
||||||
|
{
|
||||||
|
base += i == 0
|
||||||
|
? value->data.real
|
||||||
|
: -value->data.real;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec_free(&args);
|
||||||
|
|
||||||
|
if (count == 1)
|
||||||
|
{
|
||||||
|
base *= -1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_int)
|
||||||
|
{
|
||||||
|
return moka_push_int(self, (int) base, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
return moka_push_float(self, base, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOKA moka_mul(struct moka* self, int count)
|
||||||
|
{
|
||||||
|
assert(self);
|
||||||
|
struct frame* frame = moka_frame(self);
|
||||||
|
|
||||||
|
float base = 1.0f;
|
||||||
|
bool is_int = true;
|
||||||
|
int line = 0;
|
||||||
|
|
||||||
|
for (int i=0; i<count; i++)
|
||||||
|
{
|
||||||
|
MOKA arg = moka_pop(self);
|
||||||
|
|
||||||
|
struct value* value = frame->local_values.data[arg];
|
||||||
|
line = value->line;
|
||||||
|
|
||||||
|
if (value->type == TY_INT)
|
||||||
|
{
|
||||||
|
base *= value->data.integer;
|
||||||
|
}
|
||||||
|
else if (value->type == TY_FLOAT)
|
||||||
|
{
|
||||||
|
base *= value->data.real;
|
||||||
|
is_int = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_int)
|
||||||
|
{
|
||||||
|
return moka_push_int(self, (int) base, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
return moka_push_float(self, base, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOKA moka_div(struct moka* self, int count)
|
||||||
|
{
|
||||||
|
assert(self);
|
||||||
|
struct frame* frame = moka_frame(self);
|
||||||
|
|
||||||
|
float base = 1.0f;
|
||||||
|
bool is_int = true;
|
||||||
|
int line = 0;
|
||||||
|
|
||||||
|
struct vec args;
|
||||||
|
vec_init(&args);
|
||||||
|
|
||||||
|
for (int i=0; i<count; i++)
|
||||||
|
{
|
||||||
|
MOKA arg = moka_pop(self);
|
||||||
|
vec_push(&args, (void*) arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i=0; i<count; i++)
|
||||||
|
{
|
||||||
|
MOKA arg = (MOKA) args.data[count - 1 - i];
|
||||||
|
|
||||||
|
struct value* value = frame->local_values.data[arg];
|
||||||
|
line = value->line;
|
||||||
|
|
||||||
|
if (value->type == TY_INT)
|
||||||
|
{
|
||||||
|
base *= i == 0
|
||||||
|
? value->data.integer
|
||||||
|
: 1.0f/value->data.integer;;
|
||||||
|
}
|
||||||
|
else if (value->type == TY_FLOAT)
|
||||||
|
{
|
||||||
|
base *= i == 0
|
||||||
|
? value->data.real
|
||||||
|
: 1.0f/value->data.real;
|
||||||
|
is_int = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec_free(&args);
|
||||||
|
|
||||||
|
if (count == 1)
|
||||||
|
{
|
||||||
|
base = 1.0f/base;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_int)
|
||||||
|
{
|
||||||
|
return moka_push_int(self, (int) base, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
return moka_push_float(self, base, line);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOKA moka_mod(struct moka* self)
|
||||||
|
{
|
||||||
|
struct frame* frame = moka_frame(self);
|
||||||
|
struct value* rhs = frame->local_values.data[moka_pop(self)];
|
||||||
|
struct value* lhs = frame->local_values.data[moka_pop(self)];
|
||||||
|
|
||||||
|
if (lhs->type == TY_FLOAT || rhs->type == TY_FLOAT)
|
||||||
|
{
|
||||||
|
return moka_push_float(self,
|
||||||
|
fmod(lhs->data.real, rhs->data.real),
|
||||||
|
lhs->line);
|
||||||
|
}
|
||||||
|
|
||||||
|
return moka_push_int(self,
|
||||||
|
fmod(lhs->data.integer, rhs->data.integer),
|
||||||
|
lhs->line);
|
||||||
|
}
|
||||||
|
|
||||||
|
MOKA moka_pow(struct moka* self)
|
||||||
|
{
|
||||||
|
struct frame* frame = moka_frame(self);
|
||||||
|
struct value* rhs = frame->local_values.data[moka_pop(self)];
|
||||||
|
struct value* lhs = frame->local_values.data[moka_pop(self)];
|
||||||
|
|
||||||
|
if (lhs->type == TY_FLOAT || rhs->type == TY_FLOAT)
|
||||||
|
{
|
||||||
|
return moka_push_float(self,
|
||||||
|
powf(lhs->data.real, rhs->data.real),
|
||||||
|
lhs->line);
|
||||||
|
}
|
||||||
|
|
||||||
|
return moka_push_int(self,
|
||||||
|
pow(lhs->data.integer, rhs->data.integer),
|
||||||
|
lhs->line);
|
||||||
|
}
|
||||||
|
|
||||||
bool moka_is(struct moka* self, MOKA value, TypeKind type)
|
bool moka_is(struct moka* self, MOKA value, TypeKind type)
|
||||||
{
|
{
|
||||||
return moka_type_of(self, value) == type;
|
return moka_type_of(self, value) == type;
|
||||||
|
|
|
@ -67,6 +67,13 @@ bool moka_is_lt(struct moka* self, MOKA mk_lhs, MOKA mk_rhs);
|
||||||
bool moka_is_gt(struct moka* self, MOKA mk_lhs, MOKA mk_rhs);
|
bool moka_is_gt(struct moka* self, MOKA mk_lhs, MOKA mk_rhs);
|
||||||
bool moka_is_eqv(struct moka* self, MOKA mk_lhs, MOKA mk_rhs);
|
bool moka_is_eqv(struct moka* self, MOKA mk_lhs, MOKA mk_rhs);
|
||||||
|
|
||||||
|
MOKA moka_add(struct moka* self, int count);
|
||||||
|
MOKA moka_sub(struct moka* self, int count);
|
||||||
|
MOKA moka_mul(struct moka* self, int count);
|
||||||
|
MOKA moka_div(struct moka* self, int count);
|
||||||
|
MOKA moka_mod(struct moka* self);
|
||||||
|
MOKA moka_pow(struct moka* self);
|
||||||
|
|
||||||
bool moka_is(struct moka* self, MOKA value, TypeKind type);
|
bool moka_is(struct moka* self, MOKA value, TypeKind type);
|
||||||
TypeKind moka_type_of(struct moka* self, MOKA value);
|
TypeKind moka_type_of(struct moka* self, MOKA value);
|
||||||
|
|
||||||
|
|
|
@ -99,3 +99,25 @@ struct entry* symtable_try_get(struct symtable* self, char* name)
|
||||||
return env_try_get(self->root, 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);
|
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
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue