Compare commits

..

No commits in common. "687236fb7d782624d9707b9df109932a7e6d701d" and "6d34100d672db41d1fa7566e14ea9f9910365a26" have entirely different histories.

18 changed files with 34 additions and 670 deletions

View File

@ -5,15 +5,6 @@ EXPR ::=
| DECL | DECL
| ASSIGN | ASSIGN
| BEGIN | BEGIN
| IF end
| WHILE
| FOR
| continue
| break
FOR ::= for EXPR in EXPR BLOCK end
WHILE ::= while EXPR BLOCK end
IF ::=
| if EXPR BLOCK (else (IF | BLOCK))?
BEGIN ::= begin BLOCK end BEGIN ::= begin BLOCK end
BLOCK ::= EXPR* BLOCK ::= EXPR*
ASSIGN ::= (ident|INDEX) assign EXPR ASSIGN ::= (ident|INDEX) assign EXPR

View File

@ -10,7 +10,7 @@ G(OP_DIV), G(OP_POW), G(OP_MOD), G(OP_MK_TUPLE), \
G(OP_ASSERT_EQ), G(OP_ASSERT_NE), G(OP_BRF), G(OP_BR), \ G(OP_ASSERT_EQ), G(OP_ASSERT_NE), G(OP_BRF), G(OP_BR), \
G(OP_NOT), G(OP_IN), G(OP_INDEX), G(OP_EQ), G(OP_LT), \ G(OP_NOT), G(OP_IN), G(OP_INDEX), G(OP_EQ), G(OP_LT), \
G(OP_GT), G(OP_MK_ARRAY), G(OP_LOCAL_STORE), \ G(OP_GT), G(OP_MK_ARRAY), G(OP_LOCAL_STORE), \
G(OP_LOCAL_LOAD), G(OP_ASTORE), G(OP_LEN) G(OP_LOCAL_LOAD), G(OP_ASTORE)
CCM_ENUM_H(Opcode, OPCODES); CCM_ENUM_H(Opcode, OPCODES);

View File

@ -40,11 +40,6 @@ size_t ccm_str(ccm_t* self, char* buffer, size_t size)
for (size_t i=0; i<self->stack.size; i++) for (size_t i=0; i<self->stack.size; i++)
{ {
if (sz >= size)
{
break;
}
value_t* val = ccm_to_value(self, (CCM) self->stack.data[i]); value_t* val = ccm_to_value(self, (CCM) self->stack.data[i]);
sz += value_str(val, buffer + sz, size - sz); sz += value_str(val, buffer + sz, size - sz);
sz += snprintf(buffer + sz, size - sz, "\n"); sz += snprintf(buffer + sz, size - sz, "\n");
@ -266,9 +261,10 @@ char* ccm_from_str(ccm_t* self, CCM value)
return ccm_find_value(self, value)->data.str; return ccm_find_value(self, value)->data.str;
} }
CCM ccm_to_str(ccm_t* self, char const* value, int line) CCM ccm_to_str(ccm_t* self, char* value, int line)
{ {
assert(self); assert(self);
assert(value);
value_t* val = malloc(sizeof(value_t)); value_t* val = malloc(sizeof(value_t));
value_init_str(val, value, line); value_init_str(val, value, line);

View File

@ -51,7 +51,7 @@ CCM ccm_to_boolean(ccm_t* self, int value, int line);
int ccm_is_str(ccm_t* self, CCM value); int ccm_is_str(ccm_t* self, CCM value);
char* ccm_from_str(ccm_t* self, CCM value); char* ccm_from_str(ccm_t* self, CCM value);
CCM ccm_to_str(ccm_t* self, char const* value, int line); CCM ccm_to_str(ccm_t* self, char* value, int line);
int ccm_is_array(ccm_t* self, CCM value); int ccm_is_array(ccm_t* self, CCM value);
vec_t* ccm_from_array(ccm_t* self, CCM value); vec_t* ccm_from_array(ccm_t* self, CCM value);

View File

@ -1,5 +1,4 @@
#include "compiler.h" #include "compiler.h"
#include "prog.h"
void compiler_init(compiler_t* self, module_t* module) void compiler_init(compiler_t* self, module_t* module)
{ {
@ -7,15 +6,12 @@ void compiler_init(compiler_t* self, module_t* module)
err_init(&self->err); err_init(&self->err);
self->module = module; self->module = module;
self->loc_counter = 0; self->loc_counter = 0;
vec_init(&self->loop_infos);
} }
void compiler_free(compiler_t* self) void compiler_free(compiler_t* self)
{ {
assert(self); assert(self);
err_free(&self->err); err_free(&self->err);
vec_free_elements(&self->loop_infos, NULL);
vec_free(&self->loop_infos);
} }
void compiler_compile(compiler_t* self, void compiler_compile(compiler_t* self,
@ -36,181 +32,14 @@ void compiler_compile(compiler_t* self,
switch (node->kind) switch (node->kind)
{ {
case NODE_CONTINUE: {
assert(self->loop_infos.size > 0);
loop_info_t const* info
= self->loop_infos.data[
self->loop_infos.size - 1
];
prog_add_instr(prog, OP_BR, info->start_point);
} break;
case NODE_BREAK: {
assert(self->loop_infos.size > 0);
loop_info_t* info
= self->loop_infos.data[
self->loop_infos.size - 1
];
size_t point = prog_add_instr(prog, OP_BR, 0);
vec_push(&info->to_end, (void*) point);
} break;
case NODE_FOR: {
node_t const* ident = node->children.data[0];
node_t* expr = node->children.data[1];
node_t* block = node->children.data[2];
sym_open_scope(sym);
sym_declare(sym, "__iter",
self->loc_counter++, 0);
sym_declare(sym, ident->value,
self->loc_counter++, 0);
int var_id =
sym_try_get_value(sym, ident->value)->id;
int iter_id =
sym_try_get_value(sym, "__iter")->id;
// initialize iteration counter
value_t* value = malloc(sizeof(value_t));
value_init_num(value, -1, node->line);
prog_add_instr(prog, OP_PUSH, prog_add_new_constant(
prog,
ccm_from_value(ccm, value)
));
prog_add_instr(prog, OP_LOCAL_STORE, iter_id);
int start = prog->instrs.size;
loop_info_t* info = malloc(sizeof(loop_info_t));
info->start_point = start;
vec_init(&info->to_end);
vec_push(&self->loop_infos, info);
// incr iteration counter
prog_add_instr(prog, OP_LOCAL_LOAD, iter_id);
value_free(value); free(value);
value = malloc(sizeof(value_t));
value_init_num(value, 1, node->line);
prog_add_instr(prog, OP_PUSH, prog_add_new_constant(
prog,
ccm_from_value(ccm, value)
));
prog_add_instr(prog, OP_ADD, CCM_NO_PARAM);
prog_add_instr(prog, OP_LOCAL_STORE, iter_id);
// test if end is reached
prog_add_instr(prog, OP_LOCAL_LOAD, iter_id);
compiler_compile(self, expr, prog);
prog_add_instr(prog, OP_LEN, CCM_NO_PARAM);
prog_add_instr(prog, OP_LT, CCM_NO_PARAM);
int cond_point = prog_add_instr(prog, OP_BRF, 0);
// get current element
prog_add_instr(prog, OP_LOCAL_LOAD, iter_id);
compiler_compile(self, expr, prog);
prog_add_instr(prog, OP_INDEX, 1);
prog_add_instr(prog, OP_LOCAL_STORE, var_id);
// compile body
compiler_compile(self, block, prog);
// next iteration
prog_add_instr(prog, OP_BR, start);
value_free(value); free(value);
int end_point = prog->instrs.size;
((instr_t*)prog->instrs.data[cond_point])->param
= end_point;
for (size_t i=0; i<info->to_end.size; i++)
{
int addr = (size_t)info->to_end.data[i];
instr_t* instr = prog->instrs.data[addr];
instr->param = end_point;
}
sym_close_scope(sym);
info = vec_pop(&self->loop_infos);
vec_free(&info->to_end);
free(info);
} break;
case NODE_WHILE: {
node_t* expr = node->children.data[0];
node_t* block = node->children.data[1];
int start = prog->instrs.size;
loop_info_t* info = malloc(sizeof(loop_info_t));
info->start_point = start;
vec_init(&info->to_end);
vec_push(&self->loop_infos, info);
compiler_compile(self, expr, prog);
int cond_point = prog_add_instr(prog, OP_BRF, 0);
compiler_compile(self, block, prog);
prog_add_instr(prog, OP_BR, start);
int end_point = prog->instrs.size;
((instr_t*)prog->instrs.data[cond_point])->param
= end_point;
for (size_t i=0; i<info->to_end.size; i++)
{
int addr = (size_t)info->to_end.data[i];
instr_t* instr = prog->instrs.data[addr];
instr->param = end_point;
}
info = vec_pop(&self->loop_infos);
vec_free(&info->to_end);
free(info);
} break;
case NODE_IF: {
vec_t to_end;
vec_init(&to_end);
compiler_compile_if(self, node, prog, &to_end);
size_t end_point = prog->instrs.size;
for (size_t i=0; i<to_end.size; i++)
{
int const* addr = to_end.data[i];
((instr_t*) prog->instrs.data[*addr])
->param = end_point;
}
vec_free_elements(&to_end, NULL);
vec_free(&to_end);
} break;
case NODE_BLOCK: { case NODE_BLOCK: {
sym_open_scope(sym); sym_open_scope(sym);
for (size_t i=0; i<node->children.size; i++) for (size_t i=0; i<node->children.size; i++)
{ {
compiler_compile( compiler_compile(
self, self,
node->children.data[i], node->children.data[i],
prog prog
); );
} }
@ -261,18 +90,17 @@ void compiler_compile(compiler_t* self,
prog_add_instr(prog, OP_ASTORE, indexes_count); prog_add_instr(prog, OP_ASTORE, indexes_count);
} else { } else {
compiler_compile(self, expr, prog); compiler_compile(self, expr, prog);
sym_entry_t* entry = sym_try_get_value(
sym,
target->value
);
int status = int status =
sym_try_assign( sym_try_assign(
sym, sym,
target->value, self->loc_counter target->value, self->loc_counter
); );
sym_entry_t* entry = sym_try_get_value(
sym,
target->value
);
assert(entry); assert(entry);
if (entry->is_const) { if (entry->is_const) {
@ -289,11 +117,9 @@ void compiler_compile(compiler_t* self,
return; return;
} }
prog_add_instr( prog_add_instr(prog, OP_LOCAL_STORE, self->loc_counter);
prog,
OP_LOCAL_STORE, self->loc_counter++;
entry->id
);
} }
} break; } break;
@ -318,7 +144,7 @@ void compiler_compile(compiler_t* self,
case NODE_IDENT: { case NODE_IDENT: {
char const* name = node->value; char const* name = node->value;
sym_entry_t const* entry = sym_try_get_value( sym_entry_t const* entry = sym_try_get_value(
sym, sym,
name name
); );
@ -328,7 +154,7 @@ void compiler_compile(compiler_t* self,
return; return;
} }
prog_add_instr(prog, OP_LOCAL_LOAD, entry->id); prog_add_instr(prog, OP_LOCAL_LOAD, entry->local_addr);
} break; } break;
case NODE_ARRAY: { case NODE_ARRAY: {
@ -599,42 +425,3 @@ void compiler_compile_and(compiler_t* self,
vec_free(&to_false); vec_free(&to_false);
} }
void compiler_compile_if(compiler_t* self,
node_t* node,
prog_t* prog,
vec_t* to_end)
{
assert(self); assert(node); assert(prog);
if (node->kind != NODE_IF)
{
compiler_compile(self, node, prog);
return;
}
node_t* cond = node->children.data[0];
node_t* block = node->children.data[1];
node_t* next = node->children.size == 3 ?
node->children.data[2] :
NULL;
compiler_compile_if(self, cond, prog, to_end);
int cond_point = prog_add_instr(prog, OP_BRF, 0);
compiler_compile_if(self, block, prog, to_end);
int end_point = prog_add_instr(prog, OP_BR, 0); // to end
int* addr = malloc(sizeof(int));
*addr = end_point;
vec_push(to_end, (void*) addr);
int next_pos = prog->instrs.size;
((instr_t*) prog->instrs.data[cond_point])->param
= next_pos;
if (next)
{
compiler_compile_if(self, next, prog, to_end);
}
}

View File

@ -8,16 +8,10 @@
#include "err.h" #include "err.h"
#include "module.h" #include "module.h"
typedef struct {
int start_point;
vec_t to_end;
} loop_info_t;
typedef struct { typedef struct {
module_t* module; module_t* module;
err_t err; err_t err;
int loc_counter; int loc_counter;
vec_t loop_infos;
} compiler_t; } compiler_t;
void compiler_init(compiler_t* self, module_t* module); void compiler_init(compiler_t* self, module_t* module);
@ -34,9 +28,4 @@ void compiler_compile_or(compiler_t* self,
void compiler_compile_and(compiler_t* self, void compiler_compile_and(compiler_t* self,
node_t* node, node_t* node,
prog_t* prog); prog_t* prog);
void compiler_compile_if(compiler_t* self,
node_t* node,
prog_t* prog,
vec_t* to_end);
#endif #endif

View File

@ -130,31 +130,6 @@ void exec_instr(exec_t* self,
self->pc++; self->pc++;
} break; } break;
case OP_LEN: {
CCM ccm_value = ccm_pop(ccm);
value_t* value = ccm_to_value(ccm, ccm_value);
CCM ccm_res = 0;
if (value->type == TYPE_ARRAY)
{
ccm_res = ccm_to_num(
ccm,
value->data.array->size,
value->line
);
}
else if (value->type == TYPE_STR)
{
ccm_res = ccm_to_num(
ccm,
strlen(value->data.str),
value->line
);
}
ccm_push(ccm, ccm_res);
self->pc++;
} break;
case OP_INDEX: { case OP_INDEX: {
CCM ccm_target = ccm_pop(ccm); CCM ccm_target = ccm_pop(ccm);
@ -194,7 +169,7 @@ void exec_instr(exec_t* self,
return; return;
} }
char const buf[2] = {target[idx], '\0'}; char buf[2] = {target[idx], '\0'};
ccm_push(ccm, ccm_to_str(ccm, buf, line)); ccm_push(ccm, ccm_to_str(ccm, buf, line));
} }
else if (ccm_is_tuple(ccm, ccm_target) else if (ccm_is_tuple(ccm, ccm_target)

View File

@ -171,12 +171,6 @@ node_t* lexer_try_new_next(lexer_t* self)
} }
} }
CCM_KEYWORD("break", NODE_BREAK, 0);
CCM_KEYWORD("continue", NODE_CONTINUE, 0);
CCM_KEYWORD("for", NODE_FOR, 0);
CCM_KEYWORD("while", NODE_WHILE, 0);
CCM_KEYWORD("if", NODE_IF, 0);
CCM_KEYWORD("else", NODE_ELSE, 0);
CCM_KEYWORD("begin", NODE_BEGIN, 0); CCM_KEYWORD("begin", NODE_BEGIN, 0);
CCM_KEYWORD("end", NODE_END, 0); CCM_KEYWORD("end", NODE_END, 0);
CCM_KEYWORD("var", NODE_VAR, 0); CCM_KEYWORD("var", NODE_VAR, 0);
@ -451,13 +445,7 @@ node_t* lexer_try_new_str(lexer_t* self)
cursor++; cursor++;
self->cursor = cursor; self->cursor = cursor;
node_t* node = malloc(sizeof(node_t)); node_t* node = malloc(sizeof(node_t));
node_init(node, NODE_STR, value.value, self->line);
node_init(
node,
NODE_STR,
value.size == 0 ? "" : value.value,
self->line
);
str_free(&value); str_free(&value);

View File

@ -17,7 +17,7 @@ void module_init(module_t* self)
void module_free(module_t* self) void module_free(module_t* self)
{ {
assert(self); assert(self);
sym_free(&self->sym); sym_free(&self->sym);
if (self->source) if (self->source)
@ -68,7 +68,7 @@ int module_load(module_t* self, char const* path)
compiler_t compiler; compiler_t compiler;
compiler_init(&compiler, self); compiler_init(&compiler, self);
compiler_compile(&compiler, ast, &self->prog); compiler_compile(&compiler, ast, &self->prog);
if (!err_is_ok(&compiler.err)) if (!err_is_ok(&compiler.err))
{ {
err_print_stack_trace(&compiler.err); err_print_stack_trace(&compiler.err);

View File

@ -16,9 +16,7 @@ G(NODE_STR), G(NODE_LT), G(NODE_LE), G(NODE_GT), \
G(NODE_GE), G(NODE_EQ), G(NODE_NE), G(NODE_ARRAY), \ G(NODE_GE), G(NODE_EQ), G(NODE_NE), G(NODE_ARRAY), \
G(NODE_VAR), G(NODE_IDENT), G(NODE_ASSIGN), \ G(NODE_VAR), G(NODE_IDENT), G(NODE_ASSIGN), \
G(NODE_VARDECL), G(NODE_CONST), G(NODE_CONSTDECL), \ G(NODE_VARDECL), G(NODE_CONST), G(NODE_CONSTDECL), \
G(NODE_BEGIN), G(NODE_BLOCK), G(NODE_END), G(NODE_IF), \ G(NODE_BEGIN), G(NODE_BLOCK), G(NODE_END)
G(NODE_ELSE), G(NODE_WHILE), G(NODE_FOR), G(NODE_BREAK), \
G(NODE_CONTINUE)
CCM_ENUM_H(NodeKind, NODE_KIND); CCM_ENUM_H(NodeKind, NODE_KIND);

View File

@ -82,17 +82,6 @@ node_t* parser_try_new_rule(parser_t* self, rule_t rule)
return (void*) NULL; return (void*) NULL;
} }
int parser_consume(parser_t* self, NodeKind kind)
{
if (!lexer_peek_kind(self->lexer, kind, 0))
{
return 0;
}
lexer_consume_next(self->lexer, kind);
return 1;
}
int parser_ensure(parser_t* self, node_t* node, NodeKind kind) int parser_ensure(parser_t* self, node_t* node, NodeKind kind)
{ {
assert(self); assert(self);
@ -163,167 +152,12 @@ node_t* parser_try_new_expr(parser_t* self)
return CCM_TRY(parser_try_new_begin); return CCM_TRY(parser_try_new_begin);
} }
if (lexer_peek_kind(self->lexer, NODE_WHILE, 0))
{
return CCM_TRY(parser_try_new_while);
}
if (lexer_peek_kind(self->lexer, NODE_FOR, 0))
{
return CCM_TRY(parser_try_new_for);
}
if (lexer_peek_kind(self->lexer, NODE_CONTINUE, 0)
|| lexer_peek_kind(self->lexer, NODE_BREAK, 0))
{
return lexer_try_new_next(self->lexer);
}
if (lexer_peek_kind(self->lexer, NODE_IF, 0))
{
node_t* node = CCM_TRY(parser_try_new_if);
if (!node) { return NULL; }
lexer_consume_next(self->lexer, NODE_END);
return node;
}
node_t* assign = CCM_TRY(parser_try_new_assign); node_t* assign = CCM_TRY(parser_try_new_assign);
if (assign) { return assign; } if (assign) { return assign; }
return CCM_TRY(parser_try_new_or); return CCM_TRY(parser_try_new_or);
} }
node_t* parser_try_new_while(parser_t* self)
{
assert(self);
if (!parser_consume(self, NODE_WHILE))
{
return NULL;
}
node_t* expr = CCM_TRY(parser_try_new_expr);
if (!expr) { return NULL; }
node_t* block = CCM_TRY(parser_try_new_block);
if (!block || !parser_consume(self, NODE_END))
{
node_free(expr); free(expr);
return NULL;
}
node_t* node = malloc(sizeof(node_t));
node_init(node, NODE_WHILE, "", expr->line);
node_push_new_child(node, expr);
node_push_new_child(node, block);
return node;
}
node_t* parser_try_new_for(parser_t* self)
{
assert(self);
if (!parser_consume(self, NODE_FOR))
{
return NULL;
}
node_t* ident = NULL;
if (lexer_peek_kind(self->lexer, NODE_IDENT, 0))
{
ident = lexer_try_new_next(self->lexer);
}
if (!ident) { return NULL; }
if (!parser_consume(self, NODE_IN))
{
node_free(ident); free(ident);
return NULL;
}
node_t* target = CCM_TRY(parser_try_new_expr);
if (!target)
{
node_free(ident); free(ident);
return NULL;
}
node_t* block = CCM_TRY(parser_try_new_block);
if (!block || !parser_consume(self, NODE_END))
{
node_free(ident); free(ident);
return NULL;
}
node_t* node = malloc(sizeof(node_t));
node_init(node, NODE_FOR, "", ident->line);
node_push_new_child(node, ident);
node_push_new_child(node, target);
node_push_new_child(node, block);
return node;
}
node_t* parser_try_new_if(parser_t* self)
{
assert(self);
if (!parser_consume(self, NODE_IF))
{
return NULL;
}
node_t* cond = CCM_TRY(parser_try_new_expr);
if (!cond) { return NULL; }
node_t* block = CCM_TRY(parser_try_new_block);
if (!block)
{
node_free(cond); free(cond);
return NULL;
}
node_t* node = malloc(sizeof(node_t));
node_init(node, NODE_IF, "", cond->line);
node_push_new_child(node, cond);
node_push_new_child(node, block);
if (parser_consume(self, NODE_ELSE))
{
if (lexer_peek_kind(self->lexer, NODE_IF, 0))
{
node_t* next = CCM_TRY(parser_try_new_if);
if (!next)
{
node_free(cond); free(cond);
node_free(block); free(block);
node_free(node); free(node);
return NULL;
}
node_push_new_child(node, next);
}
else
{
node_t* next = CCM_TRY(parser_try_new_block);
if (!next)
{
node_free(cond); free(cond);
node_free(block); free(block);
node_free(node); free(node);
return NULL;
}
node_push_new_child(node, next);
}
}
return node;
}
node_t* parser_try_new_begin(parser_t* self) node_t* parser_try_new_begin(parser_t* self)
{ {
assert(self); assert(self);
@ -337,7 +171,7 @@ node_t* parser_try_new_begin(parser_t* self)
node_t* node = malloc(sizeof(node_t)); node_t* node = malloc(sizeof(node_t));
node_init(node, NODE_BEGIN, "", self->lexer->line); node_init(node, NODE_BEGIN, "", self->lexer->line);
node_t* block = CCM_TRY(parser_try_new_block); node_t* block = CCM_TRY(parser_try_new_block);
node_push_new_child(node, block); node_push_new_child(node, block);
@ -358,14 +192,14 @@ node_t* parser_try_new_block(parser_t* self)
node_t* node = malloc(sizeof(node_t)); node_t* node = malloc(sizeof(node_t));
node_init(node, NODE_BLOCK, "", self->lexer->line); node_init(node, NODE_BLOCK, "", self->lexer->line);
while (1) while (1)
{ {
node_t* expr = CCM_TRY(parser_try_new_expr); node_t* expr = CCM_TRY(parser_try_new_expr);
if (!expr) { break; } if (!expr) { break; }
node_push_new_child(node, expr); node_push_new_child(node, expr);
} }
return node; return node;
} }
@ -441,7 +275,7 @@ node_t* parser_try_new_decl(parser_t* self)
} }
node_t* node = malloc(sizeof(node_t)); node_t* node = malloc(sizeof(node_t));
node_init(node, is_const ? NODE_CONSTDECL : NODE_VARDECL, node_init(node, is_const ? NODE_CONSTDECL : NODE_VARDECL,
"", self->lexer->line); "", self->lexer->line);
node_push_new_child(node, ident); node_push_new_child(node, ident);
@ -847,7 +681,7 @@ node_t* parser_try_new_array(parser_t* self)
node_t* node = malloc(sizeof(node_t)); node_t* node = malloc(sizeof(node_t));
node_init(node, NODE_ARRAY, "", self->lexer->line); node_init(node, NODE_ARRAY, "", self->lexer->line);
if (!lexer_peek_kind(self->lexer, NODE_OSQUARE, 0)) if (!lexer_peek_kind(self->lexer, NODE_OSQUARE, 0))
{ {
node_free(node); free(node); node_free(node); free(node);
@ -894,7 +728,7 @@ node_t* parser_try_new_index(parser_t* self)
assert(self); assert(self);
node_t* target = NULL; node_t* target = NULL;
if (lexer_peek_kind(self->lexer, NODE_STR, 0) if (lexer_peek_kind(self->lexer, NODE_STR, 0)
|| lexer_peek_kind(self->lexer, NODE_IDENT, 0)) || lexer_peek_kind(self->lexer, NODE_IDENT, 0))
{ {

View File

@ -21,14 +21,10 @@ void parser_free(parser_t* self);
node_t* parser_try_new_parse(parser_t* self); node_t* parser_try_new_parse(parser_t* self);
node_t* parser_try_new_rule(parser_t* self, rule_t rule); node_t* parser_try_new_rule(parser_t* self, rule_t rule);
node_t* parser_try_new_rule_ll1(parser_t* self, rule_ll1_t rule, node_t* node); node_t* parser_try_new_rule_ll1(parser_t* self, rule_ll1_t rule, node_t* node);
int parser_consume(parser_t* self, NodeKind kind);
int parser_ensure(parser_t* self, node_t* node, NodeKind kind); int parser_ensure(parser_t* self, node_t* node, NodeKind kind);
node_t* parser_try_new_module(parser_t* self); node_t* parser_try_new_module(parser_t* self);
node_t* parser_try_new_expr(parser_t* self); node_t* parser_try_new_expr(parser_t* self);
node_t* parser_try_new_for(parser_t* self);
node_t* parser_try_new_while(parser_t* self);
node_t* parser_try_new_if(parser_t* self);
node_t* parser_try_new_begin(parser_t* self); node_t* parser_try_new_begin(parser_t* self);
node_t* parser_try_new_block(parser_t* self); node_t* parser_try_new_block(parser_t* self);
node_t* parser_try_new_assign(parser_t* self); node_t* parser_try_new_assign(parser_t* self);

View File

@ -60,11 +60,7 @@ void str_push(str_t* self, char c)
void str_push_cstr(str_t* self, char const* rhs) void str_push_cstr(str_t* self, char const* rhs)
{ {
assert(self); assert(self);
assert(rhs);
if (!rhs)
{
return;
}
for (size_t i=0; i<strlen(rhs); i++) for (size_t i=0; i<strlen(rhs); i++)
{ {

View File

@ -4,7 +4,6 @@ void sym_init(sym_t* self)
{ {
assert(self); assert(self);
self->env = NULL; self->env = NULL;
self->id_counter = 0;
} }
void sym_free(sym_t* self) void sym_free(sym_t* self)
@ -92,9 +91,7 @@ int sym_declare(sym_t* self,
entry->name = strdup(name); entry->name = strdup(name);
entry->local_addr = addr; entry->local_addr = addr;
entry->is_const = is_const; entry->is_const = is_const;
entry->id = self->id_counter;
vec_push(&self->env->entries, entry); vec_push(&self->env->entries, entry);
self->id_counter++;
return 1; return 1;
} }

View File

@ -7,7 +7,6 @@
typedef struct { typedef struct {
char* name; char* name;
int id;
int local_addr; int local_addr;
int is_const; int is_const;
} sym_entry_t; } sym_entry_t;
@ -19,7 +18,6 @@ typedef struct env {
typedef struct { typedef struct {
env_t* env; env_t* env;
int id_counter;
} sym_t; } sym_t;
void sym_init(sym_t* self); void sym_init(sym_t* self);

View File

@ -28,6 +28,8 @@ void value_init_boolean(value_t* self, int boolean, int line)
void value_init_str(value_t* self, char const* value, int line) void value_init_str(value_t* self, char const* value, int line)
{ {
assert(self); assert(self);
assert(value);
self->data.str = strdup(value); self->data.str = strdup(value);
self->type = TYPE_STR; self->type = TYPE_STR;
self->line = line; self->line = line;
@ -113,6 +115,7 @@ void value_free(value_t* self)
{ {
if (self->type == TYPE_ARRAY) if (self->type == TYPE_ARRAY)
{ {
//vec_free_elements(self->data.array, (void*) value_free);
vec_free(self->data.array); vec_free(self->data.array);
free(self->data.array); free(self->data.array);
} }
@ -124,7 +127,7 @@ void value_free(value_t* self)
free(self->data.tuple); free(self->data.tuple);
} }
if (self->type == TYPE_STR && self->data.str) if (self->type == TYPE_STR)
{ {
free(self->data.str); free(self->data.str);
} }

View File

@ -1,77 +0,0 @@
# IF
# ==
var a = 0
if true
a = 1
end
assert_eq (1, a)
if false
a = 2
end
assert_eq (1, a)
# IF THEN ELSE
# ============
var b = 0
b = 0
if true
b = 1
else if true
b = 2
else if true
b = 3
else
b = 4
end
assert_eq (1, b)
b = 0
if false
b = 1
else if true
b = 2
else if true
b = 3
else
b = 4
end
assert_eq (2, b)
b = 0
if false
b = 1
else if false
b = 2
else if true
b = 3
else
b = 4
end
assert_eq (3, b)
b = 0
if false
b = 1
else if false
b = 2
else if false
b = 3
else
b = 4
end
assert_eq (4, b)

View File

@ -1,107 +0,0 @@
# WHILE LOOP
# ==========
var a = 0
while a < 100
a = a + 1
end
assert_eq (100, a)
var b = 0
var c = 0
var d = 0
while b < 6
c = 0
while c < 7
d = d + 1
c = c + 1
end
b = b + 1
end
assert_eq (d, 42)
var e = 0
var f = 0
while e < 128
e = e + 1
if e % 2 == 0
continue
end
f = f + 1
end
assert_eq (64, f)
var g = 0
var h = 0
var i = 0
while g < 100
h = 0
if g >= 7
break
end
while h < 100
if h >= 6
break
end
h = h + 1
if h % 2 == 0
continue
end
i = i + 1
end
g = g + 1
end
assert_eq (21, i)
# FOR LOOP
# ========
var j = 0
for k in [1, 2, 3]
j = j + k
end
assert_eq (6, j)
var l = 0
var m = [7, 3, 1]
for n in m
l = l + n
end
assert_eq (11, l)
var o = 0
for p in [1, 2, 3, 4, 5, 6, 7]
if p > 5
break
end
if p % 2 == 0
continue
end
o = o + p
end
assert_eq (9, o)
var q = ""
for r in "hello"
q = r + q
end
assert_eq ("olleh", q)