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); }
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); }
// (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); }