45 lines
1.2 KiB
D
45 lines
1.2 KiB
D
module jlox.loxfunction;
|
|
|
|
import std.conv;
|
|
|
|
import common.util;
|
|
import jlox.token;
|
|
import jlox.stmt;
|
|
import jlox.interpreter;
|
|
import jlox.environment;
|
|
import jlox.loxinstance;
|
|
|
|
class LoxFunction : LoxCallable{
|
|
private Stmt.Function declaration;
|
|
private Environment closure;
|
|
private const bool isInitialiser;
|
|
mixin defaultCtor;
|
|
invariant{
|
|
assert(declaration && closure);
|
|
}
|
|
|
|
LoxFunction bind(LoxInstance instance){
|
|
Environment environment = new Environment(closure);
|
|
environment.define("this", instance);
|
|
return new LoxFunction(declaration, environment, isInitialiser);
|
|
}
|
|
|
|
int arity() => declaration.params.length.to!int;
|
|
LoxValue call(Interpreter interpreter, LoxValue[] arguments){
|
|
Environment environment = new Environment(closure);
|
|
foreach(i; 0 .. declaration.params.length)
|
|
environment.define(declaration.params[i].lexeme, arguments[i]);
|
|
try{
|
|
interpreter.executeBlock(declaration.body, environment);
|
|
} catch(Return returnValue){
|
|
if(isInitialiser)
|
|
return closure.getAt(0, "this");
|
|
return cast(LoxValue)returnValue.value;
|
|
}
|
|
if(isInitialiser)
|
|
return closure.getAt(0, "this");
|
|
return new LoxNil();
|
|
}
|
|
override string toString() const => "function";
|
|
}
|
|
|