#include "common.h" #include "vm.h" #include "compiler.h" #include "debug.h" static void resetStack( VM* vm ) { vm->sp = vm->stack; } void initVM( VM* vm ) { resetStack( vm ); } void freeVM( VM* vm ) { (void)vm; } void push( VM* vm, Value val ) { if ( vm->sp - vm->stack >= MAX_STACK ) { printf( "VM Error: Stack is full.\n" ); resetStack( vm ); } *(vm->sp) = val; vm->sp++; } Value pop( VM* vm ) { vm->sp--; return *(vm->sp); } static InterpretResult run( VM* vm ) { #define READ_BYTE() (*(vm->ip++)) #define READ_CONSTANT( ix ) (vm->chunk->constants.values[ix]) #define BINARY_OP( op ) do { Value b = pop( vm ), a = pop( vm ); \ push( vm, a op b ); } while ( false ) uint8_t instruction = 0; for ( ; ; ) { #ifdef DEBUG_TRACE_EXECUTION printf( "\t" ); for ( Value* v = vm->stack; v < vm->sp; v++ ) { printf( "[ " ); printValue( *v ); printf( " ]" ); } printf( "\n" ); disassembleInstruction( vm->chunk, (int)(vm->ip - vm->chunk->code) ); #endif switch ( instruction = READ_BYTE() ) { case OP_CONSTANT: case OP_CONSTANT_LONG: { uint16_t cons = READ_BYTE(); if ( instruction == OP_CONSTANT_LONG ) cons |= (READ_BYTE() << 8); Value constant = READ_CONSTANT( cons ); push( vm, constant ); break; } case OP_ADD: BINARY_OP( + ); break; case OP_SUBTRACT: BINARY_OP( - ); break; case OP_MULTIPLY: BINARY_OP( * ); break; case OP_DIVIDE: BINARY_OP( / ); break; case OP_NEGATE: push( vm, -pop( vm ) ); break; case OP_RETURN: printValue( pop( vm ) ); printf( "\n" ); return INTERPRET_OK; } } #undef BINARY_OP #undef READ_CONSTANT #undef READ_BYTE } InterpretResult interpret( VM* vm, const char* src ) { /*vm->chunk = chunk; vm->ip = vm->chunk->code; return run( vm );*/ compile( vm, src ); return INTERPRET_OK; }