};
static char* TypeNames[FORM_COUNT] = {
- [FORM_BOOL] = "_Bool",
- [FORM_INT] = "long",
- [FORM_REAL] = "double",
+ [FORM_BOOL] = "Bool",
+ [FORM_INT] = "Int",
+ [FORM_REAL] = "Real",
[FORM_STRING] = "char*"
};
// [IS] = ???
};
-static void declare_var(Parser* p, Symbol* sym, int isref)
+char* typetoptr(Type* type)
+{
+ if (type->form == FORM_BOOL)
+ {
+ return "Bool*";
+ }
+ else if (type->form == FORM_INT)
+ {
+ return "Int*";
+ }
+ else if (type->form == FORM_REAL)
+ {
+ return "Real*";
+ }
+// else if (type->form == FORM_ARRAY)
+// {
+// return "(*)[]";
+// }
+// else if (type->form == FORM_RECORD)
+// {
+// return
+// }
+ else
+ {
+ assert(!"unimplemented type output");
+ }
+}
+
+static void make_var(Parser* p, Symbol* sym, int isref)
{
char name[8192];
if (sym->global)
}
else
{
- printf(" ");
snprintf(name, sizeof(name), "(%c%s)",
(char)(isref ? '*' : ' '), sym->name);
}
printf("[%d]", type->size);
}
}
+ else if (sym->type->form == FORM_RECORD)
+ {
+ printf("char %s[%d]", name, sym->type->size);
+ }
else
{
printf("%s %s", TypeNames[sym->type->form], name);
}
}
+static void declare_var(Parser* p, Symbol* sym, int isref)
+{
+ if (!sym->global)
+ {
+ printf(" ");
+ }
+ make_var(p, sym, isref);
+}
+
+
static int declare_temp(Parser* p, Type* type, int isref)
{
char name[32];
.name = name,
.type = type,
};
- declare_var(p, &sym, isref);
+ if (type->form == FORM_RECORD)
+ {
+ printf(" char* %s", name);
+ }
+ else
+ {
+ declare_var(p, &sym, isref);
+ }
p->curr_reg++;
return reg;
}
+static char* temp(Item* a)
+{
+ char name[32];
+ if (a->mode == ITEM_INDEX)
+ {
+ snprintf(name, sizeof(name), "(*_T%d)", a->reg);
+ }
+ else if (a->mode == ITEM_FIELD)
+ {
+ snprintf(name, sizeof(name), "*((%s)_T%d)", typetoptr(a->type), a->reg);
+ }
+ else
+ {
+ snprintf(name, sizeof(name), "(_T%d)", a->reg);
+ }
+ return strdup(name);
+}
+
static void load_var(Parser* p, Item* item)
{
if (!item->reg)
{
- int isref = (item->type->form == FORM_ARRAY);
+ int isref = (
+ (item->type->form == FORM_ARRAY)
+ || (item->type->form == FORM_RECORD)
+ );
switch (item->mode)
{
case ITEM_CONST:
case ITEM_VAR:
item->reg = declare_temp(p, item->type, isref);
- printf(" = %c%s;\n", (isref ? '&' : ' '), item->imm.s);
+ if (item->type->form == FORM_RECORD)
+ {
+ printf(" = (char*)&%s[0];\n", item->imm.s);
+ }
+ else
+ {
+ 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);
+ if (item->type->form == FORM_RECORD)
+ {
+ printf(" = &%s_%s[0];\n", p->name, item->imm.s);
+ }
+ else
+ {
+ printf(" = %c%s_%s;\n", (isref ? '&' : ' '), p->name, item->imm.s);
+ }
break;
default:
}
}
-static char* temp(Item* a)
-{
- char name[32];
- snprintf(name, sizeof(name), "(%c_T%d)",
- (a->mode == ITEM_INDEX ? '*' : ' '),
- a->reg);
- return strdup(name);
-}
-
/* Operator Handling
*****************************************************************************/
static void binary_op(Parser* p, int op, Item* a, Item* b)
proc->name);
for (Symbol* arg = proc->desc; arg; arg = arg->next)
{
- printf("%s %s", TypeNames[arg->type->form], arg->name);
+ make_var(p, arg, false);
if (arg->next)
{
printf(", ");
load_var(p, b);
printf(" %s = %s;\n", temp(a), temp(b));
}
+ else if (a->mode == ITEM_FIELD)
+ {
+ load_var(p, b);
+// printf(" *((%s)%s) = %s;\n", typetoptr(a->type), temp(a), temp(b));
+ printf(" %s = %s;\n", temp(a), temp(b));
+ }
else
{
assert(!"bad store op");
printf(" = &%s[%s];\n", temp(array), temp(index));
array->reg = dest_reg;
}
+
+Field* get_field(Parser* p, Type* type, char* name)
+{
+ Field* curr = type->fields;
+ while (curr)
+ {
+ if (curr->name && !strcmp(curr->name, name))
+ {
+ break;
+ }
+ curr = curr->next;
+ }
+ if (!curr)
+ {
+ error(p, "record has no such field '%s'\n", name);
+ }
+ return curr;
+}
+
+void codegen_field(Parser* p, Item* record, char* name)
+{
+ load_var(p, record);
+ Field* f = get_field(p, record->type, name);
+ record->mode = ITEM_FIELD;
+ record->type = f->type;
+ printf(" char* _T%d", p->curr_reg);
+ p->curr_reg++;
+ printf(" = _T%d + %ld;\n", record->reg, f->offset);
+ record->reg = p->curr_reg-1;
+}