.size = -1
};
-void emit_type(Type* type);
+void emit_type(Parser* p, Type* type);
-void declare_record_type(Type* type)
+static void fout(Parser* p, char* fmt, ...)
+{
+ (void)p, (void)fmt;
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stdout, fmt, args);
+ va_end(args);
+}
+
+
+void declare_record_type(Parser* p, Type* type)
{
if (!type->name)
{
{
if (f->type->form == FORM_RECORD)
{
- declare_record_type(f->type);
+ declare_record_type(p, f->type);
}
}
type->name = calloc(1, len+1);
(void)snprintf(type->name, len+1, "struct.%p", (void*)type);
- printf("%%%s = type { ", type->name);
+ fout(p, "%%%s = type { ", type->name);
for (Field* f = type->fields; f; f = f->next)
{
- emit_type(f->type);
+ emit_type(p, f->type);
if (f->next)
{
- printf(", ");
+ fout(p, ", ");
}
}
- printf(" }\n");
+ fout(p, " }\n");
}
}
-void emit_type(Type* type)
+void emit_type(Parser* p, Type* type)
{
switch (type->form)
{
- case FORM_BOOL: printf("%%Bool"); break;
- case FORM_INT: printf("%%Int"); break;
- case FORM_REAL: printf("%%Real"); break;
- case FORM_VOID: printf("void"); break;
- case FORM_STRING: printf("%%String"); break;
+ case FORM_BOOL: fout(p, "%%Bool"); break;
+ case FORM_INT: fout(p, "%%Int"); break;
+ case FORM_REAL: fout(p, "%%Real"); break;
+ case FORM_VOID: fout(p, "void"); break;
+ case FORM_STRING: fout(p, "%%String"); break;
case FORM_ARRAY:
- printf("[%d x ", type->size);
- emit_type(type->base);
- printf("]");
+ fout(p, "[%d x ", type->size);
+ emit_type(p, type->base);
+ fout(p, "]");
break;
case FORM_RECORD:
if (type->name)
{
- printf("%%%s", type->name);
+ fout(p, "%%%s", type->name);
}
else
{
- printf("{ ");
+ fout(p, "{ ");
for (Field* field = type->fields; field; field = field->next)
{
- emit_type(field->type);
+ emit_type(p, field->type);
if (field->next)
{
- printf(", ");
+ fout(p, ", ");
}
}
- printf(" }");
+ fout(p, " }");
}
break;
case FORM_PROC:
default:
- printf("????");
+ fout(p, "????");
break;
}
}
void codegen_init(Parser* p)
{
p->codegen = true;
- printf("%%Bool = type i1\n");
- printf("%%Int = type i64\n");
- printf("%%Real = type double\n");
- printf("%%String = type { i64, i8* }\n");
+ 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");
}
void codegen_symbol(Parser* p, Symbol* sym)
{
char* modname = (sym->module == 0
? p->name : symbol_getbyid(p, sym->module)->name);
- printf("@%s_%s = global ", modname, sym->name);
- emit_type(sym->type);
+ fout(p, "@%s_%s = global ", modname, sym->name);
+ emit_type(p, sym->type);
if (sym->type->form == FORM_ARRAY || sym->type->form == FORM_RECORD)
{
- printf(" zeroinitializer\n");
+ fout(p, " zeroinitializer\n");
}
else if (sym->type->form == FORM_REAL)
{
- printf(" 0.0\n");
+ fout(p, " 0.0\n");
}
else
{
- printf(" 0\n");
+ fout(p, " 0\n");
}
- puts("");
+ fout(p, "\n");
}
else if (sym->class == SYM_TYPE)
{
if (sym->type->form == FORM_RECORD)
{
- declare_record_type(sym->type);
+ declare_record_type(p, sym->type);
}
- printf("%%%s = type ", sym->name);
- emit_type(sym->type);
- puts("\n");
+ fout(p, "%%%s = type ", sym->name);
+ emit_type(p, sym->type);
+ fout(p, "\n");
}
else if (sym->class == SYM_PROC)
{
? p->name : symbol_getbyid(p, sym->module)->name);
if (sym->forward)
{
- printf("declare ");
+ fout(p, "declare ");
}
else
{
- printf("define ");
+ fout(p, "define ");
}
- emit_type(sym->type->base);
- printf(" @%s_%s(", modname, sym->name);
+ emit_type(p, sym->type->base);
+ fout(p, " @%s_%s(", modname, sym->name);
for (Field* f = sym->type->fields; f; f = f->next)
{
- emit_type(f->type);
- printf(" %%%s.0", f->name);
+ emit_type(p, f->type);
+ fout(p, " %%%s.0", f->name);
if (f->next)
{
- printf(", ");
+ fout(p, ", ");
}
}
- printf(")\n");
+ fout(p, ")\n");
}
else if (sym->class == SYM_MODULE)
{
if (!sym->forward)
{
- printf("define ");
+ fout(p, "define ");
}
else
{
- printf("declare ");
+ fout(p, "declare ");
}
- printf(" void @%s(", sym->name);
- printf(")\n");
+ fout(p, " void @%s(", sym->name);
+ fout(p, ")\n");
}
}
static void print_ident(Parser* p, SsaVar* var)
{
-// printf("%ld\n", var->symid);
+// fout("%ld\n", var->symid);
// fflush(stdout);
Symbol* s = symbol_getbyid(p, var->symid);
assert(s);
{
char* modname = (s->module == 0
? p->name : symbol_getbyid(p, s->module)->name);
- printf("@%s_%s", modname, name);
+ fout(p, "@%s_%s", modname, name);
}
else
{
- printf("%%%s.%lu", name, var->symver);
+ fout(p, "%%%s.%lu", name, var->symver);
}
}
-static void print_const(Type* type, SsaValue* val)
+static void print_const(Parser* p, Type* type, SsaValue* val)
{
if (type->form == FORM_INT || type->form == FORM_BOOL)
{
- printf(" %lld", val->val.i);
+ fout(p, " %lld", val->val.i);
}
else if (type->form == FORM_REAL)
{
- printf(" %f", val->val.f);
+ fout(p, " %f", val->val.f);
}
else
{
}
}
-char* binop_name(SsaNode* node)
+char* binop_name(Parser* p, SsaNode* node)
{
char* name = NULL;
if (SSA_LTYPE(node)->form == FORM_INT)
}
else
{
- printf("\n%d %d\n", node->mode, node->code);
+ fout(p, "\n%d %d\n", node->mode, node->code);
fflush(stdout);
assert(!"not implemented");
}
{
if (expr->mode == MODE_CONST)
{
- print_const(expr->type, &expr->value);
+ print_const(p, expr->type, &expr->value);
}
else
{
Symbol* s = symbol_getbyid(p, SSA_VAR(expr).symid);
if (s->type && s->type->form == FORM_ARRAY)
{
- printf("*");
+ fout(p, "*");
}
- printf(" ");
+ fout(p, " ");
print_ident(p, &(SSA_VAR(expr)));
}
}
case MODE_MEMORY:
if (expr->code == LOAD)
{
- printf(" ");
+ fout(p, " ");
print_ident(p, &(SSA_VAR(expr)));
- printf(" = load ");
- emit_type(SSA_TYPE(expr));
- printf(", ");
- emit_type(SSA_TYPE(expr));
- printf("* ");
+ fout(p, " = load ");
+ emit_type(p, SSA_TYPE(expr));
+ fout(p, ", ");
+ emit_type(p, SSA_TYPE(expr));
+ fout(p, "* ");
print_ident(p, &(SSA_LVAR(expr)));
- puts("");
+ fout(p, "\n");
}
else if (expr->code == STORE)
{
- printf(" store ");
- emit_type(SSA_LTYPE(expr));
+ fout(p, " store ");
+ emit_type(p, SSA_LTYPE(expr));
print_oparg(p, expr->left);
- printf(", ");
- emit_type(SSA_TYPE(expr));
- printf("* ");
+ fout(p, ", ");
+ emit_type(p, SSA_TYPE(expr));
+ fout(p, "* ");
print_ident(p, &(SSA_VAR(expr)));
- puts("");
+ fout(p, "\n");
}
else if (expr->code == '[')
{
- printf(" ");
+ fout(p, " ");
print_ident(p, &(SSA_VAR(expr)));
- printf(" = getelementptr ");
- emit_type(SSA_LTYPE(expr));
- printf(", ");
- emit_type(SSA_LTYPE(expr));
- printf("* ");
+ fout(p, " = getelementptr ");
+ emit_type(p, SSA_LTYPE(expr));
+ fout(p, ", ");
+ emit_type(p, SSA_LTYPE(expr));
+ fout(p, "* ");
print_ident(p, &(SSA_LVAR(expr)));
- printf(", ");
- printf("%%Int 0, %%Int");
+ fout(p, ", ");
+ fout(p, "%%Int 0, %%Int");
print_oparg(p, expr->right);
- puts("");
+ fout(p, "\n");
}
else if (expr->code == '.')
{
- printf(" ");
+ fout(p, " ");
print_ident(p, &(SSA_VAR(expr)));
- printf(" = getelementptr ");
- emit_type(SSA_LTYPE(expr));
- printf(", ");
- emit_type(SSA_LTYPE(expr));
- printf("* ");
+ fout(p, " = getelementptr ");
+ emit_type(p, SSA_LTYPE(expr));
+ fout(p, ", ");
+ emit_type(p, SSA_LTYPE(expr));
+ fout(p, "* ");
print_ident(p, &(SSA_LVAR(expr)));
- printf(", i64 0");
+ fout(p, ", i64 0");
int num = 0;
char* fname = ssa_asstring(expr->right);
struct Field* field = SSA_LTYPE(expr)->fields;
break;
}
}
- printf(", i32 %d", num);
- puts("");
+ fout(p, ", i32 %d", num);
+ fout(p, "\n");
}
else
{
case MODE_CTRL_CONST:
if (expr->code == RETURN)
{
- printf(" ret ");
- emit_type(SSA_TYPE(expr));
+ fout(p, " ret ");
+ emit_type(p, SSA_TYPE(expr));
if (SSA_TYPE(expr)->form != FORM_VOID)
{
- printf(" ");
+ fout(p, " ");
if (expr->mode == MODE_CTRL)
{
print_ident(p, &(SSA_VAR(expr)));
}
else
{
- print_const(SSA_TYPE(expr), &(expr->value));
+ print_const(p, SSA_TYPE(expr), &(expr->value));
}
}
- puts("");
+ fout(p, "\n");
}
else if (expr->code == IF)
{
- printf(" br %%Bool ");
+ fout(p, " br %%Bool ");
print_ident(p, &(SSA_VAR(expr)));
- printf(", label %%L%ld, label %%L%ld\n",
+ fout(p, ", label %%L%ld, label %%L%ld\n",
SSA_LBLK(expr)->id,
SSA_RBLK(expr)->id
);
}
else if (expr->code == BRANCH)
{
- printf(" br label %%L%ld\n", SSA_LBLK(expr)->id);
+ fout(p, " br label %%L%ld\n", SSA_LBLK(expr)->id);
}
else if (expr->code == CALL)
{
- printf(" ");
+ fout(p, " ");
if (SSA_TYPE(expr) != &VoidType)
{
print_ident(p, &(SSA_VAR(expr)));
- printf(" = ");
+ fout(p, " = ");
}
- printf("call ");
- emit_type(SSA_TYPE(expr));
- printf(" ");
+ fout(p, "call ");
+ emit_type(p, SSA_TYPE(expr));
+ fout(p, " ");
print_ident(p, &(SSA_LVAR(expr)));
- printf("(");
+ fout(p, "(");
size_t nargs = expr->right->value.args.nv;
SsaNode** args = expr->right->value.args.v;
for (size_t i = 0; args && i < nargs; i++)
{
assert(args[i]);
- emit_type(SSA_TYPE(args[i]));
-// printf(" ");
+ emit_type(p, SSA_TYPE(args[i]));
+// fout(" ");
print_oparg(p, args[i]);
if (i+1 < nargs)
{
- printf(", ");
+ fout(p, ", ");
}
}
- printf(")");
- puts("");
-fflush(stdout);
-
-// printf(" ret ");
-// emit_type(SSA_TYPE(expr));
-// if (SSA_TYPE(expr)->form != FORM_VOID)
-// {
-// printf(" ");
-// if (expr->mode == MODE_CTRL)
-// {
-// print_ident(p, &(SSA_VAR(expr)));
-// }
-// else
-// {
-// print_const(SSA_TYPE(expr), &(expr->value));
-// }
-// }
-// puts("");
-
-
+ fout(p, ")");
+ fout(p, "\n");
}
else
{
break;
case MODE_UNOP:
- printf(" ");
+ fout(p, " ");
print_ident(p, &(SSA_VAR(expr)));
- printf(" = \n");
+ fout(p, " = \n");
break;
case MODE_BINOP:
- printf(" ");
+ fout(p, " ");
print_ident(p, &(SSA_VAR(expr)));
- printf(" = %s ", binop_name(expr));
- emit_type(SSA_LTYPE(expr));
- printf(" ");
+ fout(p, " = %s ", binop_name(p, expr));
+ emit_type(p, SSA_LTYPE(expr));
+ fout(p, " ");
print_oparg(p, expr->left);
- printf(", ");
+ fout(p, ", ");
print_oparg(p, expr->right);
- printf("\n");
+ fout(p, "\n");
break;
case MODE_VAR:
topsort(set, &sorted, block);
/* now let's print the plantuml representation */
- printf("{\n");
+ fout(p, "{\n");
for (SsaBlock* curr = sorted; curr; curr = curr->next)
{
if (curr->head)
{
if (curr->head)
{
- printf("L%lu:\n", curr->id);
+ fout(p, "L%lu:\n", curr->id);
}
/* print the phis */
for (SsaPhi* phi = curr->phis; phi; phi = phi->next)
{
Symbol* s = symbol_getbyid(p, phi->symid);
- printf(" %%%s.%lu = phi ", s->name, phi->latest_ver);
- emit_type(s->type);
- printf(" ");
+ fout(p, " %%%s.%lu = phi ", s->name, phi->latest_ver);
+ emit_type(p, s->type);
+ fout(p, " ");
for (SsaPhiVar* var = phi->vars; var; var = var->next)
{
- printf("[%%%s.%lu, %%L%lu]", s->name, var->version, var->block);
+ fout(p, "[%%%s.%lu, %%L%lu]", s->name, var->version, var->block);
if (var->next)
{
- printf(", ");
+ fout(p, ", ");
}
}
- puts("");
+ fout(p, "\n");
}
/* print the instructions */
}
}
}
- printf("}\n");
- puts("");
+ fout(p, "}\n");
+ fout(p, "\n");
}
void codegen_main(Parser* p)
{
if (!p->codegen) return; // Bail if just importing symbols
- printf("define i32 @main(i32 %%0, i8* %%1)\n{\n");
+ fout(p, "define i32 @main(i32 %%0, i8* %%1)\n{\n");
for (size_t i = 0; i < p->nsyms; i++)
{
if (p->syms[i].class == SYM_MODULE)
{
- printf(" call void @%s()\n", p->syms[i].name);
+ fout(p, " call void @%s()\n", p->syms[i].name);
}
}
- printf(" ret i32 0\n");
- printf("}\n");
+ fout(p, " ret i32 0\n");
+ fout(p, "}\n");
}
\ No newline at end of file