commit 3af8336b60521908f64928dadaf98d9cbc088361
parent f22acd567ef54aad9c760414829868806b0f983f
Author: Commit-Bot <unknown>
Date: Wed, 10 Nov 2010 19:21:50 +0000
Automatic commit from picoLisp.tgz, From: Wed, 10 Nov 2010 19:21:50 GMT
Diffstat:
5 files changed, 624 insertions(+), 177 deletions(-)
diff --git a/ersatz/PicoLisp.java b/ersatz/PicoLisp.java
@@ -1,4 +1,4 @@
-// 09nov10abu
+// 10nov10abu
// (c) Software Lab. Alexander Burger
import java.util.*;
@@ -16,7 +16,7 @@ public class PicoLisp {
final static HashMap<String,Symbol> Intern = new HashMap<String,Symbol>();
final static HashMap<String,Symbol> Transient = new HashMap<String,Symbol>();
final static byte MonLen[] = new byte[] {31,31,28,31,30,31,30,31,31,30,31,30,31};
- final static byte Version[] = new byte[] {3,0,4,4};
+ final static byte Version[] = new byte[] {3,0,4,5};
final static Number Zero = new Number(0);
final static Number One = new Number(1);
@@ -339,25 +339,35 @@ public class PicoLisp {
mkSymbol(new Number("273"), "path", Intern);
mkSymbol(new Number("274"), "read", Intern);
mkSymbol(new Number("275"), "wait", Intern);
- mkSymbol(new Number("276"), "char", Intern);
- mkSymbol(new Number("277"), "skip", Intern);
- mkSymbol(new Number("278"), "line", Intern);
- mkSymbol(new Number("279"), "load", Intern);
- mkSymbol(new Number("280"), "in", Intern);
- mkSymbol(new Number("281"), "out", Intern);
- mkSymbol(new Number("282"), "open", Intern);
- mkSymbol(new Number("283"), "close", Intern);
- mkSymbol(new Number("284"), "prin", Intern);
- mkSymbol(new Number("285"), "prinl", Intern);
- mkSymbol(new Number("286"), "space", Intern);
- mkSymbol(new Number("287"), "print", Intern);
- mkSymbol(new Number("288"), "printsp", Intern);
- mkSymbol(new Number("289"), "println", Intern);
- mkSymbol(new Number("290"), "flush", Intern);
- mkSymbol(new Number("291"), "port", Intern);
- mkSymbol(new Number("292"), "accept", Intern);
- mkSymbol(new Number("293"), "connect", Intern);
- MaxFun = 293;
+ mkSymbol(new Number("276"), "poll", Intern);
+ mkSymbol(new Number("277"), "peek", Intern);
+ mkSymbol(new Number("278"), "char", Intern);
+ mkSymbol(new Number("279"), "skip", Intern);
+ mkSymbol(new Number("280"), "eol", Intern);
+ mkSymbol(new Number("281"), "eof", Intern);
+ mkSymbol(new Number("282"), "from", Intern);
+ mkSymbol(new Number("283"), "till", Intern);
+ mkSymbol(new Number("284"), "line", Intern);
+ mkSymbol(new Number("285"), "any", Intern);
+ mkSymbol(new Number("286"), "sym", Intern);
+ mkSymbol(new Number("287"), "str", Intern);
+ mkSymbol(new Number("288"), "load", Intern);
+ mkSymbol(new Number("289"), "in", Intern);
+ mkSymbol(new Number("290"), "out", Intern);
+ mkSymbol(new Number("291"), "open", Intern);
+ mkSymbol(new Number("292"), "close", Intern);
+ mkSymbol(new Number("293"), "echo", Intern);
+ mkSymbol(new Number("294"), "prin", Intern);
+ mkSymbol(new Number("295"), "prinl", Intern);
+ mkSymbol(new Number("296"), "space", Intern);
+ mkSymbol(new Number("297"), "print", Intern);
+ mkSymbol(new Number("298"), "printsp", Intern);
+ mkSymbol(new Number("299"), "println", Intern);
+ mkSymbol(new Number("300"), "flush", Intern);
+ mkSymbol(new Number("301"), "port", Intern);
+ mkSymbol(new Number("302"), "accept", Intern);
+ mkSymbol(new Number("303"), "connect", Intern);
+ MaxFun = 303;
init();
for (boolean first = true; ; first = false) {
try {
@@ -547,7 +557,7 @@ public class PicoLisp {
if (s.length() > 0)
if (s.charAt(0) == '+') {
if (s.length() > 1 && s.charAt(1) == '@')
- return "+" + Home + s.substring(1);
+ return '+' + Home + s.substring(1);
}
else if (s.charAt(0) == '@')
return Home + s.substring(1);
@@ -860,50 +870,6 @@ public class PicoLisp {
catch (NumberFormatException e) {return Nil;}
}
- final static Any token(Any x, char c) {
- if (InFile.Chr == 0)
- InFile.get();
- if (InFile.skip(c) < 0)
- return null;
- if (InFile.Chr == '"') {
- InFile.get();
- if (InFile.Chr == '"') {
- InFile.get();
- return Nil;
- }
- if (!InFile.testEsc())
- return Nil;
- StringBuilder sb = new StringBuilder();
- sb.append((char)InFile.Chr);
- while (InFile.get() != '"' && InFile.testEsc())
- sb.append((char)InFile.Chr);
- InFile.get();
- return mkStr(sb);
- }
- if (InFile.Chr >= '0' && InFile.Chr <= '9') {
- StringBuilder sb = new StringBuilder();
- sb.append((char)InFile.Chr);
- while (InFile.get() >= '0' && InFile.Chr <= '9' || InFile.Chr == '.')
- sb.append((char)InFile.Chr);
- return strToAtom(sb.toString());
- }
- String s = x.name();
- if (InFile.Chr >= 'A' && InFile.Chr <= 'Z' || InFile.Chr == '\\' || InFile.Chr >= 'a' && InFile.Chr <= 'z' || s.indexOf(InFile.Chr) >= 0) {
- if (InFile.Chr == '\\')
- InFile.get();
- StringBuilder sb = new StringBuilder();
- sb.append((char)InFile.Chr);
- while (InFile.get() >= '0' && InFile.Chr <= '9' || InFile.Chr >= 'A' && InFile.Chr <= 'Z' || InFile.Chr == '\\' || InFile.Chr >= 'a' && InFile.Chr <= 'z' || s.indexOf(InFile.Chr) >= 0) {
- if (InFile.Chr == '\\')
- InFile.get();
- sb.append((char)InFile.Chr);
- }
- s = sb.toString();
- return s.equals("NIL")? Nil : mkSymbol(Nil, s, Intern);
- }
- return mkChar((char)InFile.get());
- }
-
final static Any fish(Any ex, Any foo, Any[] v, Any res) {
if (foo.apply(ex, false, v, 1) != Nil)
return new Cell(v[0], res);
@@ -995,6 +961,7 @@ public class PicoLisp {
final static int xInt(Any x) {return ((Number)x).Cnt;}
final static int evInt(Any ex) {return ((Number)ex.Car.eval()).Cnt;}
+ final static long xLong(Any x) {return ((Number)x).longValue();}
final static long evLong(Any ex) {return ((Number)ex.Car.eval()).longValue();}
final static String evString(Any ex) {return ex.Car.eval().name();}
@@ -1645,7 +1612,7 @@ public class PicoLisp {
}
return Chr;
}
- catch (IOException e) {return -1;}
+ catch (IOException e) {return Chr = -1;}
}
final boolean eol() {
@@ -1789,8 +1756,8 @@ public class PicoLisp {
return Nil;
eofErr();
}
- if (top && InFile != null && InFile.Rd instanceof LineNumberReader)
- InFile.Src = ((LineNumberReader)InFile.Rd).getLineNumber() + 1;
+ if (top && Rd instanceof LineNumberReader)
+ Src = ((LineNumberReader)Rd).getLineNumber() + 1;
if (Chr == '(') {
x = rdList();
if (top && Chr == ']')
@@ -1835,7 +1802,7 @@ public class PicoLisp {
return mkSymbol(null, sb.toString(), Transient);
}
if (Chr == ')' || Chr == ']' || Chr == '~')
- err(null, null, "Bad input '" + (char)Chr + "' (" + Chr + ")");
+ err(null, null, "Bad input '" + (char)Chr + "' (" + Chr + ')');
if (Chr == '\\')
get();
int i = Chr;
@@ -1853,6 +1820,52 @@ public class PicoLisp {
get();
return x;
}
+
+ final Any token(Any x, char c) {
+ if (Chr == 0)
+ get();
+ if (skip(c) < 0)
+ return null;
+ if (Chr == '"') {
+ get();
+ if (Chr == '"') {
+ get();
+ return Nil;
+ }
+ if (!testEsc())
+ return Nil;
+ StringBuilder sb = new StringBuilder();
+ sb.append((char)Chr);
+ while (get() != '"' && testEsc())
+ sb.append((char)Chr);
+ get();
+ return mkStr(sb);
+ }
+ if (Chr >= '0' && Chr <= '9') {
+ StringBuilder sb = new StringBuilder();
+ sb.append((char)Chr);
+ while (get() >= '0' && Chr <= '9' || Chr == '.')
+ sb.append((char)Chr);
+ return strToAtom(sb.toString());
+ }
+ String s = x.name();
+ if (Chr >= 'A' && Chr <= 'Z' || Chr == '\\' || Chr >= 'a' && Chr <= 'z' || s.indexOf(Chr) >= 0) {
+ if (Chr == '\\')
+ get();
+ StringBuilder sb = new StringBuilder();
+ sb.append((char)Chr);
+ while (get() >= '0' && Chr <= '9' || Chr >= 'A' && Chr <= 'Z' || Chr == '\\' || Chr >= 'a' && Chr <= 'z' || s.indexOf(Chr) >= 0) {
+ if (Chr == '\\')
+ get();
+ sb.append((char)Chr);
+ }
+ s = sb.toString();
+ return s.equals("NIL")? Nil : mkSymbol(Nil, s, Intern);
+ }
+ c = (char)Chr;
+ get();
+ return mkChar(c);
+ }
}
/* Ersatz PicoLisp Printer */
@@ -2620,42 +2633,62 @@ public class PicoLisp {
return do274(ex);
case 275: // wait
return do275(ex);
- case 276: // char
+ case 276: // poll
return do276(ex);
- case 277: // skip
+ case 277: // peek
return do277(ex);
- case 278: // line
+ case 278: // char
return do278(ex);
- case 279: // load
+ case 279: // skip
return do279(ex);
- case 280: // in
+ case 280: // eol
return do280(ex);
- case 281: // out
+ case 281: // eof
return do281(ex);
- case 282: // open
+ case 282: // from
return do282(ex);
- case 283: // close
+ case 283: // till
return do283(ex);
- case 284: // prin
+ case 284: // line
return do284(ex);
- case 285: // prinl
+ case 285: // any
return do285(ex);
- case 286: // space
+ case 286: // sym
return do286(ex);
- case 287: // print
+ case 287: // str
return do287(ex);
- case 288: // printsp
+ case 288: // load
return do288(ex);
- case 289: // println
+ case 289: // in
return do289(ex);
- case 290: // flush
+ case 290: // out
return do290(ex);
- case 291: // port
+ case 291: // open
return do291(ex);
- case 292: // accept
+ case 292: // close
return do292(ex);
- case 293: // connect
+ case 293: // echo
return do293(ex);
+ case 294: // prin
+ return do294(ex);
+ case 295: // prinl
+ return do295(ex);
+ case 296: // space
+ return do296(ex);
+ case 297: // print
+ return do297(ex);
+ case 298: // printsp
+ return do298(ex);
+ case 299: // println
+ return do299(ex);
+ case 300: // flush
+ return do300(ex);
+ case 301: // port
+ return do301(ex);
+ case 302: // accept
+ return do302(ex);
+ case 303: // connect
+ return do303(ex);
default:
return undefined(this, ex);
}
@@ -2948,7 +2981,7 @@ public class PicoLisp {
if (ex.Cdr.Car.eval() == Nil) {
for (i = 0; i < 4; ++i)
OutFile.Wr.print(Version[i] + (i == 3? "-" : "."));
- OutFile.Wr.println("J");
+ OutFile.Wr.println('J');
OutFile.Wr.flush();
}
for (x = Nil, i = 4; --i >= 0;)
@@ -5955,7 +5988,7 @@ public class PicoLisp {
x = InFile.read('\0');
else {
y = x.Car.eval();
- if ((x = token(y, (x = x.Cdr.Car.eval()) == Nil? '\0' : firstChar(x))) == null)
+ if ((x = InFile.token(y, (x = x.Cdr.Car.eval()) == Nil? '\0' : firstChar(x))) == null)
x = Nil;
}
if (InFile.Name == null && InFile.Chr == '\n')
@@ -5973,7 +6006,33 @@ public class PicoLisp {
return y;
}
- final static Any do276(Any ex) { // char
+ final static Any do276(Any ex) { // poll
+ int i;
+ Any x;
+ if ((i = xInt(x = ex.Cdr.Car.eval())) < 0 || i >= InFiles.length)
+ badFd(ex,x);
+ if (InFiles[i] == null)
+ return Nil;
+ try {
+ Selector sel = Selector.open();
+ if (InFiles[i].ready(sel))
+ return x;
+ InFiles[i].register(sel);
+ sel.selectNow();
+ if (InFiles[i].ready(sel))
+ return x;
+ }
+ catch (IOException e) {giveup(e);}
+ return Nil;
+ }
+
+ final static Any do277(Any ex) { // peek
+ if (InFile.Chr == 0)
+ InFile.get();
+ return InFile.Chr<0? Nil : mkChar((char)InFile.Chr);
+ }
+
+ final static Any do278(Any ex) { // char
Any x;
if (!((ex = ex.Cdr) instanceof Cell)) {
if (InFile.Chr == 0)
@@ -5987,13 +6046,82 @@ public class PicoLisp {
return x == T? mkChar((char)0x10000) : new Number(firstChar(x));
}
- final static Any do277(Any ex) { // skip
+ final static Any do279(Any ex) { // skip
char c;
c = firstChar(ex.Cdr.Car.eval());
return InFile.skip(c) < 0? Nil : mkChar(c);
}
- final static Any do278(Any ex) { // line
+ final static Any do280(Any ex) { // eol
+ return InFile.Chr=='\n' || InFile.Chr<=0? T : Nil;
+ }
+
+ final static Any do281(Any ex) { // eof
+ if (ex.Cdr.Car.eval() != Nil) {
+ InFile.Chr = -1;
+ return T;
+ }
+ if (InFile.Chr == 0)
+ InFile.get();
+ return InFile.Chr < 0? T : Nil;
+ }
+
+ final static Any do282(Any ex) { // from
+ int i, j, k;
+ Any x;
+ Any[] v;
+ if ((k = (int)(x = ex.Cdr).length()) == 0)
+ return Nil;
+ int[] p = new int[k];
+ String[] av = new String[k];
+ for (v = new Any[k], i = 0; i < k; ++i, x = x.Cdr)
+ av[i] = (v[i] = x.Car.eval()).name();
+ if (InFile.Chr == 0)
+ InFile.get();
+ while (InFile.Chr >= 0) {
+ for (i = 0; i < k; ++i) {
+ for (;;) {
+ if (av[i].charAt(p[i]) == (char)InFile.Chr) {
+ if (++p[i] != av[i].length())
+ break;
+ InFile.get();
+ return v[i];
+ }
+ if (p[i] == 0)
+ break;
+ for (j = 1; --p[i] != 0; ++j)
+ if (av[i].substring(0, p[i]).equals(av[i].substring(j, j + p[i])))
+ break;
+ }
+ }
+ InFile.get();
+ }
+ return Nil;
+ }
+
+ final static Any do283(Any ex) { // till
+ Any x, y;
+ String str;
+ StringBuilder sb;
+ str = evString(x = ex.Cdr);
+ if (InFile.Chr == 0)
+ InFile.get();
+ if (InFile.Chr < 0 || str.indexOf((char)InFile.Chr) >= 0)
+ return Nil;
+ if (x.Cdr.Car.eval() == Nil) {
+ y = x = new Cell(mkChar((char)InFile.Chr), Nil);
+ while (InFile.get() > 0 && str.indexOf((char)InFile.Chr) < 0)
+ x = x.Cdr = new Cell(mkChar((char)InFile.Chr), Nil);
+ return y;
+ }
+ sb = new StringBuilder();
+ do
+ sb.append((char)InFile.Chr);
+ while (InFile.get() > 0 && str.indexOf((char)InFile.Chr) < 0);
+ return mkStr(sb);
+ }
+
+ final static Any do284(Any ex) { // line
int i;
Any x, y, z;
StringBuilder sb;
@@ -6017,7 +6145,42 @@ public class PicoLisp {
}
}
- final static Any do279(Any ex) { // load
+ final static Any do285(Any ex) { // any
+ Any x;
+ if ((x = ex.Cdr.Car.eval()) == Nil)
+ return Nil;
+ PicoLispReader rd = new PicoLispReader(x.name(), ' ', '\0');
+ rd.get();
+ return rd.read0(true);
+ }
+
+ final static Any do286(Any ex) { // sym
+ StringWriter sw = new StringWriter();
+ PrintWriter wr = new PrintWriter(sw);
+ wr.print(ex.Cdr.Car.eval().toString());
+ return mkStr(sw.toString());
+ }
+
+ final static Any do287(Any ex) { // str
+ Any x, y;
+ if ((y = (x = ex.Cdr).Car.eval()) == Nil)
+ return Nil;
+ if (y instanceof Number)
+ argError(ex, y);
+ if (y instanceof Symbol)
+ return ((Symbol)y).parse(false, (x = x.Cdr) instanceof Cell? x.Car.eval() : null);
+ StringWriter sw = new StringWriter();
+ PrintWriter wr = new PrintWriter(sw);
+ for (;;) {
+ wr.print(y.Car.toString());
+ if (!((y = y.Cdr) instanceof Cell))
+ break;
+ wr.print(' ');
+ }
+ return mkStr(sw.toString());
+ }
+
+ final static Any do288(Any ex) { // load
Any x, y;
x = ex.Cdr;
do {
@@ -6029,7 +6192,7 @@ public class PicoLisp {
return y;
}
- final static Any do280(Any ex) { // in
+ final static Any do289(Any ex) { // in
Any x;
Env.pushInFile((x = ex.Cdr).Car.eval().rdOpen(ex));
x = x.Cdr.prog();
@@ -6037,7 +6200,7 @@ public class PicoLisp {
return x;
}
- final static Any do281(Any ex) { // out
+ final static Any do290(Any ex) { // out
Any x;
Env.pushOutFile((x = ex.Cdr).Car.eval().wrOpen(ex));
x = x.Cdr.prog();
@@ -6045,7 +6208,7 @@ public class PicoLisp {
return x;
}
- final static Any do282(Any ex) { // open
+ final static Any do291(Any ex) { // open
String str;
str = evString(ex.Cdr);
try {return new Number(new PicoLispReader(new FileReader(str), str, allocFd(), null, 0).Fd);}
@@ -6053,7 +6216,7 @@ public class PicoLisp {
return Nil;
}
- final static Any do283(Any ex) { // close
+ final static Any do292(Any ex) { // close
int i;
Any x;
if ((i = xInt(x = ex.Cdr.Car.eval())) >= 0 && i < InFiles.length) {
@@ -6071,20 +6234,102 @@ public class PicoLisp {
return Nil;
}
- final static Any do284(Any ex) { // prin
+ final static Any do293(Any ex) { // echo
+ int i, j, k;
+ long n;
+ Any x, y;
+ Any[] v;
+ y = (x = ex.Cdr).Car.eval();
+ if (InFile.Chr == 0)
+ InFile.get();
+ if (y == Nil && !(x.Cdr instanceof Cell)) {
+ while (InFile.Chr >= 0) {
+ OutFile.Wr.print((char)InFile.Chr);
+ InFile.get();
+ }
+ return T;
+ }
+ if (y instanceof Symbol) {
+ k = (int)x.length();
+ int[] p = new int[k];
+ String[] av = new String[k];
+ for (v = new Any[k], i = 0; i < k; ++i, y = (x = x.Cdr).Car.eval())
+ av[i] = (v[i] = y).name();
+ int m = -1, d, om, op = 0; /* Brain-dead Java: 'op' _is_ initialized */
+ while (InFile.Chr >= 0) {
+ if ((om = m) >= 0)
+ op = p[m];
+ for (i = 0; i < k; ++i) {
+ for (;;) {
+ if (av[i].charAt(p[i]) == (char)InFile.Chr) {
+ if (++p[i] != av[i].length()) {
+ if (m < 0 || p[i] > p[m])
+ m = i;
+ break;
+ }
+ if (om >= 0)
+ for (j = 0, d = op-p[i]; j <= d; ++j)
+ OutFile.Wr.print(av[om].charAt(j));
+ InFile.Chr = 0;
+ return v[i];
+ }
+ if (p[i] == 0)
+ break;
+ for (j = 1; --p[i] != 0; ++j)
+ if (av[i].substring(0, p[i]).equals(av[i].substring(j, j + p[i])))
+ break;
+ if (m == i)
+ for (m = -1, j = 0; j < k; ++j)
+ if (p[j] != 0 && (m < 0 || p[j] > p[m]))
+ m = j;
+ }
+ }
+ if (m < 0) {
+ if (om >= 0)
+ for (i = 0; i < op; ++i)
+ OutFile.Wr.print(av[om].charAt(i));
+ OutFile.Wr.print((char)InFile.Chr);
+ }
+ else if (om >= 0)
+ for (i = 0, d = op-p[m]; i <= d; ++i)
+ OutFile.Wr.print(av[om].charAt(i));
+ InFile.get();
+ }
+ return Nil;
+ }
+ if ((x = x.Cdr) instanceof Cell) {
+ for (n = xLong(y), y = x.Car.eval(); --n >= 0; InFile.get())
+ if (InFile.Chr < 0)
+ return Nil;
+ }
+ if ((n = xLong(y)) > 0) {
+ for (;;) {
+ if (InFile.Chr < 0)
+ return Nil;
+ OutFile.Wr.print((char)InFile.Chr);
+ if (--n == 0)
+ break;
+ InFile.get();
+ }
+ }
+ InFile.Chr = 0;
+ return T;
+ }
+
+ final static Any do294(Any ex) { // prin
Any x, y;
for (y = Nil; (ex = ex.Cdr) instanceof Cell; OutFile.Wr.print((y = ex.Car.eval()).name()));
return y;
}
- final static Any do285(Any ex) { // prinl
+ final static Any do295(Any ex) { // prinl
Any x, y;
for (y = Nil; (ex = ex.Cdr) instanceof Cell; OutFile.Wr.print((y = ex.Car.eval()).name()));
OutFile.newline();
return y;
}
- final static Any do286(Any ex) { // space
+ final static Any do296(Any ex) { // space
int i;
Any x;
if ((x = ex.Cdr.Car.eval()) == Nil) {
@@ -6096,7 +6341,7 @@ public class PicoLisp {
return x;
}
- final static Any do287(Any ex) { // print
+ final static Any do297(Any ex) { // print
Any x, y;
OutFile.print(y = (x = ex.Cdr).Car.eval());
while ((x = x.Cdr) instanceof Cell) {
@@ -6106,7 +6351,7 @@ public class PicoLisp {
return y;
}
- final static Any do288(Any ex) { // printsp
+ final static Any do298(Any ex) { // printsp
Any x, y;
x = ex.Cdr;
do {
@@ -6116,7 +6361,7 @@ public class PicoLisp {
return y;
}
- final static Any do289(Any ex) { // println
+ final static Any do299(Any ex) { // println
Any x, y;
OutFile.print(y = (x = ex.Cdr).Car.eval());
while ((x = x.Cdr) instanceof Cell) {
@@ -6127,11 +6372,11 @@ public class PicoLisp {
return y;
}
- final static Any do290(Any ex) { // flush
+ final static Any do300(Any ex) { // flush
return OutFile.Wr.checkError()? Nil : T;
}
- final static Any do291(Any ex) { // port
+ final static Any do301(Any ex) { // port
ex = ex.Cdr; // ...
try {
ServerSocketChannel chan = ServerSocketChannel.open();;
@@ -6142,7 +6387,7 @@ public class PicoLisp {
return Nil;
}
- final static Any do292(Any ex) { // accept
+ final static Any do302(Any ex) { // accept
int i;
Any x;
if ((i = xInt(x = ex.Cdr.Car.eval())) < 0 || i >= InFiles.length || InFiles[i] == null || InFiles[i].Chan == null)
@@ -6152,7 +6397,7 @@ public class PicoLisp {
return Nil;
}
- final static Any do293(Any ex) { // connect
+ final static Any do303(Any ex) { // connect
int i;
try {
SocketChannel chan = SocketChannel.open();
@@ -6665,7 +6910,7 @@ public class PicoLisp {
s = s.substring(i + 1);
if (s.startsWith("class "))
s = s.substring(6);
- return "$" + s;
+ return '$' + s;
}
if (Intern.get(Name) == this) {
@@ -6697,7 +6942,7 @@ public class PicoLisp {
}
final Any parse(boolean skp, Any s) {
- Any x, y;
+ Any x, y, z;
PicoLispReader rd;
if (s == null)
rd = new PicoLispReader(name(), '\n', ']');
@@ -6707,12 +6952,12 @@ public class PicoLisp {
rd.get();
if (s == null)
return rd.rdList();
- if ((x = token(s, '\0')) == null)
+ if ((x = rd.token(s, '\0')) == null)
return Nil;
- y = new Cell(x, Nil);
- while ((x = token(s, '\0')) != null)
+ z = y = new Cell(x, Nil);
+ while ((x = rd.token(s, '\0')) != null)
y = y.Cdr = new Cell(x, Nil);
- return y;
+ return z;
}
}
@@ -7037,7 +7282,7 @@ public class PicoLisp {
Any x, y;
StringBuilder sb;
if (Car == Quote && this != Cdr)
- return "'" + Cdr.toString();
+ return '\'' + Cdr.toString();
x = this;
sb = new StringBuilder();
sb.append('(');
diff --git a/ersatz/fun.src b/ersatz/fun.src
@@ -1,4 +1,4 @@
-# 08nov10abu
+# 10nov10abu
# (c) Software Lab. Alexander Burger
# Ersatz PicoLisp Functions
@@ -260,7 +260,7 @@ version (i x)
if (ex.Cdr.Car.eval() == Nil) {
for (i = 0; i < 4; ++i)
OutFile.Wr.print(Version[i] + (i == 3? "-" : "."));
- OutFile.Wr.println("J");
+ OutFile.Wr.println('J');
OutFile.Wr.flush();
}
for (x = Nil, i = 4; --i >= 0;)
@@ -2982,7 +2982,7 @@ read (x y)
x = InFile.read('\0');
else {
y = x.Car.eval();
- if ((x = token(y, (x = x.Cdr.Car.eval()) == Nil? '\0' : firstChar(x))) == null)
+ if ((x = InFile.token(y, (x = x.Cdr.Car.eval()) == Nil? '\0' : firstChar(x))) == null)
x = Nil;
}
if (InFile.Name == null && InFile.Chr == '\n')
@@ -2997,6 +2997,30 @@ wait (i x y)
return x.prog();
return y;
+# (poll 'cnt) -> cnt | NIL
+poll (i x)
+ if ((i = xInt(x = ex.Cdr.Car.eval())) < 0 || i >= InFiles.length)
+ badFd(ex,x);
+ if (InFiles[i] == null)
+ return Nil;
+ try {
+ Selector sel = Selector.open();
+ if (InFiles[i].ready(sel))
+ return x;
+ InFiles[i].register(sel);
+ sel.selectNow();
+ if (InFiles[i].ready(sel))
+ return x;
+ }
+ catch (IOException e) {giveup(e);}
+ return Nil;
+
+# (peek) -> sym
+peek ()
+ if (InFile.Chr == 0)
+ InFile.get();
+ return InFile.Chr<0? Nil : mkChar((char)InFile.Chr);
+
# (char) -> sym
# (char 'cnt) -> sym
# (char T) -> sym
@@ -3018,6 +3042,69 @@ skip (c)
c = firstChar(ex.Cdr.Car.eval());
return InFile.skip(c) < 0? Nil : mkChar(c);
+# (eol) -> flg
+eol ()
+ return InFile.Chr=='\n' || InFile.Chr<=0? T : Nil;
+
+# (eof ['flg]) -> flg
+eof ()
+ if (ex.Cdr.Car.eval() != Nil) {
+ InFile.Chr = -1;
+ return T;
+ }
+ if (InFile.Chr == 0)
+ InFile.get();
+ return InFile.Chr < 0? T : Nil;
+
+# (from 'any ..) -> sym
+from (i j k x v)
+ if ((k = (int)(x = ex.Cdr).length()) == 0)
+ return Nil;
+ int[] p = new int[k];
+ String[] av = new String[k];
+ for (v = new Any[k], i = 0; i < k; ++i, x = x.Cdr)
+ av[i] = (v[i] = x.Car.eval()).name();
+ if (InFile.Chr == 0)
+ InFile.get();
+ while (InFile.Chr >= 0) {
+ for (i = 0; i < k; ++i) {
+ for (;;) {
+ if (av[i].charAt(p[i]) == (char)InFile.Chr) {
+ if (++p[i] != av[i].length())
+ break;
+ InFile.get();
+ return v[i];
+ }
+ if (p[i] == 0)
+ break;
+ for (j = 1; --p[i] != 0; ++j)
+ if (av[i].substring(0, p[i]).equals(av[i].substring(j, j + p[i])))
+ break;
+ }
+ }
+ InFile.get();
+ }
+ return Nil;
+
+# (till 'any ['flg]) -> lst|sym
+till (x y str sb)
+ str = evString(x = ex.Cdr);
+ if (InFile.Chr == 0)
+ InFile.get();
+ if (InFile.Chr < 0 || str.indexOf((char)InFile.Chr) >= 0)
+ return Nil;
+ if (x.Cdr.Car.eval() == Nil) {
+ y = x = new Cell(mkChar((char)InFile.Chr), Nil);
+ while (InFile.get() > 0 && str.indexOf((char)InFile.Chr) < 0)
+ x = x.Cdr = new Cell(mkChar((char)InFile.Chr), Nil);
+ return y;
+ }
+ sb = new StringBuilder();
+ do
+ sb.append((char)InFile.Chr);
+ while (InFile.get() > 0 && str.indexOf((char)InFile.Chr) < 0);
+ return mkStr(sb);
+
# (line 'flg) -> lst|sym
line (i x y z sb)
if (InFile.Chr == 0)
@@ -3039,6 +3126,40 @@ line (i x y z sb)
y = y.Cdr = new Cell(mkChar((char)InFile.Chr), Nil);
}
+# (any 'sym) -> any
+any (x)
+ if ((x = ex.Cdr.Car.eval()) == Nil)
+ return Nil;
+ PicoLispReader rd = new PicoLispReader(x.name(), ' ', '\0');
+ rd.get();
+ return rd.read0(true);
+
+# (sym 'any) -> sym
+sym ()
+ StringWriter sw = new StringWriter();
+ PrintWriter wr = new PrintWriter(sw);
+ wr.print(ex.Cdr.Car.eval().toString());
+ return mkStr(sw.toString());
+
+# (str 'sym ['sym1]) -> lst
+# (str 'lst) -> sym
+str (x y)
+ if ((y = (x = ex.Cdr).Car.eval()) == Nil)
+ return Nil;
+ if (y instanceof Number)
+ argError(ex, y);
+ if (y instanceof Symbol)
+ return ((Symbol)y).parse(false, (x = x.Cdr) instanceof Cell? x.Car.eval() : null);
+ StringWriter sw = new StringWriter();
+ PrintWriter wr = new PrintWriter(sw);
+ for (;;) {
+ wr.print(y.Car.toString());
+ if (!((y = y.Cdr) instanceof Cell))
+ break;
+ wr.print(' ');
+ }
+ return mkStr(sw.toString());
+
# (load 'any ..) -> any
load (x y)
x = ex.Cdr;
@@ -3087,6 +3208,84 @@ close (i x)
}
return Nil;
+# (echo ['cnt ['cnt]] | ['sym ..]) -> sym
+echo (i j k n x y v)
+ y = (x = ex.Cdr).Car.eval();
+ if (InFile.Chr == 0)
+ InFile.get();
+ if (y == Nil && !(x.Cdr instanceof Cell)) {
+ while (InFile.Chr >= 0) {
+ OutFile.Wr.print((char)InFile.Chr);
+ InFile.get();
+ }
+ return T;
+ }
+ if (y instanceof Symbol) {
+ k = (int)x.length();
+ int[] p = new int[k];
+ String[] av = new String[k];
+ for (v = new Any[k], i = 0; i < k; ++i, y = (x = x.Cdr).Car.eval())
+ av[i] = (v[i] = y).name();
+ int m = -1, d, om, op = 0; /* Brain-dead Java: 'op' _is_ initialized */
+ while (InFile.Chr >= 0) {
+ if ((om = m) >= 0)
+ op = p[m];
+ for (i = 0; i < k; ++i) {
+ for (;;) {
+ if (av[i].charAt(p[i]) == (char)InFile.Chr) {
+ if (++p[i] != av[i].length()) {
+ if (m < 0 || p[i] > p[m])
+ m = i;
+ break;
+ }
+ if (om >= 0)
+ for (j = 0, d = op-p[i]; j <= d; ++j)
+ OutFile.Wr.print(av[om].charAt(j));
+ InFile.Chr = 0;
+ return v[i];
+ }
+ if (p[i] == 0)
+ break;
+ for (j = 1; --p[i] != 0; ++j)
+ if (av[i].substring(0, p[i]).equals(av[i].substring(j, j + p[i])))
+ break;
+ if (m == i)
+ for (m = -1, j = 0; j < k; ++j)
+ if (p[j] != 0 && (m < 0 || p[j] > p[m]))
+ m = j;
+ }
+ }
+ if (m < 0) {
+ if (om >= 0)
+ for (i = 0; i < op; ++i)
+ OutFile.Wr.print(av[om].charAt(i));
+ OutFile.Wr.print((char)InFile.Chr);
+ }
+ else if (om >= 0)
+ for (i = 0, d = op-p[m]; i <= d; ++i)
+ OutFile.Wr.print(av[om].charAt(i));
+ InFile.get();
+ }
+ return Nil;
+ }
+ if ((x = x.Cdr) instanceof Cell) {
+ for (n = xLong(y), y = x.Car.eval(); --n >= 0; InFile.get())
+ if (InFile.Chr < 0)
+ return Nil;
+ }
+ if ((n = xLong(y)) > 0) {
+ for (;;) {
+ if (InFile.Chr < 0)
+ return Nil;
+ OutFile.Wr.print((char)InFile.Chr);
+ if (--n == 0)
+ break;
+ InFile.get();
+ }
+ }
+ InFile.Chr = 0;
+ return T;
+
# (prin 'any ..) -> any
prin (x y)
for (y = Nil; (ex = ex.Cdr) instanceof Cell; OutFile.Wr.print((y = ex.Car.eval()).name()));
diff --git a/ersatz/picolisp.jar b/ersatz/picolisp.jar
Binary files differ.
diff --git a/ersatz/sys.src b/ersatz/sys.src
@@ -1,4 +1,4 @@
-// 09nov10abu
+// 10nov10abu
// (c) Software Lab. Alexander Burger
import java.util.*;
@@ -255,7 +255,7 @@ public class PicoLisp {
if (s.length() > 0)
if (s.charAt(0) == '+') {
if (s.length() > 1 && s.charAt(1) == '@')
- return "+" + Home + s.substring(1);
+ return '+' + Home + s.substring(1);
}
else if (s.charAt(0) == '@')
return Home + s.substring(1);
@@ -568,50 +568,6 @@ public class PicoLisp {
catch (NumberFormatException e) {return Nil;}
}
- final static Any token(Any x, char c) {
- if (InFile.Chr == 0)
- InFile.get();
- if (InFile.skip(c) < 0)
- return null;
- if (InFile.Chr == '"') {
- InFile.get();
- if (InFile.Chr == '"') {
- InFile.get();
- return Nil;
- }
- if (!InFile.testEsc())
- return Nil;
- StringBuilder sb = new StringBuilder();
- sb.append((char)InFile.Chr);
- while (InFile.get() != '"' && InFile.testEsc())
- sb.append((char)InFile.Chr);
- InFile.get();
- return mkStr(sb);
- }
- if (InFile.Chr >= '0' && InFile.Chr <= '9') {
- StringBuilder sb = new StringBuilder();
- sb.append((char)InFile.Chr);
- while (InFile.get() >= '0' && InFile.Chr <= '9' || InFile.Chr == '.')
- sb.append((char)InFile.Chr);
- return strToAtom(sb.toString());
- }
- String s = x.name();
- if (InFile.Chr >= 'A' && InFile.Chr <= 'Z' || InFile.Chr == '\\' || InFile.Chr >= 'a' && InFile.Chr <= 'z' || s.indexOf(InFile.Chr) >= 0) {
- if (InFile.Chr == '\\')
- InFile.get();
- StringBuilder sb = new StringBuilder();
- sb.append((char)InFile.Chr);
- while (InFile.get() >= '0' && InFile.Chr <= '9' || InFile.Chr >= 'A' && InFile.Chr <= 'Z' || InFile.Chr == '\\' || InFile.Chr >= 'a' && InFile.Chr <= 'z' || s.indexOf(InFile.Chr) >= 0) {
- if (InFile.Chr == '\\')
- InFile.get();
- sb.append((char)InFile.Chr);
- }
- s = sb.toString();
- return s.equals("NIL")? Nil : mkSymbol(Nil, s, Intern);
- }
- return mkChar((char)InFile.get());
- }
-
final static Any fish(Any ex, Any foo, Any[] v, Any res) {
if (foo.apply(ex, false, v, 1) != Nil)
return new Cell(v[0], res);
@@ -703,6 +659,7 @@ public class PicoLisp {
final static int xInt(Any x) {return ((Number)x).Cnt;}
final static int evInt(Any ex) {return ((Number)ex.Car.eval()).Cnt;}
+ final static long xLong(Any x) {return ((Number)x).longValue();}
final static long evLong(Any ex) {return ((Number)ex.Car.eval()).longValue();}
final static String evString(Any ex) {return ex.Car.eval().name();}
@@ -1353,7 +1310,7 @@ public class PicoLisp {
}
return Chr;
}
- catch (IOException e) {return -1;}
+ catch (IOException e) {return Chr = -1;}
}
final boolean eol() {
@@ -1497,8 +1454,8 @@ public class PicoLisp {
return Nil;
eofErr();
}
- if (top && InFile != null && InFile.Rd instanceof LineNumberReader)
- InFile.Src = ((LineNumberReader)InFile.Rd).getLineNumber() + 1;
+ if (top && Rd instanceof LineNumberReader)
+ Src = ((LineNumberReader)Rd).getLineNumber() + 1;
if (Chr == '(') {
x = rdList();
if (top && Chr == ']')
@@ -1543,7 +1500,7 @@ public class PicoLisp {
return mkSymbol(null, sb.toString(), Transient);
}
if (Chr == ')' || Chr == ']' || Chr == '~')
- err(null, null, "Bad input '" + (char)Chr + "' (" + Chr + ")");
+ err(null, null, "Bad input '" + (char)Chr + "' (" + Chr + ')');
if (Chr == '\\')
get();
int i = Chr;
@@ -1561,6 +1518,52 @@ public class PicoLisp {
get();
return x;
}
+
+ final Any token(Any x, char c) {
+ if (Chr == 0)
+ get();
+ if (skip(c) < 0)
+ return null;
+ if (Chr == '"') {
+ get();
+ if (Chr == '"') {
+ get();
+ return Nil;
+ }
+ if (!testEsc())
+ return Nil;
+ StringBuilder sb = new StringBuilder();
+ sb.append((char)Chr);
+ while (get() != '"' && testEsc())
+ sb.append((char)Chr);
+ get();
+ return mkStr(sb);
+ }
+ if (Chr >= '0' && Chr <= '9') {
+ StringBuilder sb = new StringBuilder();
+ sb.append((char)Chr);
+ while (get() >= '0' && Chr <= '9' || Chr == '.')
+ sb.append((char)Chr);
+ return strToAtom(sb.toString());
+ }
+ String s = x.name();
+ if (Chr >= 'A' && Chr <= 'Z' || Chr == '\\' || Chr >= 'a' && Chr <= 'z' || s.indexOf(Chr) >= 0) {
+ if (Chr == '\\')
+ get();
+ StringBuilder sb = new StringBuilder();
+ sb.append((char)Chr);
+ while (get() >= '0' && Chr <= '9' || Chr >= 'A' && Chr <= 'Z' || Chr == '\\' || Chr >= 'a' && Chr <= 'z' || s.indexOf(Chr) >= 0) {
+ if (Chr == '\\')
+ get();
+ sb.append((char)Chr);
+ }
+ s = sb.toString();
+ return s.equals("NIL")? Nil : mkSymbol(Nil, s, Intern);
+ }
+ c = (char)Chr;
+ get();
+ return mkChar(c);
+ }
}
/* Ersatz PicoLisp Printer */
@@ -2308,7 +2311,7 @@ public class PicoLisp {
s = s.substring(i + 1);
if (s.startsWith("class "))
s = s.substring(6);
- return "$" + s;
+ return '$' + s;
}
if (Intern.get(Name) == this) {
@@ -2340,7 +2343,7 @@ public class PicoLisp {
}
final Any parse(boolean skp, Any s) {
- Any x, y;
+ Any x, y, z;
PicoLispReader rd;
if (s == null)
rd = new PicoLispReader(name(), '\n', ']');
@@ -2350,12 +2353,12 @@ public class PicoLisp {
rd.get();
if (s == null)
return rd.rdList();
- if ((x = token(s, '\0')) == null)
+ if ((x = rd.token(s, '\0')) == null)
return Nil;
- y = new Cell(x, Nil);
- while ((x = token(s, '\0')) != null)
+ z = y = new Cell(x, Nil);
+ while ((x = rd.token(s, '\0')) != null)
y = y.Cdr = new Cell(x, Nil);
- return y;
+ return z;
}
}
@@ -2680,7 +2683,7 @@ public class PicoLisp {
Any x, y;
StringBuilder sb;
if (Car == Quote && this != Cdr)
- return "'" + Cdr.toString();
+ return '\'' + Cdr.toString();
x = this;
sb = new StringBuilder();
sb.append('(');
diff --git a/src64/version.l b/src64/version.l
@@ -1,6 +1,6 @@
-# 01nov10abu
+# 10nov10abu
# (c) Software Lab. Alexander Burger
-(de *Version 3 0 4 4)
+(de *Version 3 0 4 5)
# vi:et:ts=3:sw=3