.form = FORM_STRING,
.size = -1
};
-
-static char* TypeNames[FORM_COUNT] = {
- [FORM_BOOL] = "Bool",
- [FORM_INT] = "Int",
- [FORM_REAL] = "Real",
- [FORM_STRING] = "Byte*"
-};
-
-static char* Operators[] = {
- ['+'] = "+",
- ['-'] = "-",
- ['*'] = "*",
- ['/'] = "/",
- ['%'] = "%",
- [AND] = "&&",
- [OR] = "||",
- [NOT] = "!",
- [EQ] = "==",
- [NEQ] = "!=",
- ['<'] = "<",
- [LTEQ] = "<=",
- ['>'] = ">",
- [GTEQ] = ">=",
-// [IS] = ???
-};
-
-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)
- {
- printf("%s", (sym->export ? "" : "static "));
- snprintf(name, sizeof(name), "%s_%s", p->name, sym->name);
- }
- else
- {
- snprintf(name, sizeof(name), "(%c%s)",
- (char)(isref ? '*' : ' '), sym->name);
- }
-
- if (sym->type->form == FORM_ARRAY)
- {
- Type* type = sym->type;
- long size = 1;
- for (; type->form == FORM_ARRAY; type = type->base)
- {
- size = size * type->size;
- }
- size = size * type->size;
- printf("Byte %s[%ld]", name, size);
- }
- else if (sym->type->form == FORM_RECORD)
- {
- printf("Byte %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];
- int reg = p->curr_reg;
- snprintf(name, sizeof(name), "_T%d", reg);
- Symbol sym = {
- .class = SYM_VAR,
- .name = name,
- .type = type,
- };
- if ((type->form == FORM_RECORD) || (type->form == FORM_ARRAY))
- {
- printf(" Byte* %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 + _T%lld)", a->reg, a->imm.i);
- }
- else if (a->mode == ITEM_FIELD)
- {
- snprintf(name, sizeof(name), "*((%s)(_T%d + %lld))", typetoptr(a->type), a->reg, a->imm.i);
- }
- 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)
- || (item->type->form == FORM_RECORD)
- );
- 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);
- if (item->type->form == FORM_RECORD)
- {
- printf(" = (Byte*)&%s[0];\n", item->imm.s);
- }
- else
- {
- printf(" = %c%s;\n", (isref ? '&' : ' '), item->imm.s);
- }
- item->imm.i = 0;
- break;
-
- case ITEM_MVAR:
- item->reg = declare_temp(p, item->type, isref);
- 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);
- }
- item->imm.i = 0;
- break;
-
- default:
- assert(!"bad load_var()");
- }
- }
-}
-
-/* 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(" = %s %s %s;\n", temp(a), oper, temp(b));
- a->reg = dest_reg;
-}
-
-static void unary_op(Parser* p, int op, Item* a)
-{
- char* oper = Operators[op];
- assert(oper);
- int dest_reg = declare_temp(p, a->type, 0);
- printf(" = %s %s;\n", oper, temp(a));
- a->reg = dest_reg;
-}
-
-/* Public Interface
- *****************************************************************************/
-
-void codegen_startmod(Parser* p)
-{
- (void)p;
- printf("typedef char Byte;\n");
- printf("typedef _Bool Bool;\n");
- printf("typedef long Int;\n");
- printf("typedef double Real;\n");
- puts("");
-}
-
-void codegen_endmod(Parser* p)
-{
- (void)p;
-}
-
-void codegen_setint(Item* item, Type* type, long long val)
-{
- item->mode = ITEM_CONST;
- item->type = type;
- item->reg = 0;
- item->imm.i = val;
-}
-
-void codegen_setreal(Item* item, double val)
-{
- item->mode = ITEM_CONST;
- item->type = &RealType;
- item->reg = 0;
- item->imm.f = val;
-}
-
-void codegen_setstr(Item* item, char* val)
-{
- item->mode = ITEM_CONST;
- item->type = &StringType;
- item->reg = 0;
- item->imm.s = val;
-}
-
-void codegen_imports(Parser* p)
-{
- (void)p;
-}
-
-void codegen_var(Parser* p, Symbol* sym)
-{
- declare_var(p, sym, 0);
- puts(";");
-}
-
-void codegen_main(Parser* p)
-{
- (void)p;
- printf("\nint main(int argc, char** argv) {\n");
- printf(" (void)argc, (void)argv;\n");
- printf(" return 0;\n");
- printf("}\n");
-}
-
-void codegen_startproc(Parser* p, Symbol* proc)
-{
- if (!proc)
- {
- printf("\nvoid %s(void) {\n", p->name);
- }
- else
- {
- char* export = (proc->export ? "" : "static ");
- printf("\n%s%s %s_%s(",
- export,
- (proc->type ? TypeNames[proc->type->base->form] : "void"),
- p->name,
- proc->name);
-
- for (Field* arg = proc->type->fields; arg; arg = arg->next)
- {
- Symbol sym = { .type = arg->type, .name = arg->name };
- make_var(p, &sym, false);
- if (arg->next)
- {
- printf(", ");
- }
- }
- printf(") {\n");
- }
-}
-
-void codegen_endproc(Parser* p)
-{
- printf("}\n");
- (void)p;
-}
-
-void codegen_unop(Parser* p, int op, Item* a)
-{
- if (a->mode == ITEM_CONST)
- {
- const_unop(p, op, a);
- }
- else
- {
- load_var(p, a);
- unary_op(p, op, a);
- }
-}
-
-void codegen_binop(Parser* p, int op, Item* a, Item* b)
-{
- if (items_const(a, b))
- {
- const_binop(op, a, b);
- }
- else
- {
- load_var(p, a);
- load_var(p, b);
- binary_op(p, op, a, b);
- }
-}
-
-void codegen_store(Parser* p, Item* a, Item* 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 = %s;\n", p->name, a->imm.s, temp(b));
- }
- 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 = %s;\n", a->imm.s, temp(b));
- }
- else if (a->mode == ITEM_INDEX)
- {
- 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;\n", temp(a), temp(b));
- }
- else
- {
- assert(!"bad store op");
- }
-}
-
-void codegen_if(Parser* p, Item* item)
-{
- load_var(p, item);
- printf(" if (%s) {\n", temp(item));
-}
-
-void codegen_else(Parser* p, Item* item)
-{
- (void)p, (void)item;
- printf(" } else {\n");
-}
-
-void codegen_endif(Parser* p, long elsifs, Item* item)
-{
- (void)p, (void)item;
- printf(" ");
- for (long i = 0; i < elsifs; i ++)
- {
- printf("}");
- }
- printf("}\n");
-}
-
-void codegen_prepcall(Parser* p, Item* item)
-{
- (void)p, (void)item;
-}
-
-void codegen_call(Parser* p, Item* item, Item* args)
-{
- int dest_reg = declare_temp(p, item->type, 0);
- printf(" = %s(", item->imm.s);
- while (args)
- {
- printf("%s", temp(args));
- if (args->next)
- {
- printf(", ");
- }
- args = args->next;
- }
- item->reg = dest_reg;
- printf(");\n");
-}
-
-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 %s;\n", temp(item));
-}
-
-void codegen_index(Parser* p, Item* array, Item* index)
-{
- load_var(p, array);
- load_var(p, index);
-
- /* perform range checking */
- if (index->mode == ITEM_CONST)
- {
- if (index->type->form != FORM_INT)
- {
- error(p, "array indexes must be of integral type");
- }
- else if (index->imm.i >= array->type->size)
- {
- error(p, "array index out of bounds");
- }
- else if (index->imm.i < 0)
- {
- error(p, "negative array index");
- }
- index->imm.i = (index->imm.i * size_of(array->type->base));
- }
- else
- {
- printf(" __CHECK_RANGE(%s < %d);\n", temp(index), array->type->size);
- int dest_reg = declare_temp(p, index->type, 0);
- printf(" = %s * %ld;\n", temp(index), size_of(array->type->base));
- index->reg = dest_reg;
- }
-
- if (array->mode == ITEM_INDEX)
- {
- int dest_reg = declare_temp(p, index->type, 0);
- printf(" = _T%lld + %s;\n", array->imm.i, temp(index));
- index->reg = dest_reg;
- }
-
- /* emit the operation to calculate offset */
- array->type = array->type->base;
- array->mode = ITEM_INDEX;
- array->imm.i = index->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;
- record->imm.i += f->offset;
-}
+//
+//static char* TypeNames[FORM_COUNT] = {
+// [FORM_BOOL] = "Bool",
+// [FORM_INT] = "Int",
+// [FORM_REAL] = "Real",
+// [FORM_STRING] = "Byte*"
+//};
+//
+//static char* Operators[] = {
+// ['+'] = "+",
+// ['-'] = "-",
+// ['*'] = "*",
+// ['/'] = "/",
+// ['%'] = "%",
+// [AND] = "&&",
+// [OR] = "||",
+// [NOT] = "!",
+// [EQ] = "==",
+// [NEQ] = "!=",
+// ['<'] = "<",
+// [LTEQ] = "<=",
+// ['>'] = ">",
+// [GTEQ] = ">=",
+//// [IS] = ???
+//};
+//
+//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)
+// {
+// printf("%s", (sym->export ? "" : "static "));
+// snprintf(name, sizeof(name), "%s_%s", p->name, sym->name);
+// }
+// else
+// {
+// snprintf(name, sizeof(name), "(%c%s)",
+// (char)(isref ? '*' : ' '), sym->name);
+// }
+//
+// if (sym->type->form == FORM_ARRAY)
+// {
+// Type* type = sym->type;
+// long size = 1;
+// for (; type->form == FORM_ARRAY; type = type->base)
+// {
+// size = size * type->size;
+// }
+// size = size * type->size;
+// printf("Byte %s[%ld]", name, size);
+// }
+// else if (sym->type->form == FORM_RECORD)
+// {
+// printf("Byte %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];
+// int reg = p->curr_reg;
+// snprintf(name, sizeof(name), "_T%d", reg);
+// Symbol sym = {
+// .class = SYM_VAR,
+// .name = name,
+// .type = type,
+// };
+// if ((type->form == FORM_RECORD) || (type->form == FORM_ARRAY))
+// {
+// printf(" Byte* %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 + _T%lld)", a->reg, a->imm.i);
+// }
+// else if (a->mode == ITEM_FIELD)
+// {
+// snprintf(name, sizeof(name), "*((%s)(_T%d + %lld))", typetoptr(a->type), a->reg, a->imm.i);
+// }
+// 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)
+// || (item->type->form == FORM_RECORD)
+// );
+// 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);
+// if (item->type->form == FORM_RECORD)
+// {
+// printf(" = (Byte*)&%s[0];\n", item->imm.s);
+// }
+// else
+// {
+// printf(" = %c%s;\n", (isref ? '&' : ' '), item->imm.s);
+// }
+// item->imm.i = 0;
+// break;
+//
+// case ITEM_MVAR:
+// item->reg = declare_temp(p, item->type, isref);
+// 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);
+// }
+// item->imm.i = 0;
+// break;
+//
+// default:
+// assert(!"bad load_var()");
+// }
+// }
+//}
+//
+///* 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(" = %s %s %s;\n", temp(a), oper, temp(b));
+// a->reg = dest_reg;
+//}
+//
+//static void unary_op(Parser* p, int op, Item* a)
+//{
+// char* oper = Operators[op];
+// assert(oper);
+// int dest_reg = declare_temp(p, a->type, 0);
+// printf(" = %s %s;\n", oper, temp(a));
+// a->reg = dest_reg;
+//}
+//
+///* Public Interface
+// *****************************************************************************/
+//
+//void codegen_startmod(Parser* p)
+//{
+// (void)p;
+// printf("typedef char Byte;\n");
+// printf("typedef _Bool Bool;\n");
+// printf("typedef long Int;\n");
+// printf("typedef double Real;\n");
+// puts("");
+//}
+//
+//void codegen_endmod(Parser* p)
+//{
+// (void)p;
+//}
+//
+//void codegen_setint(Item* item, Type* type, long long val)
+//{
+// item->mode = ITEM_CONST;
+// item->type = type;
+// item->reg = 0;
+// item->imm.i = val;
+//}
+//
+//void codegen_setreal(Item* item, double val)
+//{
+// item->mode = ITEM_CONST;
+// item->type = &RealType;
+// item->reg = 0;
+// item->imm.f = val;
+//}
+//
+//void codegen_setstr(Item* item, char* val)
+//{
+// item->mode = ITEM_CONST;
+// item->type = &StringType;
+// item->reg = 0;
+// item->imm.s = val;
+//}
+//
+//void codegen_imports(Parser* p)
+//{
+// (void)p;
+//}
+//
+//void codegen_var(Parser* p, Symbol* sym)
+//{
+// declare_var(p, sym, 0);
+// puts(";");
+//}
+//
+//void codegen_main(Parser* p)
+//{
+// (void)p;
+// printf("\nint main(int argc, char** argv) {\n");
+// printf(" (void)argc, (void)argv;\n");
+// printf(" return 0;\n");
+// printf("}\n");
+//}
+//
+//void codegen_startproc(Parser* p, Symbol* proc)
+//{
+// if (!proc)
+// {
+// printf("\nvoid %s(void) {\n", p->name);
+// }
+// else
+// {
+// char* export = (proc->export ? "" : "static ");
+// printf("\n%s%s %s_%s(",
+// export,
+// (proc->type ? TypeNames[proc->type->base->form] : "void"),
+// p->name,
+// proc->name);
+//
+// for (Field* arg = proc->type->fields; arg; arg = arg->next)
+// {
+// Symbol sym = { .type = arg->type, .name = arg->name };
+// make_var(p, &sym, false);
+// if (arg->next)
+// {
+// printf(", ");
+// }
+// }
+// printf(") {\n");
+// }
+//}
+//
+//void codegen_endproc(Parser* p)
+//{
+// printf("}\n");
+// (void)p;
+//}
+//
+//void codegen_unop(Parser* p, int op, Item* a)
+//{
+// if (a->mode == ITEM_CONST)
+// {
+// const_unop(p, op, a);
+// }
+// else
+// {
+// load_var(p, a);
+// unary_op(p, op, a);
+// }
+//}
+//
+//void codegen_binop(Parser* p, int op, Item* a, Item* b)
+//{
+// if (items_const(a, b))
+// {
+// const_binop(op, a, b);
+// }
+// else
+// {
+// load_var(p, a);
+// load_var(p, b);
+// binary_op(p, op, a, b);
+// }
+//}
+//
+//void codegen_store(Parser* p, Item* a, Item* 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 = %s;\n", p->name, a->imm.s, temp(b));
+// }
+// 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 = %s;\n", a->imm.s, temp(b));
+// }
+// else if (a->mode == ITEM_INDEX)
+// {
+// 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;\n", temp(a), temp(b));
+// }
+// else
+// {
+// assert(!"bad store op");
+// }
+//}
+//
+//void codegen_if(Parser* p, Item* item)
+//{
+// load_var(p, item);
+// printf(" if (%s) {\n", temp(item));
+//}
+//
+//void codegen_else(Parser* p, Item* item)
+//{
+// (void)p, (void)item;
+// printf(" } else {\n");
+//}
+//
+//void codegen_endif(Parser* p, long elsifs, Item* item)
+//{
+// (void)p, (void)item;
+// printf(" ");
+// for (long i = 0; i < elsifs; i ++)
+// {
+// printf("}");
+// }
+// printf("}\n");
+//}
+//
+//void codegen_prepcall(Parser* p, Item* item)
+//{
+// (void)p, (void)item;
+//}
+//
+//void codegen_call(Parser* p, Item* item, Item* args)
+//{
+// int dest_reg = declare_temp(p, item->type, 0);
+// printf(" = %s(", item->imm.s);
+// while (args)
+// {
+// printf("%s", temp(args));
+// if (args->next)
+// {
+// printf(", ");
+// }
+// args = args->next;
+// }
+// item->reg = dest_reg;
+// printf(");\n");
+//}
+//
+//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 %s;\n", temp(item));
+//}
+//
+//void codegen_index(Parser* p, Item* array, Item* index)
+//{
+// load_var(p, array);
+// load_var(p, index);
+//
+// /* perform range checking */
+// if (index->mode == ITEM_CONST)
+// {
+// if (index->type->form != FORM_INT)
+// {
+// error(p, "array indexes must be of integral type");
+// }
+// else if (index->imm.i >= array->type->size)
+// {
+// error(p, "array index out of bounds");
+// }
+// else if (index->imm.i < 0)
+// {
+// error(p, "negative array index");
+// }
+// index->imm.i = (index->imm.i * size_of(array->type->base));
+// }
+// else
+// {
+// printf(" __CHECK_RANGE(%s < %d);\n", temp(index), array->type->size);
+// int dest_reg = declare_temp(p, index->type, 0);
+// printf(" = %s * %ld;\n", temp(index), size_of(array->type->base));
+// index->reg = dest_reg;
+// }
+//
+// if (array->mode == ITEM_INDEX)
+// {
+// int dest_reg = declare_temp(p, index->type, 0);
+// printf(" = _T%lld + %s;\n", array->imm.i, temp(index));
+// index->reg = dest_reg;
+// }
+//
+// /* emit the operation to calculate offset */
+// array->type = array->type->base;
+// array->mode = ITEM_INDEX;
+// array->imm.i = index->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;
+// record->imm.i += f->offset;
+//}
.form = FORM_STRING,
.size = -1
};
-//
-//
-//static size_t MaxBlocks = 0;
-//static size_t NumBlocks = 0;
-//static Block* Blocks = NULL;
-//static size_t Level = 0;
-//static struct {
-// size_t curr;
-// size_t join;
-//} Levels[32] = {0};
-//
-//static size_t block_new(void)
-//{
-// if (NumBlocks == MaxBlocks)
-// {
-// MaxBlocks = (MaxBlocks ? 16u : (MaxBlocks << 1u));
-// Blocks = realloc(Blocks, MaxBlocks * sizeof(Block));
-// }
-// memset(&Blocks[NumBlocks], 0, sizeof(Block));
-// NumBlocks++;
-// return (NumBlocks-1);
-//}
-//
-//static void put_op(Operation* op)
-//{
-// Block* block = &Blocks[Levels[Level].curr];
-// if (block->nops == block->mops)
-// {
-// block->mops = (block->mops ? 4u : (block->mops << 1u));
-// block->ops = realloc(block->ops, block->mops * sizeof(Operation));
-// }
-// block->ops[block->nops++] = *op;
-//}
-//
-//static void load_var(Parser* p, Item* item)
-//{
-// if (!item->reg)
-// {
-// switch (item->mode)
-// {
-// case ITEM_CONST:
-// /* TODO: range check the constant */
-// item->reg = p->curr_reg++;
-// printf(" $%d = %lld;\n", item->reg, item->imm.i);
-// break;
-//
-//// case ITEM_VAR:
-//// item->reg = declare_temp(p, item->type, isref);
-//// if (item->type->form == FORM_RECORD)
-//// {
-//// printf(" = (Byte*)&%s[0];\n", item->imm.s);
-//// }
-//// else
-//// {
-//// printf(" = %c%s;\n", (isref ? '&' : ' '), item->imm.s);
-//// }
-//// item->imm.i = 0;
-//// break;
-////
-//// case ITEM_MVAR:
-//// item->reg = declare_temp(p, item->type, isref);
-//// 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);
-//// }
-//// item->imm.i = 0;
-//// break;
-//
-// default:
-// assert(!"bad load_var()");
-// }
-// }
-//}
-//
-//
-//
-//
-//void codegen_startmod(Parser* p)
-//{
-// (void)p;
-//}
-//
-//void codegen_endmod(Parser* p)
-//{
-// (void)p;
-//}
-//
-//void codegen_setint(Item* item, Type* type, long long val)
-//{
-// item->mode = ITEM_CONST;
-// item->type = type;
-// item->reg = 0;
-// item->imm.i = val;
-//}
-//
-//void codegen_setreal(Item* item, double val)
-//{
-// item->mode = ITEM_CONST;
-// item->type = &RealType;
-// item->reg = 0;
-// item->imm.f = val;
-//}
-//
-//void codegen_setstr(Item* item, char* val)
-//{
-// item->mode = ITEM_CONST;
-// item->type = &StringType;
-// item->reg = 0;
-// item->imm.s = val;
-//}
-//
-//void codegen_imports(Parser* p)
-//{
-// (void)p;
-//}
-//
-//void codegen_var(Parser* p, Symbol* sym)
-//{
-// (void)p, (void)sym;
-//}
-//
-//void codegen_main(Parser* p)
-//{
-// (void)p;
-//}
-//
-//void codegen_startproc(Parser* p, Symbol* proc)
-//{
-// (void)p, (void)proc;
-// printf("func %s(){\n", (proc ? proc->name : p->name));
-// printf("L%lu:\n", block_new());
-//}
-//
-//void codegen_endproc(Parser* p)
-//{
-// (void)p;
-// printf("}\n");
-//}
-//
-//void codegen_unop(Parser* p, int op, Item* a)
-//{
-// (void)p, (void)op, (void)a;
-//}
-//
-//void codegen_binop(Parser* p, int op, Item* a, Item* b)
-//{
-// (void)p, (void)op, (void)a, (void)b;
-//}
-//
-//void codegen_store(Parser* p, Item* a, Item* b)
-//{
-// (void)p, (void)a, (void)b;
-// load_var(p, b);
-//}
-//
-//void codegen_if(Parser* p, Item* item)
-//{
-// (void)p, (void)item;
-//}
-//
-//void codegen_else(Parser* p, Item* item)
-//{
-// (void)p, (void)item;
-//}
-//
-//void codegen_endif(Parser* p, long elsifs, Item* item)
-//{
-// (void)p, (void)elsifs, (void)item;
-//}
-//
-//void codegen_prepcall(Parser* p, Item* item)
-//{
-// (void)p, (void)item;
-//}
-//
-//void codegen_call(Parser* p, Item* item, Item* args)
-//{
-// (void)p, (void)item, (void)args;
-//}
-//
-//void codegen_setarg(Parser* p, Item* item, bool firstarg)
-//{
-// (void)p, (void)item, (void)firstarg;
-//}
-//
-//void codegen_return(Parser* p, Item* item)
-//{
-// (void)p, (void)item;
-//}
-//
-//void codegen_index(Parser* p, Item* array, Item* index)
-//{
-// (void)p, (void)array, (void)index;
-//}
-//
-//void codegen_field(Parser* p, Item* record, char* name)
-//{
-// (void)p, (void)record, (void)name;
-//}
-//
int size;
} Type;
-typedef union {
- long long i;
- double f;
- char* s;
-} Operand;
+typedef struct {
+ int code : 28;
+ int mode : 4;
+ struct AstNode* next;
+ Type* type;
+} AstNodeHeader;
-struct AstNode;
+typedef struct AstNode {
+ AstNodeHeader hdr;
+ struct AstNode* links[3];
+} AstNode;
typedef struct Symbol {
enum{
char* name;
Type* type;
struct Symbol* desc;
- struct AstNode* value;
+ AstNode* value;
long nargs;
int export : 1;
int global : 1;
char* alias;
} Module;
-typedef struct Item {
- struct Item* next;
- enum {
- ITEM_CONST, ITEM_VAR, ITEM_MVAR, ITEM_REG, ITEM_INDEX, ITEM_FIELD
- } mode;
- Symbol* sym;
- Type* type;
- int reg;
- Operand imm;
-} Item;
-
typedef struct {
LexFile* done;
LexFile* file;
void symbol_closescope(Parser* p, size_t scope);
// src/type_checks.c
-void check_int(Parser* p, Item* item);
-void check_ints(Parser* p, Item* a, Item* b);
-void check_real(Parser* p, Item* item);
-void check_reals(Parser* p, Item* a, Item* b);
-void check_num(Parser* p, Item* a);
-void check_nums(Parser* p, Item* a, Item* b);
-void check_bool(Parser* p, Item* item);
-void check_bools(Parser* p, Item* a, Item* b);
-void check_types(Parser* p, Item* a, Item* b);
+void check_int(Parser* p, AstNode* a);
+void check_ints(Parser* p, AstNode* a, AstNode* b);
+void check_real(Parser* p, AstNode* a);
+void check_reals(Parser* p, AstNode* a, AstNode* b);
+void check_num(Parser* p, AstNode* a);
+void check_nums(Parser* p, AstNode* a, AstNode* b);
+void check_bool(Parser* p, AstNode* a);
+void check_bools(Parser* p, AstNode* a, AstNode* b);
+void check_types(Parser* p, AstNode* a, AstNode* b);
// src/grammar.c
void compile(char* fname);
-// src/const_ops.c
-int items_const(Item* a, Item* b);
-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);
-
// src/align.c
long align_item(long offset, long size);
long size_of(Type* type);
-/* Backend Code Generation
- *****************************************************************************/
-extern Type VoidType, BoolType, IntType, RealType, StringType;
-
-void codegen_startmod(Parser* p);
-void codegen_endmod(Parser* p);
-void codegen_setint(Item* item, Type* type, long long val);
-void codegen_setreal(Item* item, double val);
-void codegen_setstr(Item* item, char* val);
-void codegen_imports(Parser* p);
-void codegen_var(Parser* p, Symbol* sym);
-void codegen_main(Parser* p);
-void codegen_startproc(Parser* p, Symbol* func);
-void codegen_endproc(Parser* p);
-void codegen_unop(Parser* p, int op, Item* a);
-void codegen_binop(Parser* p, int op, Item* a, Item* b);
-void codegen_store(Parser* p, Item* a, Item* b);
-void codegen_if(Parser* p, Item* item);
-void codegen_else(Parser* p, Item* item);
-void codegen_endif(Parser* p, long elsifs, Item* item);
-void codegen_prepcall(Parser* p, Item* item);
-void codegen_call(Parser* p, Item* item, Item* args);
-void codegen_setarg(Parser* p, Item* item, bool firstarg);
-void codegen_return(Parser* p, Item* item);
-void codegen_index(Parser* p, Item* array, Item* index);
-void codegen_field(Parser* p, Item* record, char* name);
-
-/* Abstract Syntax Tree Definition
- *****************************************************************************/
-//enum AstMode {
-// AST_CONST = 0,
-// AST_EXPR,
-// AST_CTRL,
-//};
-
-typedef struct {
- int code : 28;
- int mode : 4;
- struct AstNode* next;
- Type* type;
-} AstNodeHeader;
-
-typedef struct AstNode {
- AstNodeHeader hdr;
- struct AstNode* links[3];
-} AstNode;
-
-typedef struct {
- AstNodeHeader hdr;
- union {
- long long i;
- double f;
- char* s;
- } val;
-} AstValue;
-
+// src/ast.c
AstNode* ast_ident(Parser* p, long long index);
AstNode* ast_bool(bool val);
AstNode* ast_int(long long val);
AstNode* ast_if(AstNode* cond, AstNode* br1, AstNode* br2);
AstNode* ast_return(AstNode* expr);
void ast_print(AstNode* expr);
+
+/* Backend Code Generation and Base Type Definitions
+ *****************************************************************************/
+extern Type VoidType, BoolType, IntType, RealType, StringType;