77c892945a879856258f5a0c7a0decae1b7cf93f
[mes.git] / scaffold / cons-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 SCM
596 push_cc (SCM p1, SCM p2, SCM a, SCM c) ///((internal))
597 {
598   puts ("push cc\n");
599   SCM x = r3;
600   r3 = c;
601   r2 = p2;
602   gc_push_frame ();
603   r1 = p1;
604   r0 = a;
605   r3 = x;
606   return cell_unspecified;
607 }
608
609 #if __GNUC__
610 SCM caar (SCM x) {return car (car (x));}
611 SCM cadr (SCM x) {return car (cdr (x));}
612 SCM cdar (SCM x) {return cdr (car (x));}
613 SCM cddr (SCM x) {return cdr (cdr (x));}
614 #else
615 // Weirdness: wrong function labeling
616 // SCM cadr (SCM x) {
617 //   x = cdr (x);
618 //   return car (x);
619 // }
620 // SCM cddr (SCM x) {
621 //   x = cdr (x);
622 //   return cdr (x);
623 // }
624 #endif
625
626 #if __GNUC__
627 //FIXME
628 SCM call (SCM,SCM);
629 SCM gc_pop_frame ();
630 #endif
631
632 SCM
633 eval_apply ()
634 {
635  eval_apply:
636   // if (g_free + GC_SAFETY > ARENA_SIZE)
637   //   gc_pop_frame (gc (gc_push_frame ()));
638
639   switch (r3)
640     {
641     case cell_vm_apply: {goto apply;}
642     case cell_unspecified: {return r1;}
643     }
644
645   SCM x = cell_nil;
646   SCM y = cell_nil;
647
648  apply:
649   switch (TYPE (car (r1)))
650     {
651     case TFUNCTION: {
652       puts ("apply.function\n");
653       //check_formals (car (r1), MAKE_NUMBER (FUNCTION (car (r1)).arity), cdr (r1));
654       r1 = call (car (r1), cdr (r1));
655       goto vm_return;
656     }
657     }
658  vm_return:
659   x = r1;
660   gc_pop_frame ();
661   r1 = x;
662   goto eval_apply;
663 }
664
665 SCM
666 call (SCM fn, SCM x)
667 {
668   puts ("call\n");
669 #if __GNUC__
670   //fn=11
671   //function1
672   puts ("fn=");
673   puts (itoa(fn)); 
674   puts ("\n");
675   puts ("functiono");
676   puts (itoa(g_cells[fn].cdr));
677   puts ("\n");
678 #endif
679   if (fn != 11) {
680     puts("FN != 11\n");
681     return 11;
682   }
683   if (g_cells[11].cdr != 1) {
684     puts("fn.cdr != 11\n");
685     return 11;
686   }
687   
688   if ((FUNCTION (fn).arity > 0 || FUNCTION (fn).arity == -1)
689       && x != cell_nil && TYPE (CAR (x)) == VALUES)
690     x = cons (CADAR (x), CDR (x));
691   puts ("00\n");
692   if ((FUNCTION (fn).arity > 1 || FUNCTION (fn).arity == -1)
693       && x != cell_nil && TYPE (CDR (x)) == PAIR && TYPE (CADR (x)) == VALUES)
694     x = cons (CAR (x), cons (CDADAR (x), CDR (x)));
695   //struct function* f = &FUNCTION (fn);
696   puts ("01\n");
697   switch (2)///FIXME FUNCTION (fn).arity)
698     {
699     // case 0: return FUNCTION (fn).function0 ();
700     // case 1: return FUNCTION (fn).function1 (car (x));
701     // case 2: return FUNCTION (fn).function2 (car (x), cadr (x));
702     // case 3: return FUNCTION (fn).function3 (car (x), cadr (x), car (cddr (x)));
703     // case -1: return FUNCTION (fn).functionn (x);
704     case 0: {puts("02.0\n");return (FUNCTION (fn).function) ();}
705     case 1: {puts("03.1\n");return ((SCM(*)(SCM))(FUNCTION (fn).function)) (car (x));}
706 #if 0
707       //__GNUC__
708     case 2: {return ((SCM(*)(SCM,SCM))(FUNCTION (fn).function)) (car (x), cadr (x));}
709 #else
710     case 2: {
711       puts ("04.2\n");
712       SCM p1 = car (x);
713       SCM p2 = cdr (x);
714       p2 = car (p2);
715       //return ((SCM(*)(SCM,SCM))(FUNCTION (fn).function)) (p1, p2);
716       int (*functionx) (int,int) = (SCM(*)(SCM,SCM))FUNCTION (fn).function;
717       //return ((SCM(*)(SCM,SCM))(*FUNCTION (fn).function)) (p1, p2);
718       //return ((SCM(*)(SCM,SCM))(*functionx)) (p1, p2);
719       SCM p3;
720       //p3 = 0x44;
721       puts ("05\n");
722       return cons (p1, p2);
723       return (*functionx) (p1, p2);
724     }
725 #endif
726     case 3: {puts("05.3\n");return ((SCM(*)(SCM,SCM,SCM))(FUNCTION (fn).function)) (car (x), cadr (x), car (cddr (x)));}
727       //case -1: {return ((SCM(*)(SCM))(FUNCTION (fn).function)) (x);}
728     default: {return ((SCM(*)(SCM))(FUNCTION (fn).function)) (x);}
729     }
730
731   return cell_unspecified;
732 }
733
734 SCM
735 gc_peek_frame ()
736 {
737   SCM frame = car (g_stack);
738   r1 = car (frame);
739 #if __GNUC__
740   r2 = cadr (frame);
741   r3 = car (cddr (frame));
742   r0 = cadr (cddr (frame));
743 #else
744   r2 = cdr (frame);
745   r2 = car (r2);
746
747   r3 = cdr (frame);
748   r3 = cdr (r3);
749   r3 = car (r3);
750
751   r0 = cdr (frame);
752   r0 = cdr (r0);
753   r0 = cdr (r0);
754   r0 = cdr (r0);
755   r0 = car (r0);
756 #endif
757   return frame;
758 }
759
760 SCM
761 gc_pop_frame ()
762 {
763   SCM frame = gc_peek_frame (g_stack);
764   g_stack = cdr (g_stack);
765   return frame;
766 }
767
768 SCM
769 mes_g_stack (SCM a) ///((internal))
770 {
771   r0 = a;
772   r1 = MAKE_CHAR (0);
773   r2 = MAKE_CHAR (0);
774   r3 = MAKE_CHAR (0);
775   g_stack = cons (cell_nil, cell_nil);
776   return r0;
777 }
778
779 //\f Environment setup
780 SCM
781 make_tmps (struct scm* cells)
782 {
783   tmp = g_free++;
784   cells[tmp].type = CHAR;
785   tmp_num = g_free++;
786   cells[tmp_num].type = NUMBER;
787   tmp_num2 = g_free++;
788   cells[tmp_num2].type = NUMBER;
789   return 0;
790 }
791
792 SCM
793 make_symbol_ (SCM s)
794 {
795   VALUE (tmp_num) = SYMBOL;
796   SCM x = make_cell (tmp_num, s, 0);
797   g_symbols = cons (x, g_symbols);
798   return x;
799 }
800
801 SCM
802 make_symbol (SCM s)
803 {
804 #if MES_MINI
805   SCM x = 0;
806 #else
807   SCM x = lookup_symbol_ (s);
808 #endif
809   return x ? x : make_symbol_ (s);
810 }
811
812 SCM
813 cstring_to_list (char const* s)
814 {
815   SCM p = cell_nil;
816   int i = strlen (s);
817   while (i--)
818     p = cons (MAKE_CHAR (s[i]), p);
819   return p;
820 }
821
822 SCM
823 acons (SCM key, SCM value, SCM alist)
824 {
825   return cons (cons (key, value), alist);
826 }
827
828 //\f Jam Collector
829 SCM g_symbol_max;
830
831 SCM
832 gc_init_cells ()
833 {
834   return 0;
835 //   g_cells = (scm *)malloc (2*ARENA_SIZE*sizeof(scm));
836
837 // #if __NYACC__ || FIXME_NYACC
838 //   TYPE (0) = TVECTOR;
839 // // #else
840 // //   TYPE (0) = VECTOR;
841 // #endif
842 //   LENGTH (0) = 1000;
843 //   VECTOR (0) = 0;
844 //   g_cells++;
845 //   TYPE (0) = CHAR;
846 //   VALUE (0) = 'c';
847 }
848
849 // INIT NEWS
850
851 SCM
852 mes_symbols () ///((internal))
853 {
854   gc_init_cells ();
855   //  gc_init_news ();
856
857 #if __GNUC__ && 0
858   //#include "mes.symbols.i"
859 #else
860 g_free++;
861 // g_cells[cell_nil] = scm_nil;
862
863 g_free++;
864 // g_cells[cell_f] = scm_f;
865
866 g_free++;
867 // g_cells[cell_t] = scm_t;
868
869 g_free++;
870 // g_cells[cell_dot] = scm_dot;
871
872 g_free++;
873 // g_cells[cell_arrow] = scm_arrow;
874
875 g_free++;
876 // g_cells[cell_undefined] = scm_undefined;
877
878 g_free++;
879 // g_cells[cell_unspecified] = scm_unspecified;
880
881 g_free++;
882 // g_cells[cell_closure] = scm_closure;
883
884 g_free++;
885 // g_cells[cell_circular] = scm_circular;
886
887 g_free++;
888 // g_cells[cell_begin] = scm_begin;
889
890 ///
891 g_free = 44;
892 g_free++;
893 // g_cells[cell_vm_apply] = scm_vm_apply;
894
895 g_free++;
896 // g_cells[cell_vm_apply2] = scm_vm_apply2;
897
898 g_free++;
899 // g_cells[cell_vm_eval] = scm_vm_eval;
900
901 ///
902 g_free = 55;
903 g_free++;
904 // g_cells[cell_vm_begin] = scm_vm_begin;
905
906 g_free++;
907 // g_cells[cell_vm_begin_read_input_file] = scm_vm_begin_read_input_file;
908
909 g_free++;
910 // g_cells[cell_vm_begin2] = scm_vm_begin2;
911
912 ///
913 g_free = 62;
914 g_free++;
915 // g_cells[cell_vm_return] = scm_vm_return;
916
917 #endif
918
919   g_symbol_max = g_free;
920   make_tmps (g_cells);
921
922   g_symbols = 0;
923   for (int i=1; i<g_symbol_max; i++)
924     g_symbols = cons (i, g_symbols);
925
926   SCM a = cell_nil;
927
928 #if __GNUC__ && 0
929   //#include "mes.symbol-names.i"
930 #else
931 // g_cells[cell_nil].car = cstring_to_list (scm_nil.name);
932 // g_cells[cell_f].car = cstring_to_list (scm_f.name);
933 // g_cells[cell_t].car = cstring_to_list (scm_t.name);
934 // g_cells[cell_dot].car = cstring_to_list (scm_dot.name);
935 // g_cells[cell_arrow].car = cstring_to_list (scm_arrow.name);
936 // g_cells[cell_undefined].car = cstring_to_list (scm_undefined.name);
937 // g_cells[cell_unspecified].car = cstring_to_list (scm_unspecified.name);
938 // g_cells[cell_closure].car = cstring_to_list (scm_closure.name);
939 // g_cells[cell_circular].car = cstring_to_list (scm_circular.name);
940 // g_cells[cell_begin].car = cstring_to_list (scm_begin.name);
941 #endif
942
943   // a = acons (cell_symbol_mes_version, MAKE_STRING (cstring_to_list (VERSION)), a);
944   // a = acons (cell_symbol_mes_prefix, MAKE_STRING (cstring_to_list (PREFIX)), a);
945
946   a = acons (cell_symbol_dot, cell_dot, a);
947   a = acons (cell_symbol_begin, cell_begin, a);
948   a = acons (cell_closure, a, a);
949
950   // a = acons (cell_symbol_call_with_current_continuation, cell_call_with_current_continuation, a);
951   // a = acons (cell_symbol_sc_expand, cell_f, a);
952
953   return a;
954 }
955
956 SCM
957 make_closure (SCM args, SCM body, SCM a)
958 {
959   return make_cell (tmp_num_ (CLOSURE), cell_f, cons (cons (cell_circular, a), cons (args, body)));
960 }
961
962 SCM
963 mes_environment () ///((internal))
964 {
965   SCM a = 0;
966   a = mes_symbols ();
967   a = mes_g_stack (a);
968   return a;
969 }
970
971 SCM
972 mes_builtins (SCM a)
973 {
974 #if 0
975   //__GNUC__
976 //#include "mes.i"
977
978 // #include "lib.i"
979 // #include "math.i"
980 // #include "posix.i"
981 // #include "reader.i"
982
983 // #include "lib.environment.i"
984 // #include "math.environment.i"
985 // #include "mes.environment.i"
986 // #include "posix.environment.i"
987 // #include "reader.environment.i"
988 #else
989
990 scm_make_cell.cdr = g_function;
991 functions[g_function++] = fun_make_cell;
992 cell_make_cell = g_free++;
993 #if __GNUC__
994  puts ("WOOOT=");
995  puts (itoa (g_free));
996  puts ("\n");
997   //FIXME GNUC
998  g_cells[cell_make_cell] = scm_make_cell;
999 #else
1000 g_cells[16] = scm_make_cell;
1001 #endif
1002  
1003 scm_cons.cdr = g_function;
1004 functions[g_function++] = fun_cons;
1005 cell_cons = g_free++;
1006 #if __GNUC__
1007   //FIXME GNUC
1008 g_cells[cell_cons] = scm_cons;
1009 #else
1010 g_cells[17] = scm_cons;
1011 #endif
1012  
1013 scm_car.cdr = g_function;
1014 functions[g_function++] = fun_car;
1015 cell_car = g_free++;
1016 #if __GNUC__
1017   //FIXME GNUC
1018 g_cells[cell_car] = scm_car;
1019 #endif
1020  
1021 #if __GNUC__
1022   //FIXME GNUC
1023 scm_cdr.cdr = g_function;
1024 functions[g_function++] = fun_cdr;
1025 cell_cdr = g_free++;
1026 g_cells[cell_cdr] = scm_cdr;
1027
1028 // scm_make_cell.string = cstring_to_list (scm_make_cell.name);
1029 // g_cells[cell_make_cell].string = MAKE_STRING (scm_make_cell.string);
1030 // a = acons (make_symbol (scm_make_cell.string), cell_make_cell, a);
1031
1032 // scm_cons.string = cstring_to_list (scm_cons.name);
1033 // g_cells[cell_cons].string = MAKE_STRING (scm_cons.string);
1034 // a = acons (make_symbol (scm_cons.string), cell_cons, a);
1035
1036 // scm_car.string = cstring_to_list (scm_car.name);
1037 // g_cells[cell_car].string = MAKE_STRING (scm_car.string);
1038 // a = acons (make_symbol (scm_car.string), cell_car, a);
1039
1040 // scm_cdr.string = cstring_to_list (scm_cdr.name);
1041 // g_cells[cell_cdr].string = MAKE_STRING (scm_cdr.string);
1042 // a = acons (make_symbol (scm_cdr.string), cell_cdr, a);
1043 #endif
1044 #endif
1045   return a;
1046 }
1047
1048 SCM
1049 bload_env (SCM a) ///((internal))
1050 {
1051   g_stdin = open ("module/mes/read-0.mo", 0);
1052 #if __GNUC__
1053   //g_stdin = g_stdin ? g_stdin : fopen (PREFIX "module/mes/read-0.mo", "r");
1054 #endif
1055   char *p = (char*)g_cells;
1056 #if __GNUC__
1057   //FIXME GNUC
1058   assert (getchar () == 'M');
1059   assert (getchar () == 'E');
1060   assert (getchar () == 'S');
1061 #else
1062   getchar ();
1063   getchar ();
1064   getchar ();
1065 #endif
1066   g_stack = getchar () << 8;
1067   g_stack += getchar ();
1068   int c = getchar ();
1069   while (c != EOF)
1070     {
1071       *p++ = c;
1072       c = getchar ();
1073     }
1074   g_free = (p-(char*)g_cells) / sizeof (struct scm);
1075   gc_peek_frame ();
1076   g_symbols = r1;
1077   g_stdin = STDIN;
1078   r0 = mes_builtins (r0);
1079   return r2;
1080 }
1081
1082 SCM
1083 fill ()
1084 {
1085   TYPE (0) = 0x6c6c6168;
1086   CAR (0) = 0x6a746f6f;
1087   CDR (0) = 0x00002165;
1088
1089   TYPE (1) = SYMBOL;
1090   CAR (1) = 0x2d2d2d2d;
1091   CDR (1) = 0x3e3e3e3e;
1092
1093   TYPE (9) = 0x2d2d2d2d;
1094   CAR (9) = 0x2d2d2d2d;
1095   CDR (9) = 0x3e3e3e3e;
1096 #if 0
1097   // (A(B))
1098   TYPE (10) = PAIR;
1099   CAR (10) = 11;
1100   CDR (10) = 12;
1101
1102   TYPE (11) = CHAR;
1103   CAR (11) = 0x58585858;
1104   CDR (11) = 89;
1105
1106   TYPE (12) = PAIR;
1107   CAR (12) = 13;
1108   CDR (12) = 1;
1109
1110   TYPE (13) = CHAR;
1111   CAR (13) = 0x58585858;
1112   CDR (13) = 90;
1113
1114   TYPE (14) = 0x58585858;
1115   CAR (14) = 0x58585858;
1116   CDR (14) = 0x58585858;
1117
1118   TYPE (14) = 0x58585858;
1119   CAR (14) = 0x58585858;
1120   CDR (14) = 0x58585858;
1121 #else
1122   // (cons 0 1)
1123   TYPE (10) = PAIR;
1124   CAR (10) = 11;
1125   CDR (10) = 12;
1126
1127   TYPE (11) = TFUNCTION;
1128   CAR (11) = 0x58585858;
1129   // 0 = make_cell
1130   // 1 = cons
1131   // 2 = car
1132   CDR (11) = 1;
1133
1134   TYPE (12) = PAIR;
1135   CAR (12) = 13;
1136   //CDR (12) = 1;
1137   CDR (12) = 14;
1138
1139   TYPE (13) = NUMBER;
1140   CAR (13) = 0x58585858;
1141   CDR (13) = 0;
1142
1143   TYPE (14) = PAIR;
1144   CAR (14) = 15;
1145   CDR (14) = 1;
1146
1147   TYPE (15) = NUMBER;
1148   CAR (15) = 0x58585858;
1149   CDR (15) = 1;
1150
1151   //g_stack@23
1152   TYPE (19) = PAIR;
1153   CAR (19) = 1;
1154   CDR (19) = 1;
1155
1156   TYPE (20) = PAIR;
1157   CAR (20) = 7;
1158   CDR (20) = 19;
1159
1160   TYPE (21) = PAIR;
1161   CAR (21) = 7;
1162   CDR (21) = 20;
1163
1164   TYPE (22) = PAIR;
1165   CAR (22) = 134;
1166   CDR (22) = 21;
1167
1168   TYPE (23) = PAIR;
1169   CAR (23) = 22;
1170   CDR (23) = 137;
1171
1172 #endif
1173
1174   return 0;
1175 }
1176
1177 SCM
1178 display_ (SCM x)
1179 {
1180   //puts ("<display>\n");
1181   switch (TYPE (x))
1182     {
1183     case CHAR:
1184       {
1185         //puts ("<char>\n");
1186         puts ("#\\");
1187         putchar (VALUE (x));
1188         break;
1189       }
1190     case TFUNCTION:
1191       {
1192         //puts ("<function>\n");
1193         if (VALUE (x) == 0)
1194           puts ("make-cell");
1195         if (VALUE (x) == 1)
1196           puts ("cons");
1197         if (VALUE (x) == 2)
1198           puts ("car");
1199         if (VALUE (x) == 3)
1200           puts ("cdr");
1201         break;
1202       }
1203     case NUMBER:
1204       {
1205         //puts ("<number>\n");
1206 #if __GNUC__
1207         putchar (48 + VALUE (x));
1208 #else
1209         int i;
1210         i = VALUE (x);
1211         i = i + 48;
1212         putchar (i);
1213 #endif
1214         break;
1215       }
1216     case PAIR:
1217       {
1218         //puts ("<pair>\n");
1219         //if (cont != cell_f) puts "(");
1220         puts ("(");
1221         if (x && x != cell_nil) display_ (CAR (x));
1222         if (CDR (x) && CDR (x) != cell_nil)
1223           {
1224 #if __GNUC__
1225             if (TYPE (CDR (x)) != PAIR)
1226               puts (" . ");
1227 #else
1228             int c;
1229             c = CDR (x);
1230             c = TYPE (c);
1231             if (c != PAIR)
1232               puts (" . ");
1233 #endif
1234             display_ (CDR (x));
1235           }
1236         //if (cont != cell_f) puts (")");
1237         puts (")");
1238         break;
1239       }
1240     default:
1241       {
1242         //puts ("<default>\n");
1243         puts ("_");
1244         break;
1245       }
1246     }
1247   return 0;
1248 }
1249
1250 SCM
1251 simple_bload_env (SCM a) ///((internal))
1252 {
1253   puts ("reading: ");
1254   char *mo = "module/mes/hack-32.mo";
1255   puts (mo);
1256   puts ("\n");
1257   g_stdin = open (mo, 0);
1258   if (g_stdin < 0) {eputs ("no such file: module/mes/read-0-32.mo\n");return 1;} 
1259
1260   char *p = (char*)g_cells;
1261   int c;
1262
1263 #if 0
1264   //__GNUC__
1265   puts ("fd: ");
1266   puts (itoa (g_stdin));
1267   puts ("\n");
1268 #endif
1269
1270 #if 0
1271   //__GNUC__
1272   assert (getchar () == 'M');
1273   assert (getchar () == 'E');
1274   assert (getchar () == 'S');
1275   puts (" *GOT MES*\n");
1276   g_stack = getchar () << 8;
1277   g_stack += getchar ();
1278   puts ("stack: ");
1279   puts (itoa (g_stack));
1280   puts ("\n");
1281 #else
1282   c = getchar ();
1283   putchar (c);
1284   if (c != 'M') exit (10);
1285   c = getchar ();
1286   putchar (c);
1287   if (c != 'E') exit (11);
1288   c = getchar ();
1289   putchar (c);
1290   if (c != 'S') exit (12);
1291   puts (" *GOT MES*\n");
1292
1293   // skip stack
1294   getchar ();
1295   getchar ();
1296 #endif
1297
1298   c = getchar ();
1299   while (c != -1)
1300     {
1301       *p++ = c;
1302       c = getchar ();
1303       putchar (c);
1304     }
1305
1306   puts ("read done\n");
1307
1308   // g_free = (p-(char*)g_cells) / sizeof (struct scm);
1309   c = p-(char*)g_cells;
1310   exit (c);
1311   
1312   
1313   
1314   
1315  if (g_free != 15) exit (33);
1316   
1317   // puts ("Xg_free: ");
1318   // puts (itoa (g_free));
1319   // puts ("\n");
1320
1321
1322   ///if (g_free != 19) return 33;
1323   
1324   // gc_peek_frame ();
1325   // g_symbols = r1;
1326   g_symbols = 1;
1327   g_stdin = STDIN;
1328   r0 = mes_builtins (r0);
1329   
1330 #if __GNUC__
1331   puts ("cells read: ");
1332   puts (itoa (g_free));
1333   puts ("\n");
1334
1335   puts ("symbols: ");
1336   puts (itoa (g_symbols));
1337   puts ("\n");
1338   // display_ (g_symbols);
1339   // puts ("\n");
1340 #endif
1341
1342   display_ (10);
1343   puts ("\n");
1344
1345   fill ();
1346   r2 = 10;
1347
1348   if (TYPE (12) != PAIR)
1349     exit (33);
1350
1351   puts ("program[");
1352 #if __GNUC__
1353   puts (itoa (r2));
1354 #endif
1355   puts ("]: ");
1356
1357   display_ (r2);
1358   //display_ (14);
1359   puts ("\n");
1360
1361   r0 = 1;
1362   //r2 = 10;
1363   return r2;
1364 }
1365
1366 char const*
1367 string_to_cstring (SCM s)
1368 {
1369   static char buf[1024];
1370   char *p = buf;
1371   s = STRING(s);
1372   while (s != cell_nil)
1373     {
1374       *p++ = VALUE (car (s));
1375       s = cdr (s);
1376     }
1377   *p = 0;
1378   return buf;
1379 }
1380
1381 SCM
1382 stderr_ (SCM x)
1383 {
1384   //SCM write;
1385 #if __NYACC__ || FIXME_NYACC
1386   if (TYPE (x) == TSTRING)
1387 // #else
1388 //   if (TYPE (x) == STRING)
1389 #endif
1390     eputs (string_to_cstring (x));
1391   // else if ((write = assq_ref_env (cell_symbol_write, r0)) != cell_undefined)
1392   //   apply (assq_ref_env (cell_symbol_display, r0), cons (x, cons (MAKE_NUMBER (2), cell_nil)), r0);
1393 #if __NYACC__ || FIXME_NYACC
1394   else if (TYPE (x) == SPECIAL || TYPE (x) == TSTRING || TYPE (x) == SYMBOL)
1395 // #else
1396 //   else if (TYPE (x) == SPECIAL || TYPE (x) == STRING || TYPE (x) == SYMBOL)
1397 #endif
1398     eputs (string_to_cstring (x));
1399   else if (TYPE (x) == NUMBER)
1400     eputs (itoa (VALUE (x)));
1401   else
1402     eputs ("display: undefined\n");
1403   return cell_unspecified;
1404 }
1405
1406 int
1407 main (int argc, char *argv[])
1408 {
1409   puts ("Hello mini-mes!\n");
1410 #if __GNUC__
1411   //g_debug = getenv ("MES_DEBUG");
1412 #endif
1413   //if (getenv ("MES_ARENA")) ARENA_SIZE = atoi (getenv ("MES_ARENA"));
1414   if (argc > 1 && !strcmp (argv[1], "--help")) return eputs ("Usage: mes [--dump|--load] < FILE");
1415 #if __GNUC__
1416   if (argc > 1 && !strcmp (argv[1], "--version")) {eputs ("Mes ");return eputs (VERSION);};
1417 #else
1418   if (argc > 1 && !strcmp (argv[1], "--version")) {eputs ("Mes ");return eputs ("0.4");};
1419 #endif
1420   g_stdin = STDIN;
1421
1422   r0 = mes_environment ();
1423   
1424 #if MES_MINI
1425   SCM program = simple_bload_env (r0);
1426 #else  
1427   SCM program = (argc > 1 && !strcmp (argv[1], "--load"))
1428     ? bload_env (r0) : load_env (r0);
1429   if (argc > 1 && !strcmp (argv[1], "--dump")) return dump ();
1430 #endif
1431
1432 #if 1
1433
1434 #if __GNUC__
1435   puts ("g_free=");
1436   puts (itoa(g_free));
1437   puts ("\n");
1438 #else
1439   g_free = 19;
1440
1441 #endif
1442
1443   //return cons (r0, cell_nil);
1444
1445   //FIXME
1446   push_cc (r2, cell_unspecified, r0, cell_unspecified);
1447 #if __GNUC__
1448   for (int x=19; x<26 ;x++)
1449     {
1450       puts(itoa(x));
1451       puts(": type=");
1452       puts(itoa(g_cells[x].type));
1453       puts(" car=");
1454       puts(itoa(g_cells[x].car));
1455       puts(" cdr=");
1456       puts(itoa(g_cells[x].cdr));
1457       puts("\n");
1458     }
1459 #endif
1460 #else
1461   g_stack = 23;
1462   g_free = 24;
1463   r1 = r2; //10: the-program
1464   r2 = cell_unspecified;
1465 #endif
1466
1467   puts ("g_stack: ");
1468   display_ (g_stack);
1469   puts ("\n");
1470
1471 #if __GNUC__
1472
1473   puts ("g_free=");
1474   puts (itoa(g_free));
1475   puts ("\n");
1476
1477   puts ("g_stack=");
1478   puts (itoa(g_stack));
1479   puts ("\n");
1480
1481   puts ("r0=");
1482   puts (itoa(r0));
1483   puts ("\n");
1484
1485   puts ("r1=");
1486   puts (itoa(r1));
1487   puts ("\n");
1488
1489   puts ("r2=");
1490   puts (itoa(r2));
1491   puts ("\n");
1492
1493   puts ("r3=");
1494   puts (itoa(r3));
1495   puts ("\n");
1496 #endif
1497
1498   //r3 = cell_vm_begin;
1499   r3 = cell_vm_apply;
1500   r1 = eval_apply ();
1501   //stderr_ (r1);
1502   display_ (r1);
1503
1504   eputs ("\n");
1505 #if !MES_MINI
1506   gc (g_stack);
1507 #endif
1508 #if __GNUC__
1509   if (g_debug)
1510     {
1511       eputs ("\nstats: [");
1512       eputs (itoa (g_free));
1513       eputs ("]\n");
1514     }
1515 #endif
1516   return 0;
1517 }
1518
1519 #if __GNUC__
1520 void
1521 _start ()
1522 {
1523   int r;
1524   asm (
1525        "mov %%ebp,%%eax\n\t"
1526        "addl $8,%%eax\n\t"
1527        "push %%eax\n\t"
1528
1529        "mov %%ebp,%%eax\n\t"
1530        "addl $4,%%eax\n\t"
1531        "movzbl (%%eax),%%eax\n\t"
1532        "push %%eax\n\t"
1533
1534        "call main\n\t"
1535        "movl %%eax,%0\n\t"
1536        : "=r" (r)
1537        : //no inputs "" (&main)
1538        );
1539   exit (r);
1540 }
1541 #endif