doOneLine method
Implementation
void doOneLine(Line line, Context context) {
if (line.op == LineOp.pushParam) {
final val = context.valueInContext(line.rhsA);
context.pushParamArgument(val);
} else if (line.op == LineOp.callFunctionA) {
// Resolve rhsA. If it's a function, invoke it; otherwise,
// just store it directly (but pop the call context).
var valueFoundInPointer = ValuePointer<ValMap>();
final funcVal = line.rhsA!.valWithMap(context, valueFoundInPointer);
if (funcVal is ValFunction) {
Value? self;
// Bind "super" to the parent of the map the function was found in
final superVal = valueFoundInPointer.value
?.lookup(ValString.magicIsA, ValuePointer());
if (line.rhsA is ValSeqElem) {
// Bind "self" to the object used to invoke the call,
// except when invoking via "super"
final seq = (line.rhsA as ValSeqElem).sequence;
if (seq is ValVar && (seq).identifier == "super") {
self = context.self;
} else {
self = context.valueInContext(seq);
}
}
final argCount = line.rhsB!.intValue();
final nextContext = context.nextCallContext(
funcVal.function,
argCount,
self != null,
line.lhs,
);
nextContext.outerVars = funcVal.outerVars;
if (valueFoundInPointer.value != null) {
nextContext.setVar("super", superVal);
}
if (self != null) nextContext.self = self;
stack.add(nextContext);
} else {
// The user is attempting to call something that's not a function.
// We'll allow that, but any number of parameters is too many. [#35]
// (No need to pop them, as the exception will pop the whole call stack anyway.)
int argCount = line.rhsB!.intValue();
if (argCount > 0) throw TooManyArgumentsException();
context.storeValue(line.lhs, funcVal);
}
} else if (line.op == LineOp.returnA) {
final val = line.evaluate(context);
context.storeValue(line.lhs, val);
popContext();
} else if (line.op == LineOp.assignImplicit) {
final val = line.evaluate(context);
if (storeImplicit) {
context.storeValue(ValVar.implicitResult, val);
context.implicitResultCounter++;
}
} else {
final val = line.evaluate(context);
context.storeValue(line.lhs, val);
}
}