Skip to content

Commit

Permalink
Parse and type dynamic members
Browse files Browse the repository at this point in the history
  • Loading branch information
RobDangerous committed Aug 27, 2024
1 parent 501eaf9 commit e541900
Show file tree
Hide file tree
Showing 4 changed files with 87 additions and 43 deletions.
14 changes: 7 additions & 7 deletions Sources/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ variable emit_expression(opcodes *code, block *parent, expression *e) {
case OPERATOR_GREATER_EQUAL:
case OPERATOR_LESS:
case OPERATOR_LESS_EQUAL:
case OPERATOR_AND:
case OPERATOR_AND:
case OPERATOR_OR: {
variable right_var = emit_expression(code, parent, right);
variable left_var = emit_expression(code, parent, left);
Expand Down Expand Up @@ -250,7 +250,7 @@ variable emit_expression(opcodes *code, block *parent, expression *e) {
emit_op(code, &o);
break;
}
case EXPRESSION_MEMBER: {
case EXPRESSION_STATIC_MEMBER: {
variable member_var = emit_expression(code, parent, left->member.left);

opcode o;
Expand Down Expand Up @@ -287,7 +287,7 @@ variable emit_expression(opcodes *code, block *parent, expression *e) {
o.op_store_member.member_parent_type = prev_struct;
o.op_store_member.member_parent_array = left->member.left->type.array_size > 0;

while (right->kind == EXPRESSION_MEMBER) {
while (right->kind == EXPRESSION_STATIC_MEMBER) {
debug_context context = {0};
check(right->type.type != NO_TYPE, context, "Part of the member does not have a type");

Expand Down Expand Up @@ -459,7 +459,7 @@ variable emit_expression(opcodes *code, block *parent, expression *e) {

return v;
}
case EXPRESSION_MEMBER: {
case EXPRESSION_STATIC_MEMBER: {
variable v = allocate_variable(e->type, VARIABLE_LOCAL);

opcode o;
Expand All @@ -483,7 +483,7 @@ variable emit_expression(opcodes *code, block *parent, expression *e) {
type *prev_s = get_type(prev_struct);
o.op_load_member.member_parent_type = prev_struct;

while (right->kind == EXPRESSION_MEMBER) {
while (right->kind == EXPRESSION_STATIC_MEMBER) {
check(right->type.type != NO_TYPE, context, "Malformed member construct");
check(right->member.left->kind == EXPRESSION_VARIABLE, context, "Malformed member construct");

Expand Down Expand Up @@ -629,7 +629,7 @@ static block_ids emit_statement(opcodes *code, block *parent, statement *stateme

if (statement->iffy.else_tests[i] != NULL) {
variable v = emit_expression(code, parent, statement->iffy.else_tests[i]);

variable else_test;
{
opcode o;
Expand Down Expand Up @@ -663,7 +663,7 @@ static block_ids emit_statement(opcodes *code, block *parent, statement *stateme
written_opcode->op_if.end_id = ids.end;
}
}

break;
}
case STATEMENT_WHILE: {
Expand Down
36 changes: 24 additions & 12 deletions Sources/kong.c
Original file line number Diff line number Diff line change
Expand Up @@ -93,19 +93,30 @@ type_ref resolve_member_var_type(statement *parent_block, type_ref parent_type,
}

void resolve_member_type(statement *parent_block, type_ref parent_type, expression *e) {
if (e->kind == EXPRESSION_VARIABLE) {
resolve_member_var_type(parent_block, parent_type, e);
return;
}

debug_context context = {0};
check(e->kind == EXPRESSION_MEMBER, context, "Malformed member");
check(e->kind == EXPRESSION_STATIC_MEMBER || e->kind == EXPRESSION_DYNAMIC_MEMBER, context, "Malformed member");

type_ref t = resolve_member_var_type(parent_block, parent_type, e->member.left);

resolve_member_type(parent_block, t, e->member.right);

e->type = e->member.right->type;
if (e->kind == EXPRESSION_STATIC_MEMBER && e->member.right->kind == EXPRESSION_VARIABLE) {
resolve_member_var_type(parent_block, t, e->member.right);
e->type = e->member.right->type;
}
else if (e->kind == EXPRESSION_DYNAMIC_MEMBER) {
resolve_types_in_expression(parent_block, e->member.right);
if (e->member.left->type.type == tex2d_type_id) {
init_type_ref(&e->type, NO_NAME);
e->type.type = float4_id;
}
else {
e->type = e->member.left->type;
e->type.array_size = 0;
}
}
else {
resolve_member_type(parent_block, t, e->member.right);
e->type = e->member.right->type;
}
}

static bool types_compatible(type_id left, type_id right) {
Expand Down Expand Up @@ -386,7 +397,8 @@ void resolve_types_in_expression(statement *parent, expression *e) {
}
break;
}
case EXPRESSION_MEMBER: {
case EXPRESSION_STATIC_MEMBER:
case EXPRESSION_DYNAMIC_MEMBER: {
type_ref t;
init_type_ref(&t, NO_NAME);
resolve_member_type(parent, t, e);
Expand Down Expand Up @@ -785,14 +797,14 @@ int main(int argc, char **argv) {
#include <Windows.h>
#endif

void execute_sync(const char* command) {
void execute_sync(const char *command) {
#ifdef _WIN32
STARTUPINFOA startupInfo;
PROCESS_INFORMATION processInfo;
memset(&startupInfo, 0, sizeof(startupInfo));
memset(&processInfo, 0, sizeof(processInfo));
startupInfo.cb = sizeof(startupInfo);
CreateProcessA(NULL, (char*)command, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, "PATH=%PATH%;.\\cygwin\\bin\0", NULL, &startupInfo, &processInfo);
CreateProcessA(NULL, (char *)command, NULL, NULL, FALSE, CREATE_DEFAULT_ERROR_MODE, "PATH=%PATH%;.\\cygwin\\bin\0", NULL, &startupInfo, &processInfo);
WaitForSingleObject(processInfo.hProcess, INFINITE);
CloseHandle(processInfo.hProcess);
CloseHandle(processInfo.hThread);
Expand Down
77 changes: 54 additions & 23 deletions Sources/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,13 +170,14 @@ static definition parse_definition(state_t *state) {
current_attribute.name = current(state).identifier;

advance_state(state);

if (current(state).kind == TOKEN_LEFT_PAREN) {
advance_state(state);

while (current(state).kind != TOKEN_RIGHT_PAREN) {
if (current(state).kind == TOKEN_IDENTIFIER) {
current_attribute.parameters[current_attribute.paramters_count] = attribute_parameter_to_number(current_attribute.name, current(state).identifier);
current_attribute.parameters[current_attribute.paramters_count] =
attribute_parameter_to_number(current_attribute.name, current(state).identifier);
current_attribute.paramters_count += 1;
advance_state(state);
}
Expand All @@ -190,7 +191,7 @@ static definition parse_definition(state_t *state) {
error(context, "Expected an identifier or a number");
}

if (current(state).kind != TOKEN_RIGHT_PAREN){
if (current(state).kind != TOKEN_RIGHT_PAREN) {
match_token(state, TOKEN_COMMA, "Expected a comma");
advance_state(state);
}
Expand Down Expand Up @@ -314,7 +315,7 @@ static statement *parse_statement(state_t *state, block *parent_block) {
advance_state(state);

statement *while_block = parse_statement(state, parent_block);

statement *s = statement_allocate();
s->kind = STATEMENT_WHILE;
s->whiley.test = test;
Expand All @@ -324,9 +325,9 @@ static statement *parse_statement(state_t *state, block *parent_block) {
}
case TOKEN_DO: {
advance_state(state);

statement *do_block = parse_statement(state, parent_block);

statement *s = statement_allocate();
s->kind = STATEMENT_DO_WHILE;
s->whiley.while_block = do_block;
Expand Down Expand Up @@ -464,7 +465,8 @@ static expression *parse_assign(state_t *state) {
while (!done) {
if (current(state).kind == TOKEN_OPERATOR) {
operatorr op = current(state).op;
if (op == OPERATOR_ASSIGN || op == OPERATOR_MINUS_ASSIGN || op == OPERATOR_PLUS_ASSIGN || op == OPERATOR_DIVIDE_ASSIGN || op == OPERATOR_MULTIPLY_ASSIGN) {
if (op == OPERATOR_ASSIGN || op == OPERATOR_MINUS_ASSIGN || op == OPERATOR_PLUS_ASSIGN || op == OPERATOR_DIVIDE_ASSIGN ||
op == OPERATOR_MULTIPLY_ASSIGN) {
advance_state(state);
expression *right = parse_logical(state);
expression *expression = expression_allocate();
Expand Down Expand Up @@ -659,16 +661,16 @@ static expression *parse_unary(state_t *state) {

static expression *parse_call(state_t *state, name_id func_name);

static expression *parse_member(state_t *state, bool number) {
if (current(state).kind == TOKEN_IDENTIFIER && !number) {
static expression *parse_member(state_t *state, bool square) {
if (current(state).kind == TOKEN_IDENTIFIER && !square) {
token token = current(state);
advance_state(state);

if (current(state).kind == TOKEN_LEFT_PAREN) {
return parse_call(state, token.identifier);
}
else if (current(state).kind == TOKEN_DOT || current(state).kind == TOKEN_LEFT_SQUARE) {
bool number = current(state).kind == TOKEN_LEFT_SQUARE;
bool square = current(state).kind == TOKEN_LEFT_SQUARE;

advance_state(state);

Expand All @@ -677,9 +679,9 @@ static expression *parse_member(state_t *state, bool number) {
var->variable = token.identifier;

expression *member = expression_allocate();
member->kind = EXPRESSION_MEMBER;
member->kind = EXPRESSION_STATIC_MEMBER;
member->member.left = var;
member->member.right = parse_member(state, number);
member->member.right = parse_member(state, square);

return member;
}
Expand All @@ -690,14 +692,14 @@ static expression *parse_member(state_t *state, bool number) {
return var;
}
}
else if (current(state).kind == TOKEN_NUMBER && number) {
else if (current(state).kind == TOKEN_NUMBER && square) {
uint32_t index = (uint32_t)current(state).number;
advance_state(state);
match_token(state, TOKEN_RIGHT_SQUARE, "Expected a closing square bracket");
advance_state(state);

if (current(state).kind == TOKEN_DOT || current(state).kind == TOKEN_LEFT_SQUARE) {
bool number = current(state).kind == TOKEN_LEFT_SQUARE;
bool square = current(state).kind == TOKEN_LEFT_SQUARE;

advance_state(state);

Expand All @@ -706,9 +708,9 @@ static expression *parse_member(state_t *state, bool number) {
var->index = index;

expression *member = expression_allocate();
member->kind = EXPRESSION_MEMBER;
member->kind = EXPRESSION_STATIC_MEMBER;
member->member.left = var;
member->member.right = parse_member(state, number);
member->member.right = parse_member(state, square);

return member;
}
Expand All @@ -719,6 +721,27 @@ static expression *parse_member(state_t *state, bool number) {
return var;
}
}
else if (square) {
expression *index = parse_expression(state);
match_token(state, TOKEN_RIGHT_SQUARE, "Expected a closing square bracket");
advance_state(state);

if (current(state).kind == TOKEN_DOT || current(state).kind == TOKEN_LEFT_SQUARE) {
bool square = current(state).kind == TOKEN_LEFT_SQUARE;

advance_state(state);

expression *member = expression_allocate();
member->kind = EXPRESSION_DYNAMIC_MEMBER;
member->member.left = index;
member->member.right = parse_member(state, square);

return member;
}
else {
return index;
}
}
else {
error(state->context, "Unexpected token");
return NULL;
Expand Down Expand Up @@ -783,13 +806,16 @@ static expression *parse_primary(state_t *state) {
}

if (current(state).kind == TOKEN_DOT || current(state).kind == TOKEN_LEFT_SQUARE) {
bool number = current(state).kind == TOKEN_LEFT_SQUARE;
bool square = current(state).kind == TOKEN_LEFT_SQUARE;

advance_state(state);
expression *right = parse_member(state, number);

bool dynamic = square && current(state).kind != TOKEN_NUMBER;

expression *right = parse_member(state, square);

expression *member = expression_allocate();
member->kind = EXPRESSION_MEMBER;
member->kind = dynamic ? EXPRESSION_DYNAMIC_MEMBER : EXPRESSION_STATIC_MEMBER;
member->member.left = left;
member->member.right = right;

Expand Down Expand Up @@ -841,12 +867,17 @@ static expression *parse_call(state_t *state, name_id func_name) {
call->call.func_name = func_name;
call->call.parameters = parse_parameters(state);

if (current(state).kind == TOKEN_DOT) {
if (current(state).kind == TOKEN_DOT || current(state).kind == TOKEN_LEFT_SQUARE) {
bool square = current(state).kind == TOKEN_LEFT_SQUARE;

advance_state(state);
expression *right = parse_expression(state);

bool dynamic = square && current(state).kind == TOKEN_NUMBER;

expression *right = parse_member(state, square);

expression *member = expression_allocate();
member->kind = EXPRESSION_MEMBER;
member->kind = dynamic ? EXPRESSION_DYNAMIC_MEMBER : EXPRESSION_STATIC_MEMBER;
member->member.left = call;
member->member.right = right;

Expand Down Expand Up @@ -1006,7 +1037,7 @@ static definition parse_function(state_t *state) {
type_ref return_type = parse_type_ref(state);

statement *block = parse_block(state, NULL);

definition d;
d.kind = DEFINITION_FUNCTION;
d.function = add_function(name.identifier);
Expand Down
3 changes: 2 additions & 1 deletion Sources/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ typedef struct expression {
EXPRESSION_VARIABLE,
EXPRESSION_GROUPING,
EXPRESSION_CALL,
EXPRESSION_MEMBER,
EXPRESSION_STATIC_MEMBER,
EXPRESSION_DYNAMIC_MEMBER,
EXPRESSION_INDEX,
EXPRESSION_CONSTRUCTOR
} kind;
Expand Down

0 comments on commit e541900

Please sign in to comment.