ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/cvsroot/microscheme/scheme.c
(Generate patch)

Comparing cvsroot/microscheme/scheme.c (file contents):
Revision 1.60 by root, Wed Dec 2 02:59:36 2015 UTC vs.
Revision 1.65 by root, Wed Dec 2 17:01:51 2015 UTC

16 * (MINISCM) This is a revised and modified version by Akira KIDA. 16 * (MINISCM) This is a revised and modified version by Akira KIDA.
17 * (MINISCM) current version is 0.85k4 (15 May 1994) 17 * (MINISCM) current version is 0.85k4 (15 May 1994)
18 * 18 *
19 */ 19 */
20 20
21#define EXPERIMENT 1 21#define _POSIX_C_SOURCE 200201
22 22#define _XOPEN_SOURCE 600
23#if 1 23#define _GNU_SOURCE 1 /* for malloc mremap */
24#define PAGE_SIZE 4096 /* does not work on sparc/alpha */
25#include "malloc.c"
26#endif
27 24
28#define SCHEME_SOURCE 25#define SCHEME_SOURCE
29#include "scheme-private.h" 26#include "scheme-private.h"
30#ifndef WIN32 27#ifndef WIN32
31# include <unistd.h> 28# include <unistd.h>
32#endif 29#endif
33#if USE_MATH 30#if USE_MATH
34# include <math.h> 31# include <math.h>
35#endif 32#endif
36 33
34#define ECB_NO_THREADS 1
37#include "ecb.h" 35#include "ecb.h"
38 36
39#include <sys/types.h> 37#include <sys/types.h>
40#include <sys/stat.h> 38#include <sys/stat.h>
41#include <fcntl.h> 39#include <fcntl.h>
49#include <string.h> 47#include <string.h>
50 48
51#include <limits.h> 49#include <limits.h>
52#include <inttypes.h> 50#include <inttypes.h>
53#include <float.h> 51#include <float.h>
54//#include <ctype.h> 52
53#if !USE_SYSTEM_MALLOC
54# define PAGE_SIZE 4096 /* does not work on sparc/alpha */
55# include "malloc.c"
56# define malloc(n) tiny_malloc (n)
57# define realloc(p,n) tiny_realloc (p, n)
58# define free(p) tiny_free (p)
59#endif
55 60
56#if '1' != '0' + 1 \ 61#if '1' != '0' + 1 \
57 || '2' != '0' + 2 || '3' != '0' + 3 || '4' != '0' + 4 || '5' != '0' + 5 \ 62 || '2' != '0' + 2 || '3' != '0' + 3 || '4' != '0' + 4 || '5' != '0' + 5 \
58 || '6' != '0' + 6 || '7' != '0' + 7 || '8' != '0' + 8 || '9' != '0' + 9 \ 63 || '6' != '0' + 6 || '7' != '0' + 7 || '8' != '0' + 8 || '9' != '0' + 9 \
59 || 'b' != 'a' + 1 || 'c' != 'a' + 2 || 'd' != 'a' + 3 || 'e' != 'a' + 4 \ 64 || 'b' != 'a' + 1 || 'c' != 'a' + 2 || 'd' != 'a' + 3 || 'e' != 'a' + 4 \
131 136
132 xnum (buf, n); 137 xnum (buf, n);
133 putstr (SCHEME_A_ buf); 138 putstr (SCHEME_A_ buf);
134} 139}
135 140
136ecb_cold static char 141#if USE_CHAR_CLASSIFIERS
142#include <ctype.h>
143#else
144
145static char
137xtoupper (char c) 146xtoupper (char c)
138{ 147{
139 if (c >= 'a' && c <= 'z') 148 if (c >= 'a' && c <= 'z')
140 c -= 'a' - 'A'; 149 c -= 'a' - 'A';
141 150
142 return c; 151 return c;
143} 152}
144 153
145ecb_cold static char 154static char
146xtolower (char c) 155xtolower (char c)
147{ 156{
148 if (c >= 'A' && c <= 'Z') 157 if (c >= 'A' && c <= 'Z')
149 c += 'a' - 'A'; 158 c += 'a' - 'A';
150 159
151 return c; 160 return c;
152} 161}
153 162
154ecb_cold static int 163static int
155xisdigit (char c) 164xisdigit (char c)
156{ 165{
157 return c >= '0' && c <= '9'; 166 return c >= '0' && c <= '9';
158} 167}
159 168
160#define toupper(c) xtoupper (c) 169#define toupper(c) xtoupper (c)
161#define tolower(c) xtolower (c) 170#define tolower(c) xtolower (c)
162#define isdigit(c) xisdigit (c) 171#define isdigit(c) xisdigit (c)
163 172
173#endif
174
164#if USE_IGNORECASE 175#if USE_IGNORECASE
165ecb_cold static const char * 176ecb_cold static const char *
166xstrlwr (char *s) 177xstrlwr (char *s)
167{ 178{
168 const char *p = s; 179 const char *p = s;
183# define stricmp(a,b) strcmp (a, b) 194# define stricmp(a,b) strcmp (a, b)
184# define strlwr(s) (s) 195# define strlwr(s) (s)
185#endif 196#endif
186 197
187#ifndef prompt 198#ifndef prompt
188# define prompt "ts> " 199# define prompt "ms> "
189#endif 200#endif
190 201
191#ifndef InitFile 202#ifndef InitFile
192# define InitFile "init.scm" 203# define InitFile "init.scm"
193#endif 204#endif
200 T_STRING, 211 T_STRING,
201 T_SYMBOL, 212 T_SYMBOL,
202 T_PROC, 213 T_PROC,
203 T_PAIR, /* also used for free cells */ 214 T_PAIR, /* also used for free cells */
204 T_CLOSURE, 215 T_CLOSURE,
216 T_BYTECODE, // temp
205 T_MACRO, 217 T_MACRO,
206 T_CONTINUATION, 218 T_CONTINUATION,
207 T_FOREIGN, 219 T_FOREIGN,
208 T_PORT, 220 T_PORT,
209 T_VECTOR, 221 T_VECTOR,
210 T_PROMISE, 222 T_PROMISE,
211 T_ENVIRONMENT, 223 T_ENVIRONMENT,
212 /* one more... */ 224
213 T_NUM_SYSTEM_TYPES 225 T_NUM_SYSTEM_TYPES
214}; 226};
215 227
216#define T_MASKTYPE 0x000f 228#define T_MASKTYPE 0x000f
217#define T_SYNTAX 0x0010 229#define T_SYNTAX 0x0010
371 383
372static pointer cadar (pointer p) { return car (cdr (car (p))); } 384static pointer cadar (pointer p) { return car (cdr (car (p))); }
373static pointer caddr (pointer p) { return car (cdr (cdr (p))); } 385static pointer caddr (pointer p) { return car (cdr (cdr (p))); }
374static pointer cdaar (pointer p) { return cdr (car (car (p))); } 386static pointer cdaar (pointer p) { return cdr (car (car (p))); }
375 387
388static pointer cadddr (pointer p) { return car (car (car (cdr (p)))); }
389
376INTERFACE void 390INTERFACE void
377set_car (pointer p, pointer q) 391set_car (pointer p, pointer q)
378{ 392{
379 CELL(p)->object.cons.car = CELL (q); 393 CELL(p)->object.cons.car = CELL (q);
380} 394}
569{ 583{
570 return list_length (SCHEME_A_ a) >= 0; 584 return list_length (SCHEME_A_ a) >= 0;
571} 585}
572 586
573#if USE_CHAR_CLASSIFIERS 587#if USE_CHAR_CLASSIFIERS
588
574ecb_inline int 589ecb_inline int
575Cisalpha (int c) 590Cisalpha (int c)
576{ 591{
577 return isascii (c) && isalpha (c); 592 return isascii (c) && isalpha (c);
578} 593}
668static int file_interactive (SCHEME_P); 683static int file_interactive (SCHEME_P);
669ecb_inline int is_one_of (const char *s, int c); 684ecb_inline int is_one_of (const char *s, int c);
670static int alloc_cellseg (SCHEME_P); 685static int alloc_cellseg (SCHEME_P);
671ecb_inline pointer get_cell (SCHEME_P_ pointer a, pointer b); 686ecb_inline pointer get_cell (SCHEME_P_ pointer a, pointer b);
672static void finalize_cell (SCHEME_P_ pointer a); 687static void finalize_cell (SCHEME_P_ pointer a);
673static int count_consecutive_cells (pointer x, int needed);
674static pointer find_slot_in_env (SCHEME_P_ pointer env, pointer sym, int all); 688static pointer find_slot_in_env (SCHEME_P_ pointer env, pointer sym, int all);
675static pointer mk_number (SCHEME_P_ const num n); 689static pointer mk_number (SCHEME_P_ const num n);
676static char *store_string (SCHEME_P_ uint32_t len, const char *str, char fill); 690static char *store_string (SCHEME_P_ uint32_t len, const char *str, char fill);
677static pointer mk_vector (SCHEME_P_ uint32_t len); 691static pointer mk_vector (SCHEME_P_ uint32_t len);
678static pointer mk_atom (SCHEME_P_ char *q); 692static pointer mk_atom (SCHEME_P_ char *q);
679static pointer mk_sharp_const (SCHEME_P_ char *name); 693static pointer mk_sharp_const (SCHEME_P_ char *name);
680 694
695static pointer mk_port (SCHEME_P_ port *p);
696
681#if USE_PORTS 697#if USE_PORTS
682static pointer mk_port (SCHEME_P_ port *p);
683static pointer port_from_filename (SCHEME_P_ const char *fn, int prop); 698static pointer port_from_filename (SCHEME_P_ const char *fn, int prop);
684static pointer port_from_file (SCHEME_P_ int, int prop); 699static pointer port_from_file (SCHEME_P_ int, int prop);
685static pointer port_from_string (SCHEME_P_ char *start, char *past_the_end, int prop); 700static pointer port_from_string (SCHEME_P_ char *start, char *past_the_end, int prop);
686static port *port_rep_from_filename (SCHEME_P_ const char *fn, int prop); 701static port *port_rep_from_filename (SCHEME_P_ const char *fn, int prop);
687static port *port_rep_from_file (SCHEME_P_ int, int prop); 702static port *port_rep_from_file (SCHEME_P_ int, int prop);
688static port *port_rep_from_string (SCHEME_P_ char *start, char *past_the_end, int prop); 703static port *port_rep_from_string (SCHEME_P_ char *start, char *past_the_end, int prop);
689static void port_close (SCHEME_P_ pointer p, int flag); 704static void port_close (SCHEME_P_ pointer p, int flag);
690#endif 705#endif
706
691static void mark (pointer a); 707static void mark (pointer a);
692static void gc (SCHEME_P_ pointer a, pointer b); 708static void gc (SCHEME_P_ pointer a, pointer b);
693static int basic_inchar (port *pt); 709static int basic_inchar (port *pt);
694static int inchar (SCHEME_P); 710static int inchar (SCHEME_P);
695static void backchar (SCHEME_P_ int c); 711static void backchar (SCHEME_P_ int c);
696static char *readstr_upto (SCHEME_P_ int skip, const char *delim); 712static char *readstr_upto (SCHEME_P_ int skip, const char *delim);
697static pointer readstrexp (SCHEME_P_ char delim); 713static pointer readstrexp (SCHEME_P_ char delim);
698ecb_inline int skipspace (SCHEME_P); 714static int skipspace (SCHEME_P);
699static int token (SCHEME_P); 715static int token (SCHEME_P);
700static void printslashstring (SCHEME_P_ char *s, int len); 716static void printslashstring (SCHEME_P_ char *s, int len);
701static void atom2str (SCHEME_P_ pointer l, int f, char **pp, int *plen); 717static void atom2str (SCHEME_P_ pointer l, int f, char **pp, int *plen);
702static void printatom (SCHEME_P_ pointer l, int f); 718static void printatom (SCHEME_P_ pointer l, int f);
703static pointer mk_proc (SCHEME_P_ enum scheme_opcodes op); 719static pointer mk_proc (SCHEME_P_ enum scheme_opcodes op);
902 918
903 if (!cp && USE_ERROR_CHECKING) 919 if (!cp && USE_ERROR_CHECKING)
904 return k; 920 return k;
905 921
906 i = ++SCHEME_V->last_cell_seg; 922 i = ++SCHEME_V->last_cell_seg;
907 SCHEME_V->alloc_seg[i] = cp;
908 923
909 newp = (struct cell *)cp; 924 newp = (struct cell *)cp;
910 SCHEME_V->cell_seg[i] = newp; 925 SCHEME_V->cell_seg[i] = newp;
911 SCHEME_V->cell_segsize[i] = segsize; 926 SCHEME_V->cell_segsize[i] = segsize;
912 SCHEME_V->fcells += segsize; 927 SCHEME_V->fcells += segsize;
935 if (SCHEME_V->no_memory && USE_ERROR_CHECKING) 950 if (SCHEME_V->no_memory && USE_ERROR_CHECKING)
936 return S_SINK; 951 return S_SINK;
937 952
938 if (SCHEME_V->free_cell == NIL) 953 if (SCHEME_V->free_cell == NIL)
939 { 954 {
940 const int min_to_be_recovered = SCHEME_V->cell_segsize [SCHEME_V->last_cell_seg] >> 1; 955 const int min_to_be_recovered = SCHEME_V->cell_segsize [SCHEME_V->last_cell_seg] >> 2;
941 956
942 gc (SCHEME_A_ a, b); 957 gc (SCHEME_A_ a, b);
943 958
944 if (SCHEME_V->fcells < min_to_be_recovered || SCHEME_V->free_cell == NIL) 959 if (SCHEME_V->fcells < min_to_be_recovered || SCHEME_V->free_cell == NIL)
945 { 960 {
1043#endif 1058#endif
1044 1059
1045/* Medium level cell allocation */ 1060/* Medium level cell allocation */
1046 1061
1047/* get new cons cell */ 1062/* get new cons cell */
1048ecb_hot pointer 1063ecb_hot static pointer
1049xcons (SCHEME_P_ pointer a, pointer b, int immutable) 1064xcons (SCHEME_P_ pointer a, pointer b)
1050{ 1065{
1051 pointer x = get_cell (SCHEME_A_ a, b); 1066 pointer x = get_cell (SCHEME_A_ a, b);
1052 1067
1053 set_typeflag (x, T_PAIR); 1068 set_typeflag (x, T_PAIR);
1054
1055 if (immutable)
1056 setimmutable (x);
1057 1069
1058 set_car (x, a); 1070 set_car (x, a);
1059 set_cdr (x, b); 1071 set_cdr (x, b);
1060 1072
1061 return x; 1073 return x;
1062} 1074}
1075
1076ecb_hot static pointer
1077ximmutable_cons (SCHEME_P_ pointer a, pointer b)
1078{
1079 pointer x = xcons (SCHEME_A_ a, b);
1080 setimmutable (x);
1081 return x;
1082}
1083
1084#define cons(a,b) xcons (SCHEME_A_ a, b)
1085#define immutable_cons(a,b) ximmutable_cons (SCHEME_A_ a, b)
1063 1086
1064ecb_cold static pointer 1087ecb_cold static pointer
1065generate_symbol (SCHEME_P_ const char *name) 1088generate_symbol (SCHEME_P_ const char *name)
1066{ 1089{
1067 pointer x = mk_string (SCHEME_A_ name); 1090 pointer x = mk_string (SCHEME_A_ name);
1075#ifndef USE_OBJECT_LIST 1098#ifndef USE_OBJECT_LIST
1076 1099
1077static int 1100static int
1078hash_fn (const char *key, int table_size) 1101hash_fn (const char *key, int table_size)
1079{ 1102{
1080 const unsigned char *p = key; 1103 const unsigned char *p = (unsigned char *)key;
1081 uint32_t hash = 2166136261; 1104 uint32_t hash = 2166136261U;
1082 1105
1083 while (*p) 1106 while (*p)
1084 hash = (hash ^ *p++) * 16777619; 1107 hash = (hash ^ *p++) * 16777619;
1085 1108
1086 return hash % table_size; 1109 return hash % table_size;
1178 return SCHEME_V->oblist; 1201 return SCHEME_V->oblist;
1179} 1202}
1180 1203
1181#endif 1204#endif
1182 1205
1183#if USE_PORTS
1184ecb_cold static pointer 1206ecb_cold static pointer
1185mk_port (SCHEME_P_ port *p) 1207mk_port (SCHEME_P_ port *p)
1186{ 1208{
1187 pointer x = get_cell (SCHEME_A_ NIL, NIL); 1209 pointer x = get_cell (SCHEME_A_ NIL, NIL);
1188 1210
1189 set_typeflag (x, T_PORT | T_ATOM); 1211 set_typeflag (x, T_PORT | T_ATOM);
1190 set_port (x, p); 1212 set_port (x, p);
1191 1213
1192 return x; 1214 return x;
1193} 1215}
1194#endif
1195 1216
1196ecb_cold pointer 1217ecb_cold pointer
1197mk_foreign_func (SCHEME_P_ foreign_func f) 1218mk_foreign_func (SCHEME_P_ foreign_func f)
1198{ 1219{
1199 pointer x = get_cell (SCHEME_A_ NIL, NIL); 1220 pointer x = get_cell (SCHEME_A_ NIL, NIL);
1722/* ========== Routines for Reading ========== */ 1743/* ========== Routines for Reading ========== */
1723 1744
1724ecb_cold static int 1745ecb_cold static int
1725file_push (SCHEME_P_ const char *fname) 1746file_push (SCHEME_P_ const char *fname)
1726{ 1747{
1727#if USE_PORTS
1728 int fin; 1748 int fin;
1729 1749
1730 if (SCHEME_V->file_i == MAXFIL - 1) 1750 if (SCHEME_V->file_i == MAXFIL - 1)
1731 return 0; 1751 return 0;
1732 1752
1749 SCHEME_V->load_stack[SCHEME_V->file_i].rep.stdio.filename = store_string (SCHEME_A_ strlen (fname), fname, 0); 1769 SCHEME_V->load_stack[SCHEME_V->file_i].rep.stdio.filename = store_string (SCHEME_A_ strlen (fname), fname, 0);
1750#endif 1770#endif
1751 } 1771 }
1752 1772
1753 return fin >= 0; 1773 return fin >= 0;
1754
1755#else
1756 return 1;
1757#endif
1758} 1774}
1759 1775
1760ecb_cold static void 1776ecb_cold static void
1761file_pop (SCHEME_P) 1777file_pop (SCHEME_P)
1762{ 1778{
1946 } 1962 }
1947} 1963}
1948#endif 1964#endif
1949 1965
1950/* get new character from input file */ 1966/* get new character from input file */
1951static int 1967ecb_cold static int
1952inchar (SCHEME_P) 1968inchar (SCHEME_P)
1953{ 1969{
1954 int c; 1970 int c;
1955 port *pt = port (SCHEME_V->inport); 1971 port *pt = port (SCHEME_V->inport);
1956 1972
1970 } 1986 }
1971 1987
1972 return c; 1988 return c;
1973} 1989}
1974 1990
1975static int ungot = -1; 1991ecb_cold static int
1976
1977static int
1978basic_inchar (port *pt) 1992basic_inchar (port *pt)
1979{ 1993{
1980#if USE_PORTS
1981 if (pt->unget != -1) 1994 if (pt->unget != -1)
1982 { 1995 {
1983 int r = pt->unget; 1996 int r = pt->unget;
1984 pt->unget = -1; 1997 pt->unget = -1;
1985 return r; 1998 return r;
1986 } 1999 }
1987 2000
2001#if USE_PORTS
1988 if (pt->kind & port_file) 2002 if (pt->kind & port_file)
1989 { 2003 {
1990 char c; 2004 char c;
1991 2005
1992 if (!read (pt->rep.stdio.file, &c, 1)) 2006 if (!read (pt->rep.stdio.file, &c, 1))
2000 return EOF; 2014 return EOF;
2001 else 2015 else
2002 return *pt->rep.string.curr++; 2016 return *pt->rep.string.curr++;
2003 } 2017 }
2004#else 2018#else
2005 if (ungot == -1)
2006 {
2007 char c; 2019 char c;
2008 if (!read (0, &c, 1)) 2020
2021 if (!read (pt->rep.stdio.file, &c, 1))
2009 return EOF; 2022 return EOF;
2010 2023
2011 ungot = c;
2012 }
2013
2014 {
2015 int r = ungot;
2016 ungot = -1;
2017 return r; 2024 return c;
2018 }
2019#endif 2025#endif
2020} 2026}
2021 2027
2022/* back character to input buffer */ 2028/* back character to input buffer */
2023static void 2029ecb_cold static void
2024backchar (SCHEME_P_ int c) 2030backchar (SCHEME_P_ int c)
2025{ 2031{
2026#if USE_PORTS 2032 port *pt = port (SCHEME_V->inport);
2027 port *pt;
2028 2033
2029 if (c == EOF) 2034 if (c == EOF)
2030 return; 2035 return;
2031 2036
2032 pt = port (SCHEME_V->inport);
2033 pt->unget = c; 2037 pt->unget = c;
2034#else
2035 if (c == EOF)
2036 return;
2037
2038 ungot = c;
2039#endif
2040} 2038}
2041 2039
2042#if USE_PORTS 2040#if USE_PORTS
2043ecb_cold static int 2041ecb_cold static int
2044realloc_port_string (SCHEME_P_ port *p) 2042realloc_port_string (SCHEME_P_ port *p)
2061 else 2059 else
2062 return 0; 2060 return 0;
2063} 2061}
2064#endif 2062#endif
2065 2063
2066ecb_cold INTERFACE void
2067putstr (SCHEME_P_ const char *s)
2068{
2069#if USE_PORTS
2070 port *pt = port (SCHEME_V->outport);
2071
2072 if (pt->kind & port_file)
2073 write (pt->rep.stdio.file, s, strlen (s));
2074 else
2075 for (; *s; s++)
2076 if (pt->rep.string.curr != pt->rep.string.past_the_end)
2077 *pt->rep.string.curr++ = *s;
2078 else if (pt->kind & port_srfi6 && realloc_port_string (SCHEME_A_ pt))
2079 *pt->rep.string.curr++ = *s;
2080
2081#else
2082 write (pt->rep.stdio.file, s, strlen (s));
2083#endif
2084}
2085
2086ecb_cold static void 2064ecb_cold static void
2087putchars (SCHEME_P_ const char *s, int len) 2065putchars (SCHEME_P_ const char *s, int len)
2088{ 2066{
2067 port *pt = port (SCHEME_V->outport);
2068
2089#if USE_PORTS 2069#if USE_PORTS
2090 port *pt = port (SCHEME_V->outport);
2091
2092 if (pt->kind & port_file) 2070 if (pt->kind & port_file)
2093 write (pt->rep.stdio.file, s, len); 2071 write (pt->rep.stdio.file, s, len);
2094 else 2072 else
2095 { 2073 {
2096 for (; len; len--) 2074 for (; len; len--)
2101 *pt->rep.string.curr++ = *s++; 2079 *pt->rep.string.curr++ = *s++;
2102 } 2080 }
2103 } 2081 }
2104 2082
2105#else 2083#else
2106 write (1, s, len); 2084 write (1, s, len); // output not initialised
2107#endif 2085#endif
2108} 2086}
2109 2087
2110ecb_cold INTERFACE void 2088INTERFACE void
2089putstr (SCHEME_P_ const char *s)
2090{
2091 putchars (SCHEME_A_ s, strlen (s));
2092}
2093
2094INTERFACE void
2111putcharacter (SCHEME_P_ int c) 2095putcharacter (SCHEME_P_ int c)
2112{ 2096{
2113#if USE_PORTS
2114 port *pt = port (SCHEME_V->outport);
2115
2116 if (pt->kind & port_file)
2117 {
2118 char cc = c;
2119 write (pt->rep.stdio.file, &cc, 1);
2120 }
2121 else
2122 {
2123 if (pt->rep.string.curr != pt->rep.string.past_the_end)
2124 *pt->rep.string.curr++ = c;
2125 else if (pt->kind & port_srfi6 && realloc_port_string (SCHEME_A_ pt))
2126 *pt->rep.string.curr++ = c;
2127 }
2128
2129#else
2130 char cc = c; 2097 char cc = c;
2131 write (1, &c, 1); 2098
2132#endif 2099 putchars (SCHEME_A_ &cc, 1);
2133} 2100}
2134 2101
2135/* read characters up to delimiter, but cater to character constants */ 2102/* read characters up to delimiter, but cater to character constants */
2136ecb_cold static char * 2103ecb_cold static char *
2137readstr_upto (SCHEME_P_ int skip, const char *delim) 2104readstr_upto (SCHEME_P_ int skip, const char *delim)
2198 case 'a': *p++ = '\a'; state = st_ok; break; 2165 case 'a': *p++ = '\a'; state = st_ok; break;
2199 case 'n': *p++ = '\n'; state = st_ok; break; 2166 case 'n': *p++ = '\n'; state = st_ok; break;
2200 case 'r': *p++ = '\r'; state = st_ok; break; 2167 case 'r': *p++ = '\r'; state = st_ok; break;
2201 case 't': *p++ = '\t'; state = st_ok; break; 2168 case 't': *p++ = '\t'; state = st_ok; break;
2202 2169
2203 //TODO: \whitespace eol whitespace 2170 // this overshoots the minimum requirements of r7rs
2171 case ' ':
2172 case '\t':
2173 case '\r':
2174 case '\n':
2175 skipspace (SCHEME_A);
2176 state = st_ok;
2177 break;
2204 2178
2205 //TODO: x should end in ;, not two-digit hex 2179 //TODO: x should end in ;, not two-digit hex
2206 case 'x': 2180 case 'x':
2207 case 'X': 2181 case 'X':
2208 state = st_x1; 2182 state = st_x1;
2964/* ========== Evaluation Cycle ========== */ 2938/* ========== Evaluation Cycle ========== */
2965 2939
2966ecb_cold static int 2940ecb_cold static int
2967xError_1 (SCHEME_P_ const char *s, pointer a) 2941xError_1 (SCHEME_P_ const char *s, pointer a)
2968{ 2942{
2969#if USE_ERROR_HOOK
2970 pointer x;
2971 pointer hdl = SCHEME_V->ERROR_HOOK;
2972#endif
2973
2974#if USE_PRINTF 2943#if USE_PRINTF
2975#if SHOW_ERROR_LINE 2944#if SHOW_ERROR_LINE
2976 char sbuf[STRBUFFSIZE]; 2945 char sbuf[STRBUFFSIZE];
2977 2946
2978 /* make sure error is not in REPL */ 2947 /* make sure error is not in REPL */
2993 } 2962 }
2994#endif 2963#endif
2995#endif 2964#endif
2996 2965
2997#if USE_ERROR_HOOK 2966#if USE_ERROR_HOOK
2998 x = find_slot_in_env (SCHEME_A_ SCHEME_V->envir, hdl, 1); 2967 pointer x = find_slot_in_env (SCHEME_A_ SCHEME_V->envir, SCHEME_V->ERROR_HOOK, 1);
2999 2968
3000 if (x != NIL) 2969 if (x != NIL)
3001 { 2970 {
3002 pointer code = a 2971 pointer code = a
3003 ? cons (cons (SCHEME_V->QUOTE, cons (a, NIL)), NIL) 2972 ? cons (cons (SCHEME_V->QUOTE, cons (a, NIL)), NIL)
3246#endif 3215#endif
3247 3216
3248#define s_retbool(tf) s_return ((tf) ? S_T : S_F) 3217#define s_retbool(tf) s_return ((tf) ? S_T : S_F)
3249 3218
3250#if EXPERIMENT 3219#if EXPERIMENT
3220
3251static int 3221static int
3252debug (SCHEME_P_ int indent, pointer x) 3222dtree (SCHEME_P_ int indent, pointer x)
3253{ 3223{
3254 int c; 3224 int c;
3255 3225
3256 if (is_syntax (x)) 3226 if (is_syntax (x))
3257 { 3227 {
3275 printf ("%*sS<%s>\n", indent, "", symname (x)); 3245 printf ("%*sS<%s>\n", indent, "", symname (x));
3276 return 24+8; 3246 return 24+8;
3277 3247
3278 case T_CLOSURE: 3248 case T_CLOSURE:
3279 printf ("%*sS<%s>\n", indent, "", "closure"); 3249 printf ("%*sS<%s>\n", indent, "", "closure");
3280 debug (SCHEME_A_ indent + 3, cdr(x)); 3250 dtree (SCHEME_A_ indent + 3, cdr(x));
3281 return 32 + debug (SCHEME_A_ indent + 3, car (x)); 3251 return 32 + dtree (SCHEME_A_ indent + 3, car (x));
3282 3252
3283 case T_PAIR: 3253 case T_PAIR:
3284 printf ("%*spair %p %p\n", indent, "", car(x),cdr(x)); 3254 printf ("%*spair %p %p\n", indent, "", car(x),cdr(x));
3285 c = debug (SCHEME_A_ indent + 3, car (x)); 3255 c = dtree (SCHEME_A_ indent + 3, car (x));
3286 c += debug (SCHEME_A_ indent + 3, cdr (x)); 3256 c += dtree (SCHEME_A_ indent + 3, cdr (x));
3287 return c + 1; 3257 return c + 1;
3288 3258
3289 case T_PORT: 3259 case T_PORT:
3290 printf ("%*sS<%s>\n", indent, "", "port"); 3260 printf ("%*sS<%s>\n", indent, "", "port");
3291 return 24+8; 3261 return 24+8;
3294 printf ("%*sS<%s>\n", indent, "", "vector"); 3264 printf ("%*sS<%s>\n", indent, "", "vector");
3295 return 24+8; 3265 return 24+8;
3296 3266
3297 case T_ENVIRONMENT: 3267 case T_ENVIRONMENT:
3298 printf ("%*sS<%s>\n", indent, "", "environment"); 3268 printf ("%*sS<%s>\n", indent, "", "environment");
3299 return 0 + debug (SCHEME_A_ indent + 3, car (x)); 3269 return 0 + dtree (SCHEME_A_ indent + 3, car (x));
3300 3270
3301 default: 3271 default:
3302 printf ("unhandled type %d\n", type (x)); 3272 printf ("unhandled type %d\n", type (x));
3303 break; 3273 break;
3304 } 3274 }
3305} 3275}
3276
3277#define DUMP(t) do { printf ("DUMP %s:%d\n", __FILE__, __LINE__); dtree (SCHEME_A_ 0, (t)); } while (0)
3278
3279typedef void *stream[1];
3280
3281#define stream_init() { 0 }
3282#define stream_data(s) ((char *)(s)[0] + sizeof (uint32_t) * 2)
3283#define stream_size(s) (((uint32_t *)(s)[0])[0] - sizeof (uint32_t) * 2)
3284#define stream_free(s) free (s[0])
3285
3286ecb_cold static void
3287stream_put (stream s, uint8_t byte)
3288{
3289 uint32_t *sp = *s;
3290 uint32_t size = sizeof (uint32_t) * 2;
3291 uint32_t offs = size;
3292
3293 if (ecb_expect_true (sp))
3294 {
3295 offs = sp[0];
3296 size = sp[1];
3297 }
3298
3299 if (ecb_expect_false (offs == size))
3300 {
3301 size *= 2;
3302 sp = realloc (sp, size);
3303 *s = sp;
3304 sp[1] = size;
3305
3306 }
3307
3308 ((uint8_t *)sp)[offs++] = byte;
3309 sp[0] = offs;
3310}
3311
3312ecb_cold static void
3313stream_put_v (stream s, uint32_t v)
3314{
3315 while (v > 0x7f)
3316 {
3317 stream_put (s, v | 0x80);
3318 v >>= 7;
3319 }
3320
3321 stream_put (s, v);
3322}
3323
3324ecb_cold static void
3325stream_put_tv (stream s, int bop, uint32_t v)
3326{
3327 printf ("put tv %d %d\n", bop, v);//D
3328 stream_put (s, bop);
3329 stream_put_v (s, v);
3330}
3331
3332ecb_cold static void
3333stream_put_stream (stream s, stream o)
3334{
3335 uint32_t i;
3336
3337 for (i = 0; i < stream_size (o); ++i)
3338 stream_put (s, stream_data (o)[i]);
3339
3340 stream_free (o);
3341}
3342
3343// calculates a (preferably small) integer that makes it possible to find
3344// the symbol again. if pointers were offsets into a memory area... until
3345// then, we return segment number in the low bits, and offset in the high
3346// bits.
3347// also, this function must never return 0.
3348ecb_cold static uint32_t
3349symbol_id (SCHEME_P_ pointer sym)
3350{
3351 struct cell *p = CELL (sym);
3352 int i;
3353
3354 for (i = SCHEME_V->last_cell_seg; i >= 0; --i)
3355 if (SCHEME_V->cell_seg[i] <= p && p < SCHEME_V->cell_seg[i] + SCHEME_V->cell_segsize[i])
3356 return i | ((p - SCHEME_V->cell_seg[i]) << CELL_NSEGMENT_LOG);
3357
3358 abort ();
3359}
3360
3361ecb_cold static uint32_t
3362cell_id (SCHEME_P_ pointer p)
3363{
3364 return symbol_id (SCHEME_A_ p);
3365}
3366
3367enum byteop
3368{
3369 BOP_NIL,
3370 BOP_SYNTAX,
3371 BOP_INTEGER,
3372 BOP_SYMBOL,
3373 BOP_LIST_BEG,
3374 BOP_LIST_END,
3375 BOP_BIFT, // branch if true
3376 BOP_BIFF, // branch if false
3377 BOP_BIFNE, // branch if not eqv?
3378 BOP_BRA, // "short" branch
3379 BOP_JMP, // "long" jump
3380 BOP_DATUM,
3381 BOP_LET,
3382 BOP_LETAST,
3383 BOP_LETREC,
3384 BOP_DEFINE,
3385 BOP_MACRO,
3386 BOP_SET,
3387 BOP_BEGIN,
3388 BOP_LAMBDA,
3389};
3390
3391ecb_cold static void compile_expr (SCHEME_P_ stream s, pointer x);
3392
3393ecb_cold static void
3394compile_list (SCHEME_P_ stream s, pointer x)
3395{
3396 for (; x != NIL; x = cdr (x))
3397 compile_expr (SCHEME_A_ s, car (x));
3398}
3399
3400static void
3401compile_if (SCHEME_P_ stream s, pointer cond, pointer ift, pointer iff)
3402{
3403 //TODO: borked
3404 stream sift = stream_init (); compile_expr (SCHEME_A_ sift, ift);
3405
3406 stream_put (s, BOP_BIFF);
3407 compile_expr (SCHEME_A_ s, cond);
3408 stream_put_v (s, stream_size (sift));
3409 stream_put_stream (s, sift);
3410
3411 if (iff != NIL)
3412 {
3413 stream siff = stream_init (); compile_expr (SCHEME_A_ siff, iff);
3414 stream_put_tv (s, BOP_BRA, stream_size (siff));
3415 stream_put_stream (s, siff);
3416 }
3417}
3418
3419typedef uint32_t stream_fixup;
3420
3421static stream_fixup
3422stream_put_fixup (stream s)
3423{
3424 stream_put (s, 0);
3425 stream_put (s, 0);
3426
3427 return stream_size (s);
3428}
3429
3430static void
3431stream_fix_fixup (stream s, stream_fixup fixup, uint32_t target)
3432{
3433 target -= fixup;
3434 assert (target < (1 << 14));
3435 stream_data (s)[fixup - 2] = target | 0x80;
3436 stream_data (s)[fixup - 1] = target >> 7;
3437}
3438
3439static void
3440compile_and_or (SCHEME_P_ stream s, int and, pointer x)
3441{
3442 if (cdr (x) == NIL)
3443 compile_expr (SCHEME_A_ s, car (x));
3444 else
3445 {
3446 stream_put (s, and ? BOP_BIFF : BOP_BIFT);
3447 compile_expr (SCHEME_A_ s, car (x));
3448 stream_fixup end = stream_put_fixup (s);
3449
3450 compile_and_or (SCHEME_A_ s, and, cdr (x));
3451 stream_fix_fixup (s, end, stream_size (s));
3452 }
3453}
3454
3455ecb_cold static void
3456compile_expr (SCHEME_P_ stream s, pointer x)
3457{
3458 if (x == NIL)
3459 {
3460 stream_put (s, BOP_NIL);
3461 return;
3462 }
3463
3464 if (is_pair (x))
3465 {
3466 pointer head = car (x);
3467
3468 if (is_syntax (head))
3469 {
3470 x = cdr (x);
3471
3472 switch (syntaxnum (head))
3473 {
3474 case OP_IF0: /* if */
3475 compile_if (SCHEME_A_ s, car (x), cadr (x), caddr (x));
3476 break;
3477
3478 case OP_OR0: /* or */
3479 compile_and_or (SCHEME_A_ s, 0, x);
3480 break;
3481
3482 case OP_AND0: /* and */
3483 compile_and_or (SCHEME_A_ s, 1, x);
3484 break;
3485
3486 case OP_CASE0: /* case */
3487 abort ();
3488 break;
3489
3490 case OP_COND0: /* cond */
3491 abort ();
3492 break;
3493
3494 case OP_LET0: /* let */
3495 case OP_LET0AST: /* let* */
3496 case OP_LET0REC: /* letrec */
3497 switch (syntaxnum (head))
3498 {
3499 case OP_LET0: stream_put (s, BOP_LET ); break;
3500 case OP_LET0AST: stream_put (s, BOP_LETAST); break;
3501 case OP_LET0REC: stream_put (s, BOP_LETREC); break;
3502 }
3503
3504 {
3505 pointer bindings = car (x);
3506 pointer body = cadr (x);
3507
3508 for (x = bindings; x != NIL; x = cdr (x))
3509 {
3510 pointer init = NIL;
3511 pointer var = car (x);
3512
3513 if (is_pair (var))
3514 {
3515 init = cdr (var);
3516 var = car (var);
3517 }
3518
3519 stream_put_v (s, symbol_id (SCHEME_A_ var));
3520 compile_expr (SCHEME_A_ s, init);
3521 }
3522
3523 stream_put_v (s, 0);
3524 compile_expr (SCHEME_A_ s, body);
3525 }
3526 break;
3527
3528 case OP_DEF0: /* define */
3529 case OP_MACRO0: /* macro */
3530 stream_put (s, syntaxnum (head) == OP_DEF0 ? BOP_DEFINE : BOP_MACRO);
3531 stream_put_v (s, cell_id (SCHEME_A_ car (x)));
3532 compile_expr (SCHEME_A_ s, cadr (x));
3533 break;
3534
3535 case OP_SET0: /* set! */
3536 stream_put (s, BOP_SET);
3537 stream_put_v (s, symbol_id (SCHEME_A_ car (x)));
3538 compile_expr (SCHEME_A_ s, cadr (x));
3539 break;
3540
3541 case OP_BEGIN: /* begin */
3542 stream_put (s, BOP_BEGIN);
3543 compile_list (SCHEME_A_ s, x);
3544 return;
3545
3546 case OP_DELAY: /* delay */
3547 abort ();
3548 break;
3549
3550 case OP_QUOTE: /* quote */
3551 stream_put_tv (s, BOP_DATUM, cell_id (SCHEME_A_ x));
3552 break;
3553
3554 case OP_LAMBDA: /* lambda */
3555 {
3556 pointer formals = car (x);
3557 pointer body = cadr (x);
3558
3559 stream_put (s, BOP_LAMBDA);
3560
3561 for (; is_pair (formals); formals = cdr (formals))
3562 stream_put_v (s, symbol_id (SCHEME_A_ car (formals)));
3563
3564 stream_put_v (s, 0);
3565 stream_put_v (s, formals == NIL ? 0 : symbol_id (SCHEME_A_ formals));
3566
3567 compile_expr (SCHEME_A_ s, body);
3568 }
3569 break;
3570
3571 case OP_C0STREAM:/* cons-stream */
3572 abort ();
3573 break;
3574 }
3575
3576 return;
3577 }
3578
3579 pointer m = find_slot_in_env (SCHEME_A_ SCHEME_V->envir, head, 1);
3580
3581 if (m != NIL)
3582 {
3583 m = slot_value_in_env (m);
3584
3585 if (is_macro (m))
3586 {
3587 s_save (SCHEME_A_ OP_DEBUG2, SCHEME_V->args, SCHEME_V->code);
3588 SCHEME_V->code = m;
3589 SCHEME_V->args = cons (x, NIL);
3590 Eval_Cycle (SCHEME_A_ OP_APPLY);
3591 x = SCHEME_V->value;
3592 compile_expr (SCHEME_A_ s, SCHEME_V->value);
3593 return;
3594 }
3595 }
3596 }
3597
3598 switch (type (x))
3599 {
3600 case T_INTEGER:
3601 {
3602 IVALUE iv = ivalue_unchecked (x);
3603 iv = iv < 0 ? ((uint32_t)-iv << 1) | 1 : (uint32_t)iv << 1;
3604 stream_put_tv (s, BOP_INTEGER, iv);
3605 }
3606 return;
3607
3608 case T_SYMBOL:
3609 stream_put_tv (s, BOP_SYMBOL, symbol_id (SCHEME_A_ x));
3610 return;
3611
3612 case T_PAIR:
3613 stream_put (s, BOP_LIST_BEG);
3614
3615 for (; x != NIL; x = cdr (x))
3616 compile_expr (SCHEME_A_ s, car (x));
3617
3618 stream_put (s, BOP_LIST_END);
3619 return;
3620
3621 default:
3622 stream_put_tv (s, BOP_DATUM, cell_id (SCHEME_A_ x));
3623 break;
3624 }
3625}
3626
3627ecb_cold static int
3628compile_closure (SCHEME_P_ pointer p)
3629{
3630 stream s = stream_init ();
3631
3632 compile_list (SCHEME_A_ s, cdar (p));
3633
3634 FILE *xxd = popen ("xxd", "we");
3635 fwrite (stream_data (s), 1, stream_size (s), xxd);
3636 fclose (xxd);
3637
3638 return stream_size (s);
3639}
3640
3306#endif 3641#endif
3307 3642
3308/* syntax, eval, core, ... */ 3643/* syntax, eval, core, ... */
3309ecb_hot static int 3644ecb_hot static int
3310opexe_0 (SCHEME_P_ enum scheme_opcodes op) 3645opexe_0 (SCHEME_P_ enum scheme_opcodes op)
3314 3649
3315 switch (op) 3650 switch (op)
3316 { 3651 {
3317#if EXPERIMENT //D 3652#if EXPERIMENT //D
3318 case OP_DEBUG: 3653 case OP_DEBUG:
3319 printf ("len = %d\n", debug (SCHEME_A_ 0, args) / 8); 3654 {
3655 uint32_t len = compile_closure (SCHEME_A_ car (args));
3656 printf ("len = %d\n", len);
3320 printf ("\n"); 3657 printf ("\n");
3321 s_return (S_T); 3658 s_return (S_T);
3659 }
3660
3661 case OP_DEBUG2:
3662 return -1;
3322#endif 3663#endif
3664
3323 case OP_LOAD: /* load */ 3665 case OP_LOAD: /* load */
3324 if (file_interactive (SCHEME_A)) 3666 if (file_interactive (SCHEME_A))
3325 { 3667 {
3326 putstr (SCHEME_A_ "Loading "); putstr (SCHEME_A_ strvalue (car (args))); putstr (SCHEME_A_ "\n"); 3668 putstr (SCHEME_A_ "Loading ");
3327 //D fprintf (port (SCHEME_V->outport)->rep.stdio.file, "Loading %s\n", strvalue (car (args))); 3669 putstr (SCHEME_A_ strvalue (car (args)));
3670 putcharacter (SCHEME_A_ '\n');
3328 } 3671 }
3329 3672
3330 if (!file_push (SCHEME_A_ strvalue (car (args)))) 3673 if (!file_push (SCHEME_A_ strvalue (car (args))))
3331 Error_1 ("unable to open", car (args)); 3674 Error_1 ("unable to open", car (args));
3332 else 3675
3333 {
3334 SCHEME_V->args = mk_integer (SCHEME_A_ SCHEME_V->file_i); 3676 SCHEME_V->args = mk_integer (SCHEME_A_ SCHEME_V->file_i);
3335 s_goto (OP_T0LVL); 3677 s_goto (OP_T0LVL);
3336 }
3337 3678
3338 case OP_T0LVL: /* top level */ 3679 case OP_T0LVL: /* top level */
3339 3680
3340 /* If we reached the end of file, this loop is done. */ 3681 /* If we reached the end of file, this loop is done. */
3341 if (port (SCHEME_V->loadport)->kind & port_saw_EOF) 3682 if (port (SCHEME_V->loadport)->kind & port_saw_EOF)
3357 /* If interactive, be nice to user. */ 3698 /* If interactive, be nice to user. */
3358 if (file_interactive (SCHEME_A)) 3699 if (file_interactive (SCHEME_A))
3359 { 3700 {
3360 SCHEME_V->envir = SCHEME_V->global_env; 3701 SCHEME_V->envir = SCHEME_V->global_env;
3361 dump_stack_reset (SCHEME_A); 3702 dump_stack_reset (SCHEME_A);
3362 putstr (SCHEME_A_ "\n"); 3703 putcharacter (SCHEME_A_ '\n');
3704#if EXPERIMENT
3705 system ("ps v $PPID");
3706#endif
3363 putstr (SCHEME_A_ prompt); 3707 putstr (SCHEME_A_ prompt);
3364 } 3708 }
3365 3709
3366 /* Set up another iteration of REPL */ 3710 /* Set up another iteration of REPL */
3367 SCHEME_V->nesting = 0; 3711 SCHEME_V->nesting = 0;
3402 { 3746 {
3403 SCHEME_V->print_flag = 1; 3747 SCHEME_V->print_flag = 1;
3404 SCHEME_V->args = SCHEME_V->value; 3748 SCHEME_V->args = SCHEME_V->value;
3405 s_goto (OP_P0LIST); 3749 s_goto (OP_P0LIST);
3406 } 3750 }
3407 else 3751
3408 s_return (SCHEME_V->value); 3752 s_return (SCHEME_V->value);
3409 3753
3410 case OP_EVAL: /* main part of evaluation */ 3754 case OP_EVAL: /* main part of evaluation */
3411#if USE_TRACING 3755#if USE_TRACING
3412 if (SCHEME_V->tracing) 3756 if (SCHEME_V->tracing)
3413 { 3757 {
3446 /* If no macros => s_save(SCHEME_A_ OP_E1ARGS, NIL, cdr(SCHEME_V->code)); */ 3790 /* If no macros => s_save(SCHEME_A_ OP_E1ARGS, NIL, cdr(SCHEME_V->code)); */
3447 SCHEME_V->code = x; 3791 SCHEME_V->code = x;
3448 s_goto (OP_EVAL); 3792 s_goto (OP_EVAL);
3449 } 3793 }
3450 } 3794 }
3451 else 3795
3452 s_return (SCHEME_V->code); 3796 s_return (SCHEME_V->code);
3453 3797
3454 case OP_E0ARGS: /* eval arguments */ 3798 case OP_E0ARGS: /* eval arguments */
3455 if (ecb_expect_false (is_macro (SCHEME_V->value))) /* macro expansion */ 3799 if (ecb_expect_false (is_macro (SCHEME_V->value))) /* macro expansion */
3456 { 3800 {
3457 s_save (SCHEME_A_ OP_DOMACRO, NIL, NIL); 3801 s_save (SCHEME_A_ OP_DOMACRO, NIL, NIL);
3458 SCHEME_V->args = cons (SCHEME_V->code, NIL); 3802 SCHEME_V->args = cons (SCHEME_V->code, NIL);
3459 SCHEME_V->code = SCHEME_V->value; 3803 SCHEME_V->code = SCHEME_V->value;
3460 s_goto (OP_APPLY); 3804 s_goto (OP_APPLY);
3461 } 3805 }
3462 else 3806
3463 {
3464 SCHEME_V->code = cdr (SCHEME_V->code); 3807 SCHEME_V->code = cdr (SCHEME_V->code);
3465 s_goto (OP_E1ARGS); 3808 s_goto (OP_E1ARGS);
3466 }
3467 3809
3468 case OP_E1ARGS: /* eval arguments */ 3810 case OP_E1ARGS: /* eval arguments */
3469 args = cons (SCHEME_V->value, args); 3811 args = cons (SCHEME_V->value, args);
3470 3812
3471 if (is_pair (SCHEME_V->code)) /* continue */ 3813 if (is_pair (SCHEME_V->code)) /* continue */
3482 SCHEME_V->args = cdr (args); 3824 SCHEME_V->args = cdr (args);
3483 s_goto (OP_APPLY); 3825 s_goto (OP_APPLY);
3484 } 3826 }
3485 3827
3486#if USE_TRACING 3828#if USE_TRACING
3487
3488 case OP_TRACING: 3829 case OP_TRACING:
3489 { 3830 {
3490 int tr = SCHEME_V->tracing; 3831 int tr = SCHEME_V->tracing;
3491 3832
3492 SCHEME_V->tracing = ivalue_unchecked (car (args)); 3833 SCHEME_V->tracing = ivalue_unchecked (car (args));
3493 s_return (mk_integer (SCHEME_A_ tr)); 3834 s_return (mk_integer (SCHEME_A_ tr));
3494 } 3835 }
3495
3496#endif 3836#endif
3497 3837
3498 case OP_APPLY: /* apply 'code' to 'args' */ 3838 case OP_APPLY: /* apply 'code' to 'args' */
3499#if USE_TRACING 3839#if USE_TRACING
3500 if (SCHEME_V->tracing) 3840 if (SCHEME_V->tracing)
3554 else if (is_continuation (SCHEME_V->code)) /* CONTINUATION */ 3894 else if (is_continuation (SCHEME_V->code)) /* CONTINUATION */
3555 { 3895 {
3556 ss_set_cont (SCHEME_A_ cont_dump (SCHEME_V->code)); 3896 ss_set_cont (SCHEME_A_ cont_dump (SCHEME_V->code));
3557 s_return (args != NIL ? car (args) : NIL); 3897 s_return (args != NIL ? car (args) : NIL);
3558 } 3898 }
3559 else 3899
3560 Error_0 ("illegal function"); 3900 Error_0 ("illegal function");
3561 3901
3562 case OP_DOMACRO: /* do macro */ 3902 case OP_DOMACRO: /* do macro */
3563 SCHEME_V->code = SCHEME_V->value; 3903 SCHEME_V->code = SCHEME_V->value;
3564 s_goto (OP_EVAL); 3904 s_goto (OP_EVAL);
3565 3905
3629 else 3969 else
3630 new_slot_in_env (SCHEME_A_ SCHEME_V->code, SCHEME_V->value); 3970 new_slot_in_env (SCHEME_A_ SCHEME_V->code, SCHEME_V->value);
3631 3971
3632 s_return (SCHEME_V->code); 3972 s_return (SCHEME_V->code);
3633 3973
3634
3635 case OP_DEFP: /* defined? */ 3974 case OP_DEFP: /* defined? */
3636 x = SCHEME_V->envir; 3975 x = SCHEME_V->envir;
3637 3976
3638 if (cdr (args) != NIL) 3977 if (cdr (args) != NIL)
3639 x = cadr (args); 3978 x = cadr (args);
3657 s_return (SCHEME_V->value); 3996 s_return (SCHEME_V->value);
3658 } 3997 }
3659 else 3998 else
3660 Error_1 ("set!: unbound variable:", SCHEME_V->code); 3999 Error_1 ("set!: unbound variable:", SCHEME_V->code);
3661 4000
3662
3663 case OP_BEGIN: /* begin */ 4001 case OP_BEGIN: /* begin */
3664 if (!is_pair (SCHEME_V->code)) 4002 if (!is_pair (SCHEME_V->code))
3665 s_return (SCHEME_V->code); 4003 s_return (SCHEME_V->code);
3666 4004
3667 if (cdr (SCHEME_V->code) != NIL) 4005 if (cdr (SCHEME_V->code) != NIL)
3678 case OP_IF1: /* if */ 4016 case OP_IF1: /* if */
3679 if (is_true (SCHEME_V->value)) 4017 if (is_true (SCHEME_V->value))
3680 SCHEME_V->code = car (SCHEME_V->code); 4018 SCHEME_V->code = car (SCHEME_V->code);
3681 else 4019 else
3682 SCHEME_V->code = cadr (SCHEME_V->code); /* (if #f 1) ==> () because * car(NIL) = NIL */ 4020 SCHEME_V->code = cadr (SCHEME_V->code); /* (if #f 1) ==> () because * car(NIL) = NIL */
4021
3683 s_goto (OP_EVAL); 4022 s_goto (OP_EVAL);
3684 4023
3685 case OP_LET0: /* let */ 4024 case OP_LET0: /* let */
3686 SCHEME_V->args = NIL; 4025 SCHEME_V->args = NIL;
3687 SCHEME_V->value = SCHEME_V->code; 4026 SCHEME_V->value = SCHEME_V->code;
3688 SCHEME_V->code = is_symbol (car (SCHEME_V->code)) ? cadr (SCHEME_V->code) : car (SCHEME_V->code); 4027 SCHEME_V->code = is_symbol (car (SCHEME_V->code)) ? cadr (SCHEME_V->code) : car (SCHEME_V->code);
3689 s_goto (OP_LET1); 4028 s_goto (OP_LET1);
3690 4029
3691 case OP_LET1: /* let (calculate parameters) */ 4030 case OP_LET1: /* let (calculate parameters) */
4031 case OP_LET1REC: /* letrec (calculate parameters) */
3692 args = cons (SCHEME_V->value, args); 4032 args = cons (SCHEME_V->value, args);
3693 4033
3694 if (is_pair (SCHEME_V->code)) /* continue */ 4034 if (is_pair (SCHEME_V->code)) /* continue */
3695 { 4035 {
3696 if (!is_pair (car (SCHEME_V->code)) || !is_pair (cdar (SCHEME_V->code))) 4036 if (!is_pair (car (SCHEME_V->code)) || !is_pair (cdar (SCHEME_V->code)))
3697 Error_1 ("Bad syntax of binding spec in let :", car (SCHEME_V->code)); 4037 Error_1 ("Bad syntax of binding spec in let/letrec:", car (SCHEME_V->code));
3698 4038
3699 s_save (SCHEME_A_ OP_LET1, args, cdr (SCHEME_V->code)); 4039 s_save (SCHEME_A_ op, args, cdr (SCHEME_V->code));
3700 SCHEME_V->code = cadar (SCHEME_V->code); 4040 SCHEME_V->code = cadar (SCHEME_V->code);
3701 SCHEME_V->args = NIL; 4041 SCHEME_V->args = NIL;
3702 s_goto (OP_EVAL); 4042 s_goto (OP_EVAL);
3703 } 4043 }
3704 else /* end */ 4044
3705 { 4045 /* end */
3706 args = reverse_in_place (SCHEME_A_ NIL, args); 4046 args = reverse_in_place (SCHEME_A_ NIL, args);
3707 SCHEME_V->code = car (args); 4047 SCHEME_V->code = car (args);
3708 SCHEME_V->args = cdr (args); 4048 SCHEME_V->args = cdr (args);
3709 s_goto (OP_LET2); 4049 s_goto (op == OP_LET1 ? OP_LET2 : OP_LET2REC);
3710 }
3711 4050
3712 case OP_LET2: /* let */ 4051 case OP_LET2: /* let */
3713 new_frame_in_env (SCHEME_A_ SCHEME_V->envir); 4052 new_frame_in_env (SCHEME_A_ SCHEME_V->envir);
3714 4053
3715 for (x = is_symbol (car (SCHEME_V->code)) ? cadr (SCHEME_V->code) : car (SCHEME_V->code), y = args; 4054 for (x = is_symbol (car (SCHEME_V->code)) ? cadr (SCHEME_V->code) : car (SCHEME_V->code), y = args;
3719 if (is_symbol (car (SCHEME_V->code))) /* named let */ 4058 if (is_symbol (car (SCHEME_V->code))) /* named let */
3720 { 4059 {
3721 for (x = cadr (SCHEME_V->code), args = NIL; x != NIL; x = cdr (x)) 4060 for (x = cadr (SCHEME_V->code), args = NIL; x != NIL; x = cdr (x))
3722 { 4061 {
3723 if (!is_pair (x)) 4062 if (!is_pair (x))
3724 Error_1 ("Bad syntax of binding in let :", x); 4063 Error_1 ("Bad syntax of binding in let:", x);
3725 4064
3726 if (!is_list (SCHEME_A_ car (x))) 4065 if (!is_list (SCHEME_A_ car (x)))
3727 Error_1 ("Bad syntax of binding in let :", car (x)); 4066 Error_1 ("Bad syntax of binding in let:", car (x));
3728 4067
3729 args = cons (caar (x), args); 4068 args = cons (caar (x), args);
3730 } 4069 }
3731 4070
3732 x = mk_closure (SCHEME_A_ cons (reverse_in_place (SCHEME_A_ NIL, args), cddr (SCHEME_V->code)), 4071 x = mk_closure (SCHEME_A_ cons (reverse_in_place (SCHEME_A_ NIL, args), cddr (SCHEME_V->code)),
3749 SCHEME_V->code = cdr (SCHEME_V->code); 4088 SCHEME_V->code = cdr (SCHEME_V->code);
3750 s_goto (OP_BEGIN); 4089 s_goto (OP_BEGIN);
3751 } 4090 }
3752 4091
3753 if (!is_pair (car (SCHEME_V->code)) || !is_pair (caar (SCHEME_V->code)) || !is_pair (cdaar (SCHEME_V->code))) 4092 if (!is_pair (car (SCHEME_V->code)) || !is_pair (caar (SCHEME_V->code)) || !is_pair (cdaar (SCHEME_V->code)))
3754 Error_1 ("Bad syntax of binding spec in let* :", car (SCHEME_V->code)); 4093 Error_1 ("Bad syntax of binding spec in let*:", car (SCHEME_V->code));
3755 4094
3756 s_save (SCHEME_A_ OP_LET1AST, cdr (SCHEME_V->code), car (SCHEME_V->code)); 4095 s_save (SCHEME_A_ OP_LET1AST, cdr (SCHEME_V->code), car (SCHEME_V->code));
3757 SCHEME_V->code = car (cdaar (SCHEME_V->code)); 4096 SCHEME_V->code = car (cdaar (SCHEME_V->code));
3758 s_goto (OP_EVAL); 4097 s_goto (OP_EVAL);
3759 4098
3770 s_save (SCHEME_A_ OP_LET2AST, args, SCHEME_V->code); 4109 s_save (SCHEME_A_ OP_LET2AST, args, SCHEME_V->code);
3771 SCHEME_V->code = cadar (SCHEME_V->code); 4110 SCHEME_V->code = cadar (SCHEME_V->code);
3772 SCHEME_V->args = NIL; 4111 SCHEME_V->args = NIL;
3773 s_goto (OP_EVAL); 4112 s_goto (OP_EVAL);
3774 } 4113 }
3775 else /* end */ 4114
4115 /* end */
3776 { 4116
3777 SCHEME_V->code = args; 4117 SCHEME_V->code = args;
3778 SCHEME_V->args = NIL; 4118 SCHEME_V->args = NIL;
3779 s_goto (OP_BEGIN); 4119 s_goto (OP_BEGIN);
3780 }
3781 4120
3782 case OP_LET0REC: /* letrec */ 4121 case OP_LET0REC: /* letrec */
3783 new_frame_in_env (SCHEME_A_ SCHEME_V->envir); 4122 new_frame_in_env (SCHEME_A_ SCHEME_V->envir);
3784 SCHEME_V->args = NIL; 4123 SCHEME_V->args = NIL;
3785 SCHEME_V->value = SCHEME_V->code; 4124 SCHEME_V->value = SCHEME_V->code;
3786 SCHEME_V->code = car (SCHEME_V->code); 4125 SCHEME_V->code = car (SCHEME_V->code);
3787 s_goto (OP_LET1REC); 4126 s_goto (OP_LET1REC);
3788 4127
3789 case OP_LET1REC: /* letrec (calculate parameters) */ 4128 /* OP_LET1REC handled by OP_LET1 */
3790 args = cons (SCHEME_V->value, args);
3791
3792 if (is_pair (SCHEME_V->code)) /* continue */
3793 {
3794 if (!is_pair (car (SCHEME_V->code)) || !is_pair (cdar (SCHEME_V->code)))
3795 Error_1 ("Bad syntax of binding spec in letrec :", car (SCHEME_V->code));
3796
3797 s_save (SCHEME_A_ OP_LET1REC, args, cdr (SCHEME_V->code));
3798 SCHEME_V->code = cadar (SCHEME_V->code);
3799 SCHEME_V->args = NIL;
3800 s_goto (OP_EVAL);
3801 }
3802 else /* end */
3803 {
3804 args = reverse_in_place (SCHEME_A_ NIL, args);
3805 SCHEME_V->code = car (args);
3806 SCHEME_V->args = cdr (args);
3807 s_goto (OP_LET2REC);
3808 }
3809 4129
3810 case OP_LET2REC: /* letrec */ 4130 case OP_LET2REC: /* letrec */
3811 for (x = car (SCHEME_V->code), y = args; y != NIL; x = cdr (x), y = cdr (y)) 4131 for (x = car (SCHEME_V->code), y = args; y != NIL; x = cdr (x), y = cdr (y))
3812 new_slot_in_env (SCHEME_A_ caar (x), car (y)); 4132 new_slot_in_env (SCHEME_A_ caar (x), car (y));
3813 4133
3843 } 4163 }
3844 else 4164 else
3845 { 4165 {
3846 if ((SCHEME_V->code = cdr (SCHEME_V->code)) == NIL) 4166 if ((SCHEME_V->code = cdr (SCHEME_V->code)) == NIL)
3847 s_return (NIL); 4167 s_return (NIL);
3848 else 4168
3849 {
3850 s_save (SCHEME_A_ OP_COND1, NIL, SCHEME_V->code); 4169 s_save (SCHEME_A_ OP_COND1, NIL, SCHEME_V->code);
3851 SCHEME_V->code = caar (SCHEME_V->code); 4170 SCHEME_V->code = caar (SCHEME_V->code);
3852 s_goto (OP_EVAL); 4171 s_goto (OP_EVAL);
3853 }
3854 } 4172 }
3855 4173
3856 case OP_DELAY: /* delay */ 4174 case OP_DELAY: /* delay */
3857 x = mk_closure (SCHEME_A_ cons (NIL, SCHEME_V->code), SCHEME_V->envir); 4175 x = mk_closure (SCHEME_A_ cons (NIL, SCHEME_V->code), SCHEME_V->envir);
3858 set_typeflag (x, T_PROMISE); 4176 set_typeflag (x, T_PROMISE);
3869 case OP_AND1: /* and */ 4187 case OP_AND1: /* and */
3870 if (is_false (SCHEME_V->value)) 4188 if (is_false (SCHEME_V->value))
3871 s_return (SCHEME_V->value); 4189 s_return (SCHEME_V->value);
3872 else if (SCHEME_V->code == NIL) 4190 else if (SCHEME_V->code == NIL)
3873 s_return (SCHEME_V->value); 4191 s_return (SCHEME_V->value);
3874 else 4192
3875 {
3876 s_save (SCHEME_A_ OP_AND1, NIL, cdr (SCHEME_V->code)); 4193 s_save (SCHEME_A_ OP_AND1, NIL, cdr (SCHEME_V->code));
3877 SCHEME_V->code = car (SCHEME_V->code); 4194 SCHEME_V->code = car (SCHEME_V->code);
3878 s_goto (OP_EVAL); 4195 s_goto (OP_EVAL);
3879 }
3880 4196
3881 case OP_OR0: /* or */ 4197 case OP_OR0: /* or */
3882 if (SCHEME_V->code == NIL) 4198 if (SCHEME_V->code == NIL)
3883 s_return (S_F); 4199 s_return (S_F);
3884 4200
3889 case OP_OR1: /* or */ 4205 case OP_OR1: /* or */
3890 if (is_true (SCHEME_V->value)) 4206 if (is_true (SCHEME_V->value))
3891 s_return (SCHEME_V->value); 4207 s_return (SCHEME_V->value);
3892 else if (SCHEME_V->code == NIL) 4208 else if (SCHEME_V->code == NIL)
3893 s_return (SCHEME_V->value); 4209 s_return (SCHEME_V->value);
3894 else 4210
3895 {
3896 s_save (SCHEME_A_ OP_OR1, NIL, cdr (SCHEME_V->code)); 4211 s_save (SCHEME_A_ OP_OR1, NIL, cdr (SCHEME_V->code));
3897 SCHEME_V->code = car (SCHEME_V->code); 4212 SCHEME_V->code = car (SCHEME_V->code);
3898 s_goto (OP_EVAL); 4213 s_goto (OP_EVAL);
3899 }
3900 4214
3901 case OP_C0STREAM: /* cons-stream */ 4215 case OP_C0STREAM: /* cons-stream */
3902 s_save (SCHEME_A_ OP_C1STREAM, NIL, cdr (SCHEME_V->code)); 4216 s_save (SCHEME_A_ OP_C1STREAM, NIL, cdr (SCHEME_V->code));
3903 SCHEME_V->code = car (SCHEME_V->code); 4217 SCHEME_V->code = car (SCHEME_V->code);
3904 s_goto (OP_EVAL); 4218 s_goto (OP_EVAL);
3969 s_save (SCHEME_A_ OP_CASE2, NIL, cdar (x)); 4283 s_save (SCHEME_A_ OP_CASE2, NIL, cdar (x));
3970 SCHEME_V->code = caar (x); 4284 SCHEME_V->code = caar (x);
3971 s_goto (OP_EVAL); 4285 s_goto (OP_EVAL);
3972 } 4286 }
3973 } 4287 }
3974 else 4288
3975 s_return (NIL); 4289 s_return (NIL);
3976 4290
3977 case OP_CASE2: /* case */ 4291 case OP_CASE2: /* case */
3978 if (is_true (SCHEME_V->value)) 4292 if (is_true (SCHEME_V->value))
3979 s_goto (OP_BEGIN); 4293 s_goto (OP_BEGIN);
3980 else 4294
3981 s_return (NIL); 4295 s_return (NIL);
3982 4296
3983 case OP_PAPPLY: /* apply */ 4297 case OP_PAPPLY: /* apply */
3984 SCHEME_V->code = car (args); 4298 SCHEME_V->code = car (args);
3985 SCHEME_V->args = list_star (SCHEME_A_ cdr (args)); 4299 SCHEME_V->args = list_star (SCHEME_A_ cdr (args));
3986 /*SCHEME_V->args = cadr(args); */ 4300 /*SCHEME_V->args = cadr(args); */
4636 else 4950 else
4637 SCHEME_V->print_flag = 0; 4951 SCHEME_V->print_flag = 0;
4638 4952
4639 s_goto (OP_P0LIST); 4953 s_goto (OP_P0LIST);
4640 4954
4955 //TODO: move to scheme
4641 case OP_NEWLINE: /* newline */ 4956 case OP_NEWLINE: /* newline */
4642 if (is_pair (args)) 4957 if (is_pair (args))
4643 { 4958 {
4644 if (a != SCHEME_V->outport) 4959 if (a != SCHEME_V->outport)
4645 { 4960 {
4647 s_save (SCHEME_A_ OP_SET_OUTPORT, x, NIL); 4962 s_save (SCHEME_A_ OP_SET_OUTPORT, x, NIL);
4648 SCHEME_V->outport = a; 4963 SCHEME_V->outport = a;
4649 } 4964 }
4650 } 4965 }
4651 4966
4652 putstr (SCHEME_A_ "\n"); 4967 putcharacter (SCHEME_A_ '\n');
4653 s_return (S_T); 4968 s_return (S_T);
4654#endif 4969#endif
4655 4970
4656 case OP_ERR0: /* error */ 4971 case OP_ERR0: /* error */
4657 SCHEME_V->retcode = -1; 4972 SCHEME_V->retcode = -1;
4666 putstr (SCHEME_A_ strvalue (car (args))); 4981 putstr (SCHEME_A_ strvalue (car (args)));
4667 SCHEME_V->args = cdr (args); 4982 SCHEME_V->args = cdr (args);
4668 s_goto (OP_ERR1); 4983 s_goto (OP_ERR1);
4669 4984
4670 case OP_ERR1: /* error */ 4985 case OP_ERR1: /* error */
4671 putstr (SCHEME_A_ " "); 4986 putcharacter (SCHEME_A_ ' ');
4672 4987
4673 if (args != NIL) 4988 if (args != NIL)
4674 { 4989 {
4675 s_save (SCHEME_A_ OP_ERR1, cdr (args), NIL); 4990 s_save (SCHEME_A_ OP_ERR1, cdr (args), NIL);
4676 SCHEME_V->args = a; 4991 SCHEME_V->args = a;
4677 SCHEME_V->print_flag = 1; 4992 SCHEME_V->print_flag = 1;
4678 s_goto (OP_P0LIST); 4993 s_goto (OP_P0LIST);
4679 } 4994 }
4680 else 4995 else
4681 { 4996 {
4682 putstr (SCHEME_A_ "\n"); 4997 putcharacter (SCHEME_A_ '\n');
4683 4998
4684 if (SCHEME_V->interactive_repl) 4999 if (SCHEME_V->interactive_repl)
4685 s_goto (OP_T0LVL); 5000 s_goto (OP_T0LVL);
4686 else 5001 else
4687 return -1; 5002 return -1;
4985 case OP_RDSEXPR: 5300 case OP_RDSEXPR:
4986 switch (SCHEME_V->tok) 5301 switch (SCHEME_V->tok)
4987 { 5302 {
4988 case TOK_EOF: 5303 case TOK_EOF:
4989 s_return (S_EOF); 5304 s_return (S_EOF);
4990 /* NOTREACHED */
4991 5305
4992 case TOK_VEC: 5306 case TOK_VEC:
4993 s_save (SCHEME_A_ OP_RDVEC, NIL, NIL); 5307 s_save (SCHEME_A_ OP_RDVEC, NIL, NIL);
4994 /* fall through */ 5308 /* fall through */
4995 5309
4998 5312
4999 if (SCHEME_V->tok == TOK_RPAREN) 5313 if (SCHEME_V->tok == TOK_RPAREN)
5000 s_return (NIL); 5314 s_return (NIL);
5001 else if (SCHEME_V->tok == TOK_DOT) 5315 else if (SCHEME_V->tok == TOK_DOT)
5002 Error_0 ("syntax error: illegal dot expression"); 5316 Error_0 ("syntax error: illegal dot expression");
5003 else 5317
5004 {
5005 SCHEME_V->nesting_stack[SCHEME_V->file_i]++; 5318 SCHEME_V->nesting_stack[SCHEME_V->file_i]++;
5006 s_save (SCHEME_A_ OP_RDLIST, NIL, NIL); 5319 s_save (SCHEME_A_ OP_RDLIST, NIL, NIL);
5007 s_goto (OP_RDSEXPR); 5320 s_goto (OP_RDSEXPR);
5008 }
5009 5321
5010 case TOK_QUOTE: 5322 case TOK_QUOTE:
5011 s_save (SCHEME_A_ OP_RDQUOTE, NIL, NIL); 5323 s_save (SCHEME_A_ OP_RDQUOTE, NIL, NIL);
5012 SCHEME_V->tok = token (SCHEME_A); 5324 SCHEME_V->tok = token (SCHEME_A);
5013 s_goto (OP_RDSEXPR); 5325 s_goto (OP_RDSEXPR);
5019 { 5331 {
5020 s_save (SCHEME_A_ OP_RDQQUOTEVEC, NIL, NIL); 5332 s_save (SCHEME_A_ OP_RDQQUOTEVEC, NIL, NIL);
5021 SCHEME_V->tok = TOK_LPAREN; 5333 SCHEME_V->tok = TOK_LPAREN;
5022 s_goto (OP_RDSEXPR); 5334 s_goto (OP_RDSEXPR);
5023 } 5335 }
5024 else 5336
5025 s_save (SCHEME_A_ OP_RDQQUOTE, NIL, NIL); 5337 s_save (SCHEME_A_ OP_RDQQUOTE, NIL, NIL);
5026
5027 s_goto (OP_RDSEXPR); 5338 s_goto (OP_RDSEXPR);
5028 5339
5029 case TOK_COMMA: 5340 case TOK_COMMA:
5030 s_save (SCHEME_A_ OP_RDUNQUOTE, NIL, NIL); 5341 s_save (SCHEME_A_ OP_RDUNQUOTE, NIL, NIL);
5031 SCHEME_V->tok = token (SCHEME_A); 5342 SCHEME_V->tok = token (SCHEME_A);
5042 case TOK_DOTATOM: 5353 case TOK_DOTATOM:
5043 SCHEME_V->strbuff[0] = '.'; 5354 SCHEME_V->strbuff[0] = '.';
5044 s_return (mk_atom (SCHEME_A_ readstr_upto (SCHEME_A_ 1, DELIMITERS))); 5355 s_return (mk_atom (SCHEME_A_ readstr_upto (SCHEME_A_ 1, DELIMITERS)));
5045 5356
5046 case TOK_STRATOM: 5357 case TOK_STRATOM:
5358 //TODO: haven't checked whether the garbage collector could interfere and free x
5359 gc (SCHEME_A_ NIL, NIL); //TODO: superheavyhanded
5047 x = readstrexp (SCHEME_A_ '|'); 5360 x = readstrexp (SCHEME_A_ '|');
5048 //TODO: haven't checked whether the garbage collector could interfere
5049 s_return (mk_atom (SCHEME_A_ strvalue (x))); 5361 s_return (mk_atom (SCHEME_A_ strvalue (x)));
5050 5362
5051 case TOK_DQUOTE: 5363 case TOK_DQUOTE:
5052 x = readstrexp (SCHEME_A_ '"'); 5364 x = readstrexp (SCHEME_A_ '"');
5053 5365
5061 { 5373 {
5062 pointer f = find_slot_in_env (SCHEME_A_ SCHEME_V->envir, SCHEME_V->SHARP_HOOK, 1); 5374 pointer f = find_slot_in_env (SCHEME_A_ SCHEME_V->envir, SCHEME_V->SHARP_HOOK, 1);
5063 5375
5064 if (f == NIL) 5376 if (f == NIL)
5065 Error_0 ("undefined sharp expression"); 5377 Error_0 ("undefined sharp expression");
5066 else 5378
5067 {
5068 SCHEME_V->code = cons (slot_value_in_env (f), NIL); 5379 SCHEME_V->code = cons (slot_value_in_env (f), NIL);
5069 s_goto (OP_EVAL); 5380 s_goto (OP_EVAL);
5070 }
5071 } 5381 }
5072 5382
5073 case TOK_SHARP_CONST: 5383 case TOK_SHARP_CONST:
5074 if ((x = mk_sharp_const (SCHEME_A_ readstr_upto (SCHEME_A_ 0, DELIMITERS))) == NIL) 5384 if ((x = mk_sharp_const (SCHEME_A_ readstr_upto (SCHEME_A_ 0, DELIMITERS))) == NIL)
5075 Error_0 ("undefined sharp expression"); 5385 Error_0 ("undefined sharp expression");
5076 else 5386
5077 s_return (x); 5387 s_return (x);
5078 5388
5079 default: 5389 default:
5080 Error_0 ("syntax error: illegal token"); 5390 Error_0 ("syntax error: illegal token");
5081 } 5391 }
5082 5392
5175 pointer b = cdr (args); 5485 pointer b = cdr (args);
5176 int ok_abbr = ok_abbrev (b); 5486 int ok_abbr = ok_abbrev (b);
5177 SCHEME_V->args = car (b); 5487 SCHEME_V->args = car (b);
5178 5488
5179 if (a == SCHEME_V->QUOTE && ok_abbr) 5489 if (a == SCHEME_V->QUOTE && ok_abbr)
5180 putstr (SCHEME_A_ "'"); 5490 putcharacter (SCHEME_A_ '\'');
5181 else if (a == SCHEME_V->QQUOTE && ok_abbr) 5491 else if (a == SCHEME_V->QQUOTE && ok_abbr)
5182 putstr (SCHEME_A_ "`"); 5492 putcharacter (SCHEME_A_ '`');
5183 else if (a == SCHEME_V->UNQUOTE && ok_abbr) 5493 else if (a == SCHEME_V->UNQUOTE && ok_abbr)
5184 putstr (SCHEME_A_ ","); 5494 putcharacter (SCHEME_A_ ',');
5185 else if (a == SCHEME_V->UNQUOTESP && ok_abbr) 5495 else if (a == SCHEME_V->UNQUOTESP && ok_abbr)
5186 putstr (SCHEME_A_ ",@"); 5496 putstr (SCHEME_A_ ",@");
5187 else 5497 else
5188 { 5498 {
5189 putstr (SCHEME_A_ "("); 5499 putcharacter (SCHEME_A_ '(');
5190 s_save (SCHEME_A_ OP_P1LIST, b, NIL); 5500 s_save (SCHEME_A_ OP_P1LIST, b, NIL);
5191 SCHEME_V->args = a; 5501 SCHEME_V->args = a;
5192 } 5502 }
5193 5503
5194 s_goto (OP_P0LIST); 5504 s_goto (OP_P0LIST);
5196 5506
5197 case OP_P1LIST: 5507 case OP_P1LIST:
5198 if (is_pair (args)) 5508 if (is_pair (args))
5199 { 5509 {
5200 s_save (SCHEME_A_ OP_P1LIST, cdr (args), NIL); 5510 s_save (SCHEME_A_ OP_P1LIST, cdr (args), NIL);
5201 putstr (SCHEME_A_ " "); 5511 putcharacter (SCHEME_A_ ' ');
5202 SCHEME_V->args = car (args); 5512 SCHEME_V->args = car (args);
5203 s_goto (OP_P0LIST); 5513 s_goto (OP_P0LIST);
5204 } 5514 }
5205 else if (is_vector (args)) 5515 else if (is_vector (args))
5206 { 5516 {
5214 { 5524 {
5215 putstr (SCHEME_A_ " . "); 5525 putstr (SCHEME_A_ " . ");
5216 printatom (SCHEME_A_ args, SCHEME_V->print_flag); 5526 printatom (SCHEME_A_ args, SCHEME_V->print_flag);
5217 } 5527 }
5218 5528
5219 putstr (SCHEME_A_ ")"); 5529 putcharacter (SCHEME_A_ ')');
5220 s_return (S_T); 5530 s_return (S_T);
5221 } 5531 }
5222 5532
5223 case OP_PVECFROM: 5533 case OP_PVECFROM:
5224 { 5534 {
5226 pointer vec = car (args); 5536 pointer vec = car (args);
5227 int len = veclength (vec); 5537 int len = veclength (vec);
5228 5538
5229 if (i == len) 5539 if (i == len)
5230 { 5540 {
5231 putstr (SCHEME_A_ ")"); 5541 putcharacter (SCHEME_A_ ')');
5232 s_return (S_T); 5542 s_return (S_T);
5233 } 5543 }
5234 else 5544 else
5235 { 5545 {
5236 pointer elem = vector_get (vec, i); 5546 pointer elem = vector_get (vec, i);
5238 ivalue_unchecked (cdr (args)) = i + 1; 5548 ivalue_unchecked (cdr (args)) = i + 1;
5239 s_save (SCHEME_A_ OP_PVECFROM, args, NIL); 5549 s_save (SCHEME_A_ OP_PVECFROM, args, NIL);
5240 SCHEME_V->args = elem; 5550 SCHEME_V->args = elem;
5241 5551
5242 if (i > 0) 5552 if (i > 0)
5243 putstr (SCHEME_A_ " "); 5553 putcharacter (SCHEME_A_ ' ');
5244 5554
5245 s_goto (OP_P0LIST); 5555 s_goto (OP_P0LIST);
5246 } 5556 }
5247 } 5557 }
5248 } 5558 }
5282 break; 5592 break;
5283 } 5593 }
5284 5594
5285 if (is_pair (y)) 5595 if (is_pair (y))
5286 s_return (car (y)); 5596 s_return (car (y));
5287 else 5597
5288 s_return (S_F); 5598 s_return (S_F);
5289
5290 5599
5291 case OP_GET_CLOSURE: /* get-closure-code *//* a.k */ 5600 case OP_GET_CLOSURE: /* get-closure-code *//* a.k */
5292 SCHEME_V->args = a; 5601 SCHEME_V->args = a;
5293 5602
5294 if (SCHEME_V->args == NIL) 5603 if (SCHEME_V->args == NIL)
5295 s_return (S_F); 5604 s_return (S_F);
5296 else if (is_closure (SCHEME_V->args)) 5605 else if (is_closure (SCHEME_V->args) || is_macro (SCHEME_V->args))
5297 s_return (cons (SCHEME_V->LAMBDA, closure_code (SCHEME_V->value))); 5606 s_return (cons (SCHEME_V->LAMBDA, closure_code (SCHEME_V->value)));
5298 else if (is_macro (SCHEME_V->args)) 5607
5299 s_return (cons (SCHEME_V->LAMBDA, closure_code (SCHEME_V->value)));
5300 else
5301 s_return (S_F); 5608 s_return (S_F);
5302 5609
5303 case OP_CLOSUREP: /* closure? */ 5610 case OP_CLOSUREP: /* closure? */
5304 /* 5611 /*
5305 * Note, macro object is also a closure. 5612 * Note, macro object is also a closure.
5306 * Therefore, (closure? <#MACRO>) ==> #t 5613 * Therefore, (closure? <#MACRO>) ==> #t
5678#endif 5985#endif
5679 } 5986 }
5680 5987
5681 SCHEME_V->gc_verbose = 0; 5988 SCHEME_V->gc_verbose = 0;
5682 dump_stack_initialize (SCHEME_A); 5989 dump_stack_initialize (SCHEME_A);
5683 SCHEME_V->code = NIL; 5990 SCHEME_V->code = NIL;
5684 SCHEME_V->args = NIL; 5991 SCHEME_V->args = NIL;
5685 SCHEME_V->envir = NIL; 5992 SCHEME_V->envir = NIL;
5993 SCHEME_V->value = NIL;
5686 SCHEME_V->tracing = 0; 5994 SCHEME_V->tracing = 0;
5687 5995
5688 /* init NIL */ 5996 /* init NIL */
5689 set_typeflag (NIL, T_ATOM | T_MARK); 5997 set_typeflag (NIL, T_ATOM | T_MARK);
5690 set_car (NIL, NIL); 5998 set_car (NIL, NIL);
5813 SCHEME_V->loadport = NIL; 6121 SCHEME_V->loadport = NIL;
5814 SCHEME_V->gc_verbose = 0; 6122 SCHEME_V->gc_verbose = 0;
5815 gc (SCHEME_A_ NIL, NIL); 6123 gc (SCHEME_A_ NIL, NIL);
5816 6124
5817 for (i = 0; i <= SCHEME_V->last_cell_seg; i++) 6125 for (i = 0; i <= SCHEME_V->last_cell_seg; i++)
5818 free (SCHEME_V->alloc_seg[i]); 6126 free (SCHEME_V->cell_seg[i]);
5819 6127
5820#if SHOW_ERROR_LINE 6128#if SHOW_ERROR_LINE
5821 for (i = 0; i <= SCHEME_V->file_i; i++) 6129 for (i = 0; i <= SCHEME_V->file_i; i++)
5822 {
5823 if (SCHEME_V->load_stack[i].kind & port_file) 6130 if (SCHEME_V->load_stack[i].kind & port_file)
5824 { 6131 {
5825 fname = SCHEME_V->load_stack[i].rep.stdio.filename; 6132 fname = SCHEME_V->load_stack[i].rep.stdio.filename;
5826 6133
5827 if (fname) 6134 if (fname)
5828 free (fname); 6135 free (fname);
5829 } 6136 }
5830 }
5831#endif 6137#endif
5832} 6138}
5833 6139
5834ecb_cold void 6140ecb_cold void
5835scheme_load_file (SCHEME_P_ int fin) 6141scheme_load_file (SCHEME_P_ int fin)
5844 SCHEME_V->envir = SCHEME_V->global_env; 6150 SCHEME_V->envir = SCHEME_V->global_env;
5845 SCHEME_V->file_i = 0; 6151 SCHEME_V->file_i = 0;
5846 SCHEME_V->load_stack[0].unget = -1; 6152 SCHEME_V->load_stack[0].unget = -1;
5847 SCHEME_V->load_stack[0].kind = port_input | port_file; 6153 SCHEME_V->load_stack[0].kind = port_input | port_file;
5848 SCHEME_V->load_stack[0].rep.stdio.file = fin; 6154 SCHEME_V->load_stack[0].rep.stdio.file = fin;
5849#if USE_PORTS
5850 SCHEME_V->loadport = mk_port (SCHEME_A_ SCHEME_V->load_stack); 6155 SCHEME_V->loadport = mk_port (SCHEME_A_ SCHEME_V->load_stack);
5851#endif
5852 SCHEME_V->retcode = 0; 6156 SCHEME_V->retcode = 0;
5853 6157
5854#if USE_PORTS
5855 if (fin == STDIN_FILENO) 6158 if (fin == STDIN_FILENO)
5856 SCHEME_V->interactive_repl = 1; 6159 SCHEME_V->interactive_repl = 1;
5857#endif
5858 6160
5859#if USE_PORTS 6161#if USE_PORTS
5860#if SHOW_ERROR_LINE 6162#if SHOW_ERROR_LINE
5861 SCHEME_V->load_stack[0].rep.stdio.curr_line = 0; 6163 SCHEME_V->load_stack[0].rep.stdio.curr_line = 0;
5862 6164
5866#endif 6168#endif
5867 6169
5868 SCHEME_V->inport = SCHEME_V->loadport; 6170 SCHEME_V->inport = SCHEME_V->loadport;
5869 SCHEME_V->args = mk_integer (SCHEME_A_ SCHEME_V->file_i); 6171 SCHEME_V->args = mk_integer (SCHEME_A_ SCHEME_V->file_i);
5870 Eval_Cycle (SCHEME_A_ OP_T0LVL); 6172 Eval_Cycle (SCHEME_A_ OP_T0LVL);
6173
5871 set_typeflag (SCHEME_V->loadport, T_ATOM); 6174 set_typeflag (SCHEME_V->loadport, T_ATOM);
5872 6175
5873 if (SCHEME_V->retcode == 0) 6176 if (SCHEME_V->retcode == 0)
5874 SCHEME_V->retcode = SCHEME_V->nesting != 0; 6177 SCHEME_V->retcode = SCHEME_V->nesting != 0;
5875} 6178}
5876 6179
5877ecb_cold void 6180ecb_cold void
5878scheme_load_string (SCHEME_P_ const char *cmd) 6181scheme_load_string (SCHEME_P_ const char *cmd)
5879{ 6182{
6183#if USE_PORTs
5880 dump_stack_reset (SCHEME_A); 6184 dump_stack_reset (SCHEME_A);
5881 SCHEME_V->envir = SCHEME_V->global_env; 6185 SCHEME_V->envir = SCHEME_V->global_env;
5882 SCHEME_V->file_i = 0; 6186 SCHEME_V->file_i = 0;
5883 SCHEME_V->load_stack[0].kind = port_input | port_string; 6187 SCHEME_V->load_stack[0].kind = port_input | port_string;
5884 SCHEME_V->load_stack[0].rep.string.start = (char *)cmd; /* This func respects const */ 6188 SCHEME_V->load_stack[0].rep.string.start = (char *)cmd; /* This func respects const */
5885 SCHEME_V->load_stack[0].rep.string.past_the_end = (char *)cmd + strlen (cmd); 6189 SCHEME_V->load_stack[0].rep.string.past_the_end = (char *)cmd + strlen (cmd);
5886 SCHEME_V->load_stack[0].rep.string.curr = (char *)cmd; 6190 SCHEME_V->load_stack[0].rep.string.curr = (char *)cmd;
5887#if USE_PORTS
5888 SCHEME_V->loadport = mk_port (SCHEME_A_ SCHEME_V->load_stack); 6191 SCHEME_V->loadport = mk_port (SCHEME_A_ SCHEME_V->load_stack);
5889#endif
5890 SCHEME_V->retcode = 0; 6192 SCHEME_V->retcode = 0;
5891 SCHEME_V->interactive_repl = 0; 6193 SCHEME_V->interactive_repl = 0;
5892 SCHEME_V->inport = SCHEME_V->loadport; 6194 SCHEME_V->inport = SCHEME_V->loadport;
5893 SCHEME_V->args = mk_integer (SCHEME_A_ SCHEME_V->file_i); 6195 SCHEME_V->args = mk_integer (SCHEME_A_ SCHEME_V->file_i);
5894 Eval_Cycle (SCHEME_A_ OP_T0LVL); 6196 Eval_Cycle (SCHEME_A_ OP_T0LVL);
5895 set_typeflag (SCHEME_V->loadport, T_ATOM); 6197 set_typeflag (SCHEME_V->loadport, T_ATOM);
5896 6198
5897 if (SCHEME_V->retcode == 0) 6199 if (SCHEME_V->retcode == 0)
5898 SCHEME_V->retcode = SCHEME_V->nesting != 0; 6200 SCHEME_V->retcode = SCHEME_V->nesting != 0;
6201#else
6202 abort ();
6203#endif
5899} 6204}
5900 6205
5901ecb_cold void 6206ecb_cold void
5902scheme_define (SCHEME_P_ pointer envir, pointer symbol, pointer value) 6207scheme_define (SCHEME_P_ pointer envir, pointer symbol, pointer value)
5903{ 6208{
6008# endif 6313# endif
6009 int fin; 6314 int fin;
6010 char *file_name = InitFile; 6315 char *file_name = InitFile;
6011 int retcode; 6316 int retcode;
6012 int isfile = 1; 6317 int isfile = 1;
6318#if EXPERIMENT
6013 system ("ps v $PPID");//D 6319 system ("ps v $PPID");
6320#endif
6014 6321
6015 if (argc == 2 && strcmp (argv[1], "-?") == 0) 6322 if (argc == 2 && strcmp (argv[1], "-?") == 0)
6016 { 6323 {
6017 putstr (SCHEME_A_ "Usage: tinyscheme -?\n"); 6324 putstr (SCHEME_A_ "Usage: tinyscheme -?\n");
6018 putstr (SCHEME_A_ "or: tinyscheme [<file1> <file2> ...]\n"); 6325 putstr (SCHEME_A_ "or: tinyscheme [<file1> <file2> ...]\n");
6047 } 6354 }
6048#endif 6355#endif
6049 6356
6050 do 6357 do
6051 { 6358 {
6052#if USE_PORTS
6053 if (strcmp (file_name, "-") == 0) 6359 if (strcmp (file_name, "-") == 0)
6054 fin = STDIN_FILENO; 6360 fin = STDIN_FILENO;
6055 else if (strcmp (file_name, "-1") == 0 || strcmp (file_name, "-c") == 0) 6361 else if (strcmp (file_name, "-1") == 0 || strcmp (file_name, "-c") == 0)
6056 { 6362 {
6057 pointer args = NIL; 6363 pointer args = NIL;
6075 scheme_define (SCHEME_A_ SCHEME_V->global_env, mk_symbol (SCHEME_A_ "*args*"), args); 6381 scheme_define (SCHEME_A_ SCHEME_V->global_env, mk_symbol (SCHEME_A_ "*args*"), args);
6076 6382
6077 } 6383 }
6078 else 6384 else
6079 fin = open (file_name, O_RDONLY); 6385 fin = open (file_name, O_RDONLY);
6080#endif
6081 6386
6082 if (isfile && fin < 0) 6387 if (isfile && fin < 0)
6083 { 6388 {
6084 putstr (SCHEME_A_ "Could not open file "); putstr (SCHEME_A_ file_name); putstr (SCHEME_A_ "\n"); 6389 putstr (SCHEME_A_ "Could not open file ");
6390 putstr (SCHEME_A_ file_name);
6391 putcharacter (SCHEME_A_ '\n');
6085 } 6392 }
6086 else 6393 else
6087 { 6394 {
6088 if (isfile) 6395 if (isfile)
6089 scheme_load_named_file (SCHEME_A_ fin, file_name); 6396 scheme_load_named_file (SCHEME_A_ fin, file_name);
6090 else 6397 else
6091 scheme_load_string (SCHEME_A_ file_name); 6398 scheme_load_string (SCHEME_A_ file_name);
6092 6399
6093#if USE_PORTS
6094 if (!isfile || fin != STDIN_FILENO) 6400 if (!isfile || fin != STDIN_FILENO)
6095 { 6401 {
6096 if (SCHEME_V->retcode != 0) 6402 if (SCHEME_V->retcode != 0)
6097 { 6403 {
6098 putstr (SCHEME_A_ "Errors encountered reading "); putstr (SCHEME_A_ file_name); putstr (SCHEME_A_ "\n"); 6404 putstr (SCHEME_A_ "Errors encountered reading ");
6405 putstr (SCHEME_A_ file_name);
6406 putcharacter (SCHEME_A_ '\n');
6099 } 6407 }
6100 6408
6101 if (isfile) 6409 if (isfile)
6102 close (fin); 6410 close (fin);
6103 } 6411 }
6104#endif
6105 } 6412 }
6106 6413
6107 file_name = *argv++; 6414 file_name = *argv++;
6108 } 6415 }
6109 while (file_name != 0); 6416 while (file_name != 0);

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines