From 72a41e81e6e4b90475cfe6451a53b573fec027f4 Mon Sep 17 00:00:00 2001 From: nazrin Date: Sat, 7 Jun 2025 23:52:16 +0000 Subject: [PATCH 1/2] Local Variables 22 --- dub.sdl | 6 +- src/clox/chunk.d | 45 ++- src/clox/compiler.d | 10 + src/clox/container/dynarray.d | 45 +++ src/clox/container/stack.d | 26 +- src/clox/container/table.d | 17 +- src/clox/container/varint.d | 73 +++++ src/clox/dbg.d | 23 +- src/clox/emitter.d | 12 +- src/clox/main.d | 1 + src/clox/memory.d | 2 +- src/clox/parser.d | 105 +++++-- src/clox/scanner.d | 2 +- src/clox/value.d | 26 -- src/clox/vm.d | 35 ++- test/biglocals.lox | 507 ++++++++++++++++++++++++++++++++++ test/bigsum.lox | 503 +++++++++++++++++++++++++++++++++ test/simplescope.lox | 12 + 18 files changed, 1335 insertions(+), 115 deletions(-) create mode 100644 src/clox/container/dynarray.d create mode 100644 src/clox/container/varint.d create mode 100644 test/biglocals.lox create mode 100644 test/bigsum.lox create mode 100644 test/simplescope.lox diff --git a/dub.sdl b/dub.sdl index c3201b0..45dbbb5 100644 --- a/dub.sdl +++ b/dub.sdl @@ -9,9 +9,9 @@ targetType "executable" sourcePaths configuration "clox" { - buildOptions "betterC" - /* debugVersions "memTrace" */ - debugVersions "traceExec" + /* buildOptions "betterC" */ + debugVersions "memTrace" + /* debugVersions "traceExec" */ /* debugVersions "printCode" */ dflags "-checkaction=C" libs "libbacktrace" diff --git a/src/clox/chunk.d b/src/clox/chunk.d index 0a2a417..a045758 100644 --- a/src/clox/chunk.d +++ b/src/clox/chunk.d @@ -4,6 +4,7 @@ import std.algorithm.searching; import clox.memory; import clox.value; +import clox.container.dynarray; struct OpColour{ string r, g, b; @@ -16,8 +17,10 @@ enum OpCode : ubyte{ @(OpColour("255", "200", "100")) False, @(OpColour("000", "200", "100")) Pop, + @(OpColour("060", "200", "150")) GetLocal, @(OpColour("000", "200", "150")) GetGlobal, @(OpColour("000", "200", "150")) DefineGlobal, + @(OpColour("060", "200", "150")) SetLocal, @(OpColour("000", "200", "150")) SetGlobal, @(OpColour("255", "100", "100")) Equal, @@ -39,40 +42,32 @@ enum OpCode : ubyte{ } struct Chunk{ - uint count; - uint capacity; - ubyte* code; - uint* lines; - ValueArray constants; + DynArray!ubyte code; + DynArray!uint lines; + DynArray!Value constants; void initialise(){ - count = 0; - capacity = 0; - code = null; - lines = null; + code.initialise(); + lines.initialise(); constants.initialise(); } - void write(ubyte b, uint line = 0){ - if(capacity < count + 1){ - uint oldCapacity = capacity; - capacity = GROW_CAPACITY(oldCapacity); - code = GROW_ARRAY!ubyte(code, oldCapacity, capacity); - lines = GROW_ARRAY!uint(lines, oldCapacity, capacity); - } - code[count] = b; - lines[count] = line; - count++; + void write(in ubyte[] bytes, uint line = 0){ + foreach(b; bytes) + write(b, line); } - int addConstant(Value value){ - int index = cast(int)constants.values[0 .. constants.count].countUntil(value); + void write(ubyte b, uint line = 0){ + code ~= b; + lines ~= line; + } + size_t addConstant(Value value){ + long index = constants[].countUntil(value); if(index >= 0) return index; - assert(constants.count <= ubyte.max); - constants.write(value); + constants ~= value; return constants.count - 1; } void free(){ - FREE_ARRAY!ubyte(code, capacity); - FREE_ARRAY!uint(lines, capacity); + code.free(); + lines.free(); constants.free(); initialise(); } diff --git a/src/clox/compiler.d b/src/clox/compiler.d index 7a4e3ee..6a5b138 100644 --- a/src/clox/compiler.d +++ b/src/clox/compiler.d @@ -7,17 +7,26 @@ import clox.parser; import clox.chunk; import clox.emitter; import clox.dbg; +import clox.container.dynarray; struct Compiler{ Scanner scanner; Parser parser; Emitter emitter; + struct Local{ + enum Uninitialised = -1; + Token name; + int depth; + } + DynArray!Local locals; + int scopeDepth; private Chunk* compilingChunk; Chunk* currentChunk() => compilingChunk; bool compile(const(char)* source, Chunk* chunk){ scanner.initialise(source); parser.initialise(&this); emitter.initialise(&this); + locals.initialise(); compilingChunk = chunk; parser.advance(); @@ -33,6 +42,7 @@ struct Compiler{ if(!parser.hadError) currentChunk.disassembleChunk(); } + locals.free(); } } diff --git a/src/clox/container/dynarray.d b/src/clox/container/dynarray.d new file mode 100644 index 0000000..c13793a --- /dev/null +++ b/src/clox/container/dynarray.d @@ -0,0 +1,45 @@ +module clox.container.dynarray; + +import clox.memory; + +struct DynArray(T){ + size_t count; + size_t capacity; + T* ptr; + void initialise(){ + count = 0; + capacity = 0; + ptr = null; + } + void opOpAssign(string op: "~")(in T value){ + if(capacity < count + 1){ + size_t oldCapacity = capacity; + capacity = GROW_CAPACITY(oldCapacity); + ptr = GROW_ARRAY!T(ptr, oldCapacity, capacity); + } + ptr[count] = value; + count++; + } + auto opSlice(){ + assert(ptr || !count); + return ptr[0 .. count]; + } + ref auto opIndex(size_t i){ + assert(ptr && count); + return ptr[i]; + } + size_t opDollar(size_t pos: 0)(){ + return count; + } + void free(){ + if(ptr) + FREE_ARRAY!T(ptr, capacity); + initialise(); + } + auto pop(){ + assert(count); + count--; + return this[count-1]; + } +} + diff --git a/src/clox/container/stack.d b/src/clox/container/stack.d index a719ad1..7fb88aa 100644 --- a/src/clox/container/stack.d +++ b/src/clox/container/stack.d @@ -1,26 +1,30 @@ module clox.container.stack; -struct Stack(T, size_t N){ - @nogc: nothrow: +import clox.container.dynarray; + +struct Stack(T){ T* top; - T[N] data; - /* invariant{ assert(top <= data.ptr + N); assert(top >= data.ptr); } */ - void reset(){ + private DynArray!T data; + void initialise(){ + data.initialise(); top = data.ptr; } void push(T value){ - assert(top < data.ptr + N); - debug assert(*top is T.init); - *(top++) = value; + data ~= value; + top = data.ptr + data.count; } T pop(){ assert(top > data.ptr); T t = *(--top); - debug *(top) = T.init; + assert(data.count-- >= 0); return t; } - const(T)[] live() const @safe{ - return data[0 .. (top - data.ptr)]; + ref T opIndex(size_t i) => data[i]; + const(T)[] live(){ + return data[]; + } + void free(){ + data.free(); } } diff --git a/src/clox/container/table.d b/src/clox/container/table.d index 1c88e21..1b476a0 100644 --- a/src/clox/container/table.d +++ b/src/clox/container/table.d @@ -10,7 +10,7 @@ import clox.memory; enum TABLE_MAX_LOAD = 0.75; struct Table{ - uint count, capacity; + size_t count, capacity; Entry* entries; struct Entry{ Obj.String* key; @@ -25,7 +25,7 @@ struct Table{ FREE_ARRAY!Entry(entries, capacity); initialise(); } - private void adjustCapacity(uint cap){ + private void adjustCapacity(size_t cap){ Entry* ent = ALLOCATE!Entry(cap); for(int i = 0; i < cap; i++){ ent[i].key = null; @@ -46,7 +46,7 @@ struct Table{ entries = ent; capacity = cap; } - private Entry* findEntry(Entry* entries, int capacity, in Obj.String* key){ + private Entry* findEntry(Entry* entries, size_t capacity, in Obj.String* key){ uint index = key.hash % capacity; Entry* tombstone = null; while(true){ @@ -66,7 +66,7 @@ struct Table{ } bool set(Obj.String* key, Value value){ if(count + 1 > capacity * TABLE_MAX_LOAD){ - uint cap = GROW_CAPACITY(capacity); + size_t cap = GROW_CAPACITY(capacity); adjustCapacity(cap); } Entry* entry = findEntry(entries, capacity, key); @@ -121,12 +121,13 @@ struct Table{ } unittest{ + import clox.vm : vm; Table tbl; tbl.initialise(); - scope(exit) + scope(exit){ tbl.free(); - scope(exit) - freeObjects(); + vm.free(); + } assert(tbl.count == 0); @@ -146,7 +147,7 @@ unittest{ assert(tbl.count == 1); foreach(i; 0..25){ - Obj.String* str2 = Obj.String.copy("hello"); + Obj.String* str2 = Obj.String.copy("hi 2"); tbl.set(str2, Value.from(i)); assert(tbl.get(str2, val)); assert(val.asNumber == i); diff --git a/src/clox/container/varint.d b/src/clox/container/varint.d new file mode 100644 index 0000000..a1270aa --- /dev/null +++ b/src/clox/container/varint.d @@ -0,0 +1,73 @@ +module clox.container.varint; + +struct VarUint{ + import std.bitmanip; + nothrow: @nogc: + uint i; + ubyte len; + private ubyte[4] data; + this(size_t l) @safe { + if(l < 0b1000_0000){ + len = 1; + data[0] = (cast(ubyte)l); + return; + } + if(l < 0b0100_0000__0000_0000){ + len = 2; + data[0 .. 2] = nativeToBigEndian(cast(ushort)l); + data[0] |= 0b1000_0000; + return; + } + if(l < 0b0010_0000__0000_0000__0000_0000__0000_0000){ + len = 4; + data[0 .. 4] = nativeToBigEndian(cast(uint)l); + data[0] |= 0b1100_0000; + return; + } + assert(0); + } + static VarUint read(in ubyte* data){ + VarUint v; + ubyte a = data[0]; + if((data[0] & 0b1000_0000) == 0){ + v.i = a; + v.len = 1; + return v; + } + if((a & 0b0100_0000) == 0){ + ubyte[2] d = data[0 .. 2]; + d[0] &= 0b0111_1111; + v.i = bigEndianToNative!ushort(d); + v.len = 2; + return v; + } + if((a & 0b0010_0000) == 0){ + ubyte[4] d = data[0 .. 4]; + d[0] &= 0b0011_1111; + v.i = bigEndianToNative!uint(d); + v.len = 4; + return v; + } + assert(0); + } + ubyte[] bytes(){ + return data[0 .. len]; + } +} +unittest{ + import std.range; + assert(VarUint(5).bytes.length == 1); + assert(VarUint(127).bytes.length == 1); + assert(VarUint(128).bytes.length == 2); + assert(VarUint(536_870_911).bytes.length == 4); + foreach(i; [ + 0, 1, 2, 5, + 150, 127, 128, + 536_870_911, + ushort.max * 100 + ]){ + auto vi = VarUint(i); + assert(i == VarUint.read(vi.bytes.ptr).i); + } +} + diff --git a/src/clox/dbg.d b/src/clox/dbg.d index 4d469dd..e3c274b 100644 --- a/src/clox/dbg.d +++ b/src/clox/dbg.d @@ -7,32 +7,35 @@ import std.traits : EnumMembers, hasUDA, getUDAs; import clox.chunk; import clox.value; import clox.util; +import clox.container.varint; -private int simpleInstruction(alias OpCode op)(const char* name, int offset){ +import std.stdio; + +private long simpleInstruction(alias OpCode op)(const char* name, long offset){ enum c = getUDAs!(op, OpColour)[0]; printf(colour!("%-27s ", c.r, c.g, c.b).ptr, name); return offset + 1; } -private int constantInstruction(alias OpCode op)(const char* name, Chunk* chunk, int offset){ +private long constantInstruction(alias OpCode op)(const char* name, Chunk* chunk, long offset){ + VarUint constant = VarUint.read(&chunk.code[offset + 1]); enum c = getUDAs!(op, OpColour)[0]; - ubyte constant = chunk.code[offset + 1]; - printf(ctEval!(colour!("%-14s", c.r, c.g, c.b) ~ colour!(" %4d ", Colour.Black)).ptr, name, constant); - int pl = chunk.constants.values[constant].print(); + printf(ctEval!(colour!("%-14s", c.r, c.g, c.b) ~ colour!(" %4d ", Colour.Black)).ptr, name, constant.i); + long pl = chunk.constants[constant.i].print(); foreach(i; 0 .. 16-pl) printf(" "); - return offset + 2; + return offset + 1 + constant.len; } void disassembleChunk(Chunk* chunk, const char* name = "chunk"){ printf(" == %s ==\n", name); - for(int offset = 0; offset < chunk.count;){ + for(long offset = 0; offset < chunk.code.count;){ offset = disassembleInstruction(chunk, offset); printf("\n"); } } -int disassembleInstruction(Chunk* chunk, int offset){ - printf("%5d ", offset); +long disassembleInstruction(Chunk* chunk, long offset){ + printf("%5ld ", offset); if(offset > 0 && chunk.lines[offset] == chunk.lines[offset - 1]){ printf(colour!(" | ", Colour.Black).ptr); } else { @@ -48,7 +51,7 @@ int disassembleInstruction(Chunk* chunk, int offset){ return simpleInstruction!e(e.stringof, offset); } } - default: printf("Unknown opcode %d", instruction); + default: printf("(Unknown opcode %d)", instruction); return offset + 1; } } diff --git a/src/clox/emitter.d b/src/clox/emitter.d index 49b972a..9163165 100644 --- a/src/clox/emitter.d +++ b/src/clox/emitter.d @@ -5,6 +5,7 @@ import core.stdc.stdio; import clox.chunk; import clox.compiler; import clox.value; +import clox.container.varint; struct Emitter{ Compiler* compiler; @@ -13,18 +14,19 @@ struct Emitter{ void initialise(Compiler* compiler){ this.compiler = compiler; } - void emit(ubyte[] bytes...){ - foreach(b; bytes) + void emit(Args...)(Args a){ + static foreach(b; a) compiler.currentChunk.write(b, compiler.parser.previous.line); } void emitReturn(){ emit(OpCode.Return); } void emitConstant(Value value){ - emit(OpCode.Constant, cast(ubyte)makeConstant(value)); + size_t c = makeConstant(value); + emit(OpCode.Constant, VarUint(c).bytes); } - uint makeConstant(Value value){ - uint constant = compiler.currentChunk.addConstant(value); + size_t makeConstant(Value value){ + size_t constant = compiler.currentChunk.addConstant(value); return constant; } } diff --git a/src/clox/main.d b/src/clox/main.d index 35a3e0c..cc91926 100644 --- a/src/clox/main.d +++ b/src/clox/main.d @@ -18,6 +18,7 @@ int interpretResult(VM.InterpretResult result){ } int runPrompt(){ + vm.isREPL = true; char[1024 * 4] line; while(true){ printf(colour!("lox> ", Colour.Green).ptr); diff --git a/src/clox/memory.d b/src/clox/memory.d index ade0b44..bfdc5a1 100644 --- a/src/clox/memory.d +++ b/src/clox/memory.d @@ -2,7 +2,7 @@ module clox.memory; import core.stdc.stdlib; -auto GROW_CAPACITY(uint capacity) => capacity < 8 ? 8 : capacity * 2; +auto GROW_CAPACITY(size_t capacity) => capacity < 8 ? 8 : capacity * 2; auto GROW_ARRAY(T)(T* ptr, size_t oldCount, size_t newCount) => cast(T*)reallocate(ptr, T.sizeof * oldCount, T.sizeof * newCount); auto FREE_ARRAY(T)(T* ptr, size_t oldCount) => reallocate!T(ptr, T.sizeof * oldCount, 0); auto FREE(T)(T* ptr) => reallocate(ptr, T.sizeof, 0); diff --git a/src/clox/parser.d b/src/clox/parser.d index 48f1bb9..f343c31 100644 --- a/src/clox/parser.d +++ b/src/clox/parser.d @@ -10,6 +10,8 @@ import clox.parserules; import clox.util; import clox.object; import clox.value; +import clox.vm; +import clox.container.varint; struct Parser{ Compiler* compiler; @@ -48,11 +50,16 @@ struct Parser{ } void expressionStatement(){ expression(); - consume(Token.Type.Semicolon, "Expect ';' after expression."); - compiler.emitter.emit(OpCode.Pop); + if(vm.isREPL){ + match(Token.Type.Semicolon); + compiler.emitter.emit(OpCode.Print); + } else { + consume(Token.Type.Semicolon, "Expect ';' after expression."); + compiler.emitter.emit(OpCode.Pop); + } } void varDeclaration(){ - ubyte global = parseVariable("Expect variable name."); + long global = parseVariable("Expect variable name."); if(match(Token.Type.Equal)) expression(); else @@ -66,12 +73,16 @@ struct Parser{ else statement(); if(compiler.parser.panicMode) - synchronize(); + synchronise(); } void statement(){ - if(match(Token.Type.Print)) + if(match(Token.Type.Print)){ printStatement(); - else + } else if(match(Token.Type.LeftBrace)){ + beginScope(); + block(); + endScope(); + } else expressionStatement(); } void printStatement(){ @@ -79,25 +90,87 @@ struct Parser{ consume(Token.Type.Semicolon, "Expect ';' after value."); compiler.emitter.emit(OpCode.Print); } - - void defineVariable(ubyte global){ - compiler.emitter.emit(OpCode.DefineGlobal, global); + void block(){ + while(!check(Token.Type.RightBrace) && !check(Token.Type.EOF)) + declaration(); + consume(Token.Type.RightBrace, "Expect '}' after block."); } - ubyte parseVariable(const char* errorMessage){ + + void defineVariable(long global){ + if(compiler.scopeDepth > 0){ + markInitialised(); + return; + } + compiler.emitter.emit(OpCode.DefineGlobal, VarUint(global).bytes); + } + void markInitialised(){ + compiler.locals[compiler.locals.count - 1].depth = compiler.scopeDepth; + } + void declareVariable(){ + if(compiler.scopeDepth == 0) + return; + Token* name = &compiler.parser.previous; + for(long i = compiler.locals.count - 1; i >= 0; i--){ + Compiler.Local* local = &compiler.locals[i]; + if(local.depth != Compiler.Local.Uninitialised && local.depth < compiler.scopeDepth) + break; + if(name.lexeme == local.name.lexeme) + error("Already a variable with this name in this scope."); + } + addLocal(*name); + } + long parseVariable(const char* errorMessage){ consume(Token.Type.Identifier, errorMessage); + declareVariable(); + if(compiler.scopeDepth > 0) + return 0; return identifierConstant(&previous); } - ubyte identifierConstant(Token* name){ + long identifierConstant(Token* name){ Value nameVal = Value.from(Obj.String.copy(name.lexeme)); - return cast(ubyte)compiler.emitter.makeConstant(nameVal); + return compiler.emitter.makeConstant(nameVal); } void namedVariable(Token name, bool canAssign){ - ubyte arg = compiler.parser.identifierConstant(&name); + OpCode getOp, setOp; + long arg = resolveLocal(&name); + if(arg != -1){ + getOp = OpCode.GetLocal; + setOp = OpCode.SetLocal; + } else { + arg = identifierConstant(&name); + getOp = OpCode.GetGlobal; + setOp = OpCode.SetGlobal; + } if(canAssign && match(Token.Type.Equal)){ expression(); - compiler.emitter.emit(OpCode.SetGlobal, arg); + compiler.emitter.emit(setOp, VarUint(arg).bytes); } else { - compiler.emitter.emit(OpCode.GetGlobal, arg); + compiler.emitter.emit(getOp, VarUint(arg).bytes); + } + } + + long resolveLocal(Token* name){ + for(long i = compiler.locals.count - 1; i >= 0; i--){ + Compiler.Local* local = &compiler.locals[i]; + if(name.lexeme == local.name.lexeme){ + if(local.depth == Compiler.Local.Uninitialised) + error("Can't read local variable in its own initialiser."); + return i; + } + } + return -1; + } + void addLocal(Token name){ + compiler.locals ~= Compiler.Local(name, Compiler.Local.Uninitialised); + } + void beginScope(){ + compiler.scopeDepth++; + } + void endScope(){ + assert(--compiler.scopeDepth >= 0); + while(compiler.locals.count > 0 && compiler.locals[compiler.locals.count - 1].depth > compiler.scopeDepth){ + compiler.emitter.emit(OpCode.Pop); + compiler.locals.count--; } } @@ -119,7 +192,7 @@ struct Parser{ error("Invalid assignment target."); } - void synchronize(){ + void synchronise(){ panicMode = false; while(current.type != Token.Type.EOF){ if(previous.type == Token.Type.Semicolon) diff --git a/src/clox/scanner.d b/src/clox/scanner.d index a3e93d0..60667bc 100644 --- a/src/clox/scanner.d +++ b/src/clox/scanner.d @@ -99,7 +99,7 @@ struct Scanner{ while(true){ char c = peek(); switch(c){ - case ' ', '\r': + case ' ', '\r', '\t': advance(); break; case '\n': diff --git a/src/clox/value.d b/src/clox/value.d index d0a8e98..8f01fb0 100644 --- a/src/clox/value.d +++ b/src/clox/value.d @@ -71,29 +71,3 @@ struct Value{ } } - -struct ValueArray{ - uint count; - uint capacity; - Value* values; - void initialise(){ - count = 0; - capacity = 0; - values = null; - } - void write(Value value){ - if(capacity < count + 1){ - int oldCapacity = capacity; - capacity = GROW_CAPACITY(oldCapacity); - values = GROW_ARRAY!Value(values, oldCapacity, capacity); - } - values[count] = value; - count++; - } - void free(){ - if(values) - FREE_ARRAY!Value(values, capacity); - initialise(); - } -} - diff --git a/src/clox/vm.d b/src/clox/vm.d index d77a1fc..6290e2d 100644 --- a/src/clox/vm.d +++ b/src/clox/vm.d @@ -12,19 +12,21 @@ import clox.compiler; import clox.memory; import clox.container.stack; import clox.container.table; +import clox.container.varint; VM vm; struct VM{ Chunk* chunk; ubyte* ip; - Stack!(Value, 256) stack; + Stack!Value stack; Table globals; Table strings; Obj* objects; + bool isREPL; enum InterpretResult{ Ok, CompileError, RuntimeError } void initialise(){ - stack.reset(); + stack.initialise(); strings.initialise(); globals.initialise(); } @@ -32,6 +34,7 @@ struct VM{ freeObjects(); strings.free(); globals.free(); + stack.free(); } InterpretResult interpret(const char* source){ Chunk cnk; @@ -42,21 +45,27 @@ struct VM{ if(!compiler.compile(source, &cnk)) return InterpretResult.CompileError; this.chunk = &cnk; - this.ip = cnk.code; + this.ip = cnk.code.ptr; return run(); } void runtimeError(Args...)(const char* format, Args args){ fprintf(stderr, format, args); fputs("\n", stderr); - size_t instruction = vm.ip - vm.chunk.code - 1; - int line = vm.chunk.lines[instruction]; + size_t instruction = vm.ip - vm.chunk.code.ptr - 1; + uint line = vm.chunk.lines[instruction]; fprintf(stderr, "[line %d] in script\n", line); - stack.reset(); } InterpretResult run(){ - ubyte readByte() => *vm.ip++; - auto readConstant() => chunk.constants.values[readByte()]; + ubyte readByte() => *ip++; + long readVarUint(){ + VarUint vi = VarUint.read(ip); + ip += vi.len; + return vi.i; + } + Value readConstant(){ + return chunk.constants[readVarUint()]; + } Obj.String* readString() => readConstant().asObj.asString; Value peek(int distance = 0) => stack.top[-1 - distance]; bool checkBinaryType(alias type)() => peek(0).isType(type) && peek(1).isType(type); @@ -73,7 +82,7 @@ struct VM{ } while(true){ debug(traceExec){ - disassembleInstruction(vm.chunk, cast(int)(vm.ip - vm.chunk.code)); + disassembleInstruction(vm.chunk, vm.ip - vm.chunk.code.ptr); printf(" "); foreach(slot; stack.live){ printf(""); @@ -93,6 +102,14 @@ struct VM{ case OpCode.False: stack.push(Value.from(false)); break; case OpCode.Pop: stack.pop(); break; + case OpCode.GetLocal: + long slot = readVarUint(); + stack.push(stack[slot]); + break; + case OpCode.SetLocal: + long slot = readVarUint(); + stack[slot] = peek(0); + break; case OpCode.GetGlobal: Obj.String* name = readString(); Value value; diff --git a/test/biglocals.lox b/test/biglocals.lox new file mode 100644 index 0000000..059e417 --- /dev/null +++ b/test/biglocals.lox @@ -0,0 +1,507 @@ + +var sum = 0; +{ +var v1 = 1; sum = sum + v1; +var v2 = 2; sum = sum + v2; +var v3 = 3; sum = sum + v3; +var v4 = 4; sum = sum + v4; +var v5 = 5; sum = sum + v5; +var v6 = 6; sum = sum + v6; +var v7 = 7; sum = sum + v7; +var v8 = 8; sum = sum + v8; +var v9 = 9; sum = sum + v9; +var v10 = 10; sum = sum + v10; +var v11 = 11; sum = sum + v11; +var v12 = 12; sum = sum + v12; +var v13 = 13; sum = sum + v13; +var v14 = 14; sum = sum + v14; +var v15 = 15; sum = sum + v15; +var v16 = 16; sum = sum + v16; +var v17 = 17; sum = sum + v17; +var v18 = 18; sum = sum + v18; +var v19 = 19; sum = sum + v19; +var v20 = 20; sum = sum + v20; +var v21 = 21; sum = sum + v21; +var v22 = 22; sum = sum + v22; +var v23 = 23; sum = sum + v23; +var v24 = 24; sum = sum + v24; +var v25 = 25; sum = sum + v25; +var v26 = 26; sum = sum + v26; +var v27 = 27; sum = sum + v27; +var v28 = 28; sum = sum + v28; +var v29 = 29; sum = sum + v29; +var v30 = 30; sum = sum + v30; +var v31 = 31; sum = sum + v31; +var v32 = 32; sum = sum + v32; +var v33 = 33; sum = sum + v33; +var v34 = 34; sum = sum + v34; +var v35 = 35; sum = sum + v35; +var v36 = 36; sum = sum + v36; +var v37 = 37; sum = sum + v37; +var v38 = 38; sum = sum + v38; +var v39 = 39; sum = sum + v39; +var v40 = 40; sum = sum + v40; +var v41 = 41; sum = sum + v41; +var v42 = 42; sum = sum + v42; +var v43 = 43; sum = sum + v43; +var v44 = 44; sum = sum + v44; +var v45 = 45; sum = sum + v45; +var v46 = 46; sum = sum + v46; +var v47 = 47; sum = sum + v47; +var v48 = 48; sum = sum + v48; +var v49 = 49; sum = sum + v49; +var v50 = 50; sum = sum + v50; +var v51 = 51; sum = sum + v51; +var v52 = 52; sum = sum + v52; +var v53 = 53; sum = sum + v53; +var v54 = 54; sum = sum + v54; +var v55 = 55; sum = sum + v55; +var v56 = 56; sum = sum + v56; +var v57 = 57; sum = sum + v57; +var v58 = 58; sum = sum + v58; +var v59 = 59; sum = sum + v59; +var v60 = 60; sum = sum + v60; +var v61 = 61; sum = sum + v61; +var v62 = 62; sum = sum + v62; +var v63 = 63; sum = sum + v63; +var v64 = 64; sum = sum + v64; +var v65 = 65; sum = sum + v65; +var v66 = 66; sum = sum + v66; +var v67 = 67; sum = sum + v67; +var v68 = 68; sum = sum + v68; +var v69 = 69; sum = sum + v69; +var v70 = 70; sum = sum + v70; +var v71 = 71; sum = sum + v71; +var v72 = 72; sum = sum + v72; +var v73 = 73; sum = sum + v73; +var v74 = 74; sum = sum + v74; +var v75 = 75; sum = sum + v75; +var v76 = 76; sum = sum + v76; +var v77 = 77; sum = sum + v77; +var v78 = 78; sum = sum + v78; +var v79 = 79; sum = sum + v79; +var v80 = 80; sum = sum + v80; +var v81 = 81; sum = sum + v81; +var v82 = 82; sum = sum + v82; +var v83 = 83; sum = sum + v83; +var v84 = 84; sum = sum + v84; +var v85 = 85; sum = sum + v85; +var v86 = 86; sum = sum + v86; +var v87 = 87; sum = sum + v87; +var v88 = 88; sum = sum + v88; +var v89 = 89; sum = sum + v89; +var v90 = 90; sum = sum + v90; +var v91 = 91; sum = sum + v91; +var v92 = 92; sum = sum + v92; +var v93 = 93; sum = sum + v93; +var v94 = 94; sum = sum + v94; +var v95 = 95; sum = sum + v95; +var v96 = 96; sum = sum + v96; +var v97 = 97; sum = sum + v97; +var v98 = 98; sum = sum + v98; +var v99 = 99; sum = sum + v99; +var v100 = 100; sum = sum + v100; +var v101 = 101; sum = sum + v101; +var v102 = 102; sum = sum + v102; +var v103 = 103; sum = sum + v103; +var v104 = 104; sum = sum + v104; +var v105 = 105; sum = sum + v105; +var v106 = 106; sum = sum + v106; +var v107 = 107; sum = sum + v107; +var v108 = 108; sum = sum + v108; +var v109 = 109; sum = sum + v109; +var v110 = 110; sum = sum + v110; +var v111 = 111; sum = sum + v111; +var v112 = 112; sum = sum + v112; +var v113 = 113; sum = sum + v113; +var v114 = 114; sum = sum + v114; +var v115 = 115; sum = sum + v115; +var v116 = 116; sum = sum + v116; +var v117 = 117; sum = sum + v117; +var v118 = 118; sum = sum + v118; +var v119 = 119; sum = sum + v119; +var v120 = 120; sum = sum + v120; +var v121 = 121; sum = sum + v121; +var v122 = 122; sum = sum + v122; +var v123 = 123; sum = sum + v123; +var v124 = 124; sum = sum + v124; +var v125 = 125; sum = sum + v125; +var v126 = 126; sum = sum + v126; +var v127 = 127; sum = sum + v127; +var v128 = 128; sum = sum + v128; +var v129 = 129; sum = sum + v129; +var v130 = 130; sum = sum + v130; +var v131 = 131; sum = sum + v131; +var v132 = 132; sum = sum + v132; +var v133 = 133; sum = sum + v133; +var v134 = 134; sum = sum + v134; +var v135 = 135; sum = sum + v135; +var v136 = 136; sum = sum + v136; +var v137 = 137; sum = sum + v137; +var v138 = 138; sum = sum + v138; +var v139 = 139; sum = sum + v139; +var v140 = 140; sum = sum + v140; +var v141 = 141; sum = sum + v141; +var v142 = 142; sum = sum + v142; +var v143 = 143; sum = sum + v143; +var v144 = 144; sum = sum + v144; +var v145 = 145; sum = sum + v145; +var v146 = 146; sum = sum + v146; +var v147 = 147; sum = sum + v147; +var v148 = 148; sum = sum + v148; +var v149 = 149; sum = sum + v149; +var v150 = 150; sum = sum + v150; +var v151 = 151; sum = sum + v151; +var v152 = 152; sum = sum + v152; +var v153 = 153; sum = sum + v153; +var v154 = 154; sum = sum + v154; +var v155 = 155; sum = sum + v155; +var v156 = 156; sum = sum + v156; +var v157 = 157; sum = sum + v157; +var v158 = 158; sum = sum + v158; +var v159 = 159; sum = sum + v159; +var v160 = 160; sum = sum + v160; +var v161 = 161; sum = sum + v161; +var v162 = 162; sum = sum + v162; +var v163 = 163; sum = sum + v163; +var v164 = 164; sum = sum + v164; +var v165 = 165; sum = sum + v165; +var v166 = 166; sum = sum + v166; +var v167 = 167; sum = sum + v167; +var v168 = 168; sum = sum + v168; +var v169 = 169; sum = sum + v169; +var v170 = 170; sum = sum + v170; +var v171 = 171; sum = sum + v171; +var v172 = 172; sum = sum + v172; +var v173 = 173; sum = sum + v173; +var v174 = 174; sum = sum + v174; +var v175 = 175; sum = sum + v175; +var v176 = 176; sum = sum + v176; +var v177 = 177; sum = sum + v177; +var v178 = 178; sum = sum + v178; +var v179 = 179; sum = sum + v179; +var v180 = 180; sum = sum + v180; +var v181 = 181; sum = sum + v181; +var v182 = 182; sum = sum + v182; +var v183 = 183; sum = sum + v183; +var v184 = 184; sum = sum + v184; +var v185 = 185; sum = sum + v185; +var v186 = 186; sum = sum + v186; +var v187 = 187; sum = sum + v187; +var v188 = 188; sum = sum + v188; +var v189 = 189; sum = sum + v189; +var v190 = 190; sum = sum + v190; +var v191 = 191; sum = sum + v191; +var v192 = 192; sum = sum + v192; +var v193 = 193; sum = sum + v193; +var v194 = 194; sum = sum + v194; +var v195 = 195; sum = sum + v195; +var v196 = 196; sum = sum + v196; +var v197 = 197; sum = sum + v197; +var v198 = 198; sum = sum + v198; +var v199 = 199; sum = sum + v199; +var v200 = 200; sum = sum + v200; +var v201 = 201; sum = sum + v201; +var v202 = 202; sum = sum + v202; +var v203 = 203; sum = sum + v203; +var v204 = 204; sum = sum + v204; +var v205 = 205; sum = sum + v205; +var v206 = 206; sum = sum + v206; +var v207 = 207; sum = sum + v207; +var v208 = 208; sum = sum + v208; +var v209 = 209; sum = sum + v209; +var v210 = 210; sum = sum + v210; +var v211 = 211; sum = sum + v211; +var v212 = 212; sum = sum + v212; +var v213 = 213; sum = sum + v213; +var v214 = 214; sum = sum + v214; +var v215 = 215; sum = sum + v215; +var v216 = 216; sum = sum + v216; +var v217 = 217; sum = sum + v217; +var v218 = 218; sum = sum + v218; +var v219 = 219; sum = sum + v219; +var v220 = 220; sum = sum + v220; +var v221 = 221; sum = sum + v221; +var v222 = 222; sum = sum + v222; +var v223 = 223; sum = sum + v223; +var v224 = 224; sum = sum + v224; +var v225 = 225; sum = sum + v225; +var v226 = 226; sum = sum + v226; +var v227 = 227; sum = sum + v227; +var v228 = 228; sum = sum + v228; +var v229 = 229; sum = sum + v229; +var v230 = 230; sum = sum + v230; +var v231 = 231; sum = sum + v231; +var v232 = 232; sum = sum + v232; +var v233 = 233; sum = sum + v233; +var v234 = 234; sum = sum + v234; +var v235 = 235; sum = sum + v235; +var v236 = 236; sum = sum + v236; +var v237 = 237; sum = sum + v237; +var v238 = 238; sum = sum + v238; +var v239 = 239; sum = sum + v239; +var v240 = 240; sum = sum + v240; +var v241 = 241; sum = sum + v241; +var v242 = 242; sum = sum + v242; +var v243 = 243; sum = sum + v243; +var v244 = 244; sum = sum + v244; +var v245 = 245; sum = sum + v245; +var v246 = 246; sum = sum + v246; +var v247 = 247; sum = sum + v247; +var v248 = 248; sum = sum + v248; +var v249 = 249; sum = sum + v249; +var v250 = 250; sum = sum + v250; +var v251 = 251; sum = sum + v251; +var v252 = 252; sum = sum + v252; +var v253 = 253; sum = sum + v253; +var v254 = 254; sum = sum + v254; +var v255 = 255; sum = sum + v255; +var v256 = 256; sum = sum + v256; +var v257 = 257; sum = sum + v257; +var v258 = 258; sum = sum + v258; +var v259 = 259; sum = sum + v259; +var v260 = 260; sum = sum + v260; +var v261 = 261; sum = sum + v261; +var v262 = 262; sum = sum + v262; +var v263 = 263; sum = sum + v263; +var v264 = 264; sum = sum + v264; +var v265 = 265; sum = sum + v265; +var v266 = 266; sum = sum + v266; +var v267 = 267; sum = sum + v267; +var v268 = 268; sum = sum + v268; +var v269 = 269; sum = sum + v269; +var v270 = 270; sum = sum + v270; +var v271 = 271; sum = sum + v271; +var v272 = 272; sum = sum + v272; +var v273 = 273; sum = sum + v273; +var v274 = 274; sum = sum + v274; +var v275 = 275; sum = sum + v275; +var v276 = 276; sum = sum + v276; +var v277 = 277; sum = sum + v277; +var v278 = 278; sum = sum + v278; +var v279 = 279; sum = sum + v279; +var v280 = 280; sum = sum + v280; +var v281 = 281; sum = sum + v281; +var v282 = 282; sum = sum + v282; +var v283 = 283; sum = sum + v283; +var v284 = 284; sum = sum + v284; +var v285 = 285; sum = sum + v285; +var v286 = 286; sum = sum + v286; +var v287 = 287; sum = sum + v287; +var v288 = 288; sum = sum + v288; +var v289 = 289; sum = sum + v289; +var v290 = 290; sum = sum + v290; +var v291 = 291; sum = sum + v291; +var v292 = 292; sum = sum + v292; +var v293 = 293; sum = sum + v293; +var v294 = 294; sum = sum + v294; +var v295 = 295; sum = sum + v295; +var v296 = 296; sum = sum + v296; +var v297 = 297; sum = sum + v297; +var v298 = 298; sum = sum + v298; +var v299 = 299; sum = sum + v299; +var v300 = 300; sum = sum + v300; +var v301 = 301; sum = sum + v301; +var v302 = 302; sum = sum + v302; +var v303 = 303; sum = sum + v303; +var v304 = 304; sum = sum + v304; +var v305 = 305; sum = sum + v305; +var v306 = 306; sum = sum + v306; +var v307 = 307; sum = sum + v307; +var v308 = 308; sum = sum + v308; +var v309 = 309; sum = sum + v309; +var v310 = 310; sum = sum + v310; +var v311 = 311; sum = sum + v311; +var v312 = 312; sum = sum + v312; +var v313 = 313; sum = sum + v313; +var v314 = 314; sum = sum + v314; +var v315 = 315; sum = sum + v315; +var v316 = 316; sum = sum + v316; +var v317 = 317; sum = sum + v317; +var v318 = 318; sum = sum + v318; +var v319 = 319; sum = sum + v319; +var v320 = 320; sum = sum + v320; +var v321 = 321; sum = sum + v321; +var v322 = 322; sum = sum + v322; +var v323 = 323; sum = sum + v323; +var v324 = 324; sum = sum + v324; +var v325 = 325; sum = sum + v325; +var v326 = 326; sum = sum + v326; +var v327 = 327; sum = sum + v327; +var v328 = 328; sum = sum + v328; +var v329 = 329; sum = sum + v329; +var v330 = 330; sum = sum + v330; +var v331 = 331; sum = sum + v331; +var v332 = 332; sum = sum + v332; +var v333 = 333; sum = sum + v333; +var v334 = 334; sum = sum + v334; +var v335 = 335; sum = sum + v335; +var v336 = 336; sum = sum + v336; +var v337 = 337; sum = sum + v337; +var v338 = 338; sum = sum + v338; +var v339 = 339; sum = sum + v339; +var v340 = 340; sum = sum + v340; +var v341 = 341; sum = sum + v341; +var v342 = 342; sum = sum + v342; +var v343 = 343; sum = sum + v343; +var v344 = 344; sum = sum + v344; +var v345 = 345; sum = sum + v345; +var v346 = 346; sum = sum + v346; +var v347 = 347; sum = sum + v347; +var v348 = 348; sum = sum + v348; +var v349 = 349; sum = sum + v349; +var v350 = 350; sum = sum + v350; +var v351 = 351; sum = sum + v351; +var v352 = 352; sum = sum + v352; +var v353 = 353; sum = sum + v353; +var v354 = 354; sum = sum + v354; +var v355 = 355; sum = sum + v355; +var v356 = 356; sum = sum + v356; +var v357 = 357; sum = sum + v357; +var v358 = 358; sum = sum + v358; +var v359 = 359; sum = sum + v359; +var v360 = 360; sum = sum + v360; +var v361 = 361; sum = sum + v361; +var v362 = 362; sum = sum + v362; +var v363 = 363; sum = sum + v363; +var v364 = 364; sum = sum + v364; +var v365 = 365; sum = sum + v365; +var v366 = 366; sum = sum + v366; +var v367 = 367; sum = sum + v367; +var v368 = 368; sum = sum + v368; +var v369 = 369; sum = sum + v369; +var v370 = 370; sum = sum + v370; +var v371 = 371; sum = sum + v371; +var v372 = 372; sum = sum + v372; +var v373 = 373; sum = sum + v373; +var v374 = 374; sum = sum + v374; +var v375 = 375; sum = sum + v375; +var v376 = 376; sum = sum + v376; +var v377 = 377; sum = sum + v377; +var v378 = 378; sum = sum + v378; +var v379 = 379; sum = sum + v379; +var v380 = 380; sum = sum + v380; +var v381 = 381; sum = sum + v381; +var v382 = 382; sum = sum + v382; +var v383 = 383; sum = sum + v383; +var v384 = 384; sum = sum + v384; +var v385 = 385; sum = sum + v385; +var v386 = 386; sum = sum + v386; +var v387 = 387; sum = sum + v387; +var v388 = 388; sum = sum + v388; +var v389 = 389; sum = sum + v389; +var v390 = 390; sum = sum + v390; +var v391 = 391; sum = sum + v391; +var v392 = 392; sum = sum + v392; +var v393 = 393; sum = sum + v393; +var v394 = 394; sum = sum + v394; +var v395 = 395; sum = sum + v395; +var v396 = 396; sum = sum + v396; +var v397 = 397; sum = sum + v397; +var v398 = 398; sum = sum + v398; +var v399 = 399; sum = sum + v399; +var v400 = 400; sum = sum + v400; +var v401 = 401; sum = sum + v401; +var v402 = 402; sum = sum + v402; +var v403 = 403; sum = sum + v403; +var v404 = 404; sum = sum + v404; +var v405 = 405; sum = sum + v405; +var v406 = 406; sum = sum + v406; +var v407 = 407; sum = sum + v407; +var v408 = 408; sum = sum + v408; +var v409 = 409; sum = sum + v409; +var v410 = 410; sum = sum + v410; +var v411 = 411; sum = sum + v411; +var v412 = 412; sum = sum + v412; +var v413 = 413; sum = sum + v413; +var v414 = 414; sum = sum + v414; +var v415 = 415; sum = sum + v415; +var v416 = 416; sum = sum + v416; +var v417 = 417; sum = sum + v417; +var v418 = 418; sum = sum + v418; +var v419 = 419; sum = sum + v419; +var v420 = 420; sum = sum + v420; +var v421 = 421; sum = sum + v421; +var v422 = 422; sum = sum + v422; +var v423 = 423; sum = sum + v423; +var v424 = 424; sum = sum + v424; +var v425 = 425; sum = sum + v425; +var v426 = 426; sum = sum + v426; +var v427 = 427; sum = sum + v427; +var v428 = 428; sum = sum + v428; +var v429 = 429; sum = sum + v429; +var v430 = 430; sum = sum + v430; +var v431 = 431; sum = sum + v431; +var v432 = 432; sum = sum + v432; +var v433 = 433; sum = sum + v433; +var v434 = 434; sum = sum + v434; +var v435 = 435; sum = sum + v435; +var v436 = 436; sum = sum + v436; +var v437 = 437; sum = sum + v437; +var v438 = 438; sum = sum + v438; +var v439 = 439; sum = sum + v439; +var v440 = 440; sum = sum + v440; +var v441 = 441; sum = sum + v441; +var v442 = 442; sum = sum + v442; +var v443 = 443; sum = sum + v443; +var v444 = 444; sum = sum + v444; +var v445 = 445; sum = sum + v445; +var v446 = 446; sum = sum + v446; +var v447 = 447; sum = sum + v447; +var v448 = 448; sum = sum + v448; +var v449 = 449; sum = sum + v449; +var v450 = 450; sum = sum + v450; +var v451 = 451; sum = sum + v451; +var v452 = 452; sum = sum + v452; +var v453 = 453; sum = sum + v453; +var v454 = 454; sum = sum + v454; +var v455 = 455; sum = sum + v455; +var v456 = 456; sum = sum + v456; +var v457 = 457; sum = sum + v457; +var v458 = 458; sum = sum + v458; +var v459 = 459; sum = sum + v459; +var v460 = 460; sum = sum + v460; +var v461 = 461; sum = sum + v461; +var v462 = 462; sum = sum + v462; +var v463 = 463; sum = sum + v463; +var v464 = 464; sum = sum + v464; +var v465 = 465; sum = sum + v465; +var v466 = 466; sum = sum + v466; +var v467 = 467; sum = sum + v467; +var v468 = 468; sum = sum + v468; +var v469 = 469; sum = sum + v469; +var v470 = 470; sum = sum + v470; +var v471 = 471; sum = sum + v471; +var v472 = 472; sum = sum + v472; +var v473 = 473; sum = sum + v473; +var v474 = 474; sum = sum + v474; +var v475 = 475; sum = sum + v475; +var v476 = 476; sum = sum + v476; +var v477 = 477; sum = sum + v477; +var v478 = 478; sum = sum + v478; +var v479 = 479; sum = sum + v479; +var v480 = 480; sum = sum + v480; +var v481 = 481; sum = sum + v481; +var v482 = 482; sum = sum + v482; +var v483 = 483; sum = sum + v483; +var v484 = 484; sum = sum + v484; +var v485 = 485; sum = sum + v485; +var v486 = 486; sum = sum + v486; +var v487 = 487; sum = sum + v487; +var v488 = 488; sum = sum + v488; +var v489 = 489; sum = sum + v489; +var v490 = 490; sum = sum + v490; +var v491 = 491; sum = sum + v491; +var v492 = 492; sum = sum + v492; +var v493 = 493; sum = sum + v493; +var v494 = 494; sum = sum + v494; +var v495 = 495; sum = sum + v495; +var v496 = 496; sum = sum + v496; +var v497 = 497; sum = sum + v497; +var v498 = 498; sum = sum + v498; +var v499 = 499; sum = sum + v499; +var v500 = 500; sum = sum + v500; +} + +print sum; + diff --git a/test/bigsum.lox b/test/bigsum.lox new file mode 100644 index 0000000..f264d53 --- /dev/null +++ b/test/bigsum.lox @@ -0,0 +1,503 @@ + var x = 0 + 1 + + 2 + + 3 + + 4 + + 5 + + 6 + + 7 + + 8 + + 9 + + 10 + + 11 + + 12 + + 13 + + 14 + + 15 + + 16 + + 17 + + 18 + + 19 + + 20 + + 21 + + 22 + + 23 + + 24 + + 25 + + 26 + + 27 + + 28 + + 29 + + 30 + + 31 + + 32 + + 33 + + 34 + + 35 + + 36 + + 37 + + 38 + + 39 + + 40 + + 41 + + 42 + + 43 + + 44 + + 45 + + 46 + + 47 + + 48 + + 49 + + 50 + + 51 + + 52 + + 53 + + 54 + + 55 + + 56 + + 57 + + 58 + + 59 + + 60 + + 61 + + 62 + + 63 + + 64 + + 65 + + 66 + + 67 + + 68 + + 69 + + 70 + + 71 + + 72 + + 73 + + 74 + + 75 + + 76 + + 77 + + 78 + + 79 + + 80 + + 81 + + 82 + + 83 + + 84 + + 85 + + 86 + + 87 + + 88 + + 89 + + 90 + + 91 + + 92 + + 93 + + 94 + + 95 + + 96 + + 97 + + 98 + + 99 + + 100 + + 101 + + 102 + + 103 + + 104 + + 105 + + 106 + + 107 + + 108 + + 109 + + 110 + + 111 + + 112 + + 113 + + 114 + + 115 + + 116 + + 117 + + 118 + + 119 + + 120 + + 121 + + 122 + + 123 + + 124 + + 125 + + 126 + + 127 + + 128 + + 129 + + 130 + + 131 + + 132 + + 133 + + 134 + + 135 + + 136 + + 137 + + 138 + + 139 + + 140 + + 141 + + 142 + + 143 + + 144 + + 145 + + 146 + + 147 + + 148 + + 149 + + 150 + + 151 + + 152 + + 153 + + 154 + + 155 + + 156 + + 157 + + 158 + + 159 + + 160 + + 161 + + 162 + + 163 + + 164 + + 165 + + 166 + + 167 + + 168 + + 169 + + 170 + + 171 + + 172 + + 173 + + 174 + + 175 + + 176 + + 177 + + 178 + + 179 + + 180 + + 181 + + 182 + + 183 + + 184 + + 185 + + 186 + + 187 + + 188 + + 189 + + 190 + + 191 + + 192 + + 193 + + 194 + + 195 + + 196 + + 197 + + 198 + + 199 + + 200 + + 201 + + 202 + + 203 + + 204 + + 205 + + 206 + + 207 + + 208 + + 209 + + 210 + + 211 + + 212 + + 213 + + 214 + + 215 + + 216 + + 217 + + 218 + + 219 + + 220 + + 221 + + 222 + + 223 + + 224 + + 225 + + 226 + + 227 + + 228 + + 229 + + 230 + + 231 + + 232 + + 233 + + 234 + + 235 + + 236 + + 237 + + 238 + + 239 + + 240 + + 241 + + 242 + + 243 + + 244 + + 245 + + 246 + + 247 + + 248 + + 249 + + 250 + + 251 + + 252 + + 253 + + 254 + + 255 + + 256 + + 257 + + 258 + + 259 + + 260 + + 261 + + 262 + + 263 + + 264 + + 265 + + 266 + + 267 + + 268 + + 269 + + 270 + + 271 + + 272 + + 273 + + 274 + + 275 + + 276 + + 277 + + 278 + + 279 + + 280 + + 281 + + 282 + + 283 + + 284 + + 285 + + 286 + + 287 + + 288 + + 289 + + 290 + + 291 + + 292 + + 293 + + 294 + + 295 + + 296 + + 297 + + 298 + + 299 + + 300 + + 301 + + 302 + + 303 + + 304 + + 305 + + 306 + + 307 + + 308 + + 309 + + 310 + + 311 + + 312 + + 313 + + 314 + + 315 + + 316 + + 317 + + 318 + + 319 + + 320 + + 321 + + 322 + + 323 + + 324 + + 325 + + 326 + + 327 + + 328 + + 329 + + 330 + + 331 + + 332 + + 333 + + 334 + + 335 + + 336 + + 337 + + 338 + + 339 + + 340 + + 341 + + 342 + + 343 + + 344 + + 345 + + 346 + + 347 + + 348 + + 349 + + 350 + + 351 + + 352 + + 353 + + 354 + + 355 + + 356 + + 357 + + 358 + + 359 + + 360 + + 361 + + 362 + + 363 + + 364 + + 365 + + 366 + + 367 + + 368 + + 369 + + 370 + + 371 + + 372 + + 373 + + 374 + + 375 + + 376 + + 377 + + 378 + + 379 + + 380 + + 381 + + 382 + + 383 + + 384 + + 385 + + 386 + + 387 + + 388 + + 389 + + 390 + + 391 + + 392 + + 393 + + 394 + + 395 + + 396 + + 397 + + 398 + + 399 + + 400 + + 401 + + 402 + + 403 + + 404 + + 405 + + 406 + + 407 + + 408 + + 409 + + 410 + + 411 + + 412 + + 413 + + 414 + + 415 + + 416 + + 417 + + 418 + + 419 + + 420 + + 421 + + 422 + + 423 + + 424 + + 425 + + 426 + + 427 + + 428 + + 429 + + 430 + + 431 + + 432 + + 433 + + 434 + + 435 + + 436 + + 437 + + 438 + + 439 + + 440 + + 441 + + 442 + + 443 + + 444 + + 445 + + 446 + + 447 + + 448 + + 449 + + 450 + + 451 + + 452 + + 453 + + 454 + + 455 + + 456 + + 457 + + 458 + + 459 + + 460 + + 461 + + 462 + + 463 + + 464 + + 465 + + 466 + + 467 + + 468 + + 469 + + 470 + + 471 + + 472 + + 473 + + 474 + + 475 + + 476 + + 477 + + 478 + + 479 + + 480 + + 481 + + 482 + + 483 + + 484 + + 485 + + 486 + + 487 + + 488 + + 489 + + 490 + + 491 + + 492 + + 493 + + 494 + + 495 + + 496 + + 497 + + 498 + + 499 + + 500; + +print x; + diff --git a/test/simplescope.lox b/test/simplescope.lox new file mode 100644 index 0000000..f44e107 --- /dev/null +++ b/test/simplescope.lox @@ -0,0 +1,12 @@ + +var a = "a"; +{ + var b = "b"; + { + var c = "c"; + print a + b + c; + } + var d = "d"; + print a + b + d; +} + From 98e7f950cf4cbb09f360237b0f2edaa4592bbdd8 Mon Sep 17 00:00:00 2001 From: nazrin Date: Sat, 7 Jun 2025 23:57:45 +0000 Subject: [PATCH 2/2] Change `stack.push(v)` to `stack ~= v` --- src/clox/container/stack.d | 2 +- src/clox/vm.d | 24 +++++++++++------------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/src/clox/container/stack.d b/src/clox/container/stack.d index 7fb88aa..6ac7551 100644 --- a/src/clox/container/stack.d +++ b/src/clox/container/stack.d @@ -9,7 +9,7 @@ struct Stack(T){ data.initialise(); top = data.ptr; } - void push(T value){ + void opOpAssign(string op: "~")(T value){ data ~= value; top = data.ptr + data.count; } diff --git a/src/clox/vm.d b/src/clox/vm.d index 6290e2d..bb08094 100644 --- a/src/clox/vm.d +++ b/src/clox/vm.d @@ -63,9 +63,7 @@ struct VM{ ip += vi.len; return vi.i; } - Value readConstant(){ - return chunk.constants[readVarUint()]; - } + Value readConstant() => chunk.constants[readVarUint()]; Obj.String* readString() => readConstant().asObj.asString; Value peek(int distance = 0) => stack.top[-1 - distance]; bool checkBinaryType(alias type)() => peek(0).isType(type) && peek(1).isType(type); @@ -77,7 +75,7 @@ struct VM{ } auto b = stack.pop().as!pre; auto a = stack.pop().as!pre; - stack.push(Value.from(mixin("a", op, "b"))); + stack ~= Value.from(mixin("a", op, "b")); return 0; } while(true){ @@ -95,16 +93,16 @@ struct VM{ opSwitch: final switch(instruction = cast(OpCode)readByte()){ case OpCode.Constant: Value constant = readConstant(); - stack.push(constant); + stack ~= constant; break; - case OpCode.Nil: stack.push(Value.nil); break; - case OpCode.True: stack.push(Value.from(true)); break; - case OpCode.False: stack.push(Value.from(false)); break; + case OpCode.Nil: stack ~= Value.nil; break; + case OpCode.True: stack ~= Value.from(true); break; + case OpCode.False: stack ~= Value.from(false); break; case OpCode.Pop: stack.pop(); break; case OpCode.GetLocal: long slot = readVarUint(); - stack.push(stack[slot]); + stack ~= stack[slot]; break; case OpCode.SetLocal: long slot = readVarUint(); @@ -117,7 +115,7 @@ struct VM{ runtimeError("Undefined variable '%s'.", name.chars.ptr); return InterpretResult.RuntimeError; } - stack.push(value); + stack ~= value; break; case OpCode.DefineGlobal: Obj.String* name = readString(); @@ -152,7 +150,7 @@ struct VM{ Obj.String* b = stack.pop().asObj.asString; Obj.String* a = stack.pop().asObj.asString; Obj.String* result = Obj.String.concat(a, b); - stack.push(Value.from(result)); + stack ~= Value.from(result); break opSwitch; } } @@ -162,14 +160,14 @@ struct VM{ } case OpCode.Not: - stack.push(Value.from(stack.pop().isFalsey)); + stack ~= Value.from(stack.pop().isFalsey); break; case OpCode.Negate: if(!peek(0).isType(Value.Type.Number)){ runtimeError("Operand must be a number."); return InterpretResult.RuntimeError; } - stack.push(Value.from(-stack.pop().asNumber)); + stack ~= Value.from(-stack.pop().asNumber); break; case OpCode.Print: stack.pop().print();