Tok tok;
Module* imports;
Symbol* scope;
+ char* name;
} Parser;
void lexfile(Parser* ctx, char* path);
void codegen_setreal(Item* item, double val);
void codegen_setstr(Item* item, char* val);
-void codegen_import(char* name);
-void codegen_var(char* name, Type* type);
-void codegen_main(char* modname);
-void codegen_startproc(char* name, long long localsz);
+void codegen_imports(Parser* p);
+void codegen_global(Parser* p, char* name, Type* type);
+void codegen_main(Parser* p);
+void codegen_startproc(Parser* p, char* name, long long localsz);
void codegen_endproc(void);
void codegen_unop(int op, Item* a);
void codegen_binop(int op, Item* a, Item* b);
}
}
-void codegen_import(char* name)
+void codegen_imports(Parser* p)
{
- printf(" call %s\n", name);
+ for (Module* m = p->imports; m; m = m->next)
+ {
+ printf(" call %s\n", m->name);
+ }
}
-void codegen_var(char* name, Type* type)
+void codegen_global(Parser* p, char* name, Type* type)
{
printf(" .data\n");
- printf("%s:\n", name);
+ printf("%s_%s:\n", p->name, name);
printf(" .zero %d\n\n", type->size);
}
-void codegen_main(char* modname)
+void codegen_main(Parser* p)
{
- codegen_startproc("main", 0);
- printf(" call %s\n", modname);
+ printf(" .text\n");
+ printf(" .globl main\n");
+ printf("main:\n");
+ printf(" pushq %%rbp\n");
+ printf(" movq %%rsp, %%rbp\n");
+ printf(" call %s\n", p->name);
printf(" xor %%rax, %%rax\n");
- codegen_endproc();
+ printf(" pop %%rbp\n");
+ printf(" ret\n");
}
-void codegen_startproc(char* name, long long localsz)
+void codegen_startproc(Parser* p, char* name, long long localsz)
{
printf(" .text\n");
- printf(" .globl %s\n", name);
- printf("%s:\n", name);
+ if (name)
+ {
+ printf(" .globl %s_%s\n", p->name, name);
+ printf("%s_%s:\n", p->name, name);
+ }
+ else
+ {
+ printf(" .globl %s\n", p->name);
+ printf("%s:\n", p->name);
+ }
printf(" pushq %%rbp\n");
if (localsz > 0)
for (int i = 0; i < nsyms; i++)
{
sym->type = type->type;
- codegen_var(sym->name, sym->type);
+ codegen_global(p, sym->name, sym->type);
sym = sym->next;
}
RULE(module)
{
expect(p, MODULE);
- char* sname = expect_text(p, IDENT);
+ p->name = expect_text(p, IDENT);
/* TODO: Check that it matches filename here */
- (void)sname;
if (matches(p, IMPORT))
{
var_decl(p, item);
}
- codegen_startproc("Module", 0);
+ codegen_startproc(p, NULL, 0);
if (accept(p, BEGIN))
{
- for (Module* m = p->imports; m; m = m->next)
- {
- codegen_import(m->name);
- }
+ codegen_imports(p);
statement_seq(p, item);
expect(p, END);
}
void compile(char* fname)
{
char* fcontents = file_load(fname);
- module(
- &(Parser){
- .scope = &RealSym,
- .file = &(LexFile){
- .path = fname,
- .fbeg = fcontents,
- .fpos = fcontents,
- }
- },
- &(Item){0}
- );
- codegen_main("Module");
+ Parser* p = &(Parser){
+ .name = NULL,
+ .scope = &RealSym,
+ .file = &(LexFile){
+ .path = fname,
+ .fbeg = fcontents,
+ .fpos = fcontents,
+ }
+ };
+ module(p, &(Item){0});
+ codegen_main(p);
}
/* Grammar Unit Tests