87 lines
1.8 KiB
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;
|
|
}
|
|
|