Skip to content

Commit

Permalink
Improve base type handling
Browse files Browse the repository at this point in the history
  • Loading branch information
RobDangerous committed Sep 12, 2024
1 parent dccbc0a commit b4ce8d5
Show file tree
Hide file tree
Showing 7 changed files with 91 additions and 19 deletions.
17 changes: 16 additions & 1 deletion Sources/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -425,7 +425,7 @@ variable emit_expression(opcodes *code, block *parent, expression *e) {

return v;
}
case EXPRESSION_NUMBER: {
case EXPRESSION_FLOAT: {
type_ref t;
init_type_ref(&t, NO_NAME);
t.type = float_id;
Expand All @@ -440,6 +440,21 @@ variable emit_expression(opcodes *code, block *parent, expression *e) {

return v;
}
case EXPRESSION_INT: {
type_ref t;
init_type_ref(&t, NO_NAME);
t.type = float_id;
variable v = allocate_variable(t, VARIABLE_LOCAL);

opcode o;
o.type = OPCODE_LOAD_INT_CONSTANT;
o.size = OP_SIZE(o, op_load_float_constant);
o.op_load_int_constant.number = (int)e->number;
o.op_load_int_constant.to = v;
emit_op(code, &o);

return v;
}
// case EXPRESSION_STRING:
// error("not implemented", 0, 0);
case EXPRESSION_VARIABLE: {
Expand Down
5 changes: 5 additions & 0 deletions Sources/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ typedef struct opcode {
OPCODE_DIVIDE_AND_STORE_MEMBER,
OPCODE_MULTIPLY_AND_STORE_MEMBER,
OPCODE_LOAD_FLOAT_CONSTANT,
OPCODE_LOAD_INT_CONSTANT,
OPCODE_LOAD_BOOL_CONSTANT,
OPCODE_LOAD_MEMBER,
OPCODE_RETURN,
Expand Down Expand Up @@ -81,6 +82,10 @@ typedef struct opcode {
float number;
variable to;
} op_load_float_constant;
struct {
int number;
variable to;
} op_load_int_constant;
struct {
bool boolean;
variable to;
Expand Down
32 changes: 31 additions & 1 deletion Sources/kong.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,16 @@ static bool types_compatible(type_id left, type_id right) {
return true;
}

if ((left == float_id && right == float2_id) || (left == float_id && right == float3_id) || (left == float_id && right == float4_id) ||
(left == float2_id && right == float_id) || (left == float3_id && right == float_id) || (left == float4_id && right == float_id)) {
return true;
}

if ((left == int_id && right == int2_id) || (left == int_id && right == int3_id) || (left == int_id && right == int4_id) ||
(left == int2_id && right == int_id) || (left == int3_id && right == int_id) || (left == int4_id && right == int_id)) {
return true;
}

return false;
}

Expand Down Expand Up @@ -250,6 +260,22 @@ static type_ref upgrade_type(type_ref left_type, type_ref right_type) {
return left_type;
}

if ((left == float2_id && right == float_id) || (left == float3_id && right == float_id) || (left == float4_id && right == float_id)) {
return left_type;
}

if ((left == float_id && right == float2_id) || (left == float_id && right == float3_id) || (left == float_id && right == float4_id)) {
return right_type;
}

if ((left == int2_id && right == int_id) || (left == int3_id && right == int_id) || (left == int4_id && right == int_id)) {
return left_type;
}

if ((left == int_id && right == int2_id) || (left == int_id && right == int3_id) || (left == int_id && right == int4_id)) {
return right_type;
}

kong_log(LOG_LEVEL_WARNING, "Suspicious type upgrade");
return left_type;
}
Expand Down Expand Up @@ -360,10 +386,14 @@ void resolve_types_in_expression(statement *parent, expression *e) {
e->type.type = bool_id;
break;
}
case EXPRESSION_NUMBER: {
case EXPRESSION_FLOAT: {
e->type.type = float_id;
break;
}
case EXPRESSION_INT: {
e->type.type = int_id;
break;
}
case EXPRESSION_VARIABLE: {
global *g = find_global(e->variable);
if (g != NULL && g->type != NO_TYPE) {
Expand Down
41 changes: 28 additions & 13 deletions Sources/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ static definition parse_definition(state_t *state) {
current_attribute.paramters_count += 1;
advance_state(state);
}
else if (current(state).kind == TOKEN_NUMBER) {
else if (current(state).kind == TOKEN_FLOAT || current(state).kind == TOKEN_INT) {
current_attribute.parameters[current_attribute.paramters_count] = current(state).number;
current_attribute.paramters_count += 1;
advance_state(state);
Expand Down Expand Up @@ -276,7 +276,7 @@ static type_ref parse_type_ref(state_t *state) {
uint32_t array_size = 0;
if (current(state).kind == TOKEN_LEFT_SQUARE) {
advance_state(state);
match_token(state, TOKEN_NUMBER, "Expected a number");
match_token(state, TOKEN_INT, "Expected an integer");
array_size = (uint32_t)current(state).number;
advance_state(state);
match_token(state, TOKEN_RIGHT_SQUARE, "Expected a closing square bracket");
Expand Down Expand Up @@ -724,7 +724,7 @@ static expression *parse_member(state_t *state, bool square) {
return var;
}
}
else if (current(state).kind == TOKEN_NUMBER && square) {
else if (current(state).kind == TOKEN_INT && square) {
uint32_t index = (uint32_t)current(state).number;
advance_state(state);
match_token(state, TOKEN_RIGHT_SQUARE, "Expected a closing square bracket");
Expand Down Expand Up @@ -792,11 +792,19 @@ static expression *parse_primary(state_t *state) {
left->boolean = value;
break;
}
case TOKEN_NUMBER: {
case TOKEN_FLOAT: {
double value = current(state).number;
advance_state(state);
left = expression_allocate();
left->kind = EXPRESSION_NUMBER;
left->kind = EXPRESSION_FLOAT;
left->number = value;
break;
}
case TOKEN_INT: {
double value = current(state).number;
advance_state(state);
left = expression_allocate();
left->kind = EXPRESSION_INT;
left->number = value;
break;
}
Expand Down Expand Up @@ -842,7 +850,7 @@ static expression *parse_primary(state_t *state) {

advance_state(state);

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

expression *right = parse_member(state, square);

Expand Down Expand Up @@ -904,7 +912,7 @@ static expression *parse_call(state_t *state, name_id func_name) {

advance_state(state);

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

expression *right = parse_member(state, square);

Expand Down Expand Up @@ -959,7 +967,8 @@ static definition parse_struct_inner(state_t *state, name_id name) {

if (current(state).kind == TOKEN_OPERATOR && current(state).op == OPERATOR_ASSIGN) {
advance_state(state);
if (current(state).kind == TOKEN_BOOLEAN || current(state).kind == TOKEN_NUMBER || current(state).kind == TOKEN_IDENTIFIER) {
if (current(state).kind == TOKEN_BOOLEAN || current(state).kind == TOKEN_FLOAT || current(state).kind == TOKEN_INT ||
current(state).kind == TOKEN_IDENTIFIER) {
member_values[count] = current(state);
advance_state(state);
}
Expand Down Expand Up @@ -997,9 +1006,12 @@ static definition parse_struct_inner(state_t *state, name_id name) {
if (member.value.kind == TOKEN_BOOLEAN) {
init_type_ref(&member.type, add_name("bool"));
}
else if (member.value.kind == TOKEN_NUMBER) {
else if (member.value.kind == TOKEN_FLOAT) {
init_type_ref(&member.type, add_name("float"));
}
else if (member.value.kind == TOKEN_INT) {
init_type_ref(&member.type, add_name("int"));
}
else if (member.value.kind == TOKEN_IDENTIFIER) {
global *g = find_global(member.value.identifier);
if (g != NULL && g->name != NO_NAME) {
Expand Down Expand Up @@ -1142,7 +1154,7 @@ static definition parse_const(state_t *state, attribute_list attributes) {
else if (type_name == add_name("float")) {
debug_context context = {0};
check(value != NULL, context, "const float requires an initialization value");
check(value->kind == EXPRESSION_NUMBER, context, "const float3 requires a number");
check(value->kind == EXPRESSION_FLOAT || value->kind == EXPRESSION_INT, context, "const float3 requires a number");

global_value float_value;
float_value.kind = GLOBAL_VALUE_FLOAT;
Expand All @@ -1163,7 +1175,8 @@ static definition parse_const(state_t *state, attribute_list attributes) {
float2_value.kind = GLOBAL_VALUE_FLOAT2;

for (int i = 0; i < 2; ++i) {
check(value->call.parameters.e[i]->kind == EXPRESSION_NUMBER, context, "const float2 construtor parameters have to be numbers");
check(value->call.parameters.e[i]->kind == EXPRESSION_FLOAT || value->call.parameters.e[i]->kind == EXPRESSION_INT, context,
"const float2 construtor parameters have to be numbers");
float2_value.value.floats[i] = (float)value->call.parameters.e[i]->number;
}

Expand All @@ -1181,7 +1194,8 @@ static definition parse_const(state_t *state, attribute_list attributes) {
float3_value.kind = GLOBAL_VALUE_FLOAT3;

for (int i = 0; i < 3; ++i) {
check(value->call.parameters.e[i]->kind == EXPRESSION_NUMBER, context, "const float3 construtor parameters have to be numbers");
check(value->call.parameters.e[i]->kind == EXPRESSION_FLOAT || value->call.parameters.e[i]->kind == EXPRESSION_INT, context,
"const float3 construtor parameters have to be numbers");
float3_value.value.floats[i] = (float)value->call.parameters.e[i]->number;
}

Expand All @@ -1199,7 +1213,8 @@ static definition parse_const(state_t *state, attribute_list attributes) {
float4_value.kind = GLOBAL_VALUE_FLOAT4;

for (int i = 0; i < 4; ++i) {
check(value->call.parameters.e[i]->kind == EXPRESSION_NUMBER, context, "const float4 construtor parameters have to be numbers");
check(value->call.parameters.e[i]->kind == EXPRESSION_FLOAT || value->call.parameters.e[i]->kind == EXPRESSION_INT, context,
"const float4 construtor parameters have to be numbers");
float4_value.value.floats[i] = (float)value->call.parameters.e[i]->number;
}

Expand Down
3 changes: 2 additions & 1 deletion Sources/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ typedef struct expression {
EXPRESSION_BINARY,
EXPRESSION_UNARY,
EXPRESSION_BOOLEAN,
EXPRESSION_NUMBER,
EXPRESSION_FLOAT,
EXPRESSION_INT,
// EXPRESSION_STRING,
EXPRESSION_VARIABLE,
EXPRESSION_GROUPING,
Expand Down
9 changes: 7 additions & 2 deletions Sources/tokenizer.c
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ static void tokens_add_identifier(tokenizer_state *state, tokens *tokens, tokeni

tokens tokenize(const char *filename, const char *source) {
mode mode = MODE_SELECT;
bool number_has_dot = false;

tokens tokens;
tokens_init(&tokens);
Expand All @@ -222,7 +223,7 @@ tokens tokenize(const char *filename, const char *source) {
tokens_add_identifier(&state, &tokens, &buffer);
break;
case MODE_NUMBER: {
token token = token_create(TOKEN_NUMBER, &state);
token token = token_create(number_has_dot ? TOKEN_FLOAT : TOKEN_INT, &state);
token.number = tokenizer_buffer_parse_number(&buffer);
tokens_add(&tokens, token);
break;
Expand Down Expand Up @@ -264,6 +265,7 @@ tokens tokenize(const char *filename, const char *source) {
}
else if (is_num(ch, state.next_next)) {
mode = MODE_NUMBER;
number_has_dot = false;
tokenizer_buffer_reset(&buffer, &state);
tokenizer_buffer_add(&buffer, ch);
}
Expand Down Expand Up @@ -342,11 +344,14 @@ tokens tokenize(const char *filename, const char *source) {
}
case MODE_NUMBER: {
if (is_num(ch, 0) || ch == '.') {
if (ch == '.') {
number_has_dot = true;
}
tokenizer_buffer_add(&buffer, ch);
tokenizer_state_advance(&context, &state);
}
else {
token token = token_create(TOKEN_NUMBER, &state);
token token = token_create(number_has_dot ? TOKEN_FLOAT : TOKEN_INT, &state);
token.number = tokenizer_buffer_parse_number(&buffer);
tokens_add(&tokens, token);
mode = MODE_SELECT;
Expand Down
3 changes: 2 additions & 1 deletion Sources/tokenizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ typedef struct token {
enum {
TOKEN_NONE,
TOKEN_BOOLEAN,
TOKEN_NUMBER,
TOKEN_FLOAT,
TOKEN_INT,
// TOKEN_STRING,
TOKEN_IDENTIFIER,
TOKEN_LEFT_PAREN,
Expand Down

0 comments on commit b4ce8d5

Please sign in to comment.