Ejemplo n.º 1
0
        public FunctionDefinition(string name, Parameter/*!*/[]/*!*/ parameters, Statement body)
        {
            ContractUtils.RequiresNotNullItems(parameters, "parameters");

            if (name == null)
            {
                _name = "<lambda$" + Interlocked.Increment(ref _lambdaId) + ">";
                _isLambda = true;
            }
            else
            {
                _name = name;
            }

            _parameters = parameters;
            _body = body;
            _argsVariable = new TotemVariable("arguments", VariableKind.Parameter, this);
        }
Ejemplo n.º 2
0
        // arg: ( identifier ':' )? expression
        private Arg ParseArg()
        {
            Arg ret;
            int start = GetStart();
            Expression value = ParseExpression();
            if (value is NameExpression)
            {
                string name = ((NameExpression)value).Name;
                int end = GetEnd();
                if (MaybeEat(TokenKind.Colon))
                {
                    value = ParseExpression();
                    ret = new Arg(name, value);
                    ret.SetLoc(_globalParent, start, GetEnd());
                    return ret;
                }
                else if (MaybeEat(TokenKind.Arrow))
                {
                    var param = new Parameter(name);
                    param.SetLoc(_globalParent, start, end);
                    ret = new Arg(ParseLambdaBody(start, param));
                    ret.SetLoc(_globalParent, start, GetEnd());
                    return ret;
                }
            }

            ret = new Arg(value);
            ret.SetLoc(_globalParent, value.IndexSpan);
            return ret;
        }
Ejemplo n.º 3
0
        private Expression ParsePrimaryExpression()
        {
            int start, end, globalStart;
            Expression ret;

            // lambda handling
            List<Parameter> parameters = new List<Parameter>();
            Parameter param;
            bool startBody = false;

            switch (PeekToken().Kind)
            {
                case TokenKind.Name:
                    NameToken nameToken = (NameToken)NextToken();
                    globalStart = GetStart();
                    if (_sink != null)
                        _sink.StartName(GetSourceSpan(), nameToken.Name);
                    ret = new NameExpression(nameToken.Name);
                    ret.SetLoc(_globalParent, GetStart(), GetEnd());
                    if (MaybeEat(TokenKind.Arrow))
                    {
                        param = new Parameter(nameToken.Name);
                        param.SetLoc(_globalParent, ret.IndexSpan);
                        parameters.Add(param);
                        startBody = true;
                        goto lambda;
                    }
                    return ret;

                case TokenKind.Constant:
                    ConstantValueToken constantToken = (ConstantValueToken)NextToken();
                    start = GetStart();
                    object cv = constantToken.Value;
                    if (cv == null)
                    {
                        ret = new ConstantExpression(null);
                    }
                    else if (cv is bool)
                    {
                        ret = new ConstantExpression((bool)cv);
                    }
                    else if (cv is string)
                    {
                        ret = new ConstantExpression((string)cv);
                    }
                    else if (cv is int)
                    {
                        ret = new ConstantExpression((int)cv);
                    }
                    else if (cv is Uninitialized)
                    {
                        ret = new ConstantExpression(Uninitialized.Instance);
                    }
                    else if (cv is double)
                    {
                        ret = new ConstantExpression((double)cv);
                    }
                    else if (cv is BigInteger)
                    {
                        ret = new ConstantExpression((BigInteger)cv);
                    }
                    else
                    {
                        throw Assert.Unreachable;
                    }
                    ret.SetLoc(_globalParent, GetStart(), GetEnd());
                    return ret;

                case TokenKind.LeftParenthesis:

                    NextToken();
                    start = GetStart();
                    globalStart = GetStart();
                    if (PeekToken().Kind == TokenKind.Name) // may be lambda: (a = 2) => a;
                    {
                        NameToken nt = (NameToken)NextToken();
                        if (PeekToken().Kind == TokenKind.RightParenthesis)
                        {
                            end = GetEnd();
                            start = GetStart();
                            NextToken();
                            if (MaybeEat(TokenKind.Arrow))
                            {
                                param = new Parameter(nt.Name);
                                param.SetLoc(_globalParent, GetStart(), end);
                                parameters.Add(param);
                                startBody = true;
                                goto lambda;
                            }
                            else
                            {
                                ret = new NameExpression(nt.Name);
                                ret.SetLoc(_globalParent, start, end);

                                ret = new ParenthesisExpression(ret);
                                ret.SetLoc(_globalParent, globalStart, GetEnd());
                                return ret;
                            }
                        }
                        else if (PeekToken().Kind == TokenKind.Assign)
                        {
                            end = GetEnd();
                            start = GetStart();
                            NextToken();
                            var left = new NameExpression(nt.Name);
                            left.SetLoc(_globalParent, start, end);
                            var right = ParseExpression();

                            if (PeekToken().Kind == TokenKind.RightParenthesis)
                            {
                                end = GetEnd();
                                NextToken();
                                if (MaybeEat(TokenKind.Arrow))
                                {
                                    param = new Parameter(nt.Name, right);
                                    param.SetLoc(_globalParent, left.StartIndex, right.EndIndex);
                                    parameters.Add(param);
                                    startBody = true;
                                    goto lambda;
                                }
                                else
                                {
                                    ret = new AssignExpression(TokenKind.Assign, left, right);
                                    ret.SetLoc(_globalParent, start, end);

                                    ret = new ParenthesisExpression(ret);
                                    ret.SetLoc(_globalParent, globalStart, GetEnd());
                                    return ret;
                                }
                            }
                            else if (PeekToken().Kind == TokenKind.Comma)
                            {
                                param = new Parameter(nt.Name, right);
                                param.SetLoc(_globalParent, start, GetEnd());
                                parameters.Add(param);
                                goto lambda;
                            }
                            else
                            {
                                throw Assert.Unreachable;
                            }
                        }
                        else if (PeekToken().Kind == TokenKind.Comma)
                        {
                            param = new Parameter(nt.Name);
                            param.SetLoc(_globalParent, GetStart(), GetEnd());
                            parameters.Add(param);
                            goto lambda;
                        }
                        else
                        {
                            throw Assert.Unreachable;
                        }
                    }
                    else if (PeekToken(TokenKind.RightParenthesis))
                    {
                        goto lambda;
                    }
                    else // not NameToken nor RightParen
                    {
                        ret = new ParenthesisExpression(ParseExpression());
                        Eat(TokenKind.RightParenthesis);
                        ret.SetLoc(_globalParent, globalStart, GetEnd());
                        return ret;
                    }

                    lambda: // parse the rest of the lambda
                    if (!startBody)
                    {
                        while (MaybeEat(TokenKind.Comma))
                        {
                            NameToken nt = (NameToken)NextToken(TokenKind.Name);
                            start = GetStart();
                            Expression defaultVal = MaybeEat(TokenKind.Assign) ? ParseExpression() : null;
                            param = new Parameter(nt.Name, defaultVal);
                            param.SetLoc(_globalParent, start, GetEnd());
                            parameters.Add(param);
                        }
                        Eat(TokenKind.RightParenthesis);
                        Eat(TokenKind.Arrow);
                    }

                    return ParseLambdaBody(globalStart, parameters.ToArray());

                case TokenKind.LeftBracket:
                    return ParseArrayLiteral();

                default:
                    return null; // syntax error
            }
        }
Ejemplo n.º 4
0
        private Statement ParseFunctionStatement()
        {
            Eat(TokenKind.KeywordFunction);
            var start = GetStart();
            var globalStart = start;

            var name = (NameToken)NextToken(TokenKind.Name);

            List<Parameter> parameters = new List<Parameter>();
            Eat(TokenKind.LeftParenthesis);
            int lStart = GetStart(), lEnd = GetEnd();
            int grouping = _tokenizer.GroupingLevel;

            if (!MaybeEat(TokenKind.RightParenthesis))
            {
                do
                {
                    NameToken nt = (NameToken)NextToken(TokenKind.Name);
                    start = GetStart();
                    Expression defaultVal = MaybeEat(TokenKind.Assign) ? ParseExpression() : null;
                    var param = new Parameter(nt.Name, defaultVal);
                    param.SetLoc(_globalParent, start, GetEnd());
                    parameters.Add(param);
                } while (MaybeEat(TokenKind.Comma));
                Eat(TokenKind.RightParenthesis);
            }
            int rStart = GetStart(), rEnd = GetEnd();

            var inFinally = _inFinally;
            var inLoop = _inLoop;
            var return_ = _return;
            var isGenerator = _isGenerator;
            var isAsync = _isAsync;
            _inLoop = false;
            _inFinally = false;
            _return = false;
            _isGenerator = false;
            var ret = new FunctionDefinition(name.Name, parameters.ToArray());

            PushFunction(ret);

            var body = ParseBlock();

            FunctionDefinition ret2 = PopFunction();
            Debug.Assert(ret == ret2);

            _inLoop = inLoop;
            _inFinally = inFinally;
            _return = return_;
            _isGenerator = isGenerator;
            _isAsync = isAsync;

            ret.Body = body;

            if(_sink != null)
                _sink.MatchPair(
                    new SourceSpan(_tokenizer.IndexToLocation(lStart), _tokenizer.IndexToLocation(lEnd)),
                    new SourceSpan(_tokenizer.IndexToLocation(rStart), _tokenizer.IndexToLocation(rEnd)),
                    grouping
                );

            ret.SetLoc(_globalParent, globalStart, GetEnd());
            return ret;
        }
Ejemplo n.º 5
0
        private TotemVariable _variable; // The variable corresponding to the function name or null for lambdas

        #endregion Fields

        #region Constructors

        public FunctionDefinition(string name, Parameter/*!*/[]/*!*/ parameters)
            : this(name, parameters, (Statement)null)
        {
        }
Ejemplo n.º 6
0
 public override bool Walk(Parameter node)
 {
     node.Parent = _binder._currentScope;
     node.TotemVariable = _binder.DefineParameter(node.Name);
     return false;
 }
Ejemplo n.º 7
0
 public override bool Walk(Parameter node)
 {
     node.Parent = _currentScope;
     return base.Walk(node);
 }
Ejemplo n.º 8
0
 public LambdaExpression(Parameter[] parameters, Statement body)
 {
     _function = new FunctionDefinition(null, parameters, body);
 }