1 package gnu.expr; 2 import gnu.mapping.*; 3 import gnu.bytecode.Type; 4 5 9 10 public class QuoteExp extends Expression 11 { 12 Object value; 13 14 public final Object getValue() { return value; } 15 16 public final Object valueIfConstant() { return value; } 17 18 protected Type type; 19 public final gnu.bytecode.Type getType() 20 { 21 if (type != null) 22 return type; 23 if (value == Values.empty) 24 return Type.void_type; 25 else if (value == null) 26 return Type.nullType; 27 else if (this == undefined_exp) 28 return Type.pointer_type; 29 else 30 return Type.make(value.getClass()); 31 } 32 33 static public QuoteExp undefined_exp = 34 new QuoteExp (Special.undefined); 35 static public QuoteExp voidExp = 36 new QuoteExp (Values.empty, Type.void_type); 37 static public QuoteExp trueExp = new QuoteExp(Boolean.TRUE); 38 static public QuoteExp falseExp = new QuoteExp(Boolean.FALSE); 39 static public QuoteExp nullExp = 40 new QuoteExp(null, Type.nullType); 41 42 public static QuoteExp getInstance (Object value) 43 { 44 if (value == null) 45 return nullExp; 46 if (value == Special.undefined) 47 return undefined_exp; 48 if (value == Values.empty) 49 return voidExp; 50 if (value instanceof Boolean ) 51 return ((Boolean ) value).booleanValue() ? trueExp : falseExp; 52 return new QuoteExp(value); 53 } 54 55 public QuoteExp (Object val) { value = val; } 56 57 public QuoteExp (Object val, Type type) { value = val; this.type = type; } 58 59 protected boolean mustCompile () { return false; } 60 61 public void apply (CallContext ctx) 62 { 63 ctx.writeValue(value); 64 } 65 66 public void compile (Compilation comp, Target target) 67 { 68 if (type == null || type == Type.pointer_type 69 || target instanceof IgnoreTarget 70 || (type instanceof gnu.bytecode.ObjectType 71 && type.isInstance(value))) 72 comp.compileConstant(value, target); 73 else 74 { 75 comp.compileConstant(value, StackTarget.getInstance(type)); 76 target.compileFromStack(comp, type); 77 } 78 } 79 80 protected Expression walk (ExpWalker walker) 81 { 82 return walker.walkQuoteExp(this); 83 } 84 85 public Expression inline (ApplyExp exp, InlineCalls walker, Declaration decl) 86 { 87 if (this == QuoteExp.undefined_exp) 88 return exp; 89 Object fval = getValue(); 90 if (! (fval instanceof Procedure)) 91 return walker.noteError(decl == null || fval == null ? "called value is not a procedure" 92 : ("calling " + decl.getName() 93 + " which is a "+fval.getClass().getName())); 94 Procedure proc = (Procedure) fval; 95 int nargs = exp.getArgCount(); 96 String msg = WrongArguments.checkArgCount(proc, nargs); 97 if (msg != null) 98 return walker.noteError(msg); 99 if (proc instanceof CanInline) 100 return ((CanInline) proc).inline(exp, walker); 101 if (exp.getFlag(ApplyExp.INLINE_IF_CONSTANT)) 102 { 103 Expression e = exp.inlineIfConstant(proc, walker); 104 if (e != exp) 105 return walker.walk(e); 106 } 107 Compilation comp = walker.getCompilation(); 108 if (comp.inlineOk(proc)) 109 { 110 if (proc instanceof Inlineable) 111 { 112 if (exp.getFunction() == this) 113 return exp; 114 return new ApplyExp(this, exp.getArgs()).setLine(exp); 115 } 116 PrimProcedure mproc 117 = PrimProcedure.getMethodFor(proc, decl, exp.args, 118 comp.getLanguage()); 119 if (mproc != null) 120 { 121 ApplyExp nexp; 122 if (mproc.getStaticFlag() || decl == null) 123 nexp = new ApplyExp(mproc, exp.args); 124 else if (decl.base == null) 125 return exp; 126 else 127 { 128 Expression[] margs = new Expression[1 + nargs]; 129 System.arraycopy(exp.getArgs(), 0, margs, 1, nargs); 130 margs[0] = new ReferenceExp(decl.base); 131 nexp = new ApplyExp(mproc, margs); 132 } 133 return nexp.setLine(exp); 134 } 135 } 136 return exp; 137 } 138 139 public boolean side_effects () { return false; } 140 141 public String toString () 142 { 143 return "QuoteExp["+value+"]"; 144 } 145 146 public void print (OutPort out) 147 { 148 out.startLogicalBlock("(Quote", ")", 2); 149 out.writeSpaceLinear(); 150 if (value instanceof Expression) 151 value = value.toString(); gnu.lists.AbstractFormat saveFormat = out.objectFormat; 153 try 154 { 155 out.objectFormat = Language.getDefaultLanguage().getFormat(true); 156 out.print(value); 157 164 } 165 finally 166 { 167 out.objectFormat = saveFormat; 168 } 169 out.endLogicalBlock(")"); 170 } 171 } 172 | Popular Tags |