core: Add initial codegen sources
Signed-off-by: Ian Moffett <ian@mirocom.org>
This commit is contained in:
5
Makefile
5
Makefile
@@ -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
19
backend/x86_64.c
Normal 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
42
core/codegen.c
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
10
core/state.c
10
core/state.c
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
20
inc/rifle/codegen.h
Normal 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
18
inc/rifle/mu.h
Normal 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 */
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user