public RoutineDefinition Resolve(RoutineReference routineReference) { try { return(Routines.Single(routine => routine == routineReference)); } catch (InvalidOperationException) { throw new RoutineNotFoundException(Context, routineReference); } }
/// <summary> /// Generate call to a routine, leaving returned value on the stack. /// </summary> /// <para>Stack behavior: </para> /// <list type="number"> /// <item><description>evaluate each routine argument in order from 1 to N</description></item> /// <item><description>arguments are on the stack one after another</description></item> /// <item><description>call routine</description></item> /// <item><description>leave returned value (if any) on the stack</description></item> /// </list> /// <para>Use returned routine definition to check whether the return type if void, /// in order to determine if there is a value left on the stack.</para> /// <param name="call">"CALL" AST fragment</param> /// <returns>Resolved routine definition</returns> private RoutineDefinition GenerateCall(Call call) { var routine = new RoutineReference(Context, call.Callee).Resolve(); if (!routine.IsStatic) { throw new NotImplementedException("Non-static unit routines are not implemented yet."); } // arguments: { // compile & leave on the stack var args = call.Arguments.Select(GenerateExpression).ToList(); // verify routine.VerifyCallArguments(args); } ip.Emit(OpCodes.Call, routine.NativeMethod); return(routine); }
public RoutineDefinition Resolve(RoutineReference routine) { // No unit reference? -> try global, then runtime. // Else, resolve unit and forward the request. if (routine.Unit == null) { try { RoutineReference r = new RoutineReference(GlobalUnit, routine.Name); return(GlobalUnit.Resolve(r)); } catch (RoutineNotFoundException) { RoutineReference r = new RoutineReference(RuntimeGlobalUnit, routine.Name); return(RuntimeGlobalUnit.Resolve(r)); } } else { var unit = routine.Unit.Resolve(); return(unit.Resolve(routine)); } }
public RoutineNotFoundException(Context ctx, RoutineReference routine) { Context = ctx; Routine = routine; }