153 lines
4.1 KiB
C
153 lines
4.1 KiB
C
#include "parser.h"
|
|
#include "compiler.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
|
|
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;
|
|
}
|