aboutsummaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c121
1 files changed, 91 insertions, 30 deletions
diff --git a/compile.c b/compile.c
index b686f8f9..f5df7fbd 100644
--- a/compile.c
+++ b/compile.c
@@ -18,19 +18,18 @@ CORD compile_type(type_ast_t *t)
static inline CORD compile_statement(ast_t *ast)
{
- CORD code = compile(ast);
switch (ast->tag) {
- case If: case For: case While: case FunctionDef:
- return code;
+ case If: case For: case While: case FunctionDef: case Return: case TypeDef: case Declare: case Assign: case UpdateAssign:
+ return compile(ast);
default:
- return CORD_cat(code, ";");
+ return CORD_asprintf("(void)%r;", compile(ast));
}
}
CORD compile(ast_t *ast)
{
switch (ast->tag) {
- case Nil: return "NULL";
+ case Nil: return CORD_asprintf("(%r)NULL", compile_type(Match(ast, Nil)->type));
case Bool: return Match(ast, Bool)->b ? "true" : "false";
case Var: return Match(ast, Var)->var.name;
case Int: return CORD_asprintf("((Int%ld_t)%ld)", Match(ast, Int)->precision, Match(ast, Int)->i);
@@ -40,7 +39,7 @@ CORD compile(ast_t *ast)
auto unop = Match(ast, UnaryOp);
CORD expr = compile(unop->value);
switch (unop->op) {
- case UNOP_NOT: return CORD_cat("!", expr);
+ case UNOP_NOT: return CORD_asprintf("not(%r)", expr);
case UNOP_NEGATIVE: return CORD_cat("-", expr);
case UNOP_HEAP_ALLOCATE: return CORD_asprintf("__heap(%r)", expr);
case UNOP_STACK_REFERENCE: return CORD_asprintf("__stack(%r)", expr);
@@ -55,7 +54,8 @@ CORD compile(ast_t *ast)
switch (binop->op) {
case BINOP_MULT: return CORD_asprintf("(%r * %r)", lhs, rhs);
case BINOP_DIVIDE: return CORD_asprintf("(%r / %r)", lhs, rhs);
- case BINOP_MOD: return CORD_asprintf("(%r %% %r)", lhs, rhs);
+ case BINOP_MOD: return CORD_asprintf("mod(%r, %r)", lhs, rhs);
+ case BINOP_MOD1: return CORD_asprintf("mod1(%r, %r)", lhs, rhs);
case BINOP_PLUS: return CORD_asprintf("(%r + %r)", lhs, rhs);
case BINOP_MINUS: return CORD_asprintf("(%r - %r)", lhs, rhs);
case BINOP_LSHIFT: return CORD_asprintf("(%r << %r)", lhs, rhs);
@@ -66,8 +66,9 @@ CORD compile(ast_t *ast)
case BINOP_LE: return CORD_asprintf("(%r <= %r)", lhs, rhs);
case BINOP_GT: return CORD_asprintf("(%r > %r)", lhs, rhs);
case BINOP_GE: return CORD_asprintf("(%r >= %r)", lhs, rhs);
- case BINOP_AND: return CORD_asprintf("(%r && %r)", lhs, rhs);
- case BINOP_OR: return CORD_asprintf("(%r || %r)", lhs, rhs);
+ case BINOP_AND: return CORD_asprintf("and(%r, %r)", lhs, rhs);
+ case BINOP_OR: return CORD_asprintf("or(%r, %r)", lhs, rhs);
+ case BINOP_XOR: return CORD_asprintf("xor(%r, %r)", lhs, rhs);
default: break;
}
errx(1, "unimplemented binop");
@@ -77,21 +78,21 @@ CORD compile(ast_t *ast)
CORD lhs = compile(update->lhs);
CORD rhs = compile(update->rhs);
switch (update->op) {
- case BINOP_MULT: return CORD_asprintf("%r *= %r", lhs, rhs);
- case BINOP_DIVIDE: return CORD_asprintf("%r /= %r", lhs, rhs);
- case BINOP_MOD: return CORD_asprintf("%r = %r %% %r", lhs, lhs, rhs);
- case BINOP_PLUS: return CORD_asprintf("%r += %r", lhs, rhs);
- case BINOP_MINUS: return CORD_asprintf("%r -= %r", lhs, rhs);
- case BINOP_LSHIFT: return CORD_asprintf("%r <<= %r", lhs, rhs);
- case BINOP_RSHIFT: return CORD_asprintf("%r >>= %r", lhs, rhs);
- case BINOP_EQ: return CORD_asprintf("%r = (%r == %r)", lhs, lhs, rhs);
- case BINOP_NE: return CORD_asprintf("%r = (%r != %r)", lhs, lhs, rhs);
- case BINOP_LT: return CORD_asprintf("%r = (%r < %r)", lhs, lhs, rhs);
- case BINOP_LE: return CORD_asprintf("%r = (%r <= %r)", lhs, lhs, rhs);
- case BINOP_GT: return CORD_asprintf("%r = (%r > %r)", lhs, lhs, rhs);
- case BINOP_GE: return CORD_asprintf("%r = (%r >= %r)", lhs, lhs, rhs);
- case BINOP_AND: return CORD_asprintf("%r = (%r && %r)", lhs, lhs, rhs);
- case BINOP_OR: return CORD_asprintf("%r = (%r || %r)", lhs, lhs, rhs);
+ case BINOP_MULT: return CORD_asprintf("%r *= %r;", lhs, rhs);
+ case BINOP_DIVIDE: return CORD_asprintf("%r /= %r;", lhs, rhs);
+ case BINOP_MOD: return CORD_asprintf("%r = %r %% %r;", lhs, lhs, rhs);
+ case BINOP_PLUS: return CORD_asprintf("%r += %r;", lhs, rhs);
+ case BINOP_MINUS: return CORD_asprintf("%r -= %r;", lhs, rhs);
+ case BINOP_LSHIFT: return CORD_asprintf("%r <<= %r;", lhs, rhs);
+ case BINOP_RSHIFT: return CORD_asprintf("%r >>= %r;", lhs, rhs);
+ case BINOP_EQ: return CORD_asprintf("%r = (%r == %r);", lhs, lhs, rhs);
+ case BINOP_NE: return CORD_asprintf("%r = (%r != %r);", lhs, lhs, rhs);
+ case BINOP_LT: return CORD_asprintf("%r = (%r < %r);", lhs, lhs, rhs);
+ case BINOP_LE: return CORD_asprintf("%r = (%r <= %r);", lhs, lhs, rhs);
+ case BINOP_GT: return CORD_asprintf("%r = (%r > %r);", lhs, lhs, rhs);
+ case BINOP_GE: return CORD_asprintf("%r = (%r >= %r);", lhs, lhs, rhs);
+ case BINOP_AND: return CORD_asprintf("%r = (%r && %r);", lhs, lhs, rhs);
+ case BINOP_OR: return CORD_asprintf("%r = (%r || %r);", lhs, lhs, rhs);
default: break;
}
errx(1, "unimplemented binop");
@@ -145,7 +146,7 @@ CORD compile(ast_t *ast)
}
case Declare: {
auto decl = Match(ast, Declare);
- return CORD_asprintf("__declare(%r, %r)", compile(decl->var), compile(decl->value));
+ return CORD_asprintf("__declare(%r, %r);", compile(decl->var), compile(decl->value));
}
case Assign: {
auto assign = Match(ast, Assign);
@@ -154,10 +155,22 @@ CORD compile(ast_t *ast)
CORD_sprintf(&code, "%r = %r", compile(target->ast), compile(value->ast));
if (target->next) code = CORD_cat(code, ", ");
}
- return code;
+ return CORD_cat(code, ";");
}
// Min, Max,
// Array, Table, TableEntry,
+ case Array: {
+ auto array = Match(ast, Array);
+ if (!array->items)
+ return "(array_t){}";
+
+ CORD code = "__array(";
+ for (ast_list_t *item = array->items; item; item = item->next) {
+ code = CORD_cat(code, compile(item->ast));
+ if (item->next) code = CORD_cat(code, ", ");
+ }
+ return CORD_cat_char(code, ')');
+ }
case FunctionDef: {
auto fndef = Match(ast, FunctionDef);
CORD code = CORD_asprintf("%r %r(", fndef->ret_type ? compile_type(fndef->ret_type) : "void", compile(fndef->name));
@@ -188,12 +201,60 @@ CORD compile(ast_t *ast)
CORD_sprintf(&code, "%r\nelse %r", code, compile(if_->else_body));
return code;
}
- // For, While, If,
+ case While: {
+ auto while_ = Match(ast, While);
+ return CORD_asprintf("while (%r) %r", compile(while_->condition), compile(while_->body));
+ }
+ case For: {
+ auto for_ = Match(ast, For);
+ CORD index = for_->index ? compile(for_->index) : "__i";
+ return CORD_asprintf("{\n"
+ "__declare(__iter, %r);\n"
+ "for (int64_t %r = 1, __len = __length(__iter); %r <= __len; ++%r) {\n"
+ "__declare(%r, __safe_index(__iter, %s));\n"
+ "%r\n"
+ "}\n}",
+ compile(for_->iter),
+ index, index, index,
+ compile(for_->value), index,
+ compile(for_->body));
+ }
+ // For,
// Reduction,
- // Skip, Stop, Pass,
- // Return,
+ case Skip: {
+ if (Match(ast, Skip)->target) errx(1, "Named skips not yet implemented");
+ return "continue";
+ }
+ case Stop: {
+ if (Match(ast, Stop)->target) errx(1, "Named stops not yet implemented");
+ return "break";
+ }
+ case Pass: return ";";
+ case Return: {
+ auto ret = Match(ast, Return)->value;
+ return ret ? CORD_asprintf("return %r;", compile(ret)) : "return;";
+ }
// Extern,
- // TypeDef,
+ case TypeDef: {
+ auto def = Match(ast, TypeDef);
+ CORD code;
+ switch (def->type->tag) {
+ case TypeVar: {
+ CORD_sprintf(&code, "typedef %r %s_t;\n", compile_type(def->type), def->var.name);
+ break;
+ }
+ case TypeStruct: {
+ CORD_sprintf(&code, "typedef struct %s_s %s_t;\nstruct %s_s {\n", def->var.name, def->var.name, def->var.name);
+ for (arg_list_t *field = Match(def->type, TypeStruct)->fields; field; field = field->next) {
+ CORD_sprintf(&code, "%r%r %s;\n", code, compile_type(field->type), field->var.name);
+ }
+ code = CORD_cat(code, "};\n");
+ break;
+ }
+ default: errx(1, "Typedef not implemented");
+ }
+ return code;
+ }
// Index, FieldAccess,
// DocTest,
// Use,