Chapter 24.4
This commit is contained in:
parent
ce478b0b80
commit
44e47b89de
1 changed files with 48 additions and 6 deletions
|
@ -46,7 +46,8 @@ typedef struct {
|
|||
|
||||
typedef enum { TYPE_FUNCTION, TYPE_SCRIPT } FunctionType;
|
||||
|
||||
typedef struct {
|
||||
typedef struct Compiler {
|
||||
struct Compiler *enclosing;
|
||||
ObjFunction *function;
|
||||
FunctionType type;
|
||||
|
||||
|
@ -171,12 +172,17 @@ static void patchJump(int offset) {
|
|||
}
|
||||
|
||||
static void initCompiler(Compiler *compiler, FunctionType type) {
|
||||
compiler->enclosing = current;
|
||||
compiler->function = NULL;
|
||||
compiler->type = type;
|
||||
compiler->localCount = 0;
|
||||
compiler->scopeDepth = 0;
|
||||
compiler->function = newFunction();
|
||||
current = compiler;
|
||||
if (type != TYPE_SCRIPT) {
|
||||
current->function->name =
|
||||
copyString(parser.previous.start, parser.previous.length);
|
||||
}
|
||||
|
||||
Local *local = ¤t->locals[current->localCount++];
|
||||
local->depth = 0;
|
||||
|
@ -196,6 +202,7 @@ static ObjFunction *endCompiler() {
|
|||
}
|
||||
#endif
|
||||
|
||||
current = current->enclosing;
|
||||
return function;
|
||||
}
|
||||
|
||||
|
@ -288,6 +295,43 @@ static void block() {
|
|||
consume(TOKEN_RIGHT_BRACE, "Expect '}' after block.");
|
||||
}
|
||||
|
||||
static void function(FunctionType type) {
|
||||
Compiler compiler;
|
||||
initCompiler(&compiler, type);
|
||||
beginScope();
|
||||
|
||||
consume(TOKEN_LEFT_PAREN, "Expect '(' after function name.");
|
||||
if (!check(TOKEN_RIGHT_PAREN)) {
|
||||
do {
|
||||
current->function->arity++;
|
||||
if (current->function->arity > 255) {
|
||||
errorAtCurrent("Can't have more than 250 parameters.");
|
||||
}
|
||||
uint8_t constant = parseVariable("Expect parameter name.");
|
||||
defineVariable(constant);
|
||||
} while (match(TOKEN_COMMA));
|
||||
}
|
||||
consume(TOKEN_RIGHT_PAREN, "Expect ')' after parameters.");
|
||||
consume(TOKEN_LEFT_BRACE, "Expect '{' before function body.");
|
||||
block();
|
||||
|
||||
ObjFunction *function = endCompiler();
|
||||
emitBytes(OP_CONSTANT, makeConstant(OBJ_VAL(function)));
|
||||
}
|
||||
|
||||
static void markInitialized() {
|
||||
if (current->scopeDepth == 0)
|
||||
return;
|
||||
current->locals[current->localCount - 1].depth = current->scopeDepth;
|
||||
}
|
||||
|
||||
static void funDeclaration() {
|
||||
uint8_t global = parseVariable("Expect function name.");
|
||||
markInitialized();
|
||||
function(TYPE_FUNCTION);
|
||||
defineVariable(global);
|
||||
}
|
||||
|
||||
static void varDeclaration() {
|
||||
uint8_t global = parseVariable("Expect variable name.");
|
||||
|
||||
|
@ -417,7 +461,9 @@ static void synchronize() {
|
|||
}
|
||||
|
||||
static void declaration() {
|
||||
if (match(TOKEN_VAR)) {
|
||||
if (match(TOKEN_FUN)) {
|
||||
funDeclaration();
|
||||
} else if (match(TOKEN_VAR)) {
|
||||
varDeclaration();
|
||||
} else {
|
||||
statement();
|
||||
|
@ -653,10 +699,6 @@ static uint8_t parseVariable(const char *errorMessage) {
|
|||
return identifierConstant(&parser.previous);
|
||||
}
|
||||
|
||||
static void markInitialized() {
|
||||
current->locals[current->localCount - 1].depth = current->scopeDepth;
|
||||
}
|
||||
|
||||
static void defineVariable(uint8_t global) {
|
||||
if (current->scopeDepth > 0) {
|
||||
markInitialized();
|
||||
|
|
Loading…
Reference in a new issue