Closed Jozott00 closed 1 year ago
Ok the problem lies here in the Interpreter:
func callFunctionOrOperator(callee: MooseObject, args: [MooseObject]) throws -> MooseObject {
...
} else if let callee = callee as? FunctionObj {
// Activate the environment in which the function was defined
let oldEnv = environment
environment = callee.closure
pushEnvironment()
...
}
since the closure of the function apparently holds the environment of the latest object...
@flofriday you implemented the closure, so i guess you can fix it in a better way than me
Ok found the reason.
In the interpreter when a constructor node is called (callConstructor(...)
) we execute classObject.bindMethods()
which makes perfect sense. The only problem is, that we do a copy of the ClassEnvironment, however since the FunctionObjs
in the funcs
dict of the environment are classes, they are copied by reference. So even if we bind the methods on the copied class, we always rebind them on the exact same FunctionObj
s.
So the most straight forward solution would be to implement a copy constructor for the FunctionObjs
and on copying the classEnvironment, we also copy each function manually.
When calling a method, in perspective of the method, the environment does always equal the environment of the latest created object.
This example shows that
b
inC.num()
is always2
, because the latest created object hasb = 2