Compare commits
No commits in common. "b8fa1df563efe876c2f6311da14dbe8a60d8f937" and "1c5ad117d8ecad785ba2261ab2f1c6572d138e66" have entirely different histories.
b8fa1df563
...
1c5ad117d8
|
@ -1,18 +0,0 @@
|
||||||
(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)
|
|
|
@ -1,24 +0,0 @@
|
||||||
(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,10 +30,6 @@ 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,22 +12,12 @@ 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)
|
||||||
|
@ -111,48 +101,6 @@ 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)
|
||||||
|
@ -238,87 +186,3 @@ 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,9 +13,6 @@ 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);
|
||||||
|
@ -25,13 +22,4 @@ 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,7 +8,6 @@
|
||||||
#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,221 +328,6 @@ 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,13 +67,6 @@ 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,25 +99,3 @@ 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,7 +42,4 @@ 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