Compare commits
No commits in common. "b5f0713fee3ba081685ce0bd03441db14cfe3217" and "06b379c99cb01a7db6aae6b54449925a919c4972" have entirely different histories.
b5f0713fee
...
06b379c99c
|
@ -2,4 +2,3 @@
|
|||
*\#*
|
||||
build
|
||||
.cache
|
||||
vgcore*
|
||||
|
|
|
@ -25,9 +25,6 @@ add_library(skopy-lib SHARED
|
|||
|
||||
src/sym.c
|
||||
src/fun.c
|
||||
|
||||
src/nfun.c
|
||||
src/natives.c
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "vec.h"
|
||||
#include "errors.h"
|
||||
|
||||
|
||||
#define SK_ENUM_ENUM(X) X
|
||||
#define SK_ENUM_STR(X) #X
|
||||
|
||||
|
|
|
@ -5,8 +5,6 @@
|
|||
#include "prog.h"
|
||||
#include "sym.h"
|
||||
|
||||
struct state;
|
||||
|
||||
struct compiler
|
||||
{
|
||||
struct vec var_names;
|
||||
|
@ -18,14 +16,12 @@ void compiler_free(struct compiler* self);
|
|||
void compiler_compile(struct compiler* self,
|
||||
struct node* node,
|
||||
struct prog* prog,
|
||||
struct sym* sym,
|
||||
struct state* state);
|
||||
struct sym* sym);
|
||||
|
||||
void compiler_compile_children(struct compiler* self,
|
||||
struct node* node,
|
||||
struct prog* prog,
|
||||
struct sym* sym,
|
||||
struct state* state);
|
||||
struct sym* sym);
|
||||
|
||||
void compiler_compile_value(struct compiler* self,
|
||||
struct node* node,
|
||||
|
@ -36,20 +32,17 @@ void compiler_compile_value(struct compiler* self,
|
|||
void compiler_compile_and(struct compiler* self,
|
||||
struct node* node,
|
||||
struct prog* prog,
|
||||
struct sym* sym,
|
||||
struct state* state);
|
||||
struct sym* sym);
|
||||
|
||||
void compiler_compile_or(struct compiler* self,
|
||||
struct node* node,
|
||||
struct prog* prog,
|
||||
struct sym* sym,
|
||||
struct state* state);
|
||||
struct sym* sym);
|
||||
|
||||
void compiler_compile_if(struct compiler* self,
|
||||
struct node* node,
|
||||
struct prog* prog,
|
||||
struct sym* sym,
|
||||
struct state* state,
|
||||
struct vec* to_end);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -4,14 +4,12 @@
|
|||
#include "commons.h"
|
||||
#include "prog.h"
|
||||
#include "sym.h"
|
||||
#include "state.h"
|
||||
|
||||
struct module
|
||||
{
|
||||
struct str source;
|
||||
struct prog prog;
|
||||
struct sym sym;
|
||||
struct state state;
|
||||
};
|
||||
|
||||
void module_init(struct module* self);
|
||||
|
|
|
@ -1,17 +0,0 @@
|
|||
#ifndef SK_NATIVES_H
|
||||
#define SK_NATIVES_H
|
||||
|
||||
#include "commons.h"
|
||||
#include "state.h"
|
||||
#include "sym.h"
|
||||
|
||||
void natives_populate(struct state* state, struct sym* sym);
|
||||
void natives_decl(struct state* state,
|
||||
struct sym* sym,
|
||||
char* name,
|
||||
nfun_body fun,
|
||||
int arity);
|
||||
|
||||
SK native_println(struct state* state, struct vec* args);
|
||||
|
||||
#endif
|
|
@ -1,21 +0,0 @@
|
|||
#ifndef SK_NFUN_H
|
||||
#define SK_NFUN_H
|
||||
|
||||
#include "commons.h"
|
||||
#include "state.h"
|
||||
|
||||
typedef SK (*nfun_body)(struct state*, struct vec*);
|
||||
|
||||
struct nfun
|
||||
{
|
||||
nfun_body body;
|
||||
int arity;
|
||||
};
|
||||
|
||||
void nfun_init(struct nfun* self, nfun_body body, int arity);
|
||||
void nfun_free(struct nfun* self);
|
||||
|
||||
SK nfun_call(struct nfun* self,
|
||||
struct state* state,
|
||||
struct vec* args);
|
||||
#endif
|
|
@ -14,8 +14,7 @@ G(OP_NOT), G(OP_AND), G(OP_OR), \
|
|||
G(OP_BR), G(OP_BRF), G(OP_LT), G(OP_GT), \
|
||||
G(OP_EQUAL), G(OP_LOCAL_STORE), G(OP_LOCAL_LOAD), \
|
||||
G(OP_CALL), G(OP_RET), G(OP_MAKE_REF), \
|
||||
G(OP_CLOSURE_LOAD), G(OP_CLOSURE_STORE), \
|
||||
G(OP_GLOBAL_LOAD)
|
||||
G(OP_CLOSURE_LOAD), G(OP_CLOSURE_STORE)
|
||||
|
||||
SK_ENUM_H(Opcode, OPCODE);
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef SK_STATE_H
|
||||
#define SK_STATE_H
|
||||
|
||||
#include "commons.h"
|
||||
#include "value.h"
|
||||
|
||||
#define SK size_t
|
||||
|
@ -26,23 +27,13 @@ struct frame
|
|||
struct fun* fun;
|
||||
};
|
||||
|
||||
struct global
|
||||
{
|
||||
int id;
|
||||
size_t addr;
|
||||
};
|
||||
|
||||
struct state
|
||||
{
|
||||
struct vec frames;
|
||||
size_t addr;
|
||||
int global_id;
|
||||
struct vec globals;
|
||||
struct vec global_values;
|
||||
};
|
||||
|
||||
typedef SK (*nfun_body)(struct state*, struct vec*);
|
||||
|
||||
void stack_value_init(struct stack_value* self,
|
||||
size_t addr,
|
||||
struct value* new_value);
|
||||
|
@ -62,6 +53,7 @@ struct frame* state_frame(struct state* self);
|
|||
void state_push_frame(struct state* self);
|
||||
void state_pop_frame(struct state* self);
|
||||
|
||||
bool state_has_top(struct state* self);
|
||||
SK state_top(struct state* self);
|
||||
struct value* state_try_get_value(struct state* self, SK value);
|
||||
struct local* state_try_get_local_by_id(struct state* self, int id);
|
||||
|
@ -91,9 +83,6 @@ void state_closure_store(struct state* self,
|
|||
void state_local_load(struct state* self,
|
||||
int id);
|
||||
|
||||
void state_global_load(struct state* self,
|
||||
int id);
|
||||
|
||||
void state_closure_load(struct state* self,
|
||||
int id);
|
||||
|
||||
|
@ -118,12 +107,6 @@ SK state_lt(struct state* self);
|
|||
SK state_gt(struct state* self);
|
||||
SK state_eq(struct state* self);
|
||||
|
||||
int state_add_global(struct state* self,
|
||||
struct value* value);
|
||||
|
||||
void state_call(struct state* self, struct fun* fun);
|
||||
void state_ret(struct state* self);
|
||||
SK state_add_nfun(struct state* self,
|
||||
nfun_body body,
|
||||
int arity);
|
||||
#endif
|
||||
|
|
|
@ -3,16 +3,13 @@
|
|||
|
||||
#include "commons.h"
|
||||
#define SK_NO_CLOSURE (-1)
|
||||
#define SK_NO_NATIVE (-1)
|
||||
|
||||
struct symbol
|
||||
{
|
||||
int id;
|
||||
int closure_id;
|
||||
int native_id;
|
||||
char* name;
|
||||
bool is_const;
|
||||
bool is_global;
|
||||
struct env* env;
|
||||
};
|
||||
|
||||
|
@ -26,8 +23,6 @@ struct sym
|
|||
{
|
||||
int id_counter;
|
||||
int closure_counter;
|
||||
int native_counter;
|
||||
int global_counter;
|
||||
struct env* env;
|
||||
};
|
||||
|
||||
|
@ -51,7 +46,6 @@ void sym_free(struct sym* self);
|
|||
int sym_decl_var(struct sym* self, char const* name);
|
||||
int sym_decl_const(struct sym* self, char const* name);
|
||||
int sym_decl_closure(struct sym* self, int id, char const* name);
|
||||
int sym_decl_global(struct sym* self, int id, char const* name);
|
||||
|
||||
void sym_open_scope(struct sym* self);
|
||||
void sym_close_scope(struct sym* self);
|
||||
|
|
|
@ -7,8 +7,7 @@
|
|||
|
||||
#define TYPE_KIND(G) \
|
||||
G(TYPE_INT), G(TYPE_BOOL), G(TYPE_FLOAT), \
|
||||
G(TYPE_STRING), G(TYPE_FUN), G(TYPE_REF), \
|
||||
G(TYPE_NATIVE_FUN)
|
||||
G(TYPE_STRING), G(TYPE_FUN), G(TYPE_REF)
|
||||
|
||||
SK_ENUM_H(TypeKind, TYPE_KIND);
|
||||
|
||||
|
@ -19,7 +18,6 @@ union val
|
|||
bool boolean;
|
||||
char* str;
|
||||
struct fun* fun;
|
||||
struct nfun* nfun;
|
||||
size_t ref;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include "compiler.h"
|
||||
#include "token.h"
|
||||
#include "state.h"
|
||||
#include "natives.h"
|
||||
|
||||
void compiler_init(struct compiler* self)
|
||||
{
|
||||
|
@ -18,8 +16,7 @@ void compiler_free(struct compiler* self)
|
|||
void compiler_compile(struct compiler* self,
|
||||
struct node* node,
|
||||
struct prog* prog,
|
||||
struct sym* sym,
|
||||
struct state* state)
|
||||
struct sym* sym)
|
||||
{
|
||||
assert(self);
|
||||
assert(node);
|
||||
|
@ -31,7 +28,7 @@ void compiler_compile(struct compiler* self,
|
|||
for (size_t i=0; i<node->children.size; i++)
|
||||
{
|
||||
compiler_compile(self, node->children.data[i],
|
||||
prog, sym, state);
|
||||
prog, sym);
|
||||
}
|
||||
} break;
|
||||
|
||||
|
@ -40,7 +37,7 @@ void compiler_compile(struct compiler* self,
|
|||
for (size_t i=0; i<node->children.size; i++)
|
||||
{
|
||||
compiler_compile(self, node->children.data[i],
|
||||
prog, sym, state);
|
||||
prog, sym);
|
||||
}
|
||||
sym_close_scope(sym);
|
||||
} break;
|
||||
|
@ -52,10 +49,10 @@ void compiler_compile(struct compiler* self,
|
|||
for (size_t i=0; i<args->children.size; i++)
|
||||
{
|
||||
compiler_compile(self, args->children.data[i],
|
||||
prog, sym, state);
|
||||
prog, sym);
|
||||
}
|
||||
|
||||
compiler_compile(self, target, prog, sym, state);
|
||||
compiler_compile(self, target, prog, sym);
|
||||
prog_add_instr(prog, OP_CALL, args->children.size);
|
||||
} break;
|
||||
|
||||
|
@ -63,8 +60,7 @@ void compiler_compile(struct compiler* self,
|
|||
struct vec to_end;
|
||||
vec_init(&to_end);
|
||||
|
||||
compiler_compile_if(self, node, prog, sym, state,
|
||||
&to_end);
|
||||
compiler_compile_if(self, node, prog, sym, &to_end);
|
||||
size_t end_point = prog->params.size;
|
||||
|
||||
for (size_t i=0; i<to_end.size; i++)
|
||||
|
@ -77,20 +73,20 @@ void compiler_compile(struct compiler* self,
|
|||
} break;
|
||||
|
||||
case NODE_NOT: {
|
||||
compiler_compile_children(self, node, prog, sym, state);
|
||||
compiler_compile_children(self, node, prog, sym);
|
||||
prog_add_instr(prog, OP_NOT, SK_NO_PARAM);
|
||||
} break;
|
||||
|
||||
case NODE_AND: {
|
||||
compiler_compile_and(self, node, prog, sym, state);
|
||||
compiler_compile_and(self, node, prog, sym);
|
||||
} break;
|
||||
|
||||
case NODE_OR: {
|
||||
compiler_compile_or(self, node, prog, sym, state);
|
||||
compiler_compile_or(self, node, prog, sym);
|
||||
} break;
|
||||
|
||||
case NODE_ASSERT_EQ: {
|
||||
compiler_compile_children(self, node, prog, sym, state);
|
||||
compiler_compile_children(self, node, prog, sym);
|
||||
prog_add_instr(prog, OP_ASSERT_EQ, SK_NO_PARAM);
|
||||
} break;
|
||||
|
||||
|
@ -107,7 +103,7 @@ void compiler_compile(struct compiler* self,
|
|||
}
|
||||
|
||||
struct node* expr = node->children.data[1];
|
||||
compiler_compile(self, expr, prog, sym, state);
|
||||
compiler_compile(self, expr, prog, sym);
|
||||
|
||||
int id = sym_decl_var(sym, ident->token->value);
|
||||
|
||||
|
@ -126,7 +122,7 @@ void compiler_compile(struct compiler* self,
|
|||
ident->token->value);
|
||||
}
|
||||
struct node* expr = node->children.data[1];
|
||||
compiler_compile(self, expr, prog, sym, state);
|
||||
compiler_compile(self, expr, prog, sym);
|
||||
int id = sym_decl_const(sym, ident->token->value);
|
||||
prog_add_instr(prog, OP_LOCAL_STORE, id);
|
||||
char* name = vec_pop(&self->var_names);
|
||||
|
@ -152,7 +148,7 @@ void compiler_compile(struct compiler* self,
|
|||
break;
|
||||
}
|
||||
|
||||
compiler_compile(self, expr, prog, sym, state);
|
||||
compiler_compile(self, expr, prog, sym);
|
||||
|
||||
if (symbol->closure_id != SK_NO_CLOSURE)
|
||||
{
|
||||
|
@ -169,29 +165,28 @@ void compiler_compile(struct compiler* self,
|
|||
node->token->value);
|
||||
if (!symbol)
|
||||
{
|
||||
errors_push(node->token->line,
|
||||
"unknown identifier '%s'.",
|
||||
node->token->value);
|
||||
break;
|
||||
}
|
||||
|
||||
struct env* itr = sym->env->parent;
|
||||
struct symbol* context = NULL;
|
||||
|
||||
while (itr)
|
||||
{
|
||||
struct symbol const* s = env_try_get(itr, symbol->name);
|
||||
struct symbol* s = env_try_get(itr, symbol->name);
|
||||
|
||||
if (s)
|
||||
{
|
||||
context = s;
|
||||
break;
|
||||
}
|
||||
|
||||
itr = itr->parent;
|
||||
}
|
||||
|
||||
if (symbol->is_global)
|
||||
if (0 && context)
|
||||
{
|
||||
prog_add_instr(prog, OP_GLOBAL_LOAD, symbol->id);
|
||||
prog_add_instr(prog, OP_LOCAL_LOAD, context->id);
|
||||
}
|
||||
else if (symbol->closure_id != SK_NO_CLOSURE)
|
||||
{
|
||||
|
@ -205,7 +200,7 @@ void compiler_compile(struct compiler* self,
|
|||
|
||||
case NODE_RETURN: {
|
||||
compiler_compile(self, node->children.data[0],
|
||||
prog, sym, state);
|
||||
prog, sym);
|
||||
prog_add_instr(prog, OP_RET, SK_NO_PARAM);
|
||||
} break;
|
||||
|
||||
|
@ -215,8 +210,6 @@ void compiler_compile(struct compiler* self,
|
|||
prog_init(p);
|
||||
|
||||
fun_init(fun, p);
|
||||
natives_populate(state, fun->sym);
|
||||
|
||||
struct node* params = node->children.data[0];
|
||||
struct node* body = node->children.data[1];
|
||||
|
||||
|
@ -260,8 +253,7 @@ void compiler_compile(struct compiler* self,
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
compiler_compile(self, body, p, fun->sym, state);
|
||||
compiler_compile(self, body, p, fun->sym);
|
||||
|
||||
union val val;
|
||||
val.fun = fun;
|
||||
|
@ -299,70 +291,70 @@ void compiler_compile(struct compiler* self,
|
|||
} break;
|
||||
|
||||
case NODE_LT: {
|
||||
compiler_compile_children(self, node, prog, sym, state);
|
||||
compiler_compile_children(self, node, prog, sym);
|
||||
prog_add_instr(prog, OP_LT, SK_NO_PARAM);
|
||||
} break;
|
||||
|
||||
case NODE_LE: {
|
||||
compiler_compile_children(self, node, prog, sym, state);
|
||||
compiler_compile_children(self, node, prog, sym);
|
||||
prog_add_instr(prog, OP_GT, SK_NO_PARAM);
|
||||
prog_add_instr(prog, OP_NOT, SK_NO_PARAM);
|
||||
} break;
|
||||
|
||||
case NODE_GT: {
|
||||
compiler_compile_children(self, node, prog, sym, state);
|
||||
compiler_compile_children(self, node, prog, sym);
|
||||
prog_add_instr(prog, OP_GT, SK_NO_PARAM);
|
||||
} break;
|
||||
|
||||
case NODE_GE: {
|
||||
compiler_compile_children(self, node, prog, sym, state);
|
||||
compiler_compile_children(self, node, prog, sym);
|
||||
prog_add_instr(prog, OP_LT, SK_NO_PARAM);
|
||||
prog_add_instr(prog, OP_NOT, SK_NO_PARAM);
|
||||
} break;
|
||||
|
||||
case NODE_EQUAL: {
|
||||
compiler_compile_children(self, node, prog, sym, state);
|
||||
compiler_compile_children(self, node, prog, sym);
|
||||
prog_add_instr(prog, OP_EQUAL, SK_NO_PARAM);
|
||||
} break;
|
||||
|
||||
case NODE_NOT_EQUAL: {
|
||||
compiler_compile_children(self, node, prog, sym, state);
|
||||
compiler_compile_children(self, node, prog, sym);
|
||||
prog_add_instr(prog, OP_EQUAL, SK_NO_PARAM);
|
||||
prog_add_instr(prog, OP_NOT, SK_NO_PARAM);
|
||||
} break;
|
||||
|
||||
case NODE_ADD: {
|
||||
compiler_compile_children(self, node, prog, sym, state);
|
||||
compiler_compile_children(self, node, prog, sym);
|
||||
prog_add_instr(prog, OP_ADD, SK_NO_PARAM);
|
||||
} break;
|
||||
|
||||
case NODE_SUB: {
|
||||
compiler_compile_children(self, node, prog, sym, state);
|
||||
compiler_compile_children(self, node, prog, sym);
|
||||
prog_add_instr(prog, OP_SUB, SK_NO_PARAM);
|
||||
} break;
|
||||
|
||||
case NODE_MUL: {
|
||||
compiler_compile_children(self, node, prog, sym, state);
|
||||
compiler_compile_children(self, node, prog, sym);
|
||||
prog_add_instr(prog, OP_MUL, SK_NO_PARAM);
|
||||
} break;
|
||||
|
||||
case NODE_DIV: {
|
||||
compiler_compile_children(self, node, prog, sym, state);
|
||||
compiler_compile_children(self, node, prog, sym);
|
||||
prog_add_instr(prog, OP_DIV, SK_NO_PARAM);
|
||||
} break;
|
||||
|
||||
case NODE_MOD: {
|
||||
compiler_compile_children(self, node, prog, sym, state);
|
||||
compiler_compile_children(self, node, prog, sym);
|
||||
prog_add_instr(prog, OP_MOD, SK_NO_PARAM);
|
||||
} break;
|
||||
|
||||
case NODE_POW: {
|
||||
compiler_compile_children(self, node, prog, sym, state);
|
||||
compiler_compile_children(self, node, prog, sym);
|
||||
prog_add_instr(prog, OP_POW, SK_NO_PARAM);
|
||||
} break;
|
||||
|
||||
case NODE_USUB: {
|
||||
compiler_compile_children(self, node, prog, sym, state);
|
||||
compiler_compile_children(self, node, prog, sym);
|
||||
prog_add_instr(prog, OP_USUB, SK_NO_PARAM);
|
||||
} break;
|
||||
|
||||
|
@ -377,8 +369,7 @@ void compiler_compile(struct compiler* self,
|
|||
void compiler_compile_children(struct compiler* self,
|
||||
struct node* node,
|
||||
struct prog* prog,
|
||||
struct sym* sym,
|
||||
struct state* state)
|
||||
struct sym* sym)
|
||||
{
|
||||
assert(self);
|
||||
assert(node);
|
||||
|
@ -387,7 +378,7 @@ void compiler_compile_children(struct compiler* self,
|
|||
for (size_t i=0; i<node->children.size; i++)
|
||||
{
|
||||
struct node* child = node->children.data[i];
|
||||
compiler_compile(self, child, prog, sym, state);
|
||||
compiler_compile(self, child, prog, sym);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -408,8 +399,7 @@ void compiler_compile_value(struct compiler* self,
|
|||
void compiler_compile_and(struct compiler* self,
|
||||
struct node* node,
|
||||
struct prog* prog,
|
||||
struct sym* sym,
|
||||
struct state* state)
|
||||
struct sym* sym)
|
||||
{
|
||||
assert(self);
|
||||
assert(node);
|
||||
|
@ -422,7 +412,7 @@ void compiler_compile_and(struct compiler* self,
|
|||
for (size_t i =0; i<node->children.size; i++)
|
||||
{
|
||||
struct node* child = node->children.data[i];
|
||||
compiler_compile(self, child, prog, sym, state);
|
||||
compiler_compile(self, child, prog, sym);
|
||||
size_t brf = prog_add_instr(prog, OP_BRF, 0); // to false
|
||||
vec_push(&to_false, (void*) brf);
|
||||
}
|
||||
|
@ -452,8 +442,7 @@ void compiler_compile_and(struct compiler* self,
|
|||
void compiler_compile_or(struct compiler* self,
|
||||
struct node* node,
|
||||
struct prog* prog,
|
||||
struct sym* sym,
|
||||
struct state* state)
|
||||
struct sym* sym)
|
||||
{
|
||||
assert(self);
|
||||
assert(node);
|
||||
|
@ -465,7 +454,7 @@ void compiler_compile_or(struct compiler* self,
|
|||
for (size_t i =0; i<node->children.size; i++)
|
||||
{
|
||||
struct node* child = node->children.data[i];
|
||||
compiler_compile(self, child, prog, sym, state);
|
||||
compiler_compile(self, child, prog, sym);
|
||||
prog_add_instr(prog, OP_NOT, 0);
|
||||
size_t brf = prog_add_instr(prog, OP_BRF, 0); // to true
|
||||
vec_push(&to_true, (void*) brf);
|
||||
|
@ -497,16 +486,15 @@ void compiler_compile_if(struct compiler* self,
|
|||
struct node* node,
|
||||
struct prog* prog,
|
||||
struct sym* sym,
|
||||
struct state* state,
|
||||
struct vec* to_end)
|
||||
{
|
||||
struct node* cond = node->children.data[0];
|
||||
struct node* block = node->children.data[1];
|
||||
|
||||
compiler_compile(self, cond, prog, sym, state);
|
||||
compiler_compile(self, cond, prog, sym);
|
||||
size_t brf = prog_add_instr(prog, OP_BRF, 40); // to next
|
||||
|
||||
compiler_compile(self, block, prog, sym, state);
|
||||
compiler_compile(self, block, prog, sym);
|
||||
|
||||
size_t br = prog_add_instr(prog, OP_BR, 0); // to end
|
||||
vec_push(to_end, (void*) br);
|
||||
|
@ -519,11 +507,11 @@ void compiler_compile_if(struct compiler* self,
|
|||
struct node* next = node->children.data[2];
|
||||
if (next->kind == NODE_IF)
|
||||
{
|
||||
compiler_compile_if(self, next, prog, sym, state, to_end);
|
||||
compiler_compile_if(self, next, prog, sym, to_end);
|
||||
}
|
||||
else
|
||||
{
|
||||
compiler_compile(self, next, prog, sym, state);
|
||||
compiler_compile(self, next, prog, sym);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include "exec.h"
|
||||
#include "sym.h"
|
||||
#include "fun.h"
|
||||
#include "nfun.h"
|
||||
|
||||
void exec_init(struct exec* self)
|
||||
{
|
||||
|
@ -40,11 +39,6 @@ void exec_execute(struct exec* self,
|
|||
self->pc++;
|
||||
} break;
|
||||
|
||||
case OP_GLOBAL_LOAD: {
|
||||
state_global_load(state, param);
|
||||
self->pc++;
|
||||
} break;
|
||||
|
||||
case OP_LOCAL_LOAD: {
|
||||
state_local_load(state, param);
|
||||
self->pc++;
|
||||
|
@ -99,70 +93,19 @@ void exec_execute(struct exec* self,
|
|||
struct vec params;
|
||||
vec_init(¶ms);
|
||||
|
||||
struct vec pvalues;
|
||||
vec_init(&pvalues);
|
||||
|
||||
SK function = state_pop(state);
|
||||
|
||||
for (size_t i=0; i<param; i++)
|
||||
{
|
||||
SK arg = state_pop(state);
|
||||
vec_push(&pvalues, (void*) arg);
|
||||
vec_push(¶ms, (void*) value_new_clone(state_try_get_value(state, arg)));
|
||||
}
|
||||
|
||||
struct value* f = value_new_clone(state_try_get_value(state, function));
|
||||
|
||||
struct value* val_fun = state_try_deref(
|
||||
struct fun* fun = state_try_deref(
|
||||
state,
|
||||
f->val.ref
|
||||
);
|
||||
|
||||
assert(val_fun);
|
||||
|
||||
if (val_fun->type == TYPE_NATIVE_FUN)
|
||||
{
|
||||
struct vec ordered;
|
||||
vec_init(&ordered);
|
||||
for (size_t i=0; i<pvalues.size; i++)
|
||||
{
|
||||
SK arg = (SK)
|
||||
pvalues.data[pvalues.size - 1 - i];
|
||||
vec_push(&ordered, (void*) arg);
|
||||
}
|
||||
SK res = nfun_call(val_fun->val.nfun,
|
||||
state,
|
||||
&ordered);
|
||||
struct value* value =
|
||||
state_try_get_value(state, res);
|
||||
state_push(
|
||||
state,
|
||||
value->type,
|
||||
value->val,
|
||||
value->line
|
||||
);
|
||||
|
||||
vec_free(&pvalues);
|
||||
vec_free(&ordered);
|
||||
vec_free_elements(¶ms, (void*) value_free);
|
||||
vec_free(¶ms);
|
||||
value_free(f);
|
||||
free(f);
|
||||
self->pc++;
|
||||
break;
|
||||
}
|
||||
|
||||
vec_free(&pvalues);
|
||||
if (!val_fun)
|
||||
{
|
||||
vec_free_elements(¶ms, NULL);
|
||||
vec_free(¶ms);
|
||||
errors_push(f->line, "cannot deref nil ref");
|
||||
free(f);
|
||||
return;
|
||||
}
|
||||
|
||||
struct fun* fun = val_fun->val.fun;
|
||||
)->val.fun;
|
||||
|
||||
state_call(state, fun);
|
||||
for (size_t i=0; i<params.size; i++)
|
||||
|
@ -248,14 +191,6 @@ void exec_execute(struct exec* self,
|
|||
);
|
||||
} break;
|
||||
|
||||
case TYPE_REF: {
|
||||
state_push_ref(
|
||||
state,
|
||||
constant->val.ref,
|
||||
constant->line
|
||||
);
|
||||
} break;
|
||||
|
||||
case TYPE_BOOL: {
|
||||
state_push_bool(
|
||||
state,
|
||||
|
|
|
@ -3,17 +3,13 @@
|
|||
#include "compiler.h"
|
||||
#include "state.h"
|
||||
#include "exec.h"
|
||||
#include "natives.h"
|
||||
|
||||
void module_init(struct module* self)
|
||||
{
|
||||
assert(self);
|
||||
str_init(&self->source);
|
||||
prog_init(&self->prog);
|
||||
state_init(&self->state);
|
||||
sym_init(&self->sym);
|
||||
|
||||
natives_populate(&self->state, &self->sym);
|
||||
}
|
||||
|
||||
void module_free(struct module* self)
|
||||
|
@ -22,7 +18,6 @@ void module_free(struct module* self)
|
|||
str_free(&self->source);
|
||||
prog_free(&self->prog);
|
||||
sym_free(&self->sym);
|
||||
state_free(&self->state);
|
||||
}
|
||||
|
||||
void module_load_source(struct module* self,
|
||||
|
@ -59,13 +54,14 @@ int module_compile(struct module* self)
|
|||
struct compiler compiler;
|
||||
compiler_init(&compiler);
|
||||
|
||||
compiler_compile(&compiler, root, &self->prog, &self->sym,
|
||||
&self->state);
|
||||
compiler_compile(&compiler, root, &self->prog, &self->sym);
|
||||
|
||||
struct exec exec;
|
||||
exec_init(&exec);
|
||||
|
||||
exec_execute(&exec, &self->state, &self->prog);
|
||||
struct state state;
|
||||
state_init(&state);
|
||||
exec_execute(&exec, &state, &self->prog);
|
||||
|
||||
if (!errors_ok())
|
||||
{
|
||||
|
@ -73,8 +69,25 @@ int module_compile(struct module* self)
|
|||
goto free_state;
|
||||
}
|
||||
|
||||
if (state_has_top(&state))
|
||||
{
|
||||
struct value* value = state_try_get_value(
|
||||
&state,
|
||||
state_top(&state)
|
||||
);
|
||||
|
||||
assert(value);
|
||||
|
||||
struct str str;
|
||||
str_init(&str);
|
||||
value_str(value, &str);
|
||||
printf("%s\n", str.value);
|
||||
str_free(&str);
|
||||
}
|
||||
|
||||
// Free
|
||||
free_state:
|
||||
state_free(&state);
|
||||
exec_free(&exec);
|
||||
compiler_free(&compiler);
|
||||
free_node:
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
#include "natives.h"
|
||||
|
||||
void natives_populate(struct state* state, struct sym* sym)
|
||||
{
|
||||
assert(state);
|
||||
assert(sym);
|
||||
|
||||
natives_decl(state, sym, "println", native_println, -1);
|
||||
}
|
||||
|
||||
void natives_decl(struct state* state,
|
||||
struct sym* sym,
|
||||
char* name,
|
||||
nfun_body fun,
|
||||
int arity)
|
||||
{
|
||||
assert(state);
|
||||
assert(sym);
|
||||
sym_decl_global(sym, state->global_id, name);
|
||||
state_add_nfun(state, fun, arity);
|
||||
}
|
||||
|
||||
SK native_println(struct state* state, struct vec* args)
|
||||
{
|
||||
for (size_t i=0; i<args->size; i++)
|
||||
{
|
||||
struct value* arg
|
||||
= state_try_get_value(state, (SK) args->data[i]);
|
||||
|
||||
struct str str;
|
||||
str_init(&str);
|
||||
value_str(arg, &str);
|
||||
if (i > 0) { printf(" "); }
|
||||
printf("%s", str.value);
|
||||
str_free(&str);
|
||||
}
|
||||
printf("\n");
|
||||
return state_push_bool(state, true, 0);
|
||||
}
|
|
@ -1,39 +0,0 @@
|
|||
#include "nfun.h"
|
||||
|
||||
void nfun_init(struct nfun* self, nfun_body body, int arity)
|
||||
{
|
||||
assert(self);
|
||||
self->body = body;
|
||||
self->arity = arity;
|
||||
}
|
||||
|
||||
void nfun_free(struct nfun* self)
|
||||
{
|
||||
assert(self);
|
||||
}
|
||||
|
||||
SK nfun_call(struct nfun* self,
|
||||
struct state* state,
|
||||
struct vec* args)
|
||||
{
|
||||
assert(self);
|
||||
int line = 0;
|
||||
|
||||
if (args->size > 0)
|
||||
{
|
||||
line = state_line(state, (SK) args->data[0]);
|
||||
}
|
||||
|
||||
if (self->arity >= 0 && self->arity != (int) args->size)
|
||||
{
|
||||
errors_push(line,
|
||||
"wrong arity, expected %zu, got %zu.",
|
||||
self->arity,
|
||||
args->size);
|
||||
return state_push_bool(state, false, line);
|
||||
}
|
||||
|
||||
SK result = (*self->body)(state, args);
|
||||
|
||||
return result;
|
||||
}
|
|
@ -214,6 +214,7 @@ struct node* parser_try_block(struct parser* self)
|
|||
}
|
||||
|
||||
struct token* tok = lexer_try_new_next(&self->lexer);
|
||||
|
||||
struct node* node = SK_TRY(parser_try_inner_block);
|
||||
|
||||
if (!node)
|
||||
|
@ -225,12 +226,9 @@ struct node* parser_try_block(struct parser* self)
|
|||
if (!lexer_next_is(&self->lexer, TOKEN_END))
|
||||
{
|
||||
node_free(node); free(node);
|
||||
token_free(tok); free(tok);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
token_free(tok);
|
||||
free(tok);
|
||||
lexer_consume_next(&self->lexer);
|
||||
return node;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "state.h"
|
||||
#include "nfun.h"
|
||||
|
||||
void stack_value_init(struct stack_value* self,
|
||||
size_t addr,
|
||||
|
@ -41,9 +40,7 @@ void state_init(struct state* self)
|
|||
assert(self);
|
||||
vec_init(&self->frames);
|
||||
self->addr = 1;
|
||||
self->global_id = 1456;
|
||||
state_push_frame(self);
|
||||
vec_init(&self->global_values);
|
||||
vec_init(&self->globals);
|
||||
}
|
||||
|
||||
|
@ -53,10 +50,7 @@ void state_free(struct state* self)
|
|||
vec_free_elements(&self->frames, (void*) frame_free);
|
||||
vec_free(&self->frames);
|
||||
|
||||
vec_free_elements(&self->global_values, (void*) value_free);
|
||||
vec_free(&self->global_values);
|
||||
|
||||
vec_free_elements(&self->globals, NULL);
|
||||
vec_free_elements(&self->globals, (void*) value_free);
|
||||
vec_free(&self->globals);
|
||||
}
|
||||
|
||||
|
@ -66,30 +60,25 @@ SK state_make_ref(struct state* self)
|
|||
struct value* value = state_try_get_value(self, val);
|
||||
|
||||
struct value* on_heap = value_new_clone(value);
|
||||
vec_push(&self->globals, on_heap);
|
||||
|
||||
size_t addr = state_add_global(
|
||||
return state_push_ref(
|
||||
self,
|
||||
on_heap
|
||||
self->globals.size - 1,
|
||||
on_heap->line
|
||||
);
|
||||
|
||||
return state_push_ref(self, addr, value->line);
|
||||
}
|
||||
|
||||
struct value* state_try_deref(struct state* self, size_t ref)
|
||||
{
|
||||
assert(self);
|
||||
|
||||
for (size_t i=0; i<self->globals.size; i++)
|
||||
if (ref >= self->globals.size)
|
||||
{
|
||||
struct global const* global = self->globals.data[i];
|
||||
|
||||
if (global->addr == ref)
|
||||
{
|
||||
return self->global_values.data[ref];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
return self->globals.data[ref];
|
||||
}
|
||||
|
||||
struct frame* state_frame(struct state* self)
|
||||
|
@ -116,6 +105,11 @@ void state_pop_frame(struct state* self)
|
|||
frame_free(frame);
|
||||
free(frame);
|
||||
}
|
||||
bool state_has_top(struct state* self)
|
||||
{
|
||||
struct frame* frame = state_frame(self);
|
||||
return frame->stack.size > 0;
|
||||
}
|
||||
|
||||
SK state_top(struct state* self)
|
||||
{
|
||||
|
@ -312,25 +306,7 @@ void state_local_load(struct state* self,
|
|||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "cannot load local %d\n", id);
|
||||
abort();
|
||||
}
|
||||
|
||||
void state_global_load(struct state* self,
|
||||
int id)
|
||||
{
|
||||
for (size_t i=0; i<self->globals.size; i++)
|
||||
{
|
||||
struct global const* global = self->globals.data[i];
|
||||
|
||||
if (global->id == id)
|
||||
{
|
||||
state_push_ref(self, global->addr, 0);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fprintf(stderr, "cannot load global %d\n", id);
|
||||
fprintf(stderr, "cannot load %d\n", id);
|
||||
abort();
|
||||
}
|
||||
|
||||
|
@ -754,23 +730,6 @@ SK state_eq(struct state* self)
|
|||
);
|
||||
}
|
||||
|
||||
int state_add_global(struct state* self,
|
||||
struct value* value)
|
||||
{
|
||||
assert(self);
|
||||
|
||||
vec_push(&self->global_values, value);
|
||||
size_t addr = self->global_values.size - 1;
|
||||
struct global* global = malloc(sizeof(struct global));
|
||||
global->id = self->global_id;
|
||||
self->global_id++;
|
||||
global->addr = addr;
|
||||
|
||||
vec_push(&self->globals, global);
|
||||
|
||||
return addr;
|
||||
}
|
||||
|
||||
void state_call(struct state* self, struct fun* fun)
|
||||
{
|
||||
assert(self);
|
||||
|
@ -784,19 +743,3 @@ void state_ret(struct state* self)
|
|||
assert(self);
|
||||
state_pop_frame(self);
|
||||
}
|
||||
|
||||
SK state_add_nfun(struct state* self,
|
||||
nfun_body body,
|
||||
int arity)
|
||||
{
|
||||
struct nfun* fun = malloc(sizeof(struct nfun));
|
||||
nfun_init(fun, body, arity);
|
||||
|
||||
union val val;
|
||||
val.nfun = fun;
|
||||
|
||||
struct value* value = malloc(sizeof(struct value));
|
||||
value_init(value, TYPE_NATIVE_FUN, val, 0);
|
||||
|
||||
return state_add_global(self, value);
|
||||
}
|
||||
|
|
|
@ -21,7 +21,6 @@ struct env* env_new_clone(struct env* self)
|
|||
new_symbol->name = strdup(symbol->name);
|
||||
new_symbol->is_const = symbol->is_const;
|
||||
new_symbol->closure_id = symbol->closure_id;
|
||||
new_symbol->native_id = symbol->native_id;
|
||||
new_symbol->env = clone;
|
||||
|
||||
vec_push(&clone->symbols, new_symbol);
|
||||
|
@ -71,9 +70,7 @@ void symbol_init(struct symbol* self,
|
|||
self->id = id;
|
||||
self->name = strdup(name);
|
||||
self->is_const = false;
|
||||
self->is_global = false;
|
||||
self->closure_id = SK_NO_CLOSURE;
|
||||
self->native_id = SK_NO_NATIVE;
|
||||
self->env = env;
|
||||
}
|
||||
|
||||
|
@ -88,8 +85,6 @@ void sym_init(struct sym* self)
|
|||
assert(self);
|
||||
self->id_counter = 1;
|
||||
self->closure_counter = 1;
|
||||
self->native_counter = 1;
|
||||
self->global_counter = 1;
|
||||
self->env = malloc(sizeof(struct env));
|
||||
env_init(self->env);
|
||||
}
|
||||
|
@ -158,16 +153,6 @@ int sym_decl_closure(struct sym* self, int id, char const* name)
|
|||
return self->closure_counter - 1;
|
||||
}
|
||||
|
||||
int sym_decl_global(struct sym* self, int id, char const* name)
|
||||
{
|
||||
assert(self);
|
||||
assert(name);
|
||||
struct symbol* symbol = malloc(sizeof(struct symbol));
|
||||
symbol_init(symbol, id, name, self->env);
|
||||
symbol->is_global = true;
|
||||
vec_push(&self->env->symbols, symbol);
|
||||
return id;
|
||||
}
|
||||
void sym_open_scope(struct sym* self)
|
||||
{
|
||||
assert(self);
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "value.h"
|
||||
#include "nfun.h"
|
||||
|
||||
SK_ENUM_C(TypeKind, TYPE_KIND);
|
||||
|
||||
|
@ -28,12 +27,6 @@ void value_free(struct value* self)
|
|||
fun_free(self->val.fun);
|
||||
free(self->val.fun);
|
||||
}
|
||||
|
||||
if (self->type == TYPE_NATIVE_FUN)
|
||||
{
|
||||
nfun_free(self->val.nfun);
|
||||
free(self->val.nfun);
|
||||
}
|
||||
}
|
||||
|
||||
struct value* value_new_clone(struct value* self)
|
||||
|
@ -70,7 +63,7 @@ struct value* value_new_clone(struct value* self)
|
|||
} break;
|
||||
|
||||
case TYPE_STRING: {
|
||||
val.str = strdup(self->val.str);
|
||||
val.str = self->val.str;
|
||||
value_init(clone, TYPE_STRING, val, self->line);
|
||||
return clone;
|
||||
} break;
|
||||
|
@ -81,14 +74,6 @@ struct value* value_new_clone(struct value* self)
|
|||
return clone;
|
||||
} break;
|
||||
|
||||
case TYPE_NATIVE_FUN: {
|
||||
val.nfun = malloc(sizeof(struct nfun));
|
||||
val.nfun->body = self->val.nfun->body;
|
||||
val.nfun->arity = self->val.nfun->arity;
|
||||
value_init(clone, TYPE_NATIVE_FUN, val, self->line);
|
||||
return clone;
|
||||
} break;
|
||||
|
||||
default: {
|
||||
fprintf(stderr, "cannot clone value '%s'\n",
|
||||
TypeKindStr[self->type]);
|
||||
|
@ -126,10 +111,6 @@ void value_str(struct value* self, struct str* dest)
|
|||
str_format(dest, "<fun:%p>", self->val.fun);
|
||||
} break;
|
||||
|
||||
case TYPE_NATIVE_FUN: {
|
||||
str_format(dest, "<nfun:%p>", self->val.nfun);
|
||||
} break;
|
||||
|
||||
case TYPE_REF: {
|
||||
str_format(dest, "<ref:%zu>", self->val.ref);
|
||||
} break;
|
||||
|
|
Loading…
Reference in New Issue