Skip to content

Commit

Permalink
Replaced the evaluator from jmc.lisp style to SICP 4.1 style to imple…
Browse files Browse the repository at this point in the history
…ment lexical scope fully
  • Loading branch information
TAKIZAWA Yozo committed Oct 27, 2020
1 parent 1832d79 commit 183fe65
Show file tree
Hide file tree
Showing 9 changed files with 204 additions and 277 deletions.
370 changes: 148 additions & 222 deletions jmclisp.sh → PureLISP.sh

Large diffs are not rendered by default.

45 changes: 23 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
[![CC0](http://i.creativecommons.org/p/zero/1.0/88x31.png "CC0")](http://creativecommons.org/publicdomain/zero/1.0/)

# jmclisp.sh
# PureLISP.sh

Hash tag on SNS: [`#jmclisp_sh`](https://twitter.com/hashtag/jmclisp_sh)
Hash tag on SNS: [`#PureLISP_sh`](https://twitter.com/hashtag/PureLISP_sh)

This software is a Pure LISP interpreter written in shell script conformed to POSIX shell,
inspired from
Expand Down Expand Up @@ -34,65 +34,66 @@ Run the script to use REPL, like the following on [busybox-w32](https://frippery
**You must type a blank line after input of LISP codes to eval**.

```
C:\Users\TAKIZAWA Yozo\busybox>busybox.exe sh jmclisp.sh
C:\Users\TAKIZAWA Yozo\busybox>busybox.exe sh PureLISP.sh
S> (def reduce
'(lambda (f L i)
(cond ((eq L nil) i)
(t (f (car L) (reduce f (cdr L) i))))))
(lambda (f L i)
(cond ((eq L nil) i)
(t (f (car L) (reduce f (cdr L) i))))))
reduce
S> (reduce 'cons '(a b c) '(d e f g))
S> (reduce cons (a b c) (d e f g))
(a b c d e f g)
S> (def rappend '(lambda (x y) (reduce 'cons x y)))
S> (def rappend (lambda (x y) (reduce cons x y)))
rappend
S> (reduce 'rappend '((a b) (c d e) (f) (g h i)) '())
S> (reduce rappend ((a b) (c d e) (f) (g h i)) ())
(a b c d e f g h i)
S> exit
C:\Users\TAKIZAWA Yozo\busybox>
```

Or, you can send a text file of LISP codes to jmclisp.sh with "-s" option,
Or, you can send a text file of LISP codes to PureLISP.sh with "-s" option,
prompt suppression mode, via redirection in a shell interpreter.

```
C:\Users\TAKIZAWA Yozo\busybox>busybox.exe sh
~/busybox $ cat examples/fibonacci.jmclisp
~/busybox $ cat examples/fibonacci.plsh
(def append
'(lambda (a b)
(lambda (a b)
(cond ((eq a nil) b)
(t (append (cdr a)
(cons (car a) b))))))
(def fib
'(lambda (n)
(lambda (n)
(cond ((eq n '()) '())
((eq (cdr n) '()) '(0))
(t (append (fib (cdr n))
(fib (cdr (cdr n))))))))
(def ten '(0 0 0 0 0 0 0 0 0 0))
(cons '(fib ten) (cons '= (cons (length (fib ten)) nil)))
(cons '(fib ten) (cons '=
(cons (length (fib ten)) nil)))
(def fib2
'(lambda (n f1 f2)
(cond ((eq n '()) f1)
(lambda (n f1 f2)
(cond ((eq n nil) f1)
(t (fib2 (cdr n) f2 (append f1 f2))))))
(def zero '())
(def one '(0))
(cons '(fib2 ten zero one) (cons '= (cons (length (fib2 ten zero one)))))
(cons '(fib2 ten zero one) (cons '=
(cons (length (fib2 ten zero one)) nil)))
exit
~/busybox $ sh jmclisp.sh -s < examples/fibonacci.jmclisp
~/busybox $ sh PureLISP.sh -s < examples/fibonacci.plsh
append
fib
ten
Expand All @@ -110,7 +111,7 @@ C:\Users\TAKIZAWA Yozo\busybox>

* Built-in functions in Pure LISP: `cons`, `car`, `cdr`, `atom`, `eq`
* Built-in functions not in Pure LISP: `length` to treat lists as numbers
* Special forms: `quote`, `cond` and lexically scoped `lambda` (closure not yet)
* Special forms: `quote`, `cond` and lexically scoped `lambda`
* Special form `def` to bind variables in global environment with quoted values
* Simple S-expression input and output functions
* Simple REPL with `exit` command and `-s` prompt suppression mode
Expand All @@ -119,13 +120,13 @@ C:\Users\TAKIZAWA Yozo\busybox>

* Conscells are firstly implemented to program as a metacircular evaluator
* Pseudo-Array and Stack implementation by using gloval variables
* Using pattern-matching to do S-expression lexical analysis especially
* Using pattern-matching, to do S-expression lexical analysis especially

## Bugs and TODO

* Introducing tail call optimization
* More suitable error checks
* Much comment
* Much more comments in the source code

## License

Expand Down
2 changes: 1 addition & 1 deletion examples/assoc.jmclisp → examples/assoc.plsh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
(def or (lambda (a b) (cond (a t) (t b))))
(def or (lambda (x y) (cond (x t) (t y))))

(def mkassoc
(lambda (a b)
Expand Down
18 changes: 9 additions & 9 deletions examples/fibonacci-times.sh
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
#!/bin/sh

if [ ! $# = 3 ]; then
printf "Usage: $0 SHELL JMCLISP NUM\n"
printf "Usage: $0 SHELL LISP NUM\n"
printf "Now using default settings\n"
SHL="dash"
JMCLISP="./jmclisp.sh"
LISP="PureLISP.sh"
COUNT=10
else
SHL=$1
JMCLISP=$2
LISP=$2
COUNT=$3
fi

Expand All @@ -21,7 +21,7 @@ do
done

COMMON="(def append
'(lambda (a b)
(lambda (a b)
(cond ((eq a nil) b)
(t (append (cdr a)
(cons (car a) b))))))
Expand All @@ -35,7 +35,7 @@ COMMON="(def append
"

FIB1="(def fib
'(lambda (n)
(lambda (n)
(cond ((eq n '()) '())
((eq (cdr n) '()) '(0))
(t (append (fib (cdr n))
Expand All @@ -48,7 +48,7 @@ exit
"

FIB2="(def fib2
'(lambda (n f1 f2)
(lambda (n f1 f2)
(cond ((eq n '()) f1)
(t (fib2 (cdr n) f2 (append f1 f2))))))
Expand All @@ -58,10 +58,10 @@ exit
"

printf "(fibonacci $COUNT) processing time test on $SHL $JMCLISP\n\n"
printf "(fibonacci $COUNT) processing time test on $SHL $LISP\n\n"
date
printf "%s%s" "$COMMON" "$FIB1" | $SHL $JMCLISP -s
printf "%s%s" "$COMMON" "$FIB1" | $SHL $LISP -s
date
printf "%s%s" "$COMMON" "$FIB2" | $SHL $JMCLISP -s
printf "%s%s" "$COMMON" "$FIB2" | $SHL $LISP -s
date

14 changes: 8 additions & 6 deletions examples/fibonacci.jmclisp → examples/fibonacci.plsh
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
(def append
'(lambda (a b)
(lambda (a b)
(cond ((eq a nil) b)
(t (append (cdr a)
(cons (car a) b))))))

(def fib
'(lambda (n)
(lambda (n)
(cond ((eq n '()) '())
((eq (cdr n) '()) '(0))
(t (append (fib (cdr n))
(fib (cdr (cdr n))))))))

(def ten '(0 0 0 0 0 0 0 0 0 0))

(cons '(fib ten) (cons '= (cons (length (fib ten)) nil)))
(cons '(fib ten) (cons '=
(cons (length (fib ten)) nil)))

(def fib2
'(lambda (n f1 f2)
(cond ((eq n '()) f1)
(lambda (n f1 f2)
(cond ((eq n nil) f1)
(t (fib2 (cdr n) f2 (append f1 f2))))))

(def zero '())

(def one '(0))

(cons '(fib2 ten zero one) (cons '= (cons (length (fib2 ten zero one)) nil)))
(cons '(fib2 ten zero one) (cons '=
(cons (length (fib2 ten zero one)) nil)))

exit

4 changes: 2 additions & 2 deletions examples/filter.jmclisp → examples/filter.plsh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(def filter
'(lambda (f x)
(lambda (f x)
(cond ((eq x nil) nil)
((f (car x))
(cons (car x) (filter f (cdr x))))
Expand All @@ -10,7 +10,7 @@

(cons '= (cons vs nil))

(def ch '(lambda (x) (eq (car x) 'o)) vs)
(def ch (lambda (x) (eq (car x) 'o)) vs)

(cons '= (cons ch nil))

Expand Down
6 changes: 2 additions & 4 deletions examples/lexicalscope.jmclisp → examples/lexicalscope.plsh
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,11 @@

(def func1 (lambda () (cons x x)))

(func1)

(def func2 (lambda (x) (func1)))

(cons
(func2 '20)
(cons '(= must be (10 . 10) in lexical scope) nil))

'(= must be (10 . 10) in lexical scope)

(((((lambda (x) (lambda (y) (lambda (z) (lambda (w)
(cons (cons (cons (cons nil x) y) z) w)))))
Expand Down
10 changes: 5 additions & 5 deletions examples/mapcar.jmclisp → examples/mapcar.plsh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(def mapcar
'(lambda (f x)
(lambda (f x)
(cond ((eq x nil) nil)
(t (cons (f (car x))
(mapcar f (cdr x)))))))
Expand All @@ -8,14 +8,14 @@

(cons '= (cons vs nil))

(def r1 (mapcar 'car vs))
(def r1 (mapcar car vs))

(cons '= (cons '(mapcar 'car vs)
(cons '= (cons '(mapcar car vs)
(cons '= (cons r1 nil))) nil)

(def r2 (mapcar 'cdr vs))
(def r2 (mapcar cdr vs))

(cons '= (cons '(mapcar 'cdr vs)
(cons '= (cons '(mapcar cdr vs)
(cons '= (cons r2 nil))) nil)

exit
Expand Down
12 changes: 6 additions & 6 deletions examples/reduce.jmclisp → examples/reduce.plsh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
(def reduce
'(lambda (f L i)
(lambda (f L i)
(cond ((eq L nil) i)
(t (f (car L) (reduce f (cdr L) i))))))

Expand All @@ -11,22 +11,22 @@

(cons '= (cons list2 nil))

(def r1 (reduce 'cons list1 list2))
(def r1 (reduce cons list1 list2))

(cons '= (cons '(reduce 'cons list1 list2)
(cons '= (cons '(reduce cons list1 list2)
(cons '= (cons r1 nil))))

(def rappend '(lambda (x y) (reduce 'cons x y)))
(def rappend (lambda (x y) (reduce cons x y)))

(cons '= (cons rappend nil))

(def list3 '((a b) (c d e) (f) (g h i)))

(cons '= (cons list3 nil))

(def r2 (reduce 'rappend list3 nil))
(def r2 (reduce rappend list3 nil))

(cons '= (cons '(reduce 'rappend list3 nil)
(cons '= (cons '(reduce rappend list3 nil)
(cons '= (cons r2 nil))))

exit
Expand Down

0 comments on commit 183fe65

Please sign in to comment.