diff options
Diffstat (limited to 'src/scheme/test')
| -rw-r--r-- | src/scheme/test/.gitignore | 1 | ||||
| -rw-r--r-- | src/scheme/test/ao_scheme_os.h | 68 | ||||
| -rw-r--r-- | src/scheme/test/ao_scheme_test.c | 139 | ||||
| -rw-r--r-- | src/scheme/test/hanoi.scheme | 174 | 
4 files changed, 382 insertions, 0 deletions
| diff --git a/src/scheme/test/.gitignore b/src/scheme/test/.gitignore new file mode 100644 index 00000000..3cdae594 --- /dev/null +++ b/src/scheme/test/.gitignore @@ -0,0 +1 @@ +ao_scheme_test diff --git a/src/scheme/test/ao_scheme_os.h b/src/scheme/test/ao_scheme_os.h new file mode 100644 index 00000000..09a945bc --- /dev/null +++ b/src/scheme/test/ao_scheme_os.h @@ -0,0 +1,68 @@ +/* + * 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> + +#define AO_SCHEME_POOL_TOTAL	16384 +#define AO_SCHEME_SAVE		1 +#define DBG_MEM_STATS		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/test/ao_scheme_test.c b/src/scheme/test/ao_scheme_test.c new file mode 100644 index 00000000..15c71203 --- /dev/null +++ b/src/scheme/test/ao_scheme_test.c @@ -0,0 +1,139 @@ +/* + * 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_stack) +			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(); + +	printf ("collects: full: %d incremental %d\n", +		ao_scheme_collects[AO_SCHEME_COLLECT_FULL], +		ao_scheme_collects[AO_SCHEME_COLLECT_INCREMENTAL]); + +	printf ("freed: full %d incremental %d\n", +		ao_scheme_freed[AO_SCHEME_COLLECT_FULL], +		ao_scheme_freed[AO_SCHEME_COLLECT_INCREMENTAL]); + +	printf("loops: full %d incremental %d\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]); +} diff --git a/src/scheme/test/hanoi.scheme b/src/scheme/test/hanoi.scheme new file mode 100644 index 00000000..c4ae7378 --- /dev/null +++ b/src/scheme/test/hanoi.scheme @@ -0,0 +1,174 @@ +; +; Towers of Hanoi +; +; 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. +; + +					; ANSI control sequences + +(define (move-to col row) +  (for-each display (list "\033[" row ";" col "H")) +  ) + +(define (clear) +  (display "\033[2J") +  ) + +(define (display-string x y str) +  (move-to x y) +  (display str) +  ) + +(define (make-piece num max) +					; A piece for position 'num' +					; is num + 1 + num stars +					; centered in a field of max * +					; 2 + 1 characters with spaces +					; on either side. This way, +					; every piece is the same +					; number of characters + +  (define (chars n c) +    (if (zero? n) "" +      (+ c (chars (- n 1) c)) +      ) +    ) +  (+ (chars (- max num 1) " ") +     (chars (+ (* num 2) 1) "*") +     (chars (- max num 1) " ") +     ) +  ) + +(define (make-pieces max) +					; Make a list of numbers from 0 to max-1 +  (define (nums cur max) +    (if (= cur max) () +      (cons cur (nums (+ cur 1) max)) +      ) +    ) +					; Create a list of pieces + +  (map (lambda (x) (make-piece x max)) (nums 0 max)) +  ) + +					; Here's all of the towers of pieces +					; This is generated when the program is run + +(define towers ()) + +					; position of the bottom of +					; the stacks set at runtime +(define bottom-y 0) +(define left-x 0) + +(define move-delay 25) + +					; Display one tower, clearing any +					; space above it + +(define (display-tower x y clear tower) +  (cond ((= 0 clear) +	 (cond ((not (null? tower)) +		(display-string x y (car tower)) +		(display-tower x (+ y 1) 0 (cdr tower)) +		) +	       ) +	 ) +	(else  +	 (display-string x y "                    ") +	 (display-tower x (+ y 1) (- clear 1) tower) +	 ) +	) +  ) + +					; Position of the top of the tower on the screen +					; Shorter towers start further down the screen + +(define (tower-pos tower) +  (- bottom-y (length tower)) +  ) + +					; Display all of the towers, spaced 20 columns apart + +(define (display-towers x towers) +  (cond ((not (null? towers)) +	 (display-tower x 0 (tower-pos (car towers)) (car towers)) +	 (display-towers (+ x 20) (cdr towers))) +	) +  ) + +					; Display all of the towers, then move the cursor +					; out of the way and flush the output + +(define (display-hanoi) +  (display-towers left-x towers) +  (move-to 1 23) +  (flush-output) +  (delay move-delay) +  ) + +					; Reset towers to the starting state, with +					; all of the pieces in the first tower and the +					; other two empty + +(define (reset-towers len) +  (set! towers (list (make-pieces len) () ())) +  (set! bottom-y (+ len 3)) +  ) + +					; Move a piece from the top of one tower +					; to the top of another + +(define (move-piece from to) + +					; references to the cons holding the two towers + +  (define from-tower (list-tail towers from)) +  (define to-tower (list-tail towers to)) + +					; stick the car of from-tower onto to-tower + +  (set-car! to-tower (cons (caar from-tower) (car to-tower))) + +					; remove the car of from-tower + +  (set-car! from-tower (cdar from-tower)) +  ) + +					; The implementation of the game + +(define (_hanoi n from to use) +  (cond ((= 1 n) +	 (move-piece from to) +	 (display-hanoi) +	 ) +	(else +	 (_hanoi (- n 1) from use to) +	 (_hanoi 1 from to use) +	 (_hanoi (- n 1) use to from) +	 ) +	) +  ) + +					; A pretty interface which +					; resets the state of the game, +					; clears the screen and runs +					; the program + +(define (hanoi len) +  (reset-towers len) +  (clear) +  (display-hanoi) +  (_hanoi len 0 1 2) +  #t +  ) | 
