public dynamic Visit(CallFuncExpr expr) { if (expr.Arguments != null) { expr.Arguments = Visit((dynamic)expr.Arguments); } return(expr); }
public dynamic Visit(CallFuncExpr expr) { var node = new TreeNode("Function Call") { Tag = expr.Node }; if (expr.Arguments != null) { node.Nodes.Add(Visit(expr.Arguments)); } return(node); }
public dynamic Visit(CallFuncExpr expr) { Visit((dynamic)expr.Function.Code); return(null); }
public dynamic Visit(CallFuncExpr expr) { return(expr.Function.ReturnType); }
/// <summary> /// Rule: Variable -> IDENTIFIER ((Array | Call))? ; /// </summary> protected override object EvalVariable(ParseTree tree, params object[] paramlist) { var identNode = GetNode(TokenType.IDENTIFIER); var name = identNode.Token.Text; var isLeftSide = paramlist != null && paramlist.Any() && (bool)paramlist.First(); if (GetNode(TokenType.Array) == null && GetNode(TokenType.Call) == null) { if (isLeftSide) { return(new LeftSideExprVariable { Name = name, Type = LeftSideExprType.Variable, Node = this }); } var existingSymbol = Namespaces.Current.Symbols.SingleOrDefault(x => x.Name == name); if (existingSymbol != null && existingSymbol.Type == SymbolType.Array) { throw new ParseException($"Использование массива {name} без индексатора", identNode); } if (existingSymbol != null && existingSymbol.Type == SymbolType.Function) { throw new ParseException($"Использование функции {name} без скобок", identNode); } if (existingSymbol != null && existingSymbol.Type != SymbolType.Unknown) { existingSymbol.UsagesCount++; return(new GetVariableExpr { Type = existingSymbol.Type, Node = this, Name = name }); } throw new ParseException($"Использование непроинициализированной переменной {name}", identNode); } if (GetNode(TokenType.Array) != null) { var expr = (ExpressionBase)GetNode(TokenType.Array).Eval(tree); var exprType = expr.GetExprType(); if (isLeftSide) { return(new LeftSideExprArray { ArrayKeyType = exprType, Index = expr, Node = this, Type = LeftSideExprType.Array, Name = name }); } var existingSymbol = Namespaces.Current.Symbols.SingleOrDefault(x => x.Name == name && x.Type == SymbolType.Array && x.ArrayKeyType == exprType); if (existingSymbol != null) { existingSymbol.UsagesCount++; return(new GetArrayExpr { ValuesType = existingSymbol.ArrayValueType, Node = this, Name = name, Index = expr, KeysType = existingSymbol.ArrayKeyType }); } if (Namespaces.Current.Symbols.Any(x => x.Name == name && x.Type == SymbolType.Array)) { throw new ParseException("Невозможно изменить тип ключа у массива", identNode); } throw new ParseException($"Использование непроинициализированного массива {name}", identNode); } if (GetNode(TokenType.Call) != null) { var arguments = ((Arguments)GetNode(TokenType.Call).Eval(tree)); var funcDeclaration = AstCreator.FuncDeclarations.SingleOrDefault(x => x.Name == name && x.Arguments.Count == arguments.Values.Count); if (funcDeclaration == null) { throw new ParseException($"Попытка использовать необъявленную функцию {name}", identNode); } var argumentsTypes = arguments.Values.Select(av => av.GetExprType()).ToList(); if (AstCreator.FuncImplementation.Count > 0) { if (AstCreator.FuncImplementation.Any(x => x.Name == name && x.ArgumentsTypes.SequenceEqual(argumentsTypes))) { throw new ParseException("Рекурсия не поддерживается", identNode); } } var funcImplementation = AstCreator.FuncImplementations.SingleOrDefault(x => x.Name == name && x.ArgumentsTypes.SequenceEqual(argumentsTypes)); if (funcImplementation == null) { funcImplementation = new FuncImplementation { Name = name, Node = this, ArgumentsTypes = argumentsTypes, Declaration = funcDeclaration }; AstCreator.FuncImplementation.Push(funcImplementation); var currentNamespace = Namespaces.Current; Namespaces.Current = Namespaces.Root; Namespaces.LevelDown(new Namespace($"{name}({string.Join(", ", argumentsTypes)})")); for (var index = 0; index < arguments.Values.Count; index++) { var symbolType = argumentsTypes[index]; var symbol = new Symbol(symbolType, funcDeclaration.Arguments[index]); Namespaces.Current.AddSymbol(symbol, identNode); } funcDeclaration.Node.Eval(tree, true, this); funcImplementation.Namespace = Namespaces.Current; Namespaces.Current = currentNamespace; AstCreator.FuncImplementations.Add(AstCreator.FuncImplementation.Pop()); } var callFuncExpr = new CallFuncExpr { Node = this, Function = funcImplementation, Arguments = arguments }; if (isLeftSide) { return(new LeftSideExprCall { Name = name, Type = LeftSideExprType.Call, Node = this, CallFunc = callFuncExpr }); } if (funcImplementation.ReturnType == SymbolType.Void || funcImplementation.ReturnType == SymbolType.Unknown) { throw new ParseException("Невозможно использовать функции, возвращающие void в выражениях", this); } return(callFuncExpr); } return(null); }
public dynamic Visit(CallFuncExpr expr) { var objects = expr.Arguments.Values.Select(x => Visit((dynamic)x)).Cast <Operand>().ToArray(); return(_codeGen.This().Invoke(expr.Function.Name, objects)); }