115 lines
2.9 KiB
C
115 lines
2.9 KiB
C
#include "codegen.h"
|
|
#include "helpers.h"
|
|
#include <stdio.h>
|
|
|
|
void codegen(Node node, bool emit_type) {
|
|
switch(node.type) {
|
|
case NODE_FUNCTION_CALL:
|
|
codegen_function_call(node.function_call);
|
|
break;
|
|
case NODE_FUNCTION_DECL:
|
|
codegen_function_decl(node.function_decl);
|
|
break;
|
|
case NODE_FUNCTION_IMPL:
|
|
codegen_function_impl(node.function_impl);
|
|
break;
|
|
case NODE_ARG_DECL:
|
|
codegen_arg_decl(node.arg_decl, emit_type);
|
|
break;
|
|
case NODE_REFERENCE:
|
|
codegen_reference(node.reference, emit_type);
|
|
break;
|
|
case NODE_NUMBER:
|
|
codegen_number(node.number, emit_type);
|
|
break;
|
|
case NODE_RETURN:
|
|
codegen_return(node.ret);
|
|
break;
|
|
default:
|
|
syntax_error("unexpected node %c", node.type);
|
|
}
|
|
}
|
|
|
|
void codegen_function_call(FunctionCall node) {
|
|
printf("call $%s(", node.name);
|
|
// printf("FunctionCall(%s", node.function_call.name);
|
|
/*if(Nodes_size(&node.function_call.args) > 0)
|
|
printf(", ");*/
|
|
for(size_t i = 0; i < Nodes_size(&node.args); i++) {
|
|
const Node* arg = Nodes_at(&node.args, i);
|
|
codegen(*arg, true);
|
|
|
|
if(arg != Nodes_back(&node.args)) {
|
|
printf(", ");
|
|
}
|
|
}
|
|
printf(")\n");
|
|
}
|
|
|
|
void codegen_function_decl(FunctionDecl node) {
|
|
printf("FunctionDecl(%s, %s, ", node.type, node.name);
|
|
for(size_t i = 0; i < Nodes_size(&node.args); i++) {
|
|
const Node* arg = Nodes_at(&node.args, i);
|
|
codegen(*arg, true);
|
|
|
|
if(arg != Nodes_back(&node.args)) {
|
|
printf(", ");
|
|
}
|
|
}
|
|
printf(")\n");
|
|
}
|
|
|
|
void codegen_function_impl(FunctionImpl node) {
|
|
printf("export function %s $%s(", node.type, node.name);
|
|
for(size_t i = 0; i < Nodes_size(&node.args); i++) {
|
|
const Node* arg = Nodes_at(&node.args, i);
|
|
codegen(*arg, true);
|
|
|
|
if(arg != Nodes_back(&node.args)) {
|
|
printf(", ");
|
|
}
|
|
}
|
|
printf(") {\n@start\n\t");
|
|
|
|
for(size_t i = 0; i < Nodes_size(&node.body); i++) {
|
|
const Node* n = Nodes_at(&node.body, i);
|
|
codegen(*n, true);
|
|
|
|
if(n != Nodes_back(&node.body)) {
|
|
printf("\t");
|
|
}
|
|
}
|
|
|
|
printf("\t\n}\n");
|
|
}
|
|
|
|
void codegen_arg_decl(ArgDecl node, bool emit_type) {
|
|
// printf("ArgDecl(%s, %s)", node.arg_decl.type, node.arg_decl.name);
|
|
if(emit_type) {
|
|
printf("%s ", node.type);
|
|
}
|
|
printf("%%%s", node.name);
|
|
}
|
|
|
|
void codegen_reference(Reference node, bool emit_type) {
|
|
// printf("Reference(%s)", node.reference.name);
|
|
if(emit_type) {
|
|
printf("%s ", node.type);
|
|
}
|
|
printf("%%%s", node.name);
|
|
}
|
|
|
|
void codegen_number(Number node, bool emit_type) {
|
|
// printf("Number(%llu)", node.number.value);
|
|
if(emit_type) {
|
|
printf("w ");
|
|
}
|
|
printf("%d", node.value);
|
|
}
|
|
|
|
void codegen_return(Return node) {
|
|
printf("ret ");
|
|
if(node.value != NULL) {
|
|
codegen(*node.value, false);
|
|
}
|
|
}
|