Skip to content

Commit

Permalink
Make for loops almost work
Browse files Browse the repository at this point in the history
  • Loading branch information
RobDangerous committed Aug 18, 2024
1 parent 9429d1e commit e437fb5
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 5 deletions.
12 changes: 12 additions & 0 deletions Sources/backends/cstyle.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,18 @@ void cstyle_write_opcode(char *code, size_t *offset, opcode *o, type_string_func
case OPCODE_STORE_VARIABLE:
*offset += sprintf(&code[*offset], "\t_%" PRIu64 " = _%" PRIu64 ";\n", o->op_store_var.to.index, o->op_store_var.from.index);
break;
case OPCODE_SUB_AND_STORE_VARIABLE:
*offset += sprintf(&code[*offset], "\t_%" PRIu64 " /= _%" PRIu64 ";\n", o->op_store_var.to.index, o->op_store_var.from.index);
break;
case OPCODE_ADD_AND_STORE_VARIABLE:
*offset += sprintf(&code[*offset], "\t_%" PRIu64 " += _%" PRIu64 ";\n", o->op_store_var.to.index, o->op_store_var.from.index);
break;
case OPCODE_DIVIDE_AND_STORE_VARIABLE:
*offset += sprintf(&code[*offset], "\t_%" PRIu64 " /= _%" PRIu64 ";\n", o->op_store_var.to.index, o->op_store_var.from.index);
break;
case OPCODE_MULTIPLY_AND_STORE_VARIABLE:
*offset += sprintf(&code[*offset], "\t_%" PRIu64 " *= _%" PRIu64 ";\n", o->op_store_var.to.index, o->op_store_var.from.index);
break;
case OPCODE_STORE_MEMBER:
case OPCODE_SUB_AND_STORE_MEMBER:
case OPCODE_ADD_AND_STORE_MEMBER:
Expand Down
31 changes: 26 additions & 5 deletions Sources/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -191,12 +191,28 @@ variable emit_expression(opcodes *code, block *parent, expression *e) {

switch (left->kind) {
case EXPRESSION_VARIABLE: {
if (e->binary.op != OPERATOR_ASSIGN) {
opcode o;
switch (e->binary.op) {
case OPERATOR_ASSIGN:
o.type = OPCODE_STORE_VARIABLE;
break;
case OPERATOR_MINUS_ASSIGN:
o.type = OPCODE_SUB_AND_STORE_VARIABLE;
break;
case OPERATOR_PLUS_ASSIGN:
o.type = OPCODE_ADD_AND_STORE_VARIABLE;
break;
case OPERATOR_DIVIDE_ASSIGN:
o.type = OPCODE_DIVIDE_AND_STORE_VARIABLE;
break;
case OPERATOR_MULTIPLY_ASSIGN:
o.type = OPCODE_MULTIPLY_AND_STORE_VARIABLE;
break;
default: {
debug_context context = {0};
error(context, "operator can not initialize a variable");
error(context, "Unexpected operator");
}
}
opcode o;
o.type = OPCODE_STORE_VARIABLE;
o.size = OP_SIZE(o, op_store_var);
o.op_store_var.from = v;
// o.op_store_var.to = left->variable;
Expand Down Expand Up @@ -612,6 +628,11 @@ void emit_statement(opcodes *code, block *parent, statement *statement) {
break;
}
case STATEMENT_BLOCK: {
for (size_t i = 0; i < statement->block.vars.size; ++i) {
variable var = allocate_variable(statement->block.vars.v[i].type, VARIABLE_LOCAL);
statement->block.vars.v[i].variable_id = var.index;
}

{
opcode o;
o.type = OPCODE_BLOCK_START;
Expand Down Expand Up @@ -646,7 +667,7 @@ void emit_statement(opcodes *code, block *parent, statement *statement) {
statement->local_variable.var.variable_id = local_var.index;
o.op_var.var.index = statement->local_variable.var.variable_id;
debug_context context = {0};
check(statement->local_variable.var.type.type != NO_TYPE, context, "Local var has not type");
check(statement->local_variable.var.type.type != NO_TYPE, context, "Local var has no type");
o.op_var.var.type = statement->local_variable.var.type;
emit_op(code, &o);

Expand Down
4 changes: 4 additions & 0 deletions Sources/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ typedef struct opcode {
OPCODE_VAR,
OPCODE_NOT,
OPCODE_STORE_VARIABLE,
OPCODE_SUB_AND_STORE_VARIABLE,
OPCODE_ADD_AND_STORE_VARIABLE,
OPCODE_DIVIDE_AND_STORE_VARIABLE,
OPCODE_MULTIPLY_AND_STORE_VARIABLE,
OPCODE_STORE_MEMBER,
OPCODE_SUB_AND_STORE_MEMBER,
OPCODE_ADD_AND_STORE_MEMBER,
Expand Down
46 changes: 46 additions & 0 deletions Sources/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -328,6 +328,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 @@ -339,6 +340,7 @@ static statement *parse_statement(state_t *state, block *parent_block) {
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 All @@ -359,6 +361,50 @@ static statement *parse_statement(state_t *state, block *parent_block) {

return s;
}
case TOKEN_FOR: {
statements outer_block_statements;
statements_init(&outer_block_statements);

statement *outer_block = statement_allocate();
outer_block->kind = STATEMENT_BLOCK;
outer_block->block.parent = parent_block;
outer_block->block.vars.size = 0;
outer_block->block.statements = outer_block_statements;

advance_state(state);

match_token(state, TOKEN_LEFT_PAREN, "Expected an opening bracket");
advance_state(state);

statement *pre = parse_statement(state, &outer_block->block);
statements_add(&outer_block->block.statements, pre);

expression *test = parse_expression(state);
match_token(state, TOKEN_SEMICOLON, "Expected a semicolon");
advance_state(state);

expression *post_expression = parse_expression(state);

match_token(state, TOKEN_RIGHT_PAREN, "Expected a closing bracket");
advance_state(state);

statement *inner_block = parse_statement(state, &outer_block->block);

statement *post_statement = statement_allocate();
post_statement->kind = STATEMENT_EXPRESSION;
post_statement->expression = post_expression;

statements_add(&inner_block->block.statements, post_statement);

statement *s = statement_allocate();
s->kind = STATEMENT_WHILE;
s->whiley.test = test;
s->whiley.while_block = inner_block;

statements_add(&outer_block->block.statements, s);

return outer_block;
}
case TOKEN_LEFT_CURLY: {
return parse_block(state, parent_block);
}
Expand Down

0 comments on commit e437fb5

Please sign in to comment.