22#include "compiler.h"
33#include "vm.h"
44
5- static InterpretResult run () {
6- #define READ_BYTE () (*vm. ip++)
7- #define READ_CONSTANT () (vm. chunk->constants[READ_BYTE()])
5+ static InterpretResult run (VM * vm ) {
6+ #define READ_BYTE () (*vm-> ip++)
7+ #define READ_CONSTANT () (vm-> chunk->constants.values [READ_BYTE()])
88 #define BINARY_OP (op ) \
99 do { \
10- double b = pop(); \
11- double a = pop(); \
12- push(a op b); \
10+ if (!IS_NUMBER(peek(0)) || !IS_NUMBER(peek(1))) { \
11+ runtime_error("Operands must be numbers."); \
12+ return INTERPRET_RUNTIME_ERROR; \
13+ } \
14+ double b = AS_NUMBER(pop(vm)); \
15+ double a = AS_NUMBER(pop(vm)); \
16+ push(vm, NUMBER_VAL(a op b)); \
1317 } while (false)
1418
1519 for (;;) {
1620 uint8_t instruction ;
1721 switch (instruction = READ_BYTE ()) {
1822 case OP_CONSTANT : {
1923 Value constant = READ_CONSTANT ();
20- push (constant );
24+ push (vm , constant );
2125 break ;
2226 }
23- case OP_NIL : push (NIL_VAL ); break ;
24- case OP_TRUE : push (BOOL_VAL (true)); break ;
25- case OP_FALSE : push (BOOL_VAL (false)); break ;
27+ case OP_NIL : push (vm , NIL_VAL ); break ;
28+ case OP_TRUE : push (vm , BOOL_VAL (true)); break ;
29+ case OP_FALSE : push (vm , BOOL_VAL (false)); break ;
2630 case OP_EQUAL : {
27- Value b = pop ();
28- Value a = pop ();
29- push (BOOL_VAL (values_equal (a , b )));
31+ Value b = pop (vm );
32+ Value a = pop (vm );
33+ push (vm , BOOL_VAL (values_equal (a , b )));
3034 break ;
3135 }
32- case OP_GREATER : BINARY_OP (> ); break ;
33- case OP_LESS : BINARY_OP (< ); break ;
34- case OP_ADD : BINARY_OP (+ ); break ;
35- case OP_SUBTRACT : BINARY_OP (- ); break ;
36- case OP_MULTIPLY : BINARY_OP (* ); break ;
37- case OP_DIVIDE : BINARY_OP (/); break ;
36+ case OP_GREATER : BINARY_OP (> ); break ;
37+ case OP_LESS : BINARY_OP (< ); break ;
38+ case OP_ADD : BINARY_OP (+ ); break ;
39+ case OP_SUBTRACT : BINARY_OP (- ); break ;
40+ case OP_MULTIPLY : BINARY_OP (* ); break ;
41+ case OP_DIVIDE : BINARY_OP (/); break ;
3842 case OP_NOT :
39- push (BOOL_VAL (is_falsey (pop ())));
43+ push (vm , BOOL_VAL (is_falsey (pop (vm ))));
4044 break ;
4145 case OP_NEGATE : {
42- Value value = pop ();
46+ Value value = pop (vm );
4347 if (!IS_NUMBER (value )) {
4448 runtime_error ("Operand must be a number." );
4549 return INTERPRET_RUNTIME_ERROR ;
4650 }
47- push (NUMBER_VAL (- AS_NUMBER (value )));
51+ push (vm , NUMBER_VAL (- AS_NUMBER (value )));
4852 break ;
4953 }
5054 case OP_PRINT : {
51- print_value (pop ());
55+ print_value (pop (vm ));
5256 printf ("\n" );
5357 break ;
5458 }
@@ -65,10 +69,13 @@ static InterpretResult run() {
6569
6670void init_vm (VM * vm ) {
6771 vm -> stack_top = vm -> stack ;
72+ vm -> objects = NULL ;
73+ vm -> bytes_allocated = 0 ;
74+ vm -> next_gc = 1024 * 1024 ;
6875}
6976
7077void free_vm (VM * vm ) {
71- // Nothing to free yet
78+ free_objects ( vm );
7279}
7380
7481InterpretResult interpret (VM * vm , const char * source ) {
@@ -83,7 +90,7 @@ InterpretResult interpret(VM* vm, const char* source) {
8390 vm -> chunk = & chunk ;
8491 vm -> ip = vm -> chunk -> code ;
8592
86- InterpretResult result = run ();
93+ InterpretResult result = run (vm );
8794
8895 free_chunk (& chunk );
8996 return result ;
@@ -100,18 +107,15 @@ Value pop(VM* vm) {
100107}
101108
102109bool is_falsey (Value value ) {
103- return (value .type == TYPE_NIL ) ||
104- (value .type == TYPE_BOOL && !value .data .bool_val );
110+ return IS_NIL (value ) || (IS_BOOL (value ) && !AS_BOOL (value ));
105111}
106112
107113bool values_equal (Value a , Value b ) {
108114 if (a .type != b .type ) return false;
109115 switch (a .type ) {
110- case TYPE_BOOL : return a .data .bool_val == b .data .bool_val ;
111- case TYPE_NIL : return true;
112- case TYPE_INT : return a .data .int_val == b .data .int_val ;
113- case TYPE_FLOAT : return a .data .float_val == b .data .float_val ;
114- case TYPE_STRING : return strcmp (a .data .str_val , b .data .str_val ) == 0 ;
115- default : return false;
116+ case VAL_BOOL : return AS_BOOL (a ) == AS_BOOL (b );
117+ case VAL_NIL : return true;
118+ case VAL_NUMBER : return AS_NUMBER (a ) == AS_NUMBER (b );
119+ default : return false; // Unreachable
116120 }
117121}
0 commit comments