private Expression Compile(bool multiple) { if (CurrentToken == null) { return(null); } List <Expression> expressions = new List <Expression>(); bool braced = CurrentToken.IsOpenBrace; if (braced) { MoveNext(); multiple = true; } IfExpression ifExpression = null; while (CurrentToken != null) { var token = CurrentToken; switch (token.TokenType) { case TokenType.CloseBrace: { if (!braced) { throw new LexerException(TokenPosition.Unknown, token.Text); } MoveNext(); multiple = false; break; } case TokenType.ForEach: { MoveNext(); InExpression expression = CompileBracketed() as InExpression; if (expression == null) { throw new LexerException("foreach syntax error", token.TokenPosition, token.Text); } ForEachExpression forEach = new ForEachExpression(TokenPosition.Unknown); forEach.Iterator = expression.Variable; forEach.Expression = expression.Expression; forEach.Body = Compile(false); expressions.Add(forEach); break; } case TokenType.If: { MoveNext(); var expr = CompileBracketed(); ifExpression = new IfExpression(TokenPosition.Unknown, expr); ifExpression.TrueExpression = Compile(false); expressions.Add(ifExpression); break; } case TokenType.Else: { MoveNext(); if (ifExpression != null) { ifExpression.FalseExpression = Compile(false); ifExpression = null; } break; } case TokenType.Return: { MoveNext(); Expression expression = Compile(multiple: false); expressions.Add(new ReturnExpression(TokenPosition.Unknown, expression)); break; } case TokenType.FunctionDefinition: { MoveNext(); var functionExpression = new FunctionDefinitionExpression(TokenPosition.Unknown); if (CurrentToken.TokenType != TokenType.Term) { throw new LexerException("function name expected", TokenPosition.Unknown, CurrentToken.Text); } functionExpression.Name = CurrentToken.Text; MoveNext(); int level = 0; int start = CurrentIndex - 1; int end = -1; while (CurrentToken != null) { if (CurrentToken.IsLeftParen) { level++; } else if (CurrentToken.IsRightParen) { if (level > 0) { level--; if (level == 0) { end = CurrentIndex; break; } } } MoveNext(); } CurrentIndex = start; var parameters = CompileStatement(end) as CallExpression; functionExpression.ParameterNames = (from p in parameters.Parameters select((VariableExpression)p).VarName).ToArray(); functionExpression.Body = Compile(false); expressions.Add(functionExpression); } break; default: expressions.Add(CompileStatement()); break; } if (!multiple) { break; } } if (expressions.Count > 1) { return(new SequenceExpression(TokenPosition.Unknown, expressions.ToArray())); } if (expressions.Count == 1) { return(expressions[0]); } return(null); }
public override ValueExpression Evaluate(IParserContext context) { object methodObject = MethodExpression.Evaluate(context).Value; ValueExpression[] parameters = EvaluateExpressionArray(Parameters, context); Type[] parameterTypes = parameters.ConvertAll(expr => expr.Type); object[] parameterValues = parameters.ConvertAll(expr => expr.Value); if (methodObject is MethodDefinition) { Type returnType; return(Exp.Value(TokenPosition, ((MethodDefinition)methodObject).Invoke(parameterTypes, parameterValues, out returnType), returnType)); } if (methodObject is ConstructorInfo[]) { ConstructorInfo[] constructors = (ConstructorInfo[])methodObject; MethodBase method = LazyBinder.SelectBestMethod(constructors, parameterTypes, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance); if (method == null) { throw new ExpressionEvaluationException("No match found for constructor " + constructors[0].Name, this); } object value = LazyBinder.Invoke(method, parameterValues); //object value = ((ConstructorInfo)method).Invoke(parameterValues); return(Exp.Value(TokenPosition, value, method.DeclaringType)); } if (methodObject is Delegate[]) { Delegate[] delegates = (Delegate[])methodObject; MethodBase[] methods = delegates.ConvertAll <Delegate, MethodBase>(d => d.GetMethodInfo()); MethodBase method = LazyBinder.SelectBestMethod(methods, parameterTypes, BindingFlags.Public | BindingFlags.Static | BindingFlags.Instance); if (method == null) { throw new ExpressionEvaluationException("No match found for delegate " + MethodExpression, this); } object value = LazyBinder.Invoke(method, delegates[Array.IndexOf(methods, method)].Target, parameterValues); return(Exp.Value(TokenPosition, value, ((MethodInfo)method).ReturnType)); } if (methodObject is Delegate) { Delegate method = (Delegate)methodObject; MethodInfo methodInfo = method.GetMethodInfo(); object value = methodInfo.Invoke(method.Target, parameterValues); return(new ValueExpression(TokenPosition, value, methodInfo.ReturnType)); } if (methodObject is FunctionDefinitionExpression) { FunctionDefinitionExpression func = (FunctionDefinitionExpression)methodObject; var functionContext = context.CreateLocal(); for (int i = 0; i < parameterValues.Length; i++) { functionContext.Set(func.ParameterNames[i], parameterValues[i]); } return(func.Body.Evaluate(functionContext)); } throw new ExpressionEvaluationException(MethodExpression + " is not a function", this); }
public FunctionValueExpression(TokenPosition position, FunctionDefinitionExpression function) : base(position, function, typeof(FunctionDefinitionExpression)) { }