示例#1
0
 public static Expression ByteVectorSet(Expression[] values)
 {
     if (values.Length == 3)
     {
         return(Ast.AssignArrayIndex(Ast.ConvertHelper(values[0], typeof(byte[])), Ast.ConvertHelper(values[1], typeof(int)), Ast.ConvertHelper(values[2], typeof(byte))));
     }
     UnsafeSyntaxError("$bytevector-set!", "expected 3 arguments", values);
     return(null);
 }
示例#2
0
 public static Expression VectorSet(Expression[] values)
 {
     if (values.Length == 3)
     {
         if (!typeof(Array).IsAssignableFrom(values[0].Type))
         {
             values[0] = Ast.ConvertHelper(values[0], typeof(object[]));
         }
         return(Ast.AssignArrayIndex(values[0], Ast.ConvertHelper(values[1], typeof(int)), values[2]));
     }
     UnsafeSyntaxError("$vector-set!", "expected 3 arguments", values);
     return(null);
 }
示例#3
0
        // (clr-call type member obj arg1 ... )
        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 = null;
            var    marg   = Builtins.Second(args);

            object memobj = null;

            Type[] argtypes = null;
            Type[] gentypes = null;

            if (marg is SymbolId)
            {
                var mem = Builtins.SymbolValue(marg);

                if (mem is Cons)
                {
                    ExtractMethodInfo(mem as Cons, out member, ref argtypes, ref gentypes);
                }
                else
                {
                    ClrSyntaxError("clr-call", "type member not supported", mem);
                }
            }
            else
            {
                memobj = Builtins.Second(marg);

                member = memobj is SymbolId?SymbolTable.IdToString((SymbolId)memobj) : "";

                if (memobj is string)
                {
                    string mems = memobj as string;
                    int    bi   = mems.IndexOf('(');
                    if (bi < 0)
                    {
                        member = mems;
                    }
                    else
                    {
                        member = mems.Substring(0, bi);
                    }
                }
                else if (memobj is Cons)
                {
                    ExtractMethodInfo(memobj as Cons, out member, ref argtypes, ref gentypes);
                }
            }

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

            CallType ct = CallType.ImplicitInstance;

            if (instance is ConstantExpression && ((ConstantExpression)instance).Value == null)
            {
                ct = CallType.None;

                if (inferred)
                {
                    ClrSyntaxError("clr-call", "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;

            Expression[] arguments = GetAstListNoCast(Cdddr(args) as Cons, cb);

            if (member == "get_Item")
            {
                if (Attribute.IsDefined(t, typeof(DefaultMemberAttribute)))
                {
                    var dma = Attribute.GetCustomAttribute(t, typeof(DefaultMemberAttribute)) as DefaultMemberAttribute;
                    member = "get_" + dma.MemberName;
                }
                else if (t.IsArray)
                {
                    var index = arguments[0];
                    return(Ast.ArrayIndex(instance, Ast.ConvertHelper(index, typeof(int))));
                }
            }
            else if (member == "set_Item")
            {
                if (Attribute.IsDefined(t, typeof(DefaultMemberAttribute)))
                {
                    var dma = Attribute.GetCustomAttribute(t, typeof(DefaultMemberAttribute)) as DefaultMemberAttribute;
                    member = "set_" + dma.MemberName;
                }
                else if (t.IsArray)
                {
                    var index = arguments[0];
                    var v     = arguments[1];
                    return(Ast.Comma(Ast.AssignArrayIndex(instance, Ast.ConvertHelper(index, typeof(int)), v), Ast.ReadField(null, Unspecified)));
                }
            }

            List <MethodBase> candidates = new List <MethodBase>();

            BindingFlags bf = BindingFlags.Public | (ct == CallType.None ? BindingFlags.Static : BindingFlags.Instance) | BindingFlags.FlattenHierarchy;

            foreach (MethodInfo mi in t.GetMember(member, MemberTypes.Method, bf))
            {
                if (PAL.ExcludeParamtypes(mi))
                {
                    continue;
                }
                if (mi.ContainsGenericParameters)
                {
                    if (gentypes != null && mi.GetGenericArguments().Length == gentypes.Length)
                    {
                        candidates.Add(mi.MakeGenericMethod(gentypes));
                        continue;
                    }
                }
                candidates.Add(mi);
            }

            Type[] types = new Type[arguments.Length];

            for (int i = 0; i < types.Length; i++)
            {
                types[i] = arguments[i].Type;
            }

            if (memobj is string)
            {
                string mems = memobj as string;
                int    bi   = mems.IndexOf('(');
                if (bi < 0)
                {
                    // do notthig
                }
                else
                {
                    string[] typeargs = mems.Substring(bi + 1).TrimEnd(')').Split(',');

                    for (int i = 0; i < types.Length; i++)
                    {
                        if (typeargs[i].Length > 0)
                        {
                            types[i] = ScanForType(typeargs[i]);
                        }
                    }
                }
            }
            else if (argtypes != null)
            {
                for (int i = 0; i < types.Length; i++)
                {
                    types[i] = argtypes[i];
                }
            }

            if (ct == CallType.ImplicitInstance)
            {
                types = ArrayUtils.Insert(t, types);
            }

            MethodBinder mb = MethodBinder.MakeBinder(Binder, member, candidates, BinderType.Normal);

            MethodCandidate mc = mb.MakeBindingTarget(ct, types);

            if (mc == null)
            {
                types = new Type[arguments.Length];

                for (int i = 0; i < types.Length; i++)
                {
                    types[i] = typeof(object);
                }

                if (ct == CallType.ImplicitInstance)
                {
                    types = ArrayUtils.Insert(t, types);
                }

                mc = mb.MakeBindingTarget(ct, types);
            }

            if (mc != null)
            {
                MethodInfo meth = (MethodInfo)mc.Target.Method;
                // do implicit cast
                ParameterInfo[] pars = meth.GetParameters();
                for (int i = 0; i < arguments.Length; i++)
                {
                    Type tt = pars[i].ParameterType;
                    arguments[i] = ConvertToHelper(tt, arguments[i]);
                }

                Expression r = null;

                // o god...
                if (ct == CallType.ImplicitInstance)
                {
                    r = Ast.ComplexCallHelper(instance, (MethodInfo)mc.Target.Method, arguments);
                }
                else
                {
                    r = Ast.ComplexCallHelper((MethodInfo)mc.Target.Method, arguments);
                }

                return(ConvertFromHelper(meth.ReturnType, r));
            }

            ClrSyntaxError("clr-call", "member could not be resolved on type: " + type, args, member);

            return(null);
        }
        private bool MakeDefaultMemberRule(Operators oper)
        {
            if (_types[0].IsArray)
            {
                if (Binder.CanConvertFrom(_types[1], typeof(int), NarrowingLevel.All))
                {
                    if (oper == Operators.GetItem)
                    {
                        _rule.SetTarget(_rule.MakeReturn(Binder,
                                                         Ast.ArrayIndex(
                                                             Param0,
                                                             ConvertIfNeeded(Param1, typeof(int))
                                                             )
                                                         ));
                    }
                    else
                    {
                        _rule.SetTarget(_rule.MakeReturn(Binder,
                                                         Ast.AssignArrayIndex(
                                                             Param0,
                                                             ConvertIfNeeded(Param1, typeof(int)),
                                                             ConvertIfNeeded(Param2, _types[0].GetElementType())
                                                             )
                                                         ));
                    }
                    return(true);
                }
            }

            MethodInfo[] defaults = GetMethodsFromDefaults(_types[0].GetDefaultMembers(), oper);
            if (defaults.Length != 0)
            {
                MethodBinder binder = MethodBinder.MakeBinder(Binder,
                                                              oper == Operators.GetItem ? "get_Item" : "set_Item",
                                                              defaults,
                                                              BinderType.Normal);

                MethodCandidate cand = binder.MakeBindingTarget(CallType.ImplicitInstance, _types);

                if (cand != null)
                {
                    if (oper == Operators.GetItem)
                    {
                        _rule.SetTarget(_rule.MakeReturn(Binder, cand.Target.MakeExpression(Binder, _rule, _rule.Parameters, _types)));
                    }
                    else
                    {
                        _rule.SetTarget(_rule.MakeReturn(Binder,
                                                         Ast.Comma(0,
                                                                   _rule.Parameters[2],
                                                                   cand.Target.MakeExpression(Binder, _rule, _rule.Parameters, _types)
                                                                   )
                                                         ));
                    }
                }
                else
                {
                    _rule.SetTarget(Binder.MakeInvalidParametersError(binder, Action, CallType.None, defaults, _rule, _args));
                }
                return(true);
            }

            return(false);
        }