picolisp

Unnamed repository; edit this file to name it for gitweb.
git clone https://logand.com/git/picolisp.git/
Log | Files | Refs | README | LICENSE

commit 59b9560bfb7bddea44005587fd7cb364f4c71f61
parent b6b302c5f3fb9f027b9eee3dbe4f7cc0fdb2f2e2
Author: Commit-Bot <unknown>
Date:   Wed, 17 Nov 2010 15:06:37 +0000

Automatic commit from picoLisp.tgz, From: Wed, 17 Nov 2010 15:06:37 GMT
Diffstat:
MCHANGES | 1+
Mdoc/ref.html | 1+
Mdoc/refC.html | 14++++++++++++++
Mersatz/fun.src | 28+++++++++++++++-------------
Mersatz/picolisp.jar | 0
Mersatz/sys.src | 90++++++++++++++++++++++++++++---------------------------------------------------
Mlib/tags | 169++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/main.c | 64++++++++++++++++++++++++++++++++++++++--------------------------
Msrc/pico.h | 3++-
Msrc/subr.c | 65++++++++++++++++++++++++++++++++++++++++-------------------------
Msrc/tab.c | 3++-
Msrc64/glob.l | 3++-
Msrc64/io.l | 8+++++---
Msrc64/main.l | 111++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Msrc64/subr.l | 124++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Msrc64/version.l | 4++--
Mtest/src/subr.l | 11++++++++++-
17 files changed, 389 insertions(+), 310 deletions(-)

diff --git a/CHANGES b/CHANGES @@ -1,4 +1,5 @@ * XXdec10 picoLisp-3.0.5 + 'circ?' function Ersatz PicoLisp (Java) version Bug in (rd 'cnt) diff --git a/doc/ref.html b/doc/ref.html @@ -1887,6 +1887,7 @@ abbreviations: <dd><code> <a href="refA.html#atom">atom</a> <a href="refP.html#pair">pair</a> + <a href="refC.html#circ?">circ?</a> <a href="refL.html#lst?">lst?</a> <a href="refN.html#num?">num?</a> <a href="refS.html#sym?">sym?</a> diff --git a/doc/refC.html b/doc/refC.html @@ -310,6 +310,7 @@ is returned. A list argument is returned unchanged. <dd>Produces a circular list of all <code>any</code> arguments by <code><a href="refC.html#cons">cons</a></code>ing them to a list and then connecting the CDR of the last cell to the first cell. See also <code><a +href="refC.html#circ?">circ?</a></code> and <code><a href="refL.html#list">list</a></code>. <pre><code> @@ -317,6 +318,19 @@ href="refL.html#list">list</a></code>. -> (a b c .) </code></pre> +<dt><a name="circ?"><code>(circ? 'any) -> any</code></a> <dd>Returs the circular +(sub)list if <code>any</code> is a circular list, else <code>NIL</code>. See +also <code><a href="refC.html#circ">circ</a></code>. + +<pre><code> +: (circ? 'a) +-> NIL +: (circ? (1 2 3)) +-> NIL +: (circ? (1 . (2 3 .))) +-> (2 3 .) +</code></pre> + <dt><a name="class"><code>(class sym . typ) -> obj</code></a> <dd>Defines <code>sym</code> as a class with the superclass(es) <code>typ</code>. As a side effect, the global variable <code><a diff --git a/ersatz/fun.src b/ersatz/fun.src @@ -1,4 +1,4 @@ -# 14nov10abu +# 17nov10abu # (c) Software Lab. Alexander Burger # Ersatz PicoLisp Functions @@ -1556,23 +1556,22 @@ sys () # (call 'any ..) -> flg call (i j x) - j = (int)(x = ex.Cdr).length(); - String[] cmd = new String[j]; - for (i = 0; i < j; ++i) { - cmd[i] = x.Car.eval().name(); - x = x.Cdr; - } + ArrayList<String> cmd = new ArrayList<String>(); + for (x = ex.Cdr; x instanceof Cell; x = x.Cdr) + cmd.add(x.Car.eval().name()); try { - Process p = Runtime.getRuntime().exec(cmd); + ProcessBuilder pb = new ProcessBuilder(cmd); + pb.redirectErrorStream(true); + Process p = pb.start(); BufferedReader in = new BufferedReader(new InputStreamReader(p.getInputStream())); String line; while ((line = in.readLine()) != null) System.out.println(line); - i = p.waitFor(); + return p.waitFor() == 0? T : Nil; } - catch (IOException e) {System.err.println(cmd[0] + ": Can't exec");} + catch (IOException e) {System.err.println(cmd.get(0) + ": Can't exec");} catch (InterruptedException e) {} //#! sighandler() - return i == 0? T : Nil; + return Nil; # (ipid) -> pid | NIL ipid () @@ -2693,6 +2692,10 @@ atom () pair (x) return (x = ex.Cdr.Car.eval()) instanceof Cell? x : Nil; +# (circ? 'any) -> any +circ? (x) + return (x = ex.Cdr.Car.eval()) instanceof Cell && (x = circ(x)) != null? x : Nil; + # (lst? 'any) -> flg lst? (x) return (x = ex.Cdr.Car.eval()) instanceof Cell || x == Nil? T : Nil; @@ -3186,8 +3189,7 @@ char (x) # (skip ['any]) -> sym skip (c) - c = firstChar(ex.Cdr.Car.eval()); - return InFile.skip(c) < 0? Nil : mkChar(c); + return InFile.skip(firstChar(ex.Cdr.Car.eval())) < 0? Nil : mkChar((char)InFile.Chr); # (eol) -> flg eol () 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 @@ -// 14nov10abu +// 17nov10abu // (c) Software Lab. Alexander Burger import java.util.*; @@ -683,15 +683,13 @@ public class PicoLisp { final static String evString(Any ex) {return ex.Car.eval().name();} final static Any circ(Any x) { - int m = 0; - Any[] mark = new Any[12]; + HashSet<Any> mark = new HashSet<Any>(); for (;;) { - mark = append(mark, m++, x); + mark.add(x); if (!((x = x.Cdr) instanceof Cell)) return null; - for (int i = 0; i < m; ++i) - if (mark[i] == x) - return x; + if (mark.contains(x)) + return x; } } @@ -2570,36 +2568,26 @@ public class PicoLisp { final boolean equal(Any x) { if (!(x instanceof Cell)) return false; - Any y = this; - while (x.Car == Quote) { - if (y.Car != Quote) - return false; - if (x == x.Cdr) - return y == y.Cdr; - if (y == y.Cdr) - return false; - if (!(x.Cdr instanceof Cell)) - return x.Cdr.equal(y.Cdr); - x = x.Cdr; - if (!(y.Cdr instanceof Cell)) - return false; - y = y; - } - Any a = x; - Any b = y; + HashSet<Any> mark = new HashSet<Any>(); + Any y = this, a = x, b = y; for (;;) { if (!x.Car.equal(y.Car)) return false; if (!(x.Cdr instanceof Cell)) return x.Cdr.equal(y.Cdr); - x = x.Cdr; if (!(y.Cdr instanceof Cell)) return false; - y = y.Cdr; - if (x == a) - return y == b; - if (y == b) - return false; + mark.add(x); x = x.Cdr; + mark.add(y); y = y.Cdr; + if (mark.contains(x) || mark.contains(y)) { + for (;;) { + if (a == x) + return b == y; + if (b == y) + return false; + a = a.Cdr; b = b.Cdr; + } + } } } @@ -2627,43 +2615,29 @@ public class PicoLisp { } final long length() { - long n = 1; - Any x = this; - while (x.Car == Quote) { - if (x == x.Cdr) - return -1; + long n = 0; + HashSet<Any> mark = new HashSet<Any>(); + for (Any x = this;;) { + ++n; + mark.add(x); if (!((x = x.Cdr) instanceof Cell)) return n; - ++n; - } - Any y = x; - while ((x = x.Cdr) instanceof Cell) { - if (x == y) + if (mark.contains(x)) return -1; - ++n; } - return n; } - final long size() {return size(this);} - final long size(Any x) { - long n; - Any y; - - n = 1; - while (x.Car == Quote) { - if (x == x.Cdr || !((x = x.Cdr) instanceof Cell)) - return n; + final long size() { + long n = 0; + HashSet<Any> mark = new HashSet<Any>(); + for (Any x = this;;) { ++n; - } - for (y = x;;) { if (x.Car instanceof Cell) - n += size(x.Car); - if (!((x = x.Cdr) instanceof Cell) || x == y) - break; - ++n; + n += x.Car.size(); + mark.add(x); + if (!((x = x.Cdr) instanceof Cell) || mark.contains(x)) + return n; } - return n; } final InFrame rdOpen(Any ex) { diff --git a/lib/tags b/lib/tags @@ -6,7 +6,7 @@ $ (2943 . "@src64/flow.l") */ (2446 . "@src64/big.l") + (2171 . "@src64/big.l") - (2209 . "@src64/big.l") --> (3820 . "@src64/subr.l") +-> (3842 . "@src64/subr.l") / (2511 . "@src64/big.l") : (2898 . "@src64/sym.l") :: (2922 . "@src64/sym.l") @@ -29,15 +29,15 @@ adr (613 . "@src64/main.l") alarm (487 . "@src64/main.l") all (772 . "@src64/sym.l") and (1621 . "@src64/flow.l") -any (3869 . "@src64/io.l") +any (3870 . "@src64/io.l") append (1329 . "@src64/subr.l") apply (591 . "@src64/apply.l") -arg (2243 . "@src64/main.l") -args (2219 . "@src64/main.l") -argv (2864 . "@src64/main.l") +arg (2266 . "@src64/main.l") +args (2242 . "@src64/main.l") +argv (2887 . "@src64/main.l") as (146 . "@src64/flow.l") -asoq (2942 . "@src64/subr.l") -assoc (2907 . "@src64/subr.l") +asoq (2964 . "@src64/subr.l") +assoc (2929 . "@src64/subr.l") at (2106 . "@src64/flow.l") atom (2372 . "@src64/subr.l") bind (1359 . "@src64/flow.l") @@ -65,7 +65,7 @@ call (3074 . "@src64/flow.l") car (5 . "@src64/subr.l") case (1962 . "@src64/flow.l") catch (2462 . "@src64/flow.l") -cd (2619 . "@src64/main.l") +cd (2642 . "@src64/main.l") cdaaar (464 . "@src64/subr.l") cdaadr (487 . "@src64/subr.l") cdaar (179 . "@src64/subr.l") @@ -82,12 +82,13 @@ cdddr (245 . "@src64/subr.l") cddr (79 . "@src64/subr.l") cdr (17 . "@src64/subr.l") chain (1132 . "@src64/subr.l") -char (3351 . "@src64/io.l") +char (3352 . "@src64/io.l") chop (1093 . "@src64/sym.l") circ (816 . "@src64/subr.l") +circ? (2389 . "@src64/subr.l") clip (1786 . "@src64/subr.l") -close (4257 . "@src64/io.l") -cmd (2846 . "@src64/main.l") +close (4258 . "@src64/io.l") +cmd (2869 . "@src64/main.l") cnt (1291 . "@src64/apply.l") co (2544 . "@src64/flow.l") commit (1496 . "@src64/db.l") @@ -97,10 +98,10 @@ cond (1916 . "@src64/flow.l") connect (201 . "@src64/net.l") cons (747 . "@src64/subr.l") copy (1216 . "@src64/subr.l") -ctl (4197 . "@src64/io.l") -ctty (2644 . "@src64/main.l") +ctl (4198 . "@src64/io.l") +ctty (2667 . "@src64/main.l") cut (1797 . "@src64/sym.l") -date (2358 . "@src64/main.l") +date (2381 . "@src64/main.l") dbck (2105 . "@src64/db.l") de (531 . "@src64/flow.l") dec (2323 . "@src64/big.l") @@ -109,39 +110,39 @@ default (1661 . "@src64/sym.l") del (1852 . "@src64/sym.l") delete (1392 . "@src64/subr.l") delq (1443 . "@src64/subr.l") -diff (2563 . "@src64/subr.l") -dir (2777 . "@src64/main.l") +diff (2576 . "@src64/subr.l") +dir (2800 . "@src64/main.l") dm (543 . "@src64/flow.l") do (2136 . "@src64/flow.l") e (2904 . "@src64/flow.l") -echo (4288 . "@src64/io.l") +echo (4289 . "@src64/io.l") env (625 . "@src64/main.l") -eof (3428 . "@src64/io.l") -eol (3419 . "@src64/io.l") -errno (1358 . "@src64/main.l") +eof (3429 . "@src64/io.l") +eol (3420 . "@src64/io.l") +errno (1381 . "@src64/main.l") eval (182 . "@src64/flow.l") -ext (5017 . "@src64/io.l") +ext (5019 . "@src64/io.l") ext? (1034 . "@src64/sym.l") extern (900 . "@src64/sym.l") extra (1263 . "@src64/flow.l") extract (1096 . "@src64/apply.l") fifo (1963 . "@src64/sym.l") -file (2724 . "@src64/main.l") -fill (3177 . "@src64/subr.l") +file (2747 . "@src64/main.l") +fill (3199 . "@src64/subr.l") filter (1039 . "@src64/apply.l") fin (2020 . "@src64/subr.l") finally (2520 . "@src64/flow.l") find (1200 . "@src64/apply.l") fish (1491 . "@src64/apply.l") -flg? (2419 . "@src64/subr.l") +flg? (2432 . "@src64/subr.l") flip (1686 . "@src64/subr.l") -flush (4992 . "@src64/io.l") +flush (4994 . "@src64/io.l") fold (3343 . "@src64/sym.l") for (2225 . "@src64/flow.l") fork (3248 . "@src64/flow.l") format (2089 . "@src64/big.l") free (2047 . "@src64/db.l") -from (3447 . "@src64/io.l") +from (3448 . "@src64/io.l") full (1066 . "@src64/subr.l") fun? (734 . "@src64/sym.l") gc (429 . "@src64/gc.l") @@ -153,42 +154,42 @@ glue (1234 . "@src64/sym.l") gt0 (2702 . "@src64/big.l") head (1807 . "@src64/subr.l") heap (542 . "@src64/main.l") -hear (3130 . "@src64/io.l") +hear (3131 . "@src64/io.l") host (184 . "@src64/net.l") id (1027 . "@src64/db.l") idx (2037 . "@src64/sym.l") if (1802 . "@src64/flow.l") if2 (1821 . "@src64/flow.l") ifn (1862 . "@src64/flow.l") -in (4093 . "@src64/io.l") +in (4094 . "@src64/io.l") inc (2256 . "@src64/big.l") -index (2611 . "@src64/subr.l") -info (2681 . "@src64/main.l") +index (2624 . "@src64/subr.l") +info (2704 . "@src64/main.l") intern (875 . "@src64/sym.l") ipid (3193 . "@src64/flow.l") isa (959 . "@src64/flow.l") job (1426 . "@src64/flow.l") journal (970 . "@src64/db.l") -key (3278 . "@src64/io.l") +key (3279 . "@src64/io.l") kill (3225 . "@src64/flow.l") last (2031 . "@src64/subr.l") -length (2687 . "@src64/subr.l") +length (2700 . "@src64/subr.l") let (1476 . "@src64/flow.l") let? (1537 . "@src64/flow.l") lieu (1156 . "@src64/db.l") -line (3603 . "@src64/io.l") -lines (3756 . "@src64/io.l") +line (3604 . "@src64/io.l") +lines (3757 . "@src64/io.l") link (1163 . "@src64/subr.l") -lisp (1921 . "@src64/main.l") +lisp (1944 . "@src64/main.l") list (887 . "@src64/subr.l") listen (151 . "@src64/net.l") lit (157 . "@src64/flow.l") -load (4070 . "@src64/io.l") +load (4071 . "@src64/io.l") lock (1184 . "@src64/db.l") loop (2168 . "@src64/flow.l") low? (3215 . "@src64/sym.l") lowc (3245 . "@src64/sym.l") -lst? (2389 . "@src64/subr.l") +lst? (2402 . "@src64/subr.l") lt0 (2680 . "@src64/big.l") lup (2226 . "@src64/sym.l") made (1098 . "@src64/subr.l") @@ -201,91 +202,91 @@ mapcon (919 . "@src64/apply.l") maplist (811 . "@src64/apply.l") maps (668 . "@src64/apply.l") mark (1965 . "@src64/db.l") -match (3062 . "@src64/subr.l") +match (3084 . "@src64/subr.l") max (2314 . "@src64/subr.l") maxi (1389 . "@src64/apply.l") -member (2429 . "@src64/subr.l") -memq (2451 . "@src64/subr.l") +member (2442 . "@src64/subr.l") +memq (2464 . "@src64/subr.l") meta (3135 . "@src64/sym.l") meth (1087 . "@src64/flow.l") method (1051 . "@src64/flow.l") min (2343 . "@src64/subr.l") mini (1440 . "@src64/apply.l") mix (1251 . "@src64/subr.l") -mmeq (2479 . "@src64/subr.l") +mmeq (2492 . "@src64/subr.l") n0 (2176 . "@src64/subr.l") n== (2074 . "@src64/subr.l") nT (2185 . "@src64/subr.l") name (499 . "@src64/sym.l") nand (1656 . "@src64/flow.l") -native (1366 . "@src64/main.l") +native (1389 . "@src64/main.l") need (918 . "@src64/subr.l") new (833 . "@src64/flow.l") -next (2226 . "@src64/main.l") +next (2249 . "@src64/main.l") nil (1739 . "@src64/flow.l") nond (1939 . "@src64/flow.l") nor (1677 . "@src64/flow.l") not (1729 . "@src64/flow.l") nth (685 . "@src64/subr.l") -num? (2400 . "@src64/subr.l") +num? (2413 . "@src64/subr.l") off (1598 . "@src64/sym.l") -offset (2651 . "@src64/subr.l") +offset (2664 . "@src64/subr.l") on (1583 . "@src64/sym.l") onOff (1613 . "@src64/sym.l") one (1646 . "@src64/sym.l") -open (4219 . "@src64/io.l") +open (4220 . "@src64/io.l") opid (3209 . "@src64/flow.l") -opt (2967 . "@src64/main.l") +opt (2990 . "@src64/main.l") or (1637 . "@src64/flow.l") -out (4113 . "@src64/io.l") +out (4114 . "@src64/io.l") pack (1144 . "@src64/sym.l") pair (2381 . "@src64/subr.l") pass (632 . "@src64/apply.l") pat? (720 . "@src64/sym.l") -path (1229 . "@src64/io.l") -peek (3335 . "@src64/io.l") +path (1230 . "@src64/io.l") +peek (3336 . "@src64/io.l") pick (1247 . "@src64/apply.l") -pipe (4134 . "@src64/io.l") -poll (3222 . "@src64/io.l") +pipe (4135 . "@src64/io.l") +poll (3223 . "@src64/io.l") pool (648 . "@src64/db.l") pop (1773 . "@src64/sym.l") port (5 . "@src64/net.l") -pr (5100 . "@src64/io.l") +pr (5102 . "@src64/io.l") pre? (1411 . "@src64/sym.l") -prin (4916 . "@src64/io.l") -prinl (4930 . "@src64/io.l") -print (4956 . "@src64/io.l") -println (4987 . "@src64/io.l") -printsp (4972 . "@src64/io.l") +prin (4918 . "@src64/io.l") +prinl (4932 . "@src64/io.l") +print (4958 . "@src64/io.l") +println (4989 . "@src64/io.l") +printsp (4974 . "@src64/io.l") prog (1757 . "@src64/flow.l") prog1 (1765 . "@src64/flow.l") prog2 (1782 . "@src64/flow.l") prop (2781 . "@src64/sym.l") protect (532 . "@src64/main.l") -prove (3434 . "@src64/subr.l") +prove (3456 . "@src64/subr.l") push (1688 . "@src64/sym.l") push1 (1724 . "@src64/sym.l") put (2698 . "@src64/sym.l") putl (2950 . "@src64/sym.l") -pwd (2608 . "@src64/main.l") +pwd (2631 . "@src64/main.l") queue (1920 . "@src64/sym.l") -quit (1075 . "@src64/main.l") +quit (1098 . "@src64/main.l") quote (141 . "@src64/flow.l") rand (2959 . "@src64/big.l") range (988 . "@src64/subr.l") -rank (2970 . "@src64/subr.l") +rank (2992 . "@src64/subr.l") raw (465 . "@src64/main.l") -rd (5034 . "@src64/io.l") -read (2561 . "@src64/io.l") +rd (5036 . "@src64/io.l") +read (2562 . "@src64/io.l") replace (1490 . "@src64/subr.l") -rest (2272 . "@src64/main.l") +rest (2295 . "@src64/main.l") reverse (1665 . "@src64/subr.l") -rewind (5000 . "@src64/io.l") +rewind (5002 . "@src64/io.l") rollback (1890 . "@src64/db.l") rot (848 . "@src64/subr.l") -rpc (5133 . "@src64/io.l") +rpc (5135 . "@src64/io.l") run (313 . "@src64/flow.l") -sect (2515 . "@src64/subr.l") +sect (2528 . "@src64/subr.l") seed (2944 . "@src64/big.l") seek (1153 . "@src64/apply.l") send (1131 . "@src64/flow.l") @@ -293,54 +294,54 @@ seq (1083 . "@src64/db.l") set (1482 . "@src64/sym.l") setq (1515 . "@src64/sym.l") sigio (503 . "@src64/main.l") -size (2752 . "@src64/subr.l") -skip (3405 . "@src64/io.l") -sort (3869 . "@src64/subr.l") +size (2765 . "@src64/subr.l") +skip (3406 . "@src64/io.l") +sort (3891 . "@src64/subr.l") sp? (711 . "@src64/sym.l") -space (4934 . "@src64/io.l") +space (4936 . "@src64/io.l") split (1579 . "@src64/subr.l") stack (571 . "@src64/main.l") state (2006 . "@src64/flow.l") stem (1976 . "@src64/subr.l") -str (3923 . "@src64/io.l") +str (3924 . "@src64/io.l") str? (1013 . "@src64/sym.l") strip (1563 . "@src64/subr.l") sub? (1444 . "@src64/sym.l") sum (1338 . "@src64/apply.l") super (1218 . "@src64/flow.l") -sym (3909 . "@src64/io.l") -sym? (2408 . "@src64/subr.l") -sync (3090 . "@src64/io.l") +sym (3910 . "@src64/io.l") +sym? (2421 . "@src64/subr.l") +sync (3091 . "@src64/io.l") sys (3045 . "@src64/flow.l") t (1748 . "@src64/flow.l") tail (1898 . "@src64/subr.l") -tell (3162 . "@src64/io.l") +tell (3163 . "@src64/io.l") text (1272 . "@src64/sym.l") throw (2488 . "@src64/flow.l") tick (3161 . "@src64/flow.l") -till (3514 . "@src64/io.l") -time (2491 . "@src64/main.l") +till (3515 . "@src64/io.l") +time (2514 . "@src64/main.l") touch (1049 . "@src64/sym.l") trim (1746 . "@src64/subr.l") try (1172 . "@src64/flow.l") type (912 . "@src64/flow.l") udp (268 . "@src64/net.l") -unify (3842 . "@src64/subr.l") +unify (3864 . "@src64/subr.l") unless (1898 . "@src64/flow.l") until (2082 . "@src64/flow.l") up (712 . "@src64/main.l") upp? (3230 . "@src64/sym.l") uppc (3294 . "@src64/sym.l") use (1570 . "@src64/flow.l") -usec (2596 . "@src64/main.l") +usec (2619 . "@src64/main.l") val (1463 . "@src64/sym.l") -version (2981 . "@src64/main.l") -wait (3052 . "@src64/io.l") +version (3004 . "@src64/main.l") +wait (3053 . "@src64/io.l") when (1881 . "@src64/flow.l") while (2058 . "@src64/flow.l") wipe (3090 . "@src64/sym.l") with (1327 . "@src64/flow.l") -wr (5117 . "@src64/io.l") +wr (5119 . "@src64/io.l") xchg (1538 . "@src64/sym.l") xor (1698 . "@src64/flow.l") x| (2871 . "@src64/big.l") diff --git a/src/main.c b/src/main.c @@ -1,4 +1,4 @@ -/* 12oct10abu +/* 16nov10abu * (c) Software Lab. Alexander Burger */ @@ -380,36 +380,48 @@ bool equal(any x, any y) { if (!isSym(y) || !isNum(x = name(x)) || !isNum(y = name(y))) return NO; } + else if (!isCell(y)) + return NO; else { - any a, b; + any a = x, b = y; + bool res = NO; - if (!isCell(y)) - return NO; - while (car(x) == Quote) { - if (car(y) != Quote) - return NO; - if (x == cdr(x)) - return y == cdr(y); - if (y == cdr(y)) - return NO; - if (!isCell(x = cdr(x))) - return equal(x, cdr(y)); - if (!isCell(y = cdr(y))) - return NO; - } - a = x, b = y; for (;;) { if (!equal(car(x), car(y))) - return NO; - if (!isCell(x = cdr(x))) - return equal(x, cdr(y)); - if (!isCell(y = cdr(y))) - return NO; - if (x == a) - return y == b; - if (y == b) - return NO; + break; + if (!isCell(cdr(x))) { + res = equal(cdr(x), cdr(y)); + break; + } + if (!isCell(cdr(y))) + break; + *(word*)&car(x) |= 1, x = cdr(x); + *(word*)&car(y) |= 1, y = cdr(y); + if (num(car(x)) & 1 || num(car(y)) & 1) { + for (;;) { + if (a == x) { + res = b == y; + break; + } + if (b == y) { + res = NO; + break; + } + *(word*)&car(a) &= ~1, a = cdr(a); + *(word*)&car(b) &= ~1, b = cdr(b); + } + do { + *(word*)&car(a) &= ~1, a = cdr(a); + *(word*)&car(b) &= ~1, b = cdr(b); + } while (a != x); + return res; + } + } + while (a != x) { + *(word*)&car(a) &= ~1, a = cdr(a); + *(word*)&car(b) &= ~1, b = cdr(b); } + return res; } } } diff --git a/src/pico.h b/src/pico.h @@ -1,4 +1,4 @@ -/* 15oct10abu +/* 16nov10abu * (c) Software Lab. Alexander Burger */ @@ -461,6 +461,7 @@ any doChain(any); any doChar(any); any doChop(any); any doCirc(any); +any doCircQ(any); any doClip(any); any doClose(any); any doCmd(any); diff --git a/src/subr.c b/src/subr.c @@ -1,4 +1,4 @@ -/* 22oct10abu +/* 16nov10abu * (c) Software Lab. Alexander Burger */ @@ -1048,6 +1048,12 @@ any doPair(any x) { return isCell(x = EVAL(car(x)))? x : Nil; } +// (circ? 'any) -> any +any doCircQ(any x) { + x = cdr(x); + return isCell(x = EVAL(car(x))) && (x = circ(x))? x : Nil; +} + // (lst? 'any) -> flg any doLstQ(any x) { x = cdr(x); @@ -1176,41 +1182,50 @@ any doLength(any x) { for (n = 0, c = symChar(name(x)); c; ++n, c = symChar(NULL)); return boxCnt(n); } - n = 1; - while (car(x) == Quote) { - if (x == cdr(x)) - return T; - if (!isCell(x = cdr(x))) - return boxCnt(n); + for (n = 0, y = x;;) { ++n; - } - y = x; - while (isCell(x = cdr(x))) { - if (x == y) + *(word*)&car(y) |= 1; + if (!isCell(y = cdr(y))) { + do + *(word*)&car(x) &= ~1; + while (isCell(x = cdr(x))); + return boxCnt(n); + } + if (num(car(y)) & 1) { + while (x != y) + *(word*)&car(x) &= ~1, x = cdr(x); + do + *(word*)&car(x) &= ~1; + while (y != (x = cdr(x))); return T; - ++n; + } } - return boxCnt(n); } static int size(any x) { int n; any y; - n = 1; - while (car(x) == Quote) { - if (x == cdr(x) || !isCell(x = cdr(x))) - return n; - ++n; - } - for (y = x;;) { - if (isCell(car(x))) - n += size(car(x)); - if (!isCell(x = cdr(x)) || x == y) - break; + for (n = 0, y = x;;) { ++n; + if (isCell(car(y))) + n += size(car(y)); + *(word*)&car(y) |= 1; + if (!isCell(y = cdr(y))) { + do + *(word*)&car(x) &= ~1; + while (isCell(x = cdr(x))); + return n; + } + if (num(car(y)) & 1) { + while (x != y) + *(word*)&car(x) &= ~1, x = cdr(x); + do + *(word*)&car(x) &= ~1; + while (y != (x = cdr(x))); + return n; + } } - return n; } // (size 'any) -> cnt diff --git a/src/tab.c b/src/tab.c @@ -1,4 +1,4 @@ -/* 30sep10abu +/* 16nov10abu * (c) Software Lab. Alexander Burger */ @@ -75,6 +75,7 @@ static symInit Symbols[] = { {doChain, "chain"}, {doChop, "chop"}, {doCirc, "circ"}, + {doCircQ, "circ?"}, {doClip, "clip"}, {doClose, "close"}, {doCmd, "cmd"}, diff --git a/src64/glob.l b/src64/glob.l @@ -1,4 +1,4 @@ -# 12oct10abu +# 16nov10abu # (c) Software Lab. Alexander Burger (data 'Globals 0) @@ -433,6 +433,7 @@ initSym NIL "min" doMin initSym NIL "atom" doAtom initSym NIL "pair" doPair + initSym NIL "circ?" doCircQ initSym NIL "lst?" doLstQ initSym NIL "num?" doNumQ initSym NIL "sym?" doSymQ diff --git a/src64/io.l b/src64/io.l @@ -1,4 +1,4 @@ -# 07oct10abu +# 16nov10abu # (c) Software Lab. Alexander Burger # Close file descriptor @@ -919,7 +919,8 @@ push Y ld B BEG # Begin list call (PutBinBZ) - call circE_XYF # Circular list? + ld X E # Keep list in X + call circE_YF # Circular? if nz # No do ld E (X) # Next item @@ -4787,7 +4788,8 @@ push Y ld B (char "(") # Open paren call (PutB) - call circE_XYF # Circular list? + ld X E # Keep list in X + call circE_YF # Circular? if nz # No do ld E (X) # Print CAR diff --git a/src64/main.l b/src64/main.l @@ -1,4 +1,4 @@ -# 07oct10abu +# 16nov10abu # (c) Software Lab. Alexander Burger ### Global return labels ### @@ -756,8 +756,7 @@ pop X ret -(code 'circE_XYF) - ld X E # Return list in X +(code 'circE_YF) ld Y E # Keep list in Y do or (E) 1 # Mark @@ -836,60 +835,84 @@ end atom E # E atomic? jnz ret # Yes: 'ne' + push X + push Y + ld X A # Keep list heads + ld Y E do - cmp (A) Quote # A quoted? - while eq # Yes - cmp (E) Quote # E also quoted? - jnz ret # No: 'ne' - cmp A (A CDR) # A circular? - if eq # Yes - cmp E (E CDR) # Check if E also circular - ret - end - cmp E (E CDR) # E circular? - jz retnz # Yes: 'ne' - ld A (A CDR) # Next cells - ld E (E CDR) - atom A # Any? - jnz equalAE_F # No: Compare with E's CDR - atom E - jnz ret # No: 'ne' - loop - push A # Save list heads - push E - do - push (A CDR) # Save CDRs - push (E CDR) - ld A (A) # Recurse on CARs - ld E (E) + push A # Save lists + push E cmp S (StkLimit) # Stack check jlt stkErr + ld A (A) # Recurse on CARs + ld E (E) call equalAE_F # Equal? - pop E # Retrieve CDRs + pop E # Retrieve lists pop A break ne # No: 'ne' - atom A # A's CDR atomic? + atom (A CDR) # A's CDR atomic? if nz # Yes - cmp S (StkLimit) # Stack check - jlt stkErr + push A # Save lists + push E + ld A (A CDR) # Recurse on CDRs + ld E (E CDR) call equalAE_F # Compare with E's CDR + pop E # Retrieve lists + pop A break T end - atom E # E's CDR atomic? + atom (E CDR) # E's CDR atomic? break nz # Yes: 'ne' - cmp A (S I) # A circular? - if eq # Yes - cmp E (S) # Return whether E is also circular - break T - end - cmp E (S) # E circular? - if eq # Yes - clrz - break T # Yes: 'ne' + or (A) 1 # Mark + ld A (A CDR) + or (E) 1 + ld E (E CDR) + test (A) 1 # Detected circularity? + jnz 10 # Yes + test (E) 1 + if nz +10 do + cmp X A # Skip non-circular parts + if eq # Done? + cmp Y E # Set result + break T + end + cmp Y E + if eq + clrz # Result "No" + break T + end + off (X) 1 # Unmark + ld X (X CDR) + off (Y) 1 + ld Y (Y CDR) + loop + push F # Save result + do + off (X) 1 # Unmark circular part + ld X (X CDR) + off (Y) 1 + ld Y (Y CDR) + cmp X A + until eq + pop F # Get result + pop Y + pop X + ret end loop - pop A # Drop list heads - pop A + push F # Save result + do + cmp X A # Skip non-circular part + while ne + off (X) 1 # Unmark + ld X (X CDR) + off (Y) 1 + ld Y (Y CDR) + loop + pop F # Get result + pop Y + pop X ret (code 'compareAE_F 0) # C diff --git a/src64/subr.l b/src64/subr.l @@ -1,4 +1,4 @@ -# 10jun10abu +# 16nov10abu # (c) Software Lab. Alexander Burger # (car 'var) -> any @@ -2385,6 +2385,19 @@ jnz retNil # Yes ret +# (circ? 'any) -> any +(code 'doCircQ 2) + ld E ((E CDR)) # Get arg + eval # Eval it + atom E # Atom? + jnz retNil # Yes + push Y + call circE_YF # Circular? + ldz E Y # Yes + ldnz E Nil + pop Y + ret + # (lst? 'any) -> flg (code 'doLstQ 2) ld E ((E CDR)) # Get arg @@ -2695,33 +2708,39 @@ end sym E # Symbol? if z # No (list) - push X - push Y - ld X E # List in X - ld E ONE # Counter + ld C E # Keep list in C + ld A ONE # Init counter do - cmp X Quote - while eq - ld Y (X CDR) # Next cell - cmp Y X # Circular? - jz lengthT # Yes - ld X Y - atom X # Done? - jnz 10 # Yes - add E (hex "10") # Increment counter - loop - ld Y X # Keep list head - do - ld X (X CDR) # Next cell - atom X # Any? - while z # Yes - cmp X Y # Hit head? - jz lengthT # Yes - add E (hex "10") # Increment counter + or (E) 1 # Mark + ld E (E CDR) # Normal list? + atom E + if nz # Yes + do + off (C) 1 # Unmark + ld C (C CDR) + atom C # Done? + until nz # Yes + ld E A # Get count + ret # Return length + end + test (E) 1 # Detected circularity? + if nz # Yes + do + cmp C E # Skip non-circular part + while ne + off (C) 1 # Unmark + ld C (C CDR) + loop + do + off (C) 1 # Unmark circular part + ld C (C CDR) + cmp C E # Done? + until eq # Yes + ld E TSym + ret # Return T + end + add A (hex "10") # Increment counter loop -10 pop Y - pop X - ret end # Symbol cmp E Nil # NIL? @@ -2742,12 +2761,6 @@ pop X ret -: lengthT - ld E TSym # Return T - pop Y - pop X - ret - # (size 'any) -> cnt (code 'doSize 2) push X @@ -2870,20 +2883,9 @@ ret (code 'sizeCE_C 0) - add C (hex "10") # Increment count + push E # Save list do - cmp (E) Quote # CAR is 'quote'? - while eq # Yes - cmp E (E CDR) # Circular? - jeq ret # Yes - ld E (E CDR) # More cells? - atom E - jnz ret # No add C (hex "10") # Increment count - loop - push X - ld X E # Keep head in X - do atom (E) # Is CAR a cell? if z # Yes push E @@ -2893,15 +2895,35 @@ call sizeCE_C pop E end - ld E (E CDR) # More cells? + or (E) 1 # Mark + ld E (E CDR) # Normal list? atom E - while z # Yes - cmp E X # Circular? - while ne # No - add C (hex "10") # Increment count + if nz # Yes + pop E # Get original list + do + off (E) 1 # Unmark + ld E (E CDR) + atom E # Done? + until nz # Yes + ret + end + test (E) 1 # Detected circularity? + if nz # Yes + pop A # Get original list + do + cmp A E # Skip non-circular part + while ne + off (A) 1 # Unmark + ld A (A CDR) + loop + do + off (A) 1 # Unmark circular part + ld A (A CDR) + cmp A E # Done? + until eq # Yes + ret + end loop - pop X - ret # (assoc 'any 'lst) -> lst (code 'doAssoc 2) diff --git a/src64/version.l b/src64/version.l @@ -1,6 +1,6 @@ -# 15nov10abu +# 16nov10abu # (c) Software Lab. Alexander Burger -(de *Version 3 0 4 8) +(de *Version 3 0 4 9) # vi:et:ts=3:sw=3 diff --git a/test/src/subr.l b/test/src/subr.l @@ -1,4 +1,4 @@ -# 07nov09abu +# 16nov10abu # (c) Software Lab. Alexander Burger ### c[ad]*r ### @@ -228,6 +228,7 @@ (test T (= "a" "a")) (test T (== "a" "a")) (test T (= (1 (2) 3) (1 (2) 3))) +(test T (= (1 . (2 3 .)) (1 . (2 3 .)))) ### <> ### @@ -305,6 +306,12 @@ (test (1 2 3) (pair (1 2 3))) +### circ? ### +(test NIL (circ? 'a)) +(test NIL (circ? (1 2 3))) +(test (2 3 . @) (circ? (1 . (2 3 .)))) + + ### lst? ### (test T (lst? NIL)) (test NIL (lst? T)) @@ -383,6 +390,7 @@ (test 3 (length 123)) (test 3 (length (1 (2) 3))) (test T (length (1 2 3 .))) +(test T (length (1 . (2 3 .)))) ### size ### @@ -394,6 +402,7 @@ (test 3 (size (1 2 3 .))) (test 8 (size '((1 2 3) (4 5 6)))) (test 6 (size '((1 2 .) (4 5 .)))) +(test 3 (size (1 . (2 3 .)))) ### assoc ###