Chapter 27.4

This commit is contained in:
Tom Willemse 2022-08-13 00:04:31 -07:00
parent f4185577e5
commit 4e77cfa612
4 changed files with 51 additions and 1 deletions

View file

@ -17,6 +17,8 @@ typedef enum {
OP_SET_GLOBAL,
OP_GET_UPVALUE,
OP_SET_UPVALUE,
OP_GET_PROPERTY,
OP_SET_PROPERTY,
OP_EQUAL,
OP_GREATER,
OP_LESS,

View file

@ -307,6 +307,18 @@ static void call(bool canAssign) {
emitBytes(OP_CALL, argCount);
}
static void dot(bool canAssign) {
consume(TOKEN_IDENTIFIER, "Expect property name after '.'.");
uint8_t name = identifierConstant(&parser.previous);
if (canAssign && match(TOKEN_EQUAL)) {
expression();
emitBytes(OP_SET_PROPERTY, name);
} else {
emitBytes(OP_GET_PROPERTY, name);
}
}
static void literal(bool canAssign) {
switch (parser.previous.type) {
case TOKEN_FALSE:
@ -689,7 +701,7 @@ ParseRule rules[] = {
[TOKEN_LEFT_BRACE] = {NULL, NULL, PREC_NONE},
[TOKEN_RIGHT_BRACE] = {NULL, NULL, PREC_NONE},
[TOKEN_COMMA] = {NULL, NULL, PREC_NONE},
[TOKEN_DOT] = {NULL, NULL, PREC_NONE},
[TOKEN_DOT] = {NULL, dot, PREC_CALL},
[TOKEN_MINUS] = {unary, binary, PREC_TERM},
[TOKEN_PLUS] = {NULL, binary, PREC_TERM},
[TOKEN_SEMICOLON] = {NULL, NULL, PREC_NONE},

View file

@ -73,6 +73,10 @@ int disassembleInstruction(Chunk *chunk, int offset) {
return byteInstruction("OP_GET_UPVALUE", chunk, offset);
case OP_SET_UPVALUE:
return byteInstruction("OP_SET_UPVALUE", chunk, offset);
case OP_GET_PROPERTY:
return constantInstruction("OP_GET_PROPERTY", chunk, offset);
case OP_SET_PROPERTY:
return constantInstruction("OP_SET_PROPERTY", chunk, offset);
case OP_EQUAL:
return simpleInstruction("OP_EQUAL", offset);
case OP_GREATER:

View file

@ -282,6 +282,38 @@ static InterpretResult run() {
*frame->closure->upvalues[slot]->location = peek(0);
break;
}
case OP_GET_PROPERTY: {
if (!IS_INSTANCE(peek(0))) {
runtimeError("Only instances have properties.");
return INTERPRET_RUNTIME_ERROR;
}
ObjInstance *instance = AS_INSTANCE(peek(0));
ObjString *name = READ_STRING();
Value value;
if (tableGet(&instance->fields, name, &value)) {
pop(); /* Instance */
push(value);
break;
}
runtimeError("Undefined property '%s'.", name->chars);
return INTERPRET_RUNTIME_ERROR;
}
case OP_SET_PROPERTY: {
if (!IS_INSTANCE(peek(1))) {
runtimeError("Only instances have fields.");
return INTERPRET_RUNTIME_ERROR;
}
ObjInstance *instance = AS_INSTANCE(peek(1));
tableSet(&instance->fields, READ_STRING(), peek(0));
Value value = pop();
pop();
push(value);
break;
}
case OP_EQUAL: {
Value b = pop();
Value a = pop();