mescc: Compile all of mini-mes.
[mes.git] / scaffold / mini-mes.c
1 /* -*-comment-start: "//";comment-end:""-*-
2  * Mes --- Maxwell Equations of Software
3  * Copyright © 2016,2017 Jan Nieuwenhuizen <janneke@gnu.org>
4  *
5  * This file is part of Mes.
6  *
7  * Mes is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or (at
10  * your option) any later version.
11  *
12  * Mes is distributed in the hope that it will be useful, but
13  * WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with Mes.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #define MES_MINI 1
22 #define FIXED_PRIMITIVES 0
23
24 #if __GNUC__
25 #define FIXME_NYACC 1
26 #define  __NYACC__ 0
27 #define NYACC_CAR
28 #define NYACC_CDR
29 #else
30 #define  __NYACC__ 1
31 #define NYACC_CAR nyacc_car
32 #define NYACC_CDR nyacc_cdr
33 #endif
34
35 int ARENA_SIZE = 200000;
36 char arena[200000];
37
38 int g_stdin = 0;
39
40 #if __GNUC__
41 typedef long size_t;
42 void *malloc (size_t i);
43 int open (char const *s, int mode);
44 int read (int fd, void* buf, size_t n);
45 void write (int fd, char const* s, int n);
46
47 void
48 exit (int code)
49 {
50   asm (
51        "movl %0,%%ebx\n\t"
52        "movl $1,%%eax\n\t"
53        "int  $0x80"
54        : // no outputs "=" (r)
55        : "" (code)
56        );
57   // not reached
58   exit (0);
59 }
60
61 char const*
62 getenv (char const* p)
63 {
64   return 0;
65 }
66
67 int
68 read (int fd, void* buf, size_t n)
69 {
70   int r;
71   //syscall (SYS_write, fd, s, n));
72   asm (
73        "movl %1,%%ebx\n\t"
74        "movl %2,%%ecx\n\t"
75        "movl %3,%%edx\n\t"
76        "movl $0x3,%%eax\n\t"
77        "int  $0x80\n\t"
78        "mov %%eax,%0\n\t"
79        : "=r" (r)
80        : "" (fd), "" (buf), "" (n)
81        : "eax", "ebx", "ecx", "edx"
82        );
83   return r;
84 }
85
86 int
87 open (char const *s, int mode)
88 {
89   int r;
90   //syscall (SYS_open, mode));
91   asm (
92        "mov %1,%%ebx\n\t"
93        "mov %2,%%ecx\n\t"
94        "mov $0x5,%%eax\n\t"
95        "int $0x80\n\t"
96        "mov %%eax,%0\n\t"
97        : "=r" (r)
98        : "" (s), "" (mode)
99        : "eax", "ebx", "ecx"
100        );
101   return r;
102 }
103
104 int puts (char const*);
105 char const* itoa (int);
106
107 int
108 getchar ()
109 {
110   char c;
111   int r = read (g_stdin, &c, 1);
112   if (r < 1) return -1;
113   int i = c;
114   if (i < 0) {
115     puts ("urg=");
116     puts (itoa (i));
117     puts ("\n");
118   }
119   if (i < 0) i += 256;
120   return i;
121 }
122
123 void
124 write (int fd, char const* s, int n)
125 {
126   int r;
127   //syscall (SYS_write, fd, s, n));
128   asm (
129        "mov %0,%%ebx\n\t"
130        "mov %1,%%ecx\n\t"
131        "mov %2,%%edx\n\t"
132
133        "mov $0x4, %%eax\n\t"
134        "int $0x80\n\t"
135        : // no outputs "=" (r)
136        : "" (fd), "" (s), "" (n)
137        : "eax", "ebx", "ecx", "edx"
138        );
139 }
140
141 int
142 putchar (int c)
143 {
144   //write (STDOUT, s, strlen (s));
145   //int i = write (STDOUT, s, strlen (s));
146   write (1, (char*)&c, 1);
147   return 0;
148 }
149
150 void *
151 malloc (size_t size)
152 {
153   int *n;
154   int len = size + sizeof (size);
155   //n = mmap (0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0 );
156   *n = len;
157   return (void*)(n+1);
158 }
159
160 void
161 free (void *p)
162 {
163   int *n = (int*)p-1;
164   //munmap ((void*)p, *n);
165 }
166
167 #define EOF -1
168 #define STDIN 0
169 #define STDOUT 1
170 #define STDERR 2
171
172 size_t
173 strlen (char const* s)
174 {
175   int i = 0;
176   while (s[i]) i++;
177   return i;
178 }
179
180 int
181 strcmp (char const* a, char const* b)
182 {
183   while (*a && *b && *a == *b) {a++;b++;}
184   return *a - *b;
185 }
186
187 int
188 puts (char const* s)
189 {
190   //write (STDOUT, s, strlen (s));
191   //int i = write (STDOUT, s, strlen (s));
192   int i = strlen (s);
193   write (1, s, i);
194   return 0;
195 }
196
197 int
198 eputs (char const* s)
199 {
200   //write (STDERR, s, strlen (s));
201   //int i = write (STDERR, s, strlen (s));
202   int i = strlen (s);
203   write (2, s, i);
204   return 0;
205 }
206
207 char const*
208 itoa (int x)
209 {
210   static char buf[10];
211   char *p = buf+9;
212   *p-- = 0;
213
214   int sign = x < 0;
215   if (sign)
216     x = -x;
217   
218   do
219     {
220       *p-- = '0' + (x % 10);
221       x = x / 10;
222     } while (x);
223
224   if (sign)
225     *p-- = '-';
226
227   return p+1;
228 }
229 #endif
230
231 void
232 assert_fail (char* s)
233 {
234   eputs ("assert fail:");
235 #if __GNUC__
236   eputs (s);
237 #endif
238   eputs ("\n");
239 #if __GNUC__
240   *((int*)0) = 0;
241 #endif
242 }
243
244 #if __GNUC__
245 #define assert(x) ((x) ? (void)0 : assert_fail ("boo:" #x))
246 #else
247 //#define assert(x) ((x) ? (void)0 : assert_fail ("boo:" #x))
248 #define assert(x) ((x) ? (void)0 : assert_fail (0))
249 #endif
250
251 typedef int SCM;
252
253 #if __GNUC__
254 int g_debug = 0;
255 #endif
256
257 int g_free = 0;
258
259 SCM g_continuations = 0;
260 SCM g_symbols = 0;
261 SCM g_stack = 0;
262 // a/env
263 SCM r0 = 0;
264 // param 1
265 SCM r1 = 0;
266 // save 2+load/dump
267 SCM r2 = 0;
268 // continuation
269 SCM r3 = 0;
270
271 #if __NYACC__ || FIXME_NYACC
272 enum type_t {CHAR, TCLOSURE, TCONTINUATION, TFUNCTION, KEYWORD, MACRO, NUMBER, PAIR, REF, SPECIAL, TSTRING, SYMBOL, VALUES, TVECTOR, BROKEN_HEART};
273 #else
274 enum type_t {CHAR, CLOSURE, CONTINUATION, FUNCTION, KEYWORD, MACRO, NUMBER, PAIR, REF, SPECIAL, STRING, SYMBOL, VALUES, VECTOR, BROKEN_HEART};
275 #endif
276
277 struct scm {
278   enum type_t type;
279   SCM car;
280   SCM cdr;
281 };
282
283 typedef int (*f_t) (void);
284 struct function {
285   int (*function) (void);
286   int arity;
287 };
288
289 struct scm *g_cells = arena;
290
291 //scm *g_news = 0;
292
293 // struct scm scm_nil = {SPECIAL, "()"};
294 // struct scm scm_f = {SPECIAL, "#f"};
295 // struct scm scm_t = {SPECIAL, "#t"};
296 // struct scm_dot = {SPECIAL, "."};
297 // struct scm_arrow = {SPECIAL, "=>"};
298 // struct scm_undefined = {SPECIAL, "*undefined*"};
299 // struct scm_unspecified = {SPECIAL, "*unspecified*"};
300 // struct scm_closure = {SPECIAL, "*closure*"};
301 // struct scm_circular = {SPECIAL, "*circular*"};
302 // struct scm_begin = {SPECIAL, "*begin*"};
303
304 // struct scm_vm_apply = {SPECIAL, "core:apply"};
305 // struct scm_vm_apply2 = {SPECIAL, "*vm-apply2*"};
306
307 // struct scm_vm_eval = {SPECIAL, "core:eval"};
308
309 // struct scm_vm_begin = {SPECIAL, "*vm-begin*"};
310 // //scm scm_vm_begin_read_input_file = {SPECIAL, "*vm-begin-read-input-file*"};
311 // struct scm_vm_begin2 = {SPECIAL, "*vm-begin2*"};
312
313 // struct scm_vm_return = {SPECIAL, "*vm-return*"};
314
315 // //#include "mes.symbols.h"
316
317 #define cell_nil 1
318 #define cell_f 2
319 #define cell_t 3
320 #define cell_dot 4
321 // #define cell_arrow 5
322 #define cell_undefined 6
323 #define cell_unspecified 7
324 #define cell_closure 8
325 #define cell_circular 9
326 #define cell_begin 10
327 #define cell_symbol_dot 11
328 #define cell_symbol_lambda 12
329 #define cell_symbol_begin 13
330 #define cell_symbol_if 14
331 #define cell_symbol_quote 15
332 #define cell_symbol_set_x 16
333 #define cell_symbol_sc_expand 17
334 #define cell_symbol_macro_expand 18
335 #define cell_symbol_sc_expander_alist 19
336 #define cell_symbol_call_with_values 20
337 #define cell_call_with_current_continuation 21
338 #define cell_symbol_call_with_current_continuation 22
339 #define cell_symbol_current_module 23
340 #define cell_symbol_primitive_load 24
341 #define cell_symbol_read_input_file 25
342
343 #define cell_vm_evlis 42
344 #define cell_vm_evlis2 43
345 #define cell_vm_evlis3 44
346 #define cell_vm_apply 45
347 #define cell_vm_apply2 46
348 #define cell_vm_eval 47
349 #define cell_vm_eval_car 48
350 #define cell_vm_eval_cdr 49
351 #define cell_vm_eval_cons 50
352 #define cell_vm_eval_null_p 51
353 #define cell_vm_eval_set_x 52
354 #define cell_vm_eval_macro 53
355 #define cell_vm_eval2 54
356 #define cell_vm_macro_expand 55
357 #define cell_vm_begin 56
358 #define cell_vm_begin_read_input_file 57
359 #define cell_vm_begin2 58
360 #define cell_vm_if 59
361 #define cell_vm_if_expr 60
362 #define cell_vm_call_with_values2 61
363 #define cell_vm_call_with_current_continuation2 62
364 #define cell_vm_return 63
365 #define cell_test 64
366
367
368
369 SCM tmp;
370 SCM tmp_num;
371 SCM tmp_num2;
372
373 struct function g_functions[5];
374 int g_function = 0;
375
376
377 #if __GNUC__
378 //FIXME
379 SCM make_cell (SCM type, SCM car, SCM cdr);
380 #endif
381 struct function fun_make_cell = {&make_cell, 3};
382 struct scm scm_make_cell = {TFUNCTION,0,0};
383    //, "make-cell", 0};
384 SCM cell_make_cell;
385
386 #if __GNUC__
387 //FIXME
388 SCM cons (SCM x, SCM y);
389 #endif
390 struct function fun_cons = {&cons, 2};
391 struct scm scm_cons = {TFUNCTION,0,0};
392   // "cons", 0};
393 SCM cell_cons;
394
395 #if __GNUC__
396 //FIXME
397 SCM car (SCM x);
398 #endif
399 struct function fun_car = {&car, 1};
400 struct scm scm_car = {TFUNCTION,0,0};
401   // "car", 0};
402 SCM cell_car;
403
404 #if __GNUC__
405 //FIXME
406 SCM cdr (SCM x);
407 #endif
408 struct function fun_cdr = {&cdr, 1};
409 struct scm scm_cdr = {TFUNCTION,0,0};
410 // "cdr", 0};
411 SCM cell_cdr;
412
413 // SCM eq_p (SCM x, SCM y);
414 // struct function fun_eq_p = {&eq_p, 2};
415 // scm scm_eq_p = {TFUNCTION,0,0};// "eq?", 0};
416 // SCM cell_eq_p;
417
418 #define TYPE(x) (g_cells[x].type)
419
420 #define CAR(x) g_cells[x].car
421 #define LENGTH(x) g_cells[x].car
422 #define STRING(x) g_cells[x].car
423
424 #define CDR(x) g_cells[x].cdr
425 #define CLOSURE(x) g_cells[x].cdr
426 #define CONTINUATION(x) g_cells[x].cdr
427 #if __GNUC__
428 //#define FUNCTION(x) g_functions[g_cells[x].function]
429 #endif
430
431 #define FUNCTION(x) g_functions[g_cells[x].cdr]
432 #define VALUE(x) g_cells[x].cdr
433 #define VECTOR(x) g_cells[x].cdr
434
435 #define MAKE_CHAR(n) make_cell (tmp_num_ (CHAR), 0, tmp_num2_ (n))
436 #define MAKE_CONTINUATION(n) make_cell (tmp_num_ (TCONTINUATION), n, g_stack)
437 #define MAKE_NUMBER(n) make_cell (tmp_num_ (NUMBER), 0, tmp_num2_ (n))
438 //#define MAKE_REF(n) make_cell (tmp_num_ (REF), n, 0)
439
440
441 #define CAAR(x) CAR (CAR (x))
442 // #define CDAR(x) CDR (CAR (x))
443 #define CADAR(x) CAR (CDR (CAR (x)))
444 #define CADDR(x) CAR (CDR (CDR (x)))
445 // #define CDDDR(x) CDR (CDR (CDR (x)))
446 #define CDADAR(x) CAR (CDR (CAR (CDR (x))))
447 #define CADR(x) CAR (CDR (x))
448
449
450 #if __NYACC__ || FIXME_NYACC
451 #define MAKE_STRING(x) make_cell (tmp_num_ (TSTRING), x, 0)
452 // #else
453 // #define MAKE_STRING(x) make_cell (tmp_num_ (STRING), x, 0)
454 #endif
455
456 SCM
457 alloc (int n)
458 {
459   assert (g_free + n < ARENA_SIZE);
460   SCM x = g_free;
461   g_free += n;
462   return x;
463 }
464
465 SCM
466 make_cell (SCM type, SCM car, SCM cdr)
467 {
468   SCM x = alloc (1);
469 #if __GNUC__
470   puts ("make_cell type=");
471   puts (itoa (type));
472   puts ("\n");
473   puts ("make_cell type.type=");
474   puts (itoa (TYPE (type)));
475   puts ("\n");
476 #endif
477   assert (TYPE (type) == NUMBER);
478   TYPE (x) = VALUE (type);
479   if (VALUE (type) == CHAR || VALUE (type) == NUMBER) {
480     if (car) CAR (x) = CAR (car);
481     if (cdr) CDR(x) = CDR(cdr);
482   }
483   else if (VALUE (type) == TFUNCTION) {
484     if (car) CAR (x) = car;
485     if (cdr) CDR(x) = CDR(cdr);
486   }
487   else {
488     CAR (x) = car;
489     CDR(x) = cdr;
490   }
491   return x;
492 }
493
494 SCM
495 tmp_num_ (int x)
496 {
497   VALUE (tmp_num) = x;
498   return tmp_num;
499 }
500
501 SCM
502 tmp_num2_ (int x)
503 {
504   VALUE (tmp_num2) = x;
505   return tmp_num2;
506 }
507
508 SCM
509 cons (SCM x, SCM y)
510 {
511   puts ("cons x=");
512 #if __GNUC__
513   puts (itoa (x));
514 #endif
515   puts ("\n");
516   VALUE (tmp_num) = PAIR;
517   return make_cell (tmp_num, x, y);
518 }
519
520 SCM
521 car (SCM x)
522 {
523   puts ("car x=");
524 #if __GNUC__
525   puts (itoa (x));
526 #endif
527   puts ("\n");
528 #if MES_MINI
529   //Nyacc
530   //assert ("!car");
531 #else
532   if (TYPE (x) != PAIR) error (cell_symbol_not_a_pair, cons (x, cell_symbol_car));
533 #endif
534   return CAR (x);
535 }
536
537 SCM
538 cdr (SCM x)
539 {
540   puts ("cdr x=");
541 #if __GNUC__
542   puts (itoa (x));
543 #endif
544   puts ("\n");
545 #if MES_MINI
546   //Nyacc
547   //assert ("!cdr");
548 #else
549   if (TYPE (x) != PAIR) error (cell_symbol_not_a_pair, cons (x, cell_symbol_cdr));
550 #endif
551   return CDR(x);
552 }
553
554 // SCM
555 // eq_p (SCM x, SCM y)
556 // {
557 //   return (x == y
558 //           || ((TYPE (x) == KEYWORD && TYPE (y) == KEYWORD
559 //                && STRING (x) == STRING (y)))
560 //           || (TYPE (x) == CHAR && TYPE (y) == CHAR
561 //               && VALUE (x) == VALUE (y))
562 //           || (TYPE (x) == NUMBER && TYPE (y) == NUMBER
563 //               && VALUE (x) == VALUE (y)))
564 //     ? cell_t : cell_f;
565 // }
566
567 SCM
568 assert_defined (SCM x, SCM e)
569 {
570   if (e != cell_undefined) return e;
571   // error (cell_symbol_unbound_variable, x);
572   puts ("unbound variable");
573   exit (33);
574   return e;
575 }
576
577 SCM
578 gc_push_frame ()
579 {
580   SCM frame = cons (r1, cons (r2, cons (r3, cons (r0, cell_nil))));
581   g_stack = cons (frame, g_stack);
582   return g_stack;
583 }
584
585 SCM
586 append2 (SCM x, SCM y)
587 {
588   if (x == cell_nil) return y;
589 #if __GNUC__
590   //FIXME GNUC
591   assert (TYPE (x) == PAIR);
592 #endif
593   return cons (car (x), append2 (cdr (x), y));
594 }
595
596 SCM
597 pairlis (SCM x, SCM y, SCM a)
598 {
599   if (x == cell_nil)
600     return a;
601   if (TYPE (x) != PAIR)
602     return cons (cons (x, y), a);
603   return cons (cons (car (x), car (y)),
604                pairlis (cdr (x), cdr (y), a));
605 }
606
607 SCM
608 assq (SCM x, SCM a)
609 {
610   //while (a != cell_nil && eq_p (x, CAAR (a)) == cell_f) a = CDR (a);
611   while (a != cell_nil && x == CAAR (a)) a = CDR (a);
612   return a != cell_nil ? car (a) : cell_f;
613 }
614
615 SCM
616 assq_ref_env (SCM x, SCM a)
617 {
618   x = assq (x, a);
619   if (x == cell_f) return cell_undefined;
620   return cdr (x);
621 }
622
623 SCM
624 set_car_x (SCM x, SCM e)
625 {
626   assert (TYPE (x) == PAIR);
627   CAR (x) = e;
628   return cell_unspecified;
629 }
630
631 SCM
632 set_cdr_x (SCM x, SCM e)
633 {
634   //if (TYPE (x) != PAIR) error (cell_symbol_not_a_pair, cons (x, cell_set_cdr_x));
635   CDR (x) = e;
636   return cell_unspecified;
637 }
638
639 SCM
640 set_env_x (SCM x, SCM e, SCM a)
641 {
642   SCM p = assert_defined (x, assq (x, a));
643   //if (TYPE (p) != PAIR)  error (cell_symbol_not_a_pair, cons (p, x));
644   return set_cdr_x (p, e);
645 }
646
647 SCM
648 call_lambda (SCM e, SCM x, SCM aa, SCM a) ///((internal))
649 {
650   SCM cl = cons (cons (cell_closure, x), x);
651   r1 = e;
652   r0 = cl;
653   return cell_unspecified;
654 }
655
656 SCM
657 push_cc (SCM p1, SCM p2, SCM a, SCM c) ///((internal))
658 {
659   puts ("push cc\n");
660   SCM x = r3;
661   r3 = c;
662   r2 = p2;
663   gc_push_frame ();
664   r1 = p1;
665   r0 = a;
666   r3 = x;
667   return cell_unspecified;
668 }
669
670 SCM caar (SCM x) {return car (car (x));}
671 SCM cadr (SCM x) {return car (cdr (x));}
672 SCM cdar (SCM x) {return cdr (car (x));}
673 SCM cddr (SCM x) {return cdr (cdr (x));}
674
675 #if __GNUC__
676 //FIXME
677 SCM make_closure (SCM,SCM,SCM);
678 SCM call (SCM,SCM);
679 SCM gc_pop_frame ();
680 #endif
681
682 SCM
683 eval_apply ()
684 {
685   puts ("e/a: fixme\n");
686  eval_apply:
687   asm (".byte 0x90");
688   asm (".byte 0x90");
689   asm (".byte 0x90");
690   asm (".byte 0x90");
691   puts ("eval_apply\n");
692   // if (g_free + GC_SAFETY > ARENA_SIZE)
693   //   gc_pop_frame (gc (gc_push_frame ()));
694
695   switch (r3)
696     {
697     case cell_vm_evlis: goto evlis;
698     case cell_vm_evlis2: goto evlis2;
699     case cell_vm_evlis3: goto evlis3;
700     case cell_vm_apply: goto apply;
701     case cell_vm_apply2: goto apply2;
702     case cell_vm_eval: goto eval;
703 #if FIXED_PRIMITIVES
704     case cell_vm_eval_car: goto eval_car;
705     case cell_vm_eval_cdr: goto eval_cdr;
706     case cell_vm_eval_cons: goto eval_cons;
707     case cell_vm_eval_null_p: goto eval_null_p;
708 #endif
709     case cell_vm_eval_set_x: goto eval_set_x;
710     case cell_vm_eval_macro: goto eval_macro;
711     case cell_vm_eval2: goto eval2;
712     case cell_vm_macro_expand: goto macro_expand;
713     case cell_vm_begin: goto begin;
714       ///case cell_vm_begin_read_input_file: goto begin_read_input_file;
715     case cell_vm_begin2: goto begin2;
716     case cell_vm_if: goto vm_if;
717     case cell_vm_if_expr: goto if_expr;
718     case cell_vm_call_with_current_continuation2: goto call_with_current_continuation2;
719     case cell_vm_call_with_values2: goto call_with_values2;
720     case cell_vm_return: goto vm_return;
721     case cell_unspecified: return r1;
722     default: assert (0);
723     }
724
725   SCM x = cell_nil;
726   SCM y = cell_nil;
727  evlis:
728   if (r1 == cell_nil) goto vm_return;
729   if (TYPE (r1) != PAIR) goto eval;
730   push_cc (car (r1), r1, r0, cell_vm_evlis2);
731   goto eval;
732  evlis2:
733   push_cc (cdr (r2), r1, r0, cell_vm_evlis3);
734   goto evlis;
735  evlis3:
736   r1 = cons (r2, r1);
737   goto vm_return;
738
739  apply:
740   puts ("apply\n");
741   switch (TYPE (car (r1)))
742     {
743     case TFUNCTION: {
744       //check_formals (car (r1), MAKE_NUMBER (FUNCTION (car (r1)).arity), cdr (r1));
745       r1 = call (car (r1), cdr (r1)); /// FIXME: move into eval_apply
746       goto vm_return;
747     }
748     case TCLOSURE:
749       {
750         SCM cl = CLOSURE (car (r1));
751         SCM formals = cadr (cl);
752         SCM body = cddr (cl);
753         SCM aa = cdar (cl);
754         aa = cdr (aa);
755         //check_formals (car (r1), formals, cdr (r1));
756         SCM p = pairlis (formals, cdr (r1), aa);
757         call_lambda (body, p, aa, r0);
758         goto begin;
759       }
760       case TCONTINUATION:
761         {
762           x = r1;
763           g_stack = CONTINUATION (CAR (r1));
764           gc_pop_frame ();
765           r1 = cadr (x);
766           goto eval_apply;
767         }
768     case SPECIAL:
769       {
770         switch (car (r1))
771           {
772           case cell_vm_apply:
773             {
774               push_cc (cons (CADR (r1), CADDR (r1)), r1, r0, cell_vm_return);
775               goto apply;
776             }
777           case cell_vm_eval:
778             {
779               push_cc (CADR (r1), r1, CADDR (r1), cell_vm_return);
780               goto eval;
781             }
782           case cell_call_with_current_continuation:
783             {
784               r1 = cdr (r1);
785               goto call_with_current_continuation;
786             }
787             //default: check_apply (cell_f, car (r1));
788           }
789       }
790     case SYMBOL:
791       {
792         if (car (r1) == cell_symbol_call_with_values)
793           {
794             r1 = cdr (r1);
795             goto call_with_values;
796           }
797         if (car (r1) == cell_symbol_current_module)
798           {
799             r1 = r0;
800             goto vm_return;
801           }
802         break;
803       }
804     case PAIR:
805       {
806         switch (caar (r1))
807           {
808           case cell_symbol_lambda:
809             {
810               SCM formals = cadr (car (r1));
811               SCM body = cddr (car (r1));
812               SCM p = pairlis (formals, cdr (r1), r0);
813               //check_formals (r1, formals, cdr (r1));
814               call_lambda (body, p, p, r0);
815               goto begin;
816             }
817           }
818       }
819     }
820   push_cc (car (r1), r1, r0, cell_vm_apply2);
821   goto eval;
822  apply2:
823   //check_apply (r1, car (r2));
824   r1 = cons (r1, cdr (r2));
825   goto apply;
826
827  eval:
828   switch (TYPE (r1))
829     {
830     case PAIR:
831       {
832         switch (car (r1))
833           {
834 #if FIXED_PRIMITIVES
835           case cell_symbol_car:
836             {
837               push_cc (CADR (r1), r1, r0, cell_vm_eval_car); goto eval;
838             eval_car:
839               x = r1; gc_pop_frame (); r1 = car (x); goto eval_apply;
840             }
841           case cell_symbol_cdr:
842             {
843               push_cc (CADR (r1), r1, r0, cell_vm_eval_cdr); goto eval;
844             eval_cdr:
845               x = r1; gc_pop_frame (); r1 = cdr (x); goto eval_apply;
846             }
847           case cell_symbol_cons: {
848             push_cc (CDR (r1), r1, r0, cell_vm_eval_cons); goto evlis;
849             eval_cons:
850             x = r1;
851             gc_pop_frame ();
852             r1 = cons (CAR (x), CADR (x));
853             goto eval_apply;
854           }
855           case cell_symbol_null_p:
856             {
857               push_cc (CADR (r1), r1, r0, cell_vm_eval_null_p);
858               goto eval;
859             eval_null_p:
860               x = r1; gc_pop_frame (); r1 = null_p (x); goto eval_apply;
861             }
862 #endif // FIXED_PRIMITIVES
863           case cell_symbol_quote:
864             {
865               x = r1; gc_pop_frame (); r1 = cadr (x); goto eval_apply;
866             }
867           case cell_symbol_begin: goto begin;
868           case cell_symbol_lambda:
869             {
870               r1 = make_closure (cadr (r1), cddr (r1), assq (cell_closure, r0));
871               goto vm_return;
872             }
873           case cell_symbol_if: {r1=cdr (r1); goto vm_if;}
874           case cell_symbol_set_x:
875             {
876               push_cc (car (cddr (r1)), r1, r0, cell_vm_eval_set_x);
877               goto eval;
878             eval_set_x:
879               x = r2;
880               r1 = set_env_x (cadr (x), r1, r0);
881               goto vm_return;
882             }
883           case cell_vm_macro_expand:
884             {
885               push_cc (cadr (r1), r1, r0, cell_vm_return);
886               goto macro_expand;
887             }
888           default: {
889             push_cc (r1, r1, r0, cell_vm_eval_macro);
890             goto macro_expand;
891             eval_macro:
892             x = r2;
893             if (r1 != r2)
894               {
895                 if (TYPE (r1) == PAIR)
896                   {
897                     set_cdr_x (r2, cdr (r1));
898                     set_car_x (r2, car (r1));
899                   }
900                 goto eval;
901               }
902             push_cc (CDR (r1), r1, r0, cell_vm_eval2); goto evlis;
903             eval2:
904             r1 = cons (car (r2), r1);
905             goto apply;
906           }
907           }
908       }
909     case SYMBOL:
910       {
911         r1 = assert_defined (r1, assq_ref_env (r1, r0));
912         goto vm_return;
913       }
914     default: {goto vm_return;}
915     }
916
917   SCM macro;
918   SCM expanders;
919  macro_expand:
920 #if 0
921   if (TYPE (r1) == PAIR
922       && (macro = lookup_macro (car (r1), r0)) != cell_f) // FIXME GNUC
923     {
924       r1 = cons (macro, CDR (r1));
925       goto apply;
926     }
927   else if (TYPE (r1) == PAIR
928            && TYPE (CAR (r1)) == SYMBOL
929            && ((expanders = assq_ref_env (cell_symbol_sc_expander_alist, r0)) != cell_undefined)
930            && ((macro = assq (CAR (r1), expanders)) != cell_f))
931     {
932       SCM sc_expand = assq_ref_env (cell_symbol_macro_expand, r0);
933       if (sc_expand != cell_undefined && sc_expand != cell_f)
934         {
935           r1 = cons (sc_expand, cons (r1, cell_nil));
936           goto apply;
937         }
938     }
939   goto vm_return;
940 #endif
941  begin:
942   x = cell_unspecified;
943   while (r1 != cell_nil) {
944     if (TYPE (r1) == PAIR && TYPE (CAR (r1)) == PAIR)
945       {
946         if (caar (r1) == cell_symbol_begin)
947           r1 = append2 (cdar (r1), cdr (r1));
948         else if (caar (r1) == cell_symbol_primitive_load)
949           {
950             push_cc (cons (cell_symbol_read_input_file, cell_nil), r1, r0, cell_vm_begin_read_input_file);
951             goto apply;
952           begin_read_input_file:
953             r1 = append2 (r1, cdr (r2));
954           }
955       }
956     if (CDR (r1) == cell_nil)
957       {
958         r1 = car (r1);
959         goto eval;
960       }
961     push_cc (CAR (r1), r1, r0, cell_vm_begin2);
962     goto eval;
963   begin2:
964     x = r1;
965     r1 = CDR (r2);
966   }
967   r1 = x;
968   goto vm_return;
969
970  vm_if:
971   push_cc (car (r1), r1, r0, cell_vm_if_expr);
972   goto eval;
973  if_expr:
974   x = r1;
975   r1 = r2;
976   if (x != cell_f)
977     {
978       r1 = cadr (r1);
979       goto eval;
980     }
981   if (cddr (r1) != cell_nil)
982     {
983       r1 = car (cddr (r1));
984       goto eval;
985     }
986   r1 = cell_unspecified;
987   goto vm_return;
988
989  call_with_current_continuation:
990   gc_push_frame ();
991 #if __GNUC__
992   // FIXME GCC
993   x = MAKE_CONTINUATION (g_continuations++);
994 #else
995   x = MAKE_CONTINUATION (g_continuations);
996   g_continuations++;
997 #endif
998   gc_pop_frame ();
999   push_cc (cons (car (r1), cons (x, cell_nil)), x, r0, cell_vm_call_with_current_continuation2);
1000   goto apply;
1001  call_with_current_continuation2:
1002   CONTINUATION (r2) = g_stack;
1003   goto vm_return;
1004
1005  call_with_values:
1006   push_cc (cons (car (r1), cell_nil), r1, r0, cell_vm_call_with_values2);
1007   goto apply;
1008  call_with_values2:
1009   if (TYPE (r1) == VALUES)
1010     r1 = CDR (r1);
1011   r1 = cons (cadr (r2), r1);
1012   goto apply;
1013
1014  vm_return:
1015   x = r1;
1016   gc_pop_frame ();
1017   r1 = x;
1018   goto eval_apply;
1019 }
1020
1021 SCM
1022 call (SCM fn, SCM x)
1023 {
1024   puts ("call\n");
1025   if ((FUNCTION (fn).arity > 0 || FUNCTION (fn).arity == -1)
1026       && x != cell_nil && TYPE (CAR (x)) == VALUES)
1027     x = cons (CADAR (x), CDR (x));
1028   if ((FUNCTION (fn).arity > 1 || FUNCTION (fn).arity == -1)
1029       && x != cell_nil && TYPE (CDR (x)) == PAIR && TYPE (CADR (x)) == VALUES)
1030     x = cons (CAR (x), cons (CDADAR (x), CDR (x)));
1031   switch (FUNCTION (fn).arity)
1032     {
1033     // case 0: return FUNCTION (fn).function0 ();
1034     // case 1: return FUNCTION (fn).function1 (car (x));
1035     // case 2: return FUNCTION (fn).function2 (car (x), cadr (x));
1036     // case 3: return FUNCTION (fn).function3 (car (x), cadr (x), car (cddr (x)));
1037     // case -1: return FUNCTION (fn).functionn (x);
1038     case 0: {return (FUNCTION (fn).function) ();}
1039     case 1: {return ((SCM(*)(SCM))(FUNCTION (fn).function)) (car (x));}
1040     case 2: {return ((SCM(*)(SCM,SCM))(FUNCTION (fn).function)) (car (x), cadr (x));}
1041     case 3: {return ((SCM(*)(SCM,SCM,SCM))(FUNCTION (fn).function)) (car (x), cadr (x), car (cddr (x)));}
1042 #if __GNUC__
1043       // FIXME GNUC
1044     case -1: {return ((SCM(*)(SCM))(FUNCTION (fn).function)) (x);}
1045 #endif
1046     default: {return ((SCM(*)(SCM))(FUNCTION (fn).function)) (x);}
1047     }
1048
1049   return cell_unspecified;
1050 }
1051
1052 SCM
1053 gc_peek_frame ()
1054 {
1055   SCM frame = car (g_stack);
1056   r1 = car (frame);
1057 #if __GNUC__
1058   r2 = cadr (frame);
1059   r3 = car (cddr (frame));
1060   r0 = cadr (cddr (frame));
1061 #else
1062   r2 = cdr (frame);
1063   r2 = car (r2);
1064
1065   r3 = cdr (frame);
1066   r3 = cdr (r3);
1067   r3 = car (r3);
1068
1069   r0 = cdr (frame);
1070   r0 = cdr (r0);
1071   r0 = cdr (r0);
1072   r0 = cdr (r0);
1073   r0 = car (r0);
1074 #endif
1075   return frame;
1076 }
1077
1078 SCM
1079 gc_pop_frame ()
1080 {
1081   SCM frame = gc_peek_frame (g_stack);
1082   g_stack = cdr (g_stack);
1083   return frame;
1084 }
1085
1086 SCM
1087 mes_g_stack (SCM a) ///((internal))
1088 {
1089   r0 = a;
1090   r1 = MAKE_CHAR (0);
1091   r2 = MAKE_CHAR (0);
1092   r3 = MAKE_CHAR (0);
1093   g_stack = cons (cell_nil, cell_nil);
1094   return r0;
1095 }
1096
1097 //\f Environment setup
1098 SCM
1099 make_tmps (struct scm* cells)
1100 {
1101   tmp = g_free++;
1102   cells[tmp].type = CHAR;
1103   tmp_num = g_free++;
1104   cells[tmp_num].type = NUMBER;
1105   tmp_num2 = g_free++;
1106   cells[tmp_num2].type = NUMBER;
1107   return 0;
1108 }
1109
1110 SCM
1111 make_symbol_ (SCM s)
1112 {
1113   VALUE (tmp_num) = SYMBOL;
1114   SCM x = make_cell (tmp_num, s, 0);
1115   g_symbols = cons (x, g_symbols);
1116   return x;
1117 }
1118
1119 SCM
1120 make_symbol (SCM s)
1121 {
1122 #if MES_MINI
1123   SCM x = 0;
1124 #else
1125   SCM x = lookup_symbol_ (s);
1126 #endif
1127   return x ? x : make_symbol_ (s);
1128 }
1129
1130 SCM
1131 cstring_to_list (char const* s)
1132 {
1133   SCM p = cell_nil;
1134   int i = strlen (s);
1135   while (i--)
1136     p = cons (MAKE_CHAR (s[i]), p);
1137   return p;
1138 }
1139
1140 SCM
1141 acons (SCM key, SCM value, SCM alist)
1142 {
1143   return cons (cons (key, value), alist);
1144 }
1145
1146 //\f Jam Collector
1147 SCM g_symbol_max;
1148
1149 SCM
1150 gc_init_cells ()
1151 {
1152   return 0;
1153 //   g_cells = (scm *)malloc (2*ARENA_SIZE*sizeof(scm));
1154
1155 // #if __NYACC__ || FIXME_NYACC
1156 //   TYPE (0) = TVECTOR;
1157 // // #else
1158 // //   TYPE (0) = VECTOR;
1159 // #endif
1160 //   LENGTH (0) = 1000;
1161 //   VECTOR (0) = 0;
1162 //   g_cells++;
1163 //   TYPE (0) = CHAR;
1164 //   VALUE (0) = 'c';
1165 }
1166
1167 // INIT NEWS
1168
1169 SCM
1170 mes_symbols () ///((internal))
1171 {
1172   gc_init_cells ();
1173   //  gc_init_news ();
1174
1175 #if __GNUC__ && 0
1176   //#include "mes.symbols.i"
1177 #else
1178 g_free++;
1179 // g_cells[cell_nil] = scm_nil;
1180
1181 g_free++;
1182 // g_cells[cell_f] = scm_f;
1183
1184 g_free++;
1185 // g_cells[cell_t] = scm_t;
1186
1187 g_free++;
1188 // g_cells[cell_dot] = scm_dot;
1189
1190 g_free++;
1191 // g_cells[cell_arrow] = scm_arrow;
1192
1193 g_free++;
1194 // g_cells[cell_undefined] = scm_undefined;
1195
1196 g_free++;
1197 // g_cells[cell_unspecified] = scm_unspecified;
1198
1199 g_free++;
1200 // g_cells[cell_closure] = scm_closure;
1201
1202 g_free++;
1203 // g_cells[cell_circular] = scm_circular;
1204
1205 g_free++;
1206 // g_cells[cell_begin] = scm_begin;
1207
1208 ///
1209 g_free = 44;
1210 g_free++;
1211 // g_cells[cell_vm_apply] = scm_vm_apply;
1212
1213 g_free++;
1214 // g_cells[cell_vm_apply2] = scm_vm_apply2;
1215
1216 g_free++;
1217 // g_cells[cell_vm_eval] = scm_vm_eval;
1218
1219 ///
1220 g_free = 55;
1221 g_free++;
1222 // g_cells[cell_vm_begin] = scm_vm_begin;
1223
1224 g_free++;
1225 // g_cells[cell_vm_begin_read_input_file] = scm_vm_begin_read_input_file;
1226
1227 g_free++;
1228 // g_cells[cell_vm_begin2] = scm_vm_begin2;
1229
1230 ///
1231 g_free = 62;
1232 g_free++;
1233 // g_cells[cell_vm_return] = scm_vm_return;
1234
1235 g_free = 63;
1236 g_free++;
1237 //g_cells[cell_test] = scm_test;
1238
1239 #endif
1240
1241   g_symbol_max = g_free;
1242   make_tmps (g_cells);
1243
1244   g_symbols = 0;
1245   for (int i=1; i<g_symbol_max; i++)
1246     g_symbols = cons (i, g_symbols);
1247
1248   SCM a = cell_nil;
1249
1250 #if __GNUC__ && 0
1251   //#include "mes.symbol-names.i"
1252 #else
1253 // g_cells[cell_nil].car = cstring_to_list (scm_nil.name);
1254 // g_cells[cell_f].car = cstring_to_list (scm_f.name);
1255 // g_cells[cell_t].car = cstring_to_list (scm_t.name);
1256 // g_cells[cell_dot].car = cstring_to_list (scm_dot.name);
1257 // g_cells[cell_arrow].car = cstring_to_list (scm_arrow.name);
1258 // g_cells[cell_undefined].car = cstring_to_list (scm_undefined.name);
1259 // g_cells[cell_unspecified].car = cstring_to_list (scm_unspecified.name);
1260 // g_cells[cell_closure].car = cstring_to_list (scm_closure.name);
1261 // g_cells[cell_circular].car = cstring_to_list (scm_circular.name);
1262 // g_cells[cell_begin].car = cstring_to_list (scm_begin.name);
1263 #endif
1264
1265   // a = acons (cell_symbol_mes_version, MAKE_STRING (cstring_to_list (VERSION)), a);
1266   // a = acons (cell_symbol_mes_prefix, MAKE_STRING (cstring_to_list (PREFIX)), a);
1267
1268   a = acons (cell_symbol_dot, cell_dot, a);
1269   a = acons (cell_symbol_begin, cell_begin, a);
1270   a = acons (cell_closure, a, a);
1271
1272   // a = acons (cell_symbol_call_with_current_continuation, cell_call_with_current_continuation, a);
1273   // a = acons (cell_symbol_sc_expand, cell_f, a);
1274
1275   return a;
1276 }
1277
1278 SCM
1279 make_closure (SCM args, SCM body, SCM a)
1280 {
1281   return make_cell (tmp_num_ (TCLOSURE), cell_f, cons (cons (cell_circular, a), cons (args, body)));
1282 }
1283
1284 SCM
1285 mes_environment () ///((internal))
1286 {
1287   SCM a = 0;
1288   a = mes_symbols ();
1289   a = mes_g_stack (a);
1290   return a;
1291 }
1292
1293 SCM
1294 mes_builtins (SCM a)
1295 {
1296 #if 0
1297   //__GNUC__
1298 //#include "mes.i"
1299
1300 // #include "lib.i"
1301 // #include "math.i"
1302 // #include "posix.i"
1303 // #include "reader.i"
1304
1305 // #include "lib.environment.i"
1306 // #include "math.environment.i"
1307 // #include "mes.environment.i"
1308 // #include "posix.environment.i"
1309 // #include "reader.environment.i"
1310 #else
1311
1312 scm_make_cell.cdr = g_function;
1313 g_functions[g_function++] = fun_make_cell;
1314 cell_make_cell = g_free++;
1315  g_cells[cell_make_cell] = scm_make_cell;
1316  
1317 scm_cons.cdr = g_function;
1318 g_functions[g_function++] = fun_cons;
1319 cell_cons = g_free++;
1320 g_cells[cell_cons] = scm_cons;
1321  
1322 scm_car.cdr = g_function;
1323 g_functions[g_function++] = fun_car;
1324 cell_car = g_free++;
1325 g_cells[cell_car] = scm_car;
1326  
1327 scm_cdr.cdr = g_function;
1328 g_functions[g_function++] = fun_cdr;
1329 cell_cdr = g_free++;
1330 g_cells[cell_cdr] = scm_cdr;
1331
1332 // scm_make_cell.string = cstring_to_list (scm_make_cell.name);
1333 // g_cells[cell_make_cell].string = MAKE_STRING (scm_make_cell.string);
1334 // a = acons (make_symbol (scm_make_cell.string), cell_make_cell, a);
1335
1336 // scm_cons.string = cstring_to_list (scm_cons.name);
1337 // g_cells[cell_cons].string = MAKE_STRING (scm_cons.string);
1338 // a = acons (make_symbol (scm_cons.string), cell_cons, a);
1339
1340 // scm_car.string = cstring_to_list (scm_car.name);
1341 // g_cells[cell_car].string = MAKE_STRING (scm_car.string);
1342 // a = acons (make_symbol (scm_car.string), cell_car, a);
1343
1344 // scm_cdr.string = cstring_to_list (scm_cdr.name);
1345 // g_cells[cell_cdr].string = MAKE_STRING (scm_cdr.string);
1346 // a = acons (make_symbol (scm_cdr.string), cell_cdr, a);
1347 #endif
1348   return a;
1349 }
1350
1351 SCM
1352 bload_env (SCM a) ///((internal))
1353 {
1354   g_stdin = open ("module/mes/read-0.mo", 0);
1355 #if __GNUC__
1356   //FIXME GNUC
1357   //g_stdin = g_stdin ? g_stdin : fopen (PREFIX "module/mes/read-0.mo", "r");
1358 #endif
1359   char *p = (char*)g_cells;
1360   assert (getchar () == 'M');
1361   assert (getchar () == 'E');
1362   assert (getchar () == 'S');
1363   g_stack = getchar () << 8;
1364   g_stack += getchar ();
1365   int c = getchar ();
1366   while (c != EOF)
1367     {
1368       *p++ = c;
1369       c = getchar ();
1370     }
1371   g_free = (p-(char*)g_cells) / sizeof (struct scm);
1372   gc_peek_frame ();
1373   g_symbols = r1;
1374   g_stdin = STDIN;
1375   r0 = mes_builtins (r0);
1376   return r2;
1377 }
1378
1379 SCM
1380 fill ()
1381 {
1382   TYPE (0) = 0x6c6c6168;
1383   CAR (0) = 0x6a746f6f;
1384   CDR (0) = 0x00002165;
1385
1386   TYPE (1) = SYMBOL;
1387   CAR (1) = 0x2d2d2d2d;
1388   CDR (1) = 0x3e3e3e3e;
1389
1390   TYPE (9) = 0x2d2d2d2d;
1391   CAR (9) = 0x2d2d2d2d;
1392   CDR (9) = 0x3e3e3e3e;
1393 #if 0
1394   // (A(B))
1395   TYPE (10) = PAIR;
1396   CAR (10) = 11;
1397   CDR (10) = 12;
1398
1399   TYPE (11) = CHAR;
1400   CAR (11) = 0x58585858;
1401   CDR (11) = 89;
1402
1403   TYPE (12) = PAIR;
1404   CAR (12) = 13;
1405   CDR (12) = 1;
1406
1407   TYPE (13) = CHAR;
1408   CAR (13) = 0x58585858;
1409   CDR (13) = 90;
1410
1411   TYPE (14) = 0x58585858;
1412   CAR (14) = 0x58585858;
1413   CDR (14) = 0x58585858;
1414
1415   TYPE (14) = 0x58585858;
1416   CAR (14) = 0x58585858;
1417   CDR (14) = 0x58585858;
1418 #else
1419   // (cons 0 1)
1420   TYPE (10) = PAIR;
1421   CAR (10) = 11;
1422   CDR (10) = 12;
1423
1424   TYPE (11) = TFUNCTION;
1425   CAR (11) = 0x58585858;
1426   // 0 = make_cell
1427   // 1 = cons
1428   // 2 = car
1429   CDR (11) = 1;
1430
1431   TYPE (12) = PAIR;
1432   CAR (12) = 13;
1433   //CDR (12) = 1;
1434   CDR (12) = 14;
1435
1436   TYPE (13) = NUMBER;
1437   CAR (13) = 0x58585858;
1438   CDR (13) = 0;
1439
1440   TYPE (14) = PAIR;
1441   CAR (14) = 15;
1442   CDR (14) = 1;
1443
1444   TYPE (15) = NUMBER;
1445   CAR (15) = 0x58585858;
1446   CDR (15) = 1;
1447
1448   //g_stack@23
1449   TYPE (19) = PAIR;
1450   CAR (19) = 1;
1451   CDR (19) = 1;
1452
1453   TYPE (20) = PAIR;
1454   CAR (20) = 7;
1455   CDR (20) = 19;
1456
1457   TYPE (21) = PAIR;
1458   CAR (21) = 7;
1459   CDR (21) = 20;
1460
1461   TYPE (22) = PAIR;
1462   CAR (22) = 134;
1463   CDR (22) = 21;
1464
1465   TYPE (23) = PAIR;
1466   CAR (23) = 22;
1467   CDR (23) = 137;
1468
1469 #endif
1470
1471   return 0;
1472 }
1473
1474 SCM
1475 display_ (SCM x)
1476 {
1477   //puts ("<display>\n");
1478   switch (TYPE (x))
1479     {
1480     case CHAR:
1481       {
1482         //puts ("<char>\n");
1483         puts ("#\\");
1484         putchar (VALUE (x));
1485         break;
1486       }
1487     case TFUNCTION:
1488       {
1489         //puts ("<function>\n");
1490         if (VALUE (x) == 0)
1491           puts ("make-cell");
1492         if (VALUE (x) == 1)
1493           puts ("cons");
1494         if (VALUE (x) == 2)
1495           puts ("car");
1496         if (VALUE (x) == 3)
1497           puts ("cdr");
1498         break;
1499       }
1500     case NUMBER:
1501       {
1502         //puts ("<number>\n");
1503 #if __GNUC__
1504         putchar (48 + VALUE (x));
1505 #else
1506         int i;
1507         i = VALUE (x);
1508         i = i + 48;
1509         putchar (i);
1510 #endif
1511         break;
1512       }
1513     case PAIR:
1514       {
1515         //puts ("<pair>\n");
1516         //if (cont != cell_f) puts "(");
1517         puts ("(");
1518         if (x && x != cell_nil) display_ (CAR (x));
1519         if (CDR (x) && CDR (x) != cell_nil)
1520           {
1521 #if __GNUC__
1522             if (TYPE (CDR (x)) != PAIR)
1523               puts (" . ");
1524 #else
1525             int c;
1526             c = CDR (x);
1527             c = TYPE (c);
1528             if (c != PAIR)
1529               puts (" . ");
1530 #endif
1531             display_ (CDR (x));
1532           }
1533         //if (cont != cell_f) puts (")");
1534         puts (")");
1535         break;
1536       }
1537     default:
1538       {
1539         //puts ("<default>\n");
1540         puts ("_");
1541         break;
1542       }
1543     }
1544   return 0;
1545 }
1546
1547 #define CONS 0
1548
1549 SCM
1550 simple_bload_env (SCM a) ///((internal))
1551 {
1552   puts ("reading: ");
1553 #if CONS
1554   char *mo = "module/mes/hack-32.mo";
1555 #else
1556   char *mo = "cons-32.mo";
1557 #endif
1558
1559   puts (mo);
1560   puts ("\n");
1561   g_stdin = open (mo, 0);
1562   if (g_stdin < 0) {eputs ("no such file: module/mes/read-0-32.mo\n");return 1;} 
1563
1564   char *p = (char*)g_cells;
1565   int c;
1566
1567 #if 0
1568   //__GNUC__
1569   puts ("fd: ");
1570   puts (itoa (g_stdin));
1571   puts ("\n");
1572 #endif
1573
1574   assert (getchar () == 'M');
1575   assert (getchar () == 'E');
1576   assert (getchar () == 'S');
1577   puts (" *GOT MES*\n");
1578   g_stack = getchar () << 8;
1579   g_stack += getchar ();
1580 #if __GNUC__
1581   puts ("stack: ");
1582   puts (itoa (g_stack));
1583   puts ("\n");
1584 #endif
1585
1586 // #if !CONS
1587 //   //FIXME: skip one cell
1588 //   for  (int q=0; q < 12; q++)
1589 //     getchar ();
1590 // #endif
1591
1592   int i = 0;
1593   c = getchar ();
1594   while (c != -1)
1595     {
1596 #if __GNUC__
1597       puts ("\ni=");
1598       puts (itoa (i));
1599       puts (" ");
1600       puts (itoa (c));
1601       puts (" ");
1602 #endif
1603       putchar (c);
1604       i++;
1605       *p++ = c;
1606       c = getchar ();
1607     }
1608
1609   puts ("read done\n");
1610
1611   g_free = (p-(char*)g_cells) / sizeof (struct scm);
1612
1613 #if !CONS
1614   gc_peek_frame ();
1615 #endif
1616
1617   // URG
1618   // r0 = 628;
1619   // r1 = 67;
1620   // r2 = 389;
1621
1622 #if __GNUC__
1623   puts ("XXcells read: ");
1624   puts (itoa (g_free));
1625   puts ("\n");
1626
1627   g_symbols = r1;
1628
1629   eputs ("r0=");
1630   eputs (itoa (r0));
1631   eputs ("\n");
1632
1633   eputs ("r1=");
1634   eputs (itoa (r1));
1635   eputs ("\n");
1636
1637   eputs ("r2=");
1638   eputs (itoa (r2));
1639   eputs ("\n");
1640
1641   eputs ("g_stack=");
1642   eputs (itoa (g_stack));
1643   eputs ("\n");
1644 #endif
1645   
1646 #if CONS
1647   if (g_free != 15) exit (33);
1648   g_symbols = 1;
1649   r2 = 10;
1650 #endif
1651
1652   g_stdin = STDIN;
1653   r0 = mes_builtins (r0);
1654
1655   ///if (g_free != 19) exit (34);
1656   
1657 #if __GNUC__
1658   puts ("cells read: ");
1659   puts (itoa (g_free));
1660   puts ("\n");
1661
1662   puts ("symbols: ");
1663   puts (itoa (g_symbols));
1664   puts ("\n");
1665
1666   puts ("r2: ");
1667   puts (itoa (r2));
1668   puts ("\n");
1669 #endif
1670
1671 #if CONS
1672   display_ (r2);
1673   puts ("\n");
1674
1675   fill ();
1676   r2 = 10;
1677
1678   if (TYPE (12) != PAIR)
1679     exit (33);
1680
1681   r0 = 1;
1682 #endif
1683
1684   puts ("program[");
1685 #if __GNUC__
1686   puts (itoa (r2));
1687 #endif
1688   puts ("]: ");
1689
1690   // display_ (r2);
1691   // puts ("\n");
1692
1693   return r2;
1694 }
1695
1696 char const*
1697 string_to_cstring (SCM s)
1698 {
1699   static char buf[1024];
1700   char *p = buf;
1701   s = STRING(s);
1702   while (s != cell_nil)
1703     {
1704       *p++ = VALUE (car (s));
1705       s = cdr (s);
1706     }
1707   *p = 0;
1708   return buf;
1709 }
1710
1711 SCM
1712 stderr_ (SCM x)
1713 {
1714   //SCM write;
1715 #if __NYACC__ || FIXME_NYACC
1716   if (TYPE (x) == TSTRING)
1717 // #else
1718 //   if (TYPE (x) == STRING)
1719 #endif
1720     eputs (string_to_cstring (x));
1721   // else if ((write = assq_ref_env (cell_symbol_write, r0)) != cell_undefined)
1722   //   apply (assq_ref_env (cell_symbol_display, r0), cons (x, cons (MAKE_NUMBER (2), cell_nil)), r0);
1723 #if __NYACC__ || FIXME_NYACC
1724   else if (TYPE (x) == SPECIAL || TYPE (x) == TSTRING || TYPE (x) == SYMBOL)
1725 // #else
1726 //   else if (TYPE (x) == SPECIAL || TYPE (x) == STRING || TYPE (x) == SYMBOL)
1727 #endif
1728     eputs (string_to_cstring (x));
1729   else if (TYPE (x) == NUMBER)
1730     eputs (itoa (VALUE (x)));
1731   else
1732     eputs ("display: undefined\n");
1733   return cell_unspecified;
1734 }
1735
1736 int
1737 main (int argc, char *argv[])
1738 {
1739   puts ("Hello mini-mes!\n");
1740 #if __GNUC__
1741   //g_debug = getenv ("MES_DEBUG");
1742 #endif
1743   //if (getenv ("MES_ARENA")) ARENA_SIZE = atoi (getenv ("MES_ARENA"));
1744   if (argc > 1 && !strcmp (argv[1], "--help")) return eputs ("Usage: mes [--dump|--load] < FILE");
1745 #if __GNUC__
1746   if (argc > 1 && !strcmp (argv[1], "--version")) {eputs ("Mes ");return eputs (VERSION);};
1747 #else
1748   if (argc > 1 && !strcmp (argv[1], "--version")) {eputs ("Mes ");return eputs ("0.4");};
1749 #endif
1750   g_stdin = STDIN;
1751
1752   r0 = mes_environment ();
1753   
1754 #if MES_MINI
1755   SCM program = simple_bload_env (r0);
1756 #else  
1757   SCM program = (argc > 1 && !strcmp (argv[1], "--load"))
1758     ? bload_env (r0) : load_env (r0);
1759   if (argc > 1 && !strcmp (argv[1], "--dump")) return dump ();
1760 #endif
1761
1762   push_cc (r2, cell_unspecified, r0, cell_unspecified);
1763
1764 #if __GNUC__
1765   puts ("stack: ");
1766   display_ (g_stack);
1767   puts ("\n");
1768
1769   puts ("g_free=");
1770   puts (itoa(g_free));
1771   puts ("\n");
1772
1773   puts ("g_stack=");
1774   puts (itoa(g_stack));
1775   puts ("\n");
1776
1777   puts ("r0=");
1778   puts (itoa(r0));
1779   puts ("\n");
1780
1781   puts ("r1=");
1782   puts (itoa(r1));
1783   puts ("\n");
1784
1785   puts ("r2=");
1786   puts (itoa(r2));
1787   puts ("\n");
1788
1789   puts ("r3=");
1790   puts (itoa(r3));
1791   puts ("\n");
1792 #endif
1793
1794   r3 = cell_vm_begin;
1795   //r3 = cell_vm_apply;
1796   r1 = eval_apply ();
1797   stderr_ (r1);
1798   //display_ (r1);
1799
1800   eputs ("\n");
1801 #if !MES_MINI
1802   gc (g_stack);
1803 #endif
1804 #if __GNUC__
1805   if (g_debug)
1806     {
1807       eputs ("\nstats: [");
1808       eputs (itoa (g_free));
1809       eputs ("]\n");
1810     }
1811 #endif
1812   return 0;
1813 }
1814
1815 #if __GNUC__
1816 void
1817 _start ()
1818 {
1819   int r;
1820   asm (
1821        "mov %%ebp,%%eax\n\t"
1822        "addl $8,%%eax\n\t"
1823        "push %%eax\n\t"
1824
1825        "mov %%ebp,%%eax\n\t"
1826        "addl $4,%%eax\n\t"
1827        "movzbl (%%eax),%%eax\n\t"
1828        "push %%eax\n\t"
1829
1830        "call main\n\t"
1831        "movl %%eax,%0\n\t"
1832        : "=r" (r)
1833        : //no inputs "" (&main)
1834        );
1835   exit (r);
1836 }
1837 #endif