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