aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Tom Willemse2021-10-11 00:13:15 -0700
committerGravatar Tom Willemse2021-10-11 00:13:15 -0700
commit7bd9934a4be7c22b8f464ab7a1cc243801b5957c (patch)
tree220c128d448c1f82fdae86560e6016b42bb7a403
parentfcbea5f617edb6e3dfa68eb31efa402b4916c032 (diff)
downloadcrafting-interpreters-7bd9934a4be7c22b8f464ab7a1cc243801b5957c.tar.gz
crafting-interpreters-7bd9934a4be7c22b8f464ab7a1cc243801b5957c.zip
Chapter 21.3
-rw-r--r--clox/src/chunk.h1
-rw-r--r--clox/src/compiler.c12
-rw-r--r--clox/src/debug.c2
-rw-r--r--clox/src/vm.c10
4 files changed, 24 insertions, 1 deletions
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));