Exemplo n.º 1
0
        /************************************************************
        * function = {
        *      name = cube_root
        *      arguments = { cr_arg_number }
        *      return = cr_ret_number
        *      effect = {
        *          ...
        *          return = mid
        *      }
        * }
        ************************************************************/


        public static PDXFunction ParseNode(Script.KeyCollectionNode head)
        {
            PDXFunction      construct      = new PDXFunction();
            HashSet <String> foundArguments = new HashSet <string>();

            if (head.Key.Trim().ToLower() != "function")
            {
                // Log this.
                return(null);
            }

            Script.KeyCollectionNode argNode    = null;
            Script.KeyCollectionNode effectNode = null;


            foreach (Script.Node child in head.Children)
            {
                switch (child)
                {
                case Script.KeyCollectionNode kcn:
                    String kcn_key = kcn.Key.ToLower();
                    switch (kcn_key)
                    {
                    case "arguments":
                        argNode = kcn;
                        break;

                    case "effect":
                        effectNode = kcn;
                        break;
                    }

                    break;

                case Script.CommentNode cn:
                    break;

                case Script.KeyValueNode kvn:
                    String kvn_key = kvn.Key.ToLower();
                    switch (kvn_key)
                    {
                    case "name":
                        if (construct.Name == String.Empty)
                        {
                            construct.Name = kvn.Value;
                        }
                        else
                        {
                            // Log.
                        }
                        break;

                    case "return":
                        if (construct.ReturnVariable == String.Empty)
                        {
                            construct.ReturnVariable = kvn.Value;
                        }
                        else
                        {
                            // Log
                        }
                        break;

                    case "arguments":
                        // Maybe log this.
                        break;
                    }
                    break;

                case Script.SingleValueNode svn:
                    break;
                }
            }

            if (argNode != null)
            {
                foreach (Script.SingleValueNode singleValueNode in argNode.Children.OfType <Script.SingleValueNode>())
                {
                    String svn_value_lower = singleValueNode.Value.Trim().ToLower();
                    if (foundArguments.Contains(svn_value_lower))
                    {
                        continue;
                    }
                    else
                    {
                        foundArguments.Add(svn_value_lower); construct.Arguments.Add(svn_value_lower);
                    }
                }

                for (int i = 0; i < construct.Arguments.Count; i++)
                {
                    construct.ArgumentIndex[construct.Arguments[i]] = i;
                }
            }

            if (effectNode != null)
            {
                construct.EffectsNode    = effectNode;
                construct.LocalVariables = FindLocals(effectNode);
                for (int i = 0; i < construct.LocalVariables.Count; i++)
                {
                    construct.LocalVariableIndex[construct.LocalVariables[i]] = i;
                }
            }

            return(construct);
        }
Exemplo n.º 2
0
        public String GenerateFunctionEffect()
        {
            // Convert local variable declarations to stack local array, and arg variables to stack arg array.
            StringBuilder stringBuilder = new StringBuilder();

            Stack <Script.Node> nodeStack = new Stack <Script.Node>();

            Script.KeyCollectionNode parseNodeEffects = (Script.KeyCollectionNode)EffectsNode.Clone();
            nodeStack.Push(parseNodeEffects);

            Script.Node currentNode = null;

            Dictionary <string, string> match_replace = new Dictionary <string, string>();

            for (int i = 0; i != this.LocalVariables.Count; i++)
            {
                match_replace[this.LocalVariables[i]] = String.Format("global.func_{0}_locals^{1}", this.Name, i);
            }


            while (nodeStack.Count > 0)
            {
                currentNode = nodeStack.Pop();

                switch (currentNode)
                {
                case Script.KeyCollectionNode kcn:
                    String kcn_key_lower = kcn.Key.ToLower();

                    if (kcn.Key == "set_local_variable")
                    {
                        kcn.Key = "set_variable";
                    }

                    if (kcn_key_lower.StartsWith("local."))
                    {
                        kcn_key_lower = kcn_key_lower.Remove(0, 6);
                        int local_index = this.LocalVariableIndex[kcn_key_lower];
                        kcn.Key = String.Format("global.func_{0}_locals^{1}", this.Name, local_index);
                    }
                    else if (kcn_key_lower.StartsWith("var:local."))
                    {
                        kcn_key_lower = kcn_key_lower.Remove(0, 10);
                        int local_index = this.LocalVariableIndex[kcn_key_lower];
                        kcn.Key = String.Format("global.func_{0}_locals^{1}", this.Name, local_index);
                    }



                    foreach (var child in kcn.Children)
                    {
                        nodeStack.Push(child);
                    }


                    break;

                case Script.KeyValueNode kvn:
                    String kvn_key_lower   = kvn.Key.ToLower();
                    String kvn_value_lower = kvn.Value.ToLower();



                    if (kvn.HasStringValue())
                    {
                        kvn_value_lower = Regex.Replace(kvn_value_lower, "(?<=\\[\\?local\\.)\\S*(?=\\])", m => match_replace[m.Value]);
                        kvn_value_lower = Regex.Replace(kvn_value_lower, "(?<=\\[\\?)\\local(?=\\])", "");
                        kvn.Value       = kvn_value_lower;
                    }
                    else
                    {
                        if (kvn.Value.StartsWith("local."))
                        {
                            kvn_value_lower = kvn_value_lower.Remove(0, 6);
                            int local_index = this.LocalVariableIndex[kvn_value_lower];
                            kvn.Value = String.Format("global.func_{0}_locals^{1}", this.Name, local_index);
                        }
                        else if (kvn.Value.StartsWith("var:local."))
                        {
                            kvn_value_lower = kvn_value_lower.Remove(0, 10);
                            int local_index = this.LocalVariableIndex[kvn_value_lower];
                            kvn.Value = String.Format("var:global.func_{0}_locals^{1}", this.Name, local_index);
                        }
                        else if (this.LocalVariableIndex.ContainsKey(kvn_value_lower))
                        {
                            int local_index = this.LocalVariableIndex[kvn_value_lower];
                            kvn.Value = String.Format("global.func_{0}_locals^{1}", this.Name, local_index);
                        }

                        if (kvn.Key.StartsWith("local."))
                        {
                            kvn_key_lower = kvn_key_lower.Remove(0, 6);
                            int local_index = this.LocalVariableIndex[kvn_key_lower];
                            kvn.Key = String.Format("global.func_{0}_locals^{1}", this.Name, local_index);
                        }
                        else if (kvn.Key.StartsWith("var:local."))
                        {
                            kvn_key_lower = kvn_key_lower.Remove(0, 10);
                            int local_index = this.LocalVariableIndex[kvn_key_lower];
                            kvn.Key = String.Format("var:global.func_{0}_locals^{1}", this.Name, local_index);
                        }
                        else if (this.LocalVariableIndex.ContainsKey(kvn_key_lower))
                        {
                            int local_index = this.LocalVariableIndex[kvn_key_lower];
                            kvn.Key = String.Format("global.func_{0}_locals^{1}", this.Name, local_index);
                        }
                    }
                    break;
                }
            }


            return(parseNodeEffects.PrintString());
        }
Exemplo n.º 3
0
        private static List <String> FindLocals(Script.KeyCollectionNode effectsNode, HashSet <String> foundArgs = null)
        {
            HashSet <String> found_local_variables_set = new HashSet <string>();
            List <String>    local_variables           = new List <string>();

            Stack <Script.Node> nodeStack = new Stack <Script.Node>();

            nodeStack.Push(effectsNode);

            Script.Node previousNode           = null;
            Script.Node currentNode            = null;
            Boolean     lookingForVariableName = false;

            while (nodeStack.Count > 0)
            {
                previousNode = currentNode;
                currentNode  = nodeStack.Pop();

                // If we jump down from an expression and are looking for a variable expression. Stop looking.
                if (previousNode != null && lookingForVariableName && previousNode.Depth > currentNode.Depth)
                {
                    lookingForVariableName = false;
                }

                // If looking for a variable name, check if the current node is a Key Value Node.
                if (lookingForVariableName && currentNode.GetType() == typeof(Script.KeyValueNode))
                {
                    Script.KeyValueNode KVN = (Script.KeyValueNode)currentNode;
                    String lower_key        = KVN.Key.ToLower();
                    String lower_value      = KVN.Value.ToLower();
                    if (lower_value.StartsWith("local."))
                    {
                        lower_value = lower_value.Remove(0, 6);
                    }
                    else if (lower_value.StartsWith("var:local."))
                    {
                        lower_value = lower_value.Remove(0, 10);
                    }


                    if (lower_key == "var" && !found_local_variables_set.Contains(lower_value) && (foundArgs == null || !foundArgs.Contains(lower_value)))
                    {
                        found_local_variables_set.Add(lower_value);
                        local_variables.Add(lower_value);
                        continue;
                    }
                    else if (VariableExpressions.Contains(lower_key) || found_local_variables_set.Contains(lower_key))
                    {
                        continue;
                    }
                    else
                    {
                        if (foundArgs == null || !foundArgs.Contains(lower_value))
                        {
                            found_local_variables_set.Add(KVN.Key.ToLower());
                            local_variables.Add(KVN.Key.ToLower());
                        }
                        continue;
                    }
                }
                else if (currentNode.GetType() == typeof(Script.KeyCollectionNode))
                {
                    Script.KeyCollectionNode KCN = (Script.KeyCollectionNode)currentNode;
                    if (LocalVariableKeyWords.Contains(KCN.Key.ToLower()))
                    {
                        lookingForVariableName = true;
                    }

                    var ReverseChildren = new List <Script.Node>(KCN.Children);
                    ReverseChildren.Reverse();
                    foreach (Script.Node child in ReverseChildren)
                    {
                        nodeStack.Push(child);
                    }
                }
            }



            return(local_variables);
        }