📄 lispobject.java
字号:
//#ifdef DEBUG
if(args==null)
throw new IllegalArgumentException();
//#endif
int size = args.length;
//#ifdef DEBUG
if(size==0)
throw new IllegalArgumentException();
//#endif
NameObjectBase functor = (NameObjectBase)args[0];
if(size==1)
return new FunctorList0(functor);
if(size==2)
return new FunctorList1(functor,args[1]);
if(size==3)
return new FunctorList2(functor,args[1],args[2]);
if(size==4)
return new FunctorList3(functor,args[1],args[2],args[3]);
LispObject newargs[] = new LispObject[size-1];
for(int i=1;i<size;i++)
newargs[i-1]=args[i];
return new FunctorListN(functor,newargs);
}
public static LispObject createFunctorOrQuotedList(LispObject args[]) {
if(args.length==0)
return EMPTY_LIST;
if(args[0] instanceof NameObjectBase)
return createFunctorList(args);
return new QuotedList(args);
}
// argumens may be only constants!!!
// will thow an exception if they are not
// throws EvaluateException for sheet loading when it tries to evaluate sublists
public static LispObject fromList( FunctorList fl ) throws EvaluateException {
final int size = fl.listSize();
if(fl.functor==Bfunc.BFUNC.table[Bfunc.INDEX_REF]) {
Reference ref = new Reference(
((ShortAtom) fl.evaluateArgN(1)).value,
((ShortAtom) fl.evaluateArgN(2)).value,
((ShortAtom) fl.evaluateArgN(3)).value,
((ShortAtom) fl.evaluateArgN(4)).value,
((ShortAtom) fl.evaluateArgN(5)).value
);
return ref;
}
if(fl.functor==Bfunc.BFUNC.table[Bfunc.INDEX_ERROR]) {
if( fl.listSize()>2 ) {
return new FormulaError( fl.getShort1(), fl.getString2() );
}
return new FormulaError( fl.getShort1() );
}
if(fl.functor==Bfunc.BFUNC.table[Bfunc.INDEX_DATE]) {
return new DateAtom( ((FloatAtom)fl.evaluateArg1()).value );
}
if(fl.functor==Bfunc.BFUNC.table[Bfunc.INDEX_SHEET_CREATE]) {
return Sheet.sheetFromList(fl);
}
if(fl.functor==Bfunc.BFUNC.table[Bfunc.INDEX_ROWCOLUMN]) {
return new RowColumn(
fl.getShort(1),
fl.getShort(2)
);
}
if(fl.functor==Bfunc.BFUNC.table[Bfunc.INDEX_CELL_CREATE]) {
return Cell.fromList(fl);
}
if(fl.functor==Bfunc.BFUNC.table[Bfunc.INDEX_QLIST]) {
return new QuotedList(fl,1,size);
}
throw new IllegalArgumentException("Wrong call of toList()");
}
/**
* Should be used only for FunctorList or QuotedList.
* @return
* FunctorList represented as quoted list
* @throws IllegalArgumentException if is called not for FunctorList or Quoted List
*/
public QuotedList toQuotedList() {
throw new IllegalArgumentException();
}
//#ifdef LISP_PARSER
/*=========================================================================
* Lisp code parser
*=========================================================================
*/
private static int ncur;
private static char buf[]; // must have '\0' at the end
static int lineno;
// get first non-blank character from input
// returns at EOF
private static char skipBlanks() {
char cc;
while ((cc = buf[ncur]) == '\n' || cc == '\r' || cc == '\t' || cc == ' ') {
if (cc == '\n') {
lineno++;
}
ncur++;
}
ncur++;
return cc;
}
// the same but with comments
private static char skipBlanks1() {
char cc;
while ((cc = skipBlanks()) == ';') {
while ((cc = buf[ncur]) != '\n' && cc != '\r' && cc != '\0' ) {
if (cc == '\n') {
lineno++;
}
ncur++;
}
}
return cc;
}
private static boolean isLetter(char c) {
return
(c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(c >= '_');
}
private static void prepareBuf( String in ) {
int len = in.length();
buf = new char[len+2];
in.getChars(0, len, buf, 0);
buf[len] = '\0';
buf[len+1] = '\0'; // to simplify EOF control when parsing trailing '\"' in strings
lineno = ncur = 0;
}
/**
* parses the input stream. function definitions are parsed as calls to the
* function defun and the interpreter will work it all out
* could be not synchronized if pass buf[] via arguments recursevely
*/
synchronized public static QuotedList parse( String in ) throws ParseException {
// get string to buffer
prepareBuf( in );
Vector args = new Vector(); // of LispObject type
// insert everything into one big top level list for execution
try {
while( skipBlanks1() != '\0' ) { // EOF
ncur--;
args.addElement( parseSExpQ() );
}
return new QuotedList( vectorToArray( args ) );
}
finally {
buf = null;
}
}
// single s-exp
synchronized public static LispObject parseSExp( String in ) throws ParseException {
// get string to buffer
prepareBuf( in );
try {
return parseSExpQ();
}
finally {
buf = null;
}
}
// load from resource
public static QuotedList loadFile( String file ) throws ParseException {
InputStream is = NIL.getClass().getResourceAsStream( file );
if( is == null )
throw new ParseException( "resource file <" + file + "> not found" );
byte sss[] = new byte[ 1024 * MAX_MC2FILE_SIZE ];
try {
int len = 0;
int total = 0;
while( len!=-1 ) {
len = is.read( sss,total,sss.length - total );
if( len > 0)
total += len;
}
String ss = getStringUTF8( sss, 0, total );
return parse( ss );
}
catch( IOException ee ) {
throw new ParseException( "i/o error while reading file <" + file + ">" );
}
finally {
sss = null;
try { is.close(); } catch( Exception ee ) {} // for is = null as well
}
}
// retrieves elements from vector as LispObject[] array
public static LispObject[] vectorToArray( Vector vv ) {
int size = vv.size();
LispObject lo[] = new LispObject[size];
for( int i=0; i<size; i++ )
lo[i] = (LispObject) vv.elementAt(i);
return lo;
}
// the quote token
private static LispObject parseSExpQ() throws ParseException {
char token = skipBlanks1();
if (token == '\'') {
LispObject sexp = parseSExp();
int type = sexp.typeNumber();
if(type==TYPE_FUNCTORLIST)
return new QuotedList( (FunctorList) sexp );
if(type==TYPE_QUOTEDLIST)
return sexp;
throw new ParseException( "quote is supported only for lists" );
}
ncur--;
return parseSExp();
}
private static LispObject parseSExp() throws ParseException {
char cc = skipBlanks1();
// list
if( cc == '(' ) {
Vector args = new Vector(4);
while( (cc=skipBlanks1()) != ')' ) {
if( cc == '\0' ) {
String msg = "missing closing ')'";
if( args.size() > 0 ) {
msg += " for '" + ((LispObject)args.elementAt(0)).toString();
throw new ParseException( msg );
}
}
ncur--;
args.addElement( parseSExpQ() );
}
return createFunctorOrQuotedList( vectorToArray(args) );
}
// string constant
if( cc == '"' ) {
StringBuffer sb = new StringBuffer(20);
while ((cc = buf[ncur])!= '"') {
if( cc == '\0' )
throw new ParseException("missing trailing \" in string constant");
ncur++;
if (cc == '\n') {
lineno++;
}
if (cc == '\\') {
cc = buf[ncur++];
// EOF control by double zeroes at the end of buffer
switch (cc) {
case 'n':
cc = '\n';
break;
case 't':
cc = '\t';
break;
case '"':
cc = '"';
break;
case '\\':
// cc = '\\';
debug("ku1");
break;
default:
sb.append('\\');
}
}
sb.append(cc);
}
// skip trailing '"'
ncur++;
//#ifdef NOGUI
//# return ModuleHandler.MODULEHANDLER.addStringConstant( sb.toString() );
//#else
return new StringAtom( sb.toString() );
//#endif
}
// numeric
if( cc == '-' ||
//#ifdef ISDIGIT
//# isDigit( cc )
//#else
Character.isDigit( cc )
//#endif
) {
StringBuffer sb = new StringBuffer(20);
sb.append( cc );
// a number constant
boolean fdot = false;
while (
//#ifdef ISDIGIT
//# isDigit(cc = buf[ncur])
//#else
Character.isDigit( cc = buf[ncur] )
//#endif
|| cc == '.') {
if( cc == '.' ) fdot = true;
sb.append(cc);
ncur++;
}
// long constant?
String ss = sb.toString();
// float
if( fdot )
return new FloatAtom( ss );
// long
if ( cc == 'L') {
ncur++;
return new LongAtom( Long.parseLong( ss ) );
}
// short
return ShortAtom.createShortAtom( Short.parseShort( ss ) );
}
// a symbol (name)
if (isLetter(cc) || cc == '$') {
StringBuffer sb = new StringBuffer(20);
sb.append( cc );
while (
isLetter(cc = buf[ncur]) ||
cc == '_' || cc == '.' || cc == '-' || cc == '$' ||
//#ifdef ISDIGIT
//# isDigit(cc)
//#else
Character.isDigit( cc )
//#endif
) {
sb.append(cc);
ncur++;
}
String name = sb.toString();
if (name.equals("nil"))
return NIL;
if (name.equals("true"))
return BooleanAtom.TRUE;
if (name.equals("false"))
return BooleanAtom.FALSE;
try {
return ModuleHandler.MODULEHANDLER.createName( name );
}
catch( EvaluateException ee ) {
throw new ParseException( "Cannot initiate name <" + name + ">: " + ee.getMessage());
}
}
throw new ParseException( "Unexpected character <" + cc + ">" );
}
//#endif
/**
* Returns length of list, including functor. Must be overrided by in FunctorList subclasses
* @return length of the list, 0 for the FunctorList and Atoms
*/
public int listSize() {
return 0;
}
//#ifdef DEBUG
private static final boolean DEBUG = true;
//#else
//# private static final boolean DEBUG = false;
//#endif
public static final void debug( String ss ) {
//#ifdef HISTORY
CanvasHandler1.addToHistory( ss );
//#endif
//#ifdef DEBUG
if( DEBUG ) {
System.out.println( ss );
}
//#endif
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -