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