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