public void SecondPass(PortableLambdaType type)
 {
     foreach (var apply in _apply)
     {
         apply.Finalize(type);
     }
 }
 public void FinishAppliers(PortableLambdaType type)
 {
     foreach (var apply in _apply)
     {
         apply.GetLambdaStatement(type);
     }
 }
 public void FirstPass(PortableLambdaType type)
 {
     foreach (var apply in _apply)
     {
         apply.GetLambdaContent(type);
     }
 }
 public void Finalize(PortableLambdaType expecting)
 {
     // Check if the current lambda implements the expected type.
     if (!LambdaType.Implements(expecting))
     {
         _parseInfo.Script.Diagnostics.Error("Expected lambda of type '" + expecting.GetName() + "'", _context.Arrow.Range);
     }
 }
Example #5
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));
            }
        }
 public ExpectingLambdaInfo(PortableLambdaType type)
 {
     RegisterOccursLater = false;
     Type = type;
 }
Example #7
0
 public LambdaVariable(int parameter, Lambda.PortableLambdaType contextualLambdaType, Scope operationalScope, IVarContextHandler contextHandler, Lambda.IBridgeInvocable invocable)
     : base(operationalScope, contextHandler, invocable)
 {
     _parameter            = parameter;
     _contextualLambdaType = contextualLambdaType;
 }
        public void GetLambdaContent(PortableLambdaType expectingType)
        {
            _resolved = true;

            // Get the lambda parameters.
            Parameters     = new Var[_context.Parameters.Count];
            InvokedState   = new SubLambdaInvoke[Parameters.Length];
            _argumentTypes = new CodeType[Parameters.Length];

            for (int i = 0; i < Parameters.Length; i++)
            {
                if (_isExplicit && _context.Parameters[i].Type == null)
                {
                    _parseInfo.Script.Diagnostics.Error("Inconsistent lambda parameter usage; parameter types must be all explicit or all implicit", _context.Parameters[i].Range);
                }

                InvokedState[i]   = new SubLambdaInvoke();
                Parameters[i]     = (Var) new LambdaVariable(i, expectingType, _lambdaScope, new LambdaContextHandler(_parseInfo, _context.Parameters[i]), InvokedState[i]).GetVar();
                _argumentTypes[i] = Parameters[i].GetDefaultInstance(null).CodeType.GetCodeType(_parseInfo.TranslateInfo);
            }

            ParseInfo parser = _parseInfo.SetCallInfo(CallInfo).AddVariableTracker(this).SetExpectType(expectingType?.ReturnType).SetReturnType(expectingType?.ReturnType);

            bool returnsValue = false;

            // Get the statements.
            if (_context.Statement is Block block)
            {
                var returnTracker = new ReturnTracker();

                // Parse the block.
                Statement = new BlockAction(parser.SetReturnTracker(returnTracker), _lambdaScope, block);

                if (returnTracker.ReturnsValue)
                {
                    ReturnType    = returnTracker.InferredType;
                    MultiplePaths = returnTracker.IsMultiplePaths;
                    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();
                    if (ReturnType != null)
                    {
                        returnsValue = true;
                    }
                }
            }

            LambdaType = new PortableLambdaType(new PortableLambdaTypeBuilder(
                                                    kind: expectingType?.LambdaKind ?? LambdaKind.Anonymous,
                                                    parameters: _argumentTypes,
                                                    returnType: ReturnType,
                                                    returnsValue: returnsValue,
                                                    parameterTypesKnown: _isExplicit));

            // Add so the lambda can be recursive-checked.
            _parseInfo.TranslateInfo.GetComponent <RecursionCheckComponent>().AddCheck(CallInfo);
        }
Example #9
0
 public LambdaInvoke(PortableLambdaType lambdaType)
 {
     LambdaType = lambdaType;
     Parameters = ParametersFromTypes(lambdaType.Parameters);
 }