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