~eshel/eshellisp

e7441d8e3999a10e306063ca1d4c3a0b6e830c3f — Eshel Yaron 2 years ago 42c97cd
ADDED: basic list processing functions
10 files changed, 110 insertions(+), 20 deletions(-)

M Makefile
M README.md
M prolog/eshellisp/eval.pl
M scheme/base.scm
R lisp/fib.eshellisp => scheme/fib.eshellisp
R lisp/giga.eshellisp => scheme/giga.eshellisp
R lisp/read_eval_write.scm => scheme/read_eval_write.scm
R lisp/repl.scm => scheme/repl.scm
R lisp/undefined.eshellisp => scheme/undefined.eshellisp
M test/suite.scm
M Makefile => Makefile +8 -5
@@ 4,24 4,27 @@ VERSION = $(shell $(PROLOG) -s pack.pl -g "version(V), writeln(V)" -t halt)
SOURCES = $(shell find prolog/ -type f -name '*.pl')


.PHONY: all check install lint pack
.PHONY: all check install lint pack clean

all: $(PACKAGE)

lint:
	$(PROLOG) -q -g "use_module(library(diagnostics))" -t halt -- prolog/$(PACKAGE)/*.pl
	@$(PROLOG) -q -g "use_module(library(diagnostics))" -t halt -- prolog/$(PACKAGE)/*.pl

check: lint $(PACKAGE)
	./$(PACKAGE) test/suite.scm
	echo "(+ 1 2)" | ./$(PACKAGE) lisp/read_eval_write.scm
	echo "(+ 1 2)" | ./$(PACKAGE) scheme/read_eval_write.scm

$(PACKAGE): $(SOURCES)
	$(PROLOG) --undefined=error -O -o $@ -c prolog/$(PACKAGE)/main.pl
	@$(PROLOG) --undefined=error -O -o $@ -c prolog/$(PACKAGE)/main.pl

pack: $(PACKAGE)-$(VERSION).zip

$(PACKAGE)-$(VERSION).zip: $(SOURCES)
	zip -r $@ pack.pl prolog README.md LICENSE
	zip -r $@ pack.pl prolog README.md LICENSE Makefile test

install:
	true

clean:
	rm $(PACKAGE) $(PACKAGE)-$(VERSION).zip

M README.md => README.md +67 -1
@@ 1,7 1,73 @@
# eshellisp
[![builds.sr.ht status](https://builds.sr.ht/~eshel/eshellisp.svg)](https://builds.sr.ht/~eshel/eshellisp?)

Lisp interpreter implemented as a SWI-Prolog `pack`.
A Scheme Lisp interpreter implemented in SWI-Prolog.

## Building

Run `make` to build the `eshellisp` interpreter:

```sh
$ make
% Disabled autoloading (loaded 34 files)
% Disabled autoloading (loaded 20 files)
% Disabled autoloading (loaded 0 files)

$ ./eshellisp -h
eshellisp [-h] PATH
--help  -h  boolean=false  Print usage information
```

## Usage

Simply point `eshellisp` at a Scheme file to run it:

```sh
$ cat scheme/repl.scm
(define repl () (write (eval (read))) (repl))
(repl)

$ ./eshellisp scheme/repl.scm
% (+ 1 2)
% 3
% (cdr '(a . (b . (c . d))))
% (b c . d)
% (define ++ (n) (+ 1 n))
% '++
% (++ (++ 0))
% 2
% (eval '(++ (- 1)))
% 0
% ^C^C
```

## Testing

$ make check
./eshellisp test/suite.scm
% (#t . #t)
% (#f . #f)
% ('#f . #f)
% ((not #t) . #f)
% ((not 3) . #f)
% ((boolean=? #t #t) . #t)
% ((boolean=? #t #f) . #f)
% ('(a b c d) a b c d)
% ('(a b c . d) a b c . d)
% ((pair? '(a . b)) . #t)
% ((pair? '(a b c)) . #t)
% ((pair? '()) . #f)
% ((cons 'a '()) a)
% ((cons '(a) '(b c d)) (a) b c d)
% ((cons 'a 3) a . 3)
% ((cons '(a b) 'c) (a b) . c)
% ((car '(a b c)) . a)
% ((car '((a) b c d)) a)
% ((car '(1 . 2)) . 1)
% ((cdr '((a) b c d)) b c d)
% ((cdr '(1 . 2)) . 2)
echo "(+ 1 2)" | ./eshellisp scheme/read_eval_write.scm
% ((eval (read)) . 3)

## Contributing


M prolog/eshellisp/eval.pl => prolog/eshellisp/eval.pl +8 -0
@@ 104,6 104,14 @@ primitive('read',   []    , O) :- !, read_form(O).
primitive('eval',   [O]   , R) :- !, evaluate_form(O, R).
primitive('write',  [O]   , '#t') :- !, write_form(O).
primitive('raise',  [O]   , exception(O)) :- !.
primitive('pair?',  [[_|_]], '#t') :- !.
primitive('pair?',  [_]   , '#f') :- !.
primitive('cons',   [H,T] , [H|T]) :- !.
primitive('car',    [[H|_]] , H) :- !.
primitive('car',    [O] , exception(no_cons(O))) :- !.
primitive('cdr',    [[_|T]] , T) :- !.
primitive('cdr',    [O] , exception(no_cons(O))) :- !.



sub_layout(_, dynamic, dynamic) :- !.

M scheme/base.scm => scheme/base.scm +4 -4
@@ 10,7 10,7 @@
(define boolean=? (a b)
  (equal? (->boolean a) (->boolean b)))

(define test (t l r)
  (if (equal? l r)
      (write t)
      (raise t)))
(define test (l r)
  (if (equal? (eval l) r)
      (write (cons l r))
      (raise (cons l r))))

R lisp/fib.eshellisp => scheme/fib.eshellisp +0 -0
R lisp/giga.eshellisp => scheme/giga.eshellisp +0 -0
R lisp/read_eval_write.scm => scheme/read_eval_write.scm +2 -1
@@ 1,2 1,3 @@
(import (scheme base))
(test 'read-eval (eval (read)) 3)

(test '(eval (read)) 3)

R lisp/repl.scm => scheme/repl.scm +0 -0
R lisp/undefined.eshellisp => scheme/undefined.eshellisp +0 -0
M test/suite.scm => test/suite.scm +21 -9
@@ 1,11 1,23 @@
(import (scheme base))

(test '#t #t #t)
(test '#f #f #f)
(test ''#f '#f #f)
(test '(not #t) (not #t) #f)
(test '(not 3) (not 3) #f)
(test '(boolean=? #t #t) (boolean=? #t #t) #t)
(test '(boolean=? #t #t) (boolean=? #t #f) #f)
(test 'dotted-proper-list '(a . (b . (c . (d . ())))) '(a b c d))
(test 'dotted-non-proper-list '(a b c . d) '(a . (b . (c . d))))
(test '#t #t)
(test '#f #f)
(test ''#f #f)
(test '(not #t) #f)
(test '(not 3) #f)
(test '(boolean=? #t #t) #t)
(test '(boolean=? #t #f) #f)
(test ''(a . (b . (c . (d . ())))) '(a b c d))
(test ''(a b c . d) '(a . (b . (c . d))))
(test '(pair? '(a . b)) #t)
(test '(pair? '(a b c)) #t)
(test '(pair? '()) #f)
(test '(cons 'a '()) '(a))
(test '(cons '(a) '(b c d)) '((a) b c d))
(test '(cons 'a 3) '(a . 3))
(test '(cons '(a b) 'c) '((a b) . c))
(test '(car '(a b c)) 'a)
(test '(car '((a) b c d)) '(a))
(test '(car '(1 . 2)) 1)
(test '(cdr '((a) b c d)) '(b c d))
(test '(cdr '(1 . 2)) 2)