include and global works
This commit is contained in:
parent
ad2baf22d2
commit
bdf3516455
81
asm/main.c
81
asm/main.c
@ -18,6 +18,12 @@ typedef struct {
|
||||
const char* output_file;
|
||||
} Args;
|
||||
|
||||
typedef struct {
|
||||
char* ident;
|
||||
Loc loc;
|
||||
uint16_t ip;
|
||||
} GlobalSym;
|
||||
|
||||
static inline Args parse_args(int argc, char** argv);
|
||||
static inline char* read_text_file(const char* filename);
|
||||
static inline int include_file(IdentResolver* resolver,
|
||||
@ -60,22 +66,37 @@ int main(int argc, char** argv)
|
||||
PLine** lines = malloc(sizeof(PLine*) * lines_capacity);
|
||||
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)) {
|
||||
if (lines_size + 1 > lines_capacity) {
|
||||
lines_capacity += 2;
|
||||
lines = realloc(lines, sizeof(PLine*) * lines_capacity);
|
||||
}
|
||||
PStmt* stmt = parser_next_stmt(&parser);
|
||||
if (!stmt) {
|
||||
continue;
|
||||
}
|
||||
switch (stmt->ty) {
|
||||
case PStmtTy_Line:
|
||||
if (lines_size + 1 > lines_capacity) {
|
||||
lines_capacity *= 2;
|
||||
lines = realloc(lines, sizeof(PLine*) * lines_capacity);
|
||||
}
|
||||
lines[lines_size++] = stmt->line;
|
||||
// NOTE: Shallow free.
|
||||
free(stmt);
|
||||
break;
|
||||
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);
|
||||
break;
|
||||
case PStmtTy_Extern:
|
||||
@ -85,8 +106,17 @@ int main(int argc, char** argv)
|
||||
const IdentResol* existing
|
||||
= ident_resolver_resolve(&resolver, stmt->ident);
|
||||
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);
|
||||
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;
|
||||
pstmt_free(stmt);
|
||||
continue;
|
||||
@ -134,6 +164,24 @@ int main(int argc, char** argv)
|
||||
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) {
|
||||
fprintf(stderr, "nothing written. stopping...\n");
|
||||
res = -1;
|
||||
@ -188,6 +236,10 @@ leave_free_chunk:
|
||||
for (size_t i = 0; i < lines_size; ++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(input_text);
|
||||
ident_resolver_destroy(&resolver);
|
||||
@ -270,8 +322,23 @@ static inline int include_file(IdentResolver* resolver,
|
||||
const IdentResol* existing
|
||||
= ident_resolver_resolve(resolver, stmt->ident);
|
||||
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);
|
||||
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;
|
||||
pstmt_free(stmt);
|
||||
continue;
|
||||
@ -372,7 +439,7 @@ static inline void use_labels(IdentResolver* resolver, PLabel* label)
|
||||
return;
|
||||
use_labels(resolver, label->next);
|
||||
const IdentResol* existing = ident_resolver_resolve(resolver, label->ident);
|
||||
if (existing->ty == IdentResolTy_Label) {
|
||||
if (existing && existing->ty == IdentResolTy_Label) {
|
||||
resolver->current_parent = existing;
|
||||
}
|
||||
}
|
||||
|
12
asm/report.c
12
asm/report.c
@ -4,6 +4,12 @@
|
||||
void print_report_loc(
|
||||
const char* filename, const char* text, size_t text_len, Loc loc)
|
||||
{
|
||||
const char* displacement_spaces
|
||||
= " "
|
||||
" "
|
||||
" "
|
||||
" ";
|
||||
|
||||
size_t line_start = loc.idx;
|
||||
while (line_start > 0 && text[line_start] != '\n') {
|
||||
line_start -= 1;
|
||||
@ -20,8 +26,8 @@ void print_report_loc(
|
||||
|
||||
fprintf(stderr,
|
||||
" \x1b[96m--> ./%s:%d:%d\n "
|
||||
"\x1b[37m|\n\x1b[96m%5d\x1b[37m|%.*s\n "
|
||||
"|%*c\x1b[1;91m^\x1b[0m\n",
|
||||
"\x1b[37m|\n\x1b[96m%5d\x1b[37m|\x1b[0m%.*s\n "
|
||||
"\x1b[37m|%.*s\x1b[1;91m^\x1b[0m\n",
|
||||
filename,
|
||||
loc.line,
|
||||
loc.col,
|
||||
@ -29,7 +35,7 @@ void print_report_loc(
|
||||
line_len,
|
||||
line,
|
||||
loc.col - 1,
|
||||
' ');
|
||||
displacement_spaces);
|
||||
}
|
||||
|
||||
void reporter_print_loc(Reporter* rep, Loc loc)
|
||||
|
@ -1,6 +1,10 @@
|
||||
|
||||
include "arch.asm"
|
||||
|
||||
|
||||
global start
|
||||
extern other
|
||||
|
||||
start:
|
||||
; rsp points *at* the top element
|
||||
mov rbp, 2048
|
||||
@ -15,6 +19,8 @@ start:
|
||||
mov r1, 1
|
||||
int Int_DiskRead
|
||||
|
||||
jmp other
|
||||
|
||||
main_loop:
|
||||
hlt
|
||||
jmp main_loop
|
||||
|
Loading…
x
Reference in New Issue
Block a user