예제 #1
0
        /// <summary>
        /// Parses a simple expression (no function calls on top-level expression.
        /// </summary>
        public static bool AcceptAtom(string Text, int Start, out Expression Expression, out int LastChar)
        {
            // Procedure
            if (AcceptString(Text, Start, "{", out LastChar))
            {
                ProcedureExpression procedure;
                AcceptWhitespace(Text, LastChar, out LastChar);
                AcceptProcedure(Text, LastChar, out procedure, out LastChar);
                AcceptWhitespace(Text, LastChar, out LastChar);
                if (AcceptString(Text, LastChar, "}", out LastChar))
                {
                    Expression = procedure;
                    return true;
                }
            }

            // Variable
            Operator op;
            string varname;
            if (AcceptWord(Text, Start, out varname, out LastChar) && ValidVariable(varname) && !LookupOperator(varname, out op))
            {
                Expression = new VariableExpression(varname);
                return true;
            }

            // Parentheses
            if (AcceptString(Text, Start, "(", out LastChar))
            {
                // Operator
                int nc = LastChar;
                if (AcceptWord(Text, nc, out varname, out LastChar) && LookupOperator(varname, out op))
                {
                    if (AcceptString(Text, LastChar, ")", out LastChar))
                    {
                        Expression = new VariableExpression(varname);
                        return true;
                    }
                }

                Expression exp;
                AcceptWhitespace(Text, nc, out LastChar);
                if (AcceptExpression(Text, LastChar, out exp, out LastChar))
                {
                    AcceptWhitespace(Text, LastChar, out LastChar);
                    if (AcceptString(Text, LastChar, ")", out LastChar))
                    {
                        Expression = exp;
                        return true;
                    }
                }
            }

            // Integer literal
            long val;
            if (AcceptIntegerLiteral(Text, Start, out val, out LastChar))
            {
                Expression = new IntegerLiteralExpression(val);
                return true;
            }

            // Alternate lambda syntax
            if (AcceptString(Text, Start, "function", out LastChar))
            {
                AcceptWhitespace(Text, LastChar, out LastChar);
                if (AcceptString(Text, LastChar, "(", out LastChar))
                {
                    AcceptWhitespace(Text, LastChar, out LastChar);
                    List<KeyValuePair<Expression, string>> arglist;
                    AcceptArgumentList(Text, LastChar, out arglist, out LastChar);
                    AcceptWhitespace(Text, LastChar, out LastChar);
                    if (AcceptString(Text, LastChar, ")", out LastChar))
                    {
                        AcceptWhitespace(Text, LastChar, out LastChar);
                        if (AcceptString(Text, LastChar, "{", out LastChar))
                        {
                            ProcedureExpression procedure;
                            AcceptWhitespace(Text, LastChar, out LastChar);
                            AcceptProcedure(Text, LastChar, out procedure, out LastChar);
                            AcceptWhitespace(Text, LastChar, out LastChar);
                            if (AcceptString(Text, LastChar, "}", out LastChar))
                            {
                                Expression = new FunctionDefineExpression(arglist, procedure);
                                return true;
                            }
                        }
                    }
                }
            }

            // Function type
            if (AcceptString(Text, Start, "<", out LastChar))
            {
                AcceptWhitespace(Text, LastChar, out LastChar);
                List<KeyValuePair<Expression, string>> argtypelist;
                AcceptArgumentList(Text, LastChar, out argtypelist, out LastChar);
                AcceptWhitespace(Text, LastChar, out LastChar);
                if (AcceptString(Text, LastChar, ">", out LastChar))
                {
                    AcceptWhitespace(Text, LastChar, out LastChar);
                    Expression returntype;
                    if (AcceptTightExpression(Text, LastChar, out returntype, out LastChar))
                    {
                        Expression = new FunctionTypeExpression(argtypelist, returntype);
                        return true;
                    }
                }
            }

            Expression = null;
            return false;
        }
예제 #2
0
 public override void TypeCheck(
     IVariableStack<Expression> TypeStack,
     IVariableStack<Expression> Stack,
     out Expression TypeSafeExpression, out Expression Type)
 {
     Expression sifunc;
     Expression itype;
     this.Function.TypeCheck(
         TypeStack.Cut(this.ArgumentIndex).Append(new Expression[] { this.ArgumentType }),
         Stack.Cut(this.ArgumentIndex).Append(new Expression[] { Expression.Variable(Stack.NextFreeIndex) }),
         out sifunc, out itype);
     Type = Expression.FunctionType(this.ArgumentIndex, this.ArgumentType, itype);
     TypeSafeExpression = new FunctionDefineExpression(this.ArgumentIndex, this.ArgumentType, sifunc);
 }
예제 #3
0
        /// <summary>
        /// Parses an expression that can not be broken apart with an operator.
        /// </summary>
        public static bool AcceptTightExpression(string Text, int Start, out Expression Expression, out int LastChar)
        {
            // Normal
            if (AcceptAtom(Text, Start, out Expression, out LastChar))
            {
                int nc = 0;
                while (true)
                {
                    // Try to get a function
                    if (AcceptString(Text, LastChar, "(", out nc))
                    {
                        List<Expression> exps;
                        AcceptExpressions(Text, nc, out exps, out nc);
                        if (AcceptString(Text, nc, ")", out nc))
                        {
                            LastChar = nc;
                            Expression = new FunctionCallExpression(Expression, exps);
                            continue;
                        }
                    }

                    // Try to get an accessor
                    if (AcceptString(Text, LastChar, ".", out nc))
                    {
                        string accessname;
                        if (AcceptWord(Text, nc, out accessname, out nc))
                        {
                            LastChar = nc;
                            Expression = new AccessorExpression(Expression, accessname);
                            continue;
                        }
                    }
                    break;
                }

                return true;
            }

            // Lambda
            if (AcceptString(Text, Start, "(", out LastChar))
            {
                AcceptWhitespace(Text, LastChar, out LastChar);
                List<KeyValuePair<Expression, string>> arglist;
                AcceptArgumentList(Text, LastChar, out arglist, out LastChar);
                AcceptWhitespace(Text, LastChar, out LastChar);
                if (AcceptString(Text, LastChar, ")", out LastChar))
                {
                    AcceptWhitespace(Text, LastChar, out LastChar);
                    if (AcceptString(Text, LastChar, "=>", out LastChar))
                    {
                        AcceptWhitespace(Text, LastChar, out LastChar);
                        Expression def;
                        if (AcceptExpression(Text, LastChar, out def, out LastChar))
                        {
                            Expression = new FunctionDefineExpression(arglist, def);
                            return true;
                        }
                    }
                }
            }

            Expression = null;
            return false;
        }