Пример #1
0
        public override BaseNode GetNextNode(Executer exec, BaseNode alreadyUsedChildNode, object nodesResult)
        {
            //Hmm, could I execute the if-statement directly here? Must I really wait
            //for executer to execute it and then proceed based on the result??

            //I'll go for direct if-clause execution for now:
            if (alreadyUsedChildNode == null)
            {
            //				if (this.m_ifExpression==null || Convert.ToInt32(this.m_ifExpression.Evaluate(exec)) != 0)
                if (this.m_ifExpression==null ||
                    Convert.ToInt32(this.m_ifExpression.Evaluate(exec).GetUnboxed(exec)) != 0)
                    return (BaseNode)this.FirstChild;
                if (this.m_nextIfNode!=null)
                    return this.m_nextIfNode;
                return null;
            }
            return base.GetNextNode(exec, alreadyUsedChildNode, nodesResult);

            //			int nIndex = this.ChildNodes.IndexOfValue(alreadyUsedChildNode);
            //			if (nIndex == 0) //it was the "if" clause
            //			{
            //				if ((int)((Types.Object)nodesResult).GetUnboxed() != 0)
            //					return (BaseNode)this.ChildNodes.GetByIndex(2); //this is where the statements begin if it's true
            //				if (this.ChildNodes.Count > 1)
            //					return (BaseNode)this.ChildNodes.GetByIndex(1);
            //			}
            //			return null;
        }
Пример #2
0
 public virtual BaseNode GetNextNode(Executer exec, BaseNode alreadyUsedChildNode, object nodesResult)
 {
     if (alreadyUsedChildNode != null)
         return (BaseNode)alreadyUsedChildNode.NextSibling;
     if (this.HasChildNodes)
         return (BaseNode)this.FirstChild;
     return null;
 }
Пример #3
0
        public void Rewind()
        {
            //EH.Put("Rewind called");
            MethodNode nodeToExecute = null;
            if (this.m_callStack != null)
            {
                //find first item in stack (i.e., the first called method)
                while (this.m_callStack.Count > 1)
                    this.m_callStack.Pop();
                nodeToExecute = (MethodNode)this.m_callStack.Pop();
            }

            this.m_callStack = new System.Collections.Stack();
            this.m_valueStack = new System.Collections.ArrayList();
            this.m_currentNode = null;
            if (nodeToExecute != null)
                this.m_callStack.Push(nodeToExecute);
        }
Пример #4
0
        private static bool HandleNodeBorderChars(string sDividerChar, ref BaseNode currentNode)
        {
            if (sDividerChar == "{" || sDividerChar == "}")
            {
                if (sDividerChar == "{")
                {
                    bool bCreateNewUndefinedNode = true;
                    //if there's a { in the middle of the code, with nothing special preceding it, (if,for etc)
                    //let's just create a chunkNode for it.

                    //					if (currentNode.GetType() == typeof(MethodNode))
                    //						//Metho
                    //						bCreateNewUndefinedNode = false;
                    //					else
                    //					{
                    try
                    {
                        //if we're in a chunk node which is supposed to close automatically after one line, like:
                        // if(true) x=1;
                        //and instead we encounter a {, like:
                        // if(true) {
                        //that means it should NOT close automatically.
                        ChunkNode chunkNode = (ChunkNode)currentNode;
                        if (chunkNode.CloseNodeAfterNextLine)
                        {
                            chunkNode.CloseNodeAfterNextLine = false;
                            bCreateNewUndefinedNode = false;
                        }
                    }
                    catch
                    {}
            //					}

                    if (bCreateNewUndefinedNode)
                    {
                        ChunkNode newChunkNode = new ChunkNode();
                        currentNode.AppendChild("undef", newChunkNode);
                        currentNode = newChunkNode;
                    }
                }
                else // "}"
                    currentNode = (BaseNode)currentNode.ParentNode;
                return true;
            }
            return false;
        }
Пример #5
0
        public static ClassNode Parse(string sScript)
        {
            ArrayList aAllLines = new ArrayList();
            string[] aKeywords = new string[]{"for", "else if", "if", "else", "while", "goto", "gosub", "return"};
            //TODO: I don't handle keyword and a statement on the same line right now-
            //e.g. "if (true) blabla();" or "for (;;) put(1);"

            BaseNode rootNode = new BaseNode();
            ClassNode classNode = new ClassNode();
            rootNode.AppendChild("Class_01", classNode);
            BaseNode currentNode = classNode;

            //easier parsing if \r\n is replaced by \n
            sScript = sScript.Replace("\r\n", "\n");
            //also a little easier if script always ends with a \n
            if (!sScript.EndsWith("\n"))
                sScript+="\n";

            //structure will be [ScriptName:[MethodName:[LabelName:[clause:[clause]]]]]
            //Labels must be on top level in a method (e.g. not inside an if(){} clause)
            while (sScript.Length > 0)
            {

                //first divide into "lines" - EndOfLine represented by: return ; { or }
                string sLine = "";
                string sDividerChar = "";
                MatchCollection matches = Regex.Matches(sScript, "[^{};\\n]*[{};\\n]");
                foreach (Match m in matches)
                {
                    sLine = sScript.Substring(0, m.Index+m.Length);
                    sDividerChar = m.Value.Substring(m.Value.Length-1,1);
                    if (sDividerChar == ";")
                    {
                        //must check if the ";" is inside parenthesis - if so, it doesn't count (e.g. "for(;;)")
                        //only when the number of "(" is the same as the number of ")", the ";" is outside
                        string sCheck = sLine.Replace("(", "");
                        int nNumRight = sLine.Length-sCheck.Length;
                        sCheck = sLine.Replace(")", "");
                        int nNumLeft = sLine.Length-sCheck.Length;
                        if (nNumRight != nNumLeft)
                            continue;
                    }
                    sScript = sScript.Remove(0, sLine.Length);
                    sLine = sLine.Remove(sLine.Length-1,1);
                    break;
                }

                sLine = sLine.Trim();

                //handle if the line only consists of a { or }
                if (sLine.Length == 0)
                {
                    if (HandleNodeBorderChars(sDividerChar, ref currentNode))
                        continue;
                }

                //empty and remmed lines are ignored:
                if (sLine.Length == 0 || sLine.IndexOf("//") == 0)
                {
                    continue;
                }

                if (currentNode.GetType() == typeof(ClassNode)) //.Depth == 1) //class level, i.e. where methods are defined
                {
                    //search for "on method([args])"
                    Match m = Regex.Match(sLine, "on\\s*\\w*\\s*[(][^()]*[)]");
                    if (m.Success)
                    {
                        string sMethod = m.Value.Replace("on ", "").Trim();
                        string sArgs = sMethod.Remove(0,sMethod.IndexOf("("));
                        sMethod = sMethod.Substring(0,sMethod.IndexOf("("));

                        MethodNode methodNode = new MethodNode();
                        methodNode.DefineArguments(sArgs.Substring(1,sArgs.Length-2));
                        currentNode.AppendChild(sMethod, methodNode);
                        currentNode = methodNode;
                        continue;
                    }
                }
                //separate code flow keywords/tokens from expressions
                if (sLine.IndexOf(":") == sLine.Length-1)
                {
                    //it's a label. Labels can currently only occur on Method level
                    if (currentNode.GetType() != typeof(MethodNode))
                        throw new Exception("Labels must be defined in Method scope!");
                    //TODO: Labels can't be nodes - they're not defined with {}'s... More like an HTML anchor
                    //sLine.Substring(0,sLine.Length-2)
                }

                #region Check for keywords

                foreach (string sKeyword in aKeywords)
                {
                    //[^\\w]+*[( ]*
                    Match m = Regex.Match(sLine+" ", sKeyword+"[^\\w]+[( ]*"); //"\\s*[(]*");
                    if (m.Success)
                    {
                        ChunkNode newNode = null;

                        string sArgs = GetStringWithinParenthesis(sLine);

                        switch (sKeyword)
                        {
                            case "for":
                                ForNode forNode = new ForNode();
                                forNode.SetConditions(sArgs);
                                newNode = forNode;
                                //With the current line seek method, the ";" in for(;;) forces us to look ahead in script
                                //TODO: lookahead for(;;)
                                break;
                            case "if":
                                if (sArgs == null)
                                    throw new Exception("If statement incomplete");
                                IfNode ifNode = new IfNode();
                                ifNode.SetIfStatement(sArgs);
                                newNode = ifNode;
                                break;
                            case "else if":
                            case "else":
                                //is the current node an IfNode?
                                if (currentNode.GetType() != typeof(IfNode))
                                    throw new Exception("\""+sKeyword+"\" must come after an \"if\" statement");
                                IfNode elseifNode = new IfNode();
                                if (sKeyword == "else if")
                                {
                                    //TODO: don't understand C# scopes... Why can't I define sArgs here too? Can't see any risk for confusion or mistakes!?
                                    //And sometimes it's too slack:
                                    //a member variable can have the same name as a variable in a method with no complaits,
                                    //although that is clearly a mistake in most cases?
                                    if (sArgs == null)
                                        throw new Exception("Else if statement incomplete");
                                    elseifNode.SetIfStatement(sArgs);
                                }
                                IfNode oldIfNode = (IfNode)currentNode;
                                oldIfNode.SetNextIfNode(elseifNode);
                                newNode = elseifNode;
                                break;
                        }
                        if (newNode!=null)
                        {
                            newNode.CloseNodeAfterNextLine = true;
                            currentNode.AppendChild(sKeyword, newNode);
                            currentNode = newNode;
                        }
                        break;
                    }
                }
                #endregion

                if (HandleNodeBorderChars(sDividerChar, ref currentNode))
                    continue;

                string sStatement = sLine;
                ExpressionNode expNode = new ExpressionNode();
                expNode.SetExpression(sStatement);
                currentNode.AppendChild(sStatement, expNode);

                //TODO: how to check nicely if ChunkNode is one of the base classes of currentNode?? This is ugly (?):
                try
                {
                    ChunkNode chunkNode = (ChunkNode)currentNode;
                    if (chunkNode.CloseNodeAfterNextLine)
                        currentNode = (BaseNode)currentNode.ParentNode;
                }
                catch
                {}
            }

            //			System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
            //			rootNode.AddToXml(doc);
            //			doc.Save("Testing.xml");

            return classNode;
        }
Пример #6
0
        //returns false when finished
        public bool Step()
        {
            bool bDebug = false;
            BaseNode owningNode = (BaseNode)this.m_callStack.Peek();
            BaseNode nextNode = owningNode.GetNextNode(this, this.m_currentNode, null);

            if (nextNode == null)
            {
                if (bDebug) EH.Put("No more nodes on that depth");
                //that node is finished. Go up one level or quit!
                if (this.m_callStack.Count <= 1) //there has to be two nodes above the current!
                {
                    //fire event! Quit!
                    return false;
                }
                //step up one level, and find next node there:
                this.m_currentNode = (BaseNode)this.m_callStack.Pop();
                this.Step();
            }
            else
            {
                if (nextNode.ParentNode != owningNode) //when going down one level (always just one)
                {
                    this.m_callStack.Push(nextNode.ParentNode);
                    this.m_currentNode = nextNode;
                    if (bDebug) EH.Put("Entering childnode: "+nextNode.Name);
                }
                else //new node is at same level
                {
                    this.m_currentNode = nextNode;
                    if (bDebug) EH.Put("Nextsibling : "+nextNode.Name); //nextNode.GetType().ToString()
                }
            }
            //			if (this.m_currentNode.GetType() == typeof(IfNode))
            //				this.m_currentNode = this.m_currentNode;

            //only ExpressionNodes can be executed, the others are only asked for next node.
            if (this.m_currentNode.GetType() != typeof(ExpressionNode))
            {
                this.m_callStack.Push(this.m_currentNode);
                this.m_currentNode = null;
                return this.Step();
            }
            else
            {
                this.m_currentNode.Execute(this); //object oVal =
                return true;
            }
        }