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);
        }
Example #2
0
        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, i)
                        );
                }
            }

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

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

            if (context.MethodStackNotRecursive.Contains(constructor))
            {
                throw new SyntaxErrorException("Constructors cannot be recursive.", node.Location);
            }
            context.MethodStackNotRecursive.Add(constructor);

            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);
            if (constructor.BlockNode != null)
            {
                context.ParseBlock(constructorScope, constructorScope, constructor.BlockNode, true, null);
            }
            constructorScope.Out(context);
            context.MethodStackNotRecursive.Remove(constructor);
        }
        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();
        }
            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;
            }