public void ShouldBeAppliedIfFunctionDoesNotEndWithReturn() { const string name = "test"; var funcAst = new AstFunction(name, new List <Parameter>(), new Position(0, 0)); funcAst.Expressions.Add( new AstFunctionCall("println", new List <AstExpression> { new AstBinaryMathOperation(BinaryMath.Plus, new AstIntegerConstant(5, null), new AstIntegerConstant(5, null), null) }, null)); funcAst.Expressions.Add( new AstFunctionCall("println", new List <AstExpression> { new AstStringConstant("hello world", null) }, null) ); var env = new ScriptEnvironment(new OperationCodeFactory(), new ValueFactory()); Compiler.Compile(env, new AstRoot(new Position(0, 0)) { Functions = { funcAst } }); Assert.Equal(typeof(Return), env.Functions[GetGlobalName(name)].Code.Last().Op.GetType()); }
public void ErrorCollection() { var node = new AstFunction("foo", new AstNode[] { new AstUnsupported("some error") }); var errorNodes = AstDocumentOrderTraverser.Traverse(node).Where(i => i.Accept(new AstIsErrorVisitor())).ToList(); Assert.AreEqual(1, errorNodes.Count); }
public Expression Visit(AstFunction functionCall) { var resolveFunction = ResolveFunction(functionCall.Function); return(Expression.Call(resolveFunction, functionCall.Arguments.Select(a => a.Accept(this)))); }
public void ExpressionCalculator() { var ast = new AstFunction("Math.Sin", new [] { new AstParameter("x") }); var f = MakeFunc <Func <object, object> >(ast); Assert.AreEqual(1.0, f((Math.PI / 2).ToString())); Assert.AreEqual(1.0, f(Math.PI / 2)); }
public static void WrapByIIFE(AstToplevel topLevelAst) { var func = new AstFunction(); func.ArgNames.Add(new AstSymbolFunarg("undefined")); func.HasUseStrictDirective = true; func.Body.TransferFrom(ref topLevelAst.Body); topLevelAst.Body.Add(new AstSimpleStatement(new AstUnaryPrefix(Operator.LogicalNot, new AstCall(func)))); }
public override AstNode ShallowClone() { var res = new AstFunction(Source, Start, End, Name, IsGenerator, Async); res.Body.AddRange(Body.AsReadOnlySpan()); res.ArgNames.AddRange(ArgNames.AsReadOnlySpan()); res.HasUseStrictDirective = HasUseStrictDirective; res.Pure = Pure; return(res); }
private static EvalValue CalcFunction(FuncEnvironment env, AstFunction ast) { // 初始化实参 var callee = env.GetMainEnv().GetFuncDef(ast.token.GetText()); if (callee != null) { // 脚本方法 var paramList = callee.paramList; for (var i = 0; i < paramList.length; ++i) { var item = paramList.GetName(i); if (ast.args.ChildrenCount() <= i) { throw new RunTimeException("实参不足", ast); } var argItem = ast.args.ChildAt(i) as AstExpression; env.AddArg(item, argItem.Eval(env.parent)); } // 执行函数体 var funcBody = callee.block; var ret = new EvalValue(); foreach (var item in funcBody) { try { ret = item.Eval(env); } catch (ReturnException) { break; } } if (env.Get("return@" + env.GetScopeName()) != null) { return(env.Get("return@" + env.GetScopeName())); } return(ret); } else { var csm = env.GetMainEnv().GetCsFuncDef(ast.token.GetText()); if (csm != null) { // CS方法 var csRet = csm(ast.args.ToArgArray(env)); var ret = new EvalValue(csRet); return(ret); } } throw new RunTimeException("函数未定义:" + ast.token.GetText() + "()", ast); }
public void ShouldBeAppliedIfFunctionIsEmpty() { const string name = "test"; var funcAst = new AstFunction(name, new List <Parameter>(), new Position(0, 0)); var env = new ScriptEnvironment(new OperationCodeFactory(), new ValueFactory()); Compiler.Compile(env, new AstRoot(new Position(0, 0)) { Functions = { funcAst } }); Assert.Equal(typeof(Return), env.Functions[GetGlobalName(name)].Code.Last().Op.GetType()); }
AstLambda ParseFunction(Position startLoc, bool isStatement, bool isNullableId, bool allowExpressionBody = false, bool isAsync = false) { var generator = false; if (Options.EcmaVersion >= 6 && !isAsync) { generator = Eat(TokenType.Star); } if (Options.EcmaVersion < 8 && isAsync) { throw new InvalidOperationException(); } AstSymbol?id = null; if (isStatement || isNullableId) { id = isNullableId && Type != TokenType.Name ? null : ParseIdent(); if (id != null) { CheckLVal(id, true, VariableKind.Var); } } var oldInGen = _inGenerator; var oldInAsync = _inAsync; var oldYieldPos = _yieldPos; var oldAwaitPos = _awaitPos; var oldInFunc = _inFunction; _inGenerator = generator; _inAsync = isAsync; _yieldPos = default; _awaitPos = default; _inFunction = true; EnterFunctionScope(); if (isStatement == false && isNullableId == false) { id = Type == TokenType.Name ? ParseIdent() : null; } var parameters = new StructList <AstNode>(); ParseFunctionParams(ref parameters); MakeSymbolFunArg(ref parameters); var body = new StructList <AstNode>(); var useStrict = false; var unused = ParseFunctionBody(parameters, startLoc, id, allowExpressionBody, ref body, ref useStrict); _inGenerator = oldInGen; _inAsync = oldInAsync; _yieldPos = oldYieldPos; _awaitPos = oldAwaitPos; _inFunction = oldInFunc; if (isStatement || isNullableId) { if (id != null) { id = new AstSymbolDefun(id); } var astDefun = new AstDefun(this, startLoc, _lastTokEnd, id != null ? (AstSymbolDefun)id : null, ref parameters, generator, isAsync, ref body); astDefun.SetUseStrict(useStrict); return(astDefun); } if (id != null) { id = new AstSymbolLambda(id); } var astFunction = new AstFunction(this, startLoc, _lastTokEnd, id != null ? (AstSymbolLambda)id : null, ref parameters, generator, isAsync, ref body); astFunction.SetUseStrict(useStrict); return(astFunction); }
public object Visit(AstFunction functionCall) { return(EvaluateFunction(functionCall.Function, functionCall.Arguments.Select(p => p.Accept(this)))); }
public string Visit(AstFunction functionCall) { return(string.Format("{0}({1})", functionCall.Function, string.Join(", ", functionCall.Arguments.Select(i => i.Accept(this))))); }
public virtual T Visit(AstFunction functionCall) { return(Default(functionCall)); }