Пример #1
0
        override public void GetSource(TranslateRule context, Element element, Location location)
        {
            IndexedVar supportedType = context.ParserData.ClassArray.CreateChild(null, Name + " root", new Element[] { element }, null);

            supportedType.Type    = this;
            element.SupportedType = supportedType;
        }
        override public Element Get(TranslateRule context, ScopeGroup scope, MethodNode methodNode, IWorkshopTree[] parameters)
        {
            // Check the method stack if this method was already called.
            // Throw a syntax error if it was.
            if (context.MethodStackNotRecursive.Contains(this))
            {
                throw new SyntaxErrorException("Recursion is not allowed in macros.", methodNode.Location);
            }
            context.MethodStackNotRecursive.Add(this);

            int actionCount = context.Actions.Count;

            ScopeGroup methodScope = scope.Root().Child();

            for (int i = 0; i < parameters.Length; i++)
            {
                new ElementReferenceVar(Parameters[i].Name, methodScope, methodNode.Parameters[i], parameters[i]);
            }

            Element result = context.ParseExpression(methodScope, methodScope, Expression);

            methodScope.Out(context);

            context.MethodStackNotRecursive.Remove(this);

            if (context.Actions.Count > actionCount)
            {
                throw new SyntaxErrorException("Macro cannot result in any actions.", methodNode.Location);
            }

            return(result);
        }
Пример #3
0
        public void Out(TranslateRule context)
        {
            if (!IsInScope)
            {
                throw new Exception("ScopeGroup is already out of scope.");
            }

            IsInScope = false;

            foreach (IScopeable var in InScope)
            {
                if (var is IndexedVar)
                {
                    ((IndexedVar)var).OutOfScope(context);
                    VarCollection.Free((IndexedVar)var);
                }
            }

            for (int i = 0; i < Children.Count; i++)
            {
                if (Children[0].IsInScope)
                {
                    throw new Exception();
                }
            }
        }
 public SubroutineInfo(Subroutine routine, ReturnHandler returnHandler, TranslateRule rule, IndexReference[] parameterStores, IndexReference objectStore)
 {
     Subroutine      = routine;
     ReturnHandler   = returnHandler;
     Rule            = rule;
     ParameterStores = parameterStores;
     ObjectStore     = objectStore;
 }
        public ActionSet(TranslateRule translate, DocRange genericErrorRange, List <IActionList> actions)
        {
            Translate     = translate;
            IsGlobal      = translate.IsGlobal;
            ActionList    = translate.Actions;
            VarCollection = translate.DeltinScript.VarCollection;

            IndexAssigner = translate.DeltinScript.DefaultIndexAssigner;
        }
        public Element Parse(TranslateRule context, bool needsToBeValue, ScopeGroup scope, MethodNode methodNode, IWorkshopTree[] parameters)
        {
            Element result = Get(context, scope, methodNode, parameters);

            if (!needsToBeValue)
            {
                result = null;
            }

            return(result);
        }
Пример #7
0
        public static void Delete(Element index, TranslateRule context)
        {
            context.Actions.AddRange(
                context.ParserData.ClassArray.SetVariable(new V_Null(), null, index)
                );

            context.Actions.AddRange(context.ParserData.ClassIndexes.SetVariable(
                                         Element.Part <V_RemoveFromArray>(
                                             context.ParserData.ClassIndexes.GetVariable(),
                                             index
                                             )
                                         ));
        }
Пример #8
0
        override public void GetSource(TranslateRule context, Element element, Location location)
        {
            ElementOrigin origin = ElementOrigin.GetElementOrigin(element);

            if (origin == null)
            {
                throw new SyntaxErrorException("Could not get the type source.", location);
            }

            IndexedVar typeVar = origin.OriginVar(context.VarCollection, null, Name + " origin");

            typeVar.Type          = this;
            element.SupportedType = typeVar;
        }
Пример #9
0
        public override void OutOfScope(TranslateRule context, Element targetPlayer = null)
        {
            Element get = base.Get(targetPlayer);

            context.Actions.AddRange(base.SetVariable(
                                         Element.Part <V_ArraySlice>(
                                             get,
                                             new V_Number(0),
                                             Element.Part <V_CountOf>(get) - 1
                                             ),
                                         targetPlayer
                                         ));

            base.OutOfScope(context, targetPlayer);
        }
        public SubroutineStack(DeltinScript deltinScript, string subroutineName, string ruleName)
        {
            _deltinScript = deltinScript;

            // Setup the subroutine element.
            Subroutine = deltinScript.SubroutineCollection.NewSubroutine(subroutineName);

            // Create the rule.
            Rule = new TranslateRule(deltinScript, subroutineName, Subroutine);

            // Setup the return handler.
            ReturnHandler = new ReturnHandler(Rule.ActionSet, subroutineName, true);
            ActionSet     = Rule.ActionSet.New(ReturnHandler);

            AsyncLock();
        }
        // Sets up single-instance methods for methods with the 'rule' attribute.
        public void SetupSubroutine()
        {
            if (!IsSubroutine)
            {
                throw new Exception(Name + " does not have the subroutine attribute.");
            }

            // Setup the subroutine element.
            Subroutine subroutine = parseInfo.TranslateInfo.SubroutineCollection.NewSubroutine(Name);

            // Create the rule.
            TranslateRule subroutineRule = new TranslateRule(parseInfo.TranslateInfo, SubroutineName, subroutine);

            // Setup the return handler.
            ReturnHandler returnHandler = new ReturnHandler(subroutineRule.ActionSet, Name, multiplePaths);
            ActionSet     actionSet     = subroutineRule.ActionSet.New(returnHandler).New(subroutineRule.ActionSet.IndexAssigner.CreateContained());

            // Get the variables that will be used to store the parameters.
            IndexReference[] parameterStores = new IndexReference[ParameterVars.Length];
            for (int i = 0; i < ParameterVars.Length; i++)
            {
                parameterStores[i] = actionSet.IndexAssigner.Add(actionSet.VarCollection, ParameterVars[i], true, null, Attributes.Recursive) as IndexReference;
            }

            // If the subroutine is an object function inside a class, create a variable to store the class object.
            IndexReference objectStore = null;

            if (Attributes.ContainingType != null && !Static)
            {
                objectStore = actionSet.VarCollection.Assign("_" + Name + "_subroutineStore", true, true);
                Attributes.ContainingType.AddObjectVariablesToAssigner(objectStore.GetVariable(), actionSet.IndexAssigner);
            }

            // Set the subroutine info.
            subroutineInfo = new SubroutineInfo(subroutine, returnHandler, subroutineRule, parameterStores, objectStore);

            // Parse the block.
            block.Translate(actionSet);

            // Apply returns.
            returnHandler.ApplyReturnSkips();

            // Add the subroutine.
            parseInfo.TranslateInfo.WorkshopRules.Add(subroutineRule.GetRule());
        }
Пример #12
0
        private void GetObjects(RulesetNode rulesetNode, string file, TranslateRule globalTranslate, TranslateRule playerTranslate)
        {
            string absolute = new Uri(file).AbsolutePath;

            // Get the defined types
            foreach (var definedType in rulesetNode.DefinedTypes)
            {
                try
                {
                    if (DefinedTypes.Any(type => type.Name == definedType.Name))
                    {
                        throw SyntaxErrorException.NameAlreadyDefined(definedType.Location);
                    }
                    DefinedTypes.Add(DefinedType.GetDefinedType(definedType));
                }
                catch (SyntaxErrorException ex)
                {
                    Diagnostics.Error(ex);
                }
            }

            // Get the user methods.
            for (int i = 0; i < rulesetNode.UserMethods.Length; i++)
            {
                try
                {
                    UserMethods.Add(UserMethod.CreateUserMethod(Root, rulesetNode.UserMethods[i]));
                }
                catch (SyntaxErrorException ex)
                {
                    Diagnostics.Error(ex);
                }
            }

            // Get the rules
            RuleNodes.AddRange(rulesetNode.Rules);

            List <string> importedFiles = new List <string>();

            foreach (ImportObjectNode importObject in rulesetNode.ObjectImports)
            {
                try
                {
                    Importer importer = new Importer(Diagnostics, importedFiles, importObject.File, file, importObject.Location);
                    if (!importer.AlreadyImported)
                    {
                        importedFiles.Add(importer.ResultingPath);
                        switch (importer.FileType)
                        {
                        case ".obj":
                            importer.FileData.Update();
                            string content  = importer.FileData.Content;
                            Model  newModel = Model.ImportObj(content);
                            new ModelVar(importObject.Name, Root, importObject, newModel);
                            break;

                        case ".pathmap":
                            PathMap pathMap = PathMap.ImportFromXML(importer.ResultingPath);
                            new PathMapVar(this, importObject.Name, Root, importObject, pathMap);
                            break;
                        }
                    }
                }
                catch (SyntaxErrorException ex)
                {
                    Diagnostics.Error(ex);
                }
            }

            // Get the variables
            foreach (var definedVar in rulesetNode.DefinedVars)
            {
                try
                {
                    IndexedVar var;

                    if (!definedVar.Extended)
                    {
                        if (definedVar.OverrideID == -1)
                        {
                            var = IndexedVar.AssignVar(VarCollection, Root, definedVar.VariableName, definedVar.IsGlobal, definedVar);
                        }
                        else
                        {
                            var = IndexedVar.AssignVar(
                                VarCollection,
                                Root,
                                definedVar.VariableName,
                                definedVar.IsGlobal,
                                new WorkshopVariable(definedVar.IsGlobal, definedVar.OverrideID, VarCollection.WorkshopNameFromCodeName(definedVar.IsGlobal, definedVar.VariableName)),
                                definedVar
                                );
                        }
                    }
                    else
                    {
                        var = IndexedVar.AssignVarExt(VarCollection, Root, definedVar.VariableName, definedVar.IsGlobal, definedVar);
                    }


                    if (definedVar.Type != null)
                    {
                        var.Type = GetDefinedType(definedVar.Type, definedVar.Location);
                    }
                }
                catch (SyntaxErrorException ex)
                {
                    Diagnostics.Error(ex);
                }
            }
        }
Пример #13
0
        private ParsingData(string file, string content)
        {
            Rule initialGlobalValues = new Rule(Constants.INTERNAL_ELEMENT + "Initial Global Values");
            Rule initialPlayerValues = new Rule(Constants.INTERNAL_ELEMENT + "Initial Player Values", RuleEvent.OngoingPlayer, Team.All, PlayerSelector.All);

            globalTranslate = new TranslateRule(initialGlobalValues, Root, this);
            playerTranslate = new TranslateRule(initialPlayerValues, Root, this);

            GetRulesets(content, file, true, null);

            VarCollection = new VarCollection(ReservedGlobalIDs.ToArray(), ReservedGlobalNames.ToArray(), ReservedPlayerIDs.ToArray(), ReservedPlayerNames.ToArray());
            Root          = new ScopeGroup(VarCollection);
            ClassIndexes  = IndexedVar.AssignInternalVar(VarCollection, null, "_classIndexes", true);
            ClassArray    = IndexedVar.AssignInternalVar(VarCollection, null, "_classArray", true);

            if (!Diagnostics.ContainsErrors())
            {
                foreach (var ruleset in Rulesets)
                {
                    GetObjects(ruleset.Value, ruleset.Key, globalTranslate, playerTranslate);
                }
            }

            foreach (var type in DefinedTypes)
            {
                try
                {
                    type.RegisterParameters(this);
                }
                catch (SyntaxErrorException ex)
                {
                    Diagnostics.Error(ex);
                }
            }
            foreach (var method in UserMethods)
            {
                try
                {
                    method.RegisterParameters(this);
                }
                catch (SyntaxErrorException ex)
                {
                    Diagnostics.Error(ex);
                }
            }

            if (!Diagnostics.ContainsErrors())
            {
                // Parse the rules.
                Rules = new List <Rule>();

                for (int i = 0; i < RuleNodes.Count; i++)
                {
                    try
                    {
                        var result = TranslateRule.GetRule(RuleNodes[i], Root, this);
                        Rules.Add(result);
                    }
                    catch (SyntaxErrorException ex)
                    {
                        Diagnostics.Error(ex);
                    }
                }

                foreach (var definedVar in VarCollection.AllVars)
                {
                    try
                    {
                        if (definedVar is IndexedVar && definedVar.IsDefinedVar && definedVar.Scope == Root)
                        {
                            Node value = ((IDefine)definedVar.Node).Value;
                            if (value != null)
                            {
                                if (((IndexedVar)definedVar).IsGlobal)
                                {
                                    globalTranslate.Actions.AddRange(((IndexedVar)definedVar).SetVariable(globalTranslate.ParseExpression(Root, Root, value)));
                                }
                                else
                                {
                                    playerTranslate.Actions.AddRange(((IndexedVar)definedVar).SetVariable(playerTranslate.ParseExpression(Root, Root, value)));
                                }
                            }
                        }
                    }
                    catch (SyntaxErrorException ex)
                    {
                        Diagnostics.Error(ex);
                    }
                }

                globalTranslate.Finish();
                playerTranslate.Finish();

                // Add the player initial values rule if it was used.
                if (initialPlayerValues.Actions.Length > 0)
                {
                    Rules.Insert(0, initialPlayerValues);
                }

                // Add the global initial values rule if it was used.
                if (initialGlobalValues.Actions.Length > 0)
                {
                    Rules.Insert(0, initialGlobalValues);
                }

                foreach (Rule rule in AdditionalRules)
                {
                    if (rule.Actions.Length > 0)
                    {
                        Rules.Add(rule);
                    }
                }
            }

            Success = !Diagnostics.ContainsErrors();
        }
Пример #14
0
        void ToWorkshop(Func <VarCollection, Rule[]> addRules)
        {
            // Set up the variable collection.
            VarCollection.Setup();

            // Set up initial global and player rules.
            InitialGlobal = new TranslateRule(this, "Initial Global", RuleEvent.OngoingGlobal);
            InitialPlayer = new TranslateRule(this, "Initial Player", RuleEvent.OngoingPlayer);
            WorkshopRules = new List <Rule>();

            // Init called types.
            foreach (var type in Types.CalledTypes.Distinct())
            {
                type.WorkshopInit(this);
            }

            // Assign variables at the rule-set level.
            foreach (var variable in rulesetVariables)
            {
                // Assign the variable an index.
                var assigner = DefaultIndexAssigner.Add(VarCollection, variable, true, null) as IndexReference;

                // Assigner will be non-null if it is an IndexReference.
                if (assigner != null)
                {
                    DebugVariables.Add(variable, assigner);
                    // Initial value.
                    if (variable.InitialValue != null)
                    {
                        var addToInitialRule = GetInitialRule(variable.VariableType == VariableType.Global);

                        addToInitialRule.ActionSet.AddAction(assigner.SetVariable(
                                                                 (Element)variable.InitialValue.Parse(addToInitialRule.ActionSet)
                                                                 ));
                    }
                }
            }

            // Setup single-instance methods.
            foreach (var method in subroutines)
            {
                method.SetupSubroutine();
            }

            // Parse the rules.
            foreach (var rule in rules)
            {
                var  translate = new TranslateRule(this, rule);
                Rule newRule   = translate.GetRule();
                WorkshopRules.Add(newRule);
                rule.ElementCountLens.RuleParsed(newRule);
            }

            // Add built-in rules.
            // Initial player
            if (InitialPlayer.Actions.Count > 0)
            {
                WorkshopRules.Insert(0, InitialPlayer.GetRule());
            }

            // Initial global
            if (InitialGlobal.Actions.Count > 0)
            {
                WorkshopRules.Insert(0, InitialGlobal.GetRule());
            }

            // Additional
            if (addRules != null)
            {
                WorkshopRules.AddRange(addRules.Invoke(VarCollection).Where(rule => rule != null));
            }

            // Order the workshop rules by priority.
            WorkshopRules = WorkshopRules.OrderBy(wr => wr.Priority).ToList();

            // Get the final workshop string.
            WorkshopBuilder result = new WorkshopBuilder(Language);

            LanguageInfo.I18nWarningMessage(result, Language);

            // Get the custom game settings.
            if (Importer.MergedLobbySettings != null)
            {
                Ruleset settings = Ruleset.Parse(Importer.MergedLobbySettings);
                settings.ToWorkshop(result);
                result.AppendLine();
            }

            // Get the variables.
            VarCollection.ToWorkshop(result);
            result.AppendLine();

            // Print class identifiers.
            Types.PrintClassIdentifiers(result);

            // Get the subroutines.
            SubroutineCollection.ToWorkshop(result);

            // Get the rules.
            for (int i = 0; i < WorkshopRules.Count; i++)
            {
                WorkshopRules[i].ToWorkshop(result, OptimizeOutput);
                ElementCount += WorkshopRules[i].ElementCount(OptimizeOutput);
                if (i != WorkshopRules.Count - 1)
                {
                    result.AppendLine();
                }
            }

            WorkshopCode = result.ToString();
        }
        public static Rule GetRule(RuleNode ruleNode, ScopeGroup root, ParsingData parserData)
        {
            var result = new TranslateRule(ruleNode, root, parserData);

            return(result.Rule);
        }
 public static void Delete(Element index, TranslateRule context)
 {
     context.Actions.AddRange(context.VarCollection.WorkshopArrayBuilder.SetVariable(
                                  new V_Null(), true, null, Variable.C, index
                                  ));
 }
        override public Element Get(TranslateRule context, ScopeGroup scope, MethodNode methodNode, IWorkshopTree[] parameters)
        {
            Element result;

            if (!IsRecursive)
            {
                // Check the method stack if this method was already called.
                // Throw a syntax error if it was.
                if (context.MethodStackNotRecursive.Contains(this))
                {
                    throw SyntaxErrorException.RecursionNotAllowed(methodNode.Location);
                }

                var methodScope = scope.Root().Child();

                // Add the parameter variables to the scope.
                context.AssignParameterVariables(methodScope, Parameters, parameters, methodNode);

                // The variable that stores the return value.
                IndexedVar returns = null;
                if (DoesReturn)
                {
                    returns      = IndexedVar.AssignVar(context.VarCollection, scope, $"{methodNode.Name} return", context.IsGlobal, null);
                    returns.Type = Type;
                }

                // Add the method to the method stack
                context.MethodStackNotRecursive.Add(this);

                Block.RelatedScopeGroup = methodScope;

                // Parse the block of the method
                context.ParseBlock(methodScope, methodScope, Block, true, returns);

                // Take the method scope out of scope.
                methodScope.Out(context);

                // Remove the method from the stack.
                context.MethodStackNotRecursive.Remove(this);

                if (DoesReturn)
                {
                    result = returns.GetVariable();
                }
                else
                {
                    result = new V_Null();
                }
            }
            else
            {
                // Check the method stack if this method was already called. It will be null if it wasn't called.
                MethodStack lastMethod = context.MethodStackRecursive.FirstOrDefault(ms => ms.UserMethod == this);
                if (lastMethod != null)
                {
                    context.ContinueSkip.Setup();

                    // Re-push the paramaters.
                    for (int i = 0; i < lastMethod.ParameterVars.Length; i++)
                    {
                        if (lastMethod.ParameterVars[i] is RecursiveVar)
                        {
                            context.Actions.AddRange
                            (
                                ((RecursiveVar)lastMethod.ParameterVars[i]).InScope((Element)parameters[i])
                            );
                        }
                    }

                    // Add to the continue skip array.
                    context.Actions.AddRange(
                        lastMethod.ContinueSkipArray.SetVariable(
                            Element.Part <V_Append>(lastMethod.ContinueSkipArray.GetVariable(), new V_Number(context.ContinueSkip.GetSkipCount() + 3))
                            )
                        );

                    // Loop back to the start of the method.
                    context.ContinueSkip.SetSkipCount(lastMethod.ActionIndex);
                    context.Actions.Add(Element.Part <A_Loop>());

                    result = lastMethod.Return.GetVariable();
                }
                else
                {
                    var methodScope = scope.Root().Child(true);

                    // Add the parameter variables to the scope.
                    Var[] parameterVars = new Var[Parameters.Length];
                    for (int i = 0; i < parameterVars.Length; i++)
                    {
                        if (parameters[i] is Element)
                        {
                            // Create a new variable using the parameter input.
                            parameterVars[i] = (RecursiveVar)IndexedVar.AssignVar(context.VarCollection, methodScope, Parameters[i].Name, context.IsGlobal, methodNode);
                            ((RecursiveVar)parameterVars[i]).Type = ((Element)parameters[i]).SupportedType?.Type;
                            context.Actions.AddRange
                            (
                                ((RecursiveVar)parameterVars[i]).InScope((Element)parameters[i])
                            );
                        }
                        else if (parameters[i] is EnumMember)
                        {
                            parameterVars[i] = new ElementReferenceVar(Parameters[i].Name, methodScope, methodNode, parameters[i]);
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                    }

                    var returns = IndexedVar.AssignInternalVarExt(context.VarCollection, null, $"{methodNode.Name}: return", context.IsGlobal);
                    returns.Type = Type;

                    // Setup the continue skip array.
                    IndexedVar continueSkipArray = IndexedVar.AssignInternalVar(context.VarCollection, null, $"{methodNode.Name} sca", context.IsGlobal);
                    var        stack             = new MethodStack(this, parameterVars, context.ContinueSkip.GetSkipCount(), returns, continueSkipArray);

                    // Add the method to the stack.
                    context.MethodStackRecursive.Add(stack);

                    Block.RelatedScopeGroup = methodScope;

                    // Parse the method block
                    context.ParseBlock(methodScope, methodScope, Block, true, returns);

                    // No return value if the method is being used as an action.
                    result = returns.GetVariable();

                    // Take the method out of scope.
                    //Actions.AddRange(methodScope.RecursiveMethodStackPop());
                    methodScope.Out(context);

                    // Setup the next continue skip.
                    context.ContinueSkip.Setup();
                    context.ContinueSkip.SetSkipCount(Element.Part <V_LastOf>(continueSkipArray.GetVariable()));

                    // Remove the last continue skip.
                    context.Actions.AddRange(
                        continueSkipArray.SetVariable(
                            Element.Part <V_ArraySlice>(
                                continueSkipArray.GetVariable(),
                                new V_Number(0),
                                Element.Part <V_CountOf>(continueSkipArray.GetVariable()) - 1
                                )
                            )
                        );

                    // Loop if the method goes any deeper by checking the length of the continue skip array.
                    context.Actions.Add(
                        Element.Part <A_LoopIf>(
                            Element.Part <V_Compare>(
                                Element.Part <V_CountOf>(continueSkipArray.GetVariable()),
                                EnumData.GetEnumValue(Operators.NotEqual),
                                new V_Number(0)
                                )
                            )
                        );

                    // Reset the continue skip.
                    context.ContinueSkip.ResetSkip();
                    context.Actions.AddRange(continueSkipArray.SetVariable(0));

                    // Remove the method from the stack.
                    context.MethodStackRecursive.Remove(stack);
                }
            }

            return(result);
        }
Пример #18
0
        // Sets up single-instance methods for methods with the 'rule' attribute.
        public void SetupSubroutine()
        {
            if (subroutineInfo != null || !IsSubroutine)
            {
                return;
            }

            // Setup the subroutine element.
            Subroutine subroutine = parseInfo.TranslateInfo.SubroutineCollection.NewSubroutine(Name);

            // Create the rule.
            TranslateRule subroutineRule = new TranslateRule(parseInfo.TranslateInfo, subroutine, SubroutineName, subroutineDefaultGlobal);

            // Setup the return handler.
            ReturnHandler returnHandler = new ReturnHandler(subroutineRule.ActionSet, Name, multiplePaths || Attributes.Virtual);
            ActionSet     actionSet     = subroutineRule.ActionSet.New(returnHandler).New(subroutineRule.ActionSet.IndexAssigner.CreateContained());

            // Get the variables that will be used to store the parameters.
            IndexReference[] parameterStores = new IndexReference[ParameterVars.Length];
            for (int i = 0; i < ParameterVars.Length; i++)
            {
                // Create the workshop variable the parameter will be stored as.
                IndexReference indexResult = actionSet.IndexAssigner.AddIndexReference(actionSet.VarCollection, ParameterVars[i], subroutineDefaultGlobal, Attributes.Recursive);
                parameterStores[i] = indexResult;

                // Assign virtual variables to the index reference.
                foreach (Var virtualParameterOption in VirtualVarGroup(i))
                {
                    actionSet.IndexAssigner.Add(virtualParameterOption, indexResult);
                }
            }

            // If the subroutine is an object function inside a class, create a variable to store the class object.
            IndexReference objectStore = null;

            if (Attributes.ContainingType != null && !Static)
            {
                objectStore = actionSet.VarCollection.Assign("_" + Name + "_subroutineStore", true, !Attributes.Recursive);

                // Set the objectStore as an empty array if the subroutine is recursive.
                if (Attributes.Recursive)
                {
                    actionSet.InitialSet().AddAction(objectStore.SetVariable(new V_EmptyArray()));
                    Attributes.ContainingType.AddObjectVariablesToAssigner(Element.Part <V_LastOf>(objectStore.GetVariable()), actionSet.IndexAssigner);
                    actionSet = actionSet.New(Element.Part <V_LastOf>(objectStore.GetVariable())).PackThis();
                }
                else
                {
                    Attributes.ContainingType.AddObjectVariablesToAssigner(objectStore.GetVariable(), actionSet.IndexAssigner);
                    actionSet = actionSet.New(objectStore.GetVariable()).PackThis();
                }
            }

            // Set the subroutine info.
            subroutineInfo = new SubroutineInfo(subroutine, returnHandler, subroutineRule, parameterStores, objectStore);

            MethodBuilder builder = new MethodBuilder(this, actionSet, returnHandler);

            builder.BuilderSet = builder.BuilderSet.New(Attributes.Recursive);
            builder.ParseInner();

            // Apply returns.
            returnHandler.ApplyReturnSkips();

            // Pop object array and parameters if recursive.
            if (Attributes.Recursive)
            {
                if (objectStore != null)
                {
                    actionSet.AddAction(objectStore.ModifyVariable(Operation.RemoveFromArrayByIndex, Element.Part <V_CountOf>(objectStore.GetVariable()) - 1));
                }
                RecursiveStack.PopParameterStacks(actionSet, ParameterVars);
            }

            // Add the subroutine.
            Rule translatedRule = subroutineRule.GetRule();

            parseInfo.TranslateInfo.WorkshopRules.Add(translatedRule);

            var codeLens = new ElementCountCodeLens(DefinedAt.range, parseInfo.TranslateInfo.OptimizeOutput);

            parseInfo.Script.AddCodeLensRange(codeLens);
            codeLens.RuleParsed(translatedRule);
        }
        protected void SetupNew(ScopeGroup getter, ScopeGroup scope, IndexedVar store, ScopeGroup typeScope, TranslateRule context, CreateObjectNode node)
        {
            // Set the default variables in the struct
            for (int i = 0; i < DefinedVars.Length; i++)
            {
                if (DefinedVars[i].Value != null)
                {
                    context.Actions.AddRange(
                        store.SetVariable(context.ParseExpression(typeScope, typeScope, DefinedVars[i].Value), null, new V_Number(i))
                        );
                }
            }

            Constructor constructor = Constructors.FirstOrDefault(c => c.Parameters.Length == node.Parameters.Length);

            if (constructor == null && !(node.Parameters.Length == 0 && Constructors.Length == 0))
            {
                throw SyntaxErrorException.NotAConstructor(TypeKind, Name, node.Parameters.Length, node.Location);
            }

            if (constructor != null)
            {
                ScopeGroup constructorScope = typeScope.Child();

                IWorkshopTree[] parameters = context.ParseParameters(
                    getter,
                    scope,
                    constructor.Parameters,
                    node.Parameters,
                    node.TypeName,
                    node.Location
                    );

                context.AssignParameterVariables(constructorScope, constructor.Parameters, parameters, node);
                context.ParseBlock(typeScope, constructorScope, constructor.BlockNode, true, null);
                constructorScope.Out(context);
            }
        }
 abstract public Element New(CreateObjectNode node, ScopeGroup getter, ScopeGroup scope, TranslateRule context);
Пример #21
0
 abstract public void GetSource(TranslateRule context, Element element, Location location);
            public ParseExpressionTree(TranslateRule translator, ScopeGroup getter, ScopeGroup scope, Node root)
            {
                if (root is VariableNode)
                {
                    VariableNode variableNode = (VariableNode)root;

                    Var var = scope.GetVar(getter, ((VariableNode)root).Name, root.Location);
                    ResultingVariable = var;

                    //if (!ResultingVariable.Gettable()) throw SyntaxErrorException.CantReadVariable(ResultingVariable.Name, root.Location);

                    if (ResultingVariable.Gettable())
                    {
                        ResultingElement = var.GetVariable();
                    }

                    VariableIndex = new Element[variableNode.Index.Length];
                    for (int i = 0; i < VariableIndex.Length; i++)
                    {
                        VariableIndex[i] = translator.ParseExpression(getter, scope, variableNode.Index[i]);
                    }

                    for (int i = 0; i < VariableIndex.Length; i++)
                    {
                        if (!ResultingVariable.Gettable())
                        {
                            throw SyntaxErrorException.CantReadVariable(ResultingVariable.Name, root.Location);
                        }
                        ResultingElement = Element.Part <V_ValueInArray>(ResultingElement, VariableIndex[i]);
                    }

                    return;
                }

                if (root is ExpressionTreeNode == false)
                {
                    throw new SyntaxErrorException("Error", root.Location);
                }

                List <Node> nodes        = flatten((ExpressionTreeNode)root);
                ScopeGroup  currentScope = scope;

                Element nodeResult = null;

                for (int index = 0; index < nodes.Count; index++)
                {
                    if (nodes[index] is RootNode)
                    {
                        currentScope = translator.ParserData.Root;
                        nodeResult   = new V_Null();
                    }
                    // If the node is a variable node, get the value.
                    else if (nodes[index] is VariableNode)
                    {
                        VariableNode variableNode = (VariableNode)nodes[index];
                        Var          var          = currentScope.GetVar(getter, variableNode.Name, variableNode.Location);

                        // If this is the last node, set the resulting var.
                        if (index == nodes.Count - 1)
                        {
                            ResultingVariable = var;
                        }

                        // Get the variable index
                        VariableIndex = new Element[variableNode.Index.Length];
                        for (int i = 0; i < VariableIndex.Length; i++)
                        {
                            VariableIndex[i] = translator.ParseExpression(getter, scope, variableNode.Index[i]);
                        }

                        // Set the nodeResult.
                        nodeResult = var.GetVariable(Target);

                        // Apply the index
                        for (int i = 0; i < VariableIndex.Length; i++)
                        {
                            nodeResult = Element.Part <V_ValueInArray>(nodeResult, VariableIndex[i]);
                        }
                    }
                    // If not, parse the node as an expression.
                    else
                    {
                        nodeResult = translator.ParseExpression(getter, currentScope, nodes[index]);
                    }

                    // SupportedType will equal null if the element is not a defined type.
                    if (nodeResult.SupportedType == null)
                    {
                        // If there is no supported type, assume the element or variable is containing a player.
                        // Reset the scope.
                        //currentScope = scope;
                        currentScope = translator.ParserData.Root;

                        // If this isn't the last node, set the target and reset the nodeResult.
                        if (index < nodes.Count - 1)
                        {
                            Target     = nodeResult;
                            nodeResult = null;
                        }
                    }
                    else
                    {
                        // Set the target scope to the type.
                        currentScope = nodeResult.SupportedType.Type.GetRootScope(nodeResult, nodeResult.SupportedType, translator.ParserData, Target);
                    }
                }
                ResultingElement = nodeResult;
            }
Пример #23
0
        override public Element New(CreateObjectNode node, ScopeGroup getter, ScopeGroup scope, TranslateRule context)
        {
            context.ParserData.SetupClasses();

            // Get the index to store the class.
            IndexedVar index        = IndexedVar.AssignInternalVarExt(context.VarCollection, scope, "New " + Name + " class index", context.IsGlobal); // Assigns the index variable.
            Element    takenIndexes = context.ParserData.ClassIndexes.GetVariable();

            // Get an empty index in the class array to store the new class.
            Element firstFree = (
                Element.Part <V_FirstOf>(
                    Element.Part <V_FilteredArray>(
                        // Sort the taken index array.
                        Element.Part <V_SortedArray>(takenIndexes, new V_ArrayElement()),
                        // Filter
                        Element.Part <V_And>(
                            // If the previous index was not taken, use that index.
                            !(Element.Part <V_ArrayContains>(
                                  takenIndexes,
                                  new V_ArrayElement() - 1
                                  )),
                            // Make sure the index does not equal 0 so the resulting index is not -1.
                            new V_Compare(new V_ArrayElement(), Operators.NotEqual, new V_Number(0))
                            )
                        )
                    ) -
                1 // Subtract 1 to get the previous index
                );

            // If the taken index array has 0 elements, just use the length of the class array subtracted by 1.
            firstFree = Element.TernaryConditional(
                new V_Compare(Element.Part <V_CountOf>(takenIndexes), Operators.NotEqual, new V_Number(0)),
                firstFree,
                Element.Part <V_CountOf>(context.ParserData.ClassArray.GetVariable()) - 1
                );

            context.Actions.AddRange(index.SetVariable(firstFree));

            context.Actions.AddRange(
                index.SetVariable(
                    Element.TernaryConditional(
                        // If the index equals -1, use the length of the class array instead.
                        new V_Compare(index.GetVariable(), Operators.Equal, new V_Number(-1)),
                        Element.Part <V_CountOf>(context.ParserData.ClassArray.GetVariable()),
                        index.GetVariable()
                        )
                    )
                );

            // Add the selected index to the taken indexes array.
            context.Actions.AddRange(
                context.ParserData.ClassIndexes.SetVariable(
                    Element.Part <V_Append>(
                        context.ParserData.ClassIndexes.GetVariable(),
                        index.GetVariable()
                        )
                    )
                );

            // The direct reference to the class variable.
            IndexedVar store = context.ParserData.ClassArray.CreateChild(scope, Name + " root", new Element[] { index.GetVariable() }, null);

            store.Index[0].SupportedType = store;
            store.Type = this;

            ScopeGroup typeScope = GetRootScope(index.GetVariable(), store, context.ParserData);

            SetupNew(getter, scope, store, typeScope, context, node);

            return(index.GetVariable());
        }
 abstract public Element Get(TranslateRule context, ScopeGroup scope, MethodNode methodNode, IWorkshopTree[] parameters);
        void ToWorkshop(Func <VarCollection, Rule[]> addRules)
        {
            // Set up the variable collection.
            VarCollection.Setup();

            WorkshopConverter = new ToWorkshop(this);

            // Set up initial global and player rules.
            InitialGlobal = new TranslateRule(this, "Initial Global", RuleEvent.OngoingGlobal);
            InitialPlayer = new TranslateRule(this, "Initial Player", RuleEvent.OngoingPlayer);
            WorkshopRules = new List <Rule>();

            WorkshopConverter.InitStatic();

            // Init called types.
            foreach (var workshopInit in _workshopInit)
            {
                workshopInit.WorkshopInit(this);
            }

            // Assign variables at the rule-set level.
            foreach (var variable in rulesetVariables)
            {
                var addToInitialRule = GetInitialRule(variable.VariableType == VariableType.Global);

                // Assign the variable an index.
                IGettable value = variable
                                  .GetDefaultInstance(null)
                                  .GetAssigner(new(addToInitialRule.ActionSet))
                                  .GetValue(new GettableAssignerValueInfo(addToInitialRule.ActionSet)
                {
                    SetInitialValue = SetInitialValue.SetIfExists
                });
                DefaultIndexAssigner.Add(variable, value);

                if (value is IndexReference indexReference)
                {
                    DebugVariables.Add(variable, indexReference);
                }
            }

            // Parse the rules.
            foreach (var rule in rules)
            {
                var  translate = new TranslateRule(this, rule);
                Rule newRule   = GetRule(translate.GetRule());
                WorkshopRules.Add(newRule);
                rule.ElementCountLens.RuleParsed(newRule);
            }

            // Add built-in rules.
            // Initial player
            if (InitialPlayer.Actions.Count > 0)
            {
                WorkshopRules.Insert(0, GetRule(InitialPlayer.GetRule()));
            }

            // Initial global
            if (InitialGlobal.Actions.Count > 0)
            {
                WorkshopRules.Insert(0, GetRule(InitialGlobal.GetRule()));
            }

            // Additional
            if (addRules != null)
            {
                WorkshopRules.AddRange(addRules.Invoke(VarCollection).Where(rule => rule != null));
            }

            // Complete portable functions
            WorkshopConverter.LambdaBuilder.Complete();

            // Order the workshop rules by priority.
            WorkshopRules = WorkshopRules.OrderBy(wr => wr.Priority).ToList();

            // Get the final workshop string.
            WorkshopBuilder result = new WorkshopBuilder(Language);

            LanguageInfo.I18nWarningMessage(result, Language);

            // Get the custom game settings.
            if (Importer.MergedLobbySettings != null)
            {
                Ruleset settings = Ruleset.Parse(Importer.MergedLobbySettings);
                settings.ToWorkshop(result);
                result.AppendLine();
            }

            // Get the variables.
            VarCollection.ToWorkshop(result);
            result.AppendLine();

            // Get the subroutines.
            SubroutineCollection.ToWorkshop(result);

            // Get the rules.
            for (int i = 0; i < WorkshopRules.Count; i++)
            {
                WorkshopRules[i].ToWorkshop(result);
                ElementCount += WorkshopRules[i].ElementCount();
                if (i != WorkshopRules.Count - 1)
                {
                    result.AppendLine();
                }
            }

            WorkshopCode = result.GetResult();
        }
        void ToWorkshop(Func <VarCollection, Rule[]> addRules)
        {
            VarCollection.Setup();
            InitialGlobal = new TranslateRule(this, "Initial Global", RuleEvent.OngoingGlobal);
            InitialPlayer = new TranslateRule(this, "Initial Player", RuleEvent.OngoingPlayer);
            WorkshopRules = new List <Rule>();

            foreach (var variable in rulesetVariables)
            {
                // Assign the variable an index.
                DefaultIndexAssigner.Add(VarCollection, variable, true, null);

                var assigner = DefaultIndexAssigner[variable] as IndexReference;
                if (assigner != null && variable.InitialValue != null)
                {
                    var addToInitialRule = GetInitialRule(variable.VariableType == VariableType.Global);

                    addToInitialRule.ActionSet.AddAction(assigner.SetVariable(
                                                             (Element)variable.InitialValue.Parse(addToInitialRule.ActionSet)
                                                             ));
                }
            }

            foreach (var rule in rules)
            {
                var translate = new TranslateRule(this, rule);
                WorkshopRules.Add(translate.GetRule());
            }

            if (InitialPlayer.Actions.Count > 0)
            {
                WorkshopRules.Insert(0, InitialPlayer.GetRule());
            }

            if (InitialGlobal.Actions.Count > 0)
            {
                WorkshopRules.Insert(0, InitialGlobal.GetRule());
            }

            if (addRules != null)
            {
                WorkshopRules.AddRange(addRules.Invoke(VarCollection).Where(rule => rule != null));
            }

            // Get the final workshop string.
            StringBuilder result = new StringBuilder();

            I18n.I18n.I18nWarningMessage(result, I18n.I18n.CurrentLanguage);

            // Get the variables.
            VarCollection.ToWorkshop(result, I18n.I18n.CurrentLanguage);
            result.AppendLine();

            // Get the rules.
            foreach (var rule in WorkshopRules)
            {
                result.AppendLine(rule.ToWorkshop(I18n.I18n.CurrentLanguage));
            }

            WorkshopCode = result.ToString();
        }
        void ToWorkshop(Func <VarCollection, Rule[]> addRules)
        {
            // Set up the variable collection.
            VarCollection.Setup();

            // Set up initial global and player rules.
            InitialGlobal = new TranslateRule(this, "Initial Global", RuleEvent.OngoingGlobal);
            InitialPlayer = new TranslateRule(this, "Initial Player", RuleEvent.OngoingPlayer);
            WorkshopRules = new List <Rule>();

            // Assign static variables.
            foreach (var type in types)
            {
                type.WorkshopInit(this);
            }

            // Assign variables at the rule-set level.
            foreach (var variable in rulesetVariables)
            {
                // Assign the variable an index.
                DefaultIndexAssigner.Add(VarCollection, variable, true, null);

                var assigner = DefaultIndexAssigner[variable] as IndexReference;
                if (assigner != null && variable.InitialValue != null)
                {
                    var addToInitialRule = GetInitialRule(variable.VariableType == VariableType.Global);

                    addToInitialRule.ActionSet.AddAction(assigner.SetVariable(
                                                             (Element)variable.InitialValue.Parse(addToInitialRule.ActionSet)
                                                             ));
                }
            }

            // Setup single-instance methods.
            foreach (var method in subroutines)
            {
                method.SetupSubroutine();
            }

            // Parse the rules.
            foreach (var rule in rules)
            {
                var translate = new TranslateRule(this, rule);
                WorkshopRules.Add(translate.GetRule());
            }

            if (InitialPlayer.Actions.Count > 0)
            {
                WorkshopRules.Insert(0, InitialPlayer.GetRule());
            }

            if (InitialGlobal.Actions.Count > 0)
            {
                WorkshopRules.Insert(0, InitialGlobal.GetRule());
            }

            if (addRules != null)
            {
                WorkshopRules.AddRange(addRules.Invoke(VarCollection).Where(rule => rule != null));
            }

            // Order the workshop rules by priority.
            WorkshopRules = WorkshopRules.OrderBy(wr => wr.Priority).ToList();

            // Get the final workshop string.
            WorkshopBuilder result = new WorkshopBuilder(Language);

            LanguageInfo.I18nWarningMessage(result, Language);

            // Get the custom game settings.
            if (MergedLobbySettings != null)
            {
                Ruleset settings = Ruleset.Parse(MergedLobbySettings);
                settings.ToWorkshop(result);
                result.AppendLine();
            }

            // Get the variables.
            VarCollection.ToWorkshop(result);
            result.AppendLine();

            // Get the subroutines.
            SubroutineCollection.ToWorkshop(result);

            // Get the rules.
            foreach (var rule in WorkshopRules)
            {
                result.AppendLine(rule.ToWorkshop(Language, OptimizeOutput));
            }

            WorkshopCode = result.ToString();
        }
        override public Element New(CreateObjectNode node, ScopeGroup getter, ScopeGroup scope, TranslateRule context)
        {
            IndexedVar store = context.VarCollection.AssignVar(scope, Name + " store", context.IsGlobal, null);

            store.Type = this;
            ScopeGroup typeScope = GetRootScope(store, context.ParserData);

            SetupNew(getter, scope, store, typeScope, context, node);

            return(store.GetVariable());
        }
        override public Element New(CreateObjectNode node, ScopeGroup getter, ScopeGroup scope, TranslateRule context)
        {
            // Get the index to store the class.
            IndexedVar index = context.VarCollection.AssignVar(scope, "New " + Name + " class index", context.IsGlobal, null); // Assigns the index variable.

            // Get the index of the next free spot in the class array.
            context.Actions.AddRange(
                index.SetVariable(
                    Element.Part <V_IndexOfArrayValue>(
                        WorkshopArrayBuilder.GetVariable(true, null, Variable.C),
                        new V_Null()
                        )
                    )
                );
            // Set the index to the count of the class array if the index equals -1.
            context.Actions.AddRange(
                index.SetVariable(
                    Element.TernaryConditional(
                        new V_Compare(index.GetVariable(), Operators.Equal, new V_Number(-1)),
                        Element.Part <V_CountOf>(
                            WorkshopArrayBuilder.GetVariable(true, null, Variable.C)
                            ),
                        index.GetVariable()
                        )
                    )
                );
            // The direct reference to the class variable.
            IndexedVar store = new IndexedVar(
                scope,
                Name + " root",
                true,
                Variable.C,
                new Element[] { index.GetVariable() },
                context.VarCollection.WorkshopArrayBuilder,
                null
                );

            store.Index[0].SupportedType = store;
            store.Type = this;

            ScopeGroup typeScope = GetRootScope(store, context.ParserData);

            SetupNew(getter, scope, store, typeScope, context, node);

            return(index.GetVariable());
        }
Пример #30
0
        private void GetObjects(string document, string file, TranslateRule globalTranslate, TranslateRule playerTranslate, bool isRoot)
        {
            // If this file was already loaded, don't load it again.
            if (Imported.Contains(file))
            {
                return;
            }
            Imported.Add(file);
            Diagnostics.AddFile(file);

            // Get the ruleset.
            RulesetNode ruleset = GetRuleset(file, document);

            Rulesets.Add(file, ruleset);

            if (ruleset != null && !Diagnostics.ContainsErrors())
            {
                if (isRoot)
                {
                    VarCollection = new VarCollection(ruleset.UseGlobalVar, ruleset.UsePlayerVar, ruleset.UseBuilderVar);
                    Root          = new ScopeGroup(VarCollection);
                }

                // Get the defined types
                foreach (var definedType in ruleset.DefinedTypes)
                {
                    try
                    {
                        if (DefinedTypes.Any(type => type.Name == definedType.Name))
                        {
                            throw SyntaxErrorException.NameAlreadyDefined(definedType.Location);
                        }
                        DefinedTypes.Add(DefinedType.GetDefinedType(definedType));
                    }
                    catch (SyntaxErrorException ex)
                    {
                        Diagnostics.Error(ex);
                    }
                }

                // Get the user methods.
                for (int i = 0; i < ruleset.UserMethods.Length; i++)
                {
                    try
                    {
                        UserMethods.Add(new UserMethod(Root, ruleset.UserMethods[i]));
                    }
                    catch (SyntaxErrorException ex)
                    {
                        Diagnostics.Error(ex);
                    }
                }

                // Get the rules
                RuleNodes.AddRange(ruleset.Rules);

                List <string> importedFiles = new List <string>();

                foreach (ImportObjectNode importObject in ruleset.ObjectImports)
                {
                    try
                    {
                        Importer importer = new Importer(Diagnostics, importedFiles, importObject.File, file, importObject.Location);
                        if (!importer.AlreadyImported)
                        {
                            importedFiles.Add(importer.ResultingPath);
                            string content = importer.GetFile();
                            switch (importer.FileType)
                            {
                            case ".obj":
                                Model newModel = Model.ImportObj(content);
                                new ModelVar(importObject.Name, Root, importObject, newModel);
                                break;
                            }
                        }
                    }
                    catch (SyntaxErrorException ex)
                    {
                        Diagnostics.Error(ex);
                    }
                }

                // Check the imported files.
                foreach (ImportNode importNode in ruleset.Imports)
                {
                    try
                    {
                        Importer importer = new Importer(Diagnostics, importedFiles, importNode.File, file, importNode.Location);
                        if (!importer.AlreadyImported)
                        {
                            string content = File.ReadAllText(importer.ResultingPath);
                            GetObjects(content, importer.ResultingPath, globalTranslate, playerTranslate, false);
                            importedFiles.Add(importer.ResultingPath);
                        }
                    }
                    catch (SyntaxErrorException ex)
                    {
                        Diagnostics.Error(ex);
                    }
                }

                // Get the variables
                foreach (var definedVar in ruleset.DefinedVars)
                {
                    try
                    {
                        IndexedVar var;
                        if (definedVar.UseVar == null)
                        {
                            var = VarCollection.AssignVar(Root, definedVar.VariableName, definedVar.IsGlobal, definedVar);
                        }
                        else
                        {
                            var = VarCollection.AssignVar(
                                Root,
                                definedVar.VariableName,
                                definedVar.IsGlobal,
                                definedVar.UseVar.Variable,
                                definedVar.UseVar.Index,
                                definedVar
                                );
                        }
                        if (definedVar.Type != null)
                        {
                            var.Type = GetDefinedType(definedVar.Type, definedVar.Location);
                        }
                    }
                    catch (SyntaxErrorException ex)
                    {
                        Diagnostics.Error(ex);
                    }
                }
            }
        }