1 4 package gnu.kawa.functions; 5 import gnu.mapping.*; 6 import gnu.lists.*; 7 import gnu.math.RatNum; 8 import gnu.math.IntNum; 9 import java.io.PrintWriter ; 10 import gnu.text.Char; 11 import gnu.kawa.xml.XmlNamespace; 12 import gnu.text.Printable; 13 14 import java.util.regex.*; 15 16 17 18 19 public class DisplayFormat extends AbstractFormat 20 { 21 22 public static final ThreadLocation outBase 23 = new ThreadLocation("out-base"); 24 static { outBase.setGlobal(IntNum.ten()); } 25 27 public static final ThreadLocation outRadix 28 = new ThreadLocation("out-radix"); 29 30 36 public DisplayFormat(boolean readable, char language) 37 { 38 this.readable = readable; 39 this.language = language; 40 } 41 42 public static DisplayFormat getEmacsLispFormat(boolean readable) 43 { 44 return new DisplayFormat(readable, 'E'); 45 } 46 47 public static DisplayFormat getCommonLispFormat(boolean readable) 48 { 49 return new DisplayFormat(readable, 'C'); 50 } 51 52 public static DisplayFormat getSchemeFormat(boolean readable) 53 { 54 return new DisplayFormat(readable, 'S'); 55 } 56 57 boolean readable; 58 59 61 char language; 62 63 public boolean getReadableOutput () { return readable; } 64 65 public void writeBoolean(boolean v, Consumer out) 66 { 67 write (language == 'S' ? (v ? "#t" : "#f") : (v ? "t" : "nil"), out); 68 } 69 70 public void write (int v, Consumer out) 71 { 72 if (! getReadableOutput ()) 73 Char.print(v, out); 74 else 75 { 76 if (language == 'E' 77 && v > ' ') 78 { 79 out.write('?'); 80 Char.print(v, out); 81 } 82 else 84 write(Char.toScmReadableString(v), out); 85 } 86 } 87 88 public void writeList(LList value, OutPort out) 89 { 90 Object list = value; 91 out.startLogicalBlock("(", false, ")"); 92 while (list instanceof Pair) 93 { 94 if (list != value) 95 out.writeSpaceFill(); 96 Pair pair = (Pair) list; 97 writeObject(pair.car, (Consumer) out); 98 list = pair.cdr; 99 } 100 if (list != LList.Empty) 101 { 102 out.writeSpaceFill(); 103 out.write(". "); 104 writeObject(LList.checkNonList(list), (Consumer) out); 105 } 106 out.endLogicalBlock(")"); 107 } 108 109 public void writeObject(Object obj, Consumer out) 110 { 111 boolean space = false; 112 if (out instanceof OutPort 113 && ! (obj instanceof gnu.kawa.xml.UntypedAtomic) 114 && ! (obj instanceof Values) 115 && (getReadableOutput() 116 || ! (obj instanceof FString 117 || obj instanceof Char 118 || obj instanceof Character ))) 119 { 120 ((OutPort) out).writeWordStart(); 121 space = true; 122 } 123 writeObjectRaw(obj, out); 124 if (space) 125 ((OutPort) out).writeWordEnd(); 126 } 127 128 public void writeObjectRaw(Object obj, Consumer out) 129 { 130 if (obj instanceof Boolean ) 131 writeBoolean(((Boolean )obj).booleanValue(), out); 132 else if (obj instanceof Char) 133 write(((Char) obj).intValue(), out); 134 else if (obj instanceof Character ) 135 write(((Character ) obj).charValue(), out); 136 else if (obj instanceof Symbol) 137 { 138 Symbol sym = (Symbol) obj; 139 if (sym.getNamespace() == XmlNamespace.HTML) 140 { 141 write("html:", out); 142 write(sym.getLocalPart(), out); 143 } 144 else 145 writeObject(obj.toString(), out); 146 } 147 148 149 else if (obj instanceof java.net.URI && getReadableOutput() 150 && out instanceof PrintWriter ) 151 { 152 write("#,(URI ", out); 153 Strings.printQuoted(obj.toString(), (PrintWriter ) out, 1); 154 out.write(')'); 155 } 156 157 158 else if (obj instanceof CharSeq) 159 { 160 CharSeq str = (CharSeq) obj; 161 if (getReadableOutput () && out instanceof PrintWriter ) 162 Strings.printQuoted(str, (PrintWriter ) out, 1); 163 else if (obj instanceof FString) { 165 FString fstr = (FString) obj; 166 out.write(fstr.data, 0, fstr.size()); 167 } 168 else 169 str.consume(0, str.size(), out); 170 } 171 else if (obj instanceof LList && out instanceof OutPort) 172 writeList((LList) obj, (OutPort) out); 173 else if (obj instanceof SimpleVector) 174 { 175 SimpleVector vec = (SimpleVector) obj; 176 String tag = vec.getTag(); 177 String start, end; 178 if (language == 'E') 179 { 180 start = "["; 181 end = "]"; 182 } 183 else 184 { 185 start = tag == null ? "#(" : ("#" + tag + "("); 186 end = ")"; 187 } 188 if (out instanceof OutPort) 189 ((OutPort) out).startLogicalBlock(start, false, end); 190 else 191 write (start, out); 192 int endpos = vec.size() << 1; 193 for (int ipos = 0; ipos < endpos; ipos += 2) 194 { 195 if (ipos > 0 && out instanceof OutPort) 196 ((OutPort) out).writeSpaceFill(); 197 if (! vec.consumeNext(ipos, out)) 198 break; 199 } 200 if (out instanceof OutPort) 201 ((OutPort) out).endLogicalBlock(end); 202 else 203 write (end, out); 204 } 205 else if (obj instanceof Array) 206 { 207 write((Array) obj, 0, 0, out); 208 } 209 else if (obj instanceof Consumable) 210 ((Consumable) obj).consume(out); 211 else if (obj instanceof Printable) 212 ((Printable) obj).print(out); 213 else if (obj instanceof RatNum) 214 { 215 int b = 10; 216 boolean showRadix = false; 217 Object base = outBase.get(null); 218 Object printRadix = outRadix.get(null); 219 if (printRadix != null 220 && (printRadix == Boolean.TRUE 221 || "yes".equals(printRadix.toString()))) 222 showRadix = true; 223 if (base instanceof Number ) 224 b = ((IntNum) base).intValue(); 225 else if (base != null) 226 b = Integer.parseInt(base.toString()); 227 String asString = ((RatNum) obj).toString(b); 228 if (showRadix) 229 { 230 if (b == 16) 231 write("#x", out); 232 else if (b == 8) 233 write("#o", out); 234 else if (b == 2) 235 write("#b", out); 236 else if (b != 10 || ! (obj instanceof IntNum)) 237 write("#"+base+"r", out); 238 } 239 write(asString, out); 240 if (showRadix && b == 10 && obj instanceof IntNum) 241 write(".", out); 242 } 243 else 244 { 245 String asString; 246 if (obj == null) 247 asString = null; 248 else 249 { 250 Class cl = obj.getClass(); 251 if (cl.isArray()) 252 { 253 int len = java.lang.reflect.Array.getLength(obj); 254 if (out instanceof OutPort) 255 ((OutPort) out).startLogicalBlock("[", false, "]"); 256 else 257 write("[", out); 258 for (int i = 0; i < len; i++) 259 { 260 if (i > 0) 261 { 262 write(" ", out); 263 if (out instanceof OutPort) 264 ((OutPort) out).writeBreakFill(); 265 } 266 writeObject(java.lang.reflect.Array.get(obj, i), out); 267 } 268 if (out instanceof OutPort) 269 ((OutPort) out).endLogicalBlock("]"); 270 else 271 write("]", out); 272 return; 273 } 274 asString = obj.toString(); 275 } 276 if (asString == null) 277 write("#!null", out); 278 else if (readable && obj instanceof String ) 279 writeReadableSymbol(asString, out); 280 else 281 write(asString, out); 282 } 283 } 284 285 291 int write(Array array, int index, int level, Consumer out) 292 { 293 int rank = array.rank(); 294 int count = 0; 295 String start = level > 0 ? "(" 296 : rank == 1 ? "#(" 297 : "#" + rank + "a("; 298 if (out instanceof OutPort) 299 ((OutPort) out).startLogicalBlock(start, false, ")"); 300 else 301 write (start, out); 302 if (rank > 0) 303 { 304 int size = array.getSize(level); 305 level++; 306 for (int i = 0; i < size; i++) 307 { 308 if (i > 0) 309 { 310 write(" ", out); 311 if (out instanceof OutPort) 312 ((OutPort) out).writeBreakFill(); 313 } 314 int step; 315 if (level == rank) 316 { 317 writeObject(array.getRowMajor(index), out); 318 step = 1; 319 } 320 else 321 step = write(array, index, level, out); 322 index += step; 323 count += step; 324 } 325 } 326 if (out instanceof OutPort) 327 ((OutPort) out).endLogicalBlock(")"); 328 else 329 write(")", out); 330 return count; 331 } 332 333 334 static Pattern r5rsIdentifierMinusInteriorColons = 335 Pattern.compile("(([a-zA-Z]|[!$%&*/:<=>?^_~])" 336 + "([a-zA-Z]|[!$%&*/<=>?^_~]|[0-9]|([-+.@]))*[:]?)" 337 + "|([-+]|[.][.][.])"); 338 339 340 void writeReadableSymbol (String sym, Consumer out) 341 { 342 343 345 if (! r5rsIdentifierMinusInteriorColons.matcher(sym).matches()) 346 { 347 int len = sym.length(); 348 if (len == 0) 349 { 350 write("||", out); 351 } 352 else 353 { 354 boolean inVerticalBars = false; 355 for (int i = 0; i < len; i++) 356 { 357 char ch = sym.charAt(i); 358 if (ch == '|') 359 { 360 write(inVerticalBars ? "|\\" : "\\", out); 361 inVerticalBars = false; 362 } 363 else if (! inVerticalBars) 364 { 365 out.write('|'); 366 inVerticalBars = true; 367 } 368 out.write(ch); 369 } 370 if (inVerticalBars) 371 out.write('|'); 372 } 373 return; 374 } 375 376 write(sym, out); 377 } 378 } 379 | Popular Tags |