clean up some stuff

This commit is contained in:
sam 2024-11-16 21:02:09 +13:00
parent 1b14ecf5ff
commit 5e02ecd80d
10 changed files with 231 additions and 66 deletions

BIN
a.out Executable file

Binary file not shown.

View file

@ -2,86 +2,114 @@
#include "helpers.h"
#include <stdio.h>
void codegen(Node node) {
void codegen(Node node, bool emit_type) {
switch(node.type) {
case NODE_FUNCTION_CALL:
codegen_function_call(node);
codegen_function_call(node.function_call);
break;
case NODE_FUNCTION_DECL:
codegen_function_decl(node);
codegen_function_decl(node.function_decl);
break;
case NODE_FUNCTION_IMPL:
codegen_function_impl(node);
codegen_function_impl(node.function_impl);
break;
case NODE_ARG_DECL:
codegen_arg_decl(node);
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);
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(Node node) {
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.function_call.args); i++) {
const Node* arg = Nodes_at(&node.function_call.args, i);
codegen(*arg);
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.function_call.args)) {
if(arg != Nodes_back(&node.args)) {
printf(", ");
}
}
printf(")\n");
}
void codegen_function_decl(Node node) {
printf("FunctionDecl(%s, %s, ", node.function_decl.type, node.function_decl.name);
for(size_t i = 0; i < Nodes_size(&node.function_decl.args); i++) {
const Node* arg = Nodes_at(&node.function_decl.args, i);
codegen(*arg);
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.function_decl.args)) {
if(arg != Nodes_back(&node.args)) {
printf(", ");
}
}
printf(")\n");
}
void codegen_function_impl(Node node) {
printf("FunctionImpl(%s, %s", node.function_impl.type, node.function_impl.name);
if(Nodes_size(&node.function_impl.args) > 0)
printf(", ");
for(size_t i = 0; i < Nodes_size(&node.function_impl.args); i++) {
const Node* arg = Nodes_at(&node.function_impl.args, i);
codegen(*arg);
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.function_impl.args)) {
if(arg != Nodes_back(&node.args)) {
printf(", ");
}
}
printf(") {\n\t");
printf(") {\n@start\n\t");
for(size_t i = 0; i < Nodes_size(&node.function_impl.body); i++) {
const Node* n = Nodes_at(&node.function_impl.body, i);
codegen(*n);
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.function_impl.body)) {
if(n != Nodes_back(&node.body)) {
printf("\t");
}
}
printf("}\n");
printf("\t\n}\n");
}
void codegen_arg_decl(Node node) {
printf("ArgDecl(%s, %s)", node.arg_decl.type, node.arg_decl.name);
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_number(Node node) {
printf("Number(%llu)", node.number.value);
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);
}
}

View file

@ -3,11 +3,13 @@
#include "node.h"
void codegen(Node node);
void codegen_function_call(Node node);
void codegen_function_decl(Node node);
void codegen_arg_decl(Node node);
void codegen_function_impl(Node node);
void codegen_number(Node node);
void codegen(Node node, bool emit_type);
void codegen_function_call(FunctionCall node);
void codegen_function_decl(FunctionDecl node);
void codegen_arg_decl(ArgDecl node, bool emit_type);
void codegen_function_impl(FunctionImpl node);
void codegen_reference(Reference node, bool emit_type);
void codegen_number(Number node, bool emit_type);
void codegen_return(Return node);
#endif

View file

@ -2,6 +2,7 @@
#define COMPILER_H
#include "lexer.h"
#include "node.h"
typedef enum {
TOKEN_IDENTIFIER = 'I',
@ -32,6 +33,7 @@ typedef enum {
typedef struct {
Lexer* lexer;
cmap_str types;
NodeMap symbols;
} Compiler;
bool next(Compiler* compiler, Token* token);

View file

@ -7,7 +7,6 @@
#include "token.h"
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
int main(int argc, char** argv) {
assert(argc > 1);
@ -38,13 +37,14 @@ int main(int argc, char** argv) {
{ "i64", "l" },
{ "void", "" },
}),
.symbols = { 0 },
};
Token token;
while(next(&compiler, &token)) {
// printf("%c: %s\n", token.type, token.value);
Node node = parse_token(&compiler, token);
codegen(node);
codegen(node, true);
}
return 0;

View file

@ -1,17 +1,22 @@
#ifndef NODE_H
#define NODE_H
#include <stdbool.h>
#include <stddef.h>
#include <stc/cstr.h>
#include <stc/forward.h>
typedef struct Node Node;
forward_cvec(Nodes, struct Node);
forward_cmap(NodeMap, cstr, struct Node);
typedef enum {
NODE_FUNCTION_CALL = 'C',
NODE_FUNCTION_DECL = 'D',
NODE_FUNCTION_IMPL = 'I',
NODE_ARG_DECL = 'A',
NODE_RETURN = 'R',
NODE_REFERENCE = 'r',
NODE_NUMBER = 'N',
} NodeType;
@ -39,9 +44,18 @@ typedef struct {
} ArgDecl;
typedef struct {
long long int value;
const char* type;
const char* name;
} Reference;
typedef struct {
int value;
} Number;
typedef struct {
Node* value;
} Return;
struct Nodes;
typedef struct Node {
NodeType type;
@ -50,7 +64,9 @@ typedef struct Node {
FunctionDecl function_decl;
FunctionImpl function_impl;
ArgDecl arg_decl;
Reference reference;
Number number;
Return ret;
};
} Node;
@ -60,4 +76,10 @@ typedef struct Node {
#define i_opt c_no_cmp
#include <stc/cvec.h>
#define i_type NodeMap
#define i_is_forward
#define i_key_str
#define i_val Node
#include <stc/cmap.h>
#endif

View file

@ -43,23 +43,53 @@ Node parse_type(Compiler* self, const char* type) {
}
}
Node parse_identifier(Compiler* self, const char* name) {
Token token;
next(self, &token);
switch(token.type) {
case TOKEN_OPAREN:
return parse_function_call(self, name);
break;
const char* resolve_type(Compiler* self, Node node) {
switch(node.type) {
case NODE_ARG_DECL:
return node.arg_decl.type;
default:
syntax_error("unexpected token \"%s\" after identifier \"%s\"", token.value, name);
syntax_error("unexpected node fed to resolve_type");
}
}
Node parse_identifier(Compiler* self, const char* name) {
if(strcmp(name, "return") == 0) {
Token token;
next(self, &token);
Node* node = NULL;
if(token.type != TOKEN_SEMICOLON) {
node = malloc(sizeof(Node));
Node parsed = parse_token(self, token);
memcpy(node, &parsed, sizeof(Node));
parse_semicolon(self);
}
return (Node){ .type = NODE_RETURN, .ret = { .value = node } };
}
const NodeMap_value* symbol = NodeMap_get(&self->symbols, name);
if(symbol == NULL) {
syntax_error("undefined symbol \"%s\"", name);
}
switch(symbol->second.type) {
case NODE_FUNCTION_DECL:
case NODE_FUNCTION_IMPL:
return parse_function_call(self, name);
case NODE_ARG_DECL:
return (Node){
.type = NODE_REFERENCE,
.reference = { .type = resolve_type(self, symbol->second), .name = name },
};
default:
syntax_error("unexpected symbol type");
}
}
Node parse_number(Compiler* self, const char* value) {
return (Node){
.type = NODE_NUMBER,
.number = atoll(value),
.number = atoi(value),
};
}
@ -85,15 +115,17 @@ Node parse_function(Compiler* self, const char* type, const char* name) {
if(arg_type.type == TOKEN_CPAREN) {
break;
}
const cmap_str_value* type = cmap_str_get(&self->types, arg_type.value);
Token arg_name;
next(self, &arg_name);
Nodes_push(&args,
(Node){
.type = NODE_ARG_DECL,
.arg_decl = { .type = arg_type.value, .name = arg_name.value },
});
Node arg_decl = (Node){
.type = NODE_ARG_DECL,
.arg_decl = { .type = cstr_str(&type->second), .name = arg_name.value },
};
Nodes_push(&args, arg_decl);
NodeMap_insert(&self->symbols, cstr_from(arg_name.value), arg_decl);
Token token;
next(self, &token);
@ -109,19 +141,29 @@ Node parse_function(Compiler* self, const char* type, const char* name) {
break; // only reached if didnt continue or error
}
const cmap_str_value* real_type = cmap_str_get(&self->types, type);
const char* real_type_cstr = cstr_str(&real_type->second);
Token token;
Node function_node;
if(next(self, &token)) {
switch(token.type) {
case TOKEN_SEMICOLON:
return parse_function_decl(self, type, name, args);
function_node = parse_function_decl(self, real_type_cstr, name, args);
break;
case TOKEN_OBRACE:
return parse_function_impl(self, type, name, args);
function_node = parse_function_impl(self, real_type_cstr, name, args);
break;
default:
syntax_error("expected semicolon or opening brace found, %s", token.value);
}
} else {
syntax_error("expected token, found eof");
}
printf("inserting %s into symbols\n", name);
NodeMap_insert(&self->symbols, cstr_from(name), function_node);
return function_node;
}
Node parse_function_decl(Compiler* self, const char* type, const char* name, Nodes args) {
@ -142,6 +184,15 @@ Node parse_function_impl(Compiler* self, const char* type, const char* name, Nod
Node parse_function_call(Compiler* self, const char* name) {
printf("parse function call %s\n", name);
Token token;
next(self, &token);
switch(token.type) {
case TOKEN_OPAREN:
break;
default:
syntax_error("unexpected token \"%s\" after function name", token.value);
}
Nodes args = parse_until(self, TOKEN_CPAREN);
parse_semicolon(self);

41
test.s Normal file
View file

@ -0,0 +1,41 @@
.text
.balign 16
.globl sayhi
sayhi:
hint #34
stp x29, x30, [sp, -32]!
mov x29, sp
str x19, [x29, 24]
mov w19, w0
mov w0, #72
bl putchar
mov w0, w19
mov w19, w0
mov w0, #105
bl putchar
mov w0, w19
bl putchar
mov w0, #5
ldr x19, [x29, 24]
ldp x29, x30, [sp], 32
ret
.type sayhi, @function
.size sayhi, .-sayhi
/* end function sayhi */
.text
.balign 16
.globl main
main:
hint #34
stp x29, x30, [sp, -16]!
mov x29, sp
mov w0, #74
bl sayhi
ldp x29, x30, [sp], 16
ret
.type main, @function
.size main, .-main
/* end function main */
.section .note.GNU-stack,"",@progbits

14
test.ssa Normal file
View file

@ -0,0 +1,14 @@
export function w $sayhi(w %char) {
@start
call $putchar(w 72)
call $putchar(w 105)
call $putchar(w %char)
ret 5
}
export function $main() {
@start
call $sayhi(w 74)
ret
}

View file

@ -1,8 +1,13 @@
i32 putchar(i32 char);
void sayhi() {
i32 sayhi(i32 char) {
putchar(72);
putchar(105);
putchar(char);
return 5;
}
sayhi();
void main() {
sayhi(74);
return;
}