Chapter 27.2

This commit is contained in:
Tom Willemse 2022-08-12 21:17:45 -07:00
parent 63527558a7
commit a819a85209
4 changed files with 58 additions and 38 deletions

View file

@ -34,6 +34,7 @@ typedef enum {
OP_CLOSURE, OP_CLOSURE,
OP_CLOSE_UPVALUE, OP_CLOSE_UPVALUE,
OP_RETURN, OP_RETURN,
OP_CLASS,
} OpCode; } OpCode;
typedef struct { typedef struct {

View file

@ -362,6 +362,55 @@ static void function(FunctionType type) {
} }
} }
static bool identifiersEqual(Token *a, Token *b) {
if (a->length != b->length)
return false;
return memcmp(a->start, b->start, a->length) == 0;
}
static void addLocal(Token name) {
if (current->localCount == UINT8_COUNT) {
error("Too many local variables in function.");
return;
}
Local *local = &current->locals[current->localCount++];
local->name = name;
local->depth = -1;
local->isCaptured = false;
}
static void declareVariable() {
if (current->scopeDepth == 0)
return;
Token *name = &parser.previous;
for (int i = current->localCount - 1; i >= 0; i--) {
Local *local = &current->locals[i];
if (local->depth != -1 && local->depth < current->scopeDepth) {
break;
}
if (identifiersEqual(name, &local->name)) {
error("Already a variable with this name in this scope.");
}
}
addLocal(*name);
}
static void classDeclaration() {
consume(TOKEN_IDENTIFIER, "Expect class name");
uint8_t nameConstant = identifierConstant(&parser.previous);
declareVariable();
emitBytes(OP_CLASS, nameConstant);
defineVariable(nameConstant);
consume(TOKEN_LEFT_BRACE, "Expect '{' before class body.");
consume(TOKEN_RIGHT_BRACE, "Expect '}' after class body.");
}
static void markInitialized() { static void markInitialized() {
if (current->scopeDepth == 0) if (current->scopeDepth == 0)
return; return;
@ -518,7 +567,9 @@ static void synchronize() {
} }
static void declaration() { static void declaration() {
if (match(TOKEN_FUN)) { if (match(TOKEN_CLASS)) {
classDeclaration();
} else if (match(TOKEN_FUN)) {
funDeclaration(); funDeclaration();
} else if (match(TOKEN_VAR)) { } else if (match(TOKEN_VAR)) {
varDeclaration(); varDeclaration();
@ -701,12 +752,6 @@ static uint8_t identifierConstant(Token *name) {
return makeConstant(OBJ_VAL(copyString(name->start, name->length))); return makeConstant(OBJ_VAL(copyString(name->start, name->length)));
} }
static bool identifiersEqual(Token *a, Token *b) {
if (a->length != b->length)
return false;
return memcmp(a->start, b->start, a->length) == 0;
}
static int resolveLocal(Compiler *compiler, Token *name) { static int resolveLocal(Compiler *compiler, Token *name) {
for (int i = compiler->localCount - 1; i >= 0; i--) { for (int i = compiler->localCount - 1; i >= 0; i--) {
Local *local = &compiler->locals[i]; Local *local = &compiler->locals[i];
@ -759,37 +804,6 @@ static int resolveUpvalue(Compiler *compiler, Token *name) {
return -1; return -1;
} }
static void addLocal(Token name) {
if (current->localCount == UINT8_COUNT) {
error("Too many local variables in function.");
return;
}
Local *local = &current->locals[current->localCount++];
local->name = name;
local->depth = -1;
local->isCaptured = false;
}
static void declareVariable() {
if (current->scopeDepth == 0)
return;
Token *name = &parser.previous;
for (int i = current->localCount - 1; i >= 0; i--) {
Local *local = &current->locals[i];
if (local->depth != -1 && local->depth < current->scopeDepth) {
break;
}
if (identifiersEqual(name, &local->name)) {
error("Already a variable with this name in this scope.");
}
}
addLocal(*name);
}
static uint8_t parseVariable(const char *errorMessage) { static uint8_t parseVariable(const char *errorMessage) {
consume(TOKEN_IDENTIFIER, errorMessage); consume(TOKEN_IDENTIFIER, errorMessage);

View file

@ -122,6 +122,8 @@ int disassembleInstruction(Chunk *chunk, int offset) {
return simpleInstruction("OP_CLOSE_UPVALUE", offset); return simpleInstruction("OP_CLOSE_UPVALUE", offset);
case OP_RETURN: case OP_RETURN:
return simpleInstruction("OP_RETURN", offset); return simpleInstruction("OP_RETURN", offset);
case OP_CLASS:
return constantInstruction("OP_CLASS", chunk, offset);
default: default:
printf("Unknown opcode %d\n", instruction); printf("Unknown opcode %d\n", instruction);
return offset + 1; return offset + 1;

View file

@ -384,6 +384,9 @@ static InterpretResult run() {
frame = &vm.frames[vm.frameCount - 1]; frame = &vm.frames[vm.frameCount - 1];
break; break;
} }
case OP_CLASS:
push(OBJ_VAL(newClass(READ_STRING())));
break;
} }
} }