1 package gnu.kawa.functions; 2 import kawa.standard.Scheme; 3 import gnu.bytecode.Type; 4 import gnu.bytecode.ClassType; 5 import gnu.bytecode.CodeAttr; 6 import gnu.mapping.*; 7 import gnu.expr.*; 8 import gnu.kawa.reflect.Invoke; 9 10 public class Convert extends Procedure2 implements CanInline, Inlineable 11 { 12 public static final Convert as = new Convert(); 13 static { as.setName("as"); } 14 15 public static Convert getInstance () 16 { 17 return as; 18 } 19 20 public Object apply2 (Object arg1, Object arg2) 21 { 22 Type type = (Type) arg1; 23 return type.coerceFromObject (arg2); 24 } 25 26 static gnu.bytecode.ClassType typeType; 27 static gnu.bytecode.Method coerceMethod; 28 29 public Expression inline (ApplyExp exp, ExpWalker walker) 30 { 31 return Invoke.inlineClassName(exp, 0, (InlineCalls) walker); 32 } 33 34 public void compile (ApplyExp exp, Compilation comp, Target target) 35 { 36 Expression[] args = exp.getArgs(); 37 if (args.length != 2) 38 throw new Error ("wrong number of arguments to "+getName()); 39 CodeAttr code = comp.getCode(); 40 Type type = Scheme.getTypeValue(args[0]); 41 if (type != null) 42 { 43 args[1].compile(comp, Target.pushValue(type)); 44 if (code.reachableHere()) 45 target.compileFromStack(comp, type); 46 } 47 else 48 { 49 if (typeType == null) 50 { 51 typeType = ClassType.make("gnu.bytecode.Type"); 52 coerceMethod = typeType.addMethod("coerceFromObject", 53 Compilation.apply1args, 54 Type.pointer_type, 55 gnu.bytecode.Access.PUBLIC); 56 } 57 58 args[0].compile(comp, typeType); 59 args[1].compile(comp, Target.pushObject); 60 code.emitInvokeVirtual(coerceMethod); 61 target.compileFromStack(comp, Type.pointer_type); 62 } 63 } 64 65 public Type getReturnType (Expression[] args) 66 { 67 if (args != null && args.length == 2) 68 { 69 Type type = Scheme.getTypeValue(args[0]); 70 if (type != null) 71 return type; 72 } 73 return Type.pointer_type; 74 } 75 76 82 public static Expression makeCoercion(Expression value, Expression type) 83 { 84 Expression[] exps = new Expression[2]; 85 exps[0] = type; 86 exps[1] = value; 87 QuoteExp c = new QuoteExp(Convert.getInstance()); 88 return new ApplyExp(c, exps); 89 } 90 91 97 public static Expression makeCoercion(Expression value, Type type) 98 { 99 return makeCoercion(value, new QuoteExp(type)); 100 } 101 102 103 public static void setCoercedReturnValue (LambdaExp lexp, Expression type, 104 Language language) 105 { 106 gnu.bytecode.Type rtype = language.getTypeFor(type); 107 if (rtype != null) 108 { 109 Expression value = lexp.body; 110 lexp.body = Convert.makeCoercion(value, type); 111 lexp.body.setLine(value); 112 lexp.setReturnType(rtype); 113 } 114 } 115 } 116 | Popular Tags |