diff options
-rw-r--r-- | src/compiler.c | 34 | ||||
-rw-r--r-- | tests/compilation.bad | 6 | ||||
-rw-r--r-- | tests/fib.bad | 12 |
3 files changed, 48 insertions, 4 deletions
diff --git a/src/compiler.c b/src/compiler.c index 0f9607e..ea9234a 100644 --- a/src/compiler.c +++ b/src/compiler.c | |||
@@ -559,8 +559,42 @@ compile_if(Chunk *chunk, Node *node) { | |||
559 | } | 559 | } |
560 | 560 | ||
561 | CompResult | 561 | CompResult |
562 | compile_while(Chunk *chunk, Node *node) { | ||
563 | sz start = array_size(chunk->code); | ||
564 | CompResult cond = compile_expr(chunk, node->while_cond); | ||
565 | OpCode jmpop; | ||
566 | switch (cond.type) { | ||
567 | case COMP_CONST: { | ||
568 | jmpop = OP_JMPFI; | ||
569 | } break; | ||
570 | case COMP_REG: { | ||
571 | jmpop = OP_JMPF; | ||
572 | } break; | ||
573 | default: { | ||
574 | return (CompResult){.type = COMP_ERR}; | ||
575 | } break; | ||
576 | } | ||
577 | sz jump_a = array_size(chunk->code); | ||
578 | |||
579 | // Jump to the `end of the loop` branch. | ||
580 | EMIT_OP(jmpop, cond.idx, 0xff, 0, node->while_cond, chunk); | ||
581 | |||
582 | // Condition is true. | ||
583 | CompResult then_expr = compile_expr(chunk, node->while_expr); | ||
584 | sz end_expr = array_size(chunk->code); | ||
585 | sz loopback = add_constant(chunk, (start - end_expr)); | ||
586 | EMIT_OP(OP_JMPI, loopback, 0, 0, node, chunk); | ||
587 | sz const_a = add_constant(chunk, end_expr - jump_a + 1); | ||
588 | chunk->code[jump_a].a = const_a; | ||
589 | |||
590 | // Return. | ||
591 | return (CompResult){.type = COMP_NIL}; | ||
592 | } | ||
593 | |||
594 | CompResult | ||
562 | compile_expr(Chunk *chunk, Node *node) { | 595 | compile_expr(Chunk *chunk, Node *node) { |
563 | switch (node->kind) { | 596 | switch (node->kind) { |
597 | case NODE_WHILE: return compile_while(chunk, node); | ||
564 | case NODE_IF: return compile_if(chunk, node); | 598 | case NODE_IF: return compile_if(chunk, node); |
565 | // Logic. | 599 | // Logic. |
566 | // case NODE_XOR: | 600 | // case NODE_XOR: |
diff --git a/tests/compilation.bad b/tests/compilation.bad index afb2be0..187d4ae 100644 --- a/tests/compilation.bad +++ b/tests/compilation.bad | |||
@@ -18,10 +18,8 @@ | |||
18 | ; } | 18 | ; } |
19 | 19 | ||
20 | let a = 0 | 20 | let a = 0 |
21 | if 1 != 1 { | 21 | while a < 10 { |
22 | set a = 1 | 22 | set a = a + 1 |
23 | } else { | ||
24 | set a = 2 | ||
25 | } | 23 | } |
26 | 24 | ||
27 | a | 25 | a |
diff --git a/tests/fib.bad b/tests/fib.bad new file mode 100644 index 0000000..8eec0b8 --- /dev/null +++ b/tests/fib.bad | |||
@@ -0,0 +1,12 @@ | |||
1 | let n = 90 | ||
2 | let a = 0 | ||
3 | let b = 1 | ||
4 | let i = 0 | ||
5 | while i < n { | ||
6 | let tmp = a + b | ||
7 | set a = b | ||
8 | set b = tmp | ||
9 | set i = i + 1 | ||
10 | } | ||
11 | |||
12 | a | ||