core+mini-mes: Move function name to struct function.
[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 1
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   char *name;
288 };
289
290 struct scm *g_cells = arena;
291
292 //scm *g_news = 0;
293
294 // struct scm scm_nil = {SPECIAL, "()"};
295 // struct scm scm_f = {SPECIAL, "#f"};
296 // struct scm scm_t = {SPECIAL, "#t"};
297 // struct scm_dot = {SPECIAL, "."};
298 // struct scm_arrow = {SPECIAL, "=>"};
299 // struct scm_undefined = {SPECIAL, "*undefined*"};
300 // struct scm_unspecified = {SPECIAL, "*unspecified*"};
301 // struct scm_closure = {SPECIAL, "*closure*"};
302 // struct scm_circular = {SPECIAL, "*circular*"};
303 // struct scm_begin = {SPECIAL, "*begin*"};
304
305 // struct scm_vm_apply = {SPECIAL, "core:apply"};
306 // struct scm_vm_apply2 = {SPECIAL, "*vm-apply2*"};
307
308 // struct scm_vm_eval = {SPECIAL, "core:eval"};
309
310 // struct scm_vm_begin = {SPECIAL, "*vm-begin*"};
311 // //scm scm_vm_begin_read_input_file = {SPECIAL, "*vm-begin-read-input-file*"};
312 // struct scm_vm_begin2 = {SPECIAL, "*vm-begin2*"};
313
314 // struct scm_vm_return = {SPECIAL, "*vm-return*"};
315
316 // //#include "mes.symbols.h"
317
318 #define cell_nil 1
319 #define cell_f 2
320 #define cell_t 3
321 #define cell_dot 4
322 // #define cell_arrow 5
323 #define cell_undefined 6
324 #define cell_unspecified 7
325 #define cell_closure 8
326 #define cell_circular 9
327 #define cell_begin 10
328 #define cell_symbol_dot 11
329 #define cell_symbol_lambda 12
330 #define cell_symbol_begin 13
331 #define cell_symbol_if 14
332 #define cell_symbol_quote 15
333 #define cell_symbol_set_x 16
334 #define cell_symbol_sc_expand 17
335 #define cell_symbol_macro_expand 18
336 #define cell_symbol_sc_expander_alist 19
337 #define cell_symbol_call_with_values 20
338 #define cell_call_with_current_continuation 21
339 #define cell_symbol_call_with_current_continuation 22
340 #define cell_symbol_current_module 23
341 #define cell_symbol_primitive_load 24
342 #define cell_symbol_read_input_file 25
343
344 #define cell_symbol_car 37
345 #define cell_symbol_cdr 38
346 #define cell_symbol_null_p 39
347 #define cell_symbol_eq_p 40
348 #define cell_symbol_cons 41
349
350 #define cell_vm_evlis 42
351 #define cell_vm_evlis2 43
352 #define cell_vm_evlis3 44
353 #define cell_vm_apply 45
354 #define cell_vm_apply2 46
355 #define cell_vm_eval 47
356 #define cell_vm_eval_car 48
357 #define cell_vm_eval_cdr 49
358 #define cell_vm_eval_cons 50
359 #define cell_vm_eval_null_p 51
360 #define cell_vm_eval_set_x 52
361 #define cell_vm_eval_macro 53
362 #define cell_vm_eval2 54
363 #define cell_vm_macro_expand 55
364 #define cell_vm_begin 56
365 #define cell_vm_begin_read_input_file 57
366 #define cell_vm_begin2 58
367 #define cell_vm_if 59
368 #define cell_vm_if_expr 60
369 #define cell_vm_call_with_values2 61
370 #define cell_vm_call_with_current_continuation2 62
371 #define cell_vm_return 63
372 #define cell_test 64
373
374
375
376 SCM tmp;
377 SCM tmp_num;
378 SCM tmp_num2;
379
380 struct function g_functions[5];
381 int g_function = 0;
382
383
384 #if __GNUC__
385 //FIXME
386 SCM make_cell (SCM type, SCM car, SCM cdr);
387 #endif
388 struct function fun_make_cell = {&make_cell,3,"make-cell"};
389 struct scm scm_make_cell = {TFUNCTION,0,0};
390 SCM cell_make_cell;
391
392 #if __GNUC__
393 //FIXME
394 SCM cons (SCM x, SCM y);
395 #endif
396 struct function fun_cons = {&cons,2,"cons"};
397 struct scm scm_cons = {TFUNCTION,0,0};
398 SCM cell_cons;
399
400 #if __GNUC__
401 //FIXME
402 SCM car (SCM x);
403 #endif
404 struct function fun_car = {&car,1,"car"};
405 struct scm scm_car = {TFUNCTION,0,0};
406 SCM cell_car;
407
408 #if __GNUC__
409 //FIXME
410 SCM cdr (SCM x);
411 #endif
412 struct function fun_cdr = {&cdr,1,"cdr"};
413 struct scm scm_cdr = {TFUNCTION,0,0};
414 SCM cell_cdr;
415
416 // SCM eq_p (SCM x, SCM y);
417 // struct function fun_eq_p = {&eq_p, 2};
418 // scm scm_eq_p = {TFUNCTION,0,0};// "eq?", 0};
419 // SCM cell_eq_p;
420
421 #define TYPE(x) (g_cells[x].type)
422
423 #define CAR(x) g_cells[x].car
424 #define LENGTH(x) g_cells[x].car
425 #define STRING(x) g_cells[x].car
426
427 #define CDR(x) g_cells[x].cdr
428 #define CLOSURE(x) g_cells[x].cdr
429 #define CONTINUATION(x) g_cells[x].cdr
430 #if __GNUC__
431 //#define FUNCTION(x) g_functions[g_cells[x].function]
432 #endif
433
434 #define FUNCTION(x) g_functions[g_cells[x].cdr]
435 #define VALUE(x) g_cells[x].cdr
436 #define VECTOR(x) g_cells[x].cdr
437
438 #define MAKE_CHAR(n) make_cell (tmp_num_ (CHAR), 0, tmp_num2_ (n))
439 #define MAKE_CONTINUATION(n) make_cell (tmp_num_ (TCONTINUATION), n, g_stack)
440 #define MAKE_NUMBER(n) make_cell (tmp_num_ (NUMBER), 0, tmp_num2_ (n))
441 //#define MAKE_REF(n) make_cell (tmp_num_ (REF), n, 0)
442
443
444 #define CAAR(x) CAR (CAR (x))
445 // #define CDAR(x) CDR (CAR (x))
446 #define CADAR(x) CAR (CDR (CAR (x)))
447 #define CADDR(x) CAR (CDR (CDR (x)))
448 // #define CDDDR(x) CDR (CDR (CDR (x)))
449 #define CDADAR(x) CAR (CDR (CAR (CDR (x))))
450 #define CADR(x) CAR (CDR (x))
451
452
453 #if __NYACC__ || FIXME_NYACC
454 #define MAKE_STRING(x) make_cell (tmp_num_ (TSTRING), x, 0)
455 // #else
456 // #define MAKE_STRING(x) make_cell (tmp_num_ (STRING), x, 0)
457 #endif
458
459 SCM
460 alloc (int n)
461 {
462   assert (g_free + n < ARENA_SIZE);
463   SCM x = g_free;
464   g_free += n;
465   return x;
466 }
467
468 #define DEBUG 0
469
470 SCM
471 make_cell (SCM type, SCM car, SCM cdr)
472 {
473   SCM x = alloc (1);
474 #if DEBUG
475   puts ("make_cell type=");
476   puts (itoa (type));
477   puts ("\n");
478   puts ("make_cell type.type=");
479   puts (itoa (TYPE (type)));
480   puts ("\n");
481 #endif
482   if  (TYPE (type) != NUMBER)
483     {
484       puts ("type != NUMBER\n");
485       if (TYPE (type) < 10) puts ("type < 10\n");
486       if (TYPE (type) < 20) puts ("type < 20\n");
487       if (TYPE (type) < 30) puts ("type < 30\n");
488       if (TYPE (type) < 40) puts ("type < 40\n");
489       if (TYPE (type) < 50) puts ("type < 50\n");
490       if (TYPE (type) < 60) puts ("type < 60\n");
491     }
492   //assert (TYPE (type) == NUMBER);
493   TYPE (x) = VALUE (type);
494   if (VALUE (type) == CHAR || VALUE (type) == NUMBER) {
495     if (car) CAR (x) = CAR (car);
496     if (cdr) CDR(x) = CDR(cdr);
497   }
498   else if (VALUE (type) == TFUNCTION) {
499     if (car) CAR (x) = car;
500     if (cdr) CDR(x) = CDR(cdr);
501   }
502   else {
503     CAR (x) = car;
504     CDR(x) = cdr;
505   }
506   return x;
507 }
508
509 SCM
510 tmp_num_ (int x)
511 {
512   VALUE (tmp_num) = x;
513   return tmp_num;
514 }
515
516 SCM
517 tmp_num2_ (int x)
518 {
519   VALUE (tmp_num2) = x;
520   return tmp_num2;
521 }
522
523 SCM
524 cons (SCM x, SCM y)
525 {
526 #if DEBUG
527   puts ("cons x=");
528   puts (itoa (x));
529   puts ("\n");
530 #endif
531   VALUE (tmp_num) = PAIR;
532   return make_cell (tmp_num, x, y);
533 }
534
535 SCM
536 car (SCM x)
537 {
538 #if DEBUG
539   puts ("car x=");
540   puts (itoa (x));
541   puts ("\n");
542 #endif
543 #if MES_MINI
544   //Nyacc
545   //assert ("!car");
546 #else
547   if (TYPE (x) != PAIR) error (cell_symbol_not_a_pair, cons (x, cell_symbol_car));
548 #endif
549   return CAR (x);
550 }
551
552 SCM
553 cdr (SCM x)
554 {
555 #if DEBUG
556   puts ("cdr x=");
557   puts (itoa (x));
558   puts ("\n");
559 #endif
560 #if MES_MINI
561   //Nyacc
562   //assert ("!cdr");
563 #else
564   if (TYPE (x) != PAIR) error (cell_symbol_not_a_pair, cons (x, cell_symbol_cdr));
565 #endif
566   return CDR(x);
567 }
568
569 SCM
570 null_p (SCM x)
571 {
572   return x == cell_nil ? cell_t : cell_f;
573 }
574
575 // SCM
576 // eq_p (SCM x, SCM y)
577 // {
578 //   return (x == y
579 //           || ((TYPE (x) == KEYWORD && TYPE (y) == KEYWORD
580 //                && STRING (x) == STRING (y)))
581 //           || (TYPE (x) == CHAR && TYPE (y) == CHAR
582 //               && VALUE (x) == VALUE (y))
583 //           || (TYPE (x) == NUMBER && TYPE (y) == NUMBER
584 //               && VALUE (x) == VALUE (y)))
585 //     ? cell_t : cell_f;
586 // }
587
588 SCM
589 assert_defined (SCM x, SCM e)
590 {
591   if (e != cell_undefined) return e;
592   // error (cell_symbol_unbound_variable, x);
593   puts ("unbound variable");
594   exit (33);
595   return e;
596 }
597
598 SCM
599 gc_push_frame ()
600 {
601   SCM frame = cons (r1, cons (r2, cons (r3, cons (r0, cell_nil))));
602   g_stack = cons (frame, g_stack);
603   return g_stack;
604 }
605
606 SCM
607 append2 (SCM x, SCM y)
608 {
609   if (x == cell_nil) return y;
610 #if __GNUC__
611   //FIXME GNUC
612   assert (TYPE (x) == PAIR);
613 #endif
614   return cons (car (x), append2 (cdr (x), y));
615 }
616
617 SCM
618 pairlis (SCM x, SCM y, SCM a)
619 {
620   if (x == cell_nil)
621     return a;
622   if (TYPE (x) != PAIR)
623     return cons (cons (x, y), a);
624   return cons (cons (car (x), car (y)),
625                pairlis (cdr (x), cdr (y), a));
626 }
627
628 SCM
629 assq (SCM x, SCM a)
630 {
631   //while (a != cell_nil && eq_p (x, CAAR (a)) == cell_f) a = CDR (a);
632   while (a != cell_nil && x == CAAR (a)) a = CDR (a);
633   return a != cell_nil ? car (a) : cell_f;
634 }
635
636 SCM
637 assq_ref_env (SCM x, SCM a)
638 {
639   x = assq (x, a);
640   if (x == cell_f) return cell_undefined;
641   return cdr (x);
642 }
643
644 SCM
645 set_car_x (SCM x, SCM e)
646 {
647   assert (TYPE (x) == PAIR);
648   CAR (x) = e;
649   return cell_unspecified;
650 }
651
652 SCM
653 set_cdr_x (SCM x, SCM e)
654 {
655   //if (TYPE (x) != PAIR) error (cell_symbol_not_a_pair, cons (x, cell_set_cdr_x));
656   CDR (x) = e;
657   return cell_unspecified;
658 }
659
660 SCM
661 set_env_x (SCM x, SCM e, SCM a)
662 {
663   SCM p = assert_defined (x, assq (x, a));
664   //if (TYPE (p) != PAIR)  error (cell_symbol_not_a_pair, cons (p, x));
665   return set_cdr_x (p, e);
666 }
667
668 SCM
669 call_lambda (SCM e, SCM x, SCM aa, SCM a) ///((internal))
670 {
671   SCM cl = cons (cons (cell_closure, x), x);
672   r1 = e;
673   r0 = cl;
674   return cell_unspecified;
675 }
676
677 SCM
678 push_cc (SCM p1, SCM p2, SCM a, SCM c) ///((internal))
679 {
680   puts ("push cc\n");
681   SCM x = r3;
682   r3 = c;
683   r2 = p2;
684   gc_push_frame ();
685   r1 = p1;
686   r0 = a;
687   r3 = x;
688   return cell_unspecified;
689 }
690
691 SCM caar (SCM x) {return car (car (x));}
692 SCM cadr (SCM x) {return car (cdr (x));}
693 SCM cdar (SCM x) {return cdr (car (x));}
694 SCM cddr (SCM x) {return cdr (cdr (x));}
695
696 #if __GNUC__
697 //FIXME
698 SCM make_closure (SCM,SCM,SCM);
699 SCM call (SCM,SCM);
700 SCM gc_pop_frame ();
701 #endif
702
703 SCM
704 cons_eval_apply ()
705 {
706   puts ("e/a: enter\n");
707  eval_apply:
708   // if (g_free + GC_SAFETY > ARENA_SIZE)
709   //   gc_pop_frame (gc (gc_push_frame ()));
710
711   switch (r3)
712     {
713     case cell_vm_apply: {goto apply;}
714     case cell_unspecified: {return r1;}
715     }
716
717   SCM x = cell_nil;
718   SCM y = cell_nil;
719
720  apply:
721   puts ("e/a: apply\n");
722   switch (TYPE (car (r1)))
723     {
724     case TFUNCTION: {
725       puts ("apply.function\n");
726       //check_formals (car (r1), MAKE_NUMBER (FUNCTION (car (r1)).arity), cdr (r1));
727       r1 = call (car (r1), cdr (r1));
728       goto vm_return;
729     }
730     }
731  vm_return:
732   x = r1;
733   gc_pop_frame ();
734   r1 = x;
735   goto eval_apply;
736 }
737
738 SCM
739 eval_apply ()
740 {
741   puts ("e/a: enter\n");
742  eval_apply:
743   puts ("e/a: eval_apply\n");
744   // if (g_free + GC_SAFETY > ARENA_SIZE)
745   //   gc_pop_frame (gc (gc_push_frame ()));
746
747   switch (r3)
748     {
749     case cell_vm_evlis: goto evlis;
750     case cell_vm_evlis2: goto evlis2;
751     case cell_vm_evlis3: goto evlis3;
752     case cell_vm_apply: goto apply;
753     case cell_vm_apply2: goto apply2;
754     case cell_vm_eval: goto eval;
755 #if FIXED_PRIMITIVES
756     case cell_vm_eval_car: goto eval_car;
757     case cell_vm_eval_cdr: goto eval_cdr;
758     case cell_vm_eval_cons: goto eval_cons;
759     case cell_vm_eval_null_p: goto eval_null_p;
760 #endif
761     case cell_vm_eval_set_x: goto eval_set_x;
762     case cell_vm_eval_macro: goto eval_macro;
763     case cell_vm_eval2: goto eval2;
764     case cell_vm_macro_expand: goto macro_expand;
765     case cell_vm_begin: goto begin;
766       ///case cell_vm_begin_read_input_file: goto begin_read_input_file;
767     case cell_vm_begin2: goto begin2;
768     case cell_vm_if: goto vm_if;
769     case cell_vm_if_expr: goto if_expr;
770     case cell_vm_call_with_current_continuation2: goto call_with_current_continuation2;
771     case cell_vm_call_with_values2: goto call_with_values2;
772     case cell_vm_return: goto vm_return;
773     case cell_unspecified: return r1;
774     default: assert (0);
775     }
776
777   SCM x = cell_nil;
778   SCM y = cell_nil;
779  evlis:
780   puts ("e/a: evlis\n");
781   if (r1 == cell_nil) goto vm_return;
782   if (TYPE (r1) != PAIR) goto eval;
783   push_cc (car (r1), r1, r0, cell_vm_evlis2);
784   goto eval;
785  evlis2:
786   push_cc (cdr (r2), r1, r0, cell_vm_evlis3);
787   goto evlis;
788  evlis3:
789   r1 = cons (r2, r1);
790   goto vm_return;
791
792  apply:
793   puts ("e/a: apply\n");
794   switch (TYPE (car (r1)))
795     {
796     case TFUNCTION: {
797       //check_formals (car (r1), MAKE_NUMBER (FUNCTION (car (r1)).arity), cdr (r1));
798       r1 = call (car (r1), cdr (r1)); /// FIXME: move into eval_apply
799       goto vm_return;
800     }
801     case TCLOSURE:
802       {
803         SCM cl = CLOSURE (car (r1));
804         SCM formals = cadr (cl);
805         SCM body = cddr (cl);
806         SCM aa = cdar (cl);
807         aa = cdr (aa);
808         //check_formals (car (r1), formals, cdr (r1));
809         SCM p = pairlis (formals, cdr (r1), aa);
810         call_lambda (body, p, aa, r0);
811         goto begin;
812       }
813       case TCONTINUATION:
814         {
815           x = r1;
816           g_stack = CONTINUATION (CAR (r1));
817           gc_pop_frame ();
818           r1 = cadr (x);
819           goto eval_apply;
820         }
821     case SPECIAL:
822       {
823         switch (car (r1))
824           {
825           case cell_vm_apply:
826             {
827               push_cc (cons (CADR (r1), CADDR (r1)), r1, r0, cell_vm_return);
828               goto apply;
829             }
830           case cell_vm_eval:
831             {
832               push_cc (CADR (r1), r1, CADDR (r1), cell_vm_return);
833               goto eval;
834             }
835           case cell_call_with_current_continuation:
836             {
837               r1 = cdr (r1);
838               goto call_with_current_continuation;
839             }
840             //default: check_apply (cell_f, car (r1));
841           }
842       }
843     case SYMBOL:
844       {
845         if (car (r1) == cell_symbol_call_with_values)
846           {
847             r1 = cdr (r1);
848             goto call_with_values;
849           }
850         if (car (r1) == cell_symbol_current_module)
851           {
852             r1 = r0;
853             goto vm_return;
854           }
855         break;
856       }
857     case PAIR:
858       {
859         switch (caar (r1))
860           {
861           case cell_symbol_lambda:
862             {
863               SCM formals = cadr (car (r1));
864               SCM body = cddr (car (r1));
865               SCM p = pairlis (formals, cdr (r1), r0);
866               //check_formals (r1, formals, cdr (r1));
867               call_lambda (body, p, p, r0);
868               goto begin;
869             }
870           }
871       }
872     }
873   push_cc (car (r1), r1, r0, cell_vm_apply2);
874   goto eval;
875  apply2:
876   //check_apply (r1, car (r2));
877   r1 = cons (r1, cdr (r2));
878   goto apply;
879
880  eval:
881   puts ("e/a: eval\n");
882   switch (TYPE (r1))
883     {
884     case PAIR:
885       {
886         switch (car (r1))
887           {
888 #if FIXED_PRIMITIVES
889           case cell_symbol_car:
890             {
891               push_cc (CADR (r1), r1, r0, cell_vm_eval_car); goto eval;
892             eval_car:
893               x = r1; gc_pop_frame (); r1 = car (x); goto eval_apply;
894             }
895           case cell_symbol_cdr:
896             {
897               push_cc (CADR (r1), r1, r0, cell_vm_eval_cdr); goto eval;
898             eval_cdr:
899               x = r1; gc_pop_frame (); r1 = cdr (x); goto eval_apply;
900             }
901           case cell_symbol_cons: {
902             push_cc (CDR (r1), r1, r0, cell_vm_eval_cons); goto evlis;
903             eval_cons:
904             x = r1;
905             gc_pop_frame ();
906             r1 = cons (CAR (x), CADR (x));
907             goto eval_apply;
908           }
909           case cell_symbol_null_p:
910             {
911               push_cc (CADR (r1), r1, r0, cell_vm_eval_null_p);
912               goto eval;
913             eval_null_p:
914               x = r1; gc_pop_frame (); r1 = null_p (x); goto eval_apply;
915             }
916 #endif // FIXED_PRIMITIVES
917           case cell_symbol_quote:
918             {
919               x = r1; gc_pop_frame (); r1 = cadr (x); goto eval_apply;
920             }
921           case cell_symbol_begin: goto begin;
922           case cell_symbol_lambda:
923             {
924               r1 = make_closure (cadr (r1), cddr (r1), assq (cell_closure, r0));
925               goto vm_return;
926             }
927           case cell_symbol_if: {r1=cdr (r1); goto vm_if;}
928           case cell_symbol_set_x:
929             {
930               push_cc (car (cddr (r1)), r1, r0, cell_vm_eval_set_x);
931               goto eval;
932             eval_set_x:
933               x = r2;
934               r1 = set_env_x (cadr (x), r1, r0);
935               goto vm_return;
936             }
937           case cell_vm_macro_expand:
938             {
939               push_cc (cadr (r1), r1, r0, cell_vm_return);
940               goto macro_expand;
941             }
942           default: {
943             push_cc (r1, r1, r0, cell_vm_eval_macro);
944             goto macro_expand;
945             eval_macro:
946             x = r2;
947             if (r1 != r2)
948               {
949                 if (TYPE (r1) == PAIR)
950                   {
951                     set_cdr_x (r2, cdr (r1));
952                     set_car_x (r2, car (r1));
953                   }
954                 goto eval;
955               }
956             push_cc (CDR (r1), r1, r0, cell_vm_eval2); goto evlis;
957             eval2:
958             r1 = cons (car (r2), r1);
959             goto apply;
960           }
961           }
962       }
963     case SYMBOL:
964       {
965         r1 = assert_defined (r1, assq_ref_env (r1, r0));
966         goto vm_return;
967       }
968     default: {goto vm_return;}
969     }
970
971   SCM macro;
972   SCM expanders;
973  macro_expand:
974 #if 0
975   if (TYPE (r1) == PAIR
976       && (macro = lookup_macro (car (r1), r0)) != cell_f) // FIXME GNUC
977     {
978       r1 = cons (macro, CDR (r1));
979       goto apply;
980     }
981   else if (TYPE (r1) == PAIR
982            && TYPE (CAR (r1)) == SYMBOL
983            && ((expanders = assq_ref_env (cell_symbol_sc_expander_alist, r0)) != cell_undefined)
984            && ((macro = assq (CAR (r1), expanders)) != cell_f))
985     {
986       SCM sc_expand = assq_ref_env (cell_symbol_macro_expand, r0);
987       if (sc_expand != cell_undefined && sc_expand != cell_f)
988         {
989           r1 = cons (sc_expand, cons (r1, cell_nil));
990           goto apply;
991         }
992     }
993   goto vm_return;
994 #endif
995  begin:
996   puts ("e/a: begin\n");
997   x = cell_unspecified;
998   while (r1 != cell_nil) {
999     if (TYPE (r1) == PAIR && TYPE (CAR (r1)) == PAIR)
1000       {
1001         if (caar (r1) == cell_symbol_begin)
1002           {
1003             puts ("begin00\n");
1004             r1 = append2 (cdar (r1), cdr (r1));
1005           }
1006         else if (caar (r1) == cell_symbol_primitive_load)
1007           {
1008             push_cc (cons (cell_symbol_read_input_file, cell_nil), r1, r0, cell_vm_begin_read_input_file);
1009             goto apply;
1010           begin_read_input_file:
1011             r1 = append2 (r1, cdr (r2));
1012           }
1013       }
1014     puts ("begin01\n");
1015     if (CDR (r1) == cell_nil)
1016       {
1017         r1 = car (r1);
1018         goto eval;
1019       }
1020     puts ("begin02\n");
1021     push_cc (CAR (r1), r1, r0, cell_vm_begin2);
1022     goto eval;
1023   begin2:
1024     x = r1;
1025     r1 = CDR (r2);
1026   }
1027   r1 = x;
1028   goto vm_return;
1029
1030  vm_if:
1031   push_cc (car (r1), r1, r0, cell_vm_if_expr);
1032   goto eval;
1033  if_expr:
1034   x = r1;
1035   r1 = r2;
1036   if (x != cell_f)
1037     {
1038       r1 = cadr (r1);
1039       goto eval;
1040     }
1041   if (cddr (r1) != cell_nil)
1042     {
1043       r1 = car (cddr (r1));
1044       goto eval;
1045     }
1046   r1 = cell_unspecified;
1047   goto vm_return;
1048
1049  call_with_current_continuation:
1050   gc_push_frame ();
1051 #if __GNUC__
1052   // FIXME GCC
1053   x = MAKE_CONTINUATION (g_continuations++);
1054 #else
1055   x = MAKE_CONTINUATION (g_continuations);
1056   g_continuations++;
1057 #endif
1058   gc_pop_frame ();
1059   push_cc (cons (car (r1), cons (x, cell_nil)), x, r0, cell_vm_call_with_current_continuation2);
1060   goto apply;
1061  call_with_current_continuation2:
1062   CONTINUATION (r2) = g_stack;
1063   goto vm_return;
1064
1065  call_with_values:
1066   push_cc (cons (car (r1), cell_nil), r1, r0, cell_vm_call_with_values2);
1067   goto apply;
1068  call_with_values2:
1069   if (TYPE (r1) == VALUES)
1070     r1 = CDR (r1);
1071   r1 = cons (cadr (r2), r1);
1072   goto apply;
1073
1074  vm_return:
1075   puts ("e/a: vm-return\n");
1076   x = r1;
1077   gc_pop_frame ();
1078   r1 = x;
1079   goto eval_apply;
1080 }
1081
1082 #if __GNUC__
1083 SCM display_ (SCM);
1084 #endif
1085
1086 SCM
1087 call (SCM fn, SCM x)
1088 {
1089   puts ("call\n");
1090   if ((FUNCTION (fn).arity > 0 || FUNCTION (fn).arity == -1)
1091       && x != cell_nil && TYPE (CAR (x)) == VALUES)
1092     x = cons (CADAR (x), CDR (x));
1093   if ((FUNCTION (fn).arity > 1 || FUNCTION (fn).arity == -1)
1094       && x != cell_nil && TYPE (CDR (x)) == PAIR && TYPE (CADR (x)) == VALUES)
1095     x = cons (CAR (x), cons (CDADAR (x), CDR (x)));
1096
1097   puts ("fn=");
1098   display_ (fn);
1099 #if __GNUC__
1100   puts (itoa (fn));
1101   puts (" .type=");
1102   puts (itoa (TYPE (fn)));
1103   puts (" .cdr=");
1104   puts (itoa (CDR (fn)));
1105 #endif
1106   puts ("\n");
1107
1108   puts ("arity=");
1109 #if __GNUC__
1110   puts (itoa (FUNCTION (fn).arity));
1111 #endif
1112   puts ("\n");
1113   switch (FUNCTION (fn).arity)
1114     {
1115     // case 0: return FUNCTION (fn).function0 ();
1116     // case 1: return FUNCTION (fn).function1 (car (x));
1117     // case 2: return FUNCTION (fn).function2 (car (x), cadr (x));
1118     // case 3: return FUNCTION (fn).function3 (car (x), cadr (x), car (cddr (x)));
1119     // case -1: return FUNCTION (fn).functionn (x);
1120     case 0: {return (FUNCTION (fn).function) ();}
1121     case 1: {return ((SCM(*)(SCM))(FUNCTION (fn).function)) (car (x));}
1122     case 2: {return ((SCM(*)(SCM,SCM))(FUNCTION (fn).function)) (car (x), cadr (x));}
1123     case 3: {return ((SCM(*)(SCM,SCM,SCM))(FUNCTION (fn).function)) (car (x), cadr (x), car (cddr (x)));}
1124 #if __GNUC__
1125       // FIXME GNUC
1126     case -1: {return ((SCM(*)(SCM))(FUNCTION (fn).function)) (x);}
1127 #endif
1128     default: {return ((SCM(*)(SCM))(FUNCTION (fn).function)) (x);}
1129     }
1130
1131   return cell_unspecified;
1132 }
1133
1134 SCM
1135 gc_peek_frame ()
1136 {
1137   SCM frame = car (g_stack);
1138   r1 = car (frame);
1139 #if 1
1140   //GNUC
1141   r2 = cadr (frame);
1142   r3 = car (cddr (frame));
1143   r0 = cadr (cddr (frame));
1144 #else
1145   r2 = cdr (frame);
1146   r2 = car (r2);
1147
1148   r3 = cdr (frame);
1149   r3 = cdr (r3);
1150   r3 = car (r3);
1151
1152   r0 = cdr (frame);
1153   r0 = cdr (r0);
1154   r0 = cdr (r0);
1155   r0 = cdr (r0);
1156   r0 = car (r0);
1157 #endif
1158   return frame;
1159 }
1160
1161 SCM
1162 gc_pop_frame ()
1163 {
1164   SCM frame = gc_peek_frame (g_stack);
1165   g_stack = cdr (g_stack);
1166   return frame;
1167 }
1168
1169 SCM
1170 mes_g_stack (SCM a) ///((internal))
1171 {
1172   r0 = a;
1173   r1 = MAKE_CHAR (0);
1174   r2 = MAKE_CHAR (0);
1175   r3 = MAKE_CHAR (0);
1176   g_stack = cons (cell_nil, cell_nil);
1177   return r0;
1178 }
1179
1180 //\f Environment setup
1181 SCM
1182 make_tmps (struct scm* cells)
1183 {
1184   tmp = g_free++;
1185   cells[tmp].type = CHAR;
1186   tmp_num = g_free++;
1187   cells[tmp_num].type = NUMBER;
1188   tmp_num2 = g_free++;
1189   cells[tmp_num2].type = NUMBER;
1190   return 0;
1191 }
1192
1193 SCM
1194 make_symbol_ (SCM s)
1195 {
1196   VALUE (tmp_num) = SYMBOL;
1197   SCM x = make_cell (tmp_num, s, 0);
1198   g_symbols = cons (x, g_symbols);
1199   return x;
1200 }
1201
1202 SCM
1203 make_symbol (SCM s)
1204 {
1205 #if MES_MINI
1206   SCM x = 0;
1207 #else
1208   SCM x = lookup_symbol_ (s);
1209 #endif
1210   return x ? x : make_symbol_ (s);
1211 }
1212
1213 SCM
1214 cstring_to_list (char const* s)
1215 {
1216   char *x = s;
1217   SCM p = cell_nil;
1218   int i = strlen (s);
1219   while (i--)
1220     {
1221 #if 0
1222       //FIXME
1223       p = cons (MAKE_CHAR (s[i]), p);
1224 #else
1225       p = cons (MAKE_CHAR (*x), p);
1226       x++;
1227 #endif
1228     }
1229   return p;
1230 }
1231
1232 SCM
1233 acons (SCM key, SCM value, SCM alist)
1234 {
1235   return cons (cons (key, value), alist);
1236 }
1237
1238 //\f Jam Collector
1239 SCM g_symbol_max;
1240
1241 SCM
1242 gc_init_cells ()
1243 {
1244   return 0;
1245 //   g_cells = (scm *)malloc (2*ARENA_SIZE*sizeof(scm));
1246
1247 // #if __NYACC__ || FIXME_NYACC
1248 //   TYPE (0) = TVECTOR;
1249 // // #else
1250 // //   TYPE (0) = VECTOR;
1251 // #endif
1252 //   LENGTH (0) = 1000;
1253 //   VECTOR (0) = 0;
1254 //   g_cells++;
1255 //   TYPE (0) = CHAR;
1256 //   VALUE (0) = 'c';
1257 }
1258
1259 // INIT NEWS
1260
1261 SCM
1262 mes_symbols () ///((internal))
1263 {
1264   gc_init_cells ();
1265   //  gc_init_news ();
1266
1267 #if __GNUC__ && 0
1268   //#include "mes.symbols.i"
1269 #else
1270 g_free++;
1271 // g_cells[cell_nil] = scm_nil;
1272
1273 g_free++;
1274 // g_cells[cell_f] = scm_f;
1275
1276 g_free++;
1277 // g_cells[cell_t] = scm_t;
1278
1279 g_free++;
1280 // g_cells[cell_dot] = scm_dot;
1281
1282 g_free++;
1283 // g_cells[cell_arrow] = scm_arrow;
1284
1285 g_free++;
1286 // g_cells[cell_undefined] = scm_undefined;
1287
1288 g_free++;
1289 // g_cells[cell_unspecified] = scm_unspecified;
1290
1291 g_free++;
1292 // g_cells[cell_closure] = scm_closure;
1293
1294 g_free++;
1295 // g_cells[cell_circular] = scm_circular;
1296
1297 g_free++;
1298 // g_cells[cell_begin] = scm_begin;
1299
1300 ///
1301 g_free = 44;
1302 g_free++;
1303 // g_cells[cell_vm_apply] = scm_vm_apply;
1304
1305 g_free++;
1306 // g_cells[cell_vm_apply2] = scm_vm_apply2;
1307
1308 g_free++;
1309 // g_cells[cell_vm_eval] = scm_vm_eval;
1310
1311 ///
1312 g_free = 55;
1313 g_free++;
1314 // g_cells[cell_vm_begin] = scm_vm_begin;
1315
1316 g_free++;
1317 // g_cells[cell_vm_begin_read_input_file] = scm_vm_begin_read_input_file;
1318
1319 g_free++;
1320 // g_cells[cell_vm_begin2] = scm_vm_begin2;
1321
1322 ///
1323 g_free = 62;
1324 g_free++;
1325 // g_cells[cell_vm_return] = scm_vm_return;
1326
1327 g_free = 63;
1328 g_free++;
1329 //g_cells[cell_test] = scm_test;
1330
1331 #endif
1332
1333   g_symbol_max = g_free;
1334   make_tmps (g_cells);
1335
1336   g_symbols = 0;
1337   for (int i=1; i<g_symbol_max; i++)
1338     g_symbols = cons (i, g_symbols);
1339
1340   SCM a = cell_nil;
1341
1342 #if __GNUC__ && 0
1343   //#include "mes.symbol-names.i"
1344 #else
1345 // g_cells[cell_nil].car = cstring_to_list (scm_nil.name);
1346 // g_cells[cell_f].car = cstring_to_list (scm_f.name);
1347 // g_cells[cell_t].car = cstring_to_list (scm_t.name);
1348 // g_cells[cell_dot].car = cstring_to_list (scm_dot.name);
1349 // g_cells[cell_arrow].car = cstring_to_list (scm_arrow.name);
1350 // g_cells[cell_undefined].car = cstring_to_list (scm_undefined.name);
1351 // g_cells[cell_unspecified].car = cstring_to_list (scm_unspecified.name);
1352 // g_cells[cell_closure].car = cstring_to_list (scm_closure.name);
1353 // g_cells[cell_circular].car = cstring_to_list (scm_circular.name);
1354 // g_cells[cell_begin].car = cstring_to_list (scm_begin.name);
1355 #endif
1356
1357   // a = acons (cell_symbol_mes_version, MAKE_STRING (cstring_to_list (VERSION)), a);
1358   // a = acons (cell_symbol_mes_prefix, MAKE_STRING (cstring_to_list (PREFIX)), a);
1359
1360   a = acons (cell_symbol_dot, cell_dot, a);
1361   a = acons (cell_symbol_begin, cell_begin, a);
1362   a = acons (cell_closure, a, a);
1363
1364   // a = acons (cell_symbol_call_with_current_continuation, cell_call_with_current_continuation, a);
1365   // a = acons (cell_symbol_sc_expand, cell_f, a);
1366
1367   return a;
1368 }
1369
1370 SCM
1371 make_closure (SCM args, SCM body, SCM a)
1372 {
1373   return make_cell (tmp_num_ (TCLOSURE), cell_f, cons (cons (cell_circular, a), cons (args, body)));
1374 }
1375
1376 SCM
1377 mes_environment () ///((internal))
1378 {
1379   SCM a = 0;
1380   a = mes_symbols ();
1381   a = mes_g_stack (a);
1382   return a;
1383 }
1384
1385 SCM
1386 mes_builtins (SCM a)
1387 {
1388 #if 0
1389   //__GNUC__
1390 //#include "mes.i"
1391
1392 // #include "lib.i"
1393 // #include "math.i"
1394 // #include "posix.i"
1395 // #include "reader.i"
1396
1397 // #include "lib.environment.i"
1398 // #include "math.environment.i"
1399 // #include "mes.environment.i"
1400 // #include "posix.environment.i"
1401 // #include "reader.environment.i"
1402 #else
1403
1404 scm_make_cell.cdr = g_function;
1405 g_functions[g_function++] = fun_make_cell;
1406 cell_make_cell = g_free++;
1407  g_cells[cell_make_cell] = scm_make_cell;
1408  
1409 scm_cons.cdr = g_function;
1410 g_functions[g_function++] = fun_cons;
1411 #if __GNUC__
1412  puts ("BUILTIN cons=");
1413  puts (itoa (g_free));
1414  puts ("\n");
1415 #endif
1416 cell_cons = g_free++;
1417 g_cells[cell_cons] = scm_cons;
1418  
1419 scm_car.cdr = g_function;
1420 g_functions[g_function++] = fun_car;
1421 cell_car = g_free++;
1422 g_cells[cell_car] = scm_car;
1423  
1424 scm_cdr.cdr = g_function;
1425 g_functions[g_function++] = fun_cdr;
1426 cell_cdr = g_free++;
1427 g_cells[cell_cdr] = scm_cdr;
1428
1429  #if 1
1430 //scm_make_cell.string = cstring_to_list (scm_make_cell.name);
1431 //g_cells[cell_make_cell].string = MAKE_STRING (scm_make_cell.string);
1432 //a = acons (make_symbol (scm_make_cell.string), cell_make_cell, a);
1433  puts ("00\n");
1434 scm_make_cell.car = cstring_to_list (fun_make_cell.name);
1435  puts ("01\n");
1436 g_cells[cell_make_cell].car = MAKE_STRING (scm_make_cell.car);
1437  puts ("02\n");
1438  a = acons (make_symbol (scm_make_cell.car), cell_make_cell, a);
1439  puts ("03\n");
1440
1441  //scm_cons.string = cstring_to_list (scm_cons.name);
1442 //g_cells[cell_cons].string = MAKE_STRING (scm_cons.string);
1443 //a = acons (make_symbol (scm_cons.string), cell_cons, a);
1444 scm_cons.car = cstring_to_list (fun_cons.name);
1445 g_cells[cell_cons].car = MAKE_STRING (scm_cons.car);
1446 a = acons (make_symbol (scm_cons.car), cell_cons, a);
1447
1448 //scm_car.string = cstring_to_list (scm_car.name);
1449 //g_cells[cell_car].string = MAKE_STRING (scm_car.string);
1450 //a = acons (make_symbol (scm_cons.string), cell_cons, a);
1451 scm_car.car = cstring_to_list (fun_car.name);
1452 g_cells[cell_car].car = MAKE_STRING (scm_car.car);
1453 a = acons (make_symbol (scm_cons.car), cell_cons, a);
1454
1455 //scm_cdr.string = cstring_to_list (scm_cdr.name);
1456 //g_cells[cell_cdr].string = MAKE_STRING (scm_cdr.string);
1457 //a = acons (make_symbol (scm_cdr.string), cell_cdr, a);
1458 scm_cdr.car = cstring_to_list (fun_cdr.name);
1459 g_cells[cell_cdr].car = MAKE_STRING (scm_cdr.car);
1460 a = acons (make_symbol (scm_cdr.car), cell_cdr, a);
1461
1462  #endif
1463  
1464 #endif
1465   return a;
1466 }
1467
1468 SCM
1469 bload_env (SCM a) ///((internal))
1470 {
1471   g_stdin = open ("module/mes/read-0.mo", 0);
1472 #if __GNUC__
1473   //FIXME GNUC
1474   //g_stdin = g_stdin ? g_stdin : fopen (PREFIX "module/mes/read-0.mo", "r");
1475 #endif
1476   char *p = (char*)g_cells;
1477   assert (getchar () == 'M');
1478   assert (getchar () == 'E');
1479   assert (getchar () == 'S');
1480   g_stack = getchar () << 8;
1481   g_stack += getchar ();
1482   int c = getchar ();
1483   while (c != EOF)
1484     {
1485       *p++ = c;
1486       c = getchar ();
1487     }
1488   g_free = (p-(char*)g_cells) / sizeof (struct scm);
1489   gc_peek_frame ();
1490   g_symbols = r1;
1491   g_stdin = STDIN;
1492   r0 = mes_builtins (r0);
1493   return r2;
1494 }
1495
1496 SCM
1497 fill ()
1498 {
1499   TYPE (0) = 0x6c6c6168;
1500   CAR (0) = 0x6a746f6f;
1501   CDR (0) = 0x00002165;
1502
1503   TYPE (1) = SYMBOL;
1504   CAR (1) = 0x2d2d2d2d;
1505   CDR (1) = 0x3e3e3e3e;
1506
1507   TYPE (9) = 0x2d2d2d2d;
1508   CAR (9) = 0x2d2d2d2d;
1509   CDR (9) = 0x3e3e3e3e;
1510 #if 0
1511   // (A(B))
1512   TYPE (10) = PAIR;
1513   CAR (10) = 11;
1514   CDR (10) = 12;
1515
1516   TYPE (11) = CHAR;
1517   CAR (11) = 0x58585858;
1518   CDR (11) = 89;
1519
1520   TYPE (12) = PAIR;
1521   CAR (12) = 13;
1522   CDR (12) = 1;
1523
1524   TYPE (13) = CHAR;
1525   CAR (13) = 0x58585858;
1526   CDR (13) = 90;
1527
1528   TYPE (14) = 0x58585858;
1529   CAR (14) = 0x58585858;
1530   CDR (14) = 0x58585858;
1531
1532   TYPE (14) = 0x58585858;
1533   CAR (14) = 0x58585858;
1534   CDR (14) = 0x58585858;
1535 #else
1536   // (cons 0 1)
1537   TYPE (10) = PAIR;
1538   CAR (10) = 11;
1539   CDR (10) = 12;
1540
1541   TYPE (11) = TFUNCTION;
1542   CAR (11) = 0x58585858;
1543   // 0 = make_cell
1544   // 1 = cons
1545   // 2 = car
1546   CDR (11) = 1;
1547
1548   TYPE (12) = PAIR;
1549   CAR (12) = 13;
1550   //CDR (12) = 1;
1551   CDR (12) = 14;
1552
1553   TYPE (13) = NUMBER;
1554   CAR (13) = 0x58585858;
1555   CDR (13) = 0;
1556
1557   TYPE (14) = PAIR;
1558   CAR (14) = 15;
1559   CDR (14) = 1;
1560
1561   TYPE (15) = NUMBER;
1562   CAR (15) = 0x58585858;
1563   CDR (15) = 1;
1564
1565   //g_stack@23
1566   TYPE (19) = PAIR;
1567   CAR (19) = 1;
1568   CDR (19) = 1;
1569
1570   TYPE (20) = PAIR;
1571   CAR (20) = 7;
1572   CDR (20) = 19;
1573
1574   TYPE (21) = PAIR;
1575   CAR (21) = 7;
1576   CDR (21) = 20;
1577
1578   TYPE (22) = PAIR;
1579   CAR (22) = 134;
1580   CDR (22) = 21;
1581
1582   TYPE (23) = PAIR;
1583   CAR (23) = 22;
1584   CDR (23) = 137;
1585
1586 #endif
1587
1588   return 0;
1589 }
1590
1591 SCM
1592 display_ (SCM x)
1593 {
1594   //puts ("<display>\n");
1595   switch (TYPE (x))
1596     {
1597     case CHAR:
1598       {
1599         //puts ("<char>\n");
1600         puts ("#\\");
1601         putchar (VALUE (x));
1602         break;
1603       }
1604     case TFUNCTION:
1605       {
1606         //puts ("<function>\n");
1607         if (VALUE (x) == 0)
1608           puts ("make-cell");
1609         if (VALUE (x) == 1)
1610           puts ("cons");
1611         if (VALUE (x) == 2)
1612           puts ("car");
1613         if (VALUE (x) == 3)
1614           puts ("cdr");
1615         break;
1616       }
1617     case NUMBER:
1618       {
1619         //puts ("<number>\n");
1620 #if __GNUC__
1621         puts (itoa (VALUE (x)));
1622 #else
1623         int i;
1624         i = VALUE (x);
1625         i = i + 48;
1626         putchar (i);
1627 #endif
1628         break;
1629       }
1630     case PAIR:
1631       {
1632         //puts ("<pair>\n");
1633         //if (cont != cell_f) puts "(");
1634         puts ("(");
1635         if (x && x != cell_nil) display_ (CAR (x));
1636         if (CDR (x) && CDR (x) != cell_nil)
1637           {
1638 #if __GNUC__
1639             if (TYPE (CDR (x)) != PAIR)
1640               puts (" . ");
1641 #else
1642             int c;
1643             c = CDR (x);
1644             c = TYPE (c);
1645             if (c != PAIR)
1646               puts (" . ");
1647 #endif
1648             display_ (CDR (x));
1649           }
1650         //if (cont != cell_f) puts (")");
1651         puts (")");
1652         break;
1653       }
1654     case SPECIAL:
1655       {
1656         switch (x)
1657           {
1658           case 1: {puts ("()"); break;}
1659           case 2: {puts ("#f"); break;}
1660           case 3: {puts ("#t"); break;}
1661           default:
1662             {
1663 #if __GNUC__
1664         puts ("<x:");
1665         puts (itoa (x));
1666         puts (">");
1667 #else
1668         puts ("<x>");
1669 #endif
1670             }
1671           }
1672         break;
1673       }
1674     case SYMBOL:
1675       {
1676         switch (x)
1677           {
1678           case 11: {puts (" . "); break;}
1679           case 12: {puts ("lambda"); break;}
1680           case 13: {puts ("begin"); break;}
1681           case 14: {puts ("if"); break;}
1682           case 15: {puts ("quote"); break;}
1683           case 37: {puts ("car"); break;}
1684           case 38: {puts ("cdr"); break;}
1685           case 39: {puts ("null?"); break;}
1686           case 40: {puts ("eq?"); break;}
1687           case 41: {puts ("cons"); break;}
1688           default:
1689             {
1690 #if __GNUC__
1691         puts ("<s:");
1692         puts (itoa (x));
1693         puts (">");
1694 #else
1695         puts ("<s>");
1696 #endif
1697             }
1698           }
1699         break;
1700       }
1701     default:
1702       {
1703         //puts ("<default>\n");
1704 #if __GNUC__
1705         puts ("<");
1706         puts (itoa (TYPE (x)));
1707         puts (":");
1708         puts (itoa (x));
1709         puts (">");
1710 #else
1711         puts ("_");
1712 #endif
1713         break;
1714       }
1715     }
1716   return 0;
1717 }
1718
1719 #define CONS 0
1720
1721 SCM
1722 simple_bload_env (SCM a) ///((internal))
1723 {
1724   puts ("reading: ");
1725 #if CONS
1726   char *mo = "module/mes/hack-32.mo";
1727 #else
1728   char *mo = "mini-0-32.mo";
1729 #endif
1730
1731   puts (mo);
1732   puts ("\n");
1733   g_stdin = open (mo, 0);
1734   if (g_stdin < 0) {eputs ("no such file: module/mes/read-0-32.mo\n");return 1;} 
1735
1736   char *p = (char*)g_cells;
1737   int c;
1738
1739 #if 0
1740   //__GNUC__
1741   puts ("fd: ");
1742   puts (itoa (g_stdin));
1743   puts ("\n");
1744 #endif
1745
1746   assert (getchar () == 'M');
1747   assert (getchar () == 'E');
1748   assert (getchar () == 'S');
1749   puts (" *GOT MES*\n");
1750   g_stack = getchar () << 8;
1751   g_stack += getchar ();
1752 #if __GNUC__
1753   puts ("stack: ");
1754   puts (itoa (g_stack));
1755   puts ("\n");
1756 #endif
1757
1758   c = getchar ();
1759   while (c != -1)
1760     {
1761       putchar (c);
1762       *p++ = c;
1763       c = getchar ();
1764     }
1765
1766   puts ("read done\n");
1767
1768   g_free = (p-(char*)g_cells) / sizeof (struct scm);
1769   gc_peek_frame ();
1770   g_symbols = r1;
1771
1772 #if __GNUC__
1773   puts ("XXcells read: ");
1774   puts (itoa (g_free));
1775   puts ("\n");
1776
1777   eputs ("r0=");
1778   eputs (itoa (r0));
1779   eputs ("\n");
1780
1781   eputs ("r1=");
1782   eputs (itoa (r1));
1783   eputs ("\n");
1784
1785   eputs ("r2=");
1786   eputs (itoa (r2));
1787   eputs ("\n");
1788
1789   eputs ("g_stack=");
1790   eputs (itoa (g_stack));
1791   eputs ("\n");
1792 #endif
1793   
1794 #if CONS
1795   if (g_free != 15) exit (33);
1796   g_symbols = 1;
1797   r2 = 10;
1798 #endif
1799
1800   g_stdin = STDIN;
1801   r0 = mes_builtins (r0);
1802
1803   ///if (g_free != 19) exit (34);
1804   
1805 #if __GNUC__
1806   puts ("cells read: ");
1807   puts (itoa (g_free));
1808   puts ("\n");
1809
1810   puts ("symbols: ");
1811   puts (itoa (g_symbols));
1812   puts ("\n");
1813
1814   puts ("r2: ");
1815   puts (itoa (r2));
1816   puts ("\n");
1817 #endif
1818
1819 #if CONS
1820   display_ (r2);
1821   puts ("\n");
1822
1823   fill ();
1824   r2 = 10;
1825
1826   if (TYPE (12) != PAIR)
1827     exit (33);
1828
1829   r0 = 1;
1830 #endif
1831
1832   puts ("program[");
1833 #if __GNUC__
1834   puts (itoa (r2));
1835 #endif
1836   puts ("]: ");
1837
1838   display_ (r2);
1839   //stderr_ (r2);
1840   puts ("\n");
1841
1842   return r2;
1843 }
1844
1845 char const*
1846 string_to_cstring (SCM s)
1847 {
1848   static char buf[1024];
1849   char *p = buf;
1850   s = STRING(s);
1851   while (s != cell_nil)
1852     {
1853       *p++ = VALUE (car (s));
1854       s = cdr (s);
1855     }
1856   *p = 0;
1857   return buf;
1858 }
1859
1860 SCM
1861 stderr_ (SCM x)
1862 {
1863   //SCM write;
1864 #if __NYACC__ || FIXME_NYACC
1865   if (TYPE (x) == TSTRING)
1866 // #else
1867 //   if (TYPE (x) == STRING)
1868 #endif
1869     eputs (string_to_cstring (x));
1870   // else if ((write = assq_ref_env (cell_symbol_write, r0)) != cell_undefined)
1871   //   apply (assq_ref_env (cell_symbol_display, r0), cons (x, cons (MAKE_NUMBER (2), cell_nil)), r0);
1872 #if __NYACC__ || FIXME_NYACC
1873   else if (TYPE (x) == SPECIAL || TYPE (x) == TSTRING || TYPE (x) == SYMBOL)
1874 // #else
1875 //   else if (TYPE (x) == SPECIAL || TYPE (x) == STRING || TYPE (x) == SYMBOL)
1876 #endif
1877     eputs (string_to_cstring (x));
1878   else if (TYPE (x) == NUMBER)
1879     eputs (itoa (VALUE (x)));
1880   else
1881     eputs ("display: undefined\n");
1882   return cell_unspecified;
1883 }
1884
1885 int
1886 main (int argc, char *argv[])
1887 {
1888   puts ("Hello mini-mes!\n");
1889 #if __GNUC__
1890   //g_debug = getenv ("MES_DEBUG");
1891 #endif
1892   //if (getenv ("MES_ARENA")) ARENA_SIZE = atoi (getenv ("MES_ARENA"));
1893   if (argc > 1 && !strcmp (argv[1], "--help")) return eputs ("Usage: mes [--dump|--load] < FILE");
1894 #if __GNUC__
1895   if (argc > 1 && !strcmp (argv[1], "--version")) {eputs ("Mes ");return eputs (VERSION);};
1896 #else
1897   if (argc > 1 && !strcmp (argv[1], "--version")) {eputs ("Mes ");return eputs ("0.4");};
1898 #endif
1899   g_stdin = STDIN;
1900
1901   r0 = mes_environment ();
1902   
1903 #if MES_MINI
1904   SCM program = simple_bload_env (r0);
1905 #else  
1906   SCM program = (argc > 1 && !strcmp (argv[1], "--load"))
1907     ? bload_env (r0) : load_env (r0);
1908   if (argc > 1 && !strcmp (argv[1], "--dump")) return dump ();
1909 #endif
1910
1911   //if  (r2 != 10) r2 = CAR (r2);
1912   push_cc (r2, cell_unspecified, r0, cell_unspecified);
1913
1914 #if __GNUC__
1915   // puts ("stack: ");
1916   // display_ (g_stack);
1917   // puts ("\n");
1918
1919   puts ("g_free=");
1920   puts (itoa(g_free));
1921   puts ("\n");
1922
1923   puts ("g_stack=");
1924   puts (itoa(g_stack));
1925   puts ("\n");
1926
1927   puts ("r0=");
1928   puts (itoa(r0));
1929   puts ("\n");
1930
1931   puts ("r1=");
1932   puts (itoa(r1));
1933   puts ("\n");
1934
1935   puts ("r2=");
1936   puts (itoa(r2));
1937   puts ("\n");
1938
1939   puts ("r3=");
1940   puts (itoa(r3));
1941   puts ("\n");
1942 #endif
1943
1944 #if 0
1945   // SKIP DINGES!
1946   if  (r1 != 10) r1 = CAR (r1);
1947   puts ("r1=");
1948   display_ (r1);
1949   puts ("\n");
1950   r3 = cell_vm_apply;
1951   //r1 = cons_eval_apply ();
1952   r1 = eval_apply ();
1953 #else
1954   r3 = cell_vm_begin;
1955   r1 = eval_apply ();
1956 #endif
1957
1958 #if __GNUC__
1959   puts ("result r1=");
1960   puts (itoa (r1));
1961   puts ("\n");
1962
1963   puts ("result r1.type=");
1964   puts (itoa (TYPE (r1)));
1965   puts ("\n");
1966 #endif
1967
1968   //stderr_ (r1);
1969   display_ (r1);
1970
1971   eputs ("\n");
1972 #if !MES_MINI
1973   gc (g_stack);
1974 #endif
1975 #if __GNUC__
1976   if (g_debug)
1977     {
1978       eputs ("\nstats: [");
1979       eputs (itoa (g_free));
1980       eputs ("]\n");
1981     }
1982 #endif
1983   return 0;
1984 }
1985
1986 #if __GNUC__
1987 void
1988 _start ()
1989 {
1990   int r;
1991   asm (
1992        "mov %%ebp,%%eax\n\t"
1993        "addl $8,%%eax\n\t"
1994        "push %%eax\n\t"
1995
1996        "mov %%ebp,%%eax\n\t"
1997        "addl $4,%%eax\n\t"
1998        "movzbl (%%eax),%%eax\n\t"
1999        "push %%eax\n\t"
2000
2001        "call main\n\t"
2002        "movl %%eax,%0\n\t"
2003        : "=r" (r)
2004        : //no inputs "" (&main)
2005        );
2006   exit (r);
2007 }
2008 #endif