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;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
12
asm/report.c
12
asm/report.c
@ -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)
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user