private IScriptObject EvaluateExpression(FunctionInvokeExpression expression)
        {
            if (expression.Target is SuperReferenceExpression)
            {
                throw new RuntimeException(expression.Target.LinePragma,
                                           ExceptionResource.SuperInvoke);
            }
            var target = EvaluateExpression(expression.Target);

            if (target is ScriptNull)
            {
                throw new RuntimeException(expression.Target.LinePragma,
                                           ExceptionResource.NullReference);
            }
            var func = target as IFunctionObject;

            if (func == null)
            {
                throw new RuntimeException(expression.LinePragma,
                                           ExceptionResource.FunctionExpectedToInvoke);
            }
            var args = new List <IScriptObject>();

            if (expression.Parameters != null)
            {
                foreach (var p in expression.Parameters)
                {
                    args.Add(EvaluateExpression(p));
                }
            }
            try
            {
                return(func.Invoke(args) ?? ScriptNull.Instance);
            }
            catch (RuntimeException)
            {
                throw;
            }
            catch (Exception ex)
            {
                throw new RuntimeException(expression.LinePragma, ex.Message, ex);
            }
        }
Exemplo n.º 2
0
        public void simple_function_call()
        {
            // Foo()
            var target = new FunctionInvokeExpression
            {
                FunctionName = new IdentifierNode {
                    Name = "Foo"
                }
            };
            AstHelper helper = Mother.CreateRuntime();

            try
            {
                target.Compile(helper);
            }
            catch (SemanticException e)
            {
                var error = e.Errors.First() as FunctionNotDefinedError;
                Assert.IsNotNull(error);
            }
        }
Exemplo n.º 3
0
        private void InitializeExpressionParsers()
        {
            var expRest
                = lex_op_assign.GetParsingRule()
                  .Concat(p_expression.OrFail(ExceptionResource.ExpressionExpected),
                          (l, r) => Tuple.Create(0, l, r))
                  | (lex_op_plusAssign.GetParsingRule()
                     | lex_op_minusAssign.GetParsingRule()
                     | lex_op_mutiplyAssign.GetParsingRule()
                     | lex_op_divideAssign.GetParsingRule()
                     | lex_op_modAssign.GetParsingRule()
                     | lex_op_xorAssign.GetParsingRule()
                     | lex_op_andAssign.GetParsingRule()
                     | lex_op_orAssign.GetParsingRule()
                     | lex_op_shiftLeftAssign.GetParsingRule()
                     | lex_op_shiftRightAssign.GetParsingRule())
                  .Concat(p_expression.OrFail(ExceptionResource.ExpressionExpected),
                          (l, r) => Tuple.Create(1, l, r));

            p_expression.Content
                = p_exp_null
                  .Concat(expRest | ParsingRule <Tuple <int, Token, Expression> > .Empty(Tuple.Create <int, Token, Expression>(-1, null, null)),
                          (l, r) =>
            {
                if (r.Item1 == -1)
                {
                    return(l);
                }
                else if (r.Item1 == 0)
                {
                    return((Expression) new AssignExpression(l.LinePragma, l, r.Item3));
                }
                else if (r.Item1 == 1)
                {
                    return((Expression) new BinaryOperatorExpression(l.LinePragma, l, r.Item2.Text, r.Item3));
                }
                else
                {
                    throw new Exception();
                }
            });

            var nullRest
                = lex_op_null.GetParsingRule()
                  .Concat(p_exp_null.OrFail(ExceptionResource.ExpressionExpected), (t, e) => e);

            p_exp_null.Content
                = p_exp_conditional
                  .Concat(nullRest | PE.Empty(null),
                          (t, e) =>
            {
                if (e != null)
                {
                    return((Expression) new BinaryOperatorExpression(t.LinePragma, t, "??", e));
                }
                else
                {
                    return(t);
                }
            });

            var conditionalRest
                = lex_op_question.GetParsingRule()
                  .Concat(p_exp_conditional.OrFail(ExceptionResource.ExpressionExpected), (t, e) => e)
                  .Concat(lex_op_colon.GetParsingRule().OrFailExpected(":"), (t, u) => t)
                  .Concat(p_exp_conditional.OrFail(ExceptionResource.ExpressionExpected), (t, e) => Tuple.Create(t, e));

            p_exp_conditional.Content
                = p_exp_orElse
                  .Concat(conditionalRest | ParsingRule <Tuple <Expression, Expression> > .Empty(null),
                          (t, e) => {
                if (e != null)
                {
                    return((Expression) new TernaryOperatorExpression(t.LinePragma, t, "?", e.Item1, ":", e.Item2));
                }
                else
                {
                    return(t);
                }
            });

            var orElseRest
                = lex_op_orElse.GetParsingRule()
                  .Concat(p_exp_andAlso.OrFail(ExceptionResource.ExpressionExpected), (o, r) => Tuple.Create(o.Text, r));

            p_exp_orElse.Content
                = p_exp_andAlso
                  .Concat(
                      orElseRest.Repeat(),
                      (f, i) => i.Aggregate(f, (a, b) => new BinaryOperatorExpression(a.LinePragma, a, b.Item1, b.Item2)));

            var andAlsoRest
                = lex_op_andAlso.GetParsingRule()
                  .Concat(p_exp_or.OrFail(ExceptionResource.ExpressionExpected), (o, r) => Tuple.Create(o.Text, r));

            p_exp_andAlso.Content
                = p_exp_or
                  .Concat(
                      andAlsoRest.Repeat(),
                      (f, i) => i.Aggregate(f, (a, b) => new BinaryOperatorExpression(a.LinePragma, a, b.Item1, b.Item2)));

            var orRest
                = lex_op_or.GetParsingRule()
                  .Concat(p_exp_xor.OrFail(ExceptionResource.ExpressionExpected), (o, r) => Tuple.Create(o.Text, r));

            p_exp_or.Content
                = p_exp_xor
                  .Concat(
                      orRest.Repeat(),
                      (f, i) => i.Aggregate(f, (a, b) => new BinaryOperatorExpression(a.LinePragma, a, b.Item1, b.Item2)));

            var xorRest
                = lex_op_xor.GetParsingRule()
                  .Concat(p_exp_and.OrFail(ExceptionResource.ExpressionExpected), (o, r) => Tuple.Create(o.Text, r));

            p_exp_xor.Content
                = p_exp_and
                  .Concat(
                      xorRest.Repeat(),
                      (f, i) => i.Aggregate(f, (a, b) => new BinaryOperatorExpression(a.LinePragma, a, b.Item1, b.Item2)));

            var andRest
                = lex_op_and.GetParsingRule()
                  .Concat(p_exp_equality.OrFail(ExceptionResource.ExpressionExpected), (o, r) => Tuple.Create(o.Text, r));

            p_exp_and.Content
                = p_exp_equality
                  .Concat(
                      andRest.Repeat(),
                      (f, i) => i.Aggregate(f, (a, b) => new BinaryOperatorExpression(a.LinePragma, a, b.Item1, b.Item2)));

            var equalityRest
                = (lex_op_equal.GetParsingRule()
                   | lex_op_notEqual.GetParsingRule())
                  .Concat(p_exp_compare.OrFail(ExceptionResource.ExpressionExpected), (o, r) => Tuple.Create(o.Text, r));

            p_exp_equality.Content
                = p_exp_compare
                  .Concat(
                      equalityRest.Repeat(),
                      (f, i) => i.Aggregate(f, (a, b) => new BinaryOperatorExpression(a.LinePragma, a, b.Item1, b.Item2)));

            var compareRest
                = (lex_op_less.GetParsingRule()
                   | lex_op_greater.GetParsingRule()
                   | lex_op_lessEqual.GetParsingRule()
                   | lex_op_greaterEqual.GetParsingRule()
                   | lex_kw_is.GetParsingRule())
                  .Concat(p_exp_shift.OrFail(ExceptionResource.ExpressionExpected), (o, r) => Tuple.Create(o.Text, r));

            p_exp_compare.Content
                = p_exp_shift
                  .Concat(
                      compareRest.Repeat(),
                      (f, i) => i.Aggregate(f, (a, b) => new BinaryOperatorExpression(a.LinePragma, a, b.Item1, b.Item2)));

            var shiftRest
                = (lex_op_shiftLeft.GetParsingRule()
                   | lex_op_shiftRight.GetParsingRule())
                  .Concat(p_exp_add.OrFail(ExceptionResource.ExpressionExpected), (o, r) => Tuple.Create(o.Text, r));

            p_exp_shift.Content
                = p_exp_add
                  .Concat(
                      shiftRest.Repeat(),
                      (f, i) => i.Aggregate(f, (a, b) => new BinaryOperatorExpression(a.LinePragma, a, b.Item1, b.Item2)));

            var addRest
                = (lex_op_plus.GetParsingRule()
                   | lex_op_minus.GetParsingRule())
                  .Concat(p_exp_multiply.OrFail(ExceptionResource.ExpressionExpected), (o, r) => Tuple.Create(o.Text, r));

            p_exp_add.Content
                = p_exp_multiply
                  .Concat(
                      addRest.Repeat(),
                      (f, i) => i.Aggregate(f, (a, b) => new BinaryOperatorExpression(a.LinePragma, a, b.Item1, b.Item2)));

            var multiplyRest
                = (lex_op_multiply.GetParsingRule()
                   | lex_op_divide.GetParsingRule()
                   | lex_op_mod.GetParsingRule())
                  .Concat(p_exp_unary.OrFail(ExceptionResource.ExpressionExpected), (o, r) => Tuple.Create(o.Text, r));

            p_exp_multiply.Content
                = p_exp_unary
                  .Concat(
                      multiplyRest.Repeat(),
                      (f, i) => i.Aggregate(f, (a, b) => new BinaryOperatorExpression(a.LinePragma, a, b.Item1, b.Item2)));

            p_exp_unary.Content
                = (lex_op_not.GetParsingRule()
                   | lex_op_inverse.GetParsingRule()
                   | lex_op_increment.GetParsingRule()
                   | lex_op_decrement.GetParsingRule()
                   | lex_op_plus.GetParsingRule()
                   | lex_op_minus.GetParsingRule())
                  .Concat(p_exp_unary.OrFail(ExceptionResource.ExpressionExpected), (o, r) => (Expression) new PrefixOperatorExpression(o.LinePragma, o.Text, r))
                  | p_exp_primary;


            var primaryRest
                = lex_op_dot.GetParsingRule()
                  .Concat(lex_identifer.GetParsingRule().OrFail(ExceptionResource.IdentifierExpected),
                          (dot, member) => Tuple.Create(dot, (object)member))
                  | lex_op_leftParenthesis.GetParsingRule()
                  .Concat(
                      p_argList | ParsingRule <ExpressionCollection> .Empty(new ExpressionCollection()),
                      (id, args) => Tuple.Create(id, (object)args))
                  .Concat(
                      lex_op_rightParenthesis.GetParsingRule().OrFailExpected(")"),
                      (e, r) => e)
                  | lex_op_leftBracket.GetParsingRule()
                  .Concat(
                      p_argList | ParsingRule <ExpressionCollection> .Empty(new ExpressionCollection()),
                      (id, args) => Tuple.Create(id, (object)args))
                  .Concat(
                      lex_op_rightBracket.GetParsingRule().OrFailExpected("]"),
                      (e, r) => e)
                  | (lex_op_increment.GetParsingRule() | lex_op_decrement.GetParsingRule())
                  .Map(op => Tuple.Create(op, (object)null));

            p_exp_primary.Content
                = p_exp_atom
                  .Concat(
                      primaryRest.Repeat(),
                      (e, i) =>
            {
                Expression exp = e;
                foreach (var t in i)
                {
                    if (t.Item1.Lexeme == lex_op_dot)
                    {
                        exp = new MemberReferenceExpression(exp.LinePragma, exp, ((Token)t.Item2).Text);
                    }
                    else if (t.Item1.Lexeme == lex_op_leftParenthesis)
                    {
                        exp = new FunctionInvokeExpression(exp.LinePragma, exp, (ExpressionCollection)t.Item2);
                    }
                    else if (t.Item1.Lexeme == lex_op_leftBracket)
                    {
                        exp = new ArrayIndexerExpression(exp.LinePragma, exp, (ExpressionCollection)t.Item2);
                    }
                    else if (t.Item1.Lexeme == lex_op_increment ||
                             t.Item1.Lexeme == lex_op_decrement)
                    {
                        exp = new PostfixOperatorExpression(exp.LinePragma, exp, t.Item1.Text);
                    }
                    else
                    {
                        throw new Exception();
                    }
                }
                return(exp);
            });


            p_exp_new.Content
                = lex_kw_new.GetParsingRule()
                  .Concat(p_exp_type.OrFail(ExceptionResource.TypeExpected), (t, e) => Tuple.Create(t, e))
                  .Concat(
                      lex_op_leftParenthesis.GetParsingRule()
                      .Concat(
                          p_argList | ParsingRule <ExpressionCollection> .Empty(new ExpressionCollection()),
                          (id, args) => args)
                      .Concat(
                          lex_op_rightParenthesis.GetParsingRule().OrFailExpected(")"),
                          (e, r) => e)
                      | ParsingRule <ExpressionCollection> .Empty(new ExpressionCollection()),
                      (t, p) => (Expression) new NewExpression(t.Item1.LinePragma, t.Item2, p));

            p_exp_atom.Content
                = p_exp_array | p_exp_function | p_exp_object | p_exp_new
                  | lex_identifer.GetParsingRule(t => (Expression) new VariableReferenceExpression(t.LinePragma, t.Text))
                  | lex_kw_false.GetParsingRule(t => (Expression) new PrimitiveExpression(t.LinePragma, bool.Parse(t.Text)))
                  | lex_kw_true.GetParsingRule(t => (Expression) new PrimitiveExpression(t.LinePragma, bool.Parse(t.Text)))
                  | lex_li_string1.GetParsingRule(t => (Expression) new PrimitiveExpression(t.LinePragma, t.Text.Trim('\'').Replace("\\\'", "\'")))
                  | lex_li_string.GetParsingRule(t =>
            {
                string str;
                try
                {
                    str = t.Text.Trim('\"').ConvertFromEscapeChar();
                }
                catch (ParserException ex)
                {
                    var lp = new LinePragma(t.LinePragma.Line + ex.LinePragma.Line - 1, t.LinePragma.Span + ex.LinePragma.Span);
                    throw new ParserException(lp, ExceptionResource.UnrecognizedEscapeCharacter);
                }
                return((Expression) new PrimitiveExpression(t.LinePragma, str));
            })
                  | lex_li_num.GetParsingRule(t => (Expression) new PrimitiveExpression(t.LinePragma, double.Parse(t.Text)))
                  | lex_kw_null.GetParsingRule(t => (Expression) new PrimitiveExpression(t.LinePragma, null))
                  | lex_kw_this.GetParsingRule(t => (Expression) new ThisReferenceExpression(t.LinePragma))
                  | lex_kw_super.GetParsingRule(t => (Expression) new SuperReferenceExpression(t.LinePragma))
                  | lex_op_leftParenthesis.GetParsingRule()
                  .Concat(
                      p_expression,
                      (l, e) => e)
                  .Concat(
                      lex_op_rightParenthesis.GetParsingRule().OrFailExpected(")"),
                      (e, r) => e);

            p_argList.Content
                = p_expression
                  .Concat(
                      lex_op_comma.GetParsingRule().Concat(p_expression.OrFail(ExceptionResource.ExpressionExpected), (comma, e) => e).Repeat(),
                      (e, i) =>
            {
                var list = i.ToList();
                list.Insert(0, e);
                return(new ExpressionCollection(list));
            });

            p_exp_array.Content
                = lex_op_leftBracket.GetParsingRule()
                  .Concat(
                      p_argList | ParsingRule <ExpressionCollection> .Empty(new ExpressionCollection()),
                      (t, eles) => Tuple.Create(t, eles))
                  .Concat(
                      lex_op_rightBracket.GetParsingRule().OrFailExpected("]"),
                      (eles, t) => (Expression) new ArrayExpression(eles.Item1.LinePragma, eles.Item2));

            var para
                = lex_identifer.GetParsingRule()
                  .Concat(
                      lex_op_assign.GetParsingRule().Concat(p_expression, (t, e) => e)
                      | PE.Empty(null),
                      (t, e) => e == null ? new Parameter(t.LinePragma, t.Text) : new Parameter(t.LinePragma, t.Text, e));

            p_paraList.Content
                = para.Concat(
                      lex_op_comma.GetParsingRule().Concat(para.OrFail(ExceptionResource.IdentifierExpected), (comma, p) => p).Repeat(),
                      (p, i) =>
            {
                var list = i.ToList();
                list.Insert(0, p);
                return(new ParameterCollection(list));
            })
                  | ParsingRule <ParameterCollection> .Empty(null);


            p_paras.Content
                = lex_op_leftParenthesis.GetParsingRule()
                  .Concat(p_paraList, (t, paras) => paras)
                  .Concat(lex_op_rightParenthesis.GetParsingRule(), (paras, t) => paras);

            var funcExp
                = lex_kw_function.GetParsingRule()
                  .Concat(p_paras.OrFail(ExceptionResource.ParemetersExpected), (t, paras) => Tuple.Create(t, paras))
                  .Concat(p_stats.OrFail(ExceptionResource.StatementsExpected), (paras, stats) => (Expression) new FunctionExpression(paras.Item1.LinePragma, paras.Item2, stats));

            var lambda_paras
                = p_paras
                  | para.Map(p => new ParameterCollection(p));

            var lambda_stats
                = p_stats
                  | p_expression.Map(e => new StatementCollection(new ReturnStatement(e.LinePragma, e)));

            var lambdaExp
                = lambda_paras
                  .Concat(lex_op_lambda.GetParsingRule(), (paras, t) => Tuple.Create(paras, t))
                  .Concat(lambda_stats.OrFail(ExceptionResource.StatementsExpected), (paras, stats) => (Expression) new FunctionExpression(paras.Item2.LinePragma, paras.Item1, stats));

            p_exp_function.Content
                = funcExp | lambdaExp;

            var objectMember
                = lex_identifer.GetParsingRule()
                  .Concat(lex_op_colon.GetParsingRule(), (t, u) => t)
                  .Concat(p_expression.OrFail(ExceptionResource.ExpressionExpected), (t, e) => Tuple.Create(t, e));
            var objectMemberList
                = objectMember
                  .Concat(
                      lex_op_comma.GetParsingRule()
                      .Concat(objectMember.OrFail(ExceptionResource.IdentifierExpected), (t, m) => m)
                      .Repeat(),
                      (t, i) =>
            {
                var list = i.ToList();
                list.Insert(0, t);
                return(list);
            });

            p_exp_object.Content
                = lex_op_leftBrace.GetParsingRule()
                  .Concat(objectMemberList | ParsingRule <List <Tuple <Token, Expression> > > .Empty(new List <Tuple <Token, Expression> >()),
                          (t, m) => Tuple.Create(t, m))
                  .Concat(lex_op_rightBrace.GetParsingRule().OrFailExpected("}"), (t, u) =>
            {
                var dict = new List <KeyValuePair <string, Expression> >();
                foreach (var m in t.Item2)
                {
                    dict.Add(new KeyValuePair <string, Expression>(m.Item1.Text, m.Item2));
                }
                return((Expression) new ObjectExpression(t.Item1.LinePragma, dict));
            });

            var typeRest
                = lex_op_dot.GetParsingRule()
                  .Concat(lex_identifer.GetParsingRule(),
                          (dot, id) => id);

            p_exp_type.Content
                = lex_identifer.GetParsingRule(id => new VariableReferenceExpression(id.LinePragma, id.Text))
                  .Concat(
                      typeRest.Repeat(),
                      (e, i) =>
            {
                Expression exp = e;
                foreach (var t in i)
                {
                    exp = new MemberReferenceExpression(exp.LinePragma, exp, t.Text);
                }
                return(exp);
            });
        }