--- /dev/null
+#include "cerise.h"
+#include <limits.h>
+#include <assert.h>
+
+Type BoolType = {
+ .form = FORM_BOOL,
+ .size = sizeof(bool)
+};
+
+Type IntType = {
+ .form = FORM_INT,
+ .size = sizeof(long)
+};
+
+Type RealType = {
+ .form = FORM_REAL,
+ .size = sizeof(double)
+};
+
+Type StringType = {
+ .form = FORM_STRING,
+ .size = -1
+};
+
+static char* TypeNames[] = {
+ [FORM_BOOL] = "bool",
+ [FORM_INT] = "long",
+ [FORM_REAL] = "double",
+ [FORM_STRING] = "char*"
+};
+
+static char* BinaryOps[] = {
+ ['+'] = "+",
+ ['-'] = "-",
+ ['*'] = "*",
+ ['/'] = "/",
+ ['%'] = "%",
+};
+
+static void load_var(Parser* p, Item* item)
+{
+ (void)p;
+ switch (item->mode)
+ {
+ 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;
+ }
+}
+
+/* Operators
+ *****************************************************************************/
+void binary_op(Parser* p, int op, Item* a, Item* b)
+{
+ char* type = TypeNames[a->type->form];
+ char* oper = BinaryOps[op];
+ 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++;
+}
+
+/* Public Interface
+ *****************************************************************************/
+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_global(Parser* p, char* name, Type* type)
+{
+ printf("%s %s_%s;\n", TypeNames[type->form], p->name, name);
+}
+
+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, char* name, bool exported)
+{
+ char* export = (exported ? "" : "static");
+ if (!name)
+ {
+ printf("\n%svoid %s(void) {\n", export, p->name);
+ }
+ else
+ {
+ assert(!"not implemented");
+ }
+}
+
+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
+ {
+ assert(!"not supported");
+ }
+}
+
+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 = _T%d;\n", p->name, a->imm.s, b->reg);
+ }
+ else
+ {
+ assert(!"bad store op");
+ }
+}
item->imm.s = val;
}
-static int items_const(Item* a, Item* b)
-{
- return ((a->mode == ITEM_CONST) && (b->mode == ITEM_CONST));
-}
-
static void load_var(Parser* p, Item* item)
{
(void)p;
printf(" ret\n");
}
-void codegen_startproc(Parser* p, char* name, long long localsz)
+void codegen_startproc(Parser* p, char* name, bool exported)
{
printf(" .text\n");
if (name)
printf(" .globl %s\n", p->name);
printf("%s:\n", p->name);
}
-
printf(" pushq %%rbp\n");
- if (localsz > 0)
- {
- printf(" movq %%rsp, %%rbp\n");
- printf(" sub $%lld, %%rsp\n\n", localsz);
- }
- else
- {
- printf(" movq %%rsp, %%rbp\n\n");
- }
+ printf(" movq %%rsp, %%rbp\n\n");
p->curr_reg = 1;
}
Module* imports;
Symbol* scope;
char* name;
- long curr_reg;
+ int curr_reg;
} Parser;
static inline void item_dump(Item* a)
/* Code Generation
*****************************************************************************/
+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);
void codegen_imports(Parser* p);
void codegen_global(Parser* p, char* name, Type* type);
void codegen_main(Parser* p);
-void codegen_startproc(Parser* p, char* name, long long localsz);
+void codegen_startproc(Parser* p, char* name, bool exported);
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);