public override Expression Generate(object args, CodeBlock c)
        {
            var refs = ClrGenerator.SaveReferences();

            object arg      = Builtins.First(args);
            object typespec = (Builtins.Second(args));

            Cons body = Builtins.Cdr(Builtins.Cdr(args)) as Cons;

            var returntype = ClrGenerator.ExtractTypeInfo(Builtins.List(quote, Builtins.Second(typespec)));

            CodeBlock cb = Ast.CodeBlock(SpanHint, GetLambdaName(c), returntype);

            NameHint    = SymbolId.Empty;
            cb.Filename = LocationHint;
            cb.Parent   = c;

            bool isrest = AssignParameters(cb, arg, Builtins.Car(typespec));

            List <Statement> stmts = new List <Statement>();

            FillBody(cb, stmts, body, true);

            Type dt = GetDelegateType(cb);
            Type ct = GetClosureType(cb);

            Expression ex = Ast.New(ct.GetConstructor(new Type[] { dt }), Ast.CodeBlockExpression(cb, true, dt));

            ClrGenerator.ResetReferences(refs);

            return(ex);
        }
        protected static bool AssignParameters(CodeBlock cb, object arg, object types)
        {
            bool isrest = false;
            Cons cargs  = arg as Cons;
            Cons ctypes = types as Cons;

            if (cargs != null)
            {
                while (cargs != null)
                {
                    SymbolId an = (SymbolId)Builtins.First(cargs);

                    if (ctypes == null)
                    {
                        Builtins.SyntaxError("AssignParameters", "missing parameter type", Builtins.UnGenSymInternal(an), Builtins.FALSE);
                    }

                    object type = Builtins.First(ctypes);

                    Type clrtype = ClrGenerator.ExtractTypeInfo(Builtins.List(quote, type));

                    CreateParameter(an, cb, clrtype);

                    Cons r  = cargs.cdr as Cons;
                    Cons rt = ctypes.cdr as Cons;

                    // not sure I can even handle this...
                    if (r == null && cargs.cdr != null)
                    {
                        SymbolId ta = (SymbolId)cargs.cdr;
                        CreateParameter(ta, cb, typeof(object));
                        isrest = true;
                        break;
                    }
                    else
                    {
                        cargs  = r;
                        ctypes = rt;
                    }
                }
                if (ctypes != null)
                {
                    Builtins.SyntaxError("AssignParameters", "extra parameter type(s)", ctypes, Builtins.FALSE);
                }
            }
            else if (arg != null) // empty
            {
                SymbolId an = (SymbolId)arg;
                isrest = true;
                CreateParameter(an, cb, typeof(object));
            }
            // else both null, which is OK, no?
            return(isrest);
        }
Exemple #3
0
        protected static bool AssignParameters(CodeBlock cb, object arg, object types)
        {
            bool isrest = false;
            Cons cargs  = arg as Cons;
            Cons ctypes = types as Cons;

            if (cargs != null)
            {
                while (cargs != null)
                {
                    SymbolId an   = (SymbolId)Builtins.First(cargs);
                    object   type = Builtins.First(ctypes);

                    Type clrtype = ClrGenerator.ExtractTypeInfo(Builtins.List(quote, type));

                    CreateParameter(an, cb, clrtype);

                    Cons r  = cargs.cdr as Cons;
                    Cons rt = ctypes.cdr as Cons;

                    if (r == null && cargs.cdr != null)
                    {
                        SymbolId ta = (SymbolId)cargs.cdr;
                        CreateParameter(ta, cb, typeof(object));
                        isrest = true;
                        break;
                    }
                    else
                    {
                        cargs  = r;
                        ctypes = rt;
                    }
                }
            }
            else if (arg != null) // empty
            {
                SymbolId an = (SymbolId)arg;
                isrest = true;
                CreateParameter(an, cb, typeof(object));
            }
            return(isrest);
        }
        public override Expression Generate(object args, CodeBlock c)
        {
            Cons lambdas = args as Cons;

            int arlen = lambdas == null ? 0 : lambdas.Length;

            if (arlen == 1)
            {
                if (lambdagen == null)
                {
                    lambdagen = Context.Scope.LookupName(SymbolTable.StringToId("typed-lambda")) as TypedLambdaGenerator;
                }
                return(lambdagen.Generate(lambdas.car, c));
            }
            else
            {
                List <CodeBlockDescriptor> cbs = new List <CodeBlockDescriptor>();

                string lambdaname = GetLambdaName(c);

                NameHint = SymbolId.Empty;

                var sh = SpanHint;
                var lh = LocationHint;


                while (lambdas != null)
                {
                    var refs = ClrGenerator.SaveReferences();

                    object actual = lambdas.car;

                    object arg      = Builtins.First(actual);
                    object typespec = (Builtins.Second(actual));

                    Cons body = Builtins.Cdr(Builtins.Cdr(actual)) as Cons;

                    var returntype = ClrGenerator.ExtractTypeInfo(Builtins.List(quote, Builtins.Second(typespec)));

                    CodeBlock cb = Ast.CodeBlock(SpanHint, lambdaname, returntype);
                    NameHint    = SymbolId.Empty;
                    cb.Filename = lh;
                    cb.Parent   = c;

                    bool isrest = AssignParameters(cb, arg, Builtins.Car(typespec));

                    List <Statement> stmts = new List <Statement>();
                    FillBody(cb, stmts, body, true);

                    Type dt = GetDelegateType(cb);
                    Type ct = GetClosureType(cb);

                    var        cbe = Ast.CodeBlockExpression(cb, true, dt);
                    Expression ex  = Ast.New(ct.GetConstructor(new Type[] { dt }), cbe);

                    CodeBlockDescriptor cbd = new CodeBlockDescriptor();
                    cbd.arity     = isrest ? -cb.ParameterCount : cb.ParameterCount;
                    cbd.callable  = ex;
                    cbd.codeblock = cbe;
                    cbd.varargs   = isrest;

                    descriptorshack2.Add(cbd.callable, cbd);

                    cbs.Add(cbd);

                    lambdas = lambdas.cdr as Cons;

                    ClrGenerator.ResetReferences(refs);
                }

                return(MakeTypedCaseClosure(lambdaname, cbs));
            }
        }