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); } }
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); } }
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); }); }