diff options
| author | Keith Packard <keithp@keithp.com> | 2017-12-12 15:25:51 -0800 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2017-12-12 15:25:51 -0800 | 
| commit | d8c9024f3829dc3f241b16869f165f3ee01764f3 (patch) | |
| tree | ee3038984838551412feeeee5e56c22afe83a99b /src/scheme/tiny-test | |
| parent | a15166c435f65cb36f487ec8e5a4ff558a7e0502 (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/.gitignore | 1 | ||||
| -rw-r--r-- | src/scheme/tiny-test/Makefile | 28 | ||||
| -rw-r--r-- | src/scheme/tiny-test/ao_scheme_os.h | 72 | ||||
| -rw-r--r-- | src/scheme/tiny-test/ao_scheme_test.c | 141 | ||||
| -rw-r--r-- | src/scheme/tiny-test/ao_scheme_tiny_const.scheme | 389 | 
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) | 
