c-compiler/src/codegen.c
2024-11-16 21:02:09 +13:00

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);
}
}