24 #define _SCHEME_SOURCE
44 #define stricmp strcasecmp
62 #define TOK_SHARP_CONST 11
65 # define BACKQUOTE '`'
71 #define banner "TinyScheme 1.35"
82 static int stricmp(
const char *s1,
const char *s2)
99 static const char *strlwr(
char *s) {
102 *s=tolower((
int) *s);
114 # define InitFile "init.scm"
117 #ifndef FIRST_CELLSEGS
118 # define FIRST_CELLSEGS 3
136 T_LAST_SYSTEM_TYPE=14
142 #define T_MASKTYPE 31
143 #define T_SYNTAX 4096
144 #define T_IMMUTABLE 8192
146 #define CLRATOM 49151
151 static num num_add(num a, num b);
152 static num num_mul(num a, num b);
153 static num num_div(num a, num b);
154 static num num_intdiv(num a, num b);
155 static num num_sub(num a, num b);
156 static num num_rem(num a, num b);
157 static num num_mod(num a, num b);
158 static int num_eq(num a, num b);
159 static int num_gt(num a, num b);
160 static int num_ge(num a, num b);
161 static int num_lt(num a, num b);
162 static int num_le(num a, num b);
165 static double round_per_R5RS(
double x);
167 static int is_zero_double(
double x);
173 #define typeflag(p) ((p)->_flag)
174 #define type(p) (typeflag(p)&T_MASKTYPE)
176 INTERFACE INLINE
int is_string(pointer p) {
return (type(p)==T_STRING); }
177 #define strvalue(p) ((p)->_object._string._svalue)
178 #define strlength(p) ((p)->_object._string._length)
180 INTERFACE INLINE
int is_vector(pointer p) {
return (type(p)==T_VECTOR); }
181 INTERFACE
static void fill_vector(pointer vec, pointer obj);
182 INTERFACE
static pointer vector_elem(pointer vec,
int ielem);
183 INTERFACE
static pointer set_vector_elem(pointer vec,
int ielem, pointer a);
184 INTERFACE INLINE
int is_number(pointer p) {
return (type(p)==T_NUMBER); }
185 INTERFACE INLINE
int is_integer(pointer p) {
186 return ((p)->_object._number.is_fixnum);
188 INTERFACE INLINE
int is_real(pointer p) {
189 return (!(p)->_object._number.is_fixnum);
192 INTERFACE INLINE
int is_character(pointer p) {
return (type(p)==T_CHARACTER); }
193 INTERFACE INLINE
char *string_value(pointer p) {
return strvalue(p); }
194 INLINE num nvalue(pointer p) {
return ((p)->_object._number); }
195 INTERFACE
long ivalue(pointer p) {
return (is_integer(p)?(p)->_object._number.value.ivalue:(
long)(p)->_object._number.value.rvalue); }
196 INTERFACE
double rvalue(pointer p) {
return (!is_integer(p)?(p)->_object._number.value.rvalue:(
double)(p)->_object._number.value.ivalue); }
197 #define ivalue_unchecked(p) ((p)->_object._number.value.ivalue)
198 #define rvalue_unchecked(p) ((p)->_object._number.value.rvalue)
199 #define set_integer(p) (p)->_object._number.is_fixnum=1;
200 #define set_real(p) (p)->_object._number.is_fixnum=0;
201 INTERFACE
long charvalue(pointer p) {
return ivalue_unchecked(p); }
203 INTERFACE INLINE
int is_port(pointer p) {
return (type(p)==T_PORT); }
204 #define is_inport(p) (type(p)==T_PORT && p->_object._port->kind&port_input)
205 #define is_outport(p) (type(p)==T_PORT && p->_object._port->kind&port_output)
207 INTERFACE INLINE
int is_pair(pointer p) {
return (type(p)==T_PAIR); }
208 #define car(p) ((p)->_object._cons._car)
209 #define cdr(p) ((p)->_object._cons._cdr)
210 INTERFACE pointer pair_car(pointer p) {
return car(p); }
211 INTERFACE pointer pair_cdr(pointer p) {
return cdr(p); }
212 INTERFACE pointer set_car(pointer p, pointer q) {
return car(p)=q; }
213 INTERFACE pointer set_cdr(pointer p, pointer q) {
return cdr(p)=q; }
215 INTERFACE INLINE
int is_symbol(pointer p) {
return (type(p)==T_SYMBOL); }
216 INTERFACE INLINE
char *symname(pointer p) {
return strvalue(car(p)); }
218 SCHEME_EXPORT INLINE
int hasprop(pointer p) {
return (typeflag(p)&T_SYMBOL); }
219 #define symprop(p) cdr(p)
222 INTERFACE INLINE
int is_syntax(pointer p) {
return (typeflag(p)&T_SYNTAX); }
223 INTERFACE INLINE
int is_proc(pointer p) {
return (type(p)==T_PROC); }
224 INTERFACE INLINE
int is_foreign(pointer p) {
return (type(p)==T_FOREIGN); }
225 INTERFACE INLINE
char *syntaxname(pointer p) {
return strvalue(car(p)); }
226 #define procnum(p) ivalue(p)
227 static const char *procname(pointer x);
229 INTERFACE INLINE
int is_closure(pointer p) {
return (type(p)==T_CLOSURE); }
230 INTERFACE INLINE
int is_macro(pointer p) {
return (type(p)==T_MACRO); }
231 INTERFACE INLINE pointer closure_code(pointer p) {
return car(p); }
232 INTERFACE INLINE pointer closure_env(pointer p) {
return cdr(p); }
234 INTERFACE INLINE
int is_continuation(pointer p) {
return (type(p)==T_CONTINUATION); }
235 #define cont_dump(p) cdr(p)
238 INTERFACE INLINE
int is_promise(pointer p) {
return (type(p)==T_PROMISE); }
240 INTERFACE INLINE
int is_environment(pointer p) {
return (type(p)==T_ENVIRONMENT); }
241 #define setenvironment(p) typeflag(p) = T_ENVIRONMENT
243 #define is_atom(p) (typeflag(p)&T_ATOM)
244 #define setatom(p) typeflag(p) |= T_ATOM
245 #define clratom(p) typeflag(p) &= CLRATOM
247 #define is_mark(p) (typeflag(p)&MARK)
248 #define setmark(p) typeflag(p) |= MARK
249 #define clrmark(p) typeflag(p) &= UNMARK
251 INTERFACE INLINE
int is_immutable(pointer p) {
return (typeflag(p)&T_IMMUTABLE); }
253 INTERFACE INLINE
void setimmutable(pointer p) { typeflag(p) |= T_IMMUTABLE; }
255 #define caar(p) car(car(p))
256 #define cadr(p) car(cdr(p))
257 #define cdar(p) cdr(car(p))
258 #define cddr(p) cdr(cdr(p))
259 #define cadar(p) car(cdr(car(p)))
260 #define caddr(p) car(cdr(cdr(p)))
261 #define cadaar(p) car(cdr(car(car(p))))
262 #define cadddr(p) car(cdr(cdr(cdr(p))))
263 #define cddddr(p) cdr(cdr(cdr(cdr(p))))
265 #if USE_CHAR_CLASSIFIERS
266 static INLINE
int Cisalpha(
int c) {
return isascii(c) && isalpha(c); }
267 static INLINE
int Cisdigit(
int c) {
return isascii(c) && isdigit(c); }
268 static INLINE
int Cisspace(
int c) {
return isascii(c) && isspace(c); }
269 static INLINE
int Cisupper(
int c) {
return isascii(c) && isupper(c); }
270 static INLINE
int Cislower(
int c) {
return isascii(c) && islower(c); }
274 static const char *charnames[32]={
309 static int is_ascii_name(
const char *name,
int *pc) {
311 for(i=0; i<32; i++) {
312 if(stricmp(name,charnames[i])==0) {
317 if(stricmp(name,
"del")==0) {
326 static int file_push(scheme *sc,
const char *fname);
327 static void file_pop(scheme *sc);
328 static int file_interactive(scheme *sc);
329 static INLINE
int is_one_of(
char *s,
int c);
330 static int alloc_cellseg(scheme *sc,
int n);
331 static long binary_decode(
const char *s);
332 static INLINE pointer get_cell(scheme *sc, pointer a, pointer b);
333 static pointer _get_cell(scheme *sc, pointer a, pointer b);
334 static pointer get_consecutive_cells(scheme *sc,
int n);
335 static pointer find_consecutive_cells(scheme *sc,
int n);
336 static void finalize_cell(scheme *sc, pointer a);
337 static int count_consecutive_cells(pointer x,
int needed);
338 static pointer find_slot_in_env(scheme *sc, pointer env, pointer sym,
int all);
339 static pointer mk_number(scheme *sc, num n);
340 static pointer mk_empty_string(scheme *sc,
int len,
char fill);
341 static char *store_string(scheme *sc,
int len,
const char *str,
char fill);
342 static pointer mk_vector(scheme *sc,
int len);
343 static pointer mk_atom(scheme *sc,
char *q);
344 static pointer mk_sharp_const(scheme *sc,
char *name);
345 static pointer mk_port(scheme *sc, port *p);
346 static pointer port_from_filename(scheme *sc,
const char *fn,
int prop);
347 static pointer port_from_file(scheme *sc, FILE *,
int prop);
348 static pointer port_from_string(scheme *sc,
char *start,
char *past_the_end,
int prop);
349 static port *port_rep_from_filename(scheme *sc,
const char *fn,
int prop);
350 static port *port_rep_from_file(scheme *sc, FILE *,
int prop);
351 static port *port_rep_from_string(scheme *sc,
char *start,
char *past_the_end,
int prop);
352 static void port_close(scheme *sc, pointer p,
int flag);
353 static void mark(pointer a);
354 static void gc(scheme *sc, pointer a, pointer b);
355 static int basic_inchar(port *pt);
356 static int inchar(scheme *sc);
357 static void backchar(scheme *sc,
int c);
358 static char *readstr_upto(scheme *sc,
char *delim);
359 static pointer readstrexp(scheme *sc);
360 static INLINE
void skipspace(scheme *sc);
361 static int token(scheme *sc);
362 static void printslashstring(scheme *sc,
char *s,
int len);
363 static void atom2str(scheme *sc, pointer l,
int f,
char **pp,
int *plen);
364 static void printatom(scheme *sc, pointer l,
int f);
365 static pointer mk_proc(scheme *sc,
enum scheme_opcodes op);
366 static pointer mk_closure(scheme *sc, pointer c, pointer e);
367 static pointer mk_continuation(scheme *sc, pointer d);
368 static pointer reverse(scheme *sc, pointer a);
369 static pointer reverse_in_place(scheme *sc, pointer term, pointer list);
370 static pointer append(scheme *sc, pointer a, pointer b);
371 static int list_length(scheme *sc, pointer a);
372 static int eqv(pointer a, pointer b);
373 static void dump_stack_mark(scheme *);
374 static pointer opexe_0(scheme *sc,
enum scheme_opcodes op);
375 static pointer opexe_1(scheme *sc,
enum scheme_opcodes op);
376 static pointer opexe_2(scheme *sc,
enum scheme_opcodes op);
377 static pointer opexe_3(scheme *sc,
enum scheme_opcodes op);
378 static pointer opexe_4(scheme *sc,
enum scheme_opcodes op);
379 static pointer opexe_5(scheme *sc,
enum scheme_opcodes op);
380 static pointer opexe_6(scheme *sc,
enum scheme_opcodes op);
381 static void Eval_Cycle(scheme *sc,
enum scheme_opcodes op);
382 static void assign_syntax(scheme *sc,
char *name);
383 static int syntaxnum(pointer p);
384 static void assign_proc(scheme *sc,
enum scheme_opcodes,
char *name);
386 #define num_ivalue(n) (n.is_fixnum?(n).value.ivalue:(long)(n).value.rvalue)
387 #define num_rvalue(n) (!n.is_fixnum?(n).value.rvalue:(double)(n).value.ivalue)
389 static num num_add(num a, num b) {
391 ret.is_fixnum=a.is_fixnum && b.is_fixnum;
393 ret.value.ivalue= a.value.ivalue+b.value.ivalue;
395 ret.value.rvalue=num_rvalue(a)+num_rvalue(b);
400 static num num_mul(num a, num b) {
402 ret.is_fixnum=a.is_fixnum && b.is_fixnum;
404 ret.value.ivalue= a.value.ivalue*b.value.ivalue;
406 ret.value.rvalue=num_rvalue(a)*num_rvalue(b);
411 static num num_div(num a, num b) {
413 ret.is_fixnum=a.is_fixnum && b.is_fixnum && a.value.ivalue%b.value.ivalue==0;
415 ret.value.ivalue= a.value.ivalue/b.value.ivalue;
417 ret.value.rvalue=num_rvalue(a)/num_rvalue(b);
422 static num num_intdiv(num a, num b) {
424 ret.is_fixnum=a.is_fixnum && b.is_fixnum;
426 ret.value.ivalue= a.value.ivalue/b.value.ivalue;
428 ret.value.rvalue=num_rvalue(a)/num_rvalue(b);
433 static num num_sub(num a, num b) {
435 ret.is_fixnum=a.is_fixnum && b.is_fixnum;
437 ret.value.ivalue= a.value.ivalue-b.value.ivalue;
439 ret.value.rvalue=num_rvalue(a)-num_rvalue(b);
444 static num num_rem(num a, num b) {
447 ret.is_fixnum=a.is_fixnum && b.is_fixnum;
456 }
else if (res < 0) {
461 ret.value.ivalue=res;
465 static num num_mod(num a, num b) {
468 ret.is_fixnum=a.is_fixnum && b.is_fixnum;
480 ret.value.ivalue=res;
484 static int num_eq(num a, num b) {
486 int is_fixnum=a.is_fixnum && b.is_fixnum;
488 ret= a.value.ivalue==b.value.ivalue;
490 ret=num_rvalue(a)==num_rvalue(b);
496 static int num_gt(num a, num b) {
498 int is_fixnum=a.is_fixnum && b.is_fixnum;
500 ret= a.value.ivalue>b.value.ivalue;
502 ret=num_rvalue(a)>num_rvalue(b);
507 static int num_ge(num a, num b) {
511 static int num_lt(num a, num b) {
513 int is_fixnum=a.is_fixnum && b.is_fixnum;
515 ret= a.value.ivalue<b.value.ivalue;
517 ret=num_rvalue(a)<num_rvalue(b);
522 static int num_le(num a, num b) {
528 static double round_per_R5RS(
double x) {
538 if(fmod(fl,2.0)==0.0) {
547 static int is_zero_double(
double x) {
548 return x<DBL_MIN && x>-DBL_MIN;
551 static long binary_decode(
const char *s) {
554 while(*s!=0 && (*s==
'1' || *s==
'0')) {
564 static int alloc_cellseg(scheme *sc,
int n) {
573 if(adj<
sizeof(
struct cell)) {
574 adj=
sizeof(
struct cell);
577 for (k = 0; k < n; k++) {
578 if (sc->last_cell_seg >= CELL_NSEGMENT - 1)
580 cp = (
char*) sc->malloc(CELL_SEGSIZE *
sizeof(
struct cell)+adj);
583 i = ++sc->last_cell_seg ;
584 sc->alloc_seg[i] = cp;
586 if((
unsigned long)cp%adj!=0) {
587 cp=(
char*)(adj*((
unsigned long)cp/adj+1));
591 sc->cell_seg[i] = newp;
592 while (i > 0 && sc->cell_seg[i - 1] > sc->cell_seg[i]) {
594 sc->cell_seg[i] = sc->cell_seg[i - 1];
595 sc->cell_seg[--i] = p;
597 sc->fcells += CELL_SEGSIZE;
598 last = newp + CELL_SEGSIZE - 1;
599 for (p = newp; p <= last; p++) {
605 if (sc->free_cell == sc->NIL || p < sc->free_cell) {
606 cdr(last) = sc->free_cell;
607 sc->free_cell = newp;
610 while (cdr(p) != sc->NIL && newp > cdr(p))
619 static INLINE pointer get_cell(scheme *sc, pointer a, pointer b) {
620 if (sc->free_cell != sc->NIL) {
621 pointer x = sc->free_cell;
622 sc->free_cell = cdr(x);
626 return _get_cell (sc, a, b);
631 static pointer _get_cell(scheme *sc, pointer a, pointer b) {
638 if (sc->free_cell == sc->NIL) {
640 if (sc->fcells < sc->last_cell_seg*8
641 || sc->free_cell == sc->NIL) {
643 if (!alloc_cellseg(sc,1) && sc->free_cell == sc->NIL) {
650 sc->free_cell = cdr(x);
655 static pointer get_consecutive_cells(scheme *sc,
int n) {
663 x=find_consecutive_cells(sc,n);
666 gc(sc, sc->NIL, sc->NIL);
667 x=find_consecutive_cells(sc,n);
670 if (!alloc_cellseg(sc,1)) {
675 x=find_consecutive_cells(sc,n);
685 static int count_consecutive_cells(pointer x,
int needed) {
690 if(n>needed)
return n;
695 static pointer find_consecutive_cells(scheme *sc,
int n) {
700 while(*pp!=sc->NIL) {
701 cnt=count_consecutive_cells(*pp,n);
714 pointer _cons(scheme *sc, pointer a, pointer b,
int immutable) {
715 pointer x = get_cell(sc,a, b);
717 typeflag(x) = T_PAIR;
728 #ifndef USE_OBJECT_LIST
730 static int hash_fn(
const char *key,
int table_size);
732 static pointer oblist_initial_value(scheme *sc)
734 return mk_vector(sc, 461);
738 static pointer oblist_add_by_name(scheme *sc,
const char *name)
743 x = immutable_cons(sc, mk_string(sc, name), sc->NIL);
744 typeflag(x) = T_SYMBOL;
745 setimmutable(car(x));
747 location = hash_fn(name, ivalue_unchecked(sc->oblist));
748 set_vector_elem(sc->oblist, location,
749 immutable_cons(sc, x, vector_elem(sc->oblist, location)));
753 static INLINE pointer oblist_find_by_name(scheme *sc,
const char *name)
759 location = hash_fn(name, ivalue_unchecked(sc->oblist));
760 for (x = vector_elem(sc->oblist, location); x != sc->NIL; x = cdr(x)) {
763 if(stricmp(name, s) == 0) {
770 static pointer oblist_all_symbols(scheme *sc)
774 pointer ob_list = sc->NIL;
776 for (i = 0; i < ivalue_unchecked(sc->oblist); i++) {
777 for (x = vector_elem(sc->oblist, i); x != sc->NIL; x = cdr(x)) {
778 ob_list = cons(sc, x, ob_list);
786 static pointer oblist_initial_value(scheme *sc)
791 static INLINE pointer oblist_find_by_name(scheme *sc,
const char *name)
796 for (x = sc->oblist; x != sc->NIL; x = cdr(x)) {
799 if(stricmp(name, s) == 0) {
807 static pointer oblist_add_by_name(scheme *sc,
const char *name)
811 x = immutable_cons(sc, mk_string(sc, name), sc->NIL);
812 typeflag(x) = T_SYMBOL;
813 setimmutable(car(x));
814 sc->oblist = immutable_cons(sc, x, sc->oblist);
817 static pointer oblist_all_symbols(scheme *sc)
824 static pointer mk_port(scheme *sc, port *p) {
825 pointer x = get_cell(sc, sc->NIL, sc->NIL);
827 typeflag(x) = T_PORT|T_ATOM;
832 pointer mk_foreign_func(scheme *sc, foreign_func f) {
833 pointer x = get_cell(sc, sc->NIL, sc->NIL);
835 typeflag(x) = (T_FOREIGN | T_ATOM);
840 INTERFACE pointer mk_character(scheme *sc,
int c) {
841 pointer x = get_cell(sc,sc->NIL, sc->NIL);
843 typeflag(x) = (T_CHARACTER | T_ATOM);
844 ivalue_unchecked(x)= c;
850 INTERFACE pointer mk_integer(scheme *sc,
long num) {
851 pointer x = get_cell(sc,sc->NIL, sc->NIL);
853 typeflag(x) = (T_NUMBER | T_ATOM);
854 ivalue_unchecked(x)= num;
859 INTERFACE pointer mk_real(scheme *sc,
double n) {
860 pointer x = get_cell(sc,sc->NIL, sc->NIL);
862 typeflag(x) = (T_NUMBER | T_ATOM);
863 rvalue_unchecked(x)= n;
868 static pointer mk_number(scheme *sc, num n) {
870 return mk_integer(sc,n.value.ivalue);
872 return mk_real(sc,n.value.rvalue);
877 static char *store_string(scheme *sc,
int len_str,
const char *str,
char fill) {
880 q=(
char*)sc->malloc(len_str+1);
888 memset(q, fill, len_str);
895 INTERFACE pointer mk_string(scheme *sc,
const char *str) {
896 return mk_counted_string(sc,str,strlen(str));
899 INTERFACE pointer mk_counted_string(scheme *sc,
const char *str,
int len) {
900 pointer x = get_cell(sc, sc->NIL, sc->NIL);
902 strvalue(x) = store_string(sc,len,str,0);
903 typeflag(x) = (T_STRING | T_ATOM);
908 static pointer mk_empty_string(scheme *sc,
int len,
char fill) {
909 pointer x = get_cell(sc, sc->NIL, sc->NIL);
911 strvalue(x) = store_string(sc,len,0,fill);
912 typeflag(x) = (T_STRING | T_ATOM);
917 INTERFACE
static pointer mk_vector(scheme *sc,
int len) {
918 pointer x=get_consecutive_cells(sc,len/2+len%2+1);
919 typeflag(x) = (T_VECTOR | T_ATOM);
920 ivalue_unchecked(x)=len;
922 fill_vector(x,sc->NIL);
926 INTERFACE
static void fill_vector(pointer vec, pointer obj) {
928 int num=ivalue(vec)/2+ivalue(vec)%2;
929 for(i=0; i<num; i++) {
930 typeflag(vec+1+i) = T_PAIR;
931 setimmutable(vec+1+i);
937 INTERFACE
static pointer vector_elem(pointer vec,
int ielem) {
946 INTERFACE
static pointer set_vector_elem(pointer vec,
int ielem, pointer a) {
949 return car(vec+1+n)=a;
951 return cdr(vec+1+n)=a;
956 INTERFACE pointer mk_symbol(scheme *sc,
const char *name) {
960 x = oblist_find_by_name(sc, name);
964 x = oblist_add_by_name(sc, name);
969 INTERFACE pointer gensym(scheme *sc) {
973 for(; sc->gensym_cnt<LONG_MAX; sc->gensym_cnt++) {
974 sprintf(name,
"gensym-%ld",sc->gensym_cnt);
977 x = oblist_find_by_name(sc, name);
982 x = oblist_add_by_name(sc, name);
991 static pointer mk_atom(scheme *sc,
char *q) {
997 if((p=strstr(q,
"::"))!=0) {
999 return cons(sc, sc->COLON_HOOK,
1003 cons(sc, mk_atom(sc,p+2), sc->NIL)),
1004 cons(sc, mk_symbol(sc,strlwr(q)), sc->NIL)));
1010 if ((c ==
'+') || (c ==
'-')) {
1016 if (!isdigit((
int) c)) {
1017 return (mk_symbol(sc, strlwr(q)));
1019 }
else if (c ==
'.') {
1022 if (!isdigit((
int) c)) {
1023 return (mk_symbol(sc, strlwr(q)));
1025 }
else if (!isdigit((
int) c)) {
1026 return (mk_symbol(sc, strlwr(q)));
1029 for ( ; (c = *p) != 0; ++p) {
1030 if (!isdigit((
int) c)) {
1032 if(!has_dec_point) {
1037 else if ((c ==
'e') || (c ==
'E')) {
1042 if ((*p ==
'-') || (*p ==
'+') || isdigit((
int) *p)) {
1047 return (mk_symbol(sc, strlwr(q)));
1051 return mk_real(sc,atof(q));
1053 return (mk_integer(sc, atol(q)));
1057 static pointer mk_sharp_const(scheme *sc,
char *name) {
1061 if (!strcmp(name,
"t"))
1063 else if (!strcmp(name,
"f"))
1065 else if (*name ==
'o') {
1066 sprintf(tmp,
"0%s", name+1);
1067 sscanf(tmp,
"%lo", &x);
1068 return (mk_integer(sc, x));
1069 }
else if (*name ==
'd') {
1070 sscanf(name+1,
"%ld", &x);
1071 return (mk_integer(sc, x));
1072 }
else if (*name ==
'x') {
1073 sprintf(tmp,
"0x%s", name+1);
1074 sscanf(tmp,
"%lx", &x);
1075 return (mk_integer(sc, x));
1076 }
else if (*name ==
'b') {
1077 x = binary_decode(name+1);
1078 return (mk_integer(sc, x));
1079 }
else if (*name ==
'\\') {
1081 if(stricmp(name+1,
"space")==0) {
1083 }
else if(stricmp(name+1,
"newline")==0) {
1085 }
else if(stricmp(name+1,
"return")==0) {
1087 }
else if(stricmp(name+1,
"tab")==0) {
1089 }
else if(name[1]==
'x' && name[2]!=0) {
1091 if(sscanf(name+2,
"%x",&c1)==1 && c1<256) {
1097 }
else if(is_ascii_name(name+1,&c)) {
1100 }
else if(name[2]==0) {
1105 return mk_character(sc,c);
1117 static void mark(pointer a) {
1125 int num=ivalue_unchecked(p)/2+ivalue_unchecked(p)%2;
1126 for(i=0; i<num; i++) {
1135 if (q && !is_mark(q)) {
1143 if (q && !is_mark(q)) {
1168 static void gc(scheme *sc, pointer a, pointer b) {
1172 if(sc->gc_verbose) {
1173 putstr(sc,
"gc...");
1178 mark(sc->global_env);
1184 dump_stack_mark(sc);
1187 mark(sc->save_inport);
1198 sc->free_cell = sc->NIL;
1204 for (i = sc->last_cell_seg; i >= 0; i--) {
1205 p = sc->cell_seg[i] + CELL_SEGSIZE;
1206 while (--p >= sc->cell_seg[i]) {
1211 if (typeflag(p) != 0) {
1212 finalize_cell(sc, p);
1217 cdr(p) = sc->free_cell;
1223 if (sc->gc_verbose) {
1225 sprintf(msg,
"done: %ld cells were recovered.\n", sc->fcells);
1230 static void finalize_cell(scheme *sc, pointer a) {
1232 sc->free(strvalue(a));
1233 }
else if(is_port(a)) {
1234 if(a->_object._port->kind&port_file
1235 && a->_object._port->rep.stdio.closeit) {
1236 port_close(sc,a,port_input|port_output);
1238 sc->free(a->_object._port);
1244 static int file_push(scheme *sc,
const char *fname) {
1245 FILE *fin=fopen(fname,
"r");
1248 sc->load_stack[sc->file_i].kind=port_file|port_input;
1249 sc->load_stack[sc->file_i].rep.stdio.file=fin;
1250 sc->load_stack[sc->file_i].rep.stdio.closeit=1;
1251 sc->nesting_stack[sc->file_i]=0;
1252 sc->loadport->_object._port=sc->load_stack+sc->file_i;
1257 static void file_pop(scheme *sc) {
1258 sc->nesting=sc->nesting_stack[sc->file_i];
1260 port_close(sc,sc->loadport,port_input);
1262 sc->loadport->_object._port=sc->load_stack+sc->file_i;
1263 if(file_interactive(sc)) {
1269 static int file_interactive(scheme *sc) {
1270 return sc->file_i==0 && sc->load_stack[0].rep.stdio.file==stdin
1271 && sc->inport->_object._port->kind&port_file;
1274 static port *port_rep_from_filename(scheme *sc,
const char *fn,
int prop) {
1278 if(prop==(port_input|port_output)) {
1280 }
else if(prop==port_output) {
1289 pt=port_rep_from_file(sc,f,prop);
1290 pt->rep.stdio.closeit=1;
1294 static pointer port_from_filename(scheme *sc,
const char *fn,
int prop) {
1296 pt=port_rep_from_filename(sc,fn,prop);
1300 return mk_port(sc,pt);
1303 static port *port_rep_from_file(scheme *sc, FILE *f,
int prop) {
1306 pt=(port*)sc->malloc(
sizeof(port));
1319 pt->kind=port_file|prop;
1320 pt->rep.stdio.file=f;
1321 pt->rep.stdio.closeit=0;
1325 static pointer port_from_file(scheme *sc, FILE *f,
int prop) {
1327 pt=port_rep_from_file(sc,f,prop);
1331 return mk_port(sc,pt);
1334 static port *port_rep_from_string(scheme *sc,
char *start,
char *past_the_end,
int prop) {
1336 pt=(port*)sc->malloc(
sizeof(port));
1340 pt->kind=port_string|prop;
1341 pt->rep.string.start=start;
1342 pt->rep.string.curr=start;
1343 pt->rep.string.past_the_end=past_the_end;
1347 static pointer port_from_string(scheme *sc,
char *start,
char *past_the_end,
int prop) {
1349 pt=port_rep_from_string(sc,start,past_the_end,prop);
1353 return mk_port(sc,pt);
1356 static void port_close(scheme *sc, pointer p,
int flag) {
1357 port *pt=p->_object._port;
1359 if((pt->kind & (port_input|port_output))==0) {
1360 if(pt->kind&port_file) {
1361 fclose(pt->rep.stdio.file);
1368 static int inchar(scheme *sc) {
1372 pt=sc->inport->_object._port;
1374 if(c==EOF && sc->inport==sc->loadport && sc->file_i!=0) {
1376 if(sc->nesting!=0) {
1384 static int basic_inchar(port *pt) {
1385 if(pt->kind&port_file) {
1386 return fgetc(pt->rep.stdio.file);
1388 if(*pt->rep.string.curr==0
1389 || pt->rep.string.curr==pt->rep.string.past_the_end) {
1392 return *pt->rep.string.curr++;
1398 static void backchar(scheme *sc,
int c) {
1401 pt=sc->inport->_object._port;
1402 if(pt->kind&port_file) {
1403 ungetc(c,pt->rep.stdio.file);
1405 if(pt->rep.string.curr!=pt->rep.string.start) {
1406 --pt->rep.string.curr;
1411 INTERFACE
void putstr(scheme *sc,
const char *s) {
1412 port *pt=sc->outport->_object._port;
1413 if(pt->kind&port_file) {
1414 fputs(s,pt->rep.stdio.file);
1417 if(pt->rep.string.curr!=pt->rep.string.past_the_end) {
1418 *pt->rep.string.curr++=*s;
1424 static void putchars(scheme *sc,
const char *s,
int len) {
1425 port *pt=sc->outport->_object._port;
1426 if(pt->kind&port_file) {
1428 if (fwrite(s,1,len,pt->rep.stdio.file) == 0)
1432 if(pt->rep.string.curr!=pt->rep.string.past_the_end) {
1433 *pt->rep.string.curr++=*s++;
1439 INTERFACE
void putcharacter(scheme *sc,
int c) {
1440 port *pt=sc->outport->_object._port;
1441 if(pt->kind&port_file) {
1442 fputc(c,pt->rep.stdio.file);
1444 if(pt->rep.string.curr!=pt->rep.string.past_the_end) {
1445 *pt->rep.string.curr++=c;
1451 static char *readstr_upto(scheme *sc,
char *delim) {
1452 char *p = sc->strbuff;
1454 while (!is_one_of(delim, (*p++ = inchar(sc))));
1455 if(p==sc->strbuff+2 && p[-2]==
'\\') {
1465 static pointer readstrexp(scheme *sc) {
1466 char *p = sc->strbuff;
1469 enum { st_ok, st_bsl, st_x1, st_x2} state=st_ok;
1473 if(c==EOF || p-sc->strbuff>
sizeof(sc->strbuff)-1) {
1484 return mk_counted_string(sc,sc->strbuff,p-sc->strbuff);
1522 if(c>=
'0' && c<=
'F') {
1526 c1=(c1<<4)+c-
'A'+10;
1543 static INLINE
int is_one_of(
char *s,
int c) {
1544 if(c==EOF)
return 1;
1552 static INLINE
void skipspace(scheme *sc) {
1554 while (isspace(c=inchar(sc)))
1562 static int token(scheme *sc) {
1565 switch (c=inchar(sc)) {
1569 return (TOK_LPAREN);
1571 return (TOK_RPAREN);
1574 if(is_one_of(
" \n\t",c)) {
1584 return (TOK_COMMENT);
1586 return (TOK_DQUOTE);
1588 return (TOK_BQUOTE);
1590 if ((c=inchar(sc)) ==
'@')
1591 return (TOK_ATMARK);
1600 }
else if(c ==
'!') {
1604 if(is_one_of(
" tfodxb\\",c)) {
1605 return TOK_SHARP_CONST;
1617 #define ok_abbrev(x) (is_pair(x) && cdr(x) == sc->NIL)
1619 static void printslashstring(scheme *sc,
char *p,
int len) {
1621 unsigned char *s=(
unsigned char*)p;
1622 putcharacter(sc,
'"');
1623 for ( i=0; i<len; i++) {
1624 if(*s==0xff || *s==
'"' || *s<
' ' || *s==
'\\') {
1625 putcharacter(sc,
'\\');
1628 putcharacter(sc,
'"');
1631 putcharacter(sc,
'n');
1634 putcharacter(sc,
't');
1637 putcharacter(sc,
'r');
1640 putcharacter(sc,
'\\');
1644 putcharacter(sc,
'x');
1646 putcharacter(sc,d+
'0');
1648 putcharacter(sc,d-10+
'A');
1652 putcharacter(sc,d+
'0');
1654 putcharacter(sc,d-10+
'A');
1659 putcharacter(sc,*s);
1663 putcharacter(sc,
'"');
1668 static void printatom(scheme *sc, pointer l,
int f) {
1671 atom2str(sc,l,f,&p,&len);
1677 static void atom2str(scheme *sc, pointer l,
int f,
char **pp,
int *plen) {
1682 }
else if (l == sc->T) {
1684 }
else if (l == sc->F) {
1686 }
else if (l == sc->EOF_OBJ) {
1688 }
else if (is_port(l)) {
1690 strcpy(p,
"#<PORT>");
1691 }
else if (is_number(l)) {
1694 sprintf(p,
"%ld", ivalue_unchecked(l));
1696 sprintf(p,
"%.10g", rvalue_unchecked(l));
1698 }
else if (is_string(l)) {
1704 printslashstring(sc, strvalue(l), strlength(l));
1707 }
else if (is_character(l)) {
1716 sprintf(p,
"#\\space");
break;
1718 sprintf(p,
"#\\newline");
break;
1720 sprintf(p,
"#\\return");
break;
1722 sprintf(p,
"#\\tab");
break;
1726 strcpy(p,
"#\\del");
break;
1728 strcpy(p,
"#\\"); strcat(p,charnames[c]);
break;
1732 sprintf(p,
"#\\x%x",c);
break;
1735 sprintf(p,
"#\\%c",c);
break;
1738 }
else if (is_symbol(l)) {
1740 }
else if (is_proc(l)) {
1742 sprintf(p,
"#<%s PROCEDURE %ld>", procname(l),procnum(l));
1743 }
else if (is_macro(l)) {
1745 }
else if (is_closure(l)) {
1747 }
else if (is_promise(l)) {
1749 }
else if (is_foreign(l)) {
1751 sprintf(p,
"#<FOREIGN PROCEDURE %ld>", procnum(l));
1752 }
else if (is_continuation(l)) {
1753 p =
"#<CONTINUATION>";
1763 static pointer mk_closure(scheme *sc, pointer c, pointer e) {
1764 pointer x = get_cell(sc, c, e);
1766 typeflag(x) = T_CLOSURE;
1773 static pointer mk_continuation(scheme *sc, pointer d) {
1774 pointer x = get_cell(sc, sc->NIL, d);
1776 typeflag(x) = T_CONTINUATION;
1781 static pointer list_star(scheme *sc, pointer d) {
1783 if(cdr(d)==sc->NIL) {
1786 p=cons(sc,car(d),cdr(d));
1788 while(cdr(cdr(p))!=sc->NIL) {
1789 d=cons(sc,car(p),cdr(p));
1790 if(cdr(cdr(p))!=sc->NIL) {
1799 static pointer reverse(scheme *sc, pointer a) {
1801 pointer p = sc->NIL;
1803 for ( ; is_pair(a); a = cdr(a)) {
1804 p = cons(sc, car(a), p);
1810 static pointer reverse_in_place(scheme *sc, pointer term, pointer list) {
1811 pointer p = list, result = term, q;
1813 while (p != sc->NIL) {
1823 static pointer append(scheme *sc, pointer a, pointer b) {
1828 while (a != sc->NIL) {
1839 static int eqv(pointer a, pointer b) {
1842 return (strvalue(a) == strvalue(b));
1845 }
else if (is_number(a)) {
1847 return num_eq(nvalue(a),nvalue(b));
1850 }
else if (is_character(a)) {
1851 if (is_character(b))
1852 return charvalue(a)==charvalue(b);
1855 }
else if (is_port(a)) {
1860 }
else if (is_proc(a)) {
1862 return procnum(a)==procnum(b);
1872 #define is_true(p) ((p) != sc->F)
1873 #define is_false(p) ((p) == sc->F)
1877 #if !defined(USE_ALIST_ENV) || !defined(USE_OBJECT_LIST)
1879 static int hash_fn(
const char *key,
int table_size)
1881 unsigned int hashed = 0;
1883 int bits_per_int =
sizeof(
unsigned int)*8;
1885 for (c = key; *c; c++) {
1887 hashed = (hashed<<5) | (hashed>>(bits_per_int-5));
1890 return hashed % table_size;
1894 #ifndef USE_ALIST_ENV
1904 static void new_frame_in_env(scheme *sc, pointer old_env)
1909 if (old_env == sc->NIL) {
1910 new_frame = mk_vector(sc, 461);
1912 new_frame = sc->NIL;
1915 sc->envir = immutable_cons(sc, new_frame, old_env);
1916 setenvironment(sc->envir);
1919 static INLINE
void new_slot_spec_in_env(scheme *sc, pointer env,
1920 pointer variable, pointer value)
1922 pointer slot = immutable_cons(sc, variable, value);
1924 if (is_vector(car(env))) {
1925 int location = hash_fn(symname(variable), ivalue_unchecked(car(env)));
1927 set_vector_elem(car(env), location,
1928 immutable_cons(sc, slot, vector_elem(car(env), location)));
1930 car(env) = immutable_cons(sc, slot, car(env));
1934 static pointer find_slot_in_env(scheme *sc, pointer env, pointer hdl,
int all)
1936 pointer x = sc->NIL, y = sc->NIL;
1939 for (x = env; x != sc->NIL; x = cdr(x)) {
1940 if (is_vector(car(x))) {
1941 location = hash_fn(symname(hdl), ivalue_unchecked(car(x)));
1942 y = vector_elem(car(x), location);
1946 for ( ; y != sc->NIL; y = cdr(y)) {
1947 if (caar(y) == hdl) {
1966 static INLINE
void new_frame_in_env(scheme *sc, pointer old_env)
1968 sc->envir = immutable_cons(sc, sc->NIL, old_env);
1969 setenvironment(sc->envir);
1972 static INLINE
void new_slot_spec_in_env(scheme *sc, pointer env,
1973 pointer variable, pointer value)
1975 car(env) = immutable_cons(sc, immutable_cons(sc, variable, value), car(env));
1978 static pointer find_slot_in_env(scheme *sc, pointer env, pointer hdl,
int all)
1981 for (x = env; x != sc->NIL; x = cdr(x)) {
1982 for (y = car(x); y != sc->NIL; y = cdr(y)) {
1983 if (caar(y) == hdl) {
2002 static INLINE
void new_slot_in_env(scheme *sc, pointer variable, pointer value)
2004 new_slot_spec_in_env(sc, sc->envir, variable, value);
2007 static INLINE
void set_slot_in_env(scheme *sc, pointer slot, pointer value)
2012 static INLINE pointer slot_value_in_env(pointer slot)
2020 static pointer _Error_1(scheme *sc,
const char *s, pointer a) {
2023 pointer hdl=sc->ERROR_HOOK;
2025 x=find_slot_in_env(sc,sc->envir,hdl,1);
2028 sc->code = cons(sc, cons(sc, sc->QUOTE, cons(sc,(a), sc->NIL)), sc->NIL);
2032 sc->code = cons(sc, mk_string(sc, (s)), sc->code);
2033 setimmutable(car(sc->code));
2034 sc->code = cons(sc, slot_value_in_env(x), sc->code);
2035 sc->op = (int)OP_EVAL;
2041 sc->args = cons(sc, (a), sc->NIL);
2045 sc->args = cons(sc, mk_string(sc, (s)), sc->args);
2046 setimmutable(car(sc->args));
2047 sc->op = (int)OP_ERR0;
2050 #define Error_1(sc,s, a) return _Error_1(sc,s,a)
2051 #define Error_0(sc,s) return _Error_1(sc,s,0)
2055 # define END } while (0)
2056 #define s_goto(sc,a) BEGIN \
2057 sc->op = (int)(a); \
2060 #define s_return(sc,a) return _s_return(sc,a)
2062 #ifndef USE_SCHEME_STACK
2065 struct dump_stack_frame {
2066 enum scheme_opcodes op;
2072 #define STACK_GROWTH 3
2074 static void s_save(scheme *sc,
enum scheme_opcodes op, pointer args, pointer code)
2076 long nframes = (long)sc->dump;
2077 struct dump_stack_frame *next_frame;
2080 if (nframes >= sc->dump_size) {
2081 sc->dump_size += STACK_GROWTH;
2083 sc->dump_base = realloc(sc->dump_base,
2084 sizeof(
struct dump_stack_frame) * sc->dump_size);
2086 next_frame = (
struct dump_stack_frame *)sc->dump_base + nframes;
2087 next_frame->op = op;
2088 next_frame->args = args;
2089 next_frame->envir = sc->envir;
2090 next_frame->code = code;
2091 sc->dump = (pointer)(nframes+1L);
2094 static pointer _s_return(scheme *sc, pointer a)
2096 long nframes = (long)sc->dump;
2097 struct dump_stack_frame *frame;
2104 frame = (
struct dump_stack_frame *)sc->dump_base + nframes;
2106 sc->args = frame->args;
2107 sc->envir = frame->envir;
2108 sc->code = frame->code;
2109 sc->dump = (pointer)nframes;
2113 static INLINE
void dump_stack_reset(scheme *sc)
2116 sc->dump = (pointer)0;
2119 static INLINE
void dump_stack_initialize(scheme *sc)
2122 sc->dump_base = NULL;
2123 dump_stack_reset(sc);
2126 static void dump_stack_free(scheme *sc)
2128 free(sc->dump_base);
2129 sc->dump_base = NULL;
2130 sc->dump = (pointer)0;
2134 static INLINE
void dump_stack_mark(scheme *sc)
2136 long nframes = (long)sc->dump;
2138 for(i=0; i<nframes; i++) {
2139 struct dump_stack_frame *frame;
2140 frame = (
struct dump_stack_frame *)sc->dump_base + i;
2149 static INLINE
void dump_stack_reset(scheme *sc)
2154 static INLINE
void dump_stack_initialize(scheme *sc)
2156 dump_stack_reset(sc);
2159 static void dump_stack_free(scheme *sc)
2164 static pointer _s_return(scheme *sc, pointer a) {
2166 if(sc->dump==sc->NIL)
return sc->NIL;
2167 sc->op = ivalue(car(sc->dump));
2168 sc->args = cadr(sc->dump);
2169 sc->envir = caddr(sc->dump);
2170 sc->code = cadddr(sc->dump);
2171 sc->dump = cddddr(sc->dump);
2175 static void s_save(scheme *sc,
enum scheme_opcodes op, pointer args, pointer code) {
2176 sc->dump = cons(sc, sc->envir, cons(sc, (code), sc->dump));
2177 sc->dump = cons(sc, (args), sc->dump);
2178 sc->dump = cons(sc, mk_integer(sc, (
long)(op)), sc->dump);
2181 static INLINE
void dump_stack_mark(scheme *sc)
2187 #define s_retbool(tf) s_return(sc,(tf) ? sc->T : sc->F)
2189 static pointer opexe_0(scheme *sc,
enum scheme_opcodes op) {
2194 if(file_interactive(sc)) {
2195 fprintf(sc->outport->_object._port->rep.stdio.file,
2196 "Loading %s\n", strvalue(car(sc->args)));
2198 if (!file_push(sc,strvalue(car(sc->args)))) {
2199 Error_1(sc,
"unable to open", car(sc->args));
2201 s_goto(sc,OP_T0LVL);
2204 if(file_interactive(sc)) {
2208 dump_stack_reset(sc);
2209 sc->envir = sc->global_env;
2210 sc->save_inport=sc->inport;
2211 sc->inport = sc->loadport;
2212 s_save(sc,OP_T0LVL, sc->NIL, sc->NIL);
2213 s_save(sc,OP_VALUEPRINT, sc->NIL, sc->NIL);
2214 s_save(sc,OP_T1LVL, sc->NIL, sc->NIL);
2215 if (file_interactive(sc)) {
2218 s_goto(sc,OP_READ_INTERNAL);
2221 sc->code = sc->value;
2222 sc->inport=sc->save_inport;
2225 case OP_READ_INTERNAL:
2226 sc->tok = token(sc);
2227 if(sc->tok==TOK_EOF) {
2228 if(sc->inport==sc->loadport) {
2232 s_return(sc,sc->EOF_OBJ);
2235 s_goto(sc,OP_RDSEXPR);
2238 s_return(sc, gensym(sc));
2245 putstr(sc,
"\nGives: ");
2247 if(file_interactive(sc)) {
2249 sc->args = sc->value;
2250 s_goto(sc,OP_P0LIST);
2252 s_return(sc,sc->value);
2259 s_save(sc,OP_REAL_EVAL,sc->args,sc->code);
2261 putstr(sc,
"\nEval: ");
2262 s_goto(sc,OP_P0LIST);
2267 if (is_symbol(sc->code)) {
2268 x=find_slot_in_env(sc,sc->envir,sc->code,1);
2270 s_return(sc,slot_value_in_env(x));
2272 Error_1(sc,
"eval: unbound variable:", sc->code);
2274 }
else if (is_pair(sc->code)) {
2275 if (is_syntax(x = car(sc->code))) {
2276 sc->code = cdr(sc->code);
2277 s_goto(sc,syntaxnum(x));
2279 s_save(sc,OP_E0ARGS, sc->NIL, sc->code);
2281 sc->code = car(sc->code);
2285 s_return(sc,sc->code);
2289 if (is_macro(sc->value)) {
2290 s_save(sc,OP_DOMACRO, sc->NIL, sc->NIL);
2291 sc->args = cons(sc,sc->code, sc->NIL);
2292 sc->code = sc->value;
2293 s_goto(sc,OP_APPLY);
2295 sc->code = cdr(sc->code);
2296 s_goto(sc,OP_E1ARGS);
2300 sc->args = cons(sc, sc->value, sc->args);
2301 if (is_pair(sc->code)) {
2302 s_save(sc,OP_E1ARGS, sc->args, cdr(sc->code));
2303 sc->code = car(sc->code);
2307 sc->args = reverse_in_place(sc, sc->NIL, sc->args);
2308 sc->code = car(sc->args);
2309 sc->args = cdr(sc->args);
2310 s_goto(sc,OP_APPLY);
2316 sc->tracing=ivalue(car(sc->args));
2317 s_return(sc,mk_integer(sc,tr));
2324 s_save(sc,OP_REAL_APPLY,sc->args,sc->code);
2327 putstr(sc,
"\nApply to: ");
2328 s_goto(sc,OP_P0LIST);
2333 if (is_proc(sc->code)) {
2334 s_goto(sc,procnum(sc->code));
2335 }
else if (is_foreign(sc->code)) {
2336 x=sc->code->_object._ff(sc,sc->args);
2338 }
else if (is_closure(sc->code) || is_macro(sc->code)
2339 || is_promise(sc->code)) {
2342 new_frame_in_env(sc, closure_env(sc->code));
2343 for (x = car(closure_code(sc->code)), y = sc->args;
2344 is_pair(x); x = cdr(x), y = cdr(y)) {
2346 Error_0(sc,
"not enough arguments");
2348 new_slot_in_env(sc, car(x), car(y));
2357 }
else if (is_symbol(x))
2358 new_slot_in_env(sc, x, y);
2360 Error_1(sc,
"syntax error in closure: not a symbol:", x);
2362 sc->code = cdr(closure_code(sc->code));
2364 s_goto(sc,OP_BEGIN);
2365 }
else if (is_continuation(sc->code)) {
2366 sc->dump = cont_dump(sc->code);
2367 s_return(sc,sc->args != sc->NIL ? car(sc->args) : sc->NIL);
2369 Error_0(sc,
"illegal function");
2373 sc->code = sc->value;
2377 s_return(sc,mk_closure(sc, sc->code, sc->envir));
2381 if(car(x)==sc->LAMBDA) {
2384 if(cdr(sc->args)==sc->NIL) {
2389 s_return(sc,mk_closure(sc, x, y));
2393 s_return(sc,car(sc->code));
2396 if (is_pair(car(sc->code))) {
2398 sc->code = cons(sc, sc->LAMBDA, cons(sc, cdar(sc->code), cdr(sc->code)));
2401 sc->code = cadr(sc->code);
2403 if (!is_symbol(x)) {
2404 Error_0(sc,
"variable is not a symbol");
2406 s_save(sc,OP_DEF1, sc->NIL, x);
2410 x=find_slot_in_env(sc,sc->envir,sc->code,0);
2412 set_slot_in_env(sc, x, sc->value);
2414 new_slot_in_env(sc, sc->code, sc->value);
2416 s_return(sc,sc->code);
2421 if(cdr(sc->args)!=sc->NIL) {
2424 s_retbool(find_slot_in_env(sc,x,car(sc->args),1)!=sc->NIL);
2427 s_save(sc,OP_SET1, sc->NIL, car(sc->code));
2428 sc->code = cadr(sc->code);
2432 y=find_slot_in_env(sc,sc->envir,sc->code,1);
2434 set_slot_in_env(sc, y, sc->value);
2435 s_return(sc,sc->value);
2437 Error_1(sc,
"set!: unbound variable:", sc->code);
2442 if (!is_pair(sc->code)) {
2443 s_return(sc,sc->code);
2445 if (cdr(sc->code) != sc->NIL) {
2446 s_save(sc,OP_BEGIN, sc->NIL, cdr(sc->code));
2448 sc->code = car(sc->code);
2452 s_save(sc,OP_IF1, sc->NIL, cdr(sc->code));
2453 sc->code = car(sc->code);
2457 if (is_true(sc->value))
2458 sc->code = car(sc->code);
2460 sc->code = cadr(sc->code);
2466 sc->value = sc->code;
2467 sc->code = is_symbol(car(sc->code)) ? cadr(sc->code) : car(sc->code);
2471 sc->args = cons(sc, sc->value, sc->args);
2472 if (is_pair(sc->code)) {
2473 s_save(sc,OP_LET1, sc->args, cdr(sc->code));
2474 sc->code = cadar(sc->code);
2478 sc->args = reverse_in_place(sc, sc->NIL, sc->args);
2479 sc->code = car(sc->args);
2480 sc->args = cdr(sc->args);
2485 new_frame_in_env(sc, sc->envir);
2486 for (x = is_symbol(car(sc->code)) ? cadr(sc->code) : car(sc->code), y = sc->args;
2487 y != sc->NIL; x = cdr(x), y = cdr(y)) {
2488 new_slot_in_env(sc, caar(x), car(y));
2490 if (is_symbol(car(sc->code))) {
2491 for (x = cadr(sc->code), sc->args = sc->NIL; x != sc->NIL; x = cdr(x)) {
2493 sc->args = cons(sc, caar(x), sc->args);
2495 x = mk_closure(sc, cons(sc, reverse_in_place(sc, sc->NIL, sc->args), cddr(sc->code)), sc->envir);
2496 new_slot_in_env(sc, car(sc->code), x);
2497 sc->code = cddr(sc->code);
2500 sc->code = cdr(sc->code);
2503 s_goto(sc,OP_BEGIN);
2506 if (car(sc->code) == sc->NIL) {
2507 new_frame_in_env(sc, sc->envir);
2508 sc->code = cdr(sc->code);
2509 s_goto(sc,OP_BEGIN);
2511 s_save(sc,OP_LET1AST, cdr(sc->code), car(sc->code));
2512 sc->code = cadaar(sc->code);
2516 new_frame_in_env(sc, sc->envir);
2517 s_goto(sc,OP_LET2AST);
2520 new_slot_in_env(sc, caar(sc->code), sc->value);
2521 sc->code = cdr(sc->code);
2522 if (is_pair(sc->code)) {
2523 s_save(sc,OP_LET2AST, sc->args, sc->code);
2524 sc->code = cadar(sc->code);
2528 sc->code = sc->args;
2530 s_goto(sc,OP_BEGIN);
2533 sprintf(sc->strbuff,
"%d: illegal operator", sc->op);
2534 Error_0(sc,sc->strbuff);
2539 static pointer opexe_1(scheme *sc,
enum scheme_opcodes op) {
2544 new_frame_in_env(sc, sc->envir);
2546 sc->value = sc->code;
2547 sc->code = car(sc->code);
2548 s_goto(sc,OP_LET1REC);
2551 sc->args = cons(sc, sc->value, sc->args);
2552 if (is_pair(sc->code)) {
2553 s_save(sc,OP_LET1REC, sc->args, cdr(sc->code));
2554 sc->code = cadar(sc->code);
2558 sc->args = reverse_in_place(sc, sc->NIL, sc->args);
2559 sc->code = car(sc->args);
2560 sc->args = cdr(sc->args);
2561 s_goto(sc,OP_LET2REC);
2565 for (x = car(sc->code), y = sc->args; y != sc->NIL; x = cdr(x), y = cdr(y)) {
2566 new_slot_in_env(sc, caar(x), car(y));
2568 sc->code = cdr(sc->code);
2570 s_goto(sc,OP_BEGIN);
2573 if (!is_pair(sc->code)) {
2574 Error_0(sc,
"syntax error in cond");
2576 s_save(sc,OP_COND1, sc->NIL, sc->code);
2577 sc->code = caar(sc->code);
2581 if (is_true(sc->value)) {
2582 if ((sc->code = cdar(sc->code)) == sc->NIL) {
2583 s_return(sc,sc->value);
2585 if(car(sc->code)==sc->FEED_TO) {
2586 if(!is_pair(cdr(sc->code))) {
2587 Error_0(sc,
"syntax error in cond");
2589 x=cons(sc, sc->QUOTE, cons(sc, sc->value, sc->NIL));
2590 sc->code=cons(sc,cadr(sc->code),cons(sc,x,sc->NIL));
2593 s_goto(sc,OP_BEGIN);
2595 if ((sc->code = cdr(sc->code)) == sc->NIL) {
2596 s_return(sc,sc->NIL);
2598 s_save(sc,OP_COND1, sc->NIL, sc->code);
2599 sc->code = caar(sc->code);
2605 x = mk_closure(sc, cons(sc, sc->NIL, sc->code), sc->envir);
2606 typeflag(x)=T_PROMISE;
2610 if (sc->code == sc->NIL) {
2613 s_save(sc,OP_AND1, sc->NIL, cdr(sc->code));
2614 sc->code = car(sc->code);
2618 if (is_false(sc->value)) {
2619 s_return(sc,sc->value);
2620 }
else if (sc->code == sc->NIL) {
2621 s_return(sc,sc->value);
2623 s_save(sc,OP_AND1, sc->NIL, cdr(sc->code));
2624 sc->code = car(sc->code);
2629 if (sc->code == sc->NIL) {
2632 s_save(sc,OP_OR1, sc->NIL, cdr(sc->code));
2633 sc->code = car(sc->code);
2637 if (is_true(sc->value)) {
2638 s_return(sc,sc->value);
2639 }
else if (sc->code == sc->NIL) {
2640 s_return(sc,sc->value);
2642 s_save(sc,OP_OR1, sc->NIL, cdr(sc->code));
2643 sc->code = car(sc->code);
2648 s_save(sc,OP_C1STREAM, sc->NIL, cdr(sc->code));
2649 sc->code = car(sc->code);
2653 sc->args = sc->value;
2654 x = mk_closure(sc, cons(sc, sc->NIL, sc->code), sc->envir);
2655 typeflag(x)=T_PROMISE;
2656 s_return(sc,cons(sc, sc->args, x));
2659 if (is_pair(car(sc->code))) {
2661 sc->code = cons(sc, sc->LAMBDA, cons(sc, cdar(sc->code), cdr(sc->code)));
2664 sc->code = cadr(sc->code);
2666 if (!is_symbol(x)) {
2667 Error_0(sc,
"variable is not a symbol");
2669 s_save(sc,OP_MACRO1, sc->NIL, x);
2673 typeflag(sc->value) = T_MACRO;
2674 x = find_slot_in_env(sc, sc->envir, sc->code, 0);
2676 set_slot_in_env(sc, x, sc->value);
2678 new_slot_in_env(sc, sc->code, sc->value);
2680 s_return(sc,sc->code);
2683 s_save(sc,OP_CASE1, sc->NIL, cdr(sc->code));
2684 sc->code = car(sc->code);
2688 for (x = sc->code; x != sc->NIL; x = cdr(x)) {
2689 if (!is_pair(y = caar(x))) {
2692 for ( ; y != sc->NIL; y = cdr(y)) {
2693 if (eqv(car(y), sc->value)) {
2702 if (is_pair(caar(x))) {
2704 s_goto(sc,OP_BEGIN);
2706 s_save(sc,OP_CASE2, sc->NIL, cdar(x));
2711 s_return(sc,sc->NIL);
2715 if (is_true(sc->value)) {
2716 s_goto(sc,OP_BEGIN);
2718 s_return(sc,sc->NIL);
2722 sc->code = car(sc->args);
2723 sc->args = list_star(sc,cdr(sc->args));
2725 s_goto(sc,OP_APPLY);
2728 if(cdr(sc->args)!=sc->NIL) {
2729 sc->envir=cadr(sc->args);
2731 sc->code = car(sc->args);
2734 case OP_CONTINUATION:
2735 sc->code = car(sc->args);
2736 sc->args = cons(sc, mk_continuation(sc, sc->dump), sc->NIL);
2737 s_goto(sc,OP_APPLY);
2740 sprintf(sc->strbuff,
"%d: illegal operator", sc->op);
2741 Error_0(sc,sc->strbuff);
2746 static pointer opexe_2(scheme *sc,
enum scheme_opcodes op) {
2759 }
else if(modf(rvalue_unchecked(x),&dd)==0.0) {
2760 s_return(sc,mk_integer(sc,ivalue(x)));
2762 Error_1(sc,
"inexact->exact: not integral:",x);
2767 s_return(sc, mk_real(sc, exp(rvalue(x))));
2771 s_return(sc, mk_real(sc, log(rvalue(x))));
2775 s_return(sc, mk_real(sc, sin(rvalue(x))));
2779 s_return(sc, mk_real(sc, cos(rvalue(x))));
2783 s_return(sc, mk_real(sc, tan(rvalue(x))));
2787 s_return(sc, mk_real(sc, asin(rvalue(x))));
2791 s_return(sc, mk_real(sc, acos(rvalue(x))));
2795 if(cdr(sc->args)==sc->NIL) {
2796 s_return(sc, mk_real(sc, atan(rvalue(x))));
2798 pointer y=cadr(sc->args);
2799 s_return(sc, mk_real(sc, atan2(rvalue(x),rvalue(y))));
2804 s_return(sc, mk_real(sc, sqrt(rvalue(x))));
2808 if(cdr(sc->args)==sc->NIL) {
2809 Error_0(sc,
"expt: needs two arguments");
2811 pointer y=cadr(sc->args);
2812 s_return(sc, mk_real(sc, pow(rvalue(x),rvalue(y))));
2817 s_return(sc, mk_real(sc, floor(rvalue(x))));
2821 s_return(sc, mk_real(sc, ceil(rvalue(x))));
2823 case OP_TRUNCATE : {
2824 double rvalue_of_x ;
2826 rvalue_of_x = rvalue(x) ;
2827 if (rvalue_of_x > 0) {
2828 s_return(sc, mk_real(sc, floor(rvalue_of_x)));
2830 s_return(sc, mk_real(sc, ceil(rvalue_of_x)));
2836 s_return(sc, mk_real(sc, round_per_R5RS(rvalue(x))));
2841 for (x = sc->args; x != sc->NIL; x = cdr(x)) {
2842 v=num_add(v,nvalue(car(x)));
2844 s_return(sc,mk_number(sc, v));
2848 for (x = sc->args; x != sc->NIL; x = cdr(x)) {
2849 v=num_mul(v,nvalue(car(x)));
2851 s_return(sc,mk_number(sc, v));
2854 if(cdr(sc->args)==sc->NIL) {
2859 v = nvalue(car(sc->args));
2861 for (; x != sc->NIL; x = cdr(x)) {
2862 v=num_sub(v,nvalue(car(x)));
2864 s_return(sc,mk_number(sc, v));
2867 if(cdr(sc->args)==sc->NIL) {
2872 v = nvalue(car(sc->args));
2874 for (; x != sc->NIL; x = cdr(x)) {
2875 if (!is_zero_double(rvalue(car(x))))
2876 v=num_div(v,nvalue(car(x)));
2878 Error_0(sc,
"/: division by zero");
2881 s_return(sc,mk_number(sc, v));
2884 if(cdr(sc->args)==sc->NIL) {
2889 v = nvalue(car(sc->args));
2891 for (; x != sc->NIL; x = cdr(x)) {
2892 if (ivalue(car(x)) != 0)
2893 v=num_intdiv(v,nvalue(car(x)));
2895 Error_0(sc,
"quotient: division by zero");
2898 s_return(sc,mk_number(sc, v));
2901 v = nvalue(car(sc->args));
2902 if (ivalue(cadr(sc->args)) != 0)
2903 v=num_rem(v,nvalue(cadr(sc->args)));
2905 Error_0(sc,
"remainder: division by zero");
2907 s_return(sc,mk_number(sc, v));
2910 v = nvalue(car(sc->args));
2911 if (ivalue(cadr(sc->args)) != 0)
2912 v=num_mod(v,nvalue(cadr(sc->args)));
2914 Error_0(sc,
"modulo: division by zero");
2916 s_return(sc,mk_number(sc, v));
2919 s_return(sc,caar(sc->args));
2922 s_return(sc,cdar(sc->args));
2925 cdr(sc->args) = cadr(sc->args);
2926 s_return(sc,sc->args);
2929 if(!is_immutable(car(sc->args))) {
2930 caar(sc->args) = cadr(sc->args);
2931 s_return(sc,car(sc->args));
2933 Error_0(sc,
"set-car!: unable to alter immutable pair");
2937 if(!is_immutable(car(sc->args))) {
2938 cdar(sc->args) = cadr(sc->args);
2939 s_return(sc,car(sc->args));
2941 Error_0(sc,
"set-cdr!: unable to alter immutable pair");
2946 c=(char)ivalue(car(sc->args));
2947 s_return(sc,mk_integer(sc,(
unsigned char)c));
2952 c=(
unsigned char)ivalue(car(sc->args));
2953 s_return(sc,mk_character(sc,(
char)c));
2956 case OP_CHARUPCASE: {
2958 c=(
unsigned char)ivalue(car(sc->args));
2960 s_return(sc,mk_character(sc,(
char)c));
2963 case OP_CHARDNCASE: {
2965 c=(
unsigned char)ivalue(car(sc->args));
2967 s_return(sc,mk_character(sc,(
char)c));
2971 s_return(sc,mk_symbol(sc,strvalue(car(sc->args))));
2974 char *s=strvalue(car(sc->args));
2976 s_return(sc, mk_sharp_const(sc, s+1));
2978 s_return(sc, mk_atom(sc, s));
2983 x=mk_string(sc,symname(car(sc->args)));
2988 if(is_number(x) || is_character(x) || is_string(x) || is_symbol(x)) {
2991 atom2str(sc,x,0,&p,&len);
2992 s_return(sc,mk_counted_string(sc,p,len));
2994 Error_1(sc,
"atom->string: not an atom:", x);
3001 len=ivalue(car(sc->args));
3003 if(cdr(sc->args)!=sc->NIL) {
3004 fill=charvalue(cadr(sc->args));
3006 s_return(sc,mk_empty_string(sc,len,(
char)fill));
3010 s_return(sc,mk_integer(sc,strlength(car(sc->args))));
3016 str=strvalue(car(sc->args));
3018 index=ivalue(cadr(sc->args));
3020 if(index>=strlength(car(sc->args))) {
3021 Error_1(sc,
"string-ref: out of bounds:",cadr(sc->args));
3024 s_return(sc,mk_character(sc,((
unsigned char*)str)[index]));
3032 if(is_immutable(car(sc->args))) {
3033 Error_1(sc,
"string-set!: unable to alter immutable string:",car(sc->args));
3035 str=strvalue(car(sc->args));
3037 index=ivalue(cadr(sc->args));
3038 if(index>=strlength(car(sc->args))) {
3039 Error_1(sc,
"string-set!: out of bounds:",cadr(sc->args));
3042 c=charvalue(caddr(sc->args));
3045 s_return(sc,car(sc->args));
3048 case OP_STRAPPEND: {
3055 for (x = sc->args; x != sc->NIL; x = cdr(x)) {
3056 len += strlength(car(x));
3058 newstr = mk_empty_string(sc, len,
' ');
3060 for (pos = strvalue(newstr), x = sc->args; x != sc->NIL;
3061 pos += strlength(car(x)), x = cdr(x)) {
3062 memcpy(pos, strvalue(car(x)), strlength(car(x)));
3064 s_return(sc, newstr);
3073 str=strvalue(car(sc->args));
3075 index0=ivalue(cadr(sc->args));
3077 if(index0>strlength(car(sc->args))) {
3078 Error_1(sc,
"substring: start out of bounds:",cadr(sc->args));
3081 if(cddr(sc->args)!=sc->NIL) {
3082 index1=ivalue(caddr(sc->args));
3083 if(index1>strlength(car(sc->args)) || index1<index0) {
3084 Error_1(sc,
"substring: end out of bounds:",caddr(sc->args));
3087 index1=strlength(car(sc->args));
3091 x=mk_empty_string(sc,len,
' ');
3092 memcpy(strvalue(x),str+index0,len);
3101 int len=list_length(sc,sc->args);
3103 Error_1(sc,
"vector: not a proper list:",sc->args);
3105 vec=mk_vector(sc,len);
3106 for (x = sc->args, i = 0; is_pair(x); x = cdr(x), i++) {
3107 set_vector_elem(vec,i,car(x));
3113 pointer fill=sc->NIL;
3117 len=ivalue(car(sc->args));
3119 if(cdr(sc->args)!=sc->NIL) {
3120 fill=cadr(sc->args);
3122 vec=mk_vector(sc,len);
3124 fill_vector(vec,fill);
3130 s_return(sc,mk_integer(sc,ivalue(car(sc->args))));
3135 index=ivalue(cadr(sc->args));
3137 if(index>=ivalue(car(sc->args))) {
3138 Error_1(sc,
"vector-ref: out of bounds:",cadr(sc->args));
3141 s_return(sc,vector_elem(car(sc->args),index));
3147 if(is_immutable(car(sc->args))) {
3148 Error_1(sc,
"vector-set!: unable to alter immutable vector:",car(sc->args));
3151 index=ivalue(cadr(sc->args));
3152 if(index>=ivalue(car(sc->args))) {
3153 Error_1(sc,
"vector-set!: out of bounds:",cadr(sc->args));
3156 set_vector_elem(car(sc->args),index,caddr(sc->args));
3157 s_return(sc,car(sc->args));
3161 sprintf(sc->strbuff,
"%d: illegal operator", sc->op);
3162 Error_0(sc,sc->strbuff);
3167 static int list_length(scheme *sc, pointer a) {
3170 for (x = a, v = 0; is_pair(x); x = cdr(x)) {
3179 static pointer opexe_3(scheme *sc,
enum scheme_opcodes op) {
3182 int (*comp_func)(num,num)=0;
3186 s_retbool(is_false(car(sc->args)));
3188 s_retbool(car(sc->args) == sc->F || car(sc->args) == sc->T);
3190 s_retbool(car(sc->args) == sc->EOF_OBJ);
3192 s_retbool(car(sc->args) == sc->NIL);
3199 case OP_NUMEQ: comp_func=num_eq;
break;
3200 case OP_LESS: comp_func=num_lt;
break;
3201 case OP_GRE: comp_func=num_gt;
break;
3202 case OP_LEQ: comp_func=num_le;
break;
3203 case OP_GEQ: comp_func=num_ge;
break;
3211 for (; x != sc->NIL; x = cdr(x)) {
3212 if(!comp_func(v,nvalue(car(x)))) {
3219 s_retbool(is_symbol(car(sc->args)));
3221 s_retbool(is_number(car(sc->args)));
3223 s_retbool(is_string(car(sc->args)));
3225 s_retbool(is_integer(car(sc->args)));
3227 s_retbool(is_number(car(sc->args)));
3229 s_retbool(is_character(car(sc->args)));
3230 #if USE_CHAR_CLASSIFIERS
3232 s_retbool(Cisalpha(ivalue(car(sc->args))));
3234 s_retbool(Cisdigit(ivalue(car(sc->args))));
3236 s_retbool(Cisspace(ivalue(car(sc->args))));
3238 s_retbool(Cisupper(ivalue(car(sc->args))));
3240 s_retbool(Cislower(ivalue(car(sc->args))));
3243 s_retbool(is_port(car(sc->args)));
3245 s_retbool(is_inport(car(sc->args)));
3247 s_retbool(is_outport(car(sc->args)));
3254 s_retbool(is_proc(car(sc->args)) || is_closure(car(sc->args))
3255 || is_continuation(car(sc->args)) || is_foreign(car(sc->args)));
3257 s_retbool(is_pair(car(sc->args)));
3260 slow = fast = car(sc->args);
3262 if (!is_pair(fast)) s_retbool(fast == sc->NIL);
3264 if (!is_pair(fast)) s_retbool(fast == sc->NIL);
3276 s_retbool(is_environment(car(sc->args)));
3278 s_retbool(is_vector(car(sc->args)));
3280 s_retbool(car(sc->args) == cadr(sc->args));
3282 s_retbool(eqv(car(sc->args), cadr(sc->args)));
3284 sprintf(sc->strbuff,
"%d: illegal operator", sc->op);
3285 Error_0(sc,sc->strbuff);
3290 static pointer opexe_4(scheme *sc,
enum scheme_opcodes op) {
3295 sc->code = car(sc->args);
3296 if (is_promise(sc->code)) {
3298 s_save(sc, OP_SAVE_FORCED, sc->NIL, sc->code);
3300 s_goto(sc,OP_APPLY);
3302 s_return(sc,sc->code);
3305 case OP_SAVE_FORCED:
3306 memcpy(sc->code,sc->value,
sizeof(
struct cell));
3307 s_return(sc,sc->value);
3312 if(is_pair(cdr(sc->args))) {
3313 if(cadr(sc->args)!=sc->outport) {
3314 x=cons(sc,sc->outport,sc->NIL);
3315 s_save(sc,OP_SET_OUTPORT, x, sc->NIL);
3316 sc->outport=cadr(sc->args);
3319 sc->args = car(sc->args);
3325 s_goto(sc,OP_P0LIST);
3328 if(is_pair(sc->args)) {
3329 if(car(sc->args)!=sc->outport) {
3330 x=cons(sc,sc->outport,sc->NIL);
3331 s_save(sc,OP_SET_OUTPORT, x, sc->NIL);
3332 sc->outport=car(sc->args);
3340 if (!is_string(car(sc->args))) {
3341 sc->args=cons(sc,mk_string(sc,
" -- "),sc->args);
3342 setimmutable(car(sc->args));
3344 putstr(sc,
"Error: ");
3345 putstr(sc, strvalue(car(sc->args)));
3346 sc->args = cdr(sc->args);
3351 if (sc->args != sc->NIL) {
3352 s_save(sc,OP_ERR1, cdr(sc->args), sc->NIL);
3353 sc->args = car(sc->args);
3355 s_goto(sc,OP_P0LIST);
3358 if(sc->interactive_repl) {
3359 s_goto(sc,OP_T0LVL);
3366 s_return(sc,reverse(sc, car(sc->args)));
3369 s_return(sc,list_star(sc,sc->args));
3372 if(sc->args==sc->NIL) {
3373 s_return(sc,sc->NIL);
3376 if(cdr(sc->args)==sc->NIL) {
3377 s_return(sc,sc->args);
3379 for (y = cdr(sc->args); y != sc->NIL; y = cdr(y)) {
3380 x=append(sc,x,car(y));
3386 if (!hasprop(car(sc->args)) || !hasprop(cadr(sc->args))) {
3387 Error_0(sc,
"illegal use of put");
3389 for (x = symprop(car(sc->args)), y = cadr(sc->args); x != sc->NIL; x = cdr(x)) {
3395 cdar(x) = caddr(sc->args);
3397 symprop(car(sc->args)) = cons(sc, cons(sc, y, caddr(sc->args)),
3398 symprop(car(sc->args)));
3402 if (!hasprop(car(sc->args)) || !hasprop(cadr(sc->args))) {
3403 Error_0(sc,
"illegal use of get");
3405 for (x = symprop(car(sc->args)), y = cadr(sc->args); x != sc->NIL; x = cdr(x)) {
3411 s_return(sc,cdar(x));
3413 s_return(sc,sc->NIL);
3417 if(is_pair(sc->args)) {
3418 sc->retcode=ivalue(car(sc->args));
3423 gc(sc, sc->NIL, sc->NIL);
3427 {
int was = sc->gc_verbose;
3429 sc->gc_verbose = (car(sc->args) != sc->F);
3434 if (!is_pair(sc->args) || !is_number(car(sc->args))) {
3435 Error_0(sc,
"new-segment: argument must be a number");
3437 alloc_cellseg(sc, (
int) ivalue(car(sc->args)));
3441 s_return(sc, oblist_all_symbols(sc));
3443 case OP_CURR_INPORT:
3444 s_return(sc,sc->inport);
3446 case OP_CURR_OUTPORT:
3447 s_return(sc,sc->outport);
3449 case OP_OPEN_INFILE:
3450 case OP_OPEN_OUTFILE:
3451 case OP_OPEN_INOUTFILE: {
3455 case OP_OPEN_INFILE: prop=port_input;
break;
3456 case OP_OPEN_OUTFILE: prop=port_output;
break;
3457 case OP_OPEN_INOUTFILE: prop=port_input|port_output;
break;
3461 p=port_from_filename(sc,strvalue(car(sc->args)),prop);
3468 #if USE_STRING_PORTS
3469 case OP_OPEN_INSTRING:
3470 case OP_OPEN_OUTSTRING:
3471 case OP_OPEN_INOUTSTRING: {
3475 case OP_OPEN_INSTRING: prop=port_input;
break;
3476 case OP_OPEN_OUTSTRING: prop=port_output;
break;
3477 case OP_OPEN_INOUTSTRING: prop=port_input|port_output;
break;
3481 p=port_from_string(sc, strvalue(car(sc->args)),
3482 strvalue(car(sc->args))+strlength(car(sc->args)), prop);
3490 case OP_CLOSE_INPORT:
3491 port_close(sc,car(sc->args),port_input);
3494 case OP_CLOSE_OUTPORT:
3495 port_close(sc,car(sc->args),port_output);
3499 s_return(sc,sc->global_env);
3502 s_return(sc,sc->envir);
3509 static pointer opexe_5(scheme *sc,
enum scheme_opcodes op) {
3512 if(sc->nesting!=0) {
3516 Error_1(sc,
"unmatched parentheses:",mk_integer(sc,n));
3522 if(!is_pair(sc->args)) {
3523 s_goto(sc,OP_READ_INTERNAL);
3525 if(!is_inport(car(sc->args))) {
3526 Error_1(sc,
"read: not an input port:",car(sc->args));
3528 if(car(sc->args)==sc->inport) {
3529 s_goto(sc,OP_READ_INTERNAL);
3532 sc->inport=car(sc->args);
3533 x=cons(sc,x,sc->NIL);
3534 s_save(sc,OP_SET_INPORT, x, sc->NIL);
3535 s_goto(sc,OP_READ_INTERNAL);
3538 case OP_PEEK_CHAR: {
3540 if(is_pair(sc->args)) {
3541 if(car(sc->args)!=sc->inport) {
3543 x=cons(sc,x,sc->NIL);
3544 s_save(sc,OP_SET_INPORT, x, sc->NIL);
3545 sc->inport=car(sc->args);
3550 s_return(sc,sc->EOF_OBJ);
3552 if(sc->op==OP_PEEK_CHAR) {
3555 s_return(sc,mk_character(sc,c));
3558 case OP_CHAR_READY: {
3559 pointer p=sc->inport;
3561 if(is_pair(sc->args)) {
3564 res=p->_object._port->kind&port_string;
3569 sc->inport=car(sc->args);
3570 s_return(sc,sc->value);
3572 case OP_SET_OUTPORT:
3573 sc->outport=car(sc->args);
3574 s_return(sc,sc->value);
3579 if(sc->inport==sc->loadport) {
3583 s_return(sc,sc->EOF_OBJ);
3587 while ((c=inchar(sc)) !=
'\n' && c!=EOF)
3589 sc->tok = token(sc);
3590 s_goto(sc,OP_RDSEXPR);
3593 s_save(sc,OP_RDVEC,sc->NIL,sc->NIL);
3596 sc->tok = token(sc);
3597 if (sc->tok == TOK_RPAREN) {
3598 s_return(sc,sc->NIL);
3599 }
else if (sc->tok == TOK_DOT) {
3600 Error_0(sc,
"syntax error: illegal dot expression");
3602 sc->nesting_stack[sc->file_i]++;
3603 s_save(sc,OP_RDLIST, sc->NIL, sc->NIL);
3604 s_goto(sc,OP_RDSEXPR);
3607 s_save(sc,OP_RDQUOTE, sc->NIL, sc->NIL);
3608 sc->tok = token(sc);
3609 s_goto(sc,OP_RDSEXPR);
3611 sc->tok = token(sc);
3612 if(sc->tok==TOK_VEC) {
3613 s_save(sc,OP_RDQQUOTEVEC, sc->NIL, sc->NIL);
3615 s_goto(sc,OP_RDSEXPR);
3617 s_save(sc,OP_RDQQUOTE, sc->NIL, sc->NIL);
3619 s_goto(sc,OP_RDSEXPR);
3621 s_save(sc,OP_RDUNQUOTE, sc->NIL, sc->NIL);
3622 sc->tok = token(sc);
3623 s_goto(sc,OP_RDSEXPR);
3625 s_save(sc,OP_RDUQTSP, sc->NIL, sc->NIL);
3626 sc->tok = token(sc);
3627 s_goto(sc,OP_RDSEXPR);
3629 s_return(sc,mk_atom(sc, readstr_upto(sc,
"();\t\n\r ")));
3633 Error_0(sc,
"Error reading string");
3638 pointer f=find_slot_in_env(sc,sc->envir,sc->SHARP_HOOK,1);
3640 Error_0(sc,
"undefined sharp expression");
3642 sc->code=cons(sc,slot_value_in_env(f),sc->NIL);
3646 case TOK_SHARP_CONST:
3647 if ((x = mk_sharp_const(sc, readstr_upto(sc,
"();\t\n\r "))) == sc->NIL) {
3648 Error_0(sc,
"undefined sharp expression");
3653 Error_0(sc,
"syntax error: illegal token");
3658 sc->args = cons(sc, sc->value, sc->args);
3659 sc->tok = token(sc);
3660 if (sc->tok == TOK_COMMENT) {
3662 while ((c=inchar(sc)) !=
'\n' && c!=EOF)
3664 sc->tok = token(sc);
3666 if (sc->tok == TOK_RPAREN) {
3668 if (c !=
'\n') backchar(sc,c);
3669 sc->nesting_stack[sc->file_i]--;
3670 s_return(sc,reverse_in_place(sc, sc->NIL, sc->args));
3671 }
else if (sc->tok == TOK_DOT) {
3672 s_save(sc,OP_RDDOT, sc->args, sc->NIL);
3673 sc->tok = token(sc);
3674 s_goto(sc,OP_RDSEXPR);
3676 s_save(sc,OP_RDLIST, sc->args, sc->NIL);;
3677 s_goto(sc,OP_RDSEXPR);
3682 if (token(sc) != TOK_RPAREN) {
3683 Error_0(sc,
"syntax error: illegal dot expression");
3685 sc->nesting_stack[sc->file_i]--;
3686 s_return(sc,reverse_in_place(sc, sc->value, sc->args));
3690 s_return(sc,cons(sc, sc->QUOTE, cons(sc, sc->value, sc->NIL)));
3693 s_return(sc,cons(sc, sc->QQUOTE, cons(sc, sc->value, sc->NIL)));
3695 case OP_RDQQUOTEVEC:
3696 s_return(sc,cons(sc, mk_symbol(sc,
"apply"),
3697 cons(sc, mk_symbol(sc,
"vector"),
3698 cons(sc,cons(sc, sc->QQUOTE,
3699 cons(sc,sc->value,sc->NIL)),
3703 s_return(sc,cons(sc, sc->UNQUOTE, cons(sc, sc->value, sc->NIL)));
3706 s_return(sc,cons(sc, sc->UNQUOTESP, cons(sc, sc->value, sc->NIL)));
3717 s_goto(sc,OP_VECTOR);
3721 if(is_vector(sc->args)) {
3723 sc->args=cons(sc,sc->args,mk_integer(sc,0));
3724 s_goto(sc,OP_PVECFROM);
3725 }
else if(is_environment(sc->args)) {
3726 putstr(sc,
"#<ENVIRONMENT>");
3728 }
else if (!is_pair(sc->args)) {
3729 printatom(sc, sc->args, sc->print_flag);
3731 }
else if (car(sc->args) == sc->QUOTE && ok_abbrev(cdr(sc->args))) {
3733 sc->args = cadr(sc->args);
3734 s_goto(sc,OP_P0LIST);
3735 }
else if (car(sc->args) == sc->QQUOTE && ok_abbrev(cdr(sc->args))) {
3737 sc->args = cadr(sc->args);
3738 s_goto(sc,OP_P0LIST);
3739 }
else if (car(sc->args) == sc->UNQUOTE && ok_abbrev(cdr(sc->args))) {
3741 sc->args = cadr(sc->args);
3742 s_goto(sc,OP_P0LIST);
3743 }
else if (car(sc->args) == sc->UNQUOTESP && ok_abbrev(cdr(sc->args))) {
3745 sc->args = cadr(sc->args);
3746 s_goto(sc,OP_P0LIST);
3749 s_save(sc,OP_P1LIST, cdr(sc->args), sc->NIL);
3750 sc->args = car(sc->args);
3751 s_goto(sc,OP_P0LIST);
3755 if (is_pair(sc->args)) {
3756 s_save(sc,OP_P1LIST, cdr(sc->args), sc->NIL);
3758 sc->args = car(sc->args);
3759 s_goto(sc,OP_P0LIST);
3760 }
else if(is_vector(sc->args)) {
3761 s_save(sc,OP_P1LIST,sc->NIL,sc->NIL);
3763 s_goto(sc,OP_P0LIST);
3765 if (sc->args != sc->NIL) {
3767 printatom(sc, sc->args, sc->print_flag);
3773 int i=ivalue_unchecked(cdr(sc->args));
3774 pointer vec=car(sc->args);
3775 int len=ivalue_unchecked(vec);
3780 pointer elem=vector_elem(vec,i);
3781 ivalue_unchecked(cdr(sc->args))=i+1;
3782 s_save(sc,OP_PVECFROM, sc->args, sc->NIL);
3785 s_goto(sc,OP_P0LIST);
3790 sprintf(sc->strbuff,
"%d: illegal operator", sc->op);
3791 Error_0(sc,sc->strbuff);
3797 static pointer opexe_6(scheme *sc,
enum scheme_opcodes op) {
3802 case OP_LIST_LENGTH:
3803 v=list_length(sc,car(sc->args));
3805 Error_1(sc,
"length: not a list:",car(sc->args));
3807 s_return(sc,mk_integer(sc, v));
3811 for (y = cadr(sc->args); is_pair(y); y = cdr(y)) {
3812 if (!is_pair(car(y))) {
3813 Error_0(sc,
"unable to handle non pair element");
3819 s_return(sc,car(y));
3825 case OP_GET_CLOSURE:
3826 sc->args = car(sc->args);
3827 if (sc->args == sc->NIL) {
3829 }
else if (is_closure(sc->args)) {
3830 s_return(sc,cons(sc, sc->LAMBDA, closure_code(sc->value)));
3831 }
else if (is_macro(sc->args)) {
3832 s_return(sc,cons(sc, sc->LAMBDA, closure_code(sc->value)));
3841 s_retbool(is_closure(car(sc->args)));
3843 s_retbool(is_macro(car(sc->args)));
3845 sprintf(sc->strbuff,
"%d: illegal operator", sc->op);
3846 Error_0(sc,sc->strbuff);
3851 typedef pointer (*dispatch_func)(scheme *,
enum scheme_opcodes);
3853 typedef int (*test_predicate)(pointer);
3854 static int is_any(pointer p) {
return 1;}
3855 static int is_num_integer(pointer p) {
3856 return is_number(p) && ((p)->_object._number.is_fixnum);
3858 static int is_nonneg(pointer p) {
3859 return is_num_integer(p) && ivalue(p)>=0;
3869 {is_string,
"string"},
3870 {is_symbol,
"symbol"},
3874 {is_environment,
"environment"},
3877 {is_character,
"character"},
3878 {is_vector,
"vector"},
3879 {is_number,
"number"},
3880 {is_num_integer,
"integer"},
3881 {is_nonneg,
"non-negative integer"}
3885 #define TST_ANY "\001"
3886 #define TST_STRING "\002"
3887 #define TST_SYMBOL "\003"
3888 #define TST_PORT "\004"
3889 #define TST_INPORT "\005"
3890 #define TST_OUTPORT "\006"
3891 #define TST_ENVIRONMENT "\007"
3892 #define TST_PAIR "\010"
3893 #define TST_LIST "\011"
3894 #define TST_CHAR "\012"
3895 #define TST_VECTOR "\013"
3896 #define TST_NUMBER "\014"
3897 #define TST_INTEGER "\015"
3898 #define TST_NATURAL "\016"
3905 char *arg_tests_encoding;
3908 #define INF_ARG 0xffff
3910 static op_code_info dispatch_table[]= {
3911 #define _OP_DEF(A,B,C,D,E,OP) {A,B,C,D,E},
3916 static const char *procname(pointer x) {
3918 const char *name=dispatch_table[n].name;
3926 static void Eval_Cycle(scheme *sc,
enum scheme_opcodes op) {
3932 op_code_info *pcd=dispatch_table+sc->op;
3936 int n=list_length(sc,sc->args);
3939 if(n<pcd->min_arity) {
3941 sprintf(msg,
"%s: needs%s %d argument(s)",
3943 pcd->min_arity==pcd->max_arity?
"":
" at least",
3946 if(ok && n>pcd->max_arity) {
3948 sprintf(msg,
"%s: needs%s %d argument(s)",
3950 pcd->min_arity==pcd->max_arity?
"":
" at most",
3954 if(pcd->arg_tests_encoding!=0) {
3957 const char *t=pcd->arg_tests_encoding;
3958 pointer arglist=sc->args;
3960 pointer arg=car(arglist);
3962 if(j==TST_INPORT[0]) {
3963 if(!is_inport(arg))
break;
3964 }
else if(j==TST_OUTPORT[0]) {
3965 if(!is_outport(arg))
break;
3966 }
else if(j==TST_LIST[0]) {
3967 if(arg!=sc->NIL && !is_pair(arg))
break;
3969 if(!tests[j].fct(arg))
break;
3975 arglist=cdr(arglist);
3980 sprintf(msg,
"%s: argument %d must be: %s",
3988 if(_Error_1(sc,msg,0)==sc->NIL) {
3991 pcd=dispatch_table+sc->op;
3995 if (pcd->func(sc, (
enum scheme_opcodes)sc->op) == sc->NIL) {
3999 fprintf(stderr,
"No memory!\n");
4008 static void assign_syntax(scheme *sc,
char *name) {
4011 x = oblist_add_by_name(sc, name);
4012 typeflag(x) |= T_SYNTAX;
4015 static void assign_proc(scheme *sc,
enum scheme_opcodes op,
char *name) {
4018 x = mk_symbol(sc, name);
4020 new_slot_in_env(sc, x, y);
4023 static pointer mk_proc(scheme *sc,
enum scheme_opcodes op) {
4026 y = get_cell(sc, sc->NIL, sc->NIL);
4027 typeflag(y) = (T_PROC | T_ATOM);
4028 ivalue_unchecked(y) = (long) op;
4034 static int syntaxnum(pointer p) {
4035 const char *s=strvalue(car(p));
4036 switch(strlength(car(p))) {
4038 if(s[0]==
'i')
return OP_IF0;
4041 if(s[0]==
'a')
return OP_AND0;
4042 else return OP_LET0;
4045 case 'e':
return OP_CASE0;
4046 case 'd':
return OP_COND0;
4047 case '*':
return OP_LET0AST;
4048 default:
return OP_SET0;
4052 case 'g':
return OP_BEGIN;
4053 case 'l':
return OP_DELAY;
4054 case 'c':
return OP_MACRO0;
4055 default:
return OP_QUOTE;
4059 case 'm':
return OP_LAMBDA;
4060 case 'f':
return OP_DEF0;
4061 default:
return OP_LET0REC;
4070 INTERFACE
static pointer s_cons(scheme *sc, pointer a, pointer b) {
4071 return cons(sc,a,b);
4073 INTERFACE
static pointer s_immutable_cons(scheme *sc, pointer a, pointer b) {
4074 return immutable_cons(sc,a,b);
4077 static struct scheme_interface vtbl ={
4138 scheme *scheme_init_new() {
4139 scheme *sc=(scheme*)malloc(
sizeof(scheme));
4140 if(!scheme_init(sc)) {
4148 scheme *scheme_init_new_custom_alloc(func_alloc malloc, func_dealloc free) {
4149 scheme *sc=(scheme*)malloc(
sizeof(scheme));
4150 if(!scheme_init_custom_alloc(sc,malloc,free)) {
4159 int scheme_init(scheme *sc) {
4160 return scheme_init_custom_alloc(sc,malloc,free);
4163 int scheme_init_custom_alloc(scheme *sc, func_alloc malloc, func_dealloc free) {
4164 int i, n=
sizeof(dispatch_table)/
sizeof(dispatch_table[0]);
4167 num_zero.is_fixnum=1;
4168 num_zero.value.ivalue=0;
4169 num_one.is_fixnum=1;
4170 num_one.value.ivalue=1;
4178 sc->last_cell_seg = -1;
4179 sc->sink = &sc->_sink;
4180 sc->NIL = &sc->_NIL;
4181 sc->T = &sc->_HASHT;
4182 sc->F = &sc->_HASHF;
4183 sc->EOF_OBJ=&sc->_EOF_OBJ;
4184 sc->free_cell = &sc->_NIL;
4188 sc->outport=sc->NIL;
4189 sc->save_inport=sc->NIL;
4190 sc->loadport=sc->NIL;
4192 sc->interactive_repl=0;
4194 if (alloc_cellseg(sc,FIRST_CELLSEGS) != FIRST_CELLSEGS) {
4199 dump_stack_initialize(sc);
4204 typeflag(sc->NIL) = (T_ATOM | MARK);
4205 car(sc->NIL) = cdr(sc->NIL) = sc->NIL;
4207 typeflag(sc->T) = (T_ATOM | MARK);
4208 car(sc->T) = cdr(sc->T) = sc->T;
4210 typeflag(sc->F) = (T_ATOM | MARK);
4211 car(sc->F) = cdr(sc->F) = sc->F;
4212 sc->oblist = oblist_initial_value(sc);
4214 new_frame_in_env(sc, sc->NIL);
4215 sc->global_env = sc->envir;
4217 x = mk_symbol(sc,
"else");
4218 new_slot_in_env(sc, x, sc->T);
4220 assign_syntax(sc,
"lambda");
4221 assign_syntax(sc,
"quote");
4222 assign_syntax(sc,
"define");
4223 assign_syntax(sc,
"if");
4224 assign_syntax(sc,
"begin");
4225 assign_syntax(sc,
"set!");
4226 assign_syntax(sc,
"let");
4227 assign_syntax(sc,
"let*");
4228 assign_syntax(sc,
"letrec");
4229 assign_syntax(sc,
"cond");
4230 assign_syntax(sc,
"delay");
4231 assign_syntax(sc,
"and");
4232 assign_syntax(sc,
"or");
4233 assign_syntax(sc,
"cons-stream");
4234 assign_syntax(sc,
"macro");
4235 assign_syntax(sc,
"case");
4237 for(i=0; i<n; i++) {
4238 if(dispatch_table[i].name!=0) {
4239 assign_proc(sc, (
enum scheme_opcodes)i, dispatch_table[i].name);
4244 sc->LAMBDA = mk_symbol(sc,
"lambda");
4245 sc->QUOTE = mk_symbol(sc,
"quote");
4246 sc->QQUOTE = mk_symbol(sc,
"quasiquote");
4247 sc->UNQUOTE = mk_symbol(sc,
"unquote");
4248 sc->UNQUOTESP = mk_symbol(sc,
"unquote-splicing");
4249 sc->FEED_TO = mk_symbol(sc,
"=>");
4250 sc->COLON_HOOK = mk_symbol(sc,
"*colon-hook*");
4251 sc->ERROR_HOOK = mk_symbol(sc,
"*error-hook*");
4252 sc->SHARP_HOOK = mk_symbol(sc,
"*sharp-hook*");
4254 return !sc->no_memory;
4257 void scheme_set_input_port_file(scheme *sc, FILE *fin) {
4258 sc->inport=port_from_file(sc,fin,port_input);
4261 void scheme_set_input_port_string(scheme *sc,
char *start,
char *past_the_end) {
4262 sc->inport=port_from_string(sc,start,past_the_end,port_input);
4265 void scheme_set_output_port_file(scheme *sc, FILE *fout) {
4266 sc->outport=port_from_file(sc,fout,port_output);
4269 void scheme_set_output_port_string(scheme *sc,
char *start,
char *past_the_end) {
4270 sc->outport=port_from_string(sc,start,past_the_end,port_output);
4273 void scheme_set_external_data(scheme *sc,
void *p) {
4277 void scheme_deinit(scheme *sc) {
4281 sc->global_env=sc->NIL;
4282 dump_stack_free(sc);
4287 if(is_port(sc->inport)) {
4288 typeflag(sc->inport) = T_ATOM;
4291 sc->outport=sc->NIL;
4292 if(is_port(sc->save_inport)) {
4293 typeflag(sc->save_inport) = T_ATOM;
4295 sc->save_inport=sc->NIL;
4296 if(is_port(sc->loadport)) {
4297 typeflag(sc->loadport) = T_ATOM;
4299 sc->loadport=sc->NIL;
4301 gc(sc,sc->NIL,sc->NIL);
4303 for(i=0; i<=sc->last_cell_seg; i++) {
4304 sc->free(sc->alloc_seg[i]);
4308 void scheme_load_file(scheme *sc, FILE *fin) {
4309 dump_stack_reset(sc);
4310 sc->envir = sc->global_env;
4312 sc->load_stack[0].kind=port_input|port_file;
4313 sc->load_stack[0].rep.stdio.file=fin;
4314 sc->loadport=mk_port(sc,sc->load_stack);
4317 sc->interactive_repl=1;
4319 sc->inport=sc->loadport;
4320 Eval_Cycle(sc, OP_T0LVL);
4321 typeflag(sc->loadport)=T_ATOM;
4322 if(sc->retcode==0) {
4323 sc->retcode=sc->nesting!=0;
4327 void scheme_load_string(scheme *sc,
const char *cmd) {
4328 dump_stack_reset(sc);
4329 sc->envir = sc->global_env;
4331 sc->load_stack[0].kind=port_input|port_string;
4332 sc->load_stack[0].rep.string.start=(
char*)cmd;
4333 sc->load_stack[0].rep.string.past_the_end=(
char*)cmd+strlen(cmd);
4334 sc->load_stack[0].rep.string.curr=(
char*)cmd;
4335 sc->loadport=mk_port(sc,sc->load_stack);
4337 sc->interactive_repl=0;
4338 sc->inport=sc->loadport;
4339 Eval_Cycle(sc, OP_T0LVL);
4340 typeflag(sc->loadport)=T_ATOM;
4341 if(sc->retcode==0) {
4342 sc->retcode=sc->nesting!=0;
4346 void scheme_define(scheme *sc, pointer envir, pointer symbol, pointer value) {
4349 x=find_slot_in_env(sc,envir,symbol,0);
4351 set_slot_in_env(sc, x, value);
4353 new_slot_spec_in_env(sc, envir, symbol, value);
4358 void scheme_apply0(scheme *sc,
const char *procname) {
4359 pointer carx=mk_symbol(sc,procname);
4360 pointer cdrx=sc->NIL;
4362 dump_stack_reset(sc);
4363 sc->envir = sc->global_env;
4364 sc->code = cons(sc,carx,cdrx);
4365 sc->interactive_repl=0;
4367 Eval_Cycle(sc,OP_EVAL);
4370 void scheme_call(scheme *sc, pointer func, pointer args) {
4371 dump_stack_reset(sc);
4372 sc->envir = sc->global_env;
4375 sc->interactive_repl =0;
4377 Eval_Cycle(sc, OP_APPLY);
4388 extern MacTS_main(
int argc,
char **argv);
4390 int argc = ccommand(&argv);
4391 MacTS_main(argc,argv);
4394 int MacTS_main(
int argc,
char **argv) {
4396 int main(
int argc,
char **argv) {
4400 char *file_name=InitFile;
4407 if(argc==2 && strcmp(argv[1],
"-?")==0) {
4408 printf(
"Usage: %s [-? | <file1> <file2> ... | -1 <file> <arg1> <arg2> ...]\n\tUse - as filename for stdin.\n",argv[0]);
4411 if(!scheme_init(&sc)) {
4412 fprintf(stderr,
"Could not initialize!\n");
4415 scheme_set_input_port_file(&sc, stdin);
4416 scheme_set_output_port_file(&sc, stdout);
4418 scheme_define(&sc,sc.global_env,mk_symbol(&sc,
"load-extension"),mk_foreign_func(&sc, scm_load_ext));
4421 if(access(file_name,0)!=0) {
4422 char *p=getenv(
"TINYSCHEMEINIT");
4428 if(strcmp(file_name,
"-")==0) {
4430 }
else if(strcmp(file_name,
"-1")==0 || strcmp(file_name,
"-c")==0) {
4431 pointer args=sc.NIL;
4432 isfile=file_name[1]==
'1';
4434 if(strcmp(file_name,
"-")==0) {
4437 fin=fopen(file_name,
"r");
4439 for(;*argv;argv++) {
4440 pointer value=mk_string(&sc,*argv);
4441 args=cons(&sc,value,args);
4443 args=reverse_in_place(&sc,sc.NIL,args);
4444 scheme_define(&sc,sc.global_env,mk_symbol(&sc,
"*args*"),args);
4447 fin=fopen(file_name,
"r");
4449 if(isfile && fin==0) {
4450 fprintf(stderr,
"Could not open file %s\n",file_name);
4453 scheme_load_file(&sc,fin);
4455 scheme_load_string(&sc,file_name);
4457 if(!isfile || fin!=stdin) {
4459 fprintf(stderr,
"Errors encountered reading %s\n",file_name);
4467 }
while(file_name!=0);
4469 scheme_load_file(&sc,stdin);