// Evaluates the argument if the argument is another operator or a reference. protected static void EvalArgument(RCRunner runner, RCClosure closure, RCValue argument) { if (argument.ArgumentEval) { RCClosure child = new RCClosure(closure, closure.Bot, argument, closure.Left, null, 0); argument.Eval(runner, child); } else { // pretty clear scope for optimization here, why go back to the runner in this // case? // runner calls have a lot of overhead. // It was easier to write this way early on. DoYield(runner, closure, argument); } }
/// <summary> /// Start evaluation for a user-defined operator. /// </summary> public static void DoEvalUserOp(RCRunner runner, RCClosure closure, RCUserOperator op) { RCValue code = closure.UserOp; RCArray <RCBlock> @this = closure.UserOpContext; if (code == null) { if (op._reference.Parts.Count > 1) { @this = new RCArray <RCBlock> (); } code = Resolve(op._reference._static, closure, op._reference.Parts, @this); } if (code == null) { throw new Exception("Cannot find definition for operator: " + op._reference.Name); } if (code.TypeCode == 's') { string name = ((RCString)code)[0]; RCValue left = closure.Result.Get("0"); RCValue right = closure.Result.Get("1"); if (left != null) { RCSystem.Activator.Invoke(runner, closure, name, left, right); } else { RCSystem.Activator.Invoke(runner, closure, name, right); } } else { code.Eval(runner, UserOpClosure(closure, code, @this, noClimb: false)); } }
public static void DoEvalOperator(RCRunner runner, RCClosure closure, RCOperator op) { RCValue left = closure.Result.Get("0"); RCValue right = closure.Result.Get("1"); RCValue virtop = Resolve(null, closure, new RCArray <string> (op.Name), null, true); if (virtop != null) { RCClosure parent = UserOpClosure(closure, virtop, null, noClimb: false); virtop.Eval(runner, parent); return; } if (left == null) { RCSystem.Activator.Invoke(runner, closure, op.Name, right); } else { RCSystem.Activator.Invoke(runner, closure, op.Name, left, right); } // A lot of good men died to bring us this one line of code... // Let's keep this around as a memorial. // right.BindRight (runner, closure, this, left); }