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")
|
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
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/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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
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;
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
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
|
#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;
|
||||||
|
|||||||
Reference in New Issue
Block a user