Skip to content

Commit

Permalink
Add top script function and call frame
Browse files Browse the repository at this point in the history
  • Loading branch information
hsl4125 committed Jan 15, 2022
1 parent 4fc7f02 commit 99a3c18
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 46 deletions.
39 changes: 26 additions & 13 deletions compiler/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,24 +44,34 @@ typedef struct {
int depth;
} Local;

typedef enum { TYPE_FUNCTION, TYPE_SCRIPT } FunctionType;

typedef struct {
Local locals[ UINT8_COUNT ];
int localCount;
int scopeDepth;
ObjFunction *function;
FunctionType type;
Local locals[ UINT8_COUNT ];
int localCount;
int scopeDepth;
} Compiler;


Parser parser;
Compiler *current = NULL;
Chunk *compilingChunk;

static void initCompiler(Compiler *compiler) {
static void initCompiler(Compiler *compiler, FunctionType type) {
compiler->localCount = 0;
compiler->scopeDepth = 0;
compiler->type = type;
compiler->function = newFunction();
current = compiler;

Local *local = &current->locals[ current->localCount++ ];
local->depth = 0;
local->name.start = "";
local->name.length = 0;
}

static Chunk *currentChunk() { return compilingChunk; }
static Chunk *currentChunk() { return &current->function->chunk; }

static void errorAt(Token *token, const char *message) {
if (parser.panicMode)
Expand Down Expand Up @@ -147,13 +157,17 @@ static void emitLoop(int loopStart) {

static void emitReturn() { emitByte(OP_RETURN); }

static void endCompiler() {
static ObjFunction *endCompiler() {
emitReturn();
ObjFunction *function = current->function;
#ifdef DEBUG_PRINT_CODE
if (!parser.hadError) {
disassembleChunk(currentChunk(), "code");
disassembleChunk(currentChunk(), function->name != NULL
? function->name->chars
: "<srcipt>");
}
#endif
return function;
}

static void beginScope() { ++current->scopeDepth; }
Expand Down Expand Up @@ -667,11 +681,10 @@ static void forStatement() {
endScope();
}

bool compile(const char *source, Chunk *chunk) {
ObjFunction *compile(const char *source) {
initScanner(source);
Compiler compiler;
initCompiler(&compiler);
compilingChunk = chunk;
initCompiler(&compiler, TYPE_SCRIPT);

parser.hadError = false;
parser.panicMode = false;
Expand All @@ -682,6 +695,6 @@ bool compile(const char *source, Chunk *chunk) {
declaration();
}

endCompiler();
return !parser.hadError;
ObjFunction *function = endCompiler();
return parser.hadError ? NULL : function;
}
5 changes: 5 additions & 0 deletions compiler/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ ObjFunction *newFunction() {
}

static void printFunction(ObjFunction *function) {
if (function->name == NULL) {
printf("<script>");
return;
}

printf("<fn %s>", function->name->chars);
}

Expand Down
52 changes: 28 additions & 24 deletions compiler/vm.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@

VM vm;

static void resetStack() { vm.stackTop = vm.stack; }
static void resetStack() {
vm.stackTop = vm.stack;
vm.frameCount = 0;
}

static void runtimeError(const char *format, ...) {
va_list args;
Expand All @@ -20,8 +23,9 @@ static void runtimeError(const char *format, ...) {

fputs("\n", stderr);

size_t instruction = vm.ip - vm.chunk->code - 1;
int line = vm.chunk->lines[ instruction ];
CallFrame *frame = &vm.frames[ vm.frameCount - 1 ];
size_t instruction = frame->ip - frame->function->chunk.code - 1;
int line = frame->function->chunk.lines[ instruction ];
fprintf(stderr, "[line %d] in script\n", line);
resetStack();
}
Expand All @@ -43,9 +47,11 @@ static Value peek(int);
static bool isFalsey(Value);
static void concatenate();
static InterpretResult run() {
#define READ_BYTE() (*vm.ip++)
#define READ_SHORT() (vm.ip += 2, (uint16_t) ((vm.ip[ -2 ] << 8) | vm.ip[ -1 ]))
#define READ_CONSTANT() (vm.chunk->constants.values[ READ_BYTE() ])
CallFrame *frame = &vm.frames[ vm.frameCount - 1 ];
#define READ_BYTE() (*frame->ip++)
#define READ_SHORT() \
(frame->ip += 2, (uint16_t) ((frame->ip[ -2 ] << 8) | frame->ip[ -1 ]))
#define READ_CONSTANT() (frame->function->chunk.constants.values[ READ_BYTE() ])
#define READ_STRING() AS_STRING(READ_CONSTANT())
#define BINARY_OP(valueType, op) \
do { \
Expand All @@ -67,7 +73,8 @@ static InterpretResult run() {
printf(" ]");
}
printf("\n");
disassembleInstruction(vm.chunk, (int) (vm.ip - vm.chunk->code));
disassembleInstruction(&frame->function->chunk,
(int) (frame->ip - frame->function->chunk.code));
#endif
uint8_t instruction;
switch (instruction = READ_BYTE()) {
Expand All @@ -90,12 +97,12 @@ static InterpretResult run() {
break;
case OP_GET_LOCAL: {
uint8_t slot = READ_BYTE();
push(vm.stack[ slot ]);
push(frame->slots[ slot ]);
break;
}
case OP_SET_LOCAL: {
uint8_t slot = READ_BYTE();
vm.stack[ slot ] = peek(0);
uint8_t slot = READ_BYTE();
frame->slots[ slot ] = peek(0);
break;
}
case OP_GET_GLOBAL: {
Expand Down Expand Up @@ -174,19 +181,19 @@ static InterpretResult run() {
}
case OP_JUMP: {
uint16_t offset = READ_SHORT();
vm.ip += offset;
frame->ip += offset;
break;
}
case OP_JUMP_IF_FALSE: {
uint16_t offset = READ_SHORT();
if (isFalsey(peek(0))) {
vm.ip += offset;
frame->ip += offset;
}
break;
}
case OP_LOOP: {
uint16_t offset = READ_SHORT();
vm.ip -= offset;
frame->ip -= offset;
break;
}
case OP_RETURN: {
Expand All @@ -203,21 +210,18 @@ static InterpretResult run() {
}

InterpretResult interpret(const char *source) {
Chunk chunk;
initChunk(&chunk);

if (!compile(source, &chunk)) {
freeChunk(&chunk);
ObjFunction *function = compile(source);
if (function == NULL) {
return INTERPRET_COMPILE_ERROR;
}

vm.chunk = &chunk;
vm.ip = vm.chunk->code;

InterpretResult result = run();
push(OBJ_VAL(function));
CallFrame *frame = &vm.frames[ vm.frameCount++ ];
frame->function = function;
frame->ip = function->chunk.code;
frame->slots = vm.stack;

freeChunk(&chunk);
return result;
return run();
}

void push(Value value) {
Expand Down
2 changes: 1 addition & 1 deletion include/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

#include "vm.h"

bool compile(const char *source, Chunk *chunk);
ObjFunction *compile(const char *source);
24 changes: 16 additions & 8 deletions include/vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,24 @@
#include "object.h"
#include "table.h"

#define STACK_MAX 256
#define FRAMES_MAX 64
#define STACK_MAX (FRAMES_MAX * UINT8_MAX)

typedef struct {
Chunk *chunk;
uint8_t *ip;
Value stack[ STACK_MAX ];
Value *stackTop;
Table globals;
Table strings;
Obj *objects;
ObjFunction *function;
uint8_t *ip;
Value *slots;
} CallFrame;

typedef struct {
CallFrame frames[ FRAMES_MAX ];
int frameCount;

Value stack[ STACK_MAX ];
Value *stackTop;
Table globals;
Table strings;
Obj *objects;
} VM;

typedef enum {
Expand Down

0 comments on commit 99a3c18

Please sign in to comment.