From dc4e6d33b220c55973b46db0f88e67a98057964c Mon Sep 17 00:00:00 2001 From: nazrin Date: Wed, 11 Jun 2025 00:30:22 +0000 Subject: [PATCH] Closures 25 --- src/clox/chunk.d | 6 +- src/clox/compiler.d | 16 +++-- src/clox/container/dynarray.d | 4 +- src/clox/container/table.d | 41 +++++++------ src/clox/container/varint.d | 22 +++---- src/clox/dbg.d | 45 ++++++++++---- src/clox/main.d | 3 +- src/clox/memory.d | 104 ++++++-------------------------- src/clox/memorydbg.d | 80 +++++++++++++++++++++++++ src/clox/obj.d | 74 +++++++++++++++++++---- src/clox/parser.d | 109 +++++++++++++++++++++------------- src/clox/parserules.d | 2 +- src/clox/value.d | 4 +- src/clox/vm.d | 98 +++++++++++++++++++++++++----- test/all.d | 5 +- test/perverseclosure.lox | 18 ++++++ 16 files changed, 422 insertions(+), 209 deletions(-) create mode 100644 src/clox/memorydbg.d create mode 100644 test/perverseclosure.lox diff --git a/src/clox/chunk.d b/src/clox/chunk.d index 333feee..95eb218 100644 --- a/src/clox/chunk.d +++ b/src/clox/chunk.d @@ -23,8 +23,10 @@ enum OpCode : ubyte{ @(OpColour("255", "200", "100")) False, @(OpColour("000", "200", "100")) Pop, - @OpStack @(OpColour("060", "200", "150")) GetLocal, + @OpStack @(OpColour("060", "210", "150")) GetLocal, @OpStack @(OpColour("060", "200", "150")) SetLocal, + @OpStack @(OpColour("080", "210", "150")) GetUpvalue, + @OpStack @(OpColour("080", "200", "150")) SetUpvalue, @OpConst @(OpColour("000", "200", "150")) GetGlobal, @OpConst @(OpColour("000", "200", "150")) DefineGlobal, @@ -51,6 +53,8 @@ enum OpCode : ubyte{ @(OpColour("000", "200", "100")) Print, @OpCall @(OpColour("250", "200", "250")) Call, + @(OpColour("250", "200", "250")) Closure, + @(OpColour("250", "200", "050")) CloseUpvalue, @(OpColour("250", "190", "200")) Return, } diff --git a/src/clox/compiler.d b/src/clox/compiler.d index a9e4153..f5080c6 100644 --- a/src/clox/compiler.d +++ b/src/clox/compiler.d @@ -7,7 +7,7 @@ import clox.parser; import clox.chunk; import clox.dbg; import clox.vm; -import clox.object; +import clox.obj; import clox.value; import clox.container.dynarray; import clox.container.varint; @@ -15,17 +15,22 @@ import clox.container.varint; Parser parser; Compiler* currentCompiler; +struct Upvalue{ + int index; + bool isLocal; +} struct Compiler{ Compiler* enclosing; Obj.Function* func; enum FunctionType{ None, Function, Script } FunctionType ftype = FunctionType.Script; struct Local{ - enum Uninitialised = -1; Token name; int depth; + bool isCaptured; } DynArray!Local locals; + DynArray!Upvalue upvalues; int scopeDepth; private Chunk* compilingChunk; Chunk* currentChunk() => &func.chunk; @@ -42,7 +47,7 @@ struct Compiler{ Local local = Local(); local.depth = 0; - local.name.lexeme = ""; + local.name.lexeme = "<>"; locals ~= local; } Obj.Function* compile(){ @@ -61,10 +66,13 @@ struct Compiler{ if(!parser.hadError) currentChunk.disassembleChunk(func.name !is null ? func.name.chars.ptr : "