Esempio n. 1
0
        public Term PerformOperation(Executer exec, Operator op, Term otherTerm)
        {
            //these should be in Types.Object really...
            Types.Object oThis = null;

            //TODO: if it's already been evaluated this time, no need to do it again!
            if (this.Expression!=null)
                this.Value = this.Expression.Evaluate(exec);

            oThis = this.Value;

            Types.Object oOther = null;
            if (otherTerm!=null)
            {
                //TODO: if it's already been evaluated this time, no need to do it again!
                if (otherTerm.Expression!=null)
                    otherTerm.Value = otherTerm.Expression.Evaluate(exec);

                oOther = otherTerm.Value;
            }

            //Here's the bad one: can't well set Value - what about next execution?? E.g. if it was a Variable??
            //this.Value = oThis.PerformOperation(exec, op, oOther);
            //return this.Value;
            Term tNew = new Term();
            tNew.Value = oThis.PerformOperation(exec, op, oOther);
            return tNew;
        }
Esempio n. 2
0
 private Term AddTerm(string sTerm)
 {
     if (sTerm.Length == 0)
         return null;
     Term term = new Term(sTerm);
     AddChunk(term);
     return term;
 }
Esempio n. 3
0
 private Term AddTerm(Expression expr)
 {
     Term term = new Term(expr);
     AddChunk(term);
     return term;
 }
Esempio n. 4
0
        /// <summary>
        /// Parse partial expression. Returns the remainder of the string (that wasn't part of the expression)
        /// </summary>
        /// <param name="sLine"></param>
        /// <returns></returns>
        public string Parse(string sLine)
        {
            //this should probably be done with regular expressions.
            //http://www.ultrapico.com/ExpressoDownload.htm

            m_aChunks = new ArrayList();
            //int nChunkStart = -1;
            int nCharIndex = 0;
            while (sLine.Length>0)
            {
                string sChar = sLine.Substring(nCharIndex,1);

                //check for quotes:
                if (sChar == "\"")
                {
                    int nQuoteEnd = sLine.IndexOf("\"", nCharIndex+1);
                    //note: sQuote includes quotation marks
                    sLine = ExtractTerm(nQuoteEnd, sLine);
                    nCharIndex = 0;
                }
                else if (sChar == " ")
                {
                    sLine = sLine.Remove(nCharIndex,1);
                    nCharIndex = 0;
                }
                else if (sChar == ",")
                {
                    //TODO: check: this can only happen to separate function arguments

                    //end of this argument.
                    sLine = ExtractTerm(nCharIndex-1, sLine);
                    return sLine; //NO: .Remove(0,1); //remove the , before returning
                }
                else
                {
                    //is it an operator?
            //					if (sChar == ".")
            //					{
            //						EH.Put("!");
            //					}
                    Operator op = Parser.GetOperator(sChar);
                    if (op!=null)
                    {
                        //first check if it's a "." - it could be a decimal dot, not an operator:
                        try
                        {
                            Term termTest = new Term(sLine.Substring(0,nCharIndex));
                            Types.Number number = (Types.Number)termTest.Value;
                            nCharIndex++;
                            continue;
                        }
                        catch {}

                        if (nCharIndex-1 >= 0)
                            sLine = ExtractTerm(nCharIndex-1, sLine);

                        //could be a two-token operator. Check that too:
                        string sChars = sLine.Substring(0,2);
                        Operator op2 = Parser.GetOperator(sChars);
                        if (op2!=null)
                        {
                            op = op2;
                            sLine = sLine.Remove(0,2);
                        }
                        else
                            sLine = sLine.Remove(0,1);

                        //if there either is no previous chunk, or it was an operator,
                        //that means this must be a pre-op (-a, ++a, etc)
                        if (this.m_aChunks.Count == 0 || this.GetLastChunk().GetType() == typeof(Operator))
                        {
                            op = Parser.GetOperator("pre"+op.InternalTokens);
                            if (op == null || !op.IsPreOp)
                                throw new Exception("Two operators in a row");
                            //Two operators can be joined if
                            //current op is a pre-op and last op was NOT (a=++b or a=-b)
                            //TODO: if (!((Operator)lastChunk).CanBePreOp)
                        }

                        //TODO: consider a = b+++++c (in C# it must be written b++ + ++c)
            //						object lastChunk = this.GetLastChunk();

                        AddOperator(op);
                        nCharIndex = 0;

                        if(op.IsSettingOperator && (op.InternalTokens.IndexOf("=")>0))
                        {
                            //if an operator with "=" in it, everything on right side must be calculated first.
                            //easiest way to accomplish this is to make one single term of it.
                            Expression expression = new Expression();
                            sLine = expression.Parse(sLine);
                            Term term = this.AddTerm(expression);
                        }
                    }
                    else if (Parser.m_aSeparators.IndexOf(sChar) >= 0 || nCharIndex == sLine.Length-1)
                    {
                        if (Parser.m_aSeparators.IndexOf(sChar) >= 0)
                        {
                            if (nCharIndex > 0)
                            {
                                sLine = ExtractTerm(nCharIndex-1, sLine);
                                nCharIndex = 0;
                            }
                        }
                        else //if (nCharIndex == sLine.Length-1)
                        {
                            sLine = ExtractTerm(nCharIndex, sLine);
                            nCharIndex = 0;
                        }

                        bool bLastChunkWasTerm = false;
                        object oLastChunk = null;
                        if (this.m_aChunks.Count > 0)
                        {
                            oLastChunk = this.GetLastChunk();
                            bLastChunkWasTerm = (oLastChunk.GetType() == typeof(Term));
                        }

                        if (sChar == ")" || sChar == "]" || nCharIndex == sLine.Length-1)
                        {
                            //we can't remove the final token - if we're parsing function arguments,
                            //the caller must know that the end of the function has been reached.
                            return sLine; //sLine.Remove(0,nCharIndex+1);
                        }
                        else if (sChar == "(" || sChar == "[")
                        {
                            if (sChar == "[")
                            {
                                //if this comes after another operator or as the first chunk in an expression,
                                //then consider it a LingoList definition and parse it as such
                                //otherwise, it's an index access function.
                                //TODO: Convert this into an access function, ie object[x+1] -> object.IndexerAccess(x+1)
                            }

                            bool bIsFunction = false;
                            if (sChar == "(" && bLastChunkWasTerm == true && ((Term)oLastChunk).CanBeMethod()) //.Value.GetType() == typeof(string))
                                bIsFunction = true;

                            if (bIsFunction)
                            {
                                //the term must be marked as a function...
                                ((Term)oLastChunk).ConvertToMethod();
                                //								((Term)oLastChunk).IsFunction = true;
                                Types.Method func = (Types.Method)((Term)oLastChunk).Value;

                                //								sub.m_aChunks = new ArrayList();
                                //NO!! changed this:
                                //if it's a function, it may have several arguments
                                //We'll express this as:
                                //term.Value = function name
                                //term.Expression = an expression with N terms (each argument is a term)
                                while (true)
                                {
                                    Expression arg = new Expression();
                                    sLine = arg.Parse(sLine.Remove(0,1)); //remove the , or ( first.
                                    //									Term term = new Term(arg);
                                    //									sub.m_aChunks.Add(term);
                                    if (arg.m_aChunks.Count > 0)
                                        func.AddArgument(arg);
                                    if (sLine.Length == 0 || sLine.Substring(0,1) == ")")
                                        break;
                                }
                            }
                            else if (!bLastChunkWasTerm) //last term was an operator,
                                //which means this is just a parenthesized expression (not a function)
                            {
                                Expression sub = new Expression();
                                sLine = sub.Parse(sLine.Remove(0,1)); //remove the (
                                this.AddTerm(sub);
                            }
                            else //throw exception?
                            {
                            }
                            if (sLine.Length > 0 && sLine.Substring(0,1) == ")")
                                sLine = sLine.Remove(0,1);

                            nCharIndex = 0;
                        }
                        else
                        {
                        }
                    }
                    else
                    {
                        nCharIndex++;
                    }
                }
            }

            this.ArrangeOpsInExecutionOrder();
            return sLine;
        }