}//constructor /* * public override void OnCodeAnalysis(CodeAnalysisArgs args) { * //process child nodes first, so that NameRef is processed * base.OnCodeAnalysis(args); * switch (args.Phase) { * case CodeAnalysisPhase.Binding: * if (NameRef.Slot != null) { * NameRef.Slot.Flags |= SlotFlags.UsedAsCallTarget; * } else { * // Slot does not exist so it is not locally-defined method. Let's try global/library function * // TODO: implement support for library references at scope level, so that all "import.." statements are checked * // before checking global methods * FixedTargetInfo = args.Context.Runtime.GetFunctionBindingInfo(NameRef.Name, Arguments); * if (FixedTargetInfo == null) { * args.Context.ReportError(this.Location, "Method not found: {0}", NameRef.Name); * return; * } * }//else * break; * case CodeAnalysisPhase.MarkTailCalls: * _isTail = IsSet(AstNodeFlags.IsTail) && this.Scope.Level > 0; * break; * case CodeAnalysisPhase.Optimization: * if (this.FixedTargetInfo != null) * this.Evaluate = InvokeFixed; * else * this.Evaluate = InvokeDynamic; * break; * }//switch * }//method * */ protected void InvokeDynamic(EvaluationContext context) { NameRef.Evaluate(context); Closure target; try { target = (Closure)context.CurrentResult; if (target.MethodName == null) { target.MethodName = NameRef.Name; } } catch (InvalidCastException castExc) { throw new RuntimeException("Method [" + NameRef.Name + "] not found or method reference is not set.", castExc, NameRef.Location); } catch (NullReferenceException) { throw new RuntimeException("Method reference is not set in variable " + NameRef.Name, null, NameRef.Location); } EvaluateArgs(context, target.BindingInfo); if (_isTail) { context.Tail = target; return; } //execute non-tail call target.Evaluate(context); if (context.Tail == null) { return; } //check returning tail while (context.Tail != null) { Closure tail = context.Tail; context.Tail = null; tail.Evaluate(context); } context.CallArgs = null; }
protected override void DoEvaluate(EvaluationContext context) { Expression.Evaluate(context); Identifier.Evaluate(context); //writes the value into the slot }