private IWorkshopTree ParseVirtual(ActionSet actionSet, MethodCall methodCall) { // Create the switch that chooses the overload. SwitchBuilder typeSwitch = new SwitchBuilder(actionSet); // Loop through all potential methods. IMethod[] options = Attributes.AllOverrideOptions(); // Get the call settings. MethodCall callSettings = new MethodCall(methodCall.ParameterValues, methodCall.AdditionalParameterData) { ResolveOverrides = false, ResolveReturnHandler = false, ReturnHandler = new ReturnHandler(actionSet, Name, true) }; // Parse the current overload. typeSwitch.NextCase(new V_Number(((ClassType)Attributes.ContainingType).Identifier)); Parse(actionSet, callSettings); foreach (IMethod option in options) { // The action set for the overload. ActionSet optionSet = actionSet.New(actionSet.IndexAssigner.CreateContained()); // Add the object variables of the selected method. option.Attributes.ContainingType.AddObjectVariablesToAssigner(optionSet.CurrentObject, optionSet.IndexAssigner); // Go to next case then parse the block. typeSwitch.NextCase(new V_Number(((ClassType)option.Attributes.ContainingType).Identifier)); option.Parse(optionSet, callSettings); } ClassData classData = actionSet.Translate.DeltinScript.SetupClasses(); // Finish the switch. typeSwitch.Finish(Element.Part <V_ValueInArray>(classData.ClassIndexes.GetVariable(), actionSet.CurrentObject)); callSettings.ReturnHandler.ApplyReturnSkips(); return(callSettings.ReturnHandler.GetReturnedValue()); }
public void Translate(ActionSet actionSet) { IWorkshopTree expression = Expression.Parse(actionSet); switchBuilder = new SwitchBuilder(actionSet); switchBuilder.AutoBreak = false; foreach (SwitchSection section in paths) { foreach (IExpression caseExpression in section.Cases) { switchBuilder.NextCase((Element)caseExpression.Parse(actionSet)); } if (section.IsDefault) { switchBuilder.AddDefault(); } section.Block.Translate(actionSet); } switchBuilder.Finish((Element)expression); }
private void ParseVirtual() { // Loop through all potential methods. DefinedMethod[] options = Array.ConvertAll(Method.Attributes.AllOverrideOptions(), iMethod => (DefinedMethod)iMethod); // Create the switch that chooses the overload. SwitchBuilder typeSwitch = new SwitchBuilder(BuilderSet); // Parse the current overload. if (Method.Attributes.Virtual) { typeSwitch.AddDefault(); } else { typeSwitch.NextCase(new V_Number(((ClassType)Method.Attributes.ContainingType).Identifier)); } TranslateSegment(BuilderSet, Method); foreach (DefinedMethod option in options) { // The action set for the overload. ActionSet optionSet = BuilderSet.New(BuilderSet.IndexAssigner.CreateContained()); // Add the object variables of the selected method. option.Attributes.ContainingType.AddObjectVariablesToAssigner(optionSet.CurrentObject, optionSet.IndexAssigner); // Go to next case then parse the block. typeSwitch.NextCase(new V_Number(((ClassType)option.Attributes.ContainingType).Identifier)); // Iterate through every type. foreach (CodeType type in BuilderSet.Translate.DeltinScript.Types.AllTypes) { // If 'type' does not equal the current virtual option's containing class... if (option.Attributes.ContainingType != type // ...and 'type' implements the containing class... && type.Implements(option.Attributes.ContainingType) // ...and 'type' does not have their own function implementation... && AutoImplemented(option.Attributes.ContainingType, options.Select(o => o.Attributes.ContainingType).ToArray(), type)) { // ...then add an additional case for 'type's class identifier. typeSwitch.NextCase(new V_Number(((ClassType)type).Identifier)); } } if (option.subroutineInfo == null) { TranslateSegment(optionSet, option); } else { option.SetupSubroutine(); BuilderSet.AddAction(Element.Part <A_StartRule>(option.subroutineInfo.Subroutine, EnumData.GetEnumValue(IfAlreadyExecuting.DoNothing))); if (Method.DoesReturnValue) { ReturnHandler.ReturnValue(option.subroutineInfo.ReturnHandler.GetReturnedValue()); } } if (Method.IsSubroutine) { option.virtualSubroutineAssigned = Method; } } ClassData classData = BuilderSet.Translate.DeltinScript.GetComponent <ClassData>(); // Finish the switch. typeSwitch.Finish(Element.Part <V_ValueInArray>(classData.ClassIndexes.GetVariable(), BuilderSet.CurrentObject)); }