All ready to implement property lists, not yet done.
This commit is contained in:
parent
5ee9531e6b
commit
b61e7c3e8c
16 changed files with 225 additions and 125 deletions
|
|
@ -1,21 +0,0 @@
|
|||
;; see page 70 of Lisp 1.5 Programmers Manual; this expands somewhat
|
||||
;; on the accounts of eval and apply given on page 13. This is M-expr
|
||||
;; syntax, obviously.
|
||||
|
||||
;; apply
|
||||
;; NOTE THAT I suspect there is a typo in the printed manual in line
|
||||
;; 7 of this definition, namely a missing closing square bracket before
|
||||
;; the final semi-colon; that has been corrected here.
|
||||
|
||||
apply[fn;args;a] = [
|
||||
null[fn] -> NIL;
|
||||
atom[fn] -> [get[fn;EXPR] -> apply[expr; args; a];
|
||||
get[fn;SUBR] -> {spread[args];
|
||||
$ALIST := a;
|
||||
TSX subr4, 4};
|
||||
T -> apply[cdr[sassoc[fn; a; λ[[]; error[A2]]]]; args a]];
|
||||
eq[car[fn]; LABEL] -> apply[caddr[fn]; args;
|
||||
cons[cons[cadr[fn];caddr[fn]]; a]];
|
||||
eq[car[fn]; FUNARG] -> apply[cadr[fn]; args; caddr[fn]];
|
||||
eq[car[fn]; LAMBDA] -> eval[caddr[fn]; nconc[pair[cadr[fn]; args]; a]];
|
||||
T -> apply[eval[fn;a]; args; a]]
|
||||
40
resources/mexpr/apply.mexpr.lsp
Normal file
40
resources/mexpr/apply.mexpr.lsp
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
;; see page 70 of Lisp 1.5 Programmers Manual; this expands somewhat
|
||||
;; on the accounts of eval and apply given on page 13. This is M-expr
|
||||
;; syntax, obviously.
|
||||
|
||||
;; ## APPLY
|
||||
|
||||
;; NOTE THAT I suspect there is a typo in the printed manual in line
|
||||
;; 7 of this definition, namely a missing closing square bracket before
|
||||
;; the final semi-colon; that has been corrected here.
|
||||
|
||||
;; RIGHT! So the 'EXPR' representation of a function is expected to be
|
||||
;; on the `EXPR` property on the property list of the symbol which is
|
||||
;; its name; an expression is simply a Lisp S-Expression as a structure
|
||||
;; of cons cells and atoms in memory. The 'SUBR' representation, expected
|
||||
;; to be on the `SUBR` property, is literally a subroutine written in
|
||||
;; assembly code, so what is happening in the curly braces is putting the
|
||||
;; arguments into processor registers prior to a jump to subroutine - TSX
|
||||
;; being presumably equivalent to a 6502's JSR call.
|
||||
|
||||
;; This accounts for the difference between this statement and the version
|
||||
;; on page 12: that is a pure interpreter, which can only call those host
|
||||
;; functions that are explicitly hard coded in.
|
||||
|
||||
;; This version knows how to recognise subroutines and jump to them, but I
|
||||
;; think that by implication at least this version can only work if it is
|
||||
;; itself compiled with the Lisp compiler, since the section in curly braces
|
||||
;; appears to be intended to be passed to the Lisp assembler.
|
||||
|
||||
;; apply[fn;args;a] = [
|
||||
;; null[fn] -> NIL;
|
||||
;; atom[fn] -> [get[fn;EXPR] -> apply[expr; args; a];
|
||||
;; get[fn;SUBR] -> {spread[args];
|
||||
;; $ALIST := a;
|
||||
;; TSX subr4, 4};
|
||||
;; T -> apply[cdr[sassoc[fn; a; λ[[]; error[A2]]]]; args a]];
|
||||
;; eq[car[fn]; LABEL] -> apply[caddr[fn]; args;
|
||||
;; cons[cons[cadr[fn];caddr[fn]]; a]];
|
||||
;; eq[car[fn]; FUNARG] -> apply[cadr[fn]; args; caddr[fn]];
|
||||
;; eq[car[fn]; LAMBDA] -> eval[caddr[fn]; nconc[pair[cadr[fn]; args]; a]];
|
||||
;; T -> apply[eval[fn;a]; args; a]]
|
||||
|
|
@ -1,7 +1,22 @@
|
|||
;; Not present in Lisp 1.5(!)
|
||||
;; Page 12 of the manual; this does NOT do what I expect a modern
|
||||
;; ASSOC to do!
|
||||
|
||||
;; Modern ASSOC would be:
|
||||
;; assoc[x; l] = [null[l] -> NIL;
|
||||
;; and[consp[car[l]]; eq[caar[l]; x]] -> cdar[l];
|
||||
;; T -> assoc[x; cdr[l]]]
|
||||
|
||||
;; In the Lisp 1.5 statement of ASSOC, there's no account of what should happen
|
||||
;; if the key (here `x`) is not present on the association list `a`. It seems
|
||||
;; inevitable that this causes an infinite run up the stack until it fails with
|
||||
;; stack exhaustion. Consequently this may be right but I'm not implementing it!
|
||||
;; assoc[x; a] = [equal[caar[a]; x] -> car[a];
|
||||
;; T -> assoc[x; cdr[a]]]
|
||||
|
||||
;; Consequently, my solution is a hybrid. It returns the pair from the
|
||||
;; association list, as the original does, but it traps the end of list
|
||||
;; condition, as a modern solution would.
|
||||
|
||||
assoc[x; l] = [null[l] -> NIL;
|
||||
and[consp[car[l]]; eq[caar[l]; x]] -> cdar[l];
|
||||
and[consp[car[l]]; eq[caar[l]; x]] -> car[l];
|
||||
T -> assoc[x; cdr[l]]]
|
||||
|
||||
;; (ASSOC 'C (PAIR '(A B C D E F) (RANGE 1 6)))
|
||||
5
resources/mexpr/pairlis.mexpr.lsp
Normal file
5
resources/mexpr/pairlis.mexpr.lsp
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
;; page 12
|
||||
|
||||
pairlis[x;y;a] = [null[x] -> a;
|
||||
T -> cons[cons[car[x]; car[y]];
|
||||
pairlis[cdr[x]; cdr[y]; a]]]
|
||||
10
resources/mexpr/sublis.mexpr.lsp
Normal file
10
resources/mexpr/sublis.mexpr.lsp
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
;; There are two different statements of SUBLIS and SUB2 in the manual, on
|
||||
;; pages 12 and 61 respectively, although they are said to be semantically
|
||||
;; equivalent; this is the version from page 12.
|
||||
|
||||
sub2[a; z] = [null[a] -> z;
|
||||
eq[caar[a]; z] -> cdar[a];
|
||||
T -> sub2[cdar[a]; z]]
|
||||
|
||||
sublis[a; y] = [atom[y] -> sub2[a; y];
|
||||
T -> cons[]]
|
||||
5
resources/mexpr/subst.mexpr.lsp
Normal file
5
resources/mexpr/subst.mexpr.lsp
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
;; page 11
|
||||
|
||||
subst[x; y; z] = [equal[y; z] -> x;
|
||||
atom[z] -> z;
|
||||
T -> cons[subst[x; y; car[z]]; subst[x; y; cdr[z]]]]
|
||||
Loading…
Add table
Add a link
Reference in a new issue