From 7bd9934a4be7c22b8f464ab7a1cc243801b5957c Mon Sep 17 00:00:00 2001 From: Tom Willemse Date: Mon, 11 Oct 2021 00:13:15 -0700 Subject: [PATCH] Chapter 21.3 --- clox/src/chunk.h | 1 + clox/src/compiler.c | 12 +++++++++++- clox/src/debug.c | 2 ++ clox/src/vm.c | 10 ++++++++++ 4 files changed, 24 insertions(+), 1 deletion(-) diff --git a/clox/src/chunk.h b/clox/src/chunk.h index 4194e8c..dda2b31 100644 --- a/clox/src/chunk.h +++ b/clox/src/chunk.h @@ -10,6 +10,7 @@ typedef enum { OP_TRUE, OP_FALSE, OP_POP, + OP_GET_GLOBAL, OP_DEFINE_GLOBAL, OP_EQUAL, OP_GREATER, diff --git a/clox/src/compiler.c b/clox/src/compiler.c index 9dd7927..f125c10 100644 --- a/clox/src/compiler.c +++ b/clox/src/compiler.c @@ -138,6 +138,7 @@ static ParseRule *getRule(TokenType type); static void parsePrecedence(Precedence precedence); static uint8_t parseVariable(const char *name); static void defineVariable(uint8_t global); +static uint8_t identifierConstant(Token *name); static void binary() { TokenType operatorType = parser.previous.type; @@ -276,6 +277,15 @@ static void string() { copyString(parser.previous.start + 1, parser.previous.length - 2))); } +static void namedVariable(Token name) { + uint8_t arg = identifierConstant(&name); + emitBytes(OP_GET_GLOBAL, arg); +} + +static void variable() { + namedVariable(parser.previous); +} + static void unary() { TokenType operatorType = parser.previous.type; @@ -320,7 +330,7 @@ ParseRule rules[] = { [TOKEN_GREATER_EQUAL] = {NULL, binary, PREC_COMPARISON}, [TOKEN_LESS] = {NULL, binary, PREC_COMPARISON}, [TOKEN_LESS_EQUAL] = {NULL, binary, PREC_COMPARISON}, - [TOKEN_IDENTIFIER] = {NULL, NULL, PREC_NONE}, + [TOKEN_IDENTIFIER] = {variable, NULL, PREC_NONE}, [TOKEN_STRING] = {string, NULL, PREC_NONE}, [TOKEN_NUMBER] = {number, NULL, PREC_NONE}, [TOKEN_AND] = {NULL, NULL, PREC_NONE}, diff --git a/clox/src/debug.c b/clox/src/debug.c index 5663091..669fc78 100644 --- a/clox/src/debug.c +++ b/clox/src/debug.c @@ -44,6 +44,8 @@ int disassembleInstruction(Chunk *chunk, int offset) { return simpleInstruction("OP_FALSE", offset); case OP_POP: return simpleInstruction("OP_POP", offset); + case OP_GET_GLOBAL: + return constantInstruction("OP_GET_GLOBAL", chunk, offset); case OP_DEFINE_GLOBAL: return constantInstruction("OP_DEFINE_GLOBAL", chunk, offset); case OP_EQUAL: diff --git a/clox/src/vm.c b/clox/src/vm.c index 709f3d1..5e35abd 100644 --- a/clox/src/vm.c +++ b/clox/src/vm.c @@ -115,6 +115,16 @@ static InterpretResult run() { case OP_POP: pop(); break; + case OP_GET_GLOBAL: { + ObjString *name = READ_STRING(); + Value value; + if (!tableGet(&vm.globals, name, &value)) { + runtimeError("Undefined variable '%s'.", name->chars); + return INTERPRET_RUNTIME_ERROR; + } + push(value); + break; + } case OP_DEFINE_GLOBAL: { ObjString *name = READ_STRING(); tableSet(&vm.globals, name, peek(0));