Skip to content

Commit

Permalink
Support limitless while loops
Browse files Browse the repository at this point in the history
  • Loading branch information
RobDangerous committed Aug 15, 2024
1 parent 650f390 commit cf0c081
Show file tree
Hide file tree
Showing 8 changed files with 64 additions and 1 deletion.
4 changes: 4 additions & 0 deletions Sources/backends/cstyle.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ void cstyle_write_opcode(char *code, size_t *offset, opcode *o, type_string_func
*offset += sprintf(&code[*offset], "\telse\n");
break;
}
case OPCODE_WHILE: {
*offset += sprintf(&code[*offset], "\twhile (_%" PRIu64 ")\n", o->op_if.condition.index);
break;
}
case OPCODE_BLOCK_START: {
*offset += sprintf(&code[*offset], "\t{\n");
break;
Expand Down
17 changes: 17 additions & 0 deletions Sources/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,23 @@ void emit_statement(opcodes *code, block *parent, statement *statement) {

break;
}
case STATEMENT_WHILE: {
{
opcode o;
o.type = OPCODE_WHILE;
o.size = OP_SIZE(o, op_while);

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

o.op_while.condition = v;

emit_op(code, &o);
}

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

break;
}
case STATEMENT_BLOCK: {
{
opcode o;
Expand Down
4 changes: 4 additions & 0 deletions Sources/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ typedef struct opcode {
OPCODE_OR,
OPCODE_IF,
OPCODE_ELSE,
OPCODE_WHILE,
OPCODE_BLOCK_START,
OPCODE_BLOCK_END
} type;
Expand Down Expand Up @@ -95,6 +96,9 @@ typedef struct opcode {
struct {
variable condition;
} op_if;
struct {
variable condition;
} op_while;
struct {
uint8_t nothing;
} op_nothing;
Expand Down
5 changes: 5 additions & 0 deletions Sources/kong.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,11 @@ 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);
break;
}
case STATEMENT_BLOCK: {
resolve_types_in_block(block, s);
break;
Expand Down
17 changes: 17 additions & 0 deletions Sources/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,23 @@ static statement *parse_statement(state_t *state, block *parent_block) {

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

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;

return s;
}
case TOKEN_LEFT_CURLY: {
return parse_block(state, parent_block);
}
Expand Down
6 changes: 5 additions & 1 deletion Sources/parser.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ typedef struct block {
} block;

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

union {
expression *expression;
Expand All @@ -97,6 +97,10 @@ typedef struct statement {
struct statement *if_block;
struct statement *else_block;
} iffy;
struct {
expression *test;
struct statement *while_block;
} willy;
block block;
struct {
local_variable var;
Expand Down
9 changes: 9 additions & 0 deletions Sources/tokenizer.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,15 @@ static void tokens_add_identifier(tokenizer_state *state, tokens *tokens, tokeni
else if (tokenizer_buffer_equals(buffer, "else")) {
token = token_create(TOKEN_ELSE, state);
}
else if (tokenizer_buffer_equals(buffer, "while")) {
token = token_create(TOKEN_WHILE, state);
}
else if (tokenizer_buffer_equals(buffer, "do")) {
token = token_create(TOKEN_DO, state);
}
else if (tokenizer_buffer_equals(buffer, "for")) {
token = token_create(TOKEN_FOR, state);
}
else if (tokenizer_buffer_equals(buffer, "in")) {
token = token_create(TOKEN_IN, state);
}
Expand Down
3 changes: 3 additions & 0 deletions Sources/tokenizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,9 @@ typedef struct token {
TOKEN_RIGHT_SQUARE,
TOKEN_IF,
TOKEN_ELSE,
TOKEN_WHILE,
TOKEN_DO,
TOKEN_FOR,
TOKEN_SEMICOLON,
TOKEN_COLON,
TOKEN_DOT,
Expand Down

0 comments on commit cf0c081

Please sign in to comment.