WIP closures + important bugfix
This commit is contained in:
parent
3e48b1cc52
commit
9b3b1056ba
|
@ -15,6 +15,7 @@ type
|
||||||
opConstant, # constant
|
opConstant, # constant
|
||||||
opDefineGlobal, opGetGlobal, opSetGlobal, # globals (uses constants)
|
opDefineGlobal, opGetGlobal, opSetGlobal, # globals (uses constants)
|
||||||
opGetLocal, opSetLocal, # locals
|
opGetLocal, opSetLocal, # locals
|
||||||
|
opGetUpvalue, opSetUpvalue, # upvalues
|
||||||
opJumpIfFalse, opJump, opLoop, opJumpIfFalsePop, # jumps
|
opJumpIfFalse, opJump, opLoop, opJumpIfFalsePop, # jumps
|
||||||
opCreateList, opCreateTable, # collection creation
|
opCreateList, opCreateTable, # collection creation
|
||||||
opLen, opSetIndex, opGetIndex, # collection operators
|
opLen, opSetIndex, opGetIndex, # collection operators
|
||||||
|
@ -114,6 +115,7 @@ const argInstructions = {
|
||||||
opJumpIfFalse, opJump, opLoop, opJumpIfFalsePop,
|
opJumpIfFalse, opJump, opLoop, opJumpIfFalsePop,
|
||||||
opFunctionDef, opClosure,
|
opFunctionDef, opClosure,
|
||||||
opCreateList, opCreateTable,
|
opCreateList, opCreateTable,
|
||||||
|
opGetUpvalue, opSetUpvalue,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -71,7 +71,7 @@ proc newScope(comp: Compiler, function: bool): Scope =
|
||||||
result.goalStackIndex = comp.stackIndex + 1
|
result.goalStackIndex = comp.stackIndex + 1
|
||||||
if function:
|
if function:
|
||||||
result.parentFunction = result
|
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
|
result.parentFunction = comp.scopes[comp.scopes.high()].parentFunction
|
||||||
|
|
||||||
comp.scopes.add(result)
|
comp.scopes.add(result)
|
||||||
|
@ -399,13 +399,13 @@ proc addUpvalue(comp: Compiler, index: int): int =
|
||||||
## have the right upvalue in them (compile time)
|
## have the right upvalue in them (compile time)
|
||||||
discard
|
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
|
## 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 a local: returns the stack index of the local of the name
|
||||||
## if it's an upvalue: returns the upvalue index
|
## if it's an upvalue: returns the upvalue index
|
||||||
## if the number is -1, then the name cannot be resolved at compile time
|
## if the number is -1, then the name cannot be resolved at compile time
|
||||||
var i = comp.locals.high
|
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:
|
while i >= 0:
|
||||||
let local = comp.locals[i]
|
let local = comp.locals[i]
|
||||||
if local.name == name:
|
if local.name == name:
|
||||||
|
@ -417,7 +417,7 @@ proc resolveLocal(comp: Compiler, name: string): Tuple[int, bool] =
|
||||||
else:
|
else:
|
||||||
return (comp.addUpvalue(i), true)
|
return (comp.addUpvalue(i), true)
|
||||||
i.dec
|
i.dec
|
||||||
return -1
|
return (index: -1, upvalue: false)
|
||||||
|
|
||||||
proc variable(comp: Compiler) =
|
proc variable(comp: Compiler) =
|
||||||
# named variable
|
# named variable
|
||||||
|
|
|
@ -2,19 +2,19 @@ type
|
||||||
UpvalueObj[T] = object
|
UpvalueObj[T] = object
|
||||||
location: ptr T
|
location: ptr T
|
||||||
|
|
||||||
Upvalue[T]* = ptr UpvalueObj[T]
|
Upvalue*[T] = ptr UpvalueObj[T]
|
||||||
|
|
||||||
ClosureObj[T] = object
|
ClosureObj[T] = object
|
||||||
start: ptr uint8
|
start: ptr uint8
|
||||||
upvalueCount: int
|
upvalueCount: int
|
||||||
upvalues: UncheckedArray[Upvalue[T]]
|
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 = cast[Closure[T]](alloc0(8 * upvalueCount + sizeof(ClosureObj[T])))
|
||||||
result.start = start
|
result.start = start
|
||||||
result.upvalueCount = upvalueCount
|
result.upvalueCount = upvalueCount
|
||||||
|
|
||||||
proc getIp*(clos: Closure): ptr uint8 {.inline.} =
|
proc getIp*[T](clos: Closure[T]): ptr uint8 {.inline.} =
|
||||||
clos.start
|
clos.start
|
|
@ -197,6 +197,10 @@ proc run*(chunk: Chunk): InterpretResult =
|
||||||
of opSetLocal:
|
of opSetLocal:
|
||||||
let slot = readDU8()
|
let slot = readDU8()
|
||||||
stack[slot + frameBottom] = stack.peek()
|
stack[slot + frameBottom] = stack.peek()
|
||||||
|
of opGetUpvalue:
|
||||||
|
discard
|
||||||
|
of opSetUpvalue:
|
||||||
|
discard
|
||||||
of opJumpIfFalse:
|
of opJumpIfFalse:
|
||||||
let offset = readDU8()
|
let offset = readDU8()
|
||||||
if stack.peek().isFalsey():
|
if stack.peek().isFalsey():
|
||||||
|
@ -220,7 +224,7 @@ proc run*(chunk: Chunk): InterpretResult =
|
||||||
let offset = readDU8()
|
let offset = readDU8()
|
||||||
let faddr: ptr uint8 = ip
|
let faddr: ptr uint8 = ip
|
||||||
ip = ip.padd(offset)
|
ip = ip.padd(offset)
|
||||||
stack.push(newClosure(faddr).fromClosure())
|
stack.push(newClosure[NdValue](faddr, 0).fromClosure())
|
||||||
of opCheckArity:
|
of opCheckArity:
|
||||||
let arity = readUI8()
|
let arity = readUI8()
|
||||||
let argcount = stack.high() - frameBottom
|
let argcount = stack.high() - frameBottom
|
||||||
|
@ -259,7 +263,7 @@ proc run*(chunk: Chunk): InterpretResult =
|
||||||
if tbl[].tableSet(key, val):
|
if tbl[].tableSet(key, val):
|
||||||
runtimeError("Attempt to redefine an existing value inside table declaration.")
|
runtimeError("Attempt to redefine an existing value inside table declaration.")
|
||||||
break
|
break
|
||||||
stack.deleteTopN(tblLen * 2)
|
# stack.deleteTopN(tblLen * 2) # THIS IS NOT NEEDED, pops are done
|
||||||
stack.push(tbl.fromTable())
|
stack.push(tbl.fromTable())
|
||||||
of opLen:
|
of opLen:
|
||||||
let res = stack.peek().getLength()
|
let res = stack.peek().getLength()
|
||||||
|
|
Loading…
Reference in New Issue