fout(p, "%%Bool = type i1\n");
fout(p, "%%Int = type i64\n");
fout(p, "%%Real = type double\n");
- fout(p, "%%String = type { i64, i8* }\n");
+ fout(p, "%%String = type i8*\n");
}
void codegen_symbol(Parser* p, Symbol* sym)
{
fout(p, " 0.0\n");
}
+ else if (sym->type->form == FORM_STRING)
+ {
+ fout(p, " null\n");
+ }
else
{
fout(p, " 0\n");
static void print_ident(Parser* p, SsaVar* var)
{
-// fout("%ld\n", var->symid);
-// fflush(stdout);
Symbol* s = symbol_getbyid(p, var->symid);
assert(s);
assert(s->name);
{
fout(p, " %f", val->val.f);
}
+ else if (type->form == FORM_STRING)
+ {
+ fout(p, " @const.%p", val->val.s);
+ }
else
{
assert(!"not implemented");
fout(p, "\n");
}
+void codegen_const(Parser* p, SsaNode* expr)
+{
+ assert(expr->mode == MODE_CONST);
+ if (expr->type->form == FORM_STRING)
+ {
+ fout(p,
+ "@const.%p = private unnamed_addr constant [%d x i8] c\"%s\\00\", align 1\n",
+ SSA_VAL(expr).s,
+ (int)strlen(SSA_VAL(expr).s)+1,
+ SSA_VAL(expr).s
+ );
+ }
+ else
+ {
+ assert(!"unimplemented constant declaration");
+ }
+}
+
void codegen_main(Parser* p)
{
if (!p->genmain) return; // Bail if no main required
fout(p, " call void @%s()\n", p->name);
fout(p, " ret i32 0\n");
fout(p, "}\n");
-}
\ No newline at end of file
+}
void codegen_init(Parser* p);
void codegen_symbol(Parser* p, Symbol* sym);
void codegen_block(Parser* p, SsaBlock* block);
+void codegen_const(Parser* p, SsaNode* expr);
void codegen_main(Parser* p);
consume(p);
break;
+ case STRING:
+ expr = ssa_string(p, peek(p)->text);
+ codegen_const(p, expr);
+ consume(p);
+ break;
+
case '(':
expect(p, '(');
expr = expression(p);
return proc;
}
-void proc_body(Parser* p, Type* proctype)
+void proc_body(Parser* p, Symbol* proc)
{
expect(p, BEGIN);
SsaBlock* block = ssa_block(p);
p->curr_join = ssa_block(p);
block->links[1] = p->curr_join;
block->links[0] = statement_seq(p);
- if (proctype->base != &VoidType)
+ if (proc->type->base != &VoidType)
{
expect(p, RETURN);
SsaNode* retval = expression(p);
- check_type(p, proctype->base, retval);
+ check_type(p, proc->type->base, retval);
expect(p, ';');
ssa_return(p, retval);
}
ssa_return(p, NULL);
}
expect(p, END);
+ codegen_symbol(p, proc);
codegen_block(p, block);
}
else
{
proc->forward = 0;
- codegen_symbol(p, proc);
- proc_body(p, proc->type);
+ proc_body(p, proc);
}
EXIT_RULE();
if (fs_modtime(obj_path) < fs_modtime(path))
{
/* run llc to generate assembly listing */
- char* llc_cmd = strmcat("llc -o \"", asm_path , "\" \"", p->outpath, "\"", 0);
+ char* llc_cmd = strmcat("llc -opaque-pointers -o \"", asm_path , "\" \"", p->outpath, "\"", 0);
printf("%s\n", llc_cmd);
if (system(llc_cmd) != 0)
{
remove(p->outpath);
/* compile the object file now */
- char* as_cmd = strmcat("clang -c -o \"", obj_path, "\" \"", asm_path, "\"", 0);
+ char* as_cmd = strmcat("clang -static -c -o \"", obj_path, "\" \"", asm_path, "\"", 0);
printf("%s\n", as_cmd);
if (system(as_cmd) != 0)
{
{
Parser p = {0};
compile_module(&p, path, true);
- char* link_cmd = strmcat("clang -o ", p.name, " ", 0);
+ char* link_cmd = strmcat("clang -static -o ", p.name, " ", 0);
for (size_t i = 0; i < p.nmods; i++)
{
char* object = strdup(p.mods[i].path);
}
}
+void check_string(Parser* p, SsaNode* a)
+{
+ if (a->type->form != FORM_STRING)
+ {
+ error(p, "not an string");
+ }
+}
+
void check_bools(Parser* p, SsaNode* a, SsaNode* b)
{
check_bool(p, a);
check_bool(p, b);
}
+void check_strings(Parser* p, SsaNode* a, SsaNode* b)
+{
+ check_string(p, a);
+ check_string(p, b);
+}
+
void check_type(Parser* p, Type* type, SsaNode* a)
{
if (type->form == FORM_REAL)
{
check_bools(p, a, b);
}
+ else if (a->type->form == FORM_STRING)
+ {
+ check_strings(p, a, b);
+ }
// else if (a->type->form == FORM_ARRAY)
// {
// }
a : Int
b : array 5 of Int
end
+ vString : String
procedure TestReturnVoid*()
begin
vBool = true;
vInt = 42;
vReal = 42.0;
+ vString = "";
end
procedure TestIntArithOps()