private static IWorkshopTree CallSubroutine(DefinedMethod method, MethodCall call, ActionSet callerSet)
        {
            method.SetupSubroutine();

            for (int i = 0; i < method.subroutineInfo.ParameterStores.Length; i++)
            {
                // Normal parameter push.
                if (!method.Attributes.Recursive)
                {
                    callerSet.AddAction(method.subroutineInfo.ParameterStores[i].SetVariable((Element)call.ParameterValues[i]));
                }
                // Recursive parameter push.
                else
                {
                    callerSet.AddAction(((RecursiveIndexReference)method.subroutineInfo.ParameterStores[i]).Push((Element)call.ParameterValues[i]));
                }
            }

            // Store the object the subroutine is executing with.
            if (method.subroutineInfo.ObjectStore != null)
            {
                // Normal
                if (!method.Attributes.Recursive)
                {
                    callerSet.AddAction(method.subroutineInfo.ObjectStore.SetVariable((Element)callerSet.CurrentObject));
                }
                // Recursive: Stack
                else
                {
                    callerSet.AddAction(method.subroutineInfo.ObjectStore.ModifyVariable(Operation.AppendToArray, (Element)callerSet.CurrentObject));
                }
            }

            switch (call.CallParallel)
            {
            // No parallel, call subroutine normally.
            case CallParallel.NoParallel:
                callerSet.AddAction(Element.Part <A_CallSubroutine>(method.subroutineInfo.Subroutine));
                return(method.subroutineInfo.ReturnHandler.GetReturnedValue());

            // Restart the subroutine if it is already running.
            case CallParallel.AlreadyRunning_RestartRule:
                callerSet.AddAction(Element.Part <A_StartRule>(method.subroutineInfo.Subroutine, EnumData.GetEnumValue(IfAlreadyExecuting.RestartRule)));
                return(null);

            // Do nothing if the subroutine is already running.
            case CallParallel.AlreadyRunning_DoNothing:
                callerSet.AddAction(Element.Part <A_StartRule>(method.subroutineInfo.Subroutine, EnumData.GetEnumValue(IfAlreadyExecuting.DoNothing)));
                return(null);

            default: throw new NotImplementedException();
            }
        }
        /// <summary>Determines if the specified type does not have their own implementation for the specified virtual function.</summary>
        /// <param name="virtualFunction">The virtual function to check overrides of.</param>
        /// <param name="options">All potential virtual functions.</param>
        /// <param name="type">The type to check.</param>
        private bool AutoImplemented(DefinedMethod virtualFunction, DefinedMethod[] options, CodeType type)
        {
            // Go through each class in the inheritance tree and check if it implements the function.
            CodeType current = type;

            while (current != null && current != virtualFunction.Attributes.ContainingType)
            {
                // If it does, return false.
                if (options.Any(option => option.Attributes.ContainingType == current))
                {
                    return(false);
                }
                current = current.Extends;
            }
            return(true);
        }
        public static IWorkshopTree Call(DefinedMethod method, MethodCall call, ActionSet actionSet)
        {
            RecursiveStack lastCall = actionSet.Translate.MethodStack.FirstOrDefault(ms => ms.Function == method) as RecursiveStack;

            if (lastCall == null)
            {
                RecursiveStack parser = new RecursiveStack(method);

                actionSet.Translate.MethodStack.Add(parser);
                var result = parser.ParseCall(actionSet, call);
                actionSet.Translate.MethodStack.Remove(parser);

                return(result);
            }
            else
            {
                return(lastCall.RecursiveCall(actionSet, call));
            }
        }
        private static IWorkshopTree CallInlineRecursive(MethodBuilder builder, DefinedMethod method, MethodCall call, ActionSet callerSet)
        {
            RecursiveStack lastCall = RecursiveStack.GetRecursiveCall(callerSet.Translate.MethodStack, method);

            if (lastCall == null)
            {
                RecursiveStack parser = new RecursiveStack(builder);
                callerSet.Translate.MethodStack.Add(parser);
                parser.ParseCall(call);
                callerSet.Translate.MethodStack.Remove(parser);

                return(builder.ReturnHandler.GetReturnedValue());
            }
            else
            {
                lastCall.RecursiveCall(call, callerSet);
                return(lastCall.Builder.ReturnHandler.GetReturnedValue());
            }
        }
        /// <summary>Calls the method.</summary>
        private IWorkshopTree ParseCall(ActionSet actionSet, MethodCall methodCall)
        {
            // Create the array used for continuing after a recursive call.
            continueArray = actionSet.VarCollection.Assign("_" + method.Name + "_recursiveContinue", actionSet.IsGlobal, false);
            nextContinue  = actionSet.VarCollection.Assign("_" + method.Name + "_nextContinue", actionSet.IsGlobal, true);
            actionSet.InitialSet().AddAction(continueArray.SetVariable(new V_EmptyArray()));

            ReturnHandler returnHandler = methodCall.ReturnHandler ?? new ReturnHandler(actionSet, method.Name, method.multiplePaths);

            this.returnHandler = returnHandler;

            DefinedMethod.AssignParameters(actionSet, method.ParameterVars, methodCall.ParameterValues, true);

            actionSet.AddAction(Element.Part <A_While>(new V_True()));

            continueAt = new SkipStartMarker(actionSet);
            continueAt.SetSkipCount((Element)nextContinue.GetVariable());
            actionSet.AddAction(continueAt);

            method.block.Translate(actionSet);

            PopParameterStacks(actionSet);

            // Pop the continueArray.
            actionSet.AddAction(Element.Part <A_SkipIf>(new V_Compare(
                                                            Element.Part <V_CountOf>(continueArray.GetVariable()),
                                                            Operators.Equal,
                                                            new V_Number(0)
                                                            ), new V_Number(3)));

            actionSet.AddAction(nextContinue.SetVariable(Element.Part <V_LastOf>(continueArray.GetVariable())));
            actionSet.AddAction(continueArray.ModifyVariable(Operation.RemoveFromArrayByIndex, Element.Part <V_CountOf>(continueArray.GetVariable()) - 1));

            actionSet.AddAction(endOfMethod);
            actionSet.AddAction(new A_End());

            actionSet.AddAction(nextContinue.SetVariable(0));

            return(returnHandler.GetReturnedValue());
        }
        public static IWorkshopTree Call(DefinedMethod method, MethodCall call, ActionSet callerSet)
        {
            // Subroutine call.
            if (method.IsSubroutine)
            {
                return(CallSubroutine(method, call, callerSet));
            }
            // Inline
            else
            {
                MethodBuilder builder = new MethodBuilder(method, callerSet);

                // Inline-recursive method call.
                if (method.Attributes.Recursive)
                {
                    return(CallInlineRecursive(builder, method, call, callerSet));
                }
                else
                {
                    if (method.virtualSubroutineAssigned != null)
                    {
                        // TODO: Maybe remove this?
                        // Virtual in another subroutine
                        return(Call(method.virtualSubroutineAssigned, call, callerSet));
                    }
                    else
                    {
                        // Normal
                        builder.BuilderSet = builder.BuilderSet.PackThis();
                        builder.AssignParameters(call);
                        builder.SetupReturnHandler();
                        builder.ParseInner();
                        builder.ReturnHandler.ApplyReturnSkips();
                        return(builder.ReturnHandler.GetReturnedValue());
                    }
                }
            }
        }
        public override void ResolveElements()
        {
            if (elementsResolved)
            {
                return;
            }

            // Get the type being extended.
            if (typeContext.TERNARY_ELSE() != null)
            {
                // If there is no type name, error.
                if (typeContext.extends == null)
                {
                    parseInfo.Script.Diagnostics.Error("Expected type name.", DocRange.GetRange(typeContext.TERNARY_ELSE()));
                }
                else
                {
                    // Get the type being inherited.
                    CodeType inheriting = parseInfo.TranslateInfo.Types.GetCodeType(typeContext.extends.Text, parseInfo.Script.Diagnostics, DocRange.GetRange(typeContext.extends));

                    // GetCodeType will return null if the type is not found.
                    if (inheriting != null)
                    {
                        inheriting.Call(parseInfo, DocRange.GetRange(typeContext.extends));

                        Inherit(inheriting, parseInfo.Script.Diagnostics, DocRange.GetRange(typeContext.extends));
                        (Extends as ClassType)?.ResolveElements();
                    }
                }
            }

            base.ResolveElements();

            // Give DefinedMethod and GetMacro a scope to use in case of the static attribute.
            foreach (var definedMethod in typeContext.define_method())
            {
                var newMethod = new DefinedMethod(parseInfo, operationalScope, staticScope, definedMethod, this);

                // Copy to serving scopes.
                if (newMethod.Static)
                {
                    operationalScope.CopyMethod(newMethod);
                }
                else
                {
                    serveObjectScope.CopyMethod(newMethod);
                }
            }

            // Get the macros.
            foreach (var macroContext in typeContext.define_macro())
            {
                var newMacro = parseInfo.GetMacro(operationalScope, staticScope, macroContext);

                // Copy to serving scopes.
                if (newMacro is IMethod asMethod)
                {
                    if (newMacro.Static)
                    {
                        operationalScope.CopyMethod(asMethod);
                    }
                    else
                    {
                        serveObjectScope.CopyMethod(asMethod);
                    }
                }
                else
                {
                    if (newMacro.Static)
                    {
                        operationalScope.CopyVariable((IVariable)newMacro);
                    }
                    else
                    {
                        serveObjectScope.CopyVariable((IVariable)newMacro);
                    }
                }
            }

            // Get the variables defined in the type.
            foreach (var definedVariable in typeContext.define())
            {
                Var newVar = new ClassVariable(operationalScope, staticScope, new DefineContextHandler(parseInfo, definedVariable));

                // Copy to serving scopes.
                if (!newVar.Static)
                {
                    ObjectVariables.Add(new ObjectVariable(newVar));
                    serveObjectScope.CopyVariable(newVar);
                }
                // Add to static scope.
                else
                {
                    staticVariables.Add(newVar);
                    staticScope.CopyVariable(newVar);
                    operationalScope.CopyVariable(newVar);
                }
            }

            // Get the constructors.
            if (typeContext.constructor().Length > 0)
            {
                Constructors = new Constructor[typeContext.constructor().Length];
                for (int i = 0; i < Constructors.Length; i++)
                {
                    Constructors[i] = new DefinedConstructor(parseInfo, operationalScope, this, typeContext.constructor(i));
                }
            }
            else
            {
                // If there are no constructors, create a default constructor.
                Constructors = new Constructor[] {
                    new Constructor(this, new Location(parseInfo.Script.Uri, DocRange.GetRange(typeContext.name)), AccessLevel.Public)
                };
            }

            // If the extend token exists, add completion that only contains all extendable classes.
            if (typeContext.TERNARY_ELSE() != null)
            {
                parseInfo.Script.AddCompletionRange(new CompletionRange(
                                                        // Get the completion items of all types.
                                                        parseInfo.TranslateInfo.Types.AllTypes
                                                        .Where(t => t is ClassType ct && ct.CanBeExtended)
                                                        .Select(t => t.GetCompletion())
                                                        .ToArray(),
                                                        // Get the completion range.
                                                        DocRange.GetRange(typeContext.TERNARY_ELSE(), parseInfo.Script.NextToken(typeContext.TERNARY_ELSE())),
                                                        // This completion takes priority.
                                                        CompletionRangeKind.ClearRest
                                                        ));
            }
            parseInfo.Script.AddCodeLensRange(new ReferenceCodeLensRange(this, parseInfo, CodeLensSourceType.Type, DefinedAt.range));
        }
예제 #8
0
 public BlockTreeScan(bool doesReturnValue, ParseInfo parseInfo, DefinedMethod method) : this(parseInfo, method.Block, method.Name, method.Context.Identifier.Range)
 {
     ReturnsValue = doesReturnValue;
 }
 public override void Parse(ActionSet actionSet, IWorkshopTree[] parameterValues, object[] additionalParameterData)
 {
     actionSet = actionSet.New(actionSet.IndexAssigner.CreateContained()).PackThis();
     DefinedMethod.AssignParameters(actionSet, ParameterVars, parameterValues);
     Block.Translate(actionSet);
 }
 public MethodBuilder(DefinedMethod method, ActionSet builderSet, ReturnHandler returnHandler = null)
 {
     Method          = method;
     this.BuilderSet = builderSet;
     ReturnHandler   = returnHandler;
 }
 private static void TranslateSegment(ActionSet actionSet, DefinedMethod method)
 {
     method.Block.Translate(actionSet);
 }
예제 #12
0
 public override void Parse(ActionSet actionSet, IWorkshopTree[] parameterValues)
 {
     actionSet = actionSet.New(actionSet.IndexAssigner.CreateContained());
     DefinedMethod.AssignParameters(actionSet, ParameterVars, parameterValues);
     Block.Translate(actionSet);
 }
예제 #13
0
 public BlockTreeScan(bool doesReturnValue, ParseInfo parseInfo, DefinedMethod method) : this(parseInfo, method.Block, method.Name, DocRange.GetRange(method.Context.name))
 {
     ReturnsValue = doesReturnValue;
 }
 public RecursiveMethodStack(DefinedMethod method, ReturnHandler returnHandler, IndexReference continueSkipArray, SkipEndMarker methodStart) : base(method)
 {
     ReturnHandler     = returnHandler;
     ContinueSkipArray = continueSkipArray;
     MethodStart       = methodStart;
 }
예제 #15
0
        public DefinedType(ParseInfo parseInfo, Scope scope, DeltinScriptParser.Type_defineContext typeContext, List <IApplyBlock> applyMethods) : base(typeContext.name.Text)
        {
            this.translateInfo = parseInfo.TranslateInfo;
            if (translateInfo.IsCodeType(Name))
            {
                parseInfo.Script.Diagnostics.Error($"A type with the name '{Name}' already exists.", DocRange.GetRange(typeContext.name));
            }

            DefinedAt = new LanguageServer.Location(parseInfo.Script.Uri, DocRange.GetRange(typeContext.name));
            translateInfo.AddSymbolLink(this, DefinedAt);

            if (typeContext.CLASS() != null)
            {
                TypeKind       = TypeKind.Class;
                TypeKindString = "class";
            }
            else if (typeContext.STRUCT() != null)
            {
                TypeKind       = TypeKind.Struct;
                TypeKindString = "struct";
            }
            else
            {
                throw new NotImplementedException();
            }

            staticScope = translateInfo.GlobalScope.Child(TypeKindString + " " + Name);
            objectScope = staticScope.Child(TypeKindString + " " + Name);

            // Get the variables defined in the type.
            foreach (var definedVariable in typeContext.define())
            {
                Var newVar = Var.CreateVarFromContext(VariableDefineType.InClass, parseInfo, definedVariable);
                newVar.Finalize(UseScope(newVar.Static));
                if (!newVar.Static)
                {
                    objectVariables.Add(newVar);
                }
            }

            // Todo: Static methods/macros.
            foreach (var definedMethod in typeContext.define_method())
            {
                var newMethod = new DefinedMethod(parseInfo, UseScope(false), definedMethod);
                applyMethods.Add(newMethod);
            }

            foreach (var macroContext in typeContext.define_macro())
            {
                DeltinScript.GetMacro(parseInfo, UseScope(false), macroContext, applyMethods);
            }

            // Get the constructors.
            if (typeContext.constructor().Length > 0)
            {
                Constructors = new Constructor[typeContext.constructor().Length];
                for (int i = 0; i < Constructors.Length; i++)
                {
                    Constructors[i] = new DefinedConstructor(parseInfo, this, typeContext.constructor(i));
                    applyMethods.Add((DefinedConstructor)Constructors[i]);
                }
            }
            else
            {
                // If there are no constructors, create a default constructor.
                Constructors = new Constructor[] {
                    new Constructor(this, new Location(parseInfo.Script.Uri, DocRange.GetRange(typeContext.name)), AccessLevel.Public)
                };
            }
        }
예제 #16
0
        public override void ResolveElements()
        {
            if (elementsResolved)
            {
                return;
            }

            // Get the type being extended.
            // This is an array for future interface support.
            if (_typeContext.Inheriting.Count > 0 && _typeContext.Inheriting[0])
            {
                var inheritToken = _typeContext.Inheriting[0];

                // Get the type being inherited.
                CodeType inheriting = _parseInfo.TranslateInfo.Types.GetCodeType(inheritToken.Text, _parseInfo.Script.Diagnostics, inheritToken.Range);

                // GetCodeType will return null if the type is not found.
                if (inheriting != null)
                {
                    inheriting.Call(_parseInfo, inheritToken.Range);

                    Inherit(inheriting, _parseInfo.Script.Diagnostics, inheritToken.Range);
                    (Extends as ClassType)?.ResolveElements();
                }
            }

            base.ResolveElements();

            // Get the declarations.
            foreach (var declaration in _typeContext.Declarations)
            {
                IScopeable scopeable;

                // Function
                if (declaration is FunctionContext function)
                {
                    scopeable = new DefinedMethod(_parseInfo, operationalScope, staticScope, function, this);
                }
                // Macro function
                else if (declaration is MacroFunctionContext macroFunction)
                {
                    scopeable = _parseInfo.GetMacro(operationalScope, staticScope, macroFunction);
                }
                // Variable
                else if (declaration is VariableDeclaration variable)
                {
                    scopeable = new ClassVariable(operationalScope, staticScope, new DefineContextHandler(_parseInfo, variable)).GetVar();
                }
                // Macro variable
                else if (declaration is MacroVarDeclaration macroVar)
                {
                    scopeable = _parseInfo.GetMacro(operationalScope, staticScope, macroVar);
                }
                // Unknown
                else
                {
                    throw new NotImplementedException(declaration.GetType().ToString());
                }

                // Add the object variable if it is an IIndexReferencer.
                if (scopeable is IIndexReferencer referencer)
                {
                    AddObjectVariable(referencer);
                }

                // Copy to scopes.
                // Method copy
                if (scopeable is IMethod method)
                {
                    if (method.Static)
                    {
                        operationalScope.CopyMethod(method);
                    }
                    else
                    {
                        serveObjectScope.CopyMethod(method);
                    }
                }
                // Variable copy
                else if (scopeable is IVariable variable)
                {
                    if (scopeable.Static)
                    {
                        operationalScope.CopyVariable(variable);
                    }
                    else
                    {
                        serveObjectScope.CopyVariable(variable);
                    }
                }
                else
                {
                    throw new NotImplementedException();
                }
            }

            // Get the constructors.
            if (_typeContext.Constructors.Count > 0)
            {
                Constructors = new Constructor[_typeContext.Constructors.Count];
                for (int i = 0; i < Constructors.Length; i++)
                {
                    Constructors[i] = new DefinedConstructor(_parseInfo, operationalScope, this, _typeContext.Constructors[i]);
                }
            }
            else
            {
                // If there are no constructors, create a default constructor.
                Constructors = new Constructor[] {
                    new Constructor(this, new Location(_parseInfo.Script.Uri, DefinedAt.range), AccessLevel.Public)
                };
            }

            // If the extend token exists, add completion that only contains all extendable classes.
            if (_typeContext.InheritToken != null && !_parseInfo.Script.IsTokenLast(_typeContext.InheritToken))
            {
                _parseInfo.Script.AddCompletionRange(new CompletionRange(
                                                         // Get the completion items of all types.
                                                         _parseInfo.TranslateInfo.Types.AllTypes
                                                         .Where(t => t is ClassType ct && ct.CanBeExtended)
                                                         .Select(t => t.GetCompletion())
                                                         .ToArray(),
                                                         // Get the completion range.
                                                         _typeContext.InheritToken.Range.End + _parseInfo.Script.NextToken(_typeContext.InheritToken).Range.Start,
                                                         // This completion takes priority.
                                                         CompletionRangeKind.ClearRest
                                                         ));
            }
            _parseInfo.Script.AddCodeLensRange(new ReferenceCodeLensRange(this, _parseInfo, CodeLensSourceType.Type, DefinedAt.range));
        }
 public RecursiveStack(DefinedMethod method) : base((IApplyBlock)method)
 {
     this.method = method;
 }
        void Translate()
        {
            List <IApplyBlock> applyMethods = new List <IApplyBlock>();

            // Get the reserved variables and IDs
            foreach (ScriptFile script in ScriptFiles)
            {
                if (script.Context.reserved_global()?.reserved_list() != null)
                {
                    foreach (var name in script.Context.reserved_global().reserved_list().PART())
                    {
                        VarCollection.Reserve(name.GetText(), true);
                    }
                    foreach (var id in script.Context.reserved_global().reserved_list().NUMBER())
                    {
                        VarCollection.Reserve(int.Parse(id.GetText()), true, null, null);
                    }
                }
                if (script.Context.reserved_player()?.reserved_list() != null)
                {
                    foreach (var name in script.Context.reserved_player().reserved_list().PART())
                    {
                        VarCollection.Reserve(name.GetText(), false);
                    }
                    foreach (var id in script.Context.reserved_player().reserved_list().NUMBER())
                    {
                        VarCollection.Reserve(int.Parse(id.GetText()), false, null, null);
                    }
                }
            }

            // Get the enums
            foreach (ScriptFile script in ScriptFiles)
            {
                foreach (var enumContext in script.Context.enum_define())
                {
                    var newEnum = new DefinedEnum(new ParseInfo(script, this), enumContext);
                    types.Add(newEnum);
                    definedTypes.Add(newEnum);
                }
            }

            // Get the types
            foreach (ScriptFile script in ScriptFiles)
            {
                foreach (var typeContext in script.Context.type_define())
                {
                    var newType = new DefinedType(new ParseInfo(script, this), GlobalScope, typeContext, applyMethods);
                    types.Add(newType);
                    definedTypes.Add(newType);
                }
            }

            // Get the methods and macros
            foreach (ScriptFile script in ScriptFiles)
            {
                // Get the methods.
                foreach (var methodContext in script.Context.define_method())
                {
                    var newMethod = new DefinedMethod(new ParseInfo(script, this), RulesetScope, methodContext);
                    applyMethods.Add(newMethod);
                    //RulesetScope.AddMethod(newMethod, script.Diagnostics, DocRange.GetRange(methodContext.name));
                }

                // Get the macros.
                foreach (var macroContext in script.Context.define_macro())
                {
                    GetMacro(new ParseInfo(script, this), RulesetScope, macroContext, applyMethods);
                }
            }

            // Get the defined variables.
            foreach (ScriptFile script in ScriptFiles)
            {
                foreach (var varContext in script.Context.define())
                {
                    var newVar = Var.CreateVarFromContext(VariableDefineType.RuleLevel, new ParseInfo(script, this), varContext);
                    newVar.Finalize(RulesetScope);
                    rulesetVariables.Add(newVar);
                    // Add the variable to the player variables scope if it is a player variable.
                    if (newVar.VariableType == VariableType.Player)
                    {
                        PlayerVariableScope.AddVariable(newVar, null, null);
                    }
                }
            }

            foreach (var apply in applyMethods)
            {
                apply.SetupBlock();
            }
            foreach (var apply in applyMethods)
            {
                apply.CallInfo.CheckRecursion();
            }

            // Get the rules
            foreach (ScriptFile script in ScriptFiles)
            {
                foreach (var ruleContext in script.Context.ow_rule())
                {
                    rules.Add(new RuleAction(new ParseInfo(script, this), RulesetScope, ruleContext));
                }
            }
        }
        void Translate()
        {
            // Get the reserved variables and IDs
            foreach (ScriptFile script in ScriptFiles)
            {
                if (script.Context.reserved_global()?.reserved_list() != null)
                {
                    foreach (var name in script.Context.reserved_global().reserved_list().PART())
                    {
                        VarCollection.Reserve(name.GetText(), true);
                    }
                    foreach (var id in script.Context.reserved_global().reserved_list().NUMBER())
                    {
                        VarCollection.Reserve(int.Parse(id.GetText()), true, null, null);
                    }
                }
                if (script.Context.reserved_player()?.reserved_list() != null)
                {
                    foreach (var name in script.Context.reserved_player().reserved_list().PART())
                    {
                        VarCollection.Reserve(name.GetText(), false);
                    }
                    foreach (var id in script.Context.reserved_player().reserved_list().NUMBER())
                    {
                        VarCollection.Reserve(int.Parse(id.GetText()), false, null, null);
                    }
                }
            }

            // Get the enums
            foreach (ScriptFile script in ScriptFiles)
            {
                foreach (var enumContext in script.Context.enum_define())
                {
                    var newEnum = new DefinedEnum(new ParseInfo(script, this), enumContext);
                    types.Add(newEnum);
                    definedTypes.Add(newEnum);
                }
            }

            // Get the types
            foreach (ScriptFile script in ScriptFiles)
            {
                foreach (var typeContext in script.Context.type_define())
                {
                    var newType = new DefinedType(new ParseInfo(script, this), GlobalScope, typeContext);
                    types.Add(newType);
                    definedTypes.Add(newType);
                }
            }

            // Get the methods and macros
            foreach (ScriptFile script in ScriptFiles)
            {
                // Get the methods.
                foreach (var methodContext in script.Context.define_method())
                {
                    var newMethod = new DefinedMethod(new ParseInfo(script, this), RulesetScope, RulesetScope, methodContext, null);
                }

                // Get the macros.
                foreach (var macroContext in script.Context.define_macro())
                {
                    GetMacro(new ParseInfo(script, this), RulesetScope, RulesetScope, macroContext);
                }
            }

            // Get the defined variables.
            foreach (ScriptFile script in ScriptFiles)
            {
                foreach (var varContext in script.Context.define())
                {
                    Var newVar = new RuleLevelVariable(RulesetScope, new DefineContextHandler(new ParseInfo(script, this), varContext));
                    rulesetVariables.Add(newVar);

                    // Add the variable to the player variables scope if it is a player variable.
                    if (newVar.VariableType == VariableType.Player)
                    {
                        PlayerVariableScope.CopyVariable(newVar);
                    }
                }
            }

            foreach (var applyType in types)
            {
                if (applyType is ClassType classType)
                {
                    classType.ResolveElements();
                }
            }
            foreach (var apply in applyBlocks)
            {
                apply.SetupParameters();
            }
            foreach (var apply in applyBlocks)
            {
                apply.SetupBlock();
            }
            foreach (var apply in applyBlocks)
            {
                apply.CallInfo?.CheckRecursion();
            }

            // Get the rules
            foreach (ScriptFile script in ScriptFiles)
            {
                foreach (var ruleContext in script.Context.ow_rule())
                {
                    rules.Add(new RuleAction(new ParseInfo(script, this), RulesetScope, ruleContext));
                }
            }
        }
 public void AddSubroutine(DefinedMethod method)
 {
     subroutines.Add(method);
 }