1 21 22 package org.armedbear.lisp; 23 24 public class Symbol extends LispObject 25 { 26 public static final Symbol AND_ALLOW_OTHER_KEYS = PACKAGE_CL.addExternalSymbol("&ALLOW-OTHER-KEYS"); 27 public static final Symbol AND_AUX = PACKAGE_CL.addExternalSymbol("&AUX"); 28 public static final Symbol AND_BODY = PACKAGE_CL.addExternalSymbol("&BODY"); 29 public static final Symbol AND_ENVIRONMENT = PACKAGE_CL.addExternalSymbol("&ENVIRONMENT"); 30 public static final Symbol AND_KEY = PACKAGE_CL.addExternalSymbol("&KEY"); 31 public static final Symbol AND_OPTIONAL = PACKAGE_CL.addExternalSymbol("&OPTIONAL"); 32 public static final Symbol AND_REST = PACKAGE_CL.addExternalSymbol("&REST"); 33 public static final Symbol AND_WHOLE = PACKAGE_CL.addExternalSymbol("&WHOLE"); 34 public static final Symbol APPLY = PACKAGE_CL.addExternalSymbol("APPLY"); 35 public static final Symbol BLOCK = PACKAGE_CL.addExternalSymbol("BLOCK"); 36 public static final Symbol BREAK = PACKAGE_CL.addExternalSymbol("BREAK"); 37 public static final Symbol CDR = PACKAGE_CL.addExternalSymbol("CDR"); 38 public static final Symbol DECLARE = PACKAGE_CL.addExternalSymbol("DECLARE"); 39 public static final Symbol DOCUMENTATION = PACKAGE_CL.addExternalSymbol("DOCUMENTATION"); 40 public static final Symbol EQ = PACKAGE_CL.addExternalSymbol("EQ"); 41 public static final Symbol EQL = PACKAGE_CL.addExternalSymbol("EQL"); 42 public static final Symbol EQUAL = PACKAGE_CL.addExternalSymbol("EQUAL"); 43 public static final Symbol EQUALP = PACKAGE_CL.addExternalSymbol("EQUALP"); 44 public static final Symbol EVAL = PACKAGE_CL.addExternalSymbol("EVAL"); 45 public static final Symbol FLET = PACKAGE_CL.addExternalSymbol("FLET"); 46 public static final Symbol FORMAT = PACKAGE_CL.addExternalSymbol("FORMAT"); 47 public static final Symbol FUNCALL = PACKAGE_CL.addExternalSymbol("FUNCALL"); 48 public static final Symbol GO = PACKAGE_CL.addExternalSymbol("GO"); 49 public static final Symbol LAMBDA = PACKAGE_CL.addExternalSymbol("LAMBDA"); 50 public static final Symbol LET = PACKAGE_CL.addExternalSymbol("LET"); 51 public static final Symbol LOAD = PACKAGE_CL.addExternalSymbol("LOAD"); 52 public static final Symbol OTHERWISE = PACKAGE_CL.addExternalSymbol("OTHERWISE"); 53 public static final Symbol QUOTE = PACKAGE_CL.addExternalSymbol("QUOTE"); 54 public static final Symbol SETF = PACKAGE_CL.addExternalSymbol("SETF"); 55 public static final Symbol SIGNAL = PACKAGE_CL.addExternalSymbol("SIGNAL"); 56 public static final Symbol SPECIAL = PACKAGE_CL.addExternalSymbol("SPECIAL"); 57 58 public static final Symbol AND = PACKAGE_CL.addExternalSymbol("AND"); 60 public static final Symbol ARRAY = PACKAGE_CL.addExternalSymbol("ARRAY"); 61 public static final Symbol ATOM = PACKAGE_CL.addExternalSymbol("ATOM"); 62 public static final Symbol BASE_CHAR = PACKAGE_CL.addExternalSymbol("BASE-CHAR"); 63 public static final Symbol BASE_STRING = PACKAGE_CL.addExternalSymbol("BASE-STRING"); 64 public static final Symbol BIGNUM = PACKAGE_CL.addExternalSymbol("BIGNUM"); 65 public static final Symbol BIT = PACKAGE_CL.addExternalSymbol("BIT"); 66 public static final Symbol BIT_VECTOR = PACKAGE_CL.addExternalSymbol("BIT-VECTOR"); 67 public static final Symbol BOOLEAN = PACKAGE_CL.addExternalSymbol("BOOLEAN"); 68 public static final Symbol BROADCAST_STREAM = PACKAGE_CL.addExternalSymbol("BROADCAST-STREAM"); 69 public static final Symbol BUILT_IN_CLASS = PACKAGE_CL.addExternalSymbol("BUILT-IN-CLASS"); 70 public static final Symbol CELL_ERROR = PACKAGE_CL.addExternalSymbol("CELL-ERROR"); 71 public static final Symbol CHARACTER = PACKAGE_CL.addExternalSymbol("CHARACTER"); 72 public static final Symbol CLASS = PACKAGE_CL.addExternalSymbol("CLASS"); 73 public static final Symbol COMPILED_FUNCTION = PACKAGE_CL.addExternalSymbol("COMPILED-FUNCTION"); 74 public static final Symbol COMPLEX = PACKAGE_CL.addExternalSymbol("COMPLEX"); 75 public static final Symbol CONCATENATED_STREAM = PACKAGE_CL.addExternalSymbol("CONCATENATED-STREAM"); 76 public static final Symbol CONS = PACKAGE_CL.addExternalSymbol("CONS"); 77 public static final Symbol DOUBLE_FLOAT = PACKAGE_CL.addExternalSymbol("DOUBLE-FLOAT"); 78 public static final Symbol ECHO_STREAM = PACKAGE_CL.addExternalSymbol("ECHO-STREAM"); 79 public static final Symbol EXTENDED_CHAR = PACKAGE_CL.addExternalSymbol("EXTENDED-CHAR"); 80 public static final Symbol FILE_STREAM = PACKAGE_CL.addExternalSymbol("FILE-STREAM"); 81 public static final Symbol FIXNUM = PACKAGE_CL.addExternalSymbol("FIXNUM"); 82 public static final Symbol FLOAT = PACKAGE_CL.addExternalSymbol("FLOAT"); 83 public static final Symbol FUNCTION = PACKAGE_CL.addExternalSymbol("FUNCTION"); 84 public static final Symbol GENERIC_FUNCTION = PACKAGE_CL.addExternalSymbol("GENERIC-FUNCTION"); 85 public static final Symbol HASH_TABLE = PACKAGE_CL.addExternalSymbol("HASH-TABLE"); 86 public static final Symbol INTEGER = PACKAGE_CL.addExternalSymbol("INTEGER"); 87 public static final Symbol KEYWORD = PACKAGE_CL.addExternalSymbol("KEYWORD"); 88 public static final Symbol LIST = PACKAGE_CL.addExternalSymbol("LIST"); 89 public static final Symbol LOGICAL_PATHNAME = PACKAGE_CL.addExternalSymbol("LOGICAL-PATHNAME"); 90 public static final Symbol LONG_FLOAT = PACKAGE_CL.addExternalSymbol("LONG-FLOAT"); 91 public static final Symbol MEMBER = PACKAGE_CL.addExternalSymbol("MEMBER"); 92 public static final Symbol METHOD = PACKAGE_CL.addExternalSymbol("METHOD"); 93 public static final Symbol METHOD_COMBINATION = PACKAGE_CL.addExternalSymbol("METHOD-COMBINATION"); 94 public static final Symbol NOT = PACKAGE_CL.addExternalSymbol("NOT"); 95 public static final Symbol NULL = PACKAGE_CL.addExternalSymbol("NULL"); 96 public static final Symbol NUMBER = PACKAGE_CL.addExternalSymbol("NUMBER"); 97 public static final Symbol OR = PACKAGE_CL.addExternalSymbol("OR"); 98 public static final Symbol PACKAGE = PACKAGE_CL.addExternalSymbol("PACKAGE"); 99 public static final Symbol PATHNAME = PACKAGE_CL.addExternalSymbol("PATHNAME"); 100 public static final Symbol RANDOM_STATE = PACKAGE_CL.addExternalSymbol("RANDOM-STATE"); 101 public static final Symbol RATIO = PACKAGE_CL.addExternalSymbol("RATIO"); 102 public static final Symbol RATIONAL = PACKAGE_CL.addExternalSymbol("RATIONAL"); 103 public static final Symbol REAL = PACKAGE_CL.addExternalSymbol("REAL"); 104 public static final Symbol READTABLE = PACKAGE_CL.addExternalSymbol("READTABLE"); 105 public static final Symbol RESTART = PACKAGE_CL.addExternalSymbol("RESTART"); 106 public static final Symbol SEQUENCE = PACKAGE_CL.addExternalSymbol("SEQUENCE"); 107 public static final Symbol SHORT_FLOAT = PACKAGE_CL.addExternalSymbol("SHORT-FLOAT"); 108 public static final Symbol SIGNED_BYTE = PACKAGE_CL.addExternalSymbol("SIGNED-BYTE"); 109 public static final Symbol SIMPLE_ARRAY = PACKAGE_CL.addExternalSymbol("SIMPLE-ARRAY"); 110 public static final Symbol SIMPLE_BASE_STRING = PACKAGE_CL.addExternalSymbol("SIMPLE-BASE-STRING"); 111 public static final Symbol SIMPLE_BIT_VECTOR = PACKAGE_CL.addExternalSymbol("SIMPLE-BIT-VECTOR"); 112 public static final Symbol SIMPLE_STRING = PACKAGE_CL.addExternalSymbol("SIMPLE-STRING"); 113 public static final Symbol SIMPLE_VECTOR = PACKAGE_CL.addExternalSymbol("SIMPLE-VECTOR"); 114 public static final Symbol SINGLE_FLOAT = PACKAGE_CL.addExternalSymbol("SINGLE-FLOAT"); 115 public static final Symbol STANDARD_CHAR = PACKAGE_CL.addExternalSymbol("STANDARD-CHAR"); 116 public static final Symbol STANDARD_CLASS = PACKAGE_CL.addExternalSymbol("STANDARD-CLASS"); 117 public static final Symbol STANDARD_GENERIC_FUNCTION = PACKAGE_CL.addExternalSymbol("STANDARD-GENERIC-FUNCTION"); 118 public static final Symbol STANDARD_METHOD = PACKAGE_CL.addExternalSymbol("STANDARD-METHOD"); 119 public static final Symbol STANDARD_OBJECT = PACKAGE_CL.addExternalSymbol("STANDARD-OBJECT"); 120 public static final Symbol STREAM = PACKAGE_CL.addExternalSymbol("STREAM"); 121 public static final Symbol STRING = PACKAGE_CL.addExternalSymbol("STRING"); 122 public static final Symbol STRING_STREAM = PACKAGE_CL.addExternalSymbol("STRING-STREAM"); 123 public static final Symbol STRUCTURE_CLASS = PACKAGE_CL.addExternalSymbol("STRUCTURE-CLASS"); 124 public static final Symbol STRUCTURE_OBJECT = PACKAGE_CL.addExternalSymbol("STRUCTURE-OBJECT"); 125 public static final Symbol SYMBOL = PACKAGE_CL.addExternalSymbol("SYMBOL"); 126 public static final Symbol SYNONYM_STREAM = PACKAGE_CL.addExternalSymbol("SYNONYM-STREAM"); 127 public static final Symbol TWO_WAY_STREAM = PACKAGE_CL.addExternalSymbol("TWO-WAY-STREAM"); 128 public static final Symbol UNSIGNED_BYTE = PACKAGE_CL.addExternalSymbol("UNSIGNED-BYTE"); 129 public static final Symbol VECTOR = PACKAGE_CL.addExternalSymbol("VECTOR"); 130 131 public static final Symbol CASE_FROB_STREAM = PACKAGE_SYS.addInternalSymbol("CASE-FROB-STREAM"); 132 public static final Symbol NIL_VECTOR = PACKAGE_SYS.addInternalSymbol("NIL-VECTOR"); 133 public static final Symbol SOCKET_STREAM = PACKAGE_SYS.addInternalSymbol("SOCKET-STREAM"); 134 public static final Symbol STRING_INPUT_STREAM = PACKAGE_SYS.addInternalSymbol("STRING-INPUT-STREAM"); 135 public static final Symbol STRING_OUTPUT_STREAM = PACKAGE_SYS.addInternalSymbol("STRING-OUTPUT-STREAM"); 136 137 public static final Symbol UNSPECIFIED = PACKAGE_CL.addExternalSymbol("*"); 138 139 public static final Symbol ARITHMETIC_ERROR = PACKAGE_CL.addExternalSymbol("ARITHMETIC-ERROR"); 141 public static final Symbol CONDITION = PACKAGE_CL.addExternalSymbol("CONDITION"); 142 public static final Symbol CONTROL_ERROR = PACKAGE_CL.addExternalSymbol("CONTROL-ERROR"); 143 public static final Symbol DIVISION_BY_ZERO = PACKAGE_CL.addExternalSymbol("DIVISION-BY-ZERO"); 144 public static final Symbol END_OF_FILE = PACKAGE_CL.addExternalSymbol("END-OF-FILE"); 145 public static final Symbol ERROR = PACKAGE_CL.addExternalSymbol("ERROR"); 146 public static final Symbol FILE_ERROR = PACKAGE_CL.addExternalSymbol("FILE-ERROR"); 147 public static final Symbol FLOATING_POINT_INEXACT = PACKAGE_CL.addExternalSymbol("FLOATING-POINT-INEXACT"); 148 public static final Symbol FLOATING_POINT_INVALID_OPERATION = PACKAGE_CL.addExternalSymbol("FLOATING-POINT-INVALID-OPERATION"); 149 public static final Symbol FLOATING_POINT_OVERFLOW = PACKAGE_CL.addExternalSymbol("FLOATING-POINT-OVERFLOW"); 150 public static final Symbol FLOATING_POINT_UNDERFLOW = PACKAGE_CL.addExternalSymbol("FLOATING-POINT-UNDERFLOW"); 151 public static final Symbol PACKAGE_ERROR = PACKAGE_CL.addExternalSymbol("PACKAGE-ERROR"); 152 public static final Symbol PARSE_ERROR = PACKAGE_CL.addExternalSymbol("PARSE-ERROR"); 153 public static final Symbol PRINT_NOT_READABLE = PACKAGE_CL.addExternalSymbol("PRINT-NOT-READABLE"); 154 public static final Symbol PROGRAM_ERROR = PACKAGE_CL.addExternalSymbol("PROGRAM-ERROR"); 155 public static final Symbol READER_ERROR = PACKAGE_CL.addExternalSymbol("READER-ERROR"); 156 public static final Symbol SERIOUS_CONDITION = PACKAGE_CL.addExternalSymbol("SERIOUS-CONDITION"); 157 public static final Symbol SIMPLE_CONDITION = PACKAGE_CL.addExternalSymbol("SIMPLE-CONDITION"); 158 public static final Symbol SIMPLE_ERROR = PACKAGE_CL.addExternalSymbol("SIMPLE-ERROR"); 159 public static final Symbol SIMPLE_TYPE_ERROR = PACKAGE_CL.addExternalSymbol("SIMPLE-TYPE-ERROR"); 160 public static final Symbol SIMPLE_WARNING = PACKAGE_CL.addExternalSymbol("SIMPLE-WARNING"); 161 public static final Symbol STORAGE_CONDITION = PACKAGE_CL.addExternalSymbol("STORAGE-CONDITION"); 162 public static final Symbol STREAM_ERROR = PACKAGE_CL.addExternalSymbol("STREAM-ERROR"); 163 public static final Symbol STYLE_WARNING = PACKAGE_CL.addExternalSymbol("STYLE-WARNING"); 164 public static final Symbol TYPE_ERROR = PACKAGE_CL.addExternalSymbol("TYPE-ERROR"); 165 public static final Symbol UNBOUND_SLOT = PACKAGE_CL.addExternalSymbol("UNBOUND-SLOT"); 166 public static final Symbol UNBOUND_VARIABLE = PACKAGE_CL.addExternalSymbol("UNBOUND-VARIABLE"); 167 public static final Symbol UNDEFINED_FUNCTION = PACKAGE_CL.addExternalSymbol("UNDEFINED-FUNCTION"); 168 public static final Symbol WARNING = PACKAGE_CL.addExternalSymbol("WARNING"); 169 170 public static final Symbol BACKQUOTE = PACKAGE_CL.addInternalSymbol("BACKQUOTE"); 172 public static final Symbol COMMA = PACKAGE_CL.addInternalSymbol("COMMA"); 173 public static final Symbol COMMA_ATSIGN = PACKAGE_CL.addInternalSymbol("COMMA-ATSIGN"); 174 public static final Symbol COMMA_DOT = PACKAGE_CL.addInternalSymbol("COMMA-DOT"); 175 public static final Symbol MACROEXPAND_MACRO = PACKAGE_SYS.addInternalSymbol("MACROEXPAND-MACRO"); 176 public static final Symbol _SETF_FUNCTION = PACKAGE_SYS.addInternalSymbol("%SETF-FUNCTION"); 177 public static final Symbol _SOURCE = PACKAGE_SYS.addInternalSymbol("%SOURCE"); 178 179 public static final Symbol DOUBLE_FLOAT_POSITIVE_INFINITY = PACKAGE_EXT.addExternalSymbol("DOUBLE-FLOAT-POSITIVE-INFINITY"); 180 public static final Symbol DOUBLE_FLOAT_NEGATIVE_INFINITY = PACKAGE_EXT.addExternalSymbol("DOUBLE-FLOAT-NEGATIVE-INFINITY"); 181 182 private static final int FLAG_SPECIAL = 0x0001; 184 private static final int FLAG_CONSTANT = 0x0002; 185 private static final int FLAG_BUILT_IN_FUNCTION = 0x0004; 186 187 public static final Symbol addFunction(String name, LispObject obj) 188 { 189 Symbol symbol = PACKAGE_CL.intern(name); 190 try { 191 PACKAGE_CL.export(symbol); } 193 catch (ConditionThrowable t) { 194 Debug.trace(t); 195 } 196 symbol.function = obj; 197 return symbol; 198 } 199 200 private final String name; 201 private LispObject pkg; 202 private LispObject value; 203 private LispObject function; 204 private LispObject propertyList; 205 private int flags; 206 207 public Symbol(String name) 209 { 210 this.name = name; 211 pkg = NIL; 212 } 213 214 public Symbol(String name, Package pkg) 215 { 216 this.name = name; 217 this.pkg = pkg; 218 } 219 220 public LispObject typeOf() 221 { 222 if (pkg == PACKAGE_KEYWORD) 223 return Symbol.KEYWORD; 224 else 225 return Symbol.SYMBOL; 226 } 227 228 public LispClass classOf() 229 { 230 return BuiltInClass.SYMBOL; 231 } 232 233 public LispObject getDescription() 234 { 235 StringBuffer sb = new StringBuffer ("The symbol "); 236 sb.append(name); 237 return new SimpleString(sb); 238 } 239 240 public LispObject typep(LispObject type) throws ConditionThrowable 241 { 242 if (type == Symbol.SYMBOL) 243 return T; 244 if (type == BuiltInClass.SYMBOL) 245 return T; 246 if (type == Symbol.KEYWORD) 247 return pkg == PACKAGE_KEYWORD ? T : NIL; 248 if (type == Symbol.BOOLEAN) 249 return this == T ? T : NIL; 250 return super.typep(type); 251 } 252 253 public final LispObject SYMBOLP() 254 { 255 return T; 256 } 257 258 public boolean constantp() 259 { 260 return (flags & FLAG_CONSTANT) != 0; 261 } 262 263 public final LispObject STRING() 264 { 265 return new SimpleString(name); 266 } 267 268 public final LispObject getPackage() 269 { 270 return pkg; 271 } 272 273 public final void setPackage(LispObject obj) 274 { 275 pkg = obj; 276 } 277 278 public final boolean isSpecialVariable() 279 { 280 return (flags & FLAG_SPECIAL) != 0; 281 } 282 283 public final void setSpecial(boolean b) 284 { 285 if (b) 286 flags |= FLAG_SPECIAL; 287 else 288 flags &= ~FLAG_SPECIAL; 289 } 290 291 public final boolean isConstant() 292 { 293 return (flags & FLAG_CONSTANT) != 0; 294 } 295 296 public final void setConstant(boolean b) 297 { 298 if (b) 299 flags |= FLAG_CONSTANT; 300 else 301 flags &= ~FLAG_CONSTANT; 302 } 303 304 public final boolean isBuiltInFunction() 305 { 306 return (flags & FLAG_BUILT_IN_FUNCTION) != 0; 307 } 308 309 public final void setBuiltInFunction(boolean b) 310 { 311 if (b) 312 flags |= FLAG_BUILT_IN_FUNCTION; 313 else 314 flags &= ~FLAG_BUILT_IN_FUNCTION; 315 } 316 317 public final String getName() 318 { 319 return name; 320 } 321 322 public final String getQualifiedName() 323 { 324 if (pkg == NIL) 325 return("#:".concat(name)); 326 if (pkg == PACKAGE_KEYWORD) 327 return ":".concat(name); 328 StringBuffer sb = new StringBuffer (pkg.getName()); 329 if (((Package )pkg).findExternalSymbol(name) != null) 330 sb.append(':'); 331 else 332 sb.append("::"); 333 sb.append(name); 334 return sb.toString(); 335 } 336 337 public LispObject getSymbolValue() 339 { 340 return value; 341 } 342 343 public final void setSymbolValue(LispObject value) 344 { 345 this.value = value; 346 } 347 348 public final LispObject symbolValue() throws ConditionThrowable 349 { 350 LispObject val = LispThread.currentThread().lookupSpecial(this); 351 if (val != null) 352 return val; 353 if (value != null) 354 return value; 355 return signal(new UnboundVariable(this)); 356 } 357 358 public final LispObject symbolValue(LispThread thread) throws ConditionThrowable 359 { 360 LispObject val = thread.lookupSpecial(this); 361 if (val != null) 362 return val; 363 if (value != null) 364 return value; 365 return signal(new UnboundVariable(this)); 366 } 367 368 public final LispObject symbolValueNoThrow() 369 { 370 if ((flags & FLAG_SPECIAL) != 0) { 371 LispObject val = LispThread.currentThread().lookupSpecial(this); 372 if (val != null) 373 return val; 374 } 375 return value; 376 } 377 378 public final LispObject symbolValueNoThrow(LispThread thread) 379 { 380 if ((flags & FLAG_SPECIAL) != 0) { 381 LispObject val = thread.lookupSpecial(this); 382 if (val != null) 383 return val; 384 } 385 return value; 386 } 387 388 public LispObject getSymbolFunction() 389 { 390 return function; 391 } 392 393 public final LispObject getSymbolFunctionOrDie() throws ConditionThrowable 394 { 395 if (function == null) 396 return signal(new UndefinedFunction(this)); 397 if (function instanceof Autoload) { 398 Autoload autoload = (Autoload) function; 399 autoload.load(); 400 } 401 return function; 402 } 403 404 public final LispObject getSymbolSetfFunctionOrDie() throws ConditionThrowable 405 { 406 LispObject obj = get(this, Symbol._SETF_FUNCTION); 407 if (obj == null) 408 return signal(new LispError("The function (SETF " + name + 409 ") is undefined.")); 410 return obj; 411 } 412 413 public final void setSymbolFunction(LispObject obj) 414 { 415 this.function = obj; 416 } 417 418 public final LispObject getPropertyList() 419 { 420 return propertyList != null ? propertyList : NIL; 421 } 422 423 public final void setPropertyList(LispObject obj) 424 { 425 if (obj == null) 426 throw new NullPointerException (); 427 propertyList = obj; 428 } 429 430 private static final Symbol _FUNCTION_DOCUMENTATION = 431 PACKAGE_SYS.intern("%FUNCTION-DOCUMENTATION"); 432 433 private static final Symbol _VARIABLE_DOCUMENTATION = 434 PACKAGE_SYS.intern("%VARIABLE-DOCUMENTATION"); 435 436 public final LispObject getFunctionDocumentation() throws ConditionThrowable 438 { 439 return get(this, _FUNCTION_DOCUMENTATION); 440 } 441 442 public final void setFunctionDocumentation(String docstring) 443 throws ConditionThrowable 444 { 445 put(this, _FUNCTION_DOCUMENTATION, new SimpleString(docstring)); 446 } 447 448 public final void setFunctionDocumentation(LispObject documentation) 449 throws ConditionThrowable 450 { 451 put(this, _FUNCTION_DOCUMENTATION, documentation); 452 } 453 454 public final void setVariableDocumentation(LispObject documentation) 455 throws ConditionThrowable 456 { 457 put(this, _VARIABLE_DOCUMENTATION, documentation); 458 } 459 460 public String writeToString() throws ConditionThrowable 461 { 462 final LispThread thread = LispThread.currentThread(); 463 boolean printEscape = (_PRINT_ESCAPE_.symbolValue(thread) != NIL); 464 LispObject printCase = _PRINT_CASE_.symbolValue(thread); 465 LispObject readtableCase = currentReadtable().getReadtableCase(); 466 boolean printReadably = (_PRINT_READABLY_.symbolValue(thread) != NIL); 467 if (printReadably) { 468 if (readtableCase != Keyword.UPCASE || 469 printCase != Keyword.UPCASE) 470 { 471 StringBuffer sb = new StringBuffer (); 472 if (pkg == PACKAGE_KEYWORD) { 473 sb.append(':'); 474 } else if (pkg != NIL) { 475 sb.append(multipleEscape(pkg.getName())); 476 sb.append("::"); 477 } else { 478 sb.append("#:"); 479 } 480 sb.append(multipleEscape(name)); 481 return sb.toString(); 482 } else 483 printEscape = true; 484 } 485 if (!printEscape) { 486 if (pkg == PACKAGE_KEYWORD) { 487 if (printCase == Keyword.DOWNCASE) 488 return name.toLowerCase(); 489 if (printCase == Keyword.CAPITALIZE) 490 return capitalize(name, readtableCase); 491 return name; 492 } 493 if (readtableCase == Keyword.UPCASE) { 495 if (printCase == Keyword.DOWNCASE) 496 return name.toLowerCase(); 497 if (printCase == Keyword.CAPITALIZE) 498 return capitalize(name, readtableCase); 499 return name; 500 } else if (readtableCase == Keyword.DOWNCASE) { 501 if (printCase == Keyword.DOWNCASE) 505 return name; 506 if (printCase == Keyword.UPCASE) 507 return name.toUpperCase(); 508 if (printCase == Keyword.CAPITALIZE) 509 return capitalize(name, readtableCase); 510 return name; 511 } else if (readtableCase == Keyword.PRESERVE) { 512 return name; 513 } else return invert(name); 515 } 516 final boolean escape = needsEscape(name, readtableCase, thread); 518 String s = escape ? multipleEscape(name) : name; 519 if (!escape) { 520 if (readtableCase == Keyword.PRESERVE) 521 ; 522 else if (readtableCase == Keyword.INVERT) 523 s = invert(s); 524 else if (printCase == Keyword.DOWNCASE) 525 s = s.toLowerCase(); 526 else if (printCase == Keyword.UPCASE) 527 s = s.toUpperCase(); 528 else if (printCase == Keyword.CAPITALIZE) 529 s = capitalize(s, readtableCase); 530 } 531 if (pkg == NIL) { 532 if (printReadably || _PRINT_GENSYM_.symbolValue(thread) != NIL) 533 return "#:".concat(s); 534 else 535 return s; 536 } 537 if (pkg == PACKAGE_KEYWORD) 538 return ":".concat(s); 539 final Package currentPackage = (Package ) _PACKAGE_.symbolValue(thread); 541 if (pkg == currentPackage) 542 return s; 543 if (currentPackage != null && currentPackage.uses(pkg)) { 544 if (currentPackage.findExternalSymbol(name) == null) 546 if (currentPackage.findInternalSymbol(name) == null) 547 if (((Package )pkg).findExternalSymbol(name) != null) 548 return s; 549 } 550 if (currentPackage.findExternalSymbol(name) == this) 552 return s; 553 if (currentPackage.findInternalSymbol(name) == this) 554 return s; 555 String packageName = pkg.getName(); 557 if (needsEscape(packageName, readtableCase, thread)) 558 packageName = multipleEscape(packageName); 559 else if (printCase == Keyword.DOWNCASE) 560 packageName = packageName.toLowerCase(); 561 StringBuffer sb = new StringBuffer (packageName); 562 if (((Package )pkg).findExternalSymbol(name) != null) 563 sb.append(':'); 564 else 565 sb.append("::"); 566 sb.append(s); 567 return sb.toString(); 568 } 569 570 private static final boolean needsEscape(String s, 571 LispObject readtableCase, 572 LispThread thread) 573 throws ConditionThrowable 574 { 575 boolean escape = false; 576 final int length = s.length(); 577 if (length == 0) 578 return true; 579 if (s.charAt(0) == '#') 580 return true; 581 int radix; 582 try { 583 radix = ((Fixnum)_PRINT_BASE_.symbolValue(thread)).value; 584 } 585 catch (ClassCastException e) { 586 signal(new TypeError("The value of *PRINT-BASE* is not of type (INTEGER 2 36).")); 587 return false; 589 } 590 if (radix < 2 || radix > 36) { 591 signal(new TypeError("The value of *PRINT-BASE* is not of type (INTEGER 2 36).")); 592 return false; 594 } 595 boolean seenNonDigit = false; 596 for (int i = length; i-- > 0;) { 597 char c = s.charAt(i); 598 if ("(),|\\`'\";:".indexOf(c) >= 0) 599 return true; 600 if (Character.isWhitespace(c)) 601 return true; 602 if (readtableCase == Keyword.UPCASE) { 603 if (Character.isLowerCase(c)) 604 return true; 605 } else if (readtableCase == Keyword.DOWNCASE) { 606 if (Character.isUpperCase(c)) 607 return true; 608 } 609 if (!escape && !seenNonDigit) { 610 if (Character.digit(c, radix) < 0) 611 seenNonDigit = true; 612 } 613 } 614 if (!seenNonDigit) 615 return true; 616 if (s.length() > 0 && s.charAt(0) == '.') { 617 boolean allDots = true; 618 for (int i = s.length(); i-- > 1;) { 619 if (s.charAt(i) != '.') { 620 allDots = false; 621 break; 622 } 623 } 624 if (allDots) 625 return true; 626 } 627 return false; 628 } 629 630 private static final String multipleEscape(String s) 631 { 632 StringBuffer sb = new StringBuffer ("|"); 633 final int limit = s.length(); 634 for (int i = 0; i < limit; i++) { 635 char c = s.charAt(i); 636 if (c == '|' || c == '\\') 637 sb.append('\\'); 638 sb.append(c); 639 } 640 sb.append('|'); 641 return sb.toString(); 642 } 643 644 private static final String capitalize(String s, LispObject readtableCase) 645 { 646 if (readtableCase == Keyword.INVERT || readtableCase == Keyword.PRESERVE) 647 return s; 648 final int limit = s.length(); 649 StringBuffer sb = new StringBuffer (limit); 650 boolean lastCharWasAlphanumeric = false; 651 for (int i = 0; i < limit; i++) { 652 char c = s.charAt(i); 653 if (Character.isLowerCase(c)) { 654 if (readtableCase == Keyword.UPCASE) 655 sb.append(c); 656 else sb.append(lastCharWasAlphanumeric ? c : Utilities.toUpperCase(c)); 658 lastCharWasAlphanumeric = true; 659 } else if (Character.isUpperCase(c)) { 660 if (readtableCase == Keyword.UPCASE) 661 sb.append(lastCharWasAlphanumeric ? Utilities.toLowerCase(c) : c); 662 else sb.append(c); 664 lastCharWasAlphanumeric = true; 665 } else { 666 sb.append(c); 667 lastCharWasAlphanumeric = Character.isDigit(c); 668 } 669 } 670 return sb.toString(); 671 } 672 673 public LispObject getParts() throws ConditionThrowable 674 { 675 LispObject result = NIL; 676 result = result.push(new Cons(new SimpleString("name"), new SimpleString(name))); 677 result = result.push(new Cons(new SimpleString("package"), pkg)); 678 result = result.push(new Cons(new SimpleString("value"), 679 value != null ? value : UNBOUND)); 680 result = result.push(new Cons(new SimpleString("function"), 681 function != null ? function : UNBOUND)); 682 result = result.push(new Cons(new SimpleString("plist"), getPropertyList())); 683 return result.nreverse(); 684 } 685 686 public final int hashCode() 687 { 688 return name.hashCode(); 689 } 690 691 public final boolean equals(Object obj) 692 { 693 return this == obj; 694 } 695 696 public static final Primitive1 SYMBOL_NAME = new Primitive1("symbol-name","symbol") 698 { 699 public LispObject execute(LispObject arg) throws ConditionThrowable 700 { 701 try { 702 return new SimpleString(((Symbol)arg).name); 703 } 704 catch (ClassCastException e) { 705 return signal(new TypeError(arg, Symbol.SYMBOL)); 706 } 707 } 708 }; 709 710 public static final Primitive1 SYMBOL_PACKAGE = new Primitive1("symbol-package","symbol") 712 { 713 public LispObject execute(LispObject arg) throws ConditionThrowable 714 { 715 try { 716 return ((Symbol)arg).pkg; 717 } 718 catch (ClassCastException e) { 719 return signal(new TypeError(arg, Symbol.SYMBOL)); 720 } 721 } 722 }; 723 724 public static final Primitive1 SYMBOL_FUNCTION = 726 new Primitive1("symbol-function", "symbol") 727 { 728 public LispObject execute(LispObject arg) throws ConditionThrowable 729 { 730 try { 731 LispObject function = ((Symbol)arg).function; 732 if (function != null) 733 return function; 734 return signal(new UndefinedFunction(arg)); 735 } 736 catch (ClassCastException e) { 737 return signal(new TypeError(arg, Symbol.SYMBOL)); 738 } 739 } 740 }; 741 742 public static final Primitive1 SYMBOL_PLIST = new Primitive1("symbol-plist", "symbol") 744 { 745 public LispObject execute(LispObject arg) throws ConditionThrowable 746 { 747 try { 748 LispObject propertyList = ((Symbol)arg).propertyList; 749 return propertyList != null ? propertyList : NIL; 750 } 751 catch (ClassCastException e) { 752 return signal(new TypeError(arg, Symbol.SYMBOL)); 753 } 754 } 755 }; 756 757 public static final Primitive1 KEYWORDP = new Primitive1("keywordp", "object") 759 { 760 public LispObject execute(LispObject arg) throws ConditionThrowable 761 { 762 if (arg instanceof Symbol) { 763 if (((Symbol)arg).pkg == PACKAGE_KEYWORD) 764 return T; 765 } 766 return NIL; 767 } 768 }; 769 770 public static final Primitive1 MAKE_SYMBOL = new Primitive1("make-symbol", "name") 772 { 773 public LispObject execute(LispObject arg) throws ConditionThrowable 774 { 775 return new Symbol(arg.getStringValue()); 776 } 777 }; 778 779 public static final Primitive1 MAKUNBOUND = new Primitive1("makunbound", "symbol") 781 { 782 public LispObject execute(LispObject arg) throws ConditionThrowable 783 { 784 try { 785 ((Symbol)arg).value = null; 786 return arg; 787 } 788 catch (ClassCastException e) { 789 return signal(new TypeError(arg, "symbol")); 790 } 791 } 792 }; 793 } 794 | Popular Tags |