📄 lispformat.java
字号:
this.length = stack.size(); this.formats = new Format[this.length]; stack.copyInto(this.formats); } static Format[] getFormats(java.util.Vector vector, int start, int end) { Format[] f = new Format[end - start]; for (int i = start; i < end; i++) f[i - start] = (Format) vector.elementAt(i); return f; } static Format popFormats(java.util.Vector vector, int start, int end) { Format f; if (end == start + 1) f = (Format) vector.elementAt(start); else f = new CompoundFormat(getFormats(vector, start, end)); vector.setSize(start); return f; } public LispFormat (String str) throws ParseException { this(str.toCharArray()); } /* private void clearSpecs (int speci, int max) { int num = specs_length - speci - 1; for (int i = num; i < max; i++) addSpec(PARAM_UNSPECIFIED); specs_length = speci + 1; } */ /* private void addSpec(Format fmt) { if (formats == null) formats = new Format[4]; else { if (this.length == formats.length) { Format[] newformats = new Format[2 * this.length]; System.arraycopy(formats, 0, newformats, 0, this.length); formats = newformats; } } formats[this.length] = fmt; addSpec(this.length); this.length++; } */ /* private void addSpec(int val) { //System.err.println("addSpec("+val+") at:"+specs_length); int old_size = specs.length; if (specs_length >= old_size) { int[] new_specs = new int[2 * old_size]; System.arraycopy(specs, 0, new_specs, 0, old_size); specs = new_specs; } specs[specs_length++] = val; } */ public LispFormat(char[] format) throws ParseException { this(format, 0, format.length); } public static int getParam(java.util.Vector vec, int index) { if (index >= vec.size()) return PARAM_UNSPECIFIED; Object arg = vec.elementAt(index); if (arg == paramFromList) return PARAM_FROM_LIST; if (arg == paramFromCount) return PARAM_FROM_COUNT; if (arg == paramUnspecified) return PARAM_UNSPECIFIED; return getParam(arg, PARAM_UNSPECIFIED); } /** Convert sequence (or Object[]) to Object[]. * Return null if not a valid Sequence. */ public static Object[] asArray (Object arg) { if (arg instanceof Object[]) return (Object[]) arg; if (!(arg instanceof Sequence)) return null; int count = ((Sequence) arg).size(); Object[] arr = new Object[count]; int i = 0; while (arg instanceof Pair) { Pair pair = (Pair) arg; arr[i++] = pair.car; arg = pair.cdr; } if (i < count) { if (! (arg instanceof Sequence)) return null; int npairs = i; Sequence seq = (Sequence) arg; for (; i < count; i++) arr[i] = seq.get(npairs + i); } return arr; }}/** Add plural suffixes ("s" or "y/ies") of English words. * Used to implement the Common Lisp ~P ('Plural') format operator. */class LispPluralFormat extends ReportFormat{ boolean backup; boolean y; public static LispPluralFormat getInstance (boolean backup, boolean y) { LispPluralFormat fmt = new LispPluralFormat(); fmt.backup = backup; fmt.y = y; return fmt; } public int format(Object[] args, int start, Writer dst, FieldPosition fpos) throws java.io.IOException { if (backup) start--; Object arg = args[start++]; boolean plural = arg != IntNum.one(); if (y) print(dst, plural ? "ies" : "y"); else if (plural) dst.write('s'); return start; }}/** Handle formatting of characters. * Used to implement the Common List ~C (Character) and ~~ (Tilde) * format operators. */class LispCharacterFormat extends ReportFormat{ boolean seenAt; boolean seenColon; int count; int charVal; public static LispCharacterFormat getInstance(int charVal, int count, boolean seenAt, boolean seenColon) { LispCharacterFormat fmt = new LispCharacterFormat(); fmt.count = count; fmt.charVal = charVal; fmt.seenAt = seenAt; fmt.seenColon = seenColon; return fmt; } public int format(Object[] args, int start, Writer dst, FieldPosition fpos) throws java.io.IOException { int count = getParam(this.count, 1, args, start); if (this.count == LispFormat.PARAM_FROM_LIST) start++; int charVal = getParam(this.charVal, '?', args, start); if (this.charVal == LispFormat.PARAM_FROM_LIST) start++; while (--count >= 0) printChar (charVal, seenAt, seenColon, dst); return start; } public static void printChar(int ch, boolean seenAt, boolean seenColon, Writer dst) throws java.io.IOException { if (seenAt) { print(dst, Char.toScmReadableString(ch)); } else if (seenColon) { if (ch < ' ') { dst.write('^'); dst.write(ch + 0x40); } else if (ch >= 0x7f) { print(dst, "#\\"); print(dst, Integer.toString(ch, 8)); } else dst.write(ch); } else { // if (ch > 0xFFFF) print surrogate chars; else dst.write(ch); } }}/** Handle formatting of newline ~% and ~_ format operator. */class LispNewlineFormat extends ReportFormat{ static final String line_separator = System.getProperty("line.separator", "\n"); /** One of NEWLINE_LITERAL, NEWLINE_LINEAR, NEWLINE_FILL, NEWLINE_MISER * or NEWLINE_MANDATORY. These are defined in gnu.text.PrettyWriter. */ int kind; int count; public static LispNewlineFormat getInstance(int count, int kind) { LispNewlineFormat fmt = new LispNewlineFormat(); fmt.count = count; fmt.kind = kind; return fmt; } public int format(Object[] args, int start, Writer dst, FieldPosition fpos) throws java.io.IOException { int count = getParam(this.count, 1, args, start); if (this.count == LispFormat.PARAM_FROM_LIST) start++; while (--count >= 0) printNewline (kind, dst); return start; } public static void printNewline(int kind, Writer dst) throws java.io.IOException { if (dst instanceof OutPort && kind != PrettyWriter.NEWLINE_LITERAL) ((OutPort) dst).writeBreak(kind); else if (dst instanceof java.io.PrintWriter) // May make a difference if autoflush. // FIXME flush if OutPort? ((java.io.PrintWriter) dst).println(); else dst.write(line_separator); }}/** Handle formatting of ~I (indent) format operator. */class LispIndentFormat extends ReportFormat{ boolean current; int columns; public static LispIndentFormat getInstance(int columns, boolean current) { LispIndentFormat fmt = new LispIndentFormat(); fmt.columns = columns; fmt.current = current; return fmt; } public int format(Object[] args, int start, Writer dst, FieldPosition fpos) throws java.io.IOException { int columns = getParam(this.columns, 0, args, start); if (this.columns == LispFormat.PARAM_FROM_LIST) start++; if (dst instanceof OutPort) ((OutPort) dst).setIndentation(columns, current); return start; }}/** Perform general padding. * Used to implement the Common Lisp ~A (Ascii) and ~ (S-expression), * format operators, unless they have no parameters. */class LispObjectFormat extends ReportFormat{ int minWidth; int colInc; int minPad; int padChar; int where; ReportFormat base; public LispObjectFormat(ReportFormat base, int minWidth, int colInc, int minPad, int padChar, int where) { this.base = base; this.minWidth = minWidth; this.colInc = colInc; this.minPad = minPad; this.padChar = padChar; this.where = where; } public int format(Object[] args, int start, Writer dst, FieldPosition fpos) throws java.io.IOException { int minWidth = getParam(this.minWidth, 0, args, start); if (this.minWidth == LispFormat.PARAM_FROM_LIST) start++; int colInc = getParam(this.colInc, 1, args, start); if (this.colInc == LispFormat.PARAM_FROM_LIST) start++; int minPad = getParam(this.minPad, 0, args, start); if (this.minPad == LispFormat.PARAM_FROM_LIST) start++; char padChar = getParam(this.padChar, ' ', args, start); if (this.padChar == LispFormat.PARAM_FROM_LIST) start++; return gnu.text.PadFormat.format(base, args, start, dst, padChar, minWidth, colInc, minPad, where, fpos); }}class LispEscapeFormat extends ReportFormat { int param1; int param2; int param3; boolean escapeAll; public final static LispEscapeFormat alwaysTerminate = new LispEscapeFormat(0, LispFormat.PARAM_UNSPECIFIED); public LispEscapeFormat(int param1, int param2) { this.param1 = param1; this.param2 = param2; this.param3 = LispFormat.PARAM_UNSPECIFIED; } public LispEscapeFormat(int param1, int param2, int param3) { this.param1 = param1; this.param2 = param2; this.param3 = param3; } static Numeric getParam(int param, Object[] args, int start) { if (param == LispFormat.PARAM_FROM_COUNT) return IntNum.make(args.length - start); if (param == LispFormat.PARAM_FROM_LIST) { Object arg = args[start]; if (arg instanceof Numeric) return (Numeric) arg; if (arg instanceof Number) { if (arg instanceof Float || arg instanceof Double) return new DFloNum(((Number) arg).doubleValue()); return IntNum.make(((Number) arg).longValue()); } if (arg instanceof Char) return new IntNum(((Char) arg).intValue()); if (arg instanceof Character) return new IntNum((int) ((Character) arg).charValue()); return new DFloNum(Double.NaN); } return IntNum.make(param); } /** WRONG: Tests if we should exit the the surrounding format. * Returns 2*ARGS_USED+(DO_TERMINATE?1:0), where ARGS_USED is the * number of arguments consumed by the specification, and * DO_TERMINATE is true if we actually should exit. */ public int format(Object[] args, int start, Writer dst, FieldPosition fpos) throws java.io.IOException { int orig_start = start; boolean do_terminate; if (param1 == LispFormat.PARAM_UNSPECIFIED) do_terminate = start == args.length; else if (param2 == LispFormat.PARAM_UNSPECIFIED && param1 == 0) do_terminate = true; // Efficiency hack else { Numeric arg1 = getParam(param1, args, start); if (param1 == LispFormat.PARAM_FROM_LIST) start++; if (param2 == LispFormat.PARAM_UNSPECIFIED) { do_terminate = arg1.isZero(); } else { Numeric arg2 = getParam(param2, args, start); if (param2 == LispFormat.PARAM_FROM_LIST) start++; if (param3 == LispFormat.PARAM_UNSPECIFIED) { do_terminate = arg1.equals(arg2); } else { Numeric arg3 = getParam(param3, args, start); if (param3 == LispFormat.PARAM_FROM_LIST) start++; do_terminate = arg2.geq(arg1) && arg3.geq(arg2); } } } return result(! do_terminate ? 0 : escapeAll ? ESCAPE_ALL : ESCAPE_NORMAL, start); } public final static int ESCAPE_NORMAL = 0xF1; public final static int ESCAPE_ALL = 0xF2;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -