Пример #1
0
        private object FuncBody(SeparatedSyntaxList <ParameterSyntax> ps, BlockSyntax body, params object[] args)
        {
            var vf = new VarFrame(Vars);

            for (int i = 0; i < ps.Count; i++)
            {
                vf.SetValue($"{ps[i].Identifier}", HybInstance.Object(args[i]));
            }
            RunBlock(body as BlockSyntax, vf);
            if (Halt == HaltType.Return)
            {
                Halt = HaltType.None;
            }

            return(Ret.Unwrap());
        }
Пример #2
0
        private HybInstance RunParenthesizedLambda(ParenthesizedLambdaExpressionSyntax node)
        {
            // Detects the lambda is `Func` or `Action`.
            var hasReturn = node.DescendantNodes()
                            .Any(x => x is ReturnStatementSyntax);
            var ps      = node.ParameterList.Parameters;
            var retType = TypeDeduction.GetReturnType(Resolver, node.Body);

            MethodInfo converter = null;
            object     body      = null;

            // `Func`
            if (hasReturn)
            {
                converter = GetConverterF(ps.Count);

                var genericArgs = new Type[ps.Count + 1];
                for (int i = 0; i < ps.Count; i++)
                {
                    if (ps[i].Type == null)
                    {
                        throw new SemanticViolationException("Please provide a explicit type to all lambda parameters, this function is partialy implemented.");
                    }
                    genericArgs[i] = Resolver
                                     .GetType($"{ps[i].Type}")
                                     .Unwrap();
                }
                genericArgs[genericArgs.Length - 1] = retType.Unwrap();
                converter = converter
                            .MakeGenericMethod(genericArgs);

                if (ps.Count == 0)
                {
                    body = new Func <object>(() => {
                        RunBlock(node.Body as BlockSyntax);
                        if (Halt == HaltType.Return)
                        {
                            Halt = HaltType.None;
                        }
                        return(Ret.Unwrap());
                    });
                }
                else if (ps.Count == 1)
                {
                    body = new Func <object, object>((a) => {
                        return(FuncBody(ps, node.Body as BlockSyntax, a));
                    });
                }
                else if (ps.Count == 2)
                {
                    body = new Func <object, object, object>((a, b) => {
                        return(FuncBody(ps, node.Body as BlockSyntax, a, b));
                    });
                }
                else if (ps.Count == 3)
                {
                    body = new Func <object, object, object, object>((a, b, c) => {
                        return(FuncBody(ps, node.Body as BlockSyntax, a, b, c));
                    });
                }
                else if (ps.Count == 4)
                {
                    body = new Func <object, object, object, object, object>((a, b, c, d) => {
                        return(FuncBody(ps, node.Body as BlockSyntax, a, b, c, d));
                    });
                }
                else if (ps.Count == 5)
                {
                    body = new Func <object, object, object, object, object, object>((a, b, c, d, e) => {
                        return(FuncBody(ps, node.Body as BlockSyntax, a, b, c, d, e));
                    });
                }
                else if (ps.Count == 6)
                {
                    body = new Func <object, object, object, object, object, object, object>((a, b, c, d, e, f) => {
                        return(FuncBody(ps, node.Body as BlockSyntax, a, b, c, d, e, f));
                    });
                }
                else if (ps.Count == 7)
                {
                    body = new Func <object, object, object, object, object, object, object, object>((a, b, c, d, e, f, g) => {
                        return(FuncBody(ps, node.Body as BlockSyntax, a, b, c, d, e, f, g));
                    });
                }
            }
            // `Action`
            else
            {
                converter = GetConverterA(ps.Count);

                var genericArgs = new Type[ps.Count];
                for (int i = 0; i < ps.Count; i++)
                {
                    if (ps[i].Type == null)
                    {
                        throw new SemanticViolationException("Please provide a explicit type to all lambda parameters, this function is partialy implemented.");
                    }
                    genericArgs[i] = Resolver
                                     .GetType($"{ps[i].Type}")
                                     .Unwrap();
                }

                if (ps.Count > 0)
                {
                    converter = converter
                                .MakeGenericMethod(genericArgs);
                }

                if (ps.Count == 0)
                {
                    body = new Action(() => {
                        RunBlock(node.Body as BlockSyntax);
                        if (Halt == HaltType.Return)
                        {
                            Halt = HaltType.None;
                        }
                    });
                }
                else if (ps.Count == 1)
                {
                    body = new Action <object>((a) => {
                        ActionBody(ps, node.Body as BlockSyntax, a);
                    });
                }
                else if (ps.Count == 2)
                {
                    body = new Action <object, object>((a, b) => {
                        ActionBody(ps, node.Body as BlockSyntax, a, b);
                    });
                }
                else if (ps.Count == 3)
                {
                    body = new Action <object, object, object>((a, b, c) => {
                        ActionBody(ps, node.Body as BlockSyntax, a, b, c);
                    });
                }
                else if (ps.Count == 4)
                {
                    body = new Action <object, object, object, object>((a, b, c, d) => {
                        ActionBody(ps, node.Body as BlockSyntax, a, b, c, d);
                    });
                }
                else if (ps.Count == 5)
                {
                    body = new Action <object, object, object, object, object>((a, b, c, d, e) => {
                        ActionBody(ps, node.Body as BlockSyntax, a, b, c, d, e);
                    });
                }
                else if (ps.Count == 6)
                {
                    body = new Action <object, object, object, object, object, object>((a, b, c, d, e, f) => {
                        ActionBody(ps, node.Body as BlockSyntax, a, b, c, d, e, f);
                    });
                }
                else if (ps.Count == 7)
                {
                    body = new Action <object, object, object, object, object, object, object>((a, b, c, d, e, f, g) => {
                        ActionBody(ps, node.Body as BlockSyntax, a, b, c, d, e, f, g);
                    });
                }
            }

            var convertedDelegate = converter.Invoke(
                null, new object[] { body });

            return(new HybInstance(
                       HybTypeCache.GetHybType(convertedDelegate.GetType()),
                       convertedDelegate));
        }