⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 lispformat.java

📁 A framework written in Java for implementing high-level and dynamic languages, compiling them into J
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
package gnu.kawa.functions;import gnu.text.*;import gnu.lists.*;import java.text.Format;import java.text.FieldPosition;import java.text.ParseException;import java.io.Writer;import gnu.math.*;import gnu.mapping.OutPort;/** A representation of a parsed Common Lisp-style format. */public class LispFormat extends CompoundFormat{  public static final String paramFromList = "<from list>";  public static final String paramFromCount = "<from count>";  public static final String paramUnspecified = "<unspecified>";  public LispFormat(char[] format, int offset, int length)    throws ParseException  {    super(null, 0);    // The index in spec of the most recent ~{, ~(, ~{ or ~[.    int start_nesting = -1;    int choices_seen = 0;  // Number of "~;" seen.    StringBuffer litbuf = new StringBuffer(100);    java.util.Stack stack = new java.util.Stack();    int limit = offset + length;    int i = offset;    for (;;)      {	if ((i >= limit || format[i] == '~') && litbuf.length() > 0)	  {	    stack.push(new LiteralFormat(litbuf));	    litbuf.setLength(0);	  }	if (i >= limit)	  break;	char ch = format[i++];	if (ch != '~')	  {	    litbuf.append(ch);	    continue;	  }	int speci = stack.size();	ch = format[i++];	for (;;)	  {	    if (ch == '#')	      {		stack.push(paramFromCount);		ch = format[i++];	      }	    else if (ch == 'v' || ch == 'V')	      {		stack.push(paramFromList);		ch = format[i++];	      }	    else if (ch == '-' || Character.digit(ch, 10) >= 0)	      {		boolean neg = (ch == '-');		if (neg)		  ch = format[i++];		int val = 0;		int start = i;		for (;;)		  {		    int dig = Character.digit(ch, 10);		    if (dig < 0)		      break;		    val = 10 * val + dig;		    ch = format[i++];		  }		stack.push(i - start < 8 ? IntNum.make(neg ? - val : val)			   : IntNum.valueOf(format, start, i-start, 10, neg));	      }	    else if (ch == '\'')	      {		stack.push(Char.make(format[i++]));		ch = format[i++];	      }	    else if (ch == ',')	      {		stack.push(paramUnspecified);	      }	    else	      break;	    if (ch != ',')	      break;	    ch = format[i++];	  }	boolean seenColon = false;	boolean seenAt = false;	for (;;)	  {	    if (ch == ':')	      seenColon = true;	    else if (ch == '@')	      seenAt = true;	    else	      break;	    ch = format[i++];	  }	ch = Character.toUpperCase(ch);	int numParams = stack.size() - speci;	Format fmt;	int minWidth, padChar, charVal, param1, param2, param3, count;	switch (ch)	  {	  case 'R':  case 'D':  case 'O':  case 'B':  case 'X':	    int argstart = speci;	    int base;	    if (ch == 'R')  base = getParam(stack, argstart++);	    else if (ch == 'D')  base = 10;	    else if (ch == 'O')  base = 8;	    else if (ch == 'X')  base = 16; 	    else base = 2;	    minWidth = getParam(stack, argstart);	    padChar = getParam(stack, argstart+1);	    int commaChar = getParam(stack, argstart+2);	    int commaInterval = getParam(stack, argstart+3);            int flags = 0;            if (seenColon)              flags |= IntegerFormat.SHOW_GROUPS;            if (seenAt)              flags |= IntegerFormat.SHOW_PLUS;	    fmt = IntegerFormat.getInstance(base, minWidth, padChar,                                            commaChar, commaInterval, flags);	    break;	  case 'P':	    fmt = LispPluralFormat.getInstance(seenColon, seenAt);	    break;	  case 'E':	  case 'F':	  case 'G':	  case '$':	    LispRealFormat dfmt = new LispRealFormat();	    dfmt.op = ch;	    dfmt.arg1 = getParam(stack, speci);	    dfmt.arg2 = getParam(stack, speci+1);	    dfmt.arg3 = getParam(stack, speci+2);	    dfmt.arg4 = getParam(stack, speci+3);	    if (ch != '$')	      {		dfmt.arg5 = getParam(stack, speci+4);		if (ch == 'E' || ch == 'G')		  {		    dfmt.arg6 = getParam(stack, speci+5);		    dfmt.arg7 = getParam(stack, speci+6);		  }	      }	    dfmt.showPlus = seenAt;	    dfmt.internalPad = seenColon;	    if (dfmt.argsUsed == 0)	      fmt = dfmt.resolve(null, 0);	    else	      fmt = dfmt;	    break;	  case 'A':  case 'S':  case 'W':	  case 'Y':  // SRFI-48 "yuppify" (pretty-print)	    // We don't distinguish between ~S and ~W.  FIXME.	    fmt = ObjectFormat.getInstance(ch != 'A');	    if (numParams > 0)	      {		minWidth = getParam(stack, speci);		int colInc = getParam(stack, speci+1);		int minPad = getParam(stack, speci+2);		padChar = getParam(stack, speci+3);		fmt = new LispObjectFormat((ReportFormat) fmt,					   minWidth, colInc, minPad,					   padChar, seenAt ? 0 : 100);	      }	    break;	  case 'C':	    charVal = numParams > 0 ? getParam(stack, speci)	      : PARAM_FROM_LIST;	    fmt = LispCharacterFormat.getInstance(charVal, 1,						  seenAt, seenColon);	    break;	  case '*':	    fmt = new LispRepositionFormat(getParam(stack, speci),					   seenColon, seenAt);	    break;	  case '(':	    ch = seenColon ? (seenAt ? 'U' : 'C') : (seenAt ? 'T': 'L');	    CaseConvertFormat cfmt = new CaseConvertFormat(null, ch);	    stack.setSize(speci);	    stack.push(cfmt);	    stack.push(IntNum.make(start_nesting));	    start_nesting = speci;	    continue;	  case ')':	    if (start_nesting < 0		|| ! (stack.elementAt(start_nesting)		      instanceof CaseConvertFormat))	      throw new ParseException("saw ~) without matching ~(", i);	    cfmt = (CaseConvertFormat) stack.elementAt(start_nesting);	    cfmt.setBaseFormat(popFormats(stack, start_nesting + 2, speci));	    start_nesting = ((IntNum) stack.pop()).intValue();	    continue;	  case '?':	    LispIterationFormat lfmt = new LispIterationFormat();	    lfmt.seenAt = seenAt;	    lfmt.maxIterations = 1;	    lfmt.atLeastOnce = true;	    fmt = lfmt;	    break;	  case '{':	    lfmt = new LispIterationFormat();	    lfmt.seenAt = seenAt;	    lfmt.seenColon = seenColon;	    lfmt.maxIterations = getParam(stack, speci);	    stack.setSize(speci);	    stack.push(lfmt);	    stack.push(IntNum.make(start_nesting));	    start_nesting = speci;	    continue;	  case '}':	    if (start_nesting < 0		|| ! (stack.elementAt(start_nesting)		      instanceof LispIterationFormat))	      throw new ParseException("saw ~} without matching ~{", i);	    lfmt = (LispIterationFormat) stack.elementAt(start_nesting);	    lfmt.atLeastOnce = seenColon;	    if (speci > start_nesting + 2)	      lfmt.body = popFormats(stack, start_nesting + 2, speci);	    start_nesting = ((IntNum) stack.pop()).intValue();	    continue;	  case '<':	    LispPrettyFormat pfmt = new LispPrettyFormat();	    pfmt.seenAt = seenAt;	    if (seenColon)	      {		pfmt.prefix = "(";		pfmt.suffix = ")";	      }	    else	      {		pfmt.prefix = "";		pfmt.suffix = "";	      }	    stack.setSize(speci);	    stack.push(pfmt);	    stack.push(IntNum.make(start_nesting));	    stack.push(IntNum.make(choices_seen));	    start_nesting = speci;	    choices_seen = 0;	    continue;	  case '>':	    if (start_nesting < 0		|| ! (stack.elementAt(start_nesting)		      instanceof LispPrettyFormat))	      throw new ParseException("saw ~> without matching ~<", i);	    fmt = popFormats(stack, start_nesting + 3 + choices_seen, speci);	    stack.push(fmt);	    pfmt = (LispPrettyFormat) stack.elementAt(start_nesting);	    pfmt.segments = getFormats(stack, start_nesting + 3, stack.size());	    stack.setSize(start_nesting + 3);	    start_nesting = ((IntNum) stack.pop()).intValue();	    start_nesting = ((IntNum) stack.pop()).intValue();	    if (seenColon)	      { // Logical Block for pretty-printing		int nsegments = pfmt.segments.length;		if (nsegments > 3)		  throw new ParseException("too many segments in Logical Block format", i);		if (nsegments >= 2)		  {		    if (! (pfmt.segments[0] instanceof LiteralFormat))		      throw new ParseException("prefix segment is not literal", i);		    pfmt.prefix = ((LiteralFormat) pfmt.segments[0]).content();		    pfmt.body = pfmt.segments[1];		  }		else		  pfmt.body = pfmt.segments[0];		if (nsegments >=3)		  {		    if (! (pfmt.segments[2] instanceof LiteralFormat))		      throw new ParseException("suffix segment is not literal", i);		    pfmt.suffix = ((LiteralFormat) pfmt.segments[2]).content();		  }	      }	    else // Justification	      throw new ParseException("not implemented: justfication i.e. ~<...~>", i);	    continue;	  case '[':	    LispChoiceFormat afmt = new LispChoiceFormat();	    afmt.param = getParam(stack, speci);	    if (afmt.param == PARAM_UNSPECIFIED)	      afmt.param = PARAM_FROM_LIST;	    if (seenColon)	      afmt.testBoolean = true;	    if (seenAt)	      afmt.skipIfFalse = true;	    stack.setSize(speci);	    stack.push(afmt);	    stack.push(IntNum.make(start_nesting));	    stack.push(IntNum.make(choices_seen));	    start_nesting = speci;	    choices_seen = 0;	    continue;	  case ';':	    if (start_nesting >= 0)	      {		if (stack.elementAt(start_nesting)		    instanceof LispChoiceFormat)		  {		    afmt = (LispChoiceFormat) stack.elementAt(start_nesting);		    if (seenColon)		      afmt.lastIsDefault = true;		    fmt = popFormats(stack,				     start_nesting + 3 + choices_seen, speci);		    stack.push(fmt);		    choices_seen++;		    continue;		  }		else if (stack.elementAt(start_nesting)		    instanceof LispPrettyFormat)		  {		    pfmt = (LispPrettyFormat) stack.elementAt(start_nesting);		    if (seenAt)		      pfmt.perLine = true;		    fmt = popFormats(stack,				     start_nesting + 3 + choices_seen, speci);		    stack.push(fmt);		    choices_seen++;		    continue;		  }		// else if saw ~< ...	      }	    throw new ParseException("saw ~; without matching ~[ or ~<", i);	  case ']':	    if (start_nesting < 0		|| ! (stack.elementAt(start_nesting)                      instanceof LispChoiceFormat))              throw new ParseException("saw ~] without matching ~[", i);	    fmt = popFormats(stack, start_nesting + 3 + choices_seen, speci);	    stack.push(fmt);	    afmt = (LispChoiceFormat) stack.elementAt(start_nesting);	    afmt.choices = getFormats(stack, start_nesting + 3, stack.size());	    stack.setSize(start_nesting + 3);	    choices_seen = ((IntNum) stack.pop()).intValue();	    start_nesting = ((IntNum) stack.pop()).intValue();	    continue;	  case '^':	    param1 = getParam(stack, speci);	    param2 = getParam(stack, speci+1);	    param3 = getParam(stack, speci+2);	    fmt = new LispEscapeFormat(param1, param2, param3);	    break;	  case '\n':	    if (seenAt)	      litbuf.append(ch);	    if (! seenColon)	      {		while (i < limit)		  {		    ch = format[i++];		    if (! Character.isWhitespace(ch))		      {			i--;			break;		      }		  }	      }	    continue;	  case '!':	    fmt = FlushFormat.getInstance();	    break;	  case 'T':	    param1 = getParam(stack, speci);	    param2 = getParam(stack, speci+1);	    param3 = getParam(stack, speci+2);	    fmt = new LispTabulateFormat(param1, param2, param3, seenAt);	    break;	  case '&':	    param1 = getParam(stack, speci);	    fmt = new LispFreshlineFormat(param1);	    break;	  case 'I': // Indent	    param1 = getParam(stack, speci);	    if (param1 == PARAM_UNSPECIFIED)	      param1 = 0;	    fmt = LispIndentFormat.getInstance(param1, seenColon);	    break;	  case '_': // conditional newline	    param1 = getParam(stack, speci);	    if (param1 == PARAM_UNSPECIFIED)	      param1 = 1;	    charVal = seenColon && seenAt ? '\n' : ' ';	    int kind;	    if (seenAt && seenColon) kind = PrettyWriter.NEWLINE_MANDATORY;	    else if (seenAt) kind = PrettyWriter.NEWLINE_MISER;	    else if (seenColon) kind = PrettyWriter.NEWLINE_FILL;	    else kind = PrettyWriter.NEWLINE_LINEAR;	    fmt = LispNewlineFormat.getInstance(param1, kind);	    break;	  case '~':	    if (numParams == 0)	      {		litbuf.append(ch);		continue;	      }	    /* ... otherwise fall through ... */	  case '|':	    count = getParam(stack, speci);	    if (count == PARAM_UNSPECIFIED)	      count = 1;	    // EXTENSION:  Allow repeating other characters than '~'.	    charVal = getParam(stack, speci+1);	    if (charVal == PARAM_UNSPECIFIED) 	      charVal = ch == '|' ? '\f' : '~';	    fmt = LispCharacterFormat.getInstance(charVal, count,						  false, false);	    break;	  case '%':	    count = getParam(stack, speci);	    if (count == PARAM_UNSPECIFIED)	      count = 1;	    fmt = LispNewlineFormat.getInstance(count,						PrettyWriter.NEWLINE_LITERAL);	    break;          default:	    throw new ParseException("unrecognized format specifier ~"+ch, i);          }	stack.setSize(speci);	stack.push(fmt);      }    if (i > limit)      throw new IndexOutOfBoundsException();    if (start_nesting >= 0)      {	throw new ParseException("missing ~] or ~}", i);      }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -