Skip to content

Commit

Permalink
impl variable node scope offsets
Browse files Browse the repository at this point in the history
  • Loading branch information
omdxp committed Aug 18, 2024
1 parent c0513db commit c83ba83
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 2 deletions.
4 changes: 4 additions & 0 deletions compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ struct node {
struct var {
struct datatype type;
int padding;
int aoffset; // aligned offset
const char *name;
struct node *val;
} var;
Expand Down Expand Up @@ -403,6 +404,7 @@ bool token_is_operator(struct token *token, const char *value);

bool datatype_is_struct_or_union_for_name(const char *name);
bool datatype_is_struct_or_union(struct datatype *dtype);
bool datatype_is_primitive(struct datatype *dtype);

size_t datatype_size_for_array_access(struct datatype *dtype);
size_t datatype_element_size(struct datatype *dtype);
Expand All @@ -424,6 +426,8 @@ void node_set_vector(struct vector *vec, struct vector *root_vec);
struct node *node_create(struct node *_node);
struct node *node_peek_expressionable_or_null();
struct node *variable_struct_or_union_body_node(struct node *node);
struct node *variable_node(struct node *node);
bool variable_node_is_primitive(struct node *node);

bool node_is_struct_or_union_variable(struct node *node);

Expand Down
4 changes: 4 additions & 0 deletions datatype.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,7 @@ size_t datatype_size(struct datatype *dtype) {

return dtype->size;
}

bool datatype_is_primitive(struct datatype *dtype) {
return !datatype_is_struct_or_union(dtype);
}
25 changes: 25 additions & 0 deletions node.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,28 @@ bool node_is_struct_or_union_variable(struct node *node) {

return datatype_is_struct_or_union(&node->var.type);
}

struct node *variable_node(struct node *node) {
struct node *var_node = NULL;
switch (node->type) {
case NODE_TYPE_VARIABLE:
var_node = node;
break;

case NODE_TYPE_STRUCT:
var_node = node->_struct.var;
break;

case NODE_TYPE_UNION:
// var_node = node->_union.var;
assert(false && "Union variable not implemented");
break;
}

return var_node;
}

bool variable_node_is_primitive(struct node *node) {
assert(node->type == NODE_TYPE_VARIABLE);
return datatype_is_primitive(&node->var.type);
}
71 changes: 69 additions & 2 deletions parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,17 @@ parser_new_scope_entity(struct node *node, int stack_offset, int flags) {
return entity;
}

enum { HISTORY_FLAG_INSIDE_UNION = 0b00000001 };
struct parser_scope_entity *parser_scope_last_entity_stop_global_scope() {
return scope_last_entity_from_scope_stop_at(current_process,
current_process->scope.root);
}

enum {
HISTORY_FLAG_INSIDE_UNION = 0b00000001,
HISTORY_FLAG_IS_UPWARD_STACK = 0b00000010,
HISTORY_FLAG_IS_GLOBAL_SCOPE = 0b000000100,
HISTORY_FLAG_INSIDE_STRUCT = 0b00001000,
};

struct history {
int flags;
Expand All @@ -62,6 +72,10 @@ void parser_scope_new() { scope_new(current_process, 0); }

void parser_scope_finish() { scope_finish(current_process); }

struct parser_scope_entity *parser_scope_last_entity() {
return scope_last_entity(current_process);
}

void parser_scope_push(struct node *node, size_t size) {
scope_push(current_process, node, size);
}
Expand Down Expand Up @@ -522,6 +536,58 @@ void make_variable_node(struct datatype *dtype, struct token *name_token,
});
}

void parser_scope_offset_for_stack(struct node *node, struct history *history) {
struct parser_scope_entity *last_entity =
parser_scope_last_entity_stop_global_scope();
bool upward_stack = history->flags & HISTORY_FLAG_IS_UPWARD_STACK;
int offset = -variable_size(node);
if (upward_stack) {
#warning "TODO: handle upward stack"
compiler_error(current_process, "Upward stack not implemented yet");
}

if (last_entity) {
offset += variable_node(last_entity->node)->var.aoffset;
if (variable_node_is_primitive(node)) {
variable_node(node)->var.padding =
padding(upward_stack ? offset : -offset, node->var.type.size);
}
}
}

void parser_scope_offset_for_global(struct node *node,
struct history *history) {
return;
}

void parser_scope_offset_for_struct(struct node *node,
struct history *history) {
int offset = 0;
struct parser_scope_entity *last_entity = parser_scope_last_entity();
if (last_entity) {
offset += last_entity->stack_offset + last_entity->node->var.type.size;
if (variable_node_is_primitive(node)) {
node->var.padding = padding(offset, node->var.type.size);
}

node->var.aoffset = offset + node->var.padding;
}
}

void parser_scope_offset(struct node *node, struct history *history) {
if (history->flags & HISTORY_FLAG_IS_GLOBAL_SCOPE) {
parser_scope_offset_for_global(node, history);
return;
}

if (history->flags & HISTORY_FLAG_INSIDE_STRUCT) {
parser_scope_offset_for_struct(node, history);
return;
}

parser_scope_offset_for_stack(node, history);
}

void make_variable_node_and_register(struct history *history,
struct datatype *dtype,
struct token *name_token,
Expand All @@ -530,9 +596,10 @@ void make_variable_node_and_register(struct history *history,
struct node *var_node = node_pop();

// calculate scope offset
parser_scope_offset(var_node, history);

// push the variable node to the current scope
#warning "TODO: calculate scope offset and push to scope"

node_push(var_node);
}

Expand Down

0 comments on commit c83ba83

Please sign in to comment.