Chapter 24.1
This commit is contained in:
parent
37ac05af6d
commit
9025da8168
4 changed files with 80 additions and 0 deletions
|
@ -288,6 +288,51 @@ static void expressionStatement() {
|
|||
emitByte(OP_POP);
|
||||
}
|
||||
|
||||
static void forStatement() {
|
||||
beginScope();
|
||||
consume(TOKEN_LEFT_PAREN, "Expect '(' after 'for'.");
|
||||
if (match(TOKEN_SEMICOLON)) {
|
||||
// No initializer
|
||||
} else if (match(TOKEN_VAR)) {
|
||||
varDeclaration();
|
||||
} else {
|
||||
expressionStatement();
|
||||
}
|
||||
|
||||
int loopStart = currentChunk()->count;
|
||||
int exitJump = -1;
|
||||
if (!match(TOKEN_SEMICOLON)) {
|
||||
expression();
|
||||
consume(TOKEN_SEMICOLON, "Expect ';' after loop condition.");
|
||||
|
||||
// Jump out of the loop if the condition is false.
|
||||
exitJump = emitJump(OP_JUMP_IF_FALSE);
|
||||
emitByte(OP_POP); /* Condition. */
|
||||
}
|
||||
|
||||
if (!match(TOKEN_RIGHT_PAREN)) {
|
||||
int bodyJump = emitJump(OP_JUMP);
|
||||
int incrementStart = currentChunk()->count;
|
||||
expression();
|
||||
emitByte(OP_POP);
|
||||
consume(TOKEN_RIGHT_PAREN, "Expect ')' after for clauses.");
|
||||
|
||||
emitLoop(loopStart);
|
||||
loopStart = incrementStart;
|
||||
patchJump(bodyJump);
|
||||
}
|
||||
|
||||
statement();
|
||||
emitLoop(loopStart);
|
||||
|
||||
if (exitJump != -1) {
|
||||
patchJump(exitJump);
|
||||
emitByte(OP_POP); /* Condition. */
|
||||
}
|
||||
|
||||
endScope();
|
||||
}
|
||||
|
||||
static void ifStatement() {
|
||||
consume(TOKEN_LEFT_PAREN, "Expect '(' after 'if'.");
|
||||
expression();
|
||||
|
@ -366,6 +411,8 @@ static void declaration() {
|
|||
static void statement() {
|
||||
if (match(TOKEN_PRINT)) {
|
||||
printStatement();
|
||||
} else if (match(TOKEN_FOR)) {
|
||||
forStatement();
|
||||
} else if (match(TOKEN_IF)) {
|
||||
ifStatement();
|
||||
} else if (match(TOKEN_WHILE)) {
|
||||
|
|
|
@ -17,6 +17,12 @@ void *reallocate(void *pointer, size_t oldSize, size_t newSize) {
|
|||
|
||||
static void freeObject(Obj *object) {
|
||||
switch (object->type) {
|
||||
case OBJ_FUNCTION: {
|
||||
ObjFunction *function = (ObjFunction *)object;
|
||||
freeChunk(&function->chunk);
|
||||
FREE(ObjFunction, object);
|
||||
break;
|
||||
}
|
||||
case OBJ_STRING: {
|
||||
ObjString *string = (ObjString *)object;
|
||||
FREE_ARRAY(char, string->chars, string->length + 1);
|
||||
|
|
|
@ -19,6 +19,14 @@ static Obj *allocateObject(size_t size, ObjType type) {
|
|||
return object;
|
||||
}
|
||||
|
||||
ObjFunction *newFunction() {
|
||||
ObjFunction *function = ALLOCATE_OBJ(ObjFunction, OBJ_FUNCTION);
|
||||
function->arity = 0;
|
||||
function->name = NULL;
|
||||
initChunk(&function->chunk);
|
||||
return function;
|
||||
}
|
||||
|
||||
static ObjString *allocateString(char *chars, int length, uint32_t hash) {
|
||||
ObjString *string = ALLOCATE_OBJ(ObjString, OBJ_STRING);
|
||||
string->length = length;
|
||||
|
@ -60,8 +68,15 @@ ObjString *copyString(const char *chars, int length) {
|
|||
return allocateString(heapChars, length, hash);
|
||||
}
|
||||
|
||||
static void printFunction(ObjFunction *function) {
|
||||
printf("<fn %s>", function->name->chars);
|
||||
}
|
||||
|
||||
void printObject(Value value) {
|
||||
switch (OBJ_TYPE(value)) {
|
||||
case OBJ_FUNCTION:
|
||||
printFunction(AS_FUNCTION(value));
|
||||
break;
|
||||
case OBJ_STRING:
|
||||
printf("%s", AS_CSTRING(value));
|
||||
break;
|
||||
|
|
|
@ -1,17 +1,21 @@
|
|||
#ifndef OBJECT_H
|
||||
#define OBJECT_H
|
||||
|
||||
#include "chunk.h"
|
||||
#include "common.h"
|
||||
#include "value.h"
|
||||
|
||||
#define OBJ_TYPE(value) (AS_OBJ(value)->type)
|
||||
|
||||
#define IS_FUNCTION(value) isObjType(value, OBJ_FUNCTION)
|
||||
#define IS_STRING(value) isObjType(value, OBJ_STRING)
|
||||
|
||||
#define AS_FUNCTION(value) ((ObjFunction *)AS_OBJ(value))
|
||||
#define AS_STRING(value) ((ObjString *)AS_OBJ(value))
|
||||
#define AS_CSTRING(value) (((ObjString *)AS_OBJ(value))->chars)
|
||||
|
||||
typedef enum {
|
||||
OBJ_FUNCTION,
|
||||
OBJ_STRING,
|
||||
} ObjType;
|
||||
|
||||
|
@ -20,6 +24,13 @@ struct Obj {
|
|||
struct Obj *next;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
Obj obj;
|
||||
int arity;
|
||||
Chunk chunk;
|
||||
ObjString *name;
|
||||
} ObjFunction;
|
||||
|
||||
struct ObjString {
|
||||
Obj obj;
|
||||
int length;
|
||||
|
@ -27,6 +38,7 @@ struct ObjString {
|
|||
uint32_t hash;
|
||||
};
|
||||
|
||||
ObjFunction *newFunction();
|
||||
ObjString *takeString(char *chars, int length);
|
||||
ObjString *copyString(const char *chars, int length);
|
||||
void printObject(Value value);
|
||||
|
|
Loading…
Reference in a new issue