NamedException.java 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. package kawa.lang;
  2. import gnu.kawa.functions.DisplayFormat;
  3. import gnu.kawa.io.CharArrayOutPort;
  4. import gnu.lists.LList;
  5. import gnu.mapping.*;
  6. /** Used to implement R7RS "error object" as created by the error procedure.
  7. * Also used to implement catch/throw named handlers as in Guile:
  8. * (catch 'key (lambda () ... (throw 'key ARGS ...) ...)
  9. * (lambda (KEY ARGS ...) HANDLER))
  10. */
  11. public class NamedException extends RuntimeException {
  12. /** Null for objecs created by error; the key for Guile-style throw. */
  13. Symbol name;
  14. /** Arguments to throw or error.
  15. * For Guile-style throw, args include the key - i.e. args[0]== name.
  16. * If created by error, the array contains the symbol 'misc-error,
  17. * followed by the object-message, followed by the object irritants.
  18. */
  19. Object[] args;
  20. static SimpleSymbol miscErrorSymbol = Symbol.valueOf("misc-error");
  21. /** Assume name==args[1], or name==null. */
  22. public NamedException(Symbol name, Object[] args) {
  23. this.name = name;
  24. this.args = args;
  25. }
  26. public static NamedException makeError(Object... args) {
  27. Object[] xargs = new Object[args.length+1];
  28. xargs[0] = miscErrorSymbol;
  29. System.arraycopy(args, 0, xargs, 1, args.length);
  30. return new NamedException(null, xargs);
  31. }
  32. public Object applyHandler(Object key, Procedure handler)
  33. throws Throwable {
  34. if (key != this.name && key != Boolean.TRUE)
  35. throw this;
  36. return handler.applyN(args);
  37. }
  38. public Object getObjectMessage() {
  39. return name == null ? args[1] : name;
  40. }
  41. public LList getObjectIrritants() {
  42. return LList.makeList(args, name==null ? 2 : 1);
  43. }
  44. public String toString() {
  45. CharArrayOutPort buf = new CharArrayOutPort();
  46. buf.append("#<ERROR");
  47. int len = args.length;
  48. // Skip initial 'misc-error as generated by the error procedure.
  49. int i = name == null ? 1 : 0;
  50. DisplayFormat format = DisplayFormat.schemeDisplayFormat;
  51. for ( ; i < len; i++) {
  52. buf.append(' ');
  53. format.format(args[i], buf);
  54. format = DisplayFormat.schemeWriteFormat;
  55. }
  56. buf.append(">");
  57. return buf.toString();
  58. }
  59. }