VM Chapter
This commit is contained in:
parent
82651b9779
commit
4b59b0fef2
@ -7,6 +7,11 @@
|
||||
typedef enum {
|
||||
OP_CONSTANT_LONG,
|
||||
OP_CONSTANT,
|
||||
OP_ADD,
|
||||
OP_SUBTRACT,
|
||||
OP_MULTIPLY,
|
||||
OP_DIVIDE,
|
||||
OP_NEGATE,
|
||||
OP_RETURN,
|
||||
OP_COUNT,
|
||||
}OpCode;
|
||||
|
@ -4,5 +4,6 @@
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#define DEBUG_TRACE_EXECUTION
|
||||
|
||||
#endif
|
||||
|
16
include/vm.h
16
include/vm.h
@ -2,13 +2,29 @@
|
||||
#define VM_INLCUDED
|
||||
|
||||
#include "chunk.h"
|
||||
#include "value.h"
|
||||
|
||||
#define STACK_MAX 256
|
||||
|
||||
typedef struct {
|
||||
Chunk *chunk;
|
||||
uint8_t *ip;
|
||||
Value stack[STACK_MAX];
|
||||
Value *stackTop;
|
||||
} VM;
|
||||
|
||||
typedef enum {
|
||||
INTERPRET_OK,
|
||||
INTERPRET_COMPILE_ERROR,
|
||||
INTERPRET_RUNTIME_ERROR,
|
||||
INTERPRET_RESULT_COUNT,
|
||||
} InterpretResult;
|
||||
|
||||
void initVM(void);
|
||||
void freeVM(void);
|
||||
|
||||
InterpretResult interpret(Chunk *chunk);
|
||||
void push(Value value);
|
||||
Value pop();
|
||||
|
||||
#endif
|
||||
|
11
src/debug.c
11
src/debug.c
@ -43,10 +43,19 @@ int disassembleInstruction(Chunk *chunk, int offset){
|
||||
switch(instruction){
|
||||
case OP_CONSTANT:
|
||||
return constantInstruction("OP_CONSTANT", chunk,offset);
|
||||
|
||||
case OP_CONSTANT_LONG:
|
||||
return longConstantInstruction("OP_CONSTANT_LONG", chunk, offset);
|
||||
case OP_ADD:
|
||||
return simpleInstruction("OP_ADD", offset);
|
||||
case OP_SUBTRACT:
|
||||
return simpleInstruction("OP_SUBTRACT", offset);
|
||||
case OP_MULTIPLY:
|
||||
return simpleInstruction("OP_MULTIPLY", offset);
|
||||
case OP_DIVIDE:
|
||||
return simpleInstruction("OP_DIVIDE", offset);
|
||||
|
||||
case OP_NEGATE:
|
||||
return simpleInstruction("OP_NEGATE", offset);
|
||||
case OP_RETURN:
|
||||
return simpleInstruction("OP_RETURN",offset);
|
||||
default:
|
||||
|
68
src/vm.c
68
src/vm.c
@ -1,11 +1,75 @@
|
||||
#include "../include/common.h"
|
||||
#include "../include/vm.h"
|
||||
#include "../include/debug.h"
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
VM vm;
|
||||
static void resetStack(void){
|
||||
vm.stackTop = vm.stack;
|
||||
}
|
||||
void initVM(void){
|
||||
|
||||
resetStack();
|
||||
}
|
||||
void freeVM(void){
|
||||
|
||||
}
|
||||
void push(Value value){
|
||||
*vm.stackTop = value;
|
||||
vm.stackTop++;
|
||||
}
|
||||
Value pop(){
|
||||
vm.stackTop--;
|
||||
return *vm.stackTop;
|
||||
}
|
||||
|
||||
static InterpretResult run(){
|
||||
#define READ_BYTE() (*vm.ip++)
|
||||
#define READ_CONSTANT() (vm.chunk->constants.values[READ_BYTE()])
|
||||
#define BINARY_OP(op) \
|
||||
do{ \
|
||||
double b = pop(); \
|
||||
double a = pop(); \
|
||||
push(a op b); \
|
||||
} while (false)
|
||||
for(;;){
|
||||
#ifndef DEBUG_TRACE_EXECUTION
|
||||
printf(" ");
|
||||
for(Value *slot = vm.stack; slot < vm.stackTop; slot++){
|
||||
printf("[");
|
||||
printValue(*slot);
|
||||
printf("]");
|
||||
}
|
||||
printf("\n");
|
||||
disassembleInstruction(vm.chunk, (int)(vm.ip - vm.chunk->code));
|
||||
#endif
|
||||
uint8_t instruction;
|
||||
|
||||
switch(instruction = READ_BYTE()){
|
||||
case OP_CONSTANT: {
|
||||
Value constant = READ_CONSTANT();
|
||||
push(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(-pop()); break;
|
||||
case OP_RETURN: {
|
||||
printValue(pop());
|
||||
printf("\n");
|
||||
return INTERPRET_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef BINARY_OP
|
||||
#undef READ_CONSTANT
|
||||
#undef READ_BYTE
|
||||
}
|
||||
|
||||
InterpretResult interpret(Chunk *chunk){
|
||||
vm.chunk = chunk;
|
||||
vm.ip = vm.chunk->code;
|
||||
return run();
|
||||
}
|
||||
|
||||
|
@ -9,12 +9,23 @@ int main(void){
|
||||
Chunk chunk;
|
||||
initChunk(&chunk);
|
||||
|
||||
int constant = addConstant(&chunk,1.2);
|
||||
writeChunk(&chunk, OP_CONSTANT,10);
|
||||
writeChunk(&chunk,constant,10);
|
||||
// writeChunk(&chunk, OP_RETURN,10);
|
||||
int constant = addConstant(&chunk,1.25);
|
||||
writeChunk(&chunk, OP_CONSTANT,1);
|
||||
writeChunk(&chunk,constant,1);
|
||||
|
||||
|
||||
|
||||
constant = addConstant(&chunk,10);
|
||||
writeChunk(&chunk, OP_CONSTANT,2);
|
||||
writeChunk(&chunk,constant,2);
|
||||
|
||||
|
||||
writeChunk(&chunk, OP_DIVIDE, 3);
|
||||
writeChunk(&chunk, OP_RETURN,5);
|
||||
|
||||
disassembleChunk(&chunk,"Test Chunk");
|
||||
int res = interpret(&chunk);
|
||||
(void) res;
|
||||
freeVM();
|
||||
freeChunk(&chunk);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user