#include "parser.h" #include "compiler.h" #include #include Symbol *symbol_table_lookup(ScopeTable *table, const char *name, u32 length, i32 scope_ref) { SymbolTable st = table->scopes[scope_ref]; for (u32 i = 0; i < st.count; i++) { if (st.symbols[i].name_length == length) { if (sleq(st.symbols[i].name, name, length)) { return &table->scopes[scope_ref].symbols[i]; } } } if (st.parent < 0) return nil; return symbol_table_lookup(table, name, length, st.parent); } u8 symbol_table_add(ScopeTable *table, Symbol s) { Symbol *sym = symbol_table_lookup(table, s.name, s.name_length, table->scope_ref); if (sym != nil) { fprintf(stderr, "Error: Symbol '%.*s' already defined, in this scope" " please pick a different variable name or create a new scope.\n", s.name_length, s.name); exit(1); } if (table->scopes[table->scope_ref].count + 1 > 255) { fprintf(stderr, "Error: Only 255 symbols are allowed per scope" " first off: impressive; secondly:" " just create a new scope and keep going.\n"); exit(1); } if (!table_realloc(table)) { fprintf(stderr, "Error: Symbol table is out of memory! This is likely because you " " built the assembler in static mode, increase the static size." " if you built using malloc, that means your computer is out of" " memory. Close a few tabs in your web browser and try again." " Count was %d, while capacity was %d\n", table->count, table->capacity); exit(1); } table->scopes[table->scope_ref].symbols[table->scopes[table->scope_ref].count] = s; u8 index = table->scopes[table->scope_ref].count; table->scopes[table->scope_ref].count++; return index; } u32 get_ref(ScopeTable *st, const char *name, u32 length) { Symbol *sym = symbol_table_lookup(st, name, length, st->scope_ref); if (!sym) { fprintf(stderr, "Error: Assembler has no idea what Symbol '%.*s' means.\n", length, name); exit(1); return 0; } return sym->ref; } u32 get_ptr(Token token, ScopeTable *st) { if (token.type == TOKEN_IDENTIFIER) { return get_ref(st, token.start, token.length); } if (token.type == TOKEN_LITERAL_INT) { return atoi(token.start); } if (token.type == TOKEN_LITERAL_NAT) { char *endptr; u32 out = (u32)strtoul(token.start, &endptr, 10); if (endptr == token.start || *endptr != '\0') { fprintf(stderr, "Invalid decimal literal at line %d: %.*s\n", token.line, token.length, token.start); exit(1); } return out; } fprintf(stderr, "Error: Not a pointer or symbol at line %d: %.*s\n", token.line, token.length, token.start); exit(1); } u32 get_reg(Token token, ScopeTable *st) { if (token.type == TOKEN_IDENTIFIER) { return get_ref(st, token.start, token.length); } if (token.type == TOKEN_BIG_MONEY) { token = next_token(); return atoi(token.start); } fprintf(stderr, "Error: Not a register or symbol at line %d: %.*s\n", token.line, token.length, token.start); exit(1); } Token next_id_or_reg() { Token token = next_token(); if (token.type == TOKEN_IDENTIFIER) { return token; } if (token.type == TOKEN_BIG_MONEY) { token = next_token(); return token; } printf("Not an ID or register at line %d: %.*s\n", token.line, token.length, token.start); exit(1); return token; } Token next_id_or_ptr() { Token token = next_token(); if (token.type != TOKEN_IDENTIFIER && token.type != TOKEN_LITERAL_NAT && token.type != TOKEN_LITERAL_INT && token.type != TOKEN_LITERAL_REAL) { printf("Not an ID or register at line %d: %.*s\n", token.line, token.length, token.start); exit(1); } return token; } Token next_token_is(TokenType type) { Token token = next_token(); if (token.type != type) { printf("ERROR at line %d: %.*s\n", token.line, token.length, token.start); exit(1); } return token; } /** * Compile. */ bool compile(ScopeTable *st, char *source) { return false; }