Skip to content

Instantly share code, notes, and snippets.

@ytaki0801
Created January 21, 2022 18:27
Show Gist options
  • Save ytaki0801/b0d329247581faeecc774dcb516de141 to your computer and use it in GitHub Desktop.
Save ytaki0801/b0d329247581faeecc774dcb516de141 to your computer and use it in GitHub Desktop.
cons () {
eval CAR"$CNUM"="$1"; eval CDR"$CNUM"="$2";
CONSR="$CNUM.conscell"; CNUM="$((CNUM+1))";
}
car () { eval CARR="\$CAR${1%%.conscell}"; }
cdr () { eval CDRR="\$CDR${1%%.conscell}"; }
TRUE=1; FALSE=0; NULL="empty";
pairp () {
case "$1" in (*.conscell) PAIRPR="$TRUE" ;; (*)
PAIRPR="$FALSE" ;; esac
}
eq () {
pairp "$1"; case "$PAIRPR" in ("$TRUE") EQR="$FALSE" ;; (*)
pairp "$2"; case "$PAIRPR" in ("$TRUE") EQR="$FALSE" ;; (*)
case "$1" in ("$2") EQR="$TRUE" ;; (*)
EQR="$FALSE" ;; esac ;; esac ;; esac
}
intp () {
case "${1#[+-]}" in (''|*[!0-9]*) INTPR="$FALSE" ;; (*)
INTPR="$TRUE" ;; esac
}
ls () {
car "$1"; sw "$CARR"; cdr "$1"; local d="$CDRR";
case "$d" in ("$NULL") printf "" ;; (*)
printf " "; ls "$d" ;; esac
}
sw () {
pairp "$1"; case "$PAIRPR" in ("$TRUE") printf "("; ls "$1"; printf ")" ;; (*)
intp "$1"; case "$INTPR" in ("$TRUE") printf "%d" "$1" ;; (*)
printf "$1" ;; esac ;; esac
}
sr_lex () {
local s; read s;
s=`echo $s | sed -r "s/[ ]+/ /g" | sed -e "s/)/ ) /g" | sed -e "s/(/ ( /g"`;
for t in `echo "$s"`; do eval TOKEN"$TNUM"="\$t"; TNUM="$((TNUM+1))"; done;
}
sr_syn0 () {
local t; eval t="\$TOKEN$SPOS";
case "$t" in ("(") SPOS="$((SPOS-1))"; SRSYN0R="$1" ;; (*)
sr_syn; cons "$SRSYNR" "$1"; sr_syn0 "$CONSR" ;; esac
}
sr_syn () {
local t; eval t="\$TOKEN$SPOS"; SPOS="$((SPOS-1))";
case "$t" in (")") sr_syn0 "$NULL"; SRSYNR="$SRSYN0R" ;; (*)
SRSYNR="$t" ;; esac
}
ap () {
eq "$1" "$NULL"; case "$EQR" in ("$TRUE") APR="$2" ;; (*)
cdr "$1"; ap "$CDRR" "$2"; car "$1"; cons "$CARR" "$APR"; APR="$CONSR" ;; esac
}
pm () {
eq "$1" "$NULL"; case "$EQR" in ("$TRUE") PMR="$NULL" ;; (*)
eq "$2" "$NULL"; case "$EQR" in ("$TRUE") PMR="$NULL" ;; (*)
cdr "$1"; local d1="$CDRR"; cdr "$2"; local d2="$CDRR"; pm "$d1" "$d2";
car "$2"; cons "$CARR" "$PMR"; car "$1"; cons "$CARR" "$CONSR";
PMR="$CONSR" ;; esac ;; esac
}
pq () {
eq "$2" "$NULL"; case "$EQR" in ("$TRUE") PQR="$FALSE" ;; (*)
car "$2"; local a="$CARR"; cdr "$2"; local d="$CDRR";
eq "$1" "$a"; case "$EQR" in ("$TRUE") car "$d"; PQR="$CARR" ;; (*)
cdr "$d"; d="$CDRR"; pq "$1" "$d" ;; esac ;; esac
}
sq () {
case "$1" in ("+"|"-"|"eq?"|"cons"|"car"|"cdr") SQR="$1" ;; (*)
pq "$1" "$2"; SQR="$PQR" ;; esac
}
ay () {
car "$2"; local a1="$CARR";
case "$1" in ("+"|"-"|"cons"|"eq?")
cdr "$2"; local a2="$CDRR"; car "$a2"; a2="$CARR";
case "$1" in ("eq?") eq "$a1" "$a2"; AYR="$EQR"
;; ("cons") cons "$a1" "$a2"; AYR="$CONSR"
;; (*) AYR="$(($a1$1$a2))" ;; esac
;; ("car") car "$a1"; AYR="$CARR"
;; ("cdr") cdr "$a1"; AYR="$CDRR" ;; esac
}
evpush () { eval STACK"$SNUM"="$EVR"; SNUM="$((SNUM+1))"; }
evpop () { SNUM="$((SNUM-1))"; eval EVR="\$STACK$SNUM"; }
ea () {
eq "$1" "$NULL"; case "$EQR" in ("$TRUE") EAR="$NULL" ;; (*)
car "$1"; ev "$CARR" "$2"; evpush; cdr "$1"; ea "$CDRR" "$2"; evpop;
cons "$EVR" "$EAR"; EAR="$CONSR" ;; esac
}
ev () {
pairp "$1";
case "$PAIRPR" in ("$TRUE")
car "$1"; local s0="$CARR"; cdr "$1"; local sr="$CDRR";
case "$s0" in ("quote") car "$sr"; EVR="$CARR"
;; ("if")
car "$sr"; local s1="$CARR"; cdr "$sr"; local sr1="$CDRR"; ev "$s1" "$2"
case "$EVR" in ("$TRUE") car "$sr1"; ev "$CARR" "$2" ;; (*)
cdr "$sr1"; local sr2="$CDRR"; car "$sr2"; ev "$CARR" "$2" ;; esac
;; ("lambda") cons "$2" "$NULL"; ap "$1" "$CONSR"; EVR="$APR";
;; (*)
ev "$s0" "$2"; local f="$EVR"; ea "$sr" "$2"; local a="$EAR"; pairp "$f";
case "$PAIRPR" in ("$FALSE") ay "$f" "$a"; EVR="$AYR" ;; (*)
cdr "$f"; local fr1="$CDRR"; car "$fr1"; local f1="$CARR";
cdr "$fr1"; local fr2="$CDRR"; car "$fr2"; local f2="$CARR";
cdr "$fr2"; local fr3="$CDRR"; car "$fr3"; local f3="$CARR";
pm "$f1" "$a"; ap "$PMR" "$f3"; ev "$f2" "$APR" ;; esac ;; esac
;; (*)
intp "$1"; case "$INTPR" in ("$TRUE") EVR="$1" ;; (*)
sq "$1" "$2"; EVR="$SQR" ;; esac ;; esac
}
TNUM=0; sr_lex;
SPOS="$((TNUM-1))"; sr_syn;
SNUM=0; ev "$SRSYNR" "$NULL"; sw "$EVR";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment