clox/vm.c

87 lines
1.8 KiB
C

#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;
}