Ejemplo n.º 1
0
        public LambdaAction(ParseInfo parseInfo, Scope scope, DeltinScriptParser.LambdaContext context)
        {
            Scope lambdaScope = scope.Child();

            RecursiveCallHandler = new LambdaRecursionHandler(this);
            CallInfo             = new CallInfo(RecursiveCallHandler, parseInfo.Script);

            // Get the lambda parameters.
            Parameters   = new Var[context.define().Length];
            InvokedState = new SubLambdaInvoke[Parameters.Length];
            for (int i = 0; i < Parameters.Length; i++)
            {
                InvokedState[i] = new SubLambdaInvoke();
                // TODO: Make custom builder.
                Parameters[i] = new ParameterVariable(lambdaScope, new DefineContextHandler(parseInfo, context.define(i)), InvokedState[i]);
            }

            CodeType[] argumentTypes = Parameters.Select(arg => arg.CodeType).ToArray();

            // context.block() will not be null if the lambda is a block.
            // () => {}
            if (context.block() != null)
            {
                // Parse the block.
                Block = new BlockAction(parseInfo.SetCallInfo(CallInfo), lambdaScope, context.block());

                // Validate the block.
                BlockTreeScan validation = new BlockTreeScan(parseInfo, Block, "lambda", DocRange.GetRange(context.INS()));
                validation.ValidateReturns();

                if (validation.ReturnsValue)
                {
                    LambdaType    = new ValueBlockLambda(validation.ReturnType, argumentTypes);
                    MultiplePaths = validation.MultiplePaths;
                }
                else
                {
                    LambdaType = new BlockLambda(argumentTypes);
                }
            }
            // context.expr() will not be null if the lambda is an expression.
            // () => 2 * x
            else if (context.expr() != null)
            {
                // Get the lambda expression.
                Expression = parseInfo.SetCallInfo(CallInfo).GetExpression(lambdaScope, context.expr());
                LambdaType = new MacroLambda(Expression.Type(), argumentTypes);
            }

            // Add so the lambda can be recursive-checked.
            parseInfo.TranslateInfo.RecursionCheck(CallInfo);

            // Add hover info
            parseInfo.Script.AddHover(DocRange.GetRange(context.INS()), new MarkupBuilder().StartCodeLine().Add(LambdaType.GetName()).EndCodeLine().ToString());
        }
Ejemplo n.º 2
0
        private void _getLambdaStatement(PortableLambdaType expectingType)
        {
            ParseInfo parser = _parseInfo.SetCallInfo(CallInfo).AddVariableTracker(this).SetExpectingLambda(expectingType?.ReturnType);

            CodeType returnType   = null;
            bool     returnsValue = false;

            // Get the statements.
            if (_context.Statement is Block block)
            {
                // Parse the block.
                Statement = new BlockAction(parser, _lambdaScope, block);

                // Validate the block.
                BlockTreeScan validation = new BlockTreeScan(_parseInfo, (BlockAction)Statement, "lambda", _context.Arrow.Range);
                validation.ValidateReturns();

                if (validation.ReturnsValue)
                {
                    returnType    = validation.ReturnType;
                    MultiplePaths = validation.MultiplePaths;
                    returnsValue  = true;
                }
            }
            else if (_context.Statement is ExpressionStatement exprStatement)
            {
                // Get the lambda expression.
                Expression   = parser.GetExpression(_lambdaScope, exprStatement.Expression);
                returnType   = Expression.Type();
                returnsValue = true;
            }
            else
            {
                // Statement
                Statement = parser.GetStatement(_lambdaScope, _context.Statement);
                if (Statement is IExpression expr)
                {
                    Expression   = expr;
                    returnType   = expr.Type();
                    returnsValue = true;
                }
            }

            LambdaType = new PortableLambdaType(expectingType?.LambdaKind ?? LambdaKind.Anonymous, _argumentTypes, returnsValue, returnType, _isExplicit);

            // Add so the lambda can be recursive-checked.
            _parseInfo.TranslateInfo.RecursionCheck(CallInfo);

            if (!LambdaType.IsConstant())
            {
                Identifier = _parseInfo.TranslateInfo.GetComponent <LambdaGroup>().Add(new LambdaHandler(this));
            }
        }
Ejemplo n.º 3
0
        public LambdaAction(ParseInfo parseInfo, Scope scope, DeltinScriptParser.LambdaContext context)
        {
            Scope lambdaScope = scope.Child();

            // Get the lambda parameters.
            Parameters = new Var[context.define().Length];
            for (int i = 0; i < Parameters.Length; i++)
            {
                // TODO: Make custom builder.
                Parameters[i] = new ParameterVariable(lambdaScope, new DefineContextHandler(parseInfo, context.define(i)));
            }

            CodeType[] argumentTypes = Parameters.Select(arg => arg.CodeType).ToArray();

            // context.block() will not be null if the lambda is a block.
            // () => {}
            if (context.block() != null)
            {
                // Parse the block.
                Block = new BlockAction(parseInfo, lambdaScope, context.block());

                // Validate the block.
                BlockTreeScan validation = new BlockTreeScan(parseInfo, Block, "lambda", DocRange.GetRange(context.INS()));
                validation.ValidateReturns();

                if (validation.ReturnsValue)
                {
                    LambdaType    = new ValueBlockLambda(validation.ReturnType, argumentTypes);
                    MultiplePaths = validation.MultiplePaths;
                }
                else
                {
                    LambdaType = new BlockLambda(argumentTypes);
                }
            }
            // context.expr() will not be null if the lambda is an expression.
            // () => 2 * x
            else if (context.expr() != null)
            {
                // Get the lambda expression.
                Expression = parseInfo.GetExpression(lambdaScope, context.expr());
                LambdaType = new MacroLambda(Expression.Type(), argumentTypes);
            }
        }