diff --git a/arch/linux/main.c b/arch/linux/main.c index 8bfc51f..9e2ba1c 100644 --- a/arch/linux/main.c +++ b/arch/linux/main.c @@ -72,7 +72,7 @@ main(int argc, char **argv) List *memory = List_init(&a); char *source = readFile(argv[2]); - compile(&a, code, memory, e, source); + compile(&a, code, memory, &e, source); Node *curr = code->head; while (curr) { diff --git a/arch/web/main.c b/arch/web/main.c index ca8993c..1c131da 100644 --- a/arch/web/main.c +++ b/arch/web/main.c @@ -28,6 +28,9 @@ static void list2buffer(List *list, char *buffer, size_t *offset) { EMSCRIPTEN_KEEPALIVE char *undar_compile(int emitter_type, char *source) { + u8 tape[MEM_SIZE]; + Arena a = {tape, 0, MEM_SIZE}; + Emitter e; if (emitter_type == 0) { e = rer_emitter(); @@ -37,13 +40,10 @@ char *undar_compile(int emitter_type, char *source) { return NULL; } - u8 tape[MEM_SIZE]; - Arena a = {tape, 0, MEM_SIZE}; - List *code = List_init(&a); List *memory = List_init(&a); - compile(&a, code, memory, e, source); + compile(&a, code, memory, &e, source); size_t code_size = List_size(code); size_t mem_size = List_size(memory); diff --git a/compiler.c b/compiler.c index 5c023b2..331903d 100644 --- a/compiler.c +++ b/compiler.c @@ -5,8 +5,8 @@ #include "libc.h" #include "list.h" -Emitter emitter = {0}; -Parser parser = {0}; +Parser *parser; +Emitter *emitter; Arena *arena; List *code; List *memory; @@ -22,8 +22,8 @@ scopes_init(void) child.symbols = List_init(arena); child.locals_offset = 0; - current = (Scope *)List_push(arena, parser.scopes, &child, sizeof(Scope)); - parser.current_scope = current; + current = (Scope *)List_push(arena, parser->scopes, &child, sizeof(Scope)); + parser->current_scope = current; } Scope * @@ -32,32 +32,32 @@ scope_new(void) Scope *current; Scope child = {0}; child.symbols = List_init(arena); - child.parent = parser.current_scope; + child.parent = parser->current_scope; child.locals_offset = 0; - current = (Scope *)List_push(arena, parser.scopes, &child, sizeof(Scope)); - parser.current_scope = current; - parser.scope_idx++; - parser.depth++; + current = (Scope *)List_push(arena, parser->scopes, &child, sizeof(Scope)); + parser->current_scope = current; + parser->scope_idx++; + parser->depth++; return current; } void scope_pop(void) { - if(parser.current_scope) { - parser.current_scope = parser.current_scope->parent; - parser.depth--; + if(parser->current_scope) { + parser->current_scope = parser->current_scope->parent; + parser->depth--; } } void scope_push(void) { - Scope *scope = List_get(parser.scopes, parser.scope_idx); - parser.current_scope = scope; - parser.depth++; - parser.scope_idx++; + Scope *scope = List_get(parser->scopes, parser->scope_idx); + parser->current_scope = scope; + parser->depth++; + parser->scope_idx++; } Symbol * @@ -80,12 +80,12 @@ Symbol * scope_add_symbol(const char *name, u32 name_length, SymbolType type, u32 size) { Symbol new_sym = {0}; - Symbol *sym = scope_get_symbol(parser.current_scope, name, name_length); + Symbol *sym = scope_get_symbol(parser->current_scope, name, name_length); if(sym != nil) { - if(parser.pass) + if(parser->pass) return sym; else - emitter.error("duplicate found", 14, parser.previous.line); + emitter->error("duplicate found", 14, parser->previous.line); } scpy(new_sym.name, name, name_length); @@ -93,9 +93,9 @@ scope_add_symbol(const char *name, u32 name_length, SymbolType type, u32 size) new_sym.type = type; new_sym.secondary_type = SYMBOL_VOID; new_sym.size = size; - new_sym.ref = parser.current_scope->locals_offset; - new_sym.scope = parser.scope_idx; - parser.current_scope->locals_offset += size; + new_sym.ref = parser->current_scope->locals_offset; + new_sym.scope = parser->scope_idx; + parser->current_scope->locals_offset += size; if(type == SYMBOL_PLEX || type == SYMBOL_METHOD || type == SYMBOL_TRAIT || type == SYMBOL_FUNCTION) { new_sym.args = List_init(arena); @@ -104,21 +104,21 @@ scope_add_symbol(const char *name, u32 name_length, SymbolType type, u32 size) if(type == SYMBOL_PLEX || type == SYMBOL_METHOD || type == SYMBOL_TRAIT) new_sym.fields = List_init(arena); - return List_push(arena, parser.current_scope->symbols, &new_sym, + return List_push(arena, parser->current_scope->symbols, &new_sym, sizeof(Symbol)); } bool is_global(void) { - return parser.current_scope != nil && parser.current_scope->parent == nil; + return parser->current_scope != nil && parser->current_scope->parent == nil; } bool is_type(void) { - return parser.previous.type >= TOKEN_TYPE_I8 && - parser.previous.type <= TOKEN_TYPE_PTR; + return parser->previous.type >= TOKEN_TYPE_I8 && + parser->previous.type <= TOKEN_TYPE_PTR; } SymbolType @@ -158,11 +158,11 @@ token_type_to_sym_type(TokenType t) bool advance(void) { - parser.previous = parser.current; + parser->previous = parser->current; for(;;) { - parser.current = next_token(); - if(parser.current.type != TOKEN_ERROR) return true; + parser->current = next_token(); + if(parser->current.type != TOKEN_ERROR) return true; return false; } @@ -170,7 +170,7 @@ advance(void) bool check(TokenType type) { - return parser.current.type == type; + return parser->current.type == type; } bool @@ -207,8 +207,8 @@ void expect(TokenType type) { if(!consume(type)) { - emitter.error(parser.previous.start, parser.previous.length, - parser.previous.line); + emitter->error(parser->previous.start, parser->previous.length, + parser->previous.line); } } @@ -230,7 +230,7 @@ define_function(void) Symbol *fn; u32 size = 0; advance(); - fn = scope_add_symbol(parser.previous.start, parser.previous.length, + fn = scope_add_symbol(parser->previous.start, parser->previous.length, SYMBOL_FUNCTION, 0); /* need to push scope early because the variables need to be a part of the fn @@ -250,20 +250,20 @@ define_function(void) if(is_type()) { /* get return slot */ - fn->secondary_type = token_type_to_sym_type(parser.previous.type); + fn->secondary_type = token_type_to_sym_type(parser->previous.type); /* now parse the fn body */ } expect(TOKEN_LBRACE); /* get the size of all the locals for the function in the body */ - while(parser.depth > 0) { + while(parser->depth > 0) { if(match(TOKEN_LBRACE)) { scope_new(); continue; } else if(match(TOKEN_RBRACE)) { scope_pop(); continue; - } else if(is_type() && parser.current.type == TOKEN_IDENTIFIER) + } else if(is_type() && parser->current.type == TOKEN_IDENTIFIER) size += variable_declaration(nil); advance(); } @@ -292,7 +292,7 @@ calculate_strides(List *dims, List *strides) if (num){ current_stride *= (*num); } else { - emitter.error("Tried to get a dimension that did not exist", 43, parser.previous.line); + emitter->error("Tried to get a dimension that did not exist", 43, parser->previous.line); } } } @@ -301,7 +301,7 @@ void define_array(void) { i32 size = 0, n = 0, flat_array_length = 1; - TokenType tt = parser.previous.type; + TokenType tt = parser->previous.type; SymbolType st = token_type_to_sym_type(tt); Symbol *array; @@ -310,8 +310,8 @@ define_array(void) advance(); while(!match(TOKEN_RBRACKET)) { - if(parser.current.type == TOKEN_LITERAL_INT) { - n = ston(parser.current.start, parser.current.length); + if(parser->current.type == TOKEN_LITERAL_INT) { + n = ston(parser->current.start, parser->current.length); flat_array_length *= n; List_push(arena, dims, &n, sizeof(u32)); } @@ -322,9 +322,9 @@ define_array(void) } } - size = emitter.get_size(st) * flat_array_length; + size = emitter->get_size(st) * flat_array_length; - array = scope_add_symbol(parser.current.start, parser.current.length, + array = scope_add_symbol(parser->current.start, parser->current.length, SYMBOL_ARRAY, size); array->secondary_type = st; calculate_strides(dims, strides); @@ -351,8 +351,8 @@ build_symbol_table(char *source) define_plex(); } else if(match(TOKEN_KEYWORD_TRAIT)) { define_trait(); - } else if (parser.current.type >= TOKEN_TYPE_I8 && - parser.current.type <= TOKEN_TYPE_PTR) { + } else if (parser->current.type >= TOKEN_TYPE_I8 && + parser->current.type <= TOKEN_TYPE_PTR) { advance(); if (check(TOKEN_LBRACKET)) { define_array(); @@ -375,22 +375,22 @@ u32 variable_declaration(Symbol *def) { i32 size = 0; - TokenType tt = parser.previous.type; + TokenType tt = parser->previous.type; SymbolType st = token_type_to_sym_type(tt); Symbol *variable; List *array_literal; - if (parser.current.type == TOKEN_LBRACKET) { + if (parser->current.type == TOKEN_LBRACKET) { while(!check(TOKEN_RBRACKET)) { advance(); } advance(); - variable = scope_get_symbol(parser.current_scope, - parser.current.start, - parser.current.length); + variable = scope_get_symbol(parser->current_scope, + parser->current.start, + parser->current.length); if (!variable) { - emitter.error("cannot find array symbol", 24, parser.current.line); + emitter->error("cannot find array symbol", 24, parser->current.line); return 0; } advance(); @@ -401,119 +401,119 @@ variable_declaration(Symbol *def) while (!match(TOKEN_RBRACKET)) { StrBuf_append_exactly(arena, array_literal, - (char*)parser.current.start, - parser.current.length); + (char*)parser->current.start, + parser->current.length); advance(); if(match(TOKEN_RBRACKET)) break; expect(TOKEN_COMMA); } expect(TOKEN_SEMICOLON); - emitter.emit_array(arena, memory, variable, array_literal); + emitter->emit_array(arena, memory, variable, array_literal); } else { expect(TOKEN_SEMICOLON); - emitter.emit_array(arena, memory, variable, nil); - emitter.emit_zero_block(arena, memory, variable->size * emitter.get_size(variable->secondary_type)); + emitter->emit_array(arena, memory, variable, nil); + emitter->emit_zero_block(arena, memory, variable->size * emitter->get_size(variable->secondary_type)); } return variable->size; } if(st != SYMBOL_UNDEFINED) { - size = emitter.get_size(st); + size = emitter->get_size(st); - variable = scope_add_symbol(parser.current.start, parser.current.length, st, size); + variable = scope_add_symbol(parser->current.start, parser->current.length, st, size); - if(!def && (parser.pass == 0)) return size; + if(!def && (parser->pass == 0)) return size; if(def) { List_push(arena, def->args, variable, sizeof(Symbol)); } else { - emitter.emit_type(arena, code, variable, parser.depth); - parser.current_type = st; + emitter->emit_type(arena, code, variable, parser->depth); + parser->current_type = st; } } else { /* we need to look up the type */ - emitter.error("Not implemented", 16, parser.previous.line); + emitter->error("Not implemented", 16, parser->previous.line); } advance(); if(def && (check(TOKEN_COMMA) || check(TOKEN_RPAREN))) return size; if(def) - emitter.error(parser.previous.start, parser.previous.length, - parser.previous.line); - if(parser.pass == 0) return size; + emitter->error(parser->previous.start, parser->previous.length, + parser->previous.line); + if(parser->pass == 0) return size; if(match(TOKEN_EQ)) { - emitter.emit_set_value(arena, code); + emitter->emit_set_value(arena, code); expression(); - emitter.emit_constant(arena, code, variable, parser.depth); + emitter->emit_constant(arena, code, variable, parser->depth); } consume(TOKEN_SEMICOLON); - emitter.emit_end_statement(arena, code); - parser.current_type = SYMBOL_UNDEFINED; + emitter->emit_end_statement(arena, code); + parser->current_type = SYMBOL_UNDEFINED; return size; } void binary(void) { - TokenType operatorType = parser.previous.type; + TokenType operatorType = parser->previous.type; ParseRule *rule = get_rule(operatorType); parse_precedence((Precedence)(rule->precedence + 1)); switch(operatorType) { case TOKEN_BANG_EQ: - emitter.emit_ne(arena, code); + emitter->emit_ne(arena, code); break; case TOKEN_EQ_EQ: - emitter.emit_eq(arena, code); + emitter->emit_eq(arena, code); break; case TOKEN_GT: - emitter.emit_gt(arena, code); + emitter->emit_gt(arena, code); break; case TOKEN_GTE: - emitter.emit_ge(arena, code); + emitter->emit_ge(arena, code); break; case TOKEN_LT: - emitter.emit_lt(arena, code); + emitter->emit_lt(arena, code); break; case TOKEN_LTE: - emitter.emit_le(arena, code); + emitter->emit_le(arena, code); break; case TOKEN_PLUS: - emitter.emit_add(arena, code); + emitter->emit_add(arena, code); break; case TOKEN_MINUS: - emitter.emit_sub(arena, code); + emitter->emit_sub(arena, code); break; case TOKEN_STAR: - emitter.emit_mul(arena, code); + emitter->emit_mul(arena, code); break; case TOKEN_SLASH: - emitter.emit_div(arena, code); + emitter->emit_div(arena, code); break; case TOKEN_OPERATOR_AND: - emitter.emit_and(arena, code); + emitter->emit_and(arena, code); break; case TOKEN_OPERATOR_OR: - emitter.emit_or(arena, code); + emitter->emit_or(arena, code); break; case TOKEN_OPERATOR_XOR: - emitter.emit_xor(arena, code); + emitter->emit_xor(arena, code); break; case TOKEN_OPERATOR_MOD: - emitter.emit_mod(arena, code); + emitter->emit_mod(arena, code); break; case TOKEN_SLL: - emitter.emit_sll(arena, code); + emitter->emit_sll(arena, code); break; case TOKEN_SRL: - emitter.emit_srl(arena, code); + emitter->emit_srl(arena, code); break; default: return; @@ -523,15 +523,15 @@ binary(void) void literal(void) { - switch(parser.previous.type) { + switch(parser->previous.type) { case TOKEN_KEYWORD_FALSE: - emitter.emit_false(arena, code); + emitter->emit_false(arena, code); break; case TOKEN_KEYWORD_TRUE: - emitter.emit_true(arena, code); + emitter->emit_true(arena, code); break; case TOKEN_KEYWORD_NIL: - emitter.emit_nil(arena, code); + emitter->emit_nil(arena, code); break; default: return; @@ -547,83 +547,83 @@ expression(void) void variable(void) { - Symbol *sym = scope_get_symbol(parser.current_scope, parser.previous.start, - parser.previous.length); + Symbol *sym = scope_get_symbol(parser->current_scope, parser->previous.start, + parser->previous.length); if(sym == nil) { - emitter.error(parser.previous.start, parser.previous.length, - parser.previous.line); + emitter->error(parser->previous.start, parser->previous.length, + parser->previous.line); } if(sym->type == SYMBOL_FUNCTION) { - parser.call_fn = sym; + parser->call_fn = sym; return; } if (sym->type == SYMBOL_ARRAY) { - emitter.emit_deref_prolog(arena, code, sym); + emitter->emit_deref_prolog(arena, code, sym); if (match(TOKEN_LBRACKET)) { expression(); - emitter.emit_address(arena, code, emitter.get_size(sym->secondary_type)); - emitter.emit_mul(arena, code); - emitter.emit_add(arena, code); + emitter->emit_address(arena, code, emitter->get_size(sym->secondary_type)); + emitter->emit_mul(arena, code); + emitter->emit_add(arena, code); /* add offset of "length"*/ - emitter.emit_nat(arena, code, "2", 1); - emitter.emit_add(arena, code); - emitter.emit_deref(arena, code); + emitter->emit_nat(arena, code, "2", 1); + emitter->emit_add(arena, code); + emitter->emit_deref(arena, code); while (!match(TOKEN_RBRACKET)) { } } else if (match(TOKEN_DOT)) { - if (sleq("length", parser.current.start, parser.current.length)) { - emitter.emit_deref(arena, code); + if (sleq("length", parser->current.start, parser->current.length)) { + emitter->emit_deref(arena, code); } else { - emitter.error("arrays currently can only get their length, don't do anything fancy yet...", 75, parser.current.line); + emitter->error("arrays currently can only get their length, don't do anything fancy yet...", 75, parser->current.line); } advance(); } return; } - parser.current_type = sym->type; + parser->current_type = sym->type; if(match(TOKEN_EQ)) { expression(); - emitter.emit_set_variable(arena, code, sym, sym->scope); + emitter->emit_set_variable(arena, code, sym, sym->scope); } else { - emitter.emit_variable(arena, code, sym, sym->scope); + emitter->emit_variable(arena, code, sym, sym->scope); } } void cast_type(void) { - SymbolType st = parser.current_type; + SymbolType st = parser->current_type; TokenType cast_type; - if(!(parser.current.type >= TOKEN_TYPE_I8 && - parser.current.type <= TOKEN_TYPE_PTR)) { - emitter.error("Expect type name after 'as'.", 26, parser.current.line); + if(!(parser->current.type >= TOKEN_TYPE_I8 && + parser->current.type <= TOKEN_TYPE_PTR)) { + emitter->error("Expect type name after 'as'.", 26, parser->current.line); return; } - cast_type = parser.current.type; + cast_type = parser->current.type; advance(); switch(st) { case SYMBOL_INT: { switch(cast_type) { case TOKEN_TYPE_NAT: { - emitter.emit_cast_int_to_nat(arena, code); + emitter->emit_cast_int_to_nat(arena, code); break; } case TOKEN_TYPE_REAL: { - emitter.emit_cast_int_to_real(arena, code); + emitter->emit_cast_int_to_real(arena, code); break; } case TOKEN_TYPE_STR: { - emitter.emit_cast_int_to_str(arena, code); + emitter->emit_cast_int_to_str(arena, code); break; } default: - emitter.error("Not castable to int", 19, parser.previous.line); + emitter->error("Not castable to int", 19, parser->previous.line); } break; @@ -631,69 +631,69 @@ cast_type(void) case SYMBOL_NAT: { switch(cast_type) { case TOKEN_TYPE_INT: { - emitter.emit_cast_nat_to_int(arena, code); + emitter->emit_cast_nat_to_int(arena, code); break; } case TOKEN_TYPE_REAL: { - emitter.emit_cast_nat_to_real(arena, code); + emitter->emit_cast_nat_to_real(arena, code); break; } case TOKEN_TYPE_STR: { - emitter.emit_cast_nat_to_str(arena, code); + emitter->emit_cast_nat_to_str(arena, code); break; } default: - emitter.error("Not castable to nat", 19, parser.previous.line); + emitter->error("Not castable to nat", 19, parser->previous.line); } break; } case SYMBOL_REAL: { switch(cast_type) { case TOKEN_TYPE_NAT: { - emitter.emit_cast_real_to_nat(arena, code); + emitter->emit_cast_real_to_nat(arena, code); break; } case TOKEN_TYPE_INT: { - emitter.emit_cast_real_to_int(arena, code); + emitter->emit_cast_real_to_int(arena, code); break; } case TOKEN_TYPE_STR: { - emitter.emit_cast_real_to_str(arena, code); + emitter->emit_cast_real_to_str(arena, code); break; } default: - emitter.error("Not castable to real", 20, parser.previous.line); + emitter->error("Not castable to real", 20, parser->previous.line); } break; } case SYMBOL_STR: { switch(cast_type) { case TOKEN_TYPE_NAT: { - emitter.emit_cast_str_to_nat(arena, code); + emitter->emit_cast_str_to_nat(arena, code); break; } case TOKEN_TYPE_REAL: { - emitter.emit_cast_str_to_real(arena, code); + emitter->emit_cast_str_to_real(arena, code); break; } case TOKEN_TYPE_INT: { - emitter.emit_cast_str_to_int(arena, code); + emitter->emit_cast_str_to_int(arena, code); break; } default: - emitter.error("Not castable to str", 19, parser.previous.line); + emitter->error("Not castable to str", 19, parser->previous.line); } break; } default: - emitter.error("Type cast not implemented for this type (oops)", 46, parser.previous.line); + emitter->error("Type cast not implemented for this type (oops)", 46, parser->previous.line); } } void declaration(void) { - if(is_type() && (parser.current.type == TOKEN_IDENTIFIER || parser.current.type == TOKEN_LBRACKET) ) + if(is_type() && (parser->current.type == TOKEN_IDENTIFIER || parser->current.type == TOKEN_LBRACKET) ) variable_declaration(nil); else statement(); @@ -704,8 +704,8 @@ print_statement(void) { expression(); consume(TOKEN_SEMICOLON); - emitter.emit_print(arena, code); - emitter.emit_end_statement(arena, code); + emitter->emit_print(arena, code); + emitter->emit_end_statement(arena, code); } void @@ -714,29 +714,29 @@ if_statement(void) consume(TOKEN_LPAREN); expression(); consume(TOKEN_RPAREN); - emitter.emit_if(arena, code); + emitter->emit_if(arena, code); statement(); - emitter.emit_patch_if(arena, code, emitter.ifs); + emitter->emit_patch_if(arena, code, emitter->ifs); if(match(TOKEN_KEYWORD_ELSE)) { - emitter.else_if_depth++; + emitter->else_if_depth++; statement(); - emitter.else_if_depth--; + emitter->else_if_depth--; } - if(emitter.else_if_depth == 0) emitter.emit_patch_if_done(arena, code, emitter.ifs++); + if(emitter->else_if_depth == 0) emitter->emit_patch_if_done(arena, code, emitter->ifs++); } void while_statement(void) { - u32 this_while = emitter.loops++; - emitter.emit_while(arena, code, this_while); + u32 this_while = emitter->loops++; + emitter->emit_while(arena, code, this_while); consume(TOKEN_LPAREN); expression(); consume(TOKEN_RPAREN); - emitter.emit_while_postfix(arena, code); + emitter->emit_while_postfix(arena, code); statement(); - emitter.emit_patch_while(arena, code, this_while); + emitter->emit_patch_while(arena, code, this_while); } void @@ -750,15 +750,15 @@ block(void) void function(void) { - Symbol *sym = scope_get_symbol(parser.current_scope, parser.previous.start, - parser.previous.length); - emitter.emit_function(arena, code, sym); + Symbol *sym = scope_get_symbol(parser->current_scope, parser->previous.start, + parser->previous.length); + emitter->emit_function(arena, code, sym); scope_push(); while(!check(TOKEN_RPAREN)) advance(); consume(TOKEN_RPAREN); consume(TOKEN_LBRACE); block(); - emitter.emit_arena_fn_return(arena, code); + emitter->emit_arena_fn_return(arena, code); } void @@ -771,8 +771,8 @@ call(void) } consume(TOKEN_RPAREN); - emitter.emit_arena_fn_call(arena, code, parser.call_fn); - parser.current_type = parser.call_fn->secondary_type; + emitter->emit_arena_fn_call(arena, code, parser->call_fn); + parser->current_type = parser->call_fn->secondary_type; return; } @@ -780,11 +780,11 @@ void return_statement(void) { if(match(TOKEN_SEMICOLON)) { - emitter.emit_early_return(arena, code); + emitter->emit_early_return(arena, code); } else { expression(); consume(TOKEN_SEMICOLON); - emitter.emit_early_return(arena, code); + emitter->emit_early_return(arena, code); } } @@ -807,7 +807,7 @@ statement(void) } else if(match(TOKEN_KEYWORD_PRINT)) { print_statement(); } else if(match(TOKEN_KEYWORD_HALT)) { - emitter.emit_halt(arena, code); + emitter->emit_halt(arena, code); } else { expression(); } @@ -816,44 +816,44 @@ statement(void) void grouping(void) { - emitter.emit_open_paren(arena, code); + emitter->emit_open_paren(arena, code); expression(); - emitter.emit_close_paren(arena, code); + emitter->emit_close_paren(arena, code); consume(TOKEN_RPAREN); } void number(void) { - emitter.emit_int(arena, code, parser.previous.start, parser.previous.length); + emitter->emit_int(arena, code, parser->previous.start, parser->previous.length); } void string(void) { - emitter.emit_str(arena, code, parser.previous.start, parser.previous.length); + emitter->emit_str(arena, code, parser->previous.start, parser->previous.length); } void character(void) { - emitter.emit_char(arena, code, parser.previous.start, parser.previous.length); + emitter->emit_char(arena, code, parser->previous.start, parser->previous.length); } void unary(void) { - TokenType operatorType = parser.previous.type; + TokenType operatorType = parser->previous.type; parse_precedence(PREC_UNARY); switch(operatorType) { case TOKEN_MINUS: - emitter.emit_neg(arena, code); + emitter->emit_neg(arena, code); break; case TOKEN_BANG: - emitter.emit_not(arena, code); + emitter->emit_not(arena, code); break; default: return; @@ -863,7 +863,7 @@ unary(void) void read(void) { - emitter.emit_read(arena, code); + emitter->emit_read(arena, code); } void @@ -872,7 +872,7 @@ write(void) consume(TOKEN_EQ); advance(); variable(); - emitter.emit_write(arena, code); + emitter->emit_write(arena, code); } ParseRule rules[] = { @@ -971,14 +971,14 @@ parse_precedence(Precedence precedence) ParseFn infixRule; advance(); - prefixRule = get_rule(parser.previous.type)->prefix; + prefixRule = get_rule(parser->previous.type)->prefix; if(prefixRule == nil) return; prefixRule(); - while(precedence <= get_rule(parser.current.type)->precedence) { + while(precedence <= get_rule(parser->current.type)->precedence) { advance(); - infixRule = get_rule(parser.previous.type)->infix; + infixRule = get_rule(parser->previous.type)->infix; infixRule(); } } @@ -995,25 +995,27 @@ emit_program(char *source) init_lexer(source); advance(); - emitter.prolog(arena, code); + emitter->prolog(arena, code); while(!match(TOKEN_EOF)) declaration(); - emitter.epilogue(arena, code); + emitter->epilogue(arena, code); } bool -compile(Arena *a, List *c, List* m, Emitter e, char *source) +compile(Arena *a, List *c, List* m, Emitter *e, char *source) { + Parser p = {0}; arena = a; emitter = e; code = c; memory = m; - parser.scopes = List_init(arena); + parser = &p; + parser->scopes = List_init(arena); build_symbol_table(source); - parser.pass++; - parser.scope_idx = 0; + parser->pass++; + parser->scope_idx = 0; emit_program(source); return true; diff --git a/compiler.h b/compiler.h index 54945c2..2ea441e 100644 --- a/compiler.h +++ b/compiler.h @@ -51,6 +51,6 @@ struct parser_s { u8 pass; }; -bool compile(Arena *a, List *c, List *m, Emitter e, char *source); +bool compile(Arena *a, List *c, List *m, Emitter *e, char *source); #endif diff --git a/lexer.c b/lexer.c index 7af6a34..80c0dde 100644 --- a/lexer.c +++ b/lexer.c @@ -17,26 +17,26 @@ init_lexer(const char *source) lexer.line = 1; } -static bool -is_alpha(char c) +bool +lex_is_alpha(char c) { return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'; } -static bool -is_digit(char c) +bool +lex_is_digit(char c) { return c >= '0' && c <= '9'; } -static bool +bool is_at_end(void) { return *lexer.current == '\0'; } -static char -advance(void) +char +lex_advance(void) { lexer.current++; return lexer.current[-1]; @@ -48,15 +48,15 @@ peek(void) return *lexer.current; } -static char +char peek_next(void) { if(is_at_end()) return '\0'; return lexer.current[1]; } -static bool -match(char expected) +bool +lex_match(char expected) { if(is_at_end()) return false; if(*lexer.current != expected) return false; @@ -64,7 +64,7 @@ match(char expected) return true; } -static Token +Token make_token(TokenType type) { Token token; @@ -75,7 +75,7 @@ make_token(TokenType type) return token; } -static Token +Token error_token(const char *message) { Token token; @@ -86,7 +86,7 @@ error_token(const char *message) return token; } -static void +void skip_whitespace(void) { for(;;) { @@ -95,29 +95,29 @@ skip_whitespace(void) case ' ': case '\r': case '\t': - advance(); + lex_advance(); break; case '\n': lexer.line++; - advance(); + lex_advance(); break; case '/': if(peek_next() == '/') { /* Single-line comment: skip until newline or end of file */ - advance(); - while(peek() != '\n' && !is_at_end()) advance(); + lex_advance(); + while(peek() != '\n' && !is_at_end()) lex_advance(); } else if(peek_next() == '*') { /* Multi-line comment: skip until '* /' or end of file */ - advance(); - advance(); + lex_advance(); + lex_advance(); while(!is_at_end()) { if(peek() == '\n') lexer.line++; if(peek() == '*' && peek_next() == '/') { - advance(); - advance(); + lex_advance(); + lex_advance(); break; /* Exit loop, comment ended */ } - advance(); + lex_advance(); } } else { return; /* Not a comment, let tokenization handle it */ @@ -129,7 +129,7 @@ skip_whitespace(void) } } -static TokenType +TokenType check_keyword(i32 start, i32 length, const char *rest, TokenType type) { i32 s1 = lexer.current - lexer.start; @@ -139,7 +139,7 @@ check_keyword(i32 start, i32 length, const char *rest, TokenType type) return TOKEN_IDENTIFIER; } -static TokenType +TokenType identifierType(void) { switch(lexer.start[0]) { @@ -342,24 +342,24 @@ identifierType(void) return TOKEN_IDENTIFIER; } -static Token +Token identifier(void) { - while(is_alpha(peek()) || is_digit(peek())) advance(); + while(lex_is_alpha(peek()) || lex_is_digit(peek())) lex_advance(); return make_token(identifierType()); } -static Token -number(void) +Token +lex_number(void) { - while(is_digit(peek())) advance(); + while(lex_is_digit(peek())) lex_advance(); /* Look for a fractional part. */ - if(peek() == '.' && is_digit(peek_next())) { + if(peek() == '.' && lex_is_digit(peek_next())) { /* Consume the ".". */ - advance(); + lex_advance(); - while(is_digit(peek())) advance(); + while(lex_is_digit(peek())) lex_advance(); return make_token(TOKEN_LITERAL_REAL); } @@ -367,33 +367,33 @@ number(void) return make_token(TOKEN_LITERAL_INT); } -static Token -string(void) +Token +lex_string(void) { while(peek() != '"' && !is_at_end()) { if(peek() == '\n') lexer.line++; - advance(); + lex_advance(); } if(is_at_end()) return error_token("Unterminated string."); /* The closing quote. */ - advance(); + lex_advance(); return make_token(TOKEN_LITERAL_STR); } -static Token -character(void) +Token +lex_character(void) { - advance(); + lex_advance(); if(peek() != '\'' && !is_at_end()) { - advance(); + lex_advance(); } if(is_at_end()) return error_token("Unterminated string."); /* The closing quote. */ - advance(); + lex_advance(); return make_token(TOKEN_LITERAL_CHAR); } @@ -407,10 +407,10 @@ next_token(void) if(is_at_end()) return make_token(TOKEN_EOF); - c = advance(); - if(is_alpha(c)) return identifier(); + c = lex_advance(); + if(lex_is_alpha(c)) return identifier(); next = peek(); - if((c == '-' && is_digit(next)) || is_digit(c)) return number(); + if((c == '-' && lex_is_digit(next)) || lex_is_digit(c)) return lex_number(); switch(c) { case '(': @@ -432,13 +432,13 @@ next_token(void) case '.': return make_token(TOKEN_DOT); case '-': - return make_token(match('>') ? TOKEN_ARROW_RIGHT : TOKEN_MINUS); + return make_token(lex_match('>') ? TOKEN_ARROW_RIGHT : TOKEN_MINUS); case '+': return make_token(TOKEN_PLUS); case '/': return make_token(TOKEN_SLASH); case '&': - return make_token(match('&') ? TOKEN_AND_AND : TOKEN_AND); + return make_token(lex_match('&') ? TOKEN_AND_AND : TOKEN_AND); case '#': return make_token(TOKEN_MESH); case '$': @@ -446,21 +446,21 @@ next_token(void) case '*': return make_token(TOKEN_STAR); case '!': - return make_token(match('=') ? TOKEN_BANG_EQ : TOKEN_BANG); + return make_token(lex_match('=') ? TOKEN_BANG_EQ : TOKEN_BANG); case '=': - return make_token(match('=') ? TOKEN_EQ_EQ : TOKEN_EQ); + return make_token(lex_match('=') ? TOKEN_EQ_EQ : TOKEN_EQ); case '<': - return make_token(match('=') ? TOKEN_LTE - : match('<') ? TOKEN_SLL + return make_token(lex_match('=') ? TOKEN_LTE + : lex_match('<') ? TOKEN_SLL : TOKEN_LT); case '>': - return make_token(match('=') ? TOKEN_GTE - : match('>') ? TOKEN_SRL + return make_token(lex_match('=') ? TOKEN_GTE + : lex_match('>') ? TOKEN_SRL : TOKEN_GT); case '"': - return string(); + return lex_string(); case '\'': - return character(); + return lex_character(); } return error_token("Unexpected character."); diff --git a/libc.c b/libc.c index 4b7d801..95d74d1 100644 --- a/libc.c +++ b/libc.c @@ -78,13 +78,16 @@ snlen(const char *str, u32 max_len) void * aalloc(Arena *arena, u32 size) { - u32 pos; - if(arena == nil) return nil; - if(arena->count + size > arena->capacity) return nil; + u32 pos, aligned; + if(arena == nil) return nil; - pos = arena->count; - arena->count += size; - return (void *)&arena->tape[pos]; + aligned = (arena->count + 7) & ~7; + + if(aligned + size > arena->capacity) return nil; + + pos = aligned; + arena->count = pos + size; + return (void *)&arena->tape[pos]; } u32