Beispiel #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());
        }
        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);
            }
        }
        public override bool Implements(CodeType type)
        {
            if (type == null || type.GetType() != this.GetType())
            {
                return(false);
            }

            BaseLambda otherLambda = (BaseLambda)type;

            // If the argument length is not the same, return false.
            if (ArgumentTypes.Length != otherLambda.ArgumentTypes.Length)
            {
                return(false);
            }

            // If the other's return type does not implement this return type, return false.
            if (ReturnType != null && (otherLambda.ReturnType == null || !otherLambda.ReturnType.Implements(ReturnType)))
            {
                return(false);
            }

            // If any of the other's parameters to not implement this respective parameters, return false.
            for (int i = 0; i < ArgumentTypes.Length; i++)
            {
                if ((ArgumentTypes[i] == null) != (otherLambda.ArgumentTypes[i] == null))
                {
                    return(false);
                }
                if (ArgumentTypes[i] != null && !otherLambda.ArgumentTypes[i].Implements(ArgumentTypes[i]))
                {
                    return(false);
                }
            }

            return(true);
        }
 public LambdaInvoke(BaseLambda lambdaType)
 {
     LambdaType = lambdaType;
     ReturnType = lambdaType.ReturnType;
     Parameters = ParametersFromTypes(lambdaType.ArgumentTypes);
 }