예제 #1
0
            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());
            }
예제 #2
0
        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);
        }
예제 #3
0
            public Expression Visit(AstFunction functionCall)
            {
                var resolveFunction = ResolveFunction(functionCall.Function);

                return(Expression.Call(resolveFunction,
                                       functionCall.Arguments.Select(a => a.Accept(this))));
            }
예제 #4
0
        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));
        }
예제 #5
0
        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))));
        }
예제 #6
0
    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);
    }
예제 #7
0
        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);
        }
예제 #8
0
            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());
            }
예제 #9
0
        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);
        }
예제 #10
0
 public object Visit(AstFunction functionCall)
 {
     return(EvaluateFunction(functionCall.Function, functionCall.Arguments.Select(p => p.Accept(this))));
 }
예제 #11
0
 public string Visit(AstFunction functionCall)
 {
     return(string.Format("{0}({1})", functionCall.Function, string.Join(", ", functionCall.Arguments.Select(i => i.Accept(this)))));
 }
예제 #12
0
 public virtual T Visit(AstFunction functionCall)
 {
     return(Default(functionCall));
 }