// [IS] = ???
};
-static declare_var(Parser* p, Symbol* sym, int isref)
+static void declare_var(Parser* p, Symbol* sym, int isref)
{
char name[8192];
if (sym->global)
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;
}
(isref ? '&' : ' '), p->name, item->imm.s);
break;
- case ITEM_REG:
- /* nothing to do */
- break;
-
default:
assert(!"bad load_var()");
}
}
}
+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)
char* oper = Operators[op];
assert(oper);
int dest_reg = declare_temp(p, a->type, 0);
- printf(" = _T%d %s _T%d;\n", a->reg, oper, b->reg);
+ printf(" = %s %s %s;\n", temp(a), oper, temp(b));
a->reg = dest_reg;
}
char* oper = Operators[op];
assert(oper);
int dest_reg = declare_temp(p, a->type, 0);
- printf(" = %s _T%d;\n", oper, a->reg);
+ printf(" = %s %s;\n", oper, temp(a));
a->reg = dest_reg;
}
void codegen_store(Parser* p, Item* a, Item* b)
{
-// item_dump(a);
-// item_dump(b);
if (a->mode == ITEM_MVAR && b->reg == 0)
{
printf(" %s_%s = %lld;\n", p->name, a->imm.s, b->imm.i);
}
else if (a->mode == ITEM_MVAR)
{
- printf(" %s_%s = _T%d;\n", p->name, a->imm.s, b->reg);
+ printf(" %s_%s = %s;\n", p->name, a->imm.s, temp(b));
}
else if (a->mode == ITEM_VAR && b->reg == 0)
{
}
else if (a->mode == ITEM_VAR)
{
- printf(" %s = _T%d;\n", a->imm.s, b->reg);
+ printf(" %s = %s;\n", a->imm.s, temp(b));
}
else if (a->mode == ITEM_INDEX)
{
load_var(p, b);
- printf(" _T%d = _T%d;\n", a->reg, b->reg);
+ printf(" %s = %s;\n", temp(a), temp(b));
}
else
{
void codegen_if(Parser* p, Item* item)
{
load_var(p, item);
- printf(" if (_T%d) {\n", item->reg);
+ printf(" if (%s) {\n", temp(item));
}
void codegen_else(Parser* p, Item* item)
printf(" = %s(", item->imm.s);
while (args)
{
- printf("_T%d", args->reg);
+ printf("%s", temp(args));
if (args->next)
{
printf(", ");
void codegen_setarg(Parser* p, Item* item, bool firstarg)
{
+ (void)firstarg;
load_var(p, item);
}
void codegen_return(Parser* p, Item* item)
{
load_var(p, item);
- printf(" return _T%d;\n", item->reg);
+ printf(" return %s;\n", temp(item));
}
void codegen_index(Parser* p, Item* array, Item* index)
{
+ /* load array and index if not already */
+ load_var(p, index);
+ load_var(p, array);
+
+ /* perform range checking */
if (index->mode == ITEM_CONST)
{
if (index->type->form != FORM_INT)
error(p, "negative array index");
}
}
+ else
+ {
+ printf(" __CHECK_RANGE(%s < %d);\n", temp(index), array->type->size);
+ }
- load_var(p, index);
- load_var(p, array);
+ /* emit the operation */
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);
+ printf(" = &%s[%s];\n", temp(array), temp(index));
array->reg = dest_reg;
}
int level;
} Parser;
-static inline void item_dump(Item* a)
-{
- printf("// Item M:%d R:%d ", a->mode, a->reg);
- if (a->mode == ITEM_MVAR)
- {
- printf(" %s", a->imm.s);
- }
- else
- {
- if (a->type->form == FORM_INT)
- {
- printf("%lld", a->imm.i);
- }
- else if (a->type->form == FORM_REAL)
- {
- printf("%f", a->imm.f);
- }
- }
- puts("");
-}
-
// src/stdlib.c
void fatal(char* estr);
void* emalloc(size_t size);
void const_binop(int op, Item* a, Item* b);
void const_unop(Parser* p, int op, Item* a);
+// src/dump.c
+void dump_item(Item* a);
+void dump_symbol(Symbol* a);
+void dump_type(Type* a);
+
/* Backend Code Generation
*****************************************************************************/
extern Type BoolType, IntType, RealType, StringType;