WIP closures + important bugfix

This commit is contained in:
prod2 2022-02-05 12:37:54 +01:00
parent 3e48b1cc52
commit 9b3b1056ba
4 changed files with 16 additions and 10 deletions

View File

@ -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,
}

View File

@ -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

View File

@ -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

View File

@ -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()