From 9b3b1056bac7d79da94283e35d51fceaa8b63327 Mon Sep 17 00:00:00 2001 From: prod2 <95874442+prod2@users.noreply.github.com> Date: Sat, 5 Feb 2022 12:37:54 +0100 Subject: [PATCH] WIP closures + important bugfix --- src/ndspkg/chunk.nim | 2 ++ src/ndspkg/compiler.nim | 8 ++++---- src/ndspkg/types/closure.nim | 8 ++++---- src/ndspkg/vm.nim | 8 ++++++-- 4 files changed, 16 insertions(+), 10 deletions(-) diff --git a/src/ndspkg/chunk.nim b/src/ndspkg/chunk.nim index 5e69927..95ab44c 100644 --- a/src/ndspkg/chunk.nim +++ b/src/ndspkg/chunk.nim @@ -15,6 +15,7 @@ type opConstant, # constant opDefineGlobal, opGetGlobal, opSetGlobal, # globals (uses constants) opGetLocal, opSetLocal, # locals + opGetUpvalue, opSetUpvalue, # upvalues opJumpIfFalse, opJump, opLoop, opJumpIfFalsePop, # jumps opCreateList, opCreateTable, # collection creation opLen, opSetIndex, opGetIndex, # collection operators @@ -114,6 +115,7 @@ const argInstructions = { opJumpIfFalse, opJump, opLoop, opJumpIfFalsePop, opFunctionDef, opClosure, opCreateList, opCreateTable, + opGetUpvalue, opSetUpvalue, } diff --git a/src/ndspkg/compiler.nim b/src/ndspkg/compiler.nim index 2c6fe3f..9ab7ac9 100644 --- a/src/ndspkg/compiler.nim +++ b/src/ndspkg/compiler.nim @@ -71,7 +71,7 @@ proc newScope(comp: Compiler, function: bool): Scope = result.goalStackIndex = comp.stackIndex + 1 if function: result.parentFunction = result - elif comp.scopes[comp.scopes.high()].parentFunction != nil: + elif comp.scopes.len() > 0 and comp.scopes[comp.scopes.high()].parentFunction != nil: result.parentFunction = comp.scopes[comp.scopes.high()].parentFunction comp.scopes.add(result) @@ -399,13 +399,13 @@ proc addUpvalue(comp: Compiler, index: int): int = ## have the right upvalue in them (compile time) discard -proc resolveLocal(comp: Compiler, name: string): Tuple[int, bool] = +proc resolveLocal(comp: Compiler, name: string): tuple[index: int, upvalue: bool] = ## the bool arg specifies whether it found an upvalue ## if it's a local: returns the stack index of the local of the name ## if it's an upvalue: returns the upvalue index ## if the number is -1, then the name cannot be resolved at compile time var i = comp.locals.high - let cfunc = comp.scopes[comp.scopes.high()].parentFunction + let cfunc: Scope = if comp.scopes.len() > 0: comp.scopes[comp.scopes.high()].parentFunction else: nil while i >= 0: let local = comp.locals[i] if local.name == name: @@ -417,7 +417,7 @@ proc resolveLocal(comp: Compiler, name: string): Tuple[int, bool] = else: return (comp.addUpvalue(i), true) i.dec - return -1 + return (index: -1, upvalue: false) proc variable(comp: Compiler) = # named variable diff --git a/src/ndspkg/types/closure.nim b/src/ndspkg/types/closure.nim index acc5797..1d1b2c1 100644 --- a/src/ndspkg/types/closure.nim +++ b/src/ndspkg/types/closure.nim @@ -2,19 +2,19 @@ type UpvalueObj[T] = object location: ptr T - Upvalue[T]* = ptr UpvalueObj[T] + Upvalue*[T] = ptr UpvalueObj[T] ClosureObj[T] = object start: ptr uint8 upvalueCount: int upvalues: UncheckedArray[Upvalue[T]] - Closure[T]* = ptr ClosureObj[T] + Closure*[T] = ptr ClosureObj[T] -proc newClosure[T]*(start: ptr uint8, upvalueCount: int): Closure[T] = +proc newClosure*[T](start: ptr uint8, upvalueCount: int): Closure[T] = result = cast[Closure[T]](alloc0(8 * upvalueCount + sizeof(ClosureObj[T]))) result.start = start result.upvalueCount = upvalueCount -proc getIp*(clos: Closure): ptr uint8 {.inline.} = +proc getIp*[T](clos: Closure[T]): ptr uint8 {.inline.} = clos.start \ No newline at end of file diff --git a/src/ndspkg/vm.nim b/src/ndspkg/vm.nim index 646b15f..23d9140 100644 --- a/src/ndspkg/vm.nim +++ b/src/ndspkg/vm.nim @@ -197,6 +197,10 @@ proc run*(chunk: Chunk): InterpretResult = of opSetLocal: let slot = readDU8() stack[slot + frameBottom] = stack.peek() + of opGetUpvalue: + discard + of opSetUpvalue: + discard of opJumpIfFalse: let offset = readDU8() if stack.peek().isFalsey(): @@ -220,7 +224,7 @@ proc run*(chunk: Chunk): InterpretResult = let offset = readDU8() let faddr: ptr uint8 = ip ip = ip.padd(offset) - stack.push(newClosure(faddr).fromClosure()) + stack.push(newClosure[NdValue](faddr, 0).fromClosure()) of opCheckArity: let arity = readUI8() let argcount = stack.high() - frameBottom @@ -259,7 +263,7 @@ proc run*(chunk: Chunk): InterpretResult = if tbl[].tableSet(key, val): runtimeError("Attempt to redefine an existing value inside table declaration.") break - stack.deleteTopN(tblLen * 2) + # stack.deleteTopN(tblLen * 2) # THIS IS NOT NEEDED, pops are done stack.push(tbl.fromTable()) of opLen: let res = stack.peek().getLength()