Skip to content

Commit

Permalink
Support do while loops
Browse files Browse the repository at this point in the history
  • Loading branch information
RobDangerous committed Aug 16, 2024
1 parent b47d729 commit 9429d1e
Show file tree
Hide file tree
Showing 4 changed files with 73 additions and 9 deletions.
35 changes: 33 additions & 2 deletions Sources/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -562,14 +562,45 @@ void emit_statement(opcodes *code, block *parent, statement *statement) {
o.type = OPCODE_WHILE_CONDITION;
o.size = OP_SIZE(o, op_while);

variable v = emit_expression(code, parent, statement->willy.test);
variable v = emit_expression(code, parent, statement->whiley.test);

o.op_while.condition = v;

emit_op(code, &o);
}

emit_statement(code, parent, statement->willy.while_block);
emit_statement(code, parent, statement->whiley.while_block);

{
opcode o;
o.type = OPCODE_WHILE_END;
o.size = OP_SIZE(o, op_nothing);
emit_op(code, &o);
}

break;
}
case STATEMENT_DO_WHILE: {
{
opcode o;
o.type = OPCODE_WHILE_START;
o.size = OP_SIZE(o, op_nothing);
emit_op(code, &o);
}

emit_statement(code, parent, statement->whiley.while_block);

{
opcode o;
o.type = OPCODE_WHILE_CONDITION;
o.size = OP_SIZE(o, op_while);

variable v = emit_expression(code, parent, statement->whiley.test);

o.op_while.condition = v;

emit_op(code, &o);
}

{
opcode o;
Expand Down
7 changes: 4 additions & 3 deletions Sources/kong.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,9 +277,10 @@ void resolve_types_in_block(statement *parent, statement *block) {
}
break;
}
case STATEMENT_WHILE: {
resolve_types_in_expression(block, s->willy.test);
resolve_types_in_block(block, s->willy.while_block);
case STATEMENT_WHILE:
case STATEMENT_DO_WHILE: {
resolve_types_in_expression(block, s->whiley.test);
resolve_types_in_block(block, s->whiley.while_block);
break;
}
case STATEMENT_BLOCK: {
Expand Down
28 changes: 26 additions & 2 deletions Sources/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,8 +330,32 @@ static statement *parse_statement(state_t *state, block *parent_block) {
statement *while_block = parse_statement(state, parent_block);
statement *s = statement_allocate();
s->kind = STATEMENT_WHILE;
s->willy.test = test;
s->willy.while_block = while_block;
s->whiley.test = test;
s->whiley.while_block = while_block;

return s;
}
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;

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

expression *test = parse_expression(state);
match_token(state, TOKEN_RIGHT_PAREN, "Expected a closing bracket");
advance_state(state);

s->whiley.test = test;

match_token(state, TOKEN_SEMICOLON, "Expected a semicolon");
advance_state(state);

return s;
}
Expand Down
12 changes: 10 additions & 2 deletions Sources/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,15 @@ typedef struct block {
} block;

typedef struct statement {
enum { STATEMENT_EXPRESSION, STATEMENT_RETURN_EXPRESSION, STATEMENT_IF, STATEMENT_WHILE, STATEMENT_BLOCK, STATEMENT_LOCAL_VARIABLE } kind;
enum {
STATEMENT_EXPRESSION,
STATEMENT_RETURN_EXPRESSION,
STATEMENT_IF,
STATEMENT_WHILE,
STATEMENT_DO_WHILE,
STATEMENT_BLOCK,
STATEMENT_LOCAL_VARIABLE
} kind;

union {
expression *expression;
Expand All @@ -100,7 +108,7 @@ typedef struct statement {
struct {
expression *test;
struct statement *while_block;
} willy;
} whiley;
block block;
struct {
local_variable var;
Expand Down

0 comments on commit 9429d1e

Please sign in to comment.