WIP closures + important bugfix
This commit is contained in:
parent
3e48b1cc52
commit
9b3b1056ba
|
@ -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,
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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()
|
||||
|
|
Loading…
Reference in New Issue