Chapter 21.3

This commit is contained in:
Tom Willemse 2021-10-11 00:13:15 -07:00
parent fcbea5f617
commit 7bd9934a4b
4 changed files with 24 additions and 1 deletions

View file

@ -10,6 +10,7 @@ typedef enum {
OP_TRUE, OP_TRUE,
OP_FALSE, OP_FALSE,
OP_POP, OP_POP,
OP_GET_GLOBAL,
OP_DEFINE_GLOBAL, OP_DEFINE_GLOBAL,
OP_EQUAL, OP_EQUAL,
OP_GREATER, OP_GREATER,

View file

@ -138,6 +138,7 @@ static ParseRule *getRule(TokenType type);
static void parsePrecedence(Precedence precedence); static void parsePrecedence(Precedence precedence);
static uint8_t parseVariable(const char *name); static uint8_t parseVariable(const char *name);
static void defineVariable(uint8_t global); static void defineVariable(uint8_t global);
static uint8_t identifierConstant(Token *name);
static void binary() { static void binary() {
TokenType operatorType = parser.previous.type; TokenType operatorType = parser.previous.type;
@ -276,6 +277,15 @@ static void string() {
copyString(parser.previous.start + 1, parser.previous.length - 2))); 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() { static void unary() {
TokenType operatorType = parser.previous.type; TokenType operatorType = parser.previous.type;
@ -320,7 +330,7 @@ ParseRule rules[] = {
[TOKEN_GREATER_EQUAL] = {NULL, binary, PREC_COMPARISON}, [TOKEN_GREATER_EQUAL] = {NULL, binary, PREC_COMPARISON},
[TOKEN_LESS] = {NULL, binary, PREC_COMPARISON}, [TOKEN_LESS] = {NULL, binary, PREC_COMPARISON},
[TOKEN_LESS_EQUAL] = {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_STRING] = {string, NULL, PREC_NONE},
[TOKEN_NUMBER] = {number, NULL, PREC_NONE}, [TOKEN_NUMBER] = {number, NULL, PREC_NONE},
[TOKEN_AND] = {NULL, NULL, PREC_NONE}, [TOKEN_AND] = {NULL, NULL, PREC_NONE},

View file

@ -44,6 +44,8 @@ int disassembleInstruction(Chunk *chunk, int offset) {
return simpleInstruction("OP_FALSE", offset); return simpleInstruction("OP_FALSE", offset);
case OP_POP: case OP_POP:
return simpleInstruction("OP_POP", offset); return simpleInstruction("OP_POP", offset);
case OP_GET_GLOBAL:
return constantInstruction("OP_GET_GLOBAL", chunk, offset);
case OP_DEFINE_GLOBAL: case OP_DEFINE_GLOBAL:
return constantInstruction("OP_DEFINE_GLOBAL", chunk, offset); return constantInstruction("OP_DEFINE_GLOBAL", chunk, offset);
case OP_EQUAL: case OP_EQUAL:

View file

@ -115,6 +115,16 @@ static InterpretResult run() {
case OP_POP: case OP_POP:
pop(); pop();
break; 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: { case OP_DEFINE_GLOBAL: {
ObjString *name = READ_STRING(); ObjString *name = READ_STRING();
tableSet(&vm.globals, name, peek(0)); tableSet(&vm.globals, name, peek(0));