Esempio n. 1
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();
                }
            }
        }
Esempio n. 2
0
 public ClassData(VarCollection varCollection)
 {
     ClassArray = varCollection.Assign("_classArray", true, false);
     if (DefinedType.CLASS_INDEX_WORKAROUND)
     {
         ClassIndexes = varCollection.Assign("_classIndexes", true, false);
     }
 }
Esempio n. 3
0
        public static IndexedVar AssignVar(VarCollection collection, ScopeGroup scope, string name, bool isGlobal, Node node)
        {
            WorkshopVariable assignedVariable = collection.Assign(name, isGlobal);
            IndexedVar       var = CreateVar(collection.WorkshopArrayBuilder, scope, name, isGlobal, assignedVariable, null, node);

            collection.AllVars.Add(var);
            return(var);
        }
        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 TranslateRule(Rule rule, ScopeGroup root, ParsingData parserData)
        {
            VarCollection = parserData.VarCollection;
            ParserData    = parserData;

            Rule     = rule;
            IsGlobal = Rule.IsGlobal;

            ContinueSkip = new ContinueSkip(IsGlobal, Actions, VarCollection);
        }
        public IndexReference GetClassVariableStack(VarCollection collection, int index)
        {
            if (index > VariableStacks.Count)
            {
                throw new Exception("Variable stack skipped");
            }
            if (index == VariableStacks.Count)
            {
                VariableStacks.Add(collection.Assign("_objectVariable_" + index, true, false));
            }

            return(VariableStacks[index]);
        }
        private ActionSet(ActionSet other)
        {
            Translate     = other.Translate;
            IsGlobal      = other.IsGlobal;
            ActionList    = other.ActionList;
            VarCollection = other.VarCollection;

            GenericErrorRange = other.GenericErrorRange;
            IndexAssigner     = other.IndexAssigner;
            ReturnHandler     = other.ReturnHandler;
            CurrentObject     = other.CurrentObject;
            This        = other.This;
            IndentCount = other.IndentCount;
            IsRecursive = other.IsRecursive;
        }
Esempio n. 8
0
        public IGettable Add(VarCollection varCollection, Var var, bool isGlobal, IWorkshopTree referenceValue, bool recursive = false)
        {
            if (varCollection == null)
            {
                throw new ArgumentNullException(nameof(varCollection));
            }
            if (var == null)
            {
                throw new ArgumentNullException(nameof(var));
            }

            if (references.ContainsKey(var))
            {
                throw new Exception(var.Name + " was already added into the variable index assigner.");
            }

            IGettable assigned;

            // A gettable/settable variable
            if (var.Settable())
            {
                assigned = varCollection.Assign(var, isGlobal);
                if (recursive)
                {
                    assigned = new RecursiveIndexReference((IndexReference)assigned);
                }
                references.Add(var, assigned);
            }

            // Element reference
            else if (var.VariableType == VariableType.ElementReference)
            {
                if (referenceValue == null)
                {
                    throw new ArgumentNullException(nameof(referenceValue));
                }
                assigned = new WorkshopElementReference(referenceValue);
                references.Add(var, assigned);
            }

            else
            {
                throw new NotImplementedException();
            }

            return(assigned);
        }
Esempio n. 9
0
        public static IndexedVar AssignVarExt(VarCollection collection, ScopeGroup scope, string name, bool isGlobal, Node node)
        {
            int        index = collection.NextFreeExtended(isGlobal);
            IndexedVar var   = CreateVar(
                collection.WorkshopArrayBuilder,
                scope,
                name,
                isGlobal,
                collection.UseVariable(isGlobal),
                new Element[] { new V_Number(index) },
                node
                );

            collection.AllVars.Add(var);
            collection.UseExtendedCollection(isGlobal)[index] = var;
            return(var);
        }
        public IGettable Add(VarCollection varCollection, IIndexReferencer var, bool isGlobal, IWorkshopTree referenceValue, bool recursive = false)
        {
            if (varCollection == null)
            {
                throw new ArgumentNullException(nameof(varCollection));
            }
            if (var == null)
            {
                throw new ArgumentNullException(nameof(var));
            }
            CheckIfAdded(var);

            IGettable assigned;

            // A gettable/settable variable
            if (var.Settable())
            {
                assigned = varCollection.Assign(var, isGlobal);
                if (recursive || var.Recursive)
                {
                    assigned = new RecursiveIndexReference((IndexReference)assigned);
                }
                references.Add(var, assigned);
            }

            // Element reference
            else if (var.VariableType == VariableType.ElementReference)
            {
                if (referenceValue == null)
                {
                    throw new ArgumentNullException(nameof(referenceValue));
                }
                assigned = new WorkshopElementReference(referenceValue);
                references.Add(var, assigned);
            }

            else
            {
                throw new NotImplementedException();
            }

            return(assigned);
        }
Esempio n. 11
0
        public static IndexedVar AssignVar(VarCollection collection, ScopeGroup scope, string name, bool isGlobal, WorkshopVariable variable, Node node)
        {
            string workshopName = variable.Name;

            if (workshopName == null)
            {
                workshopName = collection.WorkshopNameFromCodeName(isGlobal, name);
            }

            int id = variable.ID;

            if (id == -1)
            {
                id = collection.NextFree(isGlobal);
            }
            else
            {
                WorkshopVariable assigned = collection.FromID(isGlobal, variable.ID);
                if (assigned != null)
                {
                    throw new SyntaxErrorException("Variable ID '" + variable.ID + "' has already been assigned by '" + assigned.Name + "'.", node.Location);
                }
            }

            WorkshopVariable use = new WorkshopVariable(isGlobal, id, workshopName);

            IndexedVar var = CreateVar(
                collection.WorkshopArrayBuilder,
                scope,
                name,
                isGlobal,
                use,
                null,
                node
                );

            collection.AllVars.Add(var);
            collection.UseCollection(isGlobal)[id] = use;
            return(var);
        }
        public IndexReference AddIndexReference(VarCollection varCollection, Var var, bool isGlobal, bool recursive = false)
        {
            if (varCollection == null)
            {
                throw new ArgumentNullException(nameof(varCollection));
            }
            if (var == null)
            {
                throw new ArgumentNullException(nameof(var));
            }
            CheckIfAdded(var);

            IndexReference assigned = varCollection.Assign(var, isGlobal);

            if (recursive)
            {
                assigned = new RecursiveIndexReference((IndexReference)assigned);
            }
            references.Add(var, assigned);

            return(assigned);
        }
        private TranslateRule(RuleNode ruleNode, ScopeGroup root, ParsingData parserData)
        {
            VarCollection = parserData.VarCollection;
            ParserData    = parserData;

            Rule          = new Rule(ruleNode.Name, ruleNode.Event, ruleNode.Team, ruleNode.Player);
            Rule.Disabled = ruleNode.Disabled;
            IsGlobal      = Rule.IsGlobal;

            ContinueSkip = new ContinueSkip(IsGlobal, Actions, VarCollection);

            ParseConditions(root, ruleNode.Conditions);

            // Parse the block of the rule.
            ScopeGroup ruleScope = root.Child();

            ParseBlock(ruleScope, ruleScope, ruleNode.Block, false, null);

            // Fulfill remaining returns.
            FulfillReturns(0);

            Finish();
        }
Esempio n. 14
0
        public void Add(VarCollection varCollection, Var var, bool isGlobal, IWorkshopTree referenceValue, bool recursive = false)
        {
            if (varCollection == null)
            {
                throw new ArgumentNullException(nameof(varCollection));
            }
            if (var == null)
            {
                throw new ArgumentNullException(nameof(var));
            }

            // A gettable/settable variable
            if (var.Settable())
            {
                var assigned = varCollection.Assign(var, isGlobal);
                if (recursive)
                {
                    assigned = new RecursiveIndexReference(assigned);
                }
                references.Add(var, assigned);
            }

            // Element reference
            else if (var.VariableType == VariableType.ElementReference)
            {
                if (referenceValue == null)
                {
                    throw new ArgumentNullException(nameof(referenceValue));
                }
                references.Add(var, new WorkshopElementReference(referenceValue));
            }

            else
            {
                throw new NotImplementedException();
            }
        }
        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));
                }
            }
        }
Esempio n. 16
0
 public ActionSet(bool isGlobal, VarCollection varCollection)
 {
     IsGlobal      = isGlobal;
     VarCollection = varCollection;
     ActionList    = new List <IActionList>();
 }
 public WorkshopArrayBuilder(VarCollection varCollection) => _varCollection = varCollection;
        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 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));
                }
            }
        }
Esempio n. 20
0
        public static ParserData GetParser(string document, Pos documentPos)
        {
            AntlrInputStream inputStream = new AntlrInputStream(document);

            // Lexer
            DeltinScriptLexer lexer             = new DeltinScriptLexer(inputStream);
            CommonTokenStream commonTokenStream = new CommonTokenStream(lexer);

            // Parse
            DeltinScriptParser parser = new DeltinScriptParser(commonTokenStream);
            var errorListener         = new ErrorListener();

            parser.RemoveErrorListeners();
            parser.AddErrorListener(errorListener);

            DeltinScriptParser.RulesetContext ruleSetContext = parser.ruleset();

            List <Diagnostic> diagnostics = new List <Diagnostic>();

            diagnostics.AddRange(errorListener.Errors);

            // Get the ruleset node.
            BuildAstVisitor bav         = null;
            RulesetNode     ruleSetNode = null;

            if (diagnostics.Count == 0)
            {
                bav         = new BuildAstVisitor(documentPos, diagnostics);
                ruleSetNode = (RulesetNode)bav.Visit(ruleSetContext);
            }

            VarCollection     varCollection = null;
            ScopeGroup        root          = null;
            List <UserMethod> userMethods   = null;

            Rule[] rules   = null;
            bool   success = false;

            AdditionalErrorChecking aec = new AdditionalErrorChecking(parser, diagnostics);

            aec.Visit(ruleSetContext);

            bool parse = diagnostics.Count == 0;

            if (parse)
            {
                varCollection = new VarCollection();
                root          = new ScopeGroup();
                userMethods   = new List <UserMethod>();

                foreach (var definedVar in ruleSetNode.DefinedVars)
                {
                    varCollection.AssignDefinedVar(root, definedVar.IsGlobal, definedVar.VariableName, definedVar.Range);
                }

                // Get the user methods.
                for (int i = 0; i < ruleSetNode.UserMethods.Length; i++)
                {
                    userMethods.Add(new UserMethod(ruleSetNode.UserMethods[i]));
                }

                // Parse the rules.
                rules = new Rule[ruleSetNode.Rules.Length];

                for (int i = 0; i < rules.Length; i++)
                {
                    try
                    {
                        var result = Translate.GetRule(ruleSetNode.Rules[i], root, varCollection, userMethods.ToArray());
                        rules[i] = result.Rule;
                        diagnostics.AddRange(result.Diagnostics);
                    }
                    catch (SyntaxErrorException ex)
                    {
                        diagnostics.Add(new Diagnostic(ex.Message, ex.Range)
                        {
                            severity = Diagnostic.Error
                        });
                    }
                }

                success = true;
            }

            return(new ParserData()
            {
                Parser = parser,
                RulesetContext = ruleSetContext,
                RuleSetNode = ruleSetNode,
                Bav = bav,
                Diagnostics = diagnostics,
                Rules = rules,
                UserMethods = userMethods?.ToArray(),
                Root = root,
                Success = success,
                VarCollection = varCollection
            });
        }
        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();
        }
Esempio n. 22
0
 private ScopeGroup(VarCollection varCollection, ScopeGroup parent, bool recursive) : this(varCollection)
 {
     Parent    = parent;
     Recursive = recursive;
 }
Esempio n. 23
0
 private ScopeGroup(VarCollection varCollection, ScopeGroup parent) : this(varCollection)
 {
     Parent    = parent;
     Recursive = parent.Recursive;
 }
Esempio n. 24
0
        private Translate(RuleNode ruleNode, ScopeGroup root, VarCollection varCollection, UserMethod[] userMethods)
        {
            Root          = root;
            VarCollection = varCollection;
            UserMethods   = userMethods;

            Rule     = new Rule(ruleNode.Name, ruleNode.Event, ruleNode.Team, ruleNode.Player);
            IsGlobal = Rule.IsGlobal;

            ContinueSkip = new ContinueSkip(IsGlobal, Actions, varCollection);

            ParseConditions(ruleNode.Conditions);
            ParseBlock(root.Child(), ruleNode.Block, false, null);

            Rule.Actions    = Actions.ToArray();
            Rule.Conditions = Conditions.ToArray();

            // Fufill remaining skips
            foreach (var skip in ReturnSkips)
            {
                skip.ParameterValues = new IWorkshopTree[] { new V_Number(Actions.Count - ReturnSkips.IndexOf(skip)) }
            }
            ;
            ReturnSkips.Clear();
        }

        void ParseConditions(IExpressionNode[] expressions)
        {
            foreach (var expr in expressions)
            {
                Element parsedIf = ParseExpression(Root, expr);
                // If the parsed if is a V_Compare, translate it to a condition.
                // Makes "(value1 == value2) == true" to just "value1 == value2"
                if (parsedIf is V_Compare)
                {
                    Element left = (Element)parsedIf.ParameterValues[0];
                    if (!left.ElementData.IsValue)
                    {
                        throw SyntaxErrorException.InvalidMethodType(true, left.Name, ((Node)expr).Range);
                    }

                    Element right = (Element)parsedIf.ParameterValues[2];
                    if (!right.ElementData.IsValue)
                    {
                        throw SyntaxErrorException.InvalidMethodType(true, right.Name, ((Node)expr).Range);
                    }

                    Conditions.Add(
                        new Condition(
                            left,
                            (EnumMember)parsedIf.ParameterValues[1],
                            right
                            )
                        );
                }
                // If not, just do "parsedIf == true"
                else
                {
                    if (!parsedIf.ElementData.IsValue)
                    {
                        throw SyntaxErrorException.InvalidMethodType(true, parsedIf.Name, ((Node)expr).Range);
                    }

                    Conditions.Add(new Condition(
                                       parsedIf, EnumData.GetEnumValue(Operators.Equal), new V_True()
                                       ));
                }
            }
        }

        Element ParseExpression(ScopeGroup scope, IExpressionNode expression)
        {
            switch (expression)
            {
            // Math and boolean operations.
            case OperationNode operationNode:
            {
                Element left  = ParseExpression(scope, operationNode.Left);
                Element right = ParseExpression(scope, operationNode.Right);

                /*
                 * if (Constants.BoolOperations.Contains(operationNode.Operation))
                 * {
                 *  if (left.ElementData.ValueType != Elements.ValueType.Any && left.ElementData.ValueType != Elements.ValueType.Boolean)
                 *      throw new SyntaxErrorException($"Expected boolean, got {left .ElementData.ValueType.ToString()} instead.", ((Node)operationNode.Left).Range);
                 *
                 *  if (right.ElementData.ValueType != Elements.ValueType.Any && right.ElementData.ValueType != Elements.ValueType.Boolean)
                 *      throw new SyntaxErrorException($"Expected boolean, got {right.ElementData.ValueType.ToString()} instead.", ((Node)operationNode.Right).Range);
                 * }
                 */

                switch (operationNode.Operation)
                {
                // Math: ^, *, %, /, +, -
                case "^":
                    return(Element.Part <V_RaiseToPower>(left, right));

                case "*":
                    return(Element.Part <V_Multiply>(left, right));

                case "%":
                    return(Element.Part <V_Modulo>(left, right));

                case "/":
                    return(Element.Part <V_Divide>(left, right));

                case "+":
                    return(Element.Part <V_Add>(left, right));

                case "-":
                    return(Element.Part <V_Subtract>(left, right));


                // BoolCompare: &, |
                case "&":
                    return(Element.Part <V_And>(left, right));

                case "|":
                    return(Element.Part <V_Or>(left, right));

                // Compare: <, <=, ==, >=, >, !=
                case "<":
                    return(Element.Part <V_Compare>(left, EnumData.GetEnumValue(Operators.LessThan), right));

                case "<=":
                    return(Element.Part <V_Compare>(left, EnumData.GetEnumValue(Operators.LessThanOrEqual), right));

                case "==":
                    return(Element.Part <V_Compare>(left, EnumData.GetEnumValue(Operators.Equal), right));

                case ">=":
                    return(Element.Part <V_Compare>(left, EnumData.GetEnumValue(Operators.GreaterThanOrEqual), right));

                case ">":
                    return(Element.Part <V_Compare>(left, EnumData.GetEnumValue(Operators.GreaterThan), right));

                case "!=":
                    return(Element.Part <V_Compare>(left, EnumData.GetEnumValue(Operators.NotEqual), right));
                }

                throw new Exception($"Operation {operationNode.Operation} not implemented.");
            }

            // Number
            case NumberNode numberNode:
                return(new V_Number(numberNode.Value));

            // Bool
            case BooleanNode boolNode:
                if (boolNode.Value)
                {
                    return(new V_True());
                }
                else
                {
                    return(new V_False());
                }

            // Not operation
            case NotNode notNode:
                return(Element.Part <V_Not>(ParseExpression(scope, notNode.Value)));

            // Strings
            case StringNode stringNode:
                Element[] stringFormat = new Element[stringNode.Format?.Length ?? 0];
                for (int i = 0; i < stringFormat.Length; i++)
                {
                    stringFormat[i] = ParseExpression(scope, stringNode.Format[i]);
                }
                return(V_String.ParseString(stringNode.Range, stringNode.Value, stringFormat));

            // Null
            case NullNode nullNode:
                return(new V_Null());

            // TODO check if groups need to be implemented here

            // Methods
            case MethodNode methodNode:
                return(ParseMethod(scope, methodNode, true));

            // Variable
            case VariableNode variableNode:
                return(scope.GetVar(variableNode.Name, variableNode.Range, Diagnostics)
                       .GetVariable(variableNode.Target != null ? ParseExpression(scope, variableNode.Target) : null));

            // Get value in array
            case ValueInArrayNode viaNode:
                return(Element.Part <V_ValueInArray>(ParseExpression(scope, viaNode.Value), ParseExpression(scope, viaNode.Index)));

            // Create array
            case CreateArrayNode createArrayNode:
            {
                Element prev    = null;
                Element current = null;

                for (int i = 0; i < createArrayNode.Values.Length; i++)
                {
                    current = new V_Append()
                    {
                        ParameterValues = new IWorkshopTree[2]
                    };

                    if (prev != null)
                    {
                        current.ParameterValues[0] = prev;
                    }
                    else
                    {
                        current.ParameterValues[0] = new V_EmptyArray();
                    }

                    current.ParameterValues[1] = ParseExpression(scope, createArrayNode.Values[i]);
                    prev = current;
                }

                return(current ?? new V_EmptyArray());
            }

            case EnumNode enumNode:
                return(EnumData.Special(enumNode.EnumMember)
                       ?? throw SyntaxErrorException.EnumCantBeValue(enumNode.Type, enumNode.Range));

                // Seperator
            }

            throw new Exception();
        }

        Element ParseMethod(ScopeGroup scope, MethodNode methodNode, bool needsToBeValue)
        {
            methodNode.RelatedScopeGroup = scope;

            // Get the kind of method the method is (Method (Overwatch), Custom Method, or User Method.)
            var methodType = GetMethodType(UserMethods, methodNode.Name);

            // Throw exception if the method does not exist.
            if (methodType == null)
            {
                throw SyntaxErrorException.NonexistentMethod(methodNode.Name, methodNode.Range);
            }

            Element method;

            switch (methodType)
            {
            case MethodType.Method:
            {
                Type owMethod = Element.GetMethod(methodNode.Name);

                method = (Element)Activator.CreateInstance(owMethod);
                Parameter[] parameterData = owMethod.GetCustomAttributes <Parameter>().ToArray();

                List <IWorkshopTree> parsedParameters = new List <IWorkshopTree>();
                for (int i = 0; i < parameterData.Length; i++)
                {
                    if (methodNode.Parameters.Length > i)
                    {
                        // Parse the parameter.
                        parsedParameters.Add(ParseParameter(scope, methodNode.Parameters[i], methodNode.Name, parameterData[i]));
                    }
                    else
                    {
                        if (parameterData[i].ParameterType == ParameterType.Value && parameterData[i].DefaultType == null)
                        {
                            // Throw exception if there is no default method to fallback on.
                            throw SyntaxErrorException.MissingParameter(parameterData[i].Name, methodNode.Name, methodNode.Range);
                        }
                        else
                        {
                            parsedParameters.Add(parameterData[i].GetDefault());
                        }
                    }
                }

                method.ParameterValues = parsedParameters.ToArray();
                break;
            }

            case MethodType.CustomMethod:
            {
                MethodInfo  customMethod     = CustomMethods.GetCustomMethod(methodNode.Name);
                Parameter[] parameterData    = customMethod.GetCustomAttributes <Parameter>().ToArray();
                object[]    parsedParameters = new Element[parameterData.Length];

                for (int i = 0; i < parameterData.Length; i++)
                {
                    if (methodNode.Parameters.Length > i)
                    {
                        parsedParameters[i] = ParseParameter(scope, methodNode.Parameters[i], methodNode.Name, parameterData[i]);
                    }
                    else
                    {
                        // Throw exception if there is no default method to fallback on.
                        throw SyntaxErrorException.MissingParameter(parameterData[i].Name, methodNode.Name, methodNode.Range);
                    }
                }

                MethodResult result = (MethodResult)customMethod.Invoke(null, new object[] { IsGlobal, VarCollection, parsedParameters });
                switch (result.MethodType)
                {
                case CustomMethodType.Action:
                    if (needsToBeValue)
                    {
                        throw SyntaxErrorException.InvalidMethodType(true, methodNode.Name, methodNode.Range);
                    }
                    break;

                case CustomMethodType.MultiAction_Value:
                case CustomMethodType.Value:
                    if (!needsToBeValue)
                    {
                        throw SyntaxErrorException.InvalidMethodType(false, methodNode.Name, methodNode.Range);
                    }
                    break;
                }

                // Some custom methods have extra actions.
                if (result.Elements != null)
                {
                    Actions.AddRange(result.Elements);
                }
                method = result.Result;

                break;
            }

            case MethodType.UserMethod:
            {
                if (!AllowRecursion)
                {
                    UserMethod userMethod = UserMethod.GetUserMethod(UserMethods, methodNode.Name);

                    if (MethodStackNoRecursive.Contains(userMethod))
                    {
                        throw SyntaxErrorException.RecursionNotAllowed(methodNode.Range);
                    }

                    var methodScope = Root.Child();

                    // Add the parameter variables to the scope.
                    DefinedVar[] parameterVars = new DefinedVar[userMethod.Parameters.Length];
                    for (int i = 0; i < parameterVars.Length; i++)
                    {
                        if (methodNode.Parameters.Length > i)
                        {
                            // Create a new variable using the parameter input.
                            parameterVars[i] = VarCollection.AssignDefinedVar(methodScope, IsGlobal, userMethod.Parameters[i].Name, methodNode.Range);
                            Actions.Add(parameterVars[i].SetVariable(ParseExpression(scope, methodNode.Parameters[i])));
                        }
                        else
                        {
                            throw SyntaxErrorException.MissingParameter(userMethod.Parameters[i].Name, methodNode.Name, methodNode.Range);
                        }
                    }

                    var returns = VarCollection.AssignVar($"{methodNode.Name}: return temp value", IsGlobal);

                    MethodStackNoRecursive.Add(userMethod);

                    var userMethodScope = methodScope.Child();
                    userMethod.Block.RelatedScopeGroup = userMethodScope;

                    ParseBlock(userMethodScope, userMethod.Block, true, returns);

                    MethodStackNoRecursive.Remove(userMethod);

                    // No return value if the method is being used as an action.
                    if (needsToBeValue)
                    {
                        method = returns.GetVariable();
                    }
                    else
                    {
                        method = null;
                    }

                    break;
                }
                else
                {
                    UserMethod userMethod = UserMethod.GetUserMethod(UserMethods, methodNode.Name);

                    MethodStack lastMethod = MethodStack.FirstOrDefault(ms => ms.UserMethod == userMethod);
                    if (lastMethod != null)
                    {
                        ContinueSkip.Setup();

                        for (int i = 0; i < lastMethod.ParameterVars.Length; i++)
                        {
                            if (methodNode.Parameters.Length > i)
                            {
                                Actions.Add(lastMethod.ParameterVars[i].Push(ParseExpression(scope, methodNode.Parameters[i])));
                            }
                        }

                        // ?--- Multidimensional Array
                        Actions.Add(
                            Element.Part <A_SetGlobalVariable>(EnumData.GetEnumValue(Variable.B), lastMethod.ContinueSkipArray.GetVariable())
                            );
                        Actions.Add(
                            Element.Part <A_ModifyGlobalVariable>(EnumData.GetEnumValue(Variable.B), EnumData.GetEnumValue(Operation.AppendToArray), new V_Number(ContinueSkip.GetSkipCount() + 4))
                            );
                        Actions.Add(
                            lastMethod.ContinueSkipArray.SetVariable(Element.Part <V_GlobalVariable>(EnumData.GetEnumValue(Variable.B)))
                            );
                        // ?---

                        ContinueSkip.SetSkipCount(lastMethod.ActionIndex);
                        Actions.Add(Element.Part <A_Loop>());

                        if (needsToBeValue)
                        {
                            method = lastMethod.Return.GetVariable();
                        }
                        else
                        {
                            method = null;
                        }
                    }
                    else
                    {
                        var methodScope = Root.Child();

                        // Add the parameter variables to the scope.
                        ParameterVar[] parameterVars = new ParameterVar[userMethod.Parameters.Length];
                        for (int i = 0; i < parameterVars.Length; i++)
                        {
                            if (methodNode.Parameters.Length > i)
                            {
                                // Create a new variable using the parameter input.
                                parameterVars[i] = VarCollection.AssignParameterVar(Actions, methodScope, IsGlobal, userMethod.Parameters[i].Name, methodNode.Range);
                                Actions.Add(parameterVars[i].Push(ParseExpression(scope, methodNode.Parameters[i])));
                            }
                            else
                            {
                                throw SyntaxErrorException.MissingParameter(userMethod.Parameters[i].Name, methodNode.Name, methodNode.Range);
                            }
                        }

                        var returns = VarCollection.AssignVar($"{methodNode.Name}: return temp value", IsGlobal);

                        Var continueSkipArray = VarCollection.AssignVar($"{methodNode.Name}: continue skip temp value", IsGlobal);
                        var stack             = new MethodStack(userMethod, parameterVars, ContinueSkip.GetSkipCount(), returns, continueSkipArray);
                        MethodStack.Add(stack);

                        var userMethodScope = methodScope.Child();
                        userMethod.Block.RelatedScopeGroup = userMethodScope;

                        ParseBlock(userMethodScope, userMethod.Block, true, returns);

                        // No return value if the method is being used as an action.
                        if (needsToBeValue)
                        {
                            method = returns.GetVariable();
                        }
                        else
                        {
                            method = null;
                        }

                        Actions.Add(Element.Part <A_Wait>(new V_Number(Constants.MINIMUM_WAIT)));
                        for (int i = 0; i < parameterVars.Length; i++)
                        {
                            parameterVars[i].Pop();
                        }

                        ContinueSkip.Setup();
                        ContinueSkip.SetSkipCount(Element.Part <V_LastOf>(continueSkipArray.GetVariable()));

                        // ?--- Multidimensional Array
                        Actions.Add(
                            Element.Part <A_SetGlobalVariable>(EnumData.GetEnumValue(Variable.B), continueSkipArray.GetVariable())
                            );
                        Actions.Add(
                            continueSkipArray.SetVariable(
                                Element.Part <V_ArraySlice>(
                                    Element.Part <V_GlobalVariable>(EnumData.GetEnumValue(Variable.B)),
                                    new V_Number(0),
                                    Element.Part <V_Subtract>(
                                        Element.Part <V_CountOf>(Element.Part <V_GlobalVariable>(EnumData.GetEnumValue(Variable.B))),
                                        new V_Number(1)
                                        )
                                    )
                                )
                            );
                        // ?---

                        Actions.Add(
                            Element.Part <A_LoopIf>(
                                Element.Part <V_Compare>(
                                    Element.Part <V_CountOf>(continueSkipArray.GetVariable()),
                                    EnumData.GetEnumValue(Operators.NotEqual),
                                    new V_Number(0)
                                    )
                                )
                            );
                        ContinueSkip.ResetSkip();

                        MethodStack.Remove(stack);
                    }
                    break;
                }
            }

            default: throw new NotImplementedException();
            }

            methodNode.RelatedElement = method;
            return(method);
        }

        IWorkshopTree ParseParameter(ScopeGroup scope, IExpressionNode node, string methodName, Parameter parameterData)
        {
            IWorkshopTree value = null;

            switch (node)
            {
            case EnumNode enumNode:

                /*
                 * if (parameterData.ParameterType != ParameterType.Enum)
                 *  throw SyntaxErrorException.ExpectedType(true, parameterData.ValueType.ToString(), methodName, parameterData.Name, enumNode.Range);
                 *
                 * if (enumNode.Type != parameterData.EnumType.Name)
                 *  throw SyntaxErrorException.ExpectedType(false, parameterData.EnumType.ToString(), methodName, parameterData.Name, enumNode.Range);
                 */

                value = (IWorkshopTree)EnumData.Special(enumNode.EnumMember) ?? (IWorkshopTree)enumNode.EnumMember;

                //if (value == null)
                //  throw SyntaxErrorException.InvalidEnumValue(enumNode.Type, enumNode.Value, enumNode.Range);

                break;

            default:

                if (parameterData.ParameterType != ParameterType.Value)
                {
                    throw SyntaxErrorException.ExpectedType(false, parameterData.EnumType.Name, methodName, parameterData.Name, ((Node)node).Range);
                }

                value = ParseExpression(scope, node);

                Element     element     = value as Element;
                ElementData elementData = element.GetType().GetCustomAttribute <ElementData>();

                if (elementData.ValueType != Elements.ValueType.Any &&
                    !parameterData.ValueType.HasFlag(elementData.ValueType))
                {
                    throw SyntaxErrorException.InvalidType(parameterData.ValueType, elementData.ValueType, ((Node)node).Range);
                }

                break;
            }

            if (value == null)
            {
                throw new Exception("Failed to parse parameter.");
            }

            return(value);
        }
        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();
        }
        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);
                }
            }
        }
Esempio n. 27
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();
        }
Esempio n. 28
0
        public static TranslateResult GetRule(RuleNode ruleNode, ScopeGroup root, VarCollection varCollection, UserMethod[] userMethods)
        {
            var result = new Translate(ruleNode, root, varCollection, userMethods);

            return(new TranslateResult(result.Rule, result.Diagnostics.ToArray()));
        }
Esempio n. 29
0
 public ContinueSkip(bool isGlobal, List <Element> actions, VarCollection varCollection)
 {
     IsGlobal      = isGlobal;
     Actions       = actions;
     VarCollection = varCollection;
 }
Esempio n. 30
0
 public ScopeGroup(VarCollection varCollection)
 {
     VarCollection = varCollection;
 }