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")
OFILES = $(CFILES:.c=.o)
DFILES = $(CFILES:.c=.d)
@@ -7,7 +10,7 @@ CFLAGS = -Wall -pedantic -Iinc/ -MMD
.PHONY: all
all: $(OFILES)
$(CC) $(OFILES) -o rifle
$(CC) $(BACKEND) $(CFLAGS) $(OFILES) -o rifle
-include $(DFILES)
%.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/ast.h"
#include "rifle/scope.h"
#include "rifle/codegen.h"
/* Symbolic token */
#define symtok(tok) \
@@ -438,6 +439,8 @@ parse_func(struct rifle_state *state, struct token *tok, struct ast_node **res)
return -1;
}
root->symbol = symbol;
/* EXPECT '(' */
if (parse_expect(state, TT_LPAREN, tok) < 0) {
return -1;
@@ -468,6 +471,7 @@ parse_func(struct rifle_state *state, struct token *tok, struct ast_node **res)
return -1;
}
*res = root;
return 0;
}
@@ -501,7 +505,7 @@ static int
parse_begin(struct rifle_state *state)
{
struct token tok;
struct ast_node *root;
struct ast_node *root = NULL;
while (parse_scan(state, &tok) == 0) {
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;
}

View File

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

View File

@@ -24,12 +24,14 @@ typedef enum {
* @dtype: Data type
* @left: Left leaf
* @right: Right leaf
* @symbol: Symbol associated with node
*/
struct ast_node {
ast_type_t type;
struct data_type dtype;
struct ast_node *left;
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
#include <stdint.h>
#include <stdio.h>
#include <stddef.h>
#include "rifle/tokbuf.h"
#include "rifle/ptrbox.h"
@@ -11,10 +12,14 @@
/* Maximum scope depth */
#define SCOPE_STACK_MAX 8
/* Default assembly output path */
#define ASMOUT "rifleout.asm"
/*
* Represents the compiler state
*
* @in_fd: Input file descriptor
* @out_fp: Output file
* @line_num: Current line number
* @pass_num: Current pass
* @tokbuf: Global token buffer
@@ -27,6 +32,7 @@
*/
struct rifle_state {
int in_fd;
FILE *out_fp;
size_t line_num;
size_t pass_num;
struct tokbuf tokbuf;