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