core: Add initial codegen sources

Signed-off-by: Ian Moffett <ian@mirocom.org>
This commit is contained in:
2026-02-15 22:17:40 -05:00
parent 1db0ed78e1
commit 154a71b1f6
9 changed files with 131 additions and 2 deletions

View File

@@ -1,3 +1,6 @@
ARCH_TARGET = x86_64
BACKEND = backend/$(ARCH_TARGET).c
CFILES = $(shell find core/ -name "*.c") CFILES = $(shell find core/ -name "*.c")
OFILES = $(CFILES:.c=.o) OFILES = $(CFILES:.c=.o)
DFILES = $(CFILES:.c=.d) DFILES = $(CFILES:.c=.d)
@@ -7,7 +10,7 @@ CFLAGS = -Wall -pedantic -Iinc/ -MMD
.PHONY: all .PHONY: all
all: $(OFILES) all: $(OFILES)
$(CC) $(OFILES) -o rifle $(CC) $(BACKEND) $(CFLAGS) $(OFILES) -o rifle
-include $(DFILES) -include $(DFILES)
%.o: %.c %.o: %.c

19
backend/x86_64.c Normal file
View File

@@ -0,0 +1,19 @@
#include <stdio.h>
#include "rifle/mu.h"
int
mu_gen_label(struct rifle_state *state, const char *name)
{
if (state == NULL || name == NULL) {
return -1;
}
fprintf(
state->out_fp,
"%s:\n",
name
);
return 0;
}

42
core/codegen.c Normal file
View File

@@ -0,0 +1,42 @@
#include <stdint.h>
#include <stddef.h>
#include "rifle/codegen.h"
#include "rifle/trace.h"
#include "rifle/mu.h"
static int
resolve_func(struct rifle_state *state, struct ast_node *root)
{
struct symbol *symbol;
if (state == NULL || root == NULL) {
return -1;
}
if ((symbol = root->symbol) == NULL) {
trace_error(state, "internal: no symbol associated with func node\n");
return -1;
}
return mu_gen_label(state, symbol->name);
}
int
cg_resolve_node(struct rifle_state *state, struct ast_node *root)
{
if (state == NULL || root == NULL) {
return -1;
}
switch (root->type) {
case AST_FUNC:
if (resolve_func(state, root) < 0) {
return -1;
}
break;
default:
trace_error(state, "unknown ast node %d\n", root->type);
break;
}
}

View File

@@ -9,6 +9,7 @@
#include "rifle/types.h" #include "rifle/types.h"
#include "rifle/ast.h" #include "rifle/ast.h"
#include "rifle/scope.h" #include "rifle/scope.h"
#include "rifle/codegen.h"
/* Symbolic token */ /* Symbolic token */
#define symtok(tok) \ #define symtok(tok) \
@@ -438,6 +439,8 @@ parse_func(struct rifle_state *state, struct token *tok, struct ast_node **res)
return -1; return -1;
} }
root->symbol = symbol;
/* EXPECT '(' */ /* EXPECT '(' */
if (parse_expect(state, TT_LPAREN, tok) < 0) { if (parse_expect(state, TT_LPAREN, tok) < 0) {
return -1; return -1;
@@ -468,6 +471,7 @@ parse_func(struct rifle_state *state, struct token *tok, struct ast_node **res)
return -1; return -1;
} }
*res = root;
return 0; return 0;
} }
@@ -501,7 +505,7 @@ static int
parse_begin(struct rifle_state *state) parse_begin(struct rifle_state *state)
{ {
struct token tok; struct token tok;
struct ast_node *root; struct ast_node *root = NULL;
while (parse_scan(state, &tok) == 0) { while (parse_scan(state, &tok) == 0) {
switch (tok.type) { switch (tok.type) {
@@ -523,6 +527,11 @@ parse_begin(struct rifle_state *state)
} }
} }
if (root != NULL) {
if (cg_resolve_node(state, root) < 0)
return -1;
}
return 0; return 0;
} }

View File

@@ -16,19 +16,28 @@ rifle_state_init(struct rifle_state *state, const char *in_path)
return -1; return -1;
} }
state->out_fp = fopen(ASMOUT, "w");
if (state->out_fp == NULL) {
close(state->in_fd);
return -1;
}
if (ptrbox_init(&state->ptrbox) < 0) { if (ptrbox_init(&state->ptrbox) < 0) {
close(state->in_fd); close(state->in_fd);
fclose(state->out_fp);
return -1; return -1;
} }
if (symbol_table_init(&state->symtab) < 0) { if (symbol_table_init(&state->symtab) < 0) {
close(state->in_fd); close(state->in_fd);
fclose(state->out_fp);
ptrbox_destroy(&state->ptrbox); ptrbox_destroy(&state->ptrbox);
return -1; return -1;
} }
if (tokbuf_init(&state->tokbuf) < 0) { if (tokbuf_init(&state->tokbuf) < 0) {
ptrbox_destroy(&state->ptrbox); ptrbox_destroy(&state->ptrbox);
fclose(state->out_fp);
symbol_table_destroy(&state->symtab); symbol_table_destroy(&state->symtab);
close(state->in_fd); close(state->in_fd);
return -1; return -1;
@@ -49,4 +58,5 @@ rifle_state_destroy(struct rifle_state *state)
state->in_fd = -1; state->in_fd = -1;
tokbuf_destroy(&state->tokbuf); tokbuf_destroy(&state->tokbuf);
symbol_table_destroy(&state->symtab); symbol_table_destroy(&state->symtab);
fclose(state->out_fp);
} }

View File

@@ -24,12 +24,14 @@ typedef enum {
* @dtype: Data type * @dtype: Data type
* @left: Left leaf * @left: Left leaf
* @right: Right leaf * @right: Right leaf
* @symbol: Symbol associated with node
*/ */
struct ast_node { struct ast_node {
ast_type_t type; ast_type_t type;
struct data_type dtype; struct data_type dtype;
struct ast_node *left; struct ast_node *left;
struct ast_node *right; struct ast_node *right;
struct symbol *symbol;
}; };
/* /*

20
inc/rifle/codegen.h Normal file
View File

@@ -0,0 +1,20 @@
#ifndef RIFLE_CODEGEN_H
#define RIFLE_CODEGEN_H 1
#include <stdint.h>
#include <stddef.h>
#include "rifle/ast.h"
#include "rifle/state.h"
/*
* Resolve a node and generate assembly code as an
* output.
*
* @state: Compiler state
* @root: Root input node to resolve
*
* Returns zero on success
*/
int cg_resolve_node(struct rifle_state *state, struct ast_node *root);
#endif /* !RIFLE_CODEGEN_H */

18
inc/rifle/mu.h Normal file
View File

@@ -0,0 +1,18 @@
#ifndef RIFLE_MU_H
#define RIFLE_MU_H 1
#include <stdint.h>
#include <stddef.h>
#include "rifle/state.h"
/*
* Generate a named label
*
* @state: Compiler state
* @name: Name of label to generate
*
* Returns zero on success
*/
int mu_gen_label(struct rifle_state *state, const char *name);
#endif /* !RIFLE_MU_H */

View File

@@ -2,6 +2,7 @@
#define RIFLE_STATE_H 1 #define RIFLE_STATE_H 1
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
#include <stddef.h> #include <stddef.h>
#include "rifle/tokbuf.h" #include "rifle/tokbuf.h"
#include "rifle/ptrbox.h" #include "rifle/ptrbox.h"
@@ -11,10 +12,14 @@
/* Maximum scope depth */ /* Maximum scope depth */
#define SCOPE_STACK_MAX 8 #define SCOPE_STACK_MAX 8
/* Default assembly output path */
#define ASMOUT "rifleout.asm"
/* /*
* Represents the compiler state * Represents the compiler state
* *
* @in_fd: Input file descriptor * @in_fd: Input file descriptor
* @out_fp: Output file
* @line_num: Current line number * @line_num: Current line number
* @pass_num: Current pass * @pass_num: Current pass
* @tokbuf: Global token buffer * @tokbuf: Global token buffer
@@ -27,6 +32,7 @@
*/ */
struct rifle_state { struct rifle_state {
int in_fd; int in_fd;
FILE *out_fp;
size_t line_num; size_t line_num;
size_t pass_num; size_t pass_num;
struct tokbuf tokbuf; struct tokbuf tokbuf;