include and global works

This commit is contained in:
sfja 2025-04-02 22:37:48 +02:00
parent ad2baf22d2
commit bdf3516455
3 changed files with 89 additions and 10 deletions

View File

@ -18,6 +18,12 @@ typedef struct {
const char* output_file; const char* output_file;
} Args; } Args;
typedef struct {
char* ident;
Loc loc;
uint16_t ip;
} GlobalSym;
static inline Args parse_args(int argc, char** argv); static inline Args parse_args(int argc, char** argv);
static inline char* read_text_file(const char* filename); static inline char* read_text_file(const char* filename);
static inline int include_file(IdentResolver* resolver, static inline int include_file(IdentResolver* resolver,
@ -60,22 +66,37 @@ int main(int argc, char** argv)
PLine** lines = malloc(sizeof(PLine*) * lines_capacity); PLine** lines = malloc(sizeof(PLine*) * lines_capacity);
size_t lines_size = 0; size_t lines_size = 0;
size_t global_symbols_capacity = 8;
GlobalSym* global_symbols
= malloc(sizeof(GlobalSym) * global_symbols_capacity);
size_t global_symbols_size = 0;
while (!parser_done(&parser)) { while (!parser_done(&parser)) {
if (lines_size + 1 > lines_capacity) {
lines_capacity += 2;
lines = realloc(lines, sizeof(PLine*) * lines_capacity);
}
PStmt* stmt = parser_next_stmt(&parser); PStmt* stmt = parser_next_stmt(&parser);
if (!stmt) { if (!stmt) {
continue; continue;
} }
switch (stmt->ty) { switch (stmt->ty) {
case PStmtTy_Line: case PStmtTy_Line:
if (lines_size + 1 > lines_capacity) {
lines_capacity *= 2;
lines = realloc(lines, sizeof(PLine*) * lines_capacity);
}
lines[lines_size++] = stmt->line; lines[lines_size++] = stmt->line;
// NOTE: Shallow free. // NOTE: Shallow free.
free(stmt); free(stmt);
break; break;
case PStmtTy_Global: case PStmtTy_Global:
if (global_symbols_size + 1 > global_symbols_capacity) {
global_symbols_capacity *= 2;
global_symbols = realloc(global_symbols,
sizeof(GlobalSym) * global_symbols_capacity);
}
global_symbols[global_symbols_size++] = (GlobalSym) {
.ident = asm_strdup(stmt->ident),
.loc = stmt->loc,
.ip = 0,
};
pstmt_free(stmt); pstmt_free(stmt);
break; break;
case PStmtTy_Extern: case PStmtTy_Extern:
@ -85,8 +106,17 @@ int main(int argc, char** argv)
const IdentResol* existing const IdentResol* existing
= ident_resolver_resolve(&resolver, stmt->ident); = ident_resolver_resolve(&resolver, stmt->ident);
if (existing != NULL) { if (existing != NULL) {
REPORTF_ERROR("redefinition of constant '%s'", stmt->ident); REPORTF_ERROR(
"redefinition of identifier '%s'", stmt->ident);
reporter_print_loc(&rep, stmt->loc); reporter_print_loc(&rep, stmt->loc);
const char* filename = rep.filename;
if (existing->ty == IdentResolTy_Const) {
filename = existing->src_filename;
}
REPORTF_INFO(
"previous definition of '%s' here", existing->ident);
reporter_print_loc(&rep, existing->loc);
rep.filename = filename;
errors_occured = true; errors_occured = true;
pstmt_free(stmt); pstmt_free(stmt);
continue; continue;
@ -134,6 +164,24 @@ int main(int argc, char** argv)
ip += size; ip += size;
} }
for (size_t i = 0; i < global_symbols_size; ++i) {
const IdentResol* res
= ident_resolver_resolve(&resolver, global_symbols[i].ident);
if (res == NULL) {
REPORTF_ERROR("undefined global '%s'", global_symbols[i].ident);
REPORTF_INFO("'%s' declared global here", global_symbols[i].ident);
reporter_print_loc(&rep, global_symbols[i].loc);
continue;
} else if (res->ty != IdentResolTy_Label) {
REPORTF_ERROR("'%s' cannot be declared global", res->ident);
reporter_print_loc(&rep, res->loc);
REPORTF_INFO("'%s' declared global here", global_symbols[i].ident);
reporter_print_loc(&rep, global_symbols[i].loc);
continue;
}
global_symbols[i].ip = res->ip;
}
if (errors_occured) { if (errors_occured) {
fprintf(stderr, "nothing written. stopping...\n"); fprintf(stderr, "nothing written. stopping...\n");
res = -1; res = -1;
@ -188,6 +236,10 @@ leave_free_chunk:
for (size_t i = 0; i < lines_size; ++i) { for (size_t i = 0; i < lines_size; ++i) {
pline_free(lines[i]); pline_free(lines[i]);
} }
for (size_t i = 0; i < global_symbols_size; ++i) {
free(global_symbols[i].ident);
}
free(global_symbols);
free(lines); free(lines);
free(input_text); free(input_text);
ident_resolver_destroy(&resolver); ident_resolver_destroy(&resolver);
@ -270,8 +322,23 @@ static inline int include_file(IdentResolver* resolver,
const IdentResol* existing const IdentResol* existing
= ident_resolver_resolve(resolver, stmt->ident); = ident_resolver_resolve(resolver, stmt->ident);
if (existing != NULL) { if (existing != NULL) {
REPORTF_ERROR("redefinition of constant '%s'", stmt->ident); if (existing->ty == IdentResolTy_Const
&& strcmp(existing->src_filename, filepath) == 0) {
// Same file included multiple times.
pstmt_free(stmt);
continue;
}
REPORTF_ERROR(
"redefinition of identifier '%s'", stmt->ident);
reporter_print_loc(&rep, stmt->loc); reporter_print_loc(&rep, stmt->loc);
const char* filename = rep.filename;
if (existing->ty == IdentResolTy_Const) {
filename = existing->src_filename;
}
REPORTF_INFO(
"previous definition of '%s' here", existing->ident);
reporter_print_loc(&rep, existing->loc);
rep.filename = filename;
errors_occured = true; errors_occured = true;
pstmt_free(stmt); pstmt_free(stmt);
continue; continue;
@ -372,7 +439,7 @@ static inline void use_labels(IdentResolver* resolver, PLabel* label)
return; return;
use_labels(resolver, label->next); use_labels(resolver, label->next);
const IdentResol* existing = ident_resolver_resolve(resolver, label->ident); const IdentResol* existing = ident_resolver_resolve(resolver, label->ident);
if (existing->ty == IdentResolTy_Label) { if (existing && existing->ty == IdentResolTy_Label) {
resolver->current_parent = existing; resolver->current_parent = existing;
} }
} }

View File

@ -4,6 +4,12 @@
void print_report_loc( void print_report_loc(
const char* filename, const char* text, size_t text_len, Loc loc) const char* filename, const char* text, size_t text_len, Loc loc)
{ {
const char* displacement_spaces
= " "
" "
" "
" ";
size_t line_start = loc.idx; size_t line_start = loc.idx;
while (line_start > 0 && text[line_start] != '\n') { while (line_start > 0 && text[line_start] != '\n') {
line_start -= 1; line_start -= 1;
@ -20,8 +26,8 @@ void print_report_loc(
fprintf(stderr, fprintf(stderr,
" \x1b[96m--> ./%s:%d:%d\n " " \x1b[96m--> ./%s:%d:%d\n "
"\x1b[37m|\n\x1b[96m%5d\x1b[37m|%.*s\n " "\x1b[37m|\n\x1b[96m%5d\x1b[37m|\x1b[0m%.*s\n "
"|%*c\x1b[1;91m^\x1b[0m\n", "\x1b[37m|%.*s\x1b[1;91m^\x1b[0m\n",
filename, filename,
loc.line, loc.line,
loc.col, loc.col,
@ -29,7 +35,7 @@ void print_report_loc(
line_len, line_len,
line, line,
loc.col - 1, loc.col - 1,
' '); displacement_spaces);
} }
void reporter_print_loc(Reporter* rep, Loc loc) void reporter_print_loc(Reporter* rep, Loc loc)

View File

@ -1,6 +1,10 @@
include "arch.asm" include "arch.asm"
global start
extern other
start: start:
; rsp points *at* the top element ; rsp points *at* the top element
mov rbp, 2048 mov rbp, 2048
@ -15,6 +19,8 @@ start:
mov r1, 1 mov r1, 1
int Int_DiskRead int Int_DiskRead
jmp other
main_loop: main_loop:
hlt hlt
jmp main_loop jmp main_loop