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);
        }
        // (clr-field-set! type field-name obj value)
        public override Expression Generate(object args, CodeBlock cb)
        {
            Type   t        = null;
            string type     = null;
            bool   inferred = false;

            object rtype = Builtins.First(args);

            ExtractTypeInfo(rtype, out t, out type, out inferred);

            string member = SymbolTable.IdToString((SymbolId)Builtins.Second(Builtins.Second(args)));

            BindingFlags bf = BindingFlags.Instance;

            Expression instance = GetAst(Builtins.Third(args), cb);

            if (instance is ConstantExpression && ((ConstantExpression)instance).Value == null)
            {
                bf       = BindingFlags.Static;
                instance = null;

                if (inferred)
                {
                    ClrSyntaxError("clr-field-set!", "type inference not possible on static member", member);
                }
            }
            else if (inferred)
            {
                if (instance is UnaryExpression && instance.Type == typeof(object))
                {
                    var ue = (UnaryExpression)instance;
                    instance = ue.Operand;
                }
                t = instance.Type;
            }
            else
            {
                instance = ConvertToHelper(t, instance);
            }
            type = t.Name;


            FieldInfo fi = t.GetField(member, BindingFlags.Public | bf | BindingFlags.FlattenHierarchy);

            if (fi == null)
            {
                ClrSyntaxError("clr-field-set!", "field not found on type: " + type, args);
            }

            if (fi.IsLiteral)
            {
                ClrSyntaxError("clr-field-set!", "cannot set a constant field: " + type);
            }

            Expression value = GetAst(Builtins.Car(Builtins.LastPair(args)), cb);

            return(Ast.Comma(Ast.AssignField(instance, fi, value), Ast.ReadField(null, Unspecified)));
        }
        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));
            }
        }
Exemple #4
0
 public override Expression Generate(object args, CodeBlock cb)
 {
     return(GetCons(Builtins.Car(args), cb));
 }