From e9e3c992cb67ddfbe8dab65b490135a5ef8cf685 Mon Sep 17 00:00:00 2001 From: nazrin Date: Mon, 2 Jun 2025 01:27:19 +0000 Subject: [PATCH] Functions 10 --- src/jlox/interpreter.d | 2 +- src/jlox/loxfunction.d | 6 +++++- test/all.d | 1 + test/closure.lox | 13 +++++++++++++ 4 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 test/closure.lox diff --git a/src/jlox/interpreter.d b/src/jlox/interpreter.d index fd61716..d248eda 100644 --- a/src/jlox/interpreter.d +++ b/src/jlox/interpreter.d @@ -106,7 +106,7 @@ class Interpreter : Stmt.Visitor!void, Expr.Visitor!TValue { evaluate(stmt.expression); } void visit(Stmt.Function stmt){ - LoxFunction func = new LoxFunction(stmt); + LoxFunction func = new LoxFunction(stmt, environment); environment.define(stmt.name.lexeme, TValue.cal(func)); } void visit(Stmt.If stmt){ diff --git a/src/jlox/loxfunction.d b/src/jlox/loxfunction.d index 39a91ff..16c5878 100644 --- a/src/jlox/loxfunction.d +++ b/src/jlox/loxfunction.d @@ -10,11 +10,15 @@ import jlox.util; class LoxFunction : LoxCallable{ private Stmt.Function declaration; + private Environment closure; mixin defaultCtor; + invariant{ + assert(declaration && closure); + } int arity() => declaration.params.length.to!int; TValue call(Interpreter interpreter, TValue[] arguments){ - Environment environment = new Environment(interpreter.globals); + Environment environment = new Environment(closure); foreach(i; 0 .. declaration.params.length) environment.define(declaration.params[i].lexeme, arguments[i]); try{ diff --git a/test/all.d b/test/all.d index d22369c..5b79f0e 100755 --- a/test/all.d +++ b/test/all.d @@ -17,5 +17,6 @@ void main(){ } assert([ "./lox", "test/fib21.lox" ].execute.output == fib(6765)); assert([ "./lox", "test/fib10.lox" ].execute.output == fib(34)); + assert([ "./lox", "test/closure.lox" ].execute.output == "1\n2\n"); } diff --git a/test/closure.lox b/test/closure.lox new file mode 100644 index 0000000..170cdd0 --- /dev/null +++ b/test/closure.lox @@ -0,0 +1,13 @@ + +fun makeCounter(){ + var i = 0; + fun counter(){ + return i = i + 1; + } + return counter; +} + +var counter = makeCounter(); +print counter(); // "1". +print counter(); // "2". +