Skip to content

Commit 5ad2213

Browse files
committed
feat: implement first flow control (if)
1 parent 8d50a08 commit 5ad2213

4 files changed

Lines changed: 46 additions & 3 deletions

File tree

src/chunk.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ typedef enum
2626
OP_NOT,
2727
OP_NEGATE,
2828
OP_PRINT,
29+
OP_JUMP_IF_FALSE,
2930
OP_RETURN,
3031
} OpCode;
3132

src/common.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#define UINT8_COUNT (UINT8_MAX + 1)
99

1010
typedef uint8_t u8;
11+
typedef uint16_t u16;
1112
typedef uint32_t u32;
1213

1314
#define DEBUG_PRINT_CODE

src/compiler.c

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,9 @@ typedef struct
6464

6565
static bool immutable_globals[UINT8_MAX];
6666

67-
Parser parser;
68-
Compiler* current;
69-
Chunk* compiling_chunk;
67+
Parser parser;
68+
Compiler* current;
69+
Chunk* compiling_chunk;
7070

7171
static Chunk* current_chunk()
7272
{
@@ -153,6 +153,14 @@ static void emit_bytes(u8 byte_1, u8 byte_2)
153153
emit_byte(byte_2);
154154
}
155155

156+
static int emit_jump(u8 instruction)
157+
{
158+
emit_byte(instruction);
159+
emit_byte(0xff);
160+
emit_byte(0xff);
161+
return current_chunk()->count - 2;
162+
}
163+
156164
static void emit_return()
157165
{
158166
emit_byte(OP_RETURN);
@@ -174,6 +182,15 @@ static void emit_constant(Value value)
174182
emit_bytes(OP_CONSTANT, make_constant(value));
175183
}
176184

185+
static void patch_jump(int offset)
186+
{
187+
int jump = current_chunk()->count - offset - 2;
188+
if (jump > UINT16_MAX)
189+
error("Too much code to jump over");
190+
191+
current_chunk()->code[offset] = (jump >> 8) & 0xff;
192+
current_chunk()->code[offset + 1] = jump & 0xff;
193+
}
177194
static void init_compiler(Compiler* compiler)
178195
{
179196
compiler->local_count = 0;
@@ -566,6 +583,17 @@ static void expression_statement()
566583
emit_byte(OP_POP);
567584
}
568585

586+
static void if_statement()
587+
{
588+
consume(TOKEN_LEFT_PAREN, "Expect '(' after if statement");
589+
expression();
590+
consume(TOKEN_RIGHT_PAREN, "Expect ')' after condition");
591+
592+
int then_jump = emit_jump(OP_JUMP_IF_FALSE);
593+
statement();
594+
patch_jump(then_jump);
595+
}
596+
569597
static void print_statement()
570598
{
571599
expression();
@@ -619,6 +647,10 @@ static void statement()
619647
{
620648
print_statement();
621649
}
650+
else if (TOKEN_IF)
651+
{
652+
if_statement();
653+
}
622654
else if (match(TOKEN_LEFT_BRACE))
623655
{
624656
begin_scope();

src/vm.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ static InterpretResult run()
9090
{
9191
#define READ_BYTE() (*vm.ip++)
9292
#define READ_CONSTANT() (vm.chunk->constants.values[READ_BYTE()])
93+
#define READ_SHORT() (vm.ip += 2, (u16)(vm.ip[-2] << 8) | vm.ip[-1])
9394
#define READ_STRING() AS_STRING(READ_CONSTANT())
9495
#define BINARY_OP(value_type, op) \
9596
do \
@@ -237,13 +238,21 @@ static InterpretResult run()
237238
printf("\n");
238239
break;
239240
}
241+
case OP_JUMP_IF_FALSE:
242+
{
243+
u16 offset = READ_SHORT();
244+
if (is_falsey(peek(0)))
245+
vm.ip += offset;
246+
break;
247+
}
240248
case OP_RETURN:
241249
return INTERPRET_OK;
242250
}
243251
}
244252

245253
#undef READ_BYTE
246254
#undef READ_CONSTANT
255+
#undef READ_SHORT
247256
#undef READ_STRING
248257
#undef BINARY_OP
249258
}

0 commit comments

Comments
 (0)