.size = -1
};
-static char* TypeNames[] = {
+static char* TypeNames[FORM_COUNT] = {
[FORM_BOOL] = "bool",
[FORM_INT] = "long",
[FORM_REAL] = "double",
// [IS] = ???
};
+static declare_var(Parser* p, Symbol* sym, int isref)
+{
+ char name[8192];
+ if (sym->global)
+ {
+ printf("%s", (sym->export ? "" : "static "));
+ snprintf(name, sizeof(name), "%s_%s", p->name, sym->name);
+ }
+ else
+ {
+ printf(" ");
+ snprintf(name, sizeof(name), "(%c%s)",
+ (char)(isref ? '*' : ' '), sym->name);
+ }
+
+ if (sym->type->form == FORM_ARRAY)
+ {
+ Type* type = sym->type;
+ for (; type->form == FORM_ARRAY; type = type->base);
+ printf("%s %s", TypeNames[type->form], name);
+ for (type = sym->type; type->form == FORM_ARRAY; type = type->base)
+ {
+ printf("[%d]", type->size);
+ }
+ }
+ else
+ {
+ printf("%s %s", TypeNames[sym->type->form], name);
+ }
+}
+
+static int declare_temp(Parser* p, Type* type, int isref)
+{
+ char name[32];
+ int reg = p->curr_reg;
+ snprintf(name, sizeof(name), "_T%d", reg);
+// puts("TEMP");
+ Symbol sym = {
+ .class = SYM_VAR,
+ .name = name,
+ .type = type,
+ };
+ declare_var(p, &sym, isref);
+// puts("END");
+
+ p->curr_reg++;
+ return reg;
+}
+
static void load_var(Parser* p, Item* item)
{
- (void)p;
- switch (item->mode)
+ if (!item->reg)
{
- case ITEM_CONST:
- /* TODO: range check the constant */
- printf(" const %s _T%d = %lld;\n",
- TypeNames[item->type->form], p->curr_reg, item->imm.i);
- item->reg = p->curr_reg;
- p->curr_reg++;
-
- case ITEM_VAR:
- break;
-
- case ITEM_MVAR:
- /* TODO: range check the constant */
- printf(" const %s _T%d = %s_%s;\n",
- TypeNames[item->type->form], p->curr_reg, p->name, item->imm.s);
- item->reg = p->curr_reg;
- p->curr_reg++;
- break;
-
- case ITEM_REG:
- /* nothing to do */
- break;
+ int isref = (item->type->form == FORM_ARRAY);
+ switch (item->mode)
+ {
+ case ITEM_CONST:
+ /* TODO: range check the constant */
+ item->reg = declare_temp(p, item->type, 0);
+ printf(" = %lld;\n", item->imm.i);
+ break;
+
+ case ITEM_VAR:
+ item->reg = declare_temp(p, item->type, isref);
+ printf(" = %c%s;\n", (isref ? '&' : ' '), item->imm.s);
+ break;
+
+ case ITEM_MVAR:
+ item->reg = declare_temp(p, item->type, isref);
+ printf(" = %c%s_%s;\n",
+ (isref ? '&' : ' '), p->name, item->imm.s);
+ break;
+
+ case ITEM_REG:
+ /* nothing to do */
+ break;
+
+ default:
+ assert(!"bad load_var()");
+ }
}
}
*****************************************************************************/
static void binary_op(Parser* p, int op, Item* a, Item* b)
{
- char* type = TypeNames[a->type->form];
char* oper = Operators[op];
- assert(type && oper);
- printf(" const %s _T%d = _T%d %s _T%d;\n",
- type, p->curr_reg, a->reg, oper, b->reg);
- a->reg = p->curr_reg;
- p->curr_reg++;
+ assert(oper);
+ int dest_reg = declare_temp(p, a->type, 0);
+ printf(" = _T%d %s _T%d;\n", a->reg, oper, b->reg);
+ a->reg = dest_reg;
}
static void unary_op(Parser* p, int op, Item* a)
{
- char* type = TypeNames[a->type->form];
char* oper = Operators[op];
- assert(type && oper);
- printf(" const %s _T%d = %s _T%d;\n",
- type, p->curr_reg, oper, a->reg);
- a->reg = p->curr_reg;
- p->curr_reg++;
+ assert(oper);
+ int dest_reg = declare_temp(p, a->type, 0);
+ printf(" = %s _T%d;\n", oper, a->reg);
+ a->reg = dest_reg;
}
/* Public Interface
void codegen_var(Parser* p, Symbol* sym)
{
- if (sym->global)
- {
- printf("%s%s %s_%s;\n",
- (sym->export ? "" : "static "), TypeNames[sym->type->form], p->name, sym->name);
- }
- else
- {
- printf(" %s %s;\n", TypeNames[sym->type->form], sym->name);
- }
+ declare_var(p, sym, 0);
+ puts(";");
}
void codegen_main(Parser* p)
void codegen_store(Parser* p, Item* a, Item* b)
{
- item_dump(a);
- item_dump(b);
+// item_dump(a);
+// item_dump(b);
if (a->mode == ITEM_MVAR && b->reg == 0)
{
-// if (a->offset)
-// {
-// printf(" (%s*)\n",
-// TypeNames[a->type->form]
-//
-// );
-// }
printf(" %s_%s = %lld;\n", p->name, a->imm.s, b->imm.i);
}
else if (a->mode == ITEM_MVAR)
{
-// if (a->offset)
-// {
-// printf(" (%s*)\n",
-// TypeNames[a->type->form]
-//
-// );
-// }
printf(" %s_%s = _T%d;\n", p->name, a->imm.s, b->reg);
}
+ else if (a->mode == ITEM_VAR && b->reg == 0)
+ {
+ printf(" %s = %lld;\n", a->imm.s, b->imm.i);
+ }
+ else if (a->mode == ITEM_VAR)
+ {
+ printf(" %s = _T%d;\n", a->imm.s, b->reg);
+ }
+ else if (a->mode == ITEM_INDEX)
+ {
+ load_var(p, b);
+ printf(" _T%d = _T%d;\n", a->reg, b->reg);
+ }
else
{
assert(!"bad store op");
void codegen_call(Parser* p, Item* item, Item* args)
{
- printf(" const long _T%d = %s(", p->curr_reg, item->imm.s);
+ int dest_reg = declare_temp(p, item->type, 0);
+ printf(" = %s(", item->imm.s);
while (args)
{
printf("_T%d", args->reg);
}
args = args->next;
}
- item->reg = p->curr_reg;
- p->curr_reg++;
+ item->reg = dest_reg;
printf(");\n");
}
void codegen_return(Parser* p, Item* item)
{
- if (item)
- {
- load_var(p, item);
- printf(" return _T%d;\n", item->reg);
- }
+ load_var(p, item);
+ printf(" return _T%d;\n", item->reg);
}
void codegen_index(Parser* p, Item* array, Item* index)
{
-// codegen_binop(p, '*', index, base);
if (index->mode == ITEM_CONST)
{
if (index->type->form != FORM_INT)
{
error(p, "negative array index");
}
-
- array->offset = index->imm.i;
}
+
+ load_var(p, index);
+ load_var(p, array);
+ array->type = array->type->base;
+ array->mode = ITEM_INDEX;
+ int dest_reg = declare_temp(p, array->type, 1);
+ printf(" = _T%d[_T%d]\;\n", array->reg, index->reg);
+ array->reg = dest_reg;
}