Skip to content

Commit

Permalink
build stack frame functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
omdxp committed Aug 25, 2024
1 parent 03c48a5 commit f64e0b2
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 9 deletions.
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
OBJECTS= ./build/compiler.o ./build/codegen.o ./build/array.o ./build/fixup.o ./build/helper.o ./build/scope.o ./build/symresolver.o ./build/cprocess.o ./build/datatype.o ./build/expressionable.o ./build/lexer.o ./build/token.o ./build/lex_process.o ./build/parser.o ./build/node.o ./build/helpers/buffer.o ./build/helpers/vector.o
OBJECTS= ./build/compiler.o ./build/codegen.o ./build/stackframe.o ./build/array.o ./build/fixup.o ./build/helper.o ./build/scope.o ./build/symresolver.o ./build/cprocess.o ./build/datatype.o ./build/expressionable.o ./build/lexer.o ./build/token.o ./build/lex_process.o ./build/parser.o ./build/node.o ./build/helpers/buffer.o ./build/helpers/vector.o
INCLUDES= -I./

all: ${OBJECTS}
Expand All @@ -10,6 +10,9 @@ all: ${OBJECTS}
./build/codegen.o: ./codegen.c
gcc ./codegen.c ${INCLUDES} -o ./build/codegen.o -g -c

./build/stackframe.o: ./stackframe.c
gcc ./stackframe.c ${INCLUDES} -o ./build/stackframe.o -g -c

./build/cprocess.o: ./cprocess.c
gcc ./cprocess.c ${INCLUDES} -o ./build/cprocess.o -g -c

Expand Down
62 changes: 62 additions & 0 deletions compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,62 @@ struct datatype {
} array;
};

struct stack_frame_data {
// data type that the stack frame is for
struct datatype *type;
};

struct stack_frame_element {
// stack frame flags
int flags;

// type of the stack frame element
int type;

// name of the stack frame element
const char *name;

// offset from the base pointer
int offset_from_bp;

// data for the stack frame element
struct stack_frame_data data;
};

#define STACK_PUSH_SIZE 4

enum {
STACK_FRAME_ELEMENT_TYPE_LOCAL_VARIABLE,
STACK_FRAME_ELEMENT_TYPE_SAVED_REGISTER,
STACK_FRAME_ELEMENT_TYPE_SAVED_BASE_POINTER,
STACK_FRAME_ELEMENT_TYPE_PUSHED_VALUE,
STACK_FRAME_ELEMENT_TYPE_UNKNOWN,
};

enum {
STACK_FRAME_ELEMENT_FLAG_IS_PUSHED_ADDRESS = 0b00000001,
STACK_FRAME_ELEMENT_FLAG_ELEMENT_NOT_FOUND = 0b00000010,
STACK_FRAME_ELEMENT_FLAG_IS_NUMERICAL = 0b00000100,
STACK_FRAME_ELEMENT_FLAG_HAS_DATA_TYPE = 0b00001000,
};

void stackframe_pop(struct node *func_node);
struct stack_frame_element *stackframe_back(struct node *func_node);
struct stack_frame_element *stackframe_back_expect(struct node *func_node,
int expecting_type,
const char *expecting_name);
void stackframe_pop_expecting(struct node *func_node, int expecting_type,
const char *expecting_name);
void stackframe_peek_start(struct node *func_node);
struct stack_frame_element *stackframe_peek(struct node *func_node);
void stackframe_push(struct node *func_node,
struct stack_frame_element *element);
void stackframe_sub(struct node *func_node, int type, const char *name,
size_t amount);
void stackframe_add(struct node *func_node, int type, const char *name,
size_t amount);
void stackframe_assert_empty(struct node *func_node);

struct parsed_switch_case {
// index of parsed case
int index;
Expand Down Expand Up @@ -400,6 +456,12 @@ struct node {
// body of the function (NULL if it is a function prototype)
struct node *body_n;

// stack frame
struct stack_frame {
// vector of struct stack_frame_element*
struct vector *elements;
} stack_frame;

// stack size for all the variables in the function
size_t stack_size;
} func;
Expand Down
17 changes: 9 additions & 8 deletions node.c
Original file line number Diff line number Diff line change
Expand Up @@ -193,14 +193,15 @@ void make_union_node(const char *name, struct node *body_node) {

void make_function_node(struct datatype *rtype, const char *name,
struct vector *args, struct node *body) {
node_create(&(struct node){.type = NODE_TYPE_FUNCTION,
.func.rtype = *rtype,
.func.name = name,
.func.args.args = args,
.func.body_n = body,
.func.args.stack_addition = DATA_SIZE_QWORD});

#warning "TODO: build frame elements"
struct node *func_node =
node_create(&(struct node){.type = NODE_TYPE_FUNCTION,
.func.rtype = *rtype,
.func.name = name,
.func.args.args = args,
.func.body_n = body,
.func.args.stack_addition = DATA_SIZE_QWORD});
func_node->func.stack_frame.elements =
vector_create(sizeof(struct stack_frame_element));
}

struct node *node_from_sym(struct symbol *sym) {
Expand Down
78 changes: 78 additions & 0 deletions stackframe.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#include "compiler.h"
#include "helpers/vector.h"
#include <assert.h>

void stackframe_pop(struct node *func_node) {
struct stack_frame *frame = &func_node->func.stack_frame;
vector_pop(frame->elements);
}

struct stack_frame_element *stackframe_back(struct node *func_node) {
struct stack_frame *frame = &func_node->func.stack_frame;
return vector_back_or_null(frame->elements);
}

struct stack_frame_element *stackframe_back_expect(struct node *func_node,
int expecting_type,
const char *expecting_name) {
struct stack_frame_element *last_element = stackframe_back(func_node);
if (last_element && last_element->type != expecting_type ||
!S_EQ(last_element->name, expecting_name)) {
return NULL;
}

return last_element;
}

void stackframe_pop_expecting(struct node *func_node, int expecting_type,
const char *expecting_name) {
struct stack_frame *frame = &func_node->func.stack_frame;
struct stack_frame_element *last_element = stackframe_back(func_node);
assert(last_element);
assert(last_element->type == expecting_type &&
S_EQ(last_element->name, expecting_name));
stackframe_pop(func_node);
}

void stackframe_peek_start(struct node *func_node) {
struct stack_frame *frame = &func_node->func.stack_frame;
vector_set_peek_pointer(frame->elements, 0);
vector_set_flag(frame->elements, VECTOR_FLAG_PEEK_DECREMENT);
}

struct stack_frame_element *stackframe_peek(struct node *func_node) {
struct stack_frame *frame = &func_node->func.stack_frame;
return vector_peek(frame->elements);
}

void stackframe_push(struct node *func_node,
struct stack_frame_element *element) {
struct stack_frame *frame = &func_node->func.stack_frame;
// stack grows downwards
element->offset_from_bp = -(vector_count(frame->elements) * STACK_PUSH_SIZE);
vector_push(frame->elements, element);
}

void stackframe_sub(struct node *func_node, int type, const char *name,
size_t amount) {
assert((amount % STACK_PUSH_SIZE) == 0);
size_t total_pushes = amount / STACK_PUSH_SIZE;
for (size_t i = 0; i < total_pushes; i++) {
stackframe_push(func_node,
&(struct stack_frame_element){.type = type, .name = name});
}
}

void stackframe_add(struct node *func_node, int type, const char *name,
size_t amount) {
assert((amount % STACK_PUSH_SIZE) == 0);
size_t total_pushes = amount / STACK_PUSH_SIZE;
for (size_t i = 0; i < total_pushes; i++) {
stackframe_pop(func_node);
}
}

void stackframe_assert_empty(struct node *func_node) {
struct stack_frame *frame = &func_node->func.stack_frame;
assert(vector_count(frame->elements) == 0);
}

0 comments on commit f64e0b2

Please sign in to comment.