summaryrefslogtreecommitdiff
path: root/src/scheme/tiny-test
diff options
context:
space:
mode:
authorKeith Packard <keithp@keithp.com>2017-12-12 15:25:51 -0800
committerKeith Packard <keithp@keithp.com>2017-12-12 15:25:51 -0800
commitd8c9024f3829dc3f241b16869f165f3ee01764f3 (patch)
treeee3038984838551412feeeee5e56c22afe83a99b /src/scheme/tiny-test
parenta15166c435f65cb36f487ec8e5a4ff558a7e0502 (diff)
altos/scheme: Support scheme subsetting via feature settings
This provides for the creation of smaller versions of the interpreter, leaving out options like floating point numbers and vectors. Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src/scheme/tiny-test')
-rw-r--r--src/scheme/tiny-test/.gitignore1
-rw-r--r--src/scheme/tiny-test/Makefile28
-rw-r--r--src/scheme/tiny-test/ao_scheme_os.h72
-rw-r--r--src/scheme/tiny-test/ao_scheme_test.c141
-rw-r--r--src/scheme/tiny-test/ao_scheme_tiny_const.scheme389
5 files changed, 631 insertions, 0 deletions
diff --git a/src/scheme/tiny-test/.gitignore b/src/scheme/tiny-test/.gitignore
new file mode 100644
index 00000000..7c4c3956
--- /dev/null
+++ b/src/scheme/tiny-test/.gitignore
@@ -0,0 +1 @@
+ao-scheme-tiny
diff --git a/src/scheme/tiny-test/Makefile b/src/scheme/tiny-test/Makefile
new file mode 100644
index 00000000..5082df44
--- /dev/null
+++ b/src/scheme/tiny-test/Makefile
@@ -0,0 +1,28 @@
+include ../Makefile-inc
+
+vpath %.o .
+vpath %.c ..
+vpath %.h ..
+
+DEFS=
+
+SRCS=$(SCHEME_SRCS) ao_scheme_test.c
+HDRS=$(SCHEME_HDRS) ao_scheme_const.h
+
+OBJS=$(SRCS:.c=.o)
+
+CFLAGS=-O0 -g -Wall -Wextra -I. -I..
+
+ao-scheme-tiny: $(OBJS)
+ cc $(CFLAGS) -o $@ $(OBJS) -lm
+
+$(OBJS): $(HDRS)
+
+ao_scheme_const.h: ../make-const/ao_scheme_make_const ao_scheme_tiny_const.scheme
+ ../make-const/ao_scheme_make_const -o $@ -d FLOAT,VECTOR,QUASI,BIGINT ao_scheme_tiny_const.scheme
+
+clean::
+ rm -f $(OBJS) ao-scheme-tiny ao_scheme_const.h
+
+install: ao-scheme-tiny
+ cp $^ $$HOME/bin
diff --git a/src/scheme/tiny-test/ao_scheme_os.h b/src/scheme/tiny-test/ao_scheme_os.h
new file mode 100644
index 00000000..7cfe3981
--- /dev/null
+++ b/src/scheme/tiny-test/ao_scheme_os.h
@@ -0,0 +1,72 @@
+/*
+ * Copyright © 2016 Keith Packard <keithp@keithp.com>
+ *
+ * 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; version 2 of the License.
+ *
+ * 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.
+ */
+
+#ifndef _AO_SCHEME_OS_H_
+#define _AO_SCHEME_OS_H_
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+
+#undef AO_SCHEME_FEATURE_FLOAT
+#undef AO_SCHEME_FEATURE_VECTOR
+#undef AO_SCHEME_FEATURE_QUASI
+#undef AO_SCHEME_FEATURE_BIGINT
+
+#define AO_SCHEME_POOL_TOTAL 4096
+#define AO_SCHEME_SAVE 1
+
+extern int ao_scheme_getc(void);
+
+static inline void
+ao_scheme_os_flush() {
+ fflush(stdout);
+}
+
+static inline void
+ao_scheme_abort(void)
+{
+ abort();
+}
+
+static inline void
+ao_scheme_os_led(int led)
+{
+ printf("leds set to 0x%x\n", led);
+}
+
+#define AO_SCHEME_JIFFIES_PER_SECOND 100
+
+static inline void
+ao_scheme_os_delay(int jiffies)
+{
+ struct timespec ts = {
+ .tv_sec = jiffies / AO_SCHEME_JIFFIES_PER_SECOND,
+ .tv_nsec = (jiffies % AO_SCHEME_JIFFIES_PER_SECOND) * (1000000000L / AO_SCHEME_JIFFIES_PER_SECOND)
+ };
+ nanosleep(&ts, NULL);
+}
+
+static inline int
+ao_scheme_os_jiffy(void)
+{
+ struct timespec tp;
+ clock_gettime(CLOCK_MONOTONIC, &tp);
+ return tp.tv_sec * AO_SCHEME_JIFFIES_PER_SECOND + (tp.tv_nsec / (1000000000L / AO_SCHEME_JIFFIES_PER_SECOND));
+}
+
+#endif
diff --git a/src/scheme/tiny-test/ao_scheme_test.c b/src/scheme/tiny-test/ao_scheme_test.c
new file mode 100644
index 00000000..45068369
--- /dev/null
+++ b/src/scheme/tiny-test/ao_scheme_test.c
@@ -0,0 +1,141 @@
+/*
+ * Copyright © 2016 Keith Packard <keithp@keithp.com>
+ *
+ * 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.
+ */
+
+#include "ao_scheme.h"
+#include <stdio.h>
+
+static FILE *ao_scheme_file;
+static int newline = 1;
+
+static char save_file[] = "scheme.image";
+
+int
+ao_scheme_os_save(void)
+{
+ FILE *save = fopen(save_file, "w");
+
+ if (!save) {
+ perror(save_file);
+ return 0;
+ }
+ fwrite(ao_scheme_pool, 1, AO_SCHEME_POOL_TOTAL, save);
+ fclose(save);
+ return 1;
+}
+
+int
+ao_scheme_os_restore_save(struct ao_scheme_os_save *save, int offset)
+{
+ FILE *restore = fopen(save_file, "r");
+ size_t ret;
+
+ if (!restore) {
+ perror(save_file);
+ return 0;
+ }
+ fseek(restore, offset, SEEK_SET);
+ ret = fread(save, sizeof (struct ao_scheme_os_save), 1, restore);
+ fclose(restore);
+ if (ret != 1)
+ return 0;
+ return 1;
+}
+
+int
+ao_scheme_os_restore(void)
+{
+ FILE *restore = fopen(save_file, "r");
+ size_t ret;
+
+ if (!restore) {
+ perror(save_file);
+ return 0;
+ }
+ ret = fread(ao_scheme_pool, 1, AO_SCHEME_POOL_TOTAL, restore);
+ fclose(restore);
+ if (ret != AO_SCHEME_POOL_TOTAL)
+ return 0;
+ return 1;
+}
+
+int
+ao_scheme_getc(void)
+{
+ int c;
+
+ if (ao_scheme_file)
+ return getc(ao_scheme_file);
+
+ if (newline) {
+ if (ao_scheme_read_list)
+ printf("+ ");
+ else
+ printf("> ");
+ newline = 0;
+ }
+ c = getchar();
+ if (c == '\n')
+ newline = 1;
+ return c;
+}
+
+int
+main (int argc, char **argv)
+{
+ (void) argc;
+
+ while (*++argv) {
+ ao_scheme_file = fopen(*argv, "r");
+ if (!ao_scheme_file) {
+ perror(*argv);
+ exit(1);
+ }
+ ao_scheme_read_eval_print();
+ fclose(ao_scheme_file);
+ ao_scheme_file = NULL;
+ }
+ ao_scheme_read_eval_print();
+
+#ifdef DBG_MEM_STATS
+ printf ("collects: full: %lu incremental %lu\n",
+ ao_scheme_collects[AO_SCHEME_COLLECT_FULL],
+ ao_scheme_collects[AO_SCHEME_COLLECT_INCREMENTAL]);
+
+ printf ("freed: full %lu incremental %lu\n",
+ ao_scheme_freed[AO_SCHEME_COLLECT_FULL],
+ ao_scheme_freed[AO_SCHEME_COLLECT_INCREMENTAL]);
+
+ printf("loops: full %lu incremental %lu\n",
+ ao_scheme_loops[AO_SCHEME_COLLECT_FULL],
+ ao_scheme_loops[AO_SCHEME_COLLECT_INCREMENTAL]);
+
+ printf("loops per collect: full %f incremental %f\n",
+ (double) ao_scheme_loops[AO_SCHEME_COLLECT_FULL] /
+ (double) ao_scheme_collects[AO_SCHEME_COLLECT_FULL],
+ (double) ao_scheme_loops[AO_SCHEME_COLLECT_INCREMENTAL] /
+ (double) ao_scheme_collects[AO_SCHEME_COLLECT_INCREMENTAL]);
+
+ printf("freed per collect: full %f incremental %f\n",
+ (double) ao_scheme_freed[AO_SCHEME_COLLECT_FULL] /
+ (double) ao_scheme_collects[AO_SCHEME_COLLECT_FULL],
+ (double) ao_scheme_freed[AO_SCHEME_COLLECT_INCREMENTAL] /
+ (double) ao_scheme_collects[AO_SCHEME_COLLECT_INCREMENTAL]);
+
+ printf("freed per loop: full %f incremental %f\n",
+ (double) ao_scheme_freed[AO_SCHEME_COLLECT_FULL] /
+ (double) ao_scheme_loops[AO_SCHEME_COLLECT_FULL],
+ (double) ao_scheme_freed[AO_SCHEME_COLLECT_INCREMENTAL] /
+ (double) ao_scheme_loops[AO_SCHEME_COLLECT_INCREMENTAL]);
+#endif
+}
diff --git a/src/scheme/tiny-test/ao_scheme_tiny_const.scheme b/src/scheme/tiny-test/ao_scheme_tiny_const.scheme
new file mode 100644
index 00000000..d0c0e578
--- /dev/null
+++ b/src/scheme/tiny-test/ao_scheme_tiny_const.scheme
@@ -0,0 +1,389 @@
+;
+; Copyright © 2016 Keith Packard <keithp@keithp.com>
+;
+; 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.
+;
+; Lisp code placed in ROM
+
+ ; return a list containing all of the arguments
+(def (quote list) (lambda l l))
+
+(def (quote def!)
+ (macro (a b)
+ (list
+ def
+ (list quote a)
+ b)
+ )
+ )
+
+(begin
+ (def! append
+ (lambda args
+ (def! a-l
+ (lambda (a b)
+ (cond ((null? a) b)
+ (else (cons (car a) (a-l (cdr a) b)))
+ )
+ )
+ )
+
+ (def! a-ls
+ (lambda (l)
+ (cond ((null? l) l)
+ ((null? (cdr l)) (car l))
+ (else (a-l (car l) (a-ls (cdr l))))
+ )
+ )
+ )
+ (a-ls args)
+ )
+ )
+ 'append)
+
+(append '(a b c) '(d e f) '(g h i))
+
+ ;
+ ; Define a variable without returning the value
+ ; Useful when defining functions to avoid
+ ; having lots of output generated.
+ ;
+ ; Also accepts the alternate
+ ; form for defining lambdas of
+ ; (define (name a y z) sexprs ...)
+ ;
+
+(begin
+ (def (quote define)
+ (macro (a . b)
+ ; check for alternate lambda definition form
+
+ (cond ((list? a)
+ (set! b
+ (cons lambda (cons (cdr a) b)))
+ (set! a (car a))
+ )
+ (else
+ (set! b (car b))
+ )
+ )
+ (cons begin
+ (cons
+ (cons def
+ (cons (cons quote (cons a '()))
+ (cons b '())
+ )
+ )
+ (cons
+ (cons quote (cons a '()))
+ '())
+ )
+ )
+ )
+ )
+ 'define
+ )
+
+ ; basic list accessors
+
+(define (caar l) (car (car l)))
+
+(define (cadr l) (car (cdr l)))
+
+(define (cdar l) (cdr (car l)))
+
+(define (caddr l) (car (cdr (cdr l))))
+
+ ; (if <condition> <if-true>)
+ ; (if <condition> <if-true> <if-false)
+
+(define if
+ (macro (test . args)
+ (cond ((null? (cdr args))
+ (list cond (list test (car args)))
+ )
+ (else
+ (list cond
+ (list test (car args))
+ (list 'else (cadr args))
+ )
+ )
+ )
+ )
+ )
+
+(if (> 3 2) 'yes)
+(if (> 3 2) 'yes 'no)
+(if (> 2 3) 'no 'yes)
+(if (> 2 3) 'no)
+
+ ; simple math operators
+
+(define zero? (macro (value) (list eqv? value 0)))
+
+(zero? 1)
+(zero? 0)
+(zero? "hello")
+
+(define positive? (macro (value) (list > value 0)))
+
+(positive? 12)
+(positive? -12)
+
+(define negative? (macro (value) (list < value 0)))
+
+(negative? 12)
+(negative? -12)
+
+(define (abs a) (if (>= a 0) a (- a)))
+
+(abs 12)
+(abs -12)
+
+(define max (lambda (a . b)
+ (while (not (null? b))
+ (cond ((< a (car b))
+ (set! a (car b)))
+ )
+ (set! b (cdr b))
+ )
+ a)
+ )
+
+(max 1 2 3)
+(max 3 2 1)
+
+(define min (lambda (a . b)
+ (while (not (null? b))
+ (cond ((> a (car b))
+ (set! a (car b)))
+ )
+ (set! b (cdr b))
+ )
+ a)
+ )
+
+(min 1 2 3)
+(min 3 2 1)
+
+(define (even? a) (zero? (% a 2)))
+
+(even? 2)
+(even? -2)
+(even? 3)
+(even? -1)
+
+(define (odd? a) (not (even? a)))
+
+(odd? 2)
+(odd? -2)
+(odd? 3)
+(odd? -1)
+
+
+(define (list-tail a b)
+ (if (zero? b)
+ a
+ (list-tail (cdr a (- b 1)))
+ )
+ )
+
+(define (list-ref a b)
+ (car (list-tail a b))
+ )
+
+(define (list-tail a b)
+ (if (zero? b)
+ a
+ (list-tail (cdr a) (- b 1))))
+
+(list-tail '(1 2 3) 2)
+
+(define (list-ref a b) (car (list-tail a b)))
+
+(list-ref '(1 2 3) 2)
+
+
+ ; define a set of local
+ ; variables one at a time and
+ ; then evaluate a list of
+ ; sexprs
+ ;
+ ; (let* (var-defines) sexprs)
+ ;
+ ; where var-defines are either
+ ;
+ ; (name value)
+ ;
+ ; or
+ ;
+ ; (name)
+ ;
+ ; e.g.
+ ;
+ ; (let* ((x 1) (y)) (set! y (+ x 1)) y)
+
+(define let*
+ (macro (a . b)
+
+ ;
+ ; make the list of names in the let
+ ;
+
+ (define (_n a)
+ (cond ((not (null? a))
+ (cons (car (car a))
+ (_n (cdr a))))
+ (else ())
+ )
+ )
+
+ ; the set of expressions is
+ ; the list of set expressions
+ ; pre-pended to the
+ ; expressions to evaluate
+
+ (define (_v a b)
+ (cond ((null? a) b) (else
+ (cons
+ (list set
+ (list quote
+ (car (car a))
+ )
+ (cond ((null? (cdr (car a))) ())
+ (else (cadr (car a))))
+ )
+ (_v (cdr a) b)
+ )
+ )
+ )
+ )
+
+ ; the parameters to the lambda is a list
+ ; of nils of the right length
+
+ (define (_z a)
+ (cond ((null? a) ())
+ (else (cons () (_z (cdr a))))
+ )
+ )
+ ; build the lambda.
+
+ (cons (cons lambda (cons (_n a) (_v a b))) (_z a))
+ )
+ )
+
+(let* ((a 1) (y a)) (+ a y))
+
+(define let let*)
+ ; recursive equality
+
+(define (equal? a b)
+ (cond ((eq? a b) #t)
+ ((pair? a)
+ (cond ((pair? b)
+ (cond ((equal? (car a) (car b))
+ (equal? (cdr a) (cdr b)))
+ )
+ )
+ )
+ )
+ )
+ )
+
+(equal? '(a b c) '(a b c))
+(equal? '(a b c) '(a b b))
+
+(define member (lambda (obj a . test?)
+ (cond ((null? a)
+ #f
+ )
+ (else
+ (if (null? test?) (set! test? equal?) (set! test? (car test?)))
+ (if (test? obj (car a))
+ a
+ (member obj (cdr a) test?))
+ )
+ )
+ )
+ )
+
+(member '(2) '((1) (2) (3)))
+
+(member '(4) '((1) (2) (3)))
+
+(define (memq obj a) (member obj a eq?))
+
+(memq 2 '(1 2 3))
+
+(memq 4 '(1 2 3))
+
+(memq '(2) '((1) (2) (3)))
+
+(define (_assoc a b t?)
+ (if (null? b)
+ #f
+ (if (t? a (caar b))
+ (car b)
+ (_assoc a (cdr b) t?)
+ )
+ )
+ )
+
+(define (assq a b) (_assoc a b eq?))
+(define (assoc a b) (_assoc a b equal?))
+
+(assq 'a '((a 1) (b 2) (c 3)))
+(assoc '(c) '((a 1) (b 2) ((c) 3)))
+
+(define string (lambda a (list->string a)))
+
+(display "apply\n")
+(apply cons '(a b))
+
+(define map
+ (lambda (a . b)
+ (define (args b)
+ (cond ((null? b) ())
+ (else
+ (cons (caar b) (args (cdr b)))
+ )
+ )
+ )
+ (define (next b)
+ (cond ((null? b) ())
+ (else
+ (cons (cdr (car b)) (next (cdr b)))
+ )
+ )
+ )
+ (define (domap b)
+ (cond ((null? (car b)) ())
+ (else
+ (cons (apply a (args b)) (domap (next b)))
+ )
+ )
+ )
+ (domap b)
+ )
+ )
+
+(map cadr '((a b) (d e) (g h)))
+
+(define for-each (lambda (a . b)
+ (apply map a b)
+ #t))
+
+(for-each display '("hello" " " "world" "\n"))
+
+(define (newline) (write-char #\newline))
+
+(newline)