Change compilation ordering by splitting into chunks
This commit is contained in:
parent
5de71394a3
commit
2e8f8b348a
166
compile.c
166
compile.c
@ -8,36 +8,37 @@
|
||||
#include "compile.h"
|
||||
#include "util.h"
|
||||
|
||||
CORD compile_type(type_ast_t *t)
|
||||
CORD compile_type(env_t *env, type_ast_t *t)
|
||||
{
|
||||
(void)env;
|
||||
switch (t->tag) {
|
||||
case VarTypeAST: return CORD_cat(Match(t, VarTypeAST)->name, "_t");
|
||||
default: errx(1, "Not implemented");
|
||||
}
|
||||
}
|
||||
|
||||
CORD compile_statement(ast_t *ast)
|
||||
CORD compile_statement(env_t *env, ast_t *ast)
|
||||
{
|
||||
switch (ast->tag) {
|
||||
case If: case For: case While: case FunctionDef: case Return: case StructDef: case EnumDef:
|
||||
case Declare: case Assign: case UpdateAssign: case DocTest:
|
||||
return compile(ast);
|
||||
return compile(env, ast);
|
||||
default:
|
||||
return CORD_asprintf("(void)%r;", compile(ast));
|
||||
return CORD_asprintf("(void)%r;", compile(env, ast));
|
||||
}
|
||||
}
|
||||
|
||||
CORD compile(ast_t *ast)
|
||||
CORD compile(env_t *env, ast_t *ast)
|
||||
{
|
||||
switch (ast->tag) {
|
||||
case Nil: return CORD_asprintf("(%r)NULL", compile_type(Match(ast, Nil)->type));
|
||||
case Nil: return CORD_asprintf("(%r)NULL", compile_type(env, Match(ast, Nil)->type));
|
||||
case Bool: return Match(ast, Bool)->b ? "yes" : "no";
|
||||
case Var: return Match(ast, Var)->name;
|
||||
case Int: return CORD_asprintf("((Int%ld_t)%ld)", Match(ast, Int)->precision, Match(ast, Int)->i);
|
||||
case Num: return CORD_asprintf(Match(ast, Num)->precision == 64 ? "%g" : "%gf", Match(ast, Num)->n);
|
||||
case UnaryOp: {
|
||||
auto unop = Match(ast, UnaryOp);
|
||||
CORD expr = compile(unop->value);
|
||||
CORD expr = compile(env, unop->value);
|
||||
switch (unop->op) {
|
||||
case UNOP_NOT: return CORD_asprintf("not(%r)", expr);
|
||||
case UNOP_NEGATIVE: return CORD_cat("-", expr);
|
||||
@ -49,8 +50,8 @@ CORD compile(ast_t *ast)
|
||||
}
|
||||
case BinaryOp: {
|
||||
auto binop = Match(ast, BinaryOp);
|
||||
CORD lhs = compile(binop->lhs);
|
||||
CORD rhs = compile(binop->rhs);
|
||||
CORD lhs = compile(env, binop->lhs);
|
||||
CORD rhs = compile(env, binop->rhs);
|
||||
switch (binop->op) {
|
||||
case BINOP_MULT: return CORD_asprintf("(%r * %r)", lhs, rhs);
|
||||
case BINOP_DIVIDE: return CORD_asprintf("(%r / %r)", lhs, rhs);
|
||||
@ -75,8 +76,8 @@ CORD compile(ast_t *ast)
|
||||
}
|
||||
case UpdateAssign: {
|
||||
auto update = Match(ast, UpdateAssign);
|
||||
CORD lhs = compile(update->lhs);
|
||||
CORD rhs = compile(update->rhs);
|
||||
CORD lhs = compile(env, update->lhs);
|
||||
CORD rhs = compile(env, 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);
|
||||
@ -130,7 +131,7 @@ CORD compile(ast_t *ast)
|
||||
if (!chunks) {
|
||||
return "(CORD)CORD_EMPTY";
|
||||
} else if (!chunks->next) {
|
||||
CORD code = compile(chunks->ast);
|
||||
CORD code = compile(env, chunks->ast);
|
||||
if (chunks->ast->tag != StringLiteral)
|
||||
code = CORD_asprintf("__cord(%r)", code);
|
||||
return code;
|
||||
@ -141,7 +142,7 @@ CORD compile(ast_t *ast)
|
||||
|
||||
CORD code = CORD_asprintf("CORD_catn(%ld", num_chunks);
|
||||
for (ast_list_t *chunk = chunks; chunk; chunk = chunk->next) {
|
||||
CORD chunk_code = compile(chunk->ast);
|
||||
CORD chunk_code = compile(env, chunk->ast);
|
||||
if (chunk->ast->tag != StringLiteral)
|
||||
chunk_code = CORD_asprintf("__cord(%r)", chunk_code);
|
||||
CORD_sprintf(&code, "%r, %r", code, chunk_code);
|
||||
@ -152,39 +153,39 @@ CORD compile(ast_t *ast)
|
||||
case Block: {
|
||||
ast_list_t *stmts = Match(ast, Block)->statements;
|
||||
if (stmts && !stmts->next)
|
||||
return compile_statement(stmts->ast);
|
||||
return compile_statement(env, stmts->ast);
|
||||
|
||||
CORD code = "{\n";
|
||||
for (ast_list_t *stmt = stmts; stmt; stmt = stmt->next) {
|
||||
code = CORD_cat(code, compile_statement(stmt->ast));
|
||||
code = CORD_cat(code, compile_statement(env, stmt->ast));
|
||||
code = CORD_cat(code, "\n");
|
||||
}
|
||||
return CORD_cat(code, "}");
|
||||
}
|
||||
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(env, decl->var), compile(env, decl->value));
|
||||
}
|
||||
case Assign: {
|
||||
auto assign = Match(ast, Assign);
|
||||
// Single assignment:
|
||||
if (assign->targets && !assign->targets->next)
|
||||
return CORD_asprintf("%r = %r", compile(assign->targets->ast), compile(assign->values->ast));
|
||||
return CORD_asprintf("%r = %r", compile(env, assign->targets->ast), compile(env, assign->values->ast));
|
||||
|
||||
CORD code = "{ // Assignment\n";
|
||||
int64_t i = 1;
|
||||
for (ast_list_t *value = assign->values; value; value = value->next)
|
||||
CORD_appendf(&code, "__declare(_%ld, %r);\n", i++, compile(value->ast));
|
||||
CORD_appendf(&code, "__declare(_%ld, %r);\n", i++, compile(env, value->ast));
|
||||
i = 1;
|
||||
for (ast_list_t *target = assign->targets; target; target = target->next)
|
||||
CORD_appendf(&code, "%r = _%ld;\n", compile(target->ast), i++);
|
||||
CORD_appendf(&code, "%r = _%ld;\n", compile(env, target->ast), i++);
|
||||
return CORD_cat(code, "\n}");
|
||||
}
|
||||
case Min: {
|
||||
return CORD_asprintf("min(%r, %r)", compile(Match(ast, Min)->lhs), compile(Match(ast, Min)->rhs));
|
||||
return CORD_asprintf("min(%r, %r)", compile(env, Match(ast, Min)->lhs), compile(env, Match(ast, Min)->rhs));
|
||||
}
|
||||
case Max: {
|
||||
return CORD_asprintf("max(%r, %r)", compile(Match(ast, Max)->lhs), compile(Match(ast, Max)->rhs));
|
||||
return CORD_asprintf("max(%r, %r)", compile(env, Match(ast, Max)->lhs), compile(env, Match(ast, Max)->rhs));
|
||||
}
|
||||
// Min, Max,
|
||||
// Array, Table, TableEntry,
|
||||
@ -195,27 +196,36 @@ CORD compile(ast_t *ast)
|
||||
|
||||
CORD code = "__array(";
|
||||
for (ast_list_t *item = array->items; item; item = item->next) {
|
||||
code = CORD_cat(code, compile(item->ast));
|
||||
code = CORD_cat(code, compile(env, 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));
|
||||
CORD_appendf(&env->staticdefs, "static %r %r(", fndef->ret_type ? compile_type(env, fndef->ret_type) : "void", compile(env, fndef->name));
|
||||
for (arg_ast_t *arg = fndef->args; arg; arg = arg->next) {
|
||||
CORD_sprintf(&code, "%r%r %s", code, compile_type(arg->type), arg->name);
|
||||
if (arg->next) code = CORD_cat(code, ", ");
|
||||
CORD_appendf(&env->staticdefs, "%r %s", compile_type(env, arg->type), arg->name);
|
||||
if (arg->next) env->staticdefs = CORD_cat(env->staticdefs, ", ");
|
||||
}
|
||||
code = CORD_cat(code, ") ");
|
||||
code = CORD_cat(code, compile(fndef->body));
|
||||
return code;
|
||||
env->staticdefs = CORD_cat(env->staticdefs, ");\n");
|
||||
|
||||
CORD_appendf(&env->funcs, "%r %r(", fndef->ret_type ? compile_type(env, fndef->ret_type) : "void", compile(env, fndef->name));
|
||||
for (arg_ast_t *arg = fndef->args; arg; arg = arg->next) {
|
||||
CORD_appendf(&env->funcs, "%r %s", compile_type(env, arg->type), arg->name);
|
||||
if (arg->next) env->funcs = CORD_cat(env->funcs, ", ");
|
||||
}
|
||||
CORD body = compile(env, fndef->body);
|
||||
if (CORD_fetch(body, 0) != '{')
|
||||
body = CORD_asprintf("{\n%r\n}", body);
|
||||
CORD_appendf(&env->funcs, ") %r", body);
|
||||
return CORD_EMPTY;
|
||||
}
|
||||
case FunctionCall: {
|
||||
auto call = Match(ast, FunctionCall);
|
||||
CORD code = CORD_cat_char(compile(call->fn), '(');
|
||||
CORD code = CORD_cat_char(compile(env, call->fn), '(');
|
||||
for (ast_list_t *arg = call->args; arg; arg = arg->next) {
|
||||
code = CORD_cat(code, compile(arg->ast));
|
||||
code = CORD_cat(code, compile(env, arg->ast));
|
||||
if (arg->next) code = CORD_cat(code, ", ");
|
||||
}
|
||||
return CORD_cat_char(code, ')');
|
||||
@ -223,34 +233,34 @@ CORD compile(ast_t *ast)
|
||||
// Lambda,
|
||||
case KeywordArg: {
|
||||
auto kwarg = Match(ast, KeywordArg);
|
||||
return CORD_asprintf(".%s=%r", kwarg->name, compile(kwarg->arg));
|
||||
return CORD_asprintf(".%s=%r", kwarg->name, compile(env, kwarg->arg));
|
||||
}
|
||||
// KeywordArg,
|
||||
case If: {
|
||||
auto if_ = Match(ast, If);
|
||||
CORD code;
|
||||
CORD_sprintf(&code, "if (%r) %r", compile(if_->condition), compile(if_->body));
|
||||
CORD_sprintf(&code, "if (%r) %r", compile(env, if_->condition), compile(env, if_->body));
|
||||
if (if_->else_body)
|
||||
CORD_sprintf(&code, "%r\nelse %r", code, compile(if_->else_body));
|
||||
CORD_sprintf(&code, "%r\nelse %r", code, compile(env, if_->else_body));
|
||||
return code;
|
||||
}
|
||||
case While: {
|
||||
auto while_ = Match(ast, While);
|
||||
return CORD_asprintf("while (%r) %r", compile(while_->condition), compile(while_->body));
|
||||
return CORD_asprintf("while (%r) %r", compile(env, while_->condition), compile(env, while_->body));
|
||||
}
|
||||
case For: {
|
||||
auto for_ = Match(ast, For);
|
||||
CORD index = for_->index ? compile(for_->index) : "__i";
|
||||
CORD index = for_->index ? compile(env, 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),
|
||||
compile(env, for_->iter),
|
||||
index, index, index,
|
||||
compile(for_->value), index,
|
||||
compile(for_->body));
|
||||
compile(env, for_->value), index,
|
||||
compile(env, for_->body));
|
||||
}
|
||||
// For,
|
||||
// Reduction,
|
||||
@ -265,54 +275,56 @@ CORD compile(ast_t *ast)
|
||||
case Pass: return ";";
|
||||
case Return: {
|
||||
auto ret = Match(ast, Return)->value;
|
||||
return ret ? CORD_asprintf("return %r;", compile(ret)) : "return;";
|
||||
return ret ? CORD_asprintf("return %r;", compile(env, ret)) : "return;";
|
||||
}
|
||||
// Extern,
|
||||
case StructDef: {
|
||||
auto def = Match(ast, StructDef);
|
||||
CORD code = CORD_asprintf(
|
||||
"typedef struct %s_s %s_t;\n"
|
||||
"#define %s(...) ((%s_t){__VA_ARGS__})\n"
|
||||
"struct %s_s {\n", def->name, def->name, def->name, def->name, def->name);
|
||||
CORD_appendf(&env->typedefs, "typedef struct %s_s %s_t;\n", def->name, def->name);
|
||||
CORD_appendf(&env->typedefs, "#define %s(...) ((%s_t){__VA_ARGS__})\n", def->name, def->name);
|
||||
|
||||
CORD_appendf(&env->types, "struct %s_s {\n", def->name);
|
||||
for (arg_ast_t *field = def->fields; field; field = field->next) {
|
||||
CORD_sprintf(&code, "%r%r %s;\n", code, compile_type(field->type), field->name);
|
||||
CORD_appendf(&env->types, "%r %s;\n", compile_type(env, field->type), field->name);
|
||||
}
|
||||
code = CORD_cat(code, "};\n");
|
||||
CORD_sprintf(&code,
|
||||
"%rCORD %s__cord(%s_t *obj, bool use_color) {\n"
|
||||
CORD_appendf(&env->types, "};\n");
|
||||
|
||||
CORD_appendf(&env->funcs,
|
||||
"CORD %s__cord(%s_t *obj, bool use_color) {\n"
|
||||
"\tif (!obj) return \"%s\";\n"
|
||||
"\treturn CORD_asprintf(use_color ? \"\\x1b[0;1m%s\\x1b[m(", code, def->name, def->name, def->name, def->name);
|
||||
"\treturn CORD_asprintf(use_color ? \"\\x1b[0;1m%s\\x1b[m(", def->name, def->name, def->name, def->name);
|
||||
for (arg_ast_t *field = def->fields; field; field = field->next) {
|
||||
CORD_sprintf(&code, "%r%s=\\x1b[35m%%r\\x1b[m", code, field->name);
|
||||
if (field->next) code = CORD_cat(code, ", ");
|
||||
CORD_appendf(&env->funcs, "%s=\\x1b[35m%%r\\x1b[m", field->name);
|
||||
if (field->next) env->funcs = CORD_cat(env->funcs, ", ");
|
||||
}
|
||||
CORD_appendf(&code, ")\" : \"%s(", def->name);
|
||||
CORD_appendf(&env->funcs, ")\" : \"%s(", def->name);
|
||||
for (arg_ast_t *field = def->fields; field; field = field->next) {
|
||||
CORD_sprintf(&code, "%r%s=%%r", code, field->name);
|
||||
if (field->next) code = CORD_cat(code, ", ");
|
||||
CORD_appendf(&env->funcs, "%s=%%r", field->name);
|
||||
if (field->next) env->funcs = CORD_cat(env->funcs, ", ");
|
||||
}
|
||||
code = CORD_cat(code, ")\"");
|
||||
env->funcs = CORD_cat(env->funcs, ")\"");
|
||||
for (arg_ast_t *field = def->fields; field; field = field->next)
|
||||
CORD_sprintf(&code, "%r, __cord(obj->%s)", code, field->name);
|
||||
code = CORD_cat(code, ");\n}");
|
||||
return code;
|
||||
CORD_appendf(&env->funcs, ", __cord(obj->%s)", field->name);
|
||||
env->funcs = CORD_cat(env->funcs, ");\n}");
|
||||
return CORD_EMPTY;
|
||||
}
|
||||
case EnumDef: {
|
||||
auto def = Match(ast, EnumDef);
|
||||
CORD code = CORD_asprintf("typedef struct %s_s %s_t;\nstruct %s_s {\nenum {", def->name, def->name, def->name);
|
||||
CORD_appendf(&env->typedefs, "typedef struct %s_s %s_t;\n", def->name, def->name);
|
||||
CORD_appendf(&env->types, "struct %s_s {\nenum {", def->name);
|
||||
for (tag_ast_t *tag = def->tags; tag; tag = tag->next) {
|
||||
CORD_sprintf(&code, "%r%s__%s = %ld, ", code, def->name, tag->name, tag->value);
|
||||
CORD_appendf(&env->types, "%s__%s = %ld, ", def->name, tag->name, tag->value);
|
||||
}
|
||||
code = CORD_cat(code, "} tag;\nunion {\n");
|
||||
env->types = CORD_cat(env->types, "} tag;\nunion {\n");
|
||||
for (tag_ast_t *tag = def->tags; tag; tag = tag->next) {
|
||||
code = CORD_cat(code, "struct {\n");
|
||||
env->types = CORD_cat(env->types, "struct {\n");
|
||||
for (arg_ast_t *field = tag->fields; field; field = field->next) {
|
||||
CORD_sprintf(&code, "%r%r %s;\n", code, compile_type(field->type), field->name);
|
||||
CORD_appendf(&env->types, "%r %s;\n", compile_type(env, field->type), field->name);
|
||||
}
|
||||
CORD_sprintf(&code, "%r} %s;\n", code, tag->name);
|
||||
CORD_appendf(&env->types, "} %s;\n", tag->name);
|
||||
}
|
||||
code = CORD_cat(code, "} __data;\n};\n");
|
||||
return code;
|
||||
env->types = CORD_cat(env->types, "} __data;\n};\n");
|
||||
return CORD_EMPTY;
|
||||
}
|
||||
case DocTest: {
|
||||
auto test = Match(ast, DocTest);
|
||||
@ -321,19 +333,19 @@ CORD compile(ast_t *ast)
|
||||
auto decl = Match(test->expr, Declare);
|
||||
return CORD_asprintf(
|
||||
"__declare(%r, %r);\n__test(%r, %r, %r);\n",
|
||||
compile(decl->var), compile(decl->value),
|
||||
compile(WrapAST(test->expr, StringLiteral, .cord=src)),
|
||||
compile(decl->var),
|
||||
compile(WrapAST(test->expr, StringLiteral, .cord=test->output)));
|
||||
compile(env, decl->var), compile(env, decl->value),
|
||||
compile(env, WrapAST(test->expr, StringLiteral, .cord=src)),
|
||||
compile(env, decl->var),
|
||||
compile(env, WrapAST(test->expr, StringLiteral, .cord=test->output)));
|
||||
} else if (test->expr->tag == Assign) {
|
||||
auto assign = Match(test->expr, Assign);
|
||||
CORD code = "{ // Assignment\n";
|
||||
int64_t i = 1;
|
||||
for (ast_list_t *value = assign->values; value; value = value->next)
|
||||
CORD_appendf(&code, "__declare(_%ld, %r);\n", i++, compile(value->ast));
|
||||
CORD_appendf(&code, "__declare(_%ld, %r);\n", i++, compile(env, value->ast));
|
||||
i = 1;
|
||||
for (ast_list_t *target = assign->targets; target; target = target->next)
|
||||
CORD_appendf(&code, "%r = _%ld;\n", compile(target->ast), i++);
|
||||
CORD_appendf(&code, "%r = _%ld;\n", compile(env, target->ast), i++);
|
||||
|
||||
CORD expr_cord = "CORD_asprintf(\"";
|
||||
for (ast_list_t *target = assign->targets; target; target = target->next)
|
||||
@ -345,21 +357,21 @@ CORD compile(ast_t *ast)
|
||||
expr_cord = CORD_cat(expr_cord, ")");
|
||||
|
||||
CORD_appendf(&code, "__test(%r, %r, %r);",
|
||||
compile(WrapAST(test->expr, StringLiteral, .cord=src)),
|
||||
compile(env, WrapAST(test->expr, StringLiteral, .cord=src)),
|
||||
expr_cord,
|
||||
compile(WrapAST(test->expr, StringLiteral, .cord=test->output)));
|
||||
compile(env, WrapAST(test->expr, StringLiteral, .cord=test->output)));
|
||||
return CORD_cat(code, "\n}");
|
||||
} else {
|
||||
return CORD_asprintf(
|
||||
"__test(%r, %r, %r);\n",
|
||||
compile(WrapAST(test->expr, StringLiteral, .cord=src)),
|
||||
compile(test->expr),
|
||||
compile(WrapAST(test->expr, StringLiteral, .cord=test->output)));
|
||||
compile(env, WrapAST(test->expr, StringLiteral, .cord=src)),
|
||||
compile(env, test->expr),
|
||||
compile(env, WrapAST(test->expr, StringLiteral, .cord=test->output)));
|
||||
}
|
||||
}
|
||||
case FieldAccess: {
|
||||
auto f = Match(ast, FieldAccess);
|
||||
return CORD_asprintf("(%r).%s", compile(f->fielded), f->field);
|
||||
return CORD_asprintf("(%r).%s", compile(env, f->fielded), f->field);
|
||||
}
|
||||
// Index, FieldAccess,
|
||||
// DocTest,
|
||||
|
@ -5,9 +5,10 @@
|
||||
#include <stdio.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "environment.h"
|
||||
|
||||
CORD compile_type(type_ast_t *t);
|
||||
CORD compile(ast_t *ast);
|
||||
CORD compile_statement(ast_t *ast);
|
||||
CORD compile_type(env_t *env, type_ast_t *t);
|
||||
CORD compile(env_t *env, ast_t *ast);
|
||||
CORD compile_statement(env_t *env, ast_t *ast);
|
||||
|
||||
// vim: ts=4 sw=0 et cino=L2,l1,(0,W4,m1,\:0
|
||||
|
89
nextlang.c
89
nextlang.c
@ -42,69 +42,38 @@ int main(int argc, char *argv[])
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
CORD header = "#include \"nextlang.h\"\n";
|
||||
env_t env = {.bindings = new(table_t)};
|
||||
|
||||
// Predeclare types:
|
||||
for (ast_list_t *stmt = Match(ast, Block)->statements; stmt; stmt = stmt->next) {
|
||||
switch (stmt->ast->tag) {
|
||||
case StructDef: case EnumDef: {
|
||||
CORD_sprintf(&header, "%r\n%r", header, compile(stmt->ast));
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
CORD_appendf(&env.imports, "#include \"nextlang.h\"\n");
|
||||
CORD_appendf(&env.staticdefs, "static bool USE_COLOR = true;\n");
|
||||
|
||||
CORD program = CORD_cat(header, "\n/////////////////////////////////////////////////////////////////////////\n\n"
|
||||
"bool USE_COLOR = true;\n");
|
||||
|
||||
// Predeclare funcs:
|
||||
for (ast_list_t *stmt = Match(ast, Block)->statements; stmt; stmt = stmt->next) {
|
||||
switch (stmt->ast->tag) {
|
||||
case FunctionDef: {
|
||||
auto fndef = Match(stmt->ast, FunctionDef);
|
||||
CORD_sprintf(&program, "%rstatic %r %r(", program, fndef->ret_type ? compile_type(fndef->ret_type) : "void", compile(fndef->name));
|
||||
for (arg_ast_t *arg = fndef->args; arg; arg = arg->next) {
|
||||
CORD_sprintf(&program, "%r%r %s", program, compile_type(arg->type), arg->name);
|
||||
if (arg->next) program = CORD_cat(program, ", ");
|
||||
}
|
||||
program = CORD_cat(program, ");\n");
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
// Declare funcs:
|
||||
for (ast_list_t *stmt = Match(ast, Block)->statements; stmt; stmt = stmt->next) {
|
||||
switch (stmt->ast->tag) {
|
||||
case FunctionDef: {
|
||||
CORD_sprintf(&program, "%r\n\n%r", program, compile(stmt->ast));
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
// Main body:
|
||||
program = CORD_cat(program, "\n\n"
|
||||
"int main(int argc, const char *argv[]) {\n"
|
||||
"(void)argc;\n"
|
||||
"(void)argv;\n"
|
||||
"GC_INIT();\n"
|
||||
"USE_COLOR = getenv(\"COLOR\") ? strcmp(getenv(\"COLOR\"), \"1\") == 0 : isatty(STDOUT_FILENO);\n"
|
||||
"// User code:\n");
|
||||
for (ast_list_t *stmt = Match(ast, Block)->statements; stmt; stmt = stmt->next) {
|
||||
switch (stmt->ast->tag) {
|
||||
case FunctionDef: case StructDef: case EnumDef: break;
|
||||
default: {
|
||||
program = CORD_cat(program, compile_statement(stmt->ast));
|
||||
program = CORD_cat(program, "\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
program = CORD_cat(program, "return 0;\n}\n");
|
||||
for (ast_list_t *stmt = Match(ast, Block)->statements; stmt; stmt = stmt->next)
|
||||
CORD_appendf(&env.main, "%r\n", compile_statement(&env, stmt->ast));
|
||||
|
||||
CORD program = CORD_asprintf(
|
||||
"// Generated code:\n"
|
||||
"%r\n" // imports
|
||||
"%r\n" // typedefs
|
||||
"%r\n" // types
|
||||
"//////////////////////////////////////////\n"
|
||||
"%r\n" // static defs
|
||||
"%r\n" // funcs
|
||||
"\n"
|
||||
"static void __load(void) {\n"
|
||||
"%r\n" // main
|
||||
"}\n"
|
||||
"\n"
|
||||
"int main(int argc, const char *argv[]) {\n"
|
||||
"(void)argc;\n"
|
||||
"(void)argv;\n"
|
||||
"GC_INIT();\n"
|
||||
"USE_COLOR = getenv(\"COLOR\") ? strcmp(getenv(\"COLOR\"), \"1\") == 0 : isatty(STDOUT_FILENO);\n"
|
||||
"__load();\n"
|
||||
"return 0;\n"
|
||||
"}\n",
|
||||
env.imports, env.typedefs, env.types, env.staticdefs,
|
||||
env.funcs, env.main);
|
||||
|
||||
if (verbose) {
|
||||
FILE *out = popen(heap_strf("%s | bat -P --file-name=program.c", autofmt), "w");
|
||||
|
Loading…
Reference in New Issue
Block a user