### This is an interpreter of the Unlambda language, written in the ### same language. ### Copyright (C) 2001 by rjan Johansen ### This program is free software; you can redistribute it and/or modify ### it under the terms of the GNU General Public License as published by ### the Free Software Foundation; either version 2 of the License, or ### (at your option) any later version. ### This program is distributed in the hope that it will be useful, ### but WITHOUT ANY WARRANTY; without even the implied warranty of ### MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ### GNU General Public License for more details. ### You should have received a copy of the GNU General Public License ### along with this program; if not, write to the Free Software ### Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #### Put it all together # `c ^q ```si`k $q ``$P $q `$R $q # = `c``s``s`k`sik``s$P$R `c ``s ``s`k `s i k ``s #### Parse function # $P # ^q -> `$K`$Q$q # = ``s`k$K$Q ``s`k # $K # Turn function recursive # ^f -> ```sii ^p `$f`d`$p$p ``s`k ``sii ``s ``s`k s k `k ``s`k d ``sii # $Q # Read character before operator lookup # ^q -> ^p ^r ```$O $q $p `$r $r # = ^q -> ^p ^r ```si `k`$r $r ``$O $q $p # ~ ``s`k`s`k`s``s`k`si``s`kk``sii``s`k`s`kk$O ``s`k `s`k `s ``s`k `si ``s`k k ``sii ``s`k `s `kk # $O # Look up and apply operator rule # ^q ^p ^r ````c ^c `$L $c $q $p $r # = ``s`k`s`kd``s`kd```si`ki``s`kc`k$L ``s`k `s `k d ``s`k d ```si `ki # De-optimized to ensure $L is only evaluated once `s ``s `k c `k ### Operator lookup table # $L # cont -> throw back rule for current character from list, or # an error raising rule. # Apply list builder to i, table, and default action. ` ```````````````````````````````````` ` # Apply $S 18 times to i. ````s``s`ks``s`kk ``s``s`kski ```s``s`kski ```s``s`kski ``s``s`kski # $S # Generate list builder $p recursively # ^p -> ^f -> ^k ^r -> `$p ```$C $f $k $r # ~ ``s``s`ks``s`kk``s`ks``s`kk``s`ksk`k$C ``s ``s`k s ``s`k k ``s`k s ``s`k k ``s`k s k `k # $C # Generate list propagator function $f recursively # ^f ^k ^r -> ^l `$f ```$B $k $r $l # ~ ``s``s`ks``s`kk``s`ks``s`kk``s`ksk`k$B ``s ``s`k s ``s`k k ``s`k s ``s`k k ``s`k s k `k # $B # Add data to list $l # ^k ^r ^l -> ^c `$l ``k $c ```$k i $c $r ``s`k `s `k `s ``s`k s k ``s`k `s `k k ``s`k `s `k `s k ``s ``s`k s ``s`k k ``s`k s ``s`k d ``s i `k i `k k # Trivial list builder # ^f ^l -> `$f $l i # Trivial list propagator function # ^l $l i ### Rules for operators: # quit-parsing parse-expression require-char -> # (quit-running -> evaluated expression) ?` # ^q ^p ^r ``s`$p$r`$p$r `k ``s ``s`k s `s`k s i # whitespace ? `k i ? `k i ? `k i ? `k i ?# # ^q ^p ^r `$p `... $r `k ``s ``s`k s k `k # require-char -> ignore-to-eol # ^r `c ^c ```sii ^l `$l ``k $l ```? # `$ri $c $r # = ^r `c ^c ```sii # ``s i # ``s k # `d`k ```? # `$ri $c $r # = ^r `c ``s`k ``sii # ``s`k `si # ``s`k `sk # ``s`k d # ``s`k k # ``s # `d `? # `$ri # `k $r ``s`k c ``s`k `s`k ``sii ``s`k `s`k `si ``s`k `s`k `sk ``s`k `s`k d ``s`k `s`k k ``s ``s`k s ``s`k d ``s`k ? ``s i `k i k ?k `k`k`k`k k ?s `k`k`k`k s ?i `k`k`k`k i ?v v ?c `k`k`k`k c ?d `k`k`k`k d ?. # ^q ^p ^r `| `$r k `k `k ``s`k | ``si `kk ?r `k`k`k`k r ?e # ^q ^p ^r -> ^e $e `k`k`k i ?@ `k`k`k`k @ ?| `k`k`k`k | ## ? is the most complicated operator. ?? # ^q ^p ^r ``c ^c `$L `$r $c $q # = ^q ^p ^r ```si `k $q `c ^c `$L `$r $c # = ``s`kk``s``s`ks``s`kk``s`k`sik`k``s`kc`s`k$L ``s`k k ``s ``s`k s ``s`k k ``s`k `s i k `k ``s`k c `s `k # $L # cont -> throw back ^q `k ?x for current character from list, or # ^q ...raise error... # Apply list builder to i, table, and default action. ` ```````````````` ```````````````````````````````````````````````` ```````````````````````````````````````````````````````````````` ```````````````````````````````````````````````````````````````` ```````````````````````````````````````````````````````````````` ` # Apply $S 256 times to i. `` ```s``s`kski ```s``s`kski ```s``s`kski ``s``s`kski # $S # Generate list builder $p recursively # ^p -> ^f ^k -> `$p ``$C $f $k # ~ ``s``s`ks``s`kk``s`ksk`k$C ``s ``s`k s ``s`k k ``s`k s k `k # $C # ^f ^k -> ^l `$f ``$B $k $l # Generate list propagator function $f recursively # ~ ``s``s`ks``s`kk``s`ksk`k$B ``s ``s`k s ``s`k k ``s`k s k `k # $B # Add data to list $l # ^k ^l -> ^c `$l ``k $c ```$k i $c `$T $k # ~ ``s`k`s``s`ksk``s`kd``s`kk``s`k`sk``s``s`ks``s`kd``si`ki``s`kk$T ``s`k `s ``s`k s k ``s`k d ``s`k k ``s`k `s k ``s ``s`k s ``s`k d ``s i `k i ``s `k k # $T # ?char -> (quit -> `k ?char) # ^c `k`k$c ``s`k k k # Trivial list builder # ^f ^l -> `$f $l i # Trivial list propagator function # ^l $l i # Character table needed as there is no way to create or simulate ?x # operators not present in the program. # NOTE: Some of the below characters might be interpreted as end of # file in some circumstances. In my version of Netscape, downloading # works but viewing is cut off at the first (NUL) character. See also # the comment at the end of the table. ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?! ?" ?# ?$ ?% ?& ?' ?( ?) ?* ?+ ?, ?- ?. ?/ ?0 ?1 ?2 ?3 ?4 ?5 ?6 ?7 ?8 ?9 ?: ?; ?< ?= ?> ?? ?@ ?A ?B ?C ?D ?E ?F ?G ?H ?I ?J ?K ?L ?M ?N ?O ?P ?Q ?R ?S ?T ?U ?V ?W ?X ?Y ?Z ?[ ?\ ?] ?^ ?_ ?` ?a ?b ?c ?d ?e ?f ?g ?h ?i ?j ?k ?l ?m ?n ?o ?p ?q ?r ?s ?t ?u ?v ?w ?x ?y ?z ?{ ?| ?} ?~ ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? # The last character above may catch a bug in the C interpreter, if so # change it to something else. # Default character rule # cont -> throw (quit -> unknown-char-error) # = ^c `$c ^q `$q `... v # = ``si `k ``si `d`k `... v ``si `k ``s i `d`k ````````````````````` .U.n.k.n.o.w.n. .c.h.a.r.a.c.t.e.r.:. `|ir v ## end ? operator # Default operator rule # cont -> throw (^q ^p ^r -> unknown-function-error) # = ^c -> `$c ^q ^p ^r -> `$q `... v # = ``si`k``s`kk``s`kd``s`kk``si`d`k `... v ``si `k ``s`k k ``s`k d ``s`k k ``si `d `k ```````````````````` .U.n.k.n.o.w.n. .f.u.n.c.t.i.o.n.:. `|ir v ### end operator rules #### end parse function #### quit -> (-> require-char) # $R # ^v `^v `$F `$G $v `$H $v # = ``s`k ``s`k $F $G $H ``s`k ``s`k # raise-eof-error-on-false -> require-char # = ^r ^v ``@ $r $v ``s`k d @ # raise-eof-error -> raise-eof-error-on-false # = ^r ^? `c ^c `$r ``$? $c $? ``s`k `s`kc ``s ``s`k s ``s`k k ``s`k s k `k ``ssk # quit -> raise-eof-error # = ^q ^v `$q ``d ... $v ``s ``s`k s k `k `d`````````````````````` .U.n.e.x.p.e.c.t.e.d. .e.n.d. .o.f. .f.i.l.er #### end (quit -> require-char)