5a4c95dea05f6da2ff3afd124efb57ce926151ec
[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 g_functions[5];
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) g_functions[g_cells[x].function]
397 #endif
398
399 #define FUNCTION(x) g_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   assert (g_free + n < ARENA_SIZE);
428   SCM x = g_free;
429   g_free += n;
430   return x;
431 }
432
433 SCM
434 make_cell (SCM type, SCM car, SCM cdr)
435 {
436   SCM x = alloc (1);
437   assert (TYPE (type) == NUMBER);
438   TYPE (x) = VALUE (type);
439   if (VALUE (type) == CHAR || VALUE (type) == NUMBER) {
440     if (car) CAR (x) = CAR (car);
441     if (cdr) CDR(x) = CDR(cdr);
442   }
443   else if (VALUE (type) == TFUNCTION) {
444     if (car) CAR (x) = car;
445     if (cdr) CDR(x) = CDR(cdr);
446   }
447   else {
448     CAR (x) = car;
449     CDR(x) = cdr;
450   }
451   return x;
452 }
453
454 SCM
455 tmp_num_ (int x)
456 {
457   VALUE (tmp_num) = x;
458   return tmp_num;
459 }
460
461 SCM
462 tmp_num2_ (int x)
463 {
464   VALUE (tmp_num2) = x;
465   return tmp_num2;
466 }
467
468 SCM
469 cons (SCM x, SCM y)
470 {
471   puts ("cons x=");
472 #if __GNUC__
473   puts (itoa (x));
474 #endif
475   puts ("\n");
476   VALUE (tmp_num) = PAIR;
477   return make_cell (tmp_num, x, y);
478 }
479
480 SCM
481 car (SCM x)
482 {
483   puts ("car x=");
484 #if __GNUC__
485   puts (itoa (x));
486 #endif
487   puts ("\n");
488 #if MES_MINI
489   //Nyacc
490   //assert ("!car");
491 #else
492   if (TYPE (x) != PAIR) error (cell_symbol_not_a_pair, cons (x, cell_symbol_car));
493 #endif
494   return CAR (x);
495 }
496
497 SCM
498 cdr (SCM x)
499 {
500   puts ("cdr x=");
501 #if __GNUC__
502   puts (itoa (x));
503 #endif
504   puts ("\n");
505 #if MES_MINI
506   //Nyacc
507   //assert ("!cdr");
508 #else
509   if (TYPE (x) != PAIR) error (cell_symbol_not_a_pair, cons (x, cell_symbol_cdr));
510 #endif
511   return CDR(x);
512 }
513
514 SCM
515 gc_push_frame ()
516 {
517   SCM frame = cons (r1, cons (r2, cons (r3, cons (r0, cell_nil))));
518   g_stack = cons (frame, g_stack);
519   return g_stack;
520 }
521
522 SCM
523 append2 (SCM x, SCM y)
524 {
525   if (x == cell_nil) return y;
526 #if __GNUC__
527   //FIXME GNUC
528   assert (TYPE (x) == PAIR);
529 #endif
530   return cons (car (x), append2 (cdr (x), y));
531 }
532
533 SCM
534 pairlis (SCM x, SCM y, SCM a)
535 {
536   if (x == cell_nil)
537     return a;
538   if (TYPE (x) != PAIR)
539     return cons (cons (x, y), a);
540   return cons (cons (car (x), car (y)),
541                pairlis (cdr (x), cdr (y), a));
542 }
543
544 SCM
545 assq (SCM x, SCM a)
546 {
547   //while (a != cell_nil && eq_p (x, CAAR (a)) == cell_f) a = CDR (a);
548   while (a != cell_nil && x == CAAR (a)) a = CDR (a);
549   return a != cell_nil ? car (a) : cell_f;
550 }
551
552 SCM
553 push_cc (SCM p1, SCM p2, SCM a, SCM c) ///((internal))
554 {
555   puts ("push cc\n");
556   SCM x = r3;
557   r3 = c;
558   r2 = p2;
559   gc_push_frame ();
560   r1 = p1;
561   r0 = a;
562   r3 = x;
563   return cell_unspecified;
564 }
565
566 SCM caar (SCM x) {return car (car (x));}
567 SCM cadr (SCM x) {return car (cdr (x));}
568 SCM cdar (SCM x) {return cdr (car (x));}
569 SCM cddr (SCM x) {return cdr (cdr (x));}
570
571 #if __GNUC__
572 //FIXME
573 SCM call (SCM,SCM);
574 SCM gc_pop_frame ();
575 #endif
576
577 SCM
578 eval_apply ()
579 {
580  eval_apply:
581   // if (g_free + GC_SAFETY > ARENA_SIZE)
582   //   gc_pop_frame (gc (gc_push_frame ()));
583
584   switch (r3)
585     {
586     case cell_vm_apply: {goto apply;}
587     case cell_unspecified: {return r1;}
588     }
589
590   SCM x = cell_nil;
591   SCM y = cell_nil;
592
593  apply:
594   switch (TYPE (car (r1)))
595     {
596     case TFUNCTION: {
597       puts ("apply.function\n");
598       //check_formals (car (r1), MAKE_NUMBER (FUNCTION (car (r1)).arity), cdr (r1));
599       r1 = call (car (r1), cdr (r1));
600       goto vm_return;
601     }
602     }
603  vm_return:
604   x = r1;
605   gc_pop_frame ();
606   r1 = x;
607   goto eval_apply;
608 }
609
610 SCM
611 call (SCM fn, SCM x)
612 {
613   puts ("call\n");
614   if ((FUNCTION (fn).arity > 0 || FUNCTION (fn).arity == -1)
615       && x != cell_nil && TYPE (CAR (x)) == VALUES)
616     x = cons (CADAR (x), CDR (x));
617   if ((FUNCTION (fn).arity > 1 || FUNCTION (fn).arity == -1)
618       && x != cell_nil && TYPE (CDR (x)) == PAIR && TYPE (CADR (x)) == VALUES)
619     x = cons (CAR (x), cons (CDADAR (x), CDR (x)));
620   switch (FUNCTION (fn).arity)
621     {
622     // case 0: return FUNCTION (fn).function0 ();
623     // case 1: return FUNCTION (fn).function1 (car (x));
624     // case 2: return FUNCTION (fn).function2 (car (x), cadr (x));
625     // case 3: return FUNCTION (fn).function3 (car (x), cadr (x), car (cddr (x)));
626     // case -1: return FUNCTION (fn).functionn (x);
627     case 0: {return (FUNCTION (fn).function) ();}
628     case 1: {return ((SCM(*)(SCM))(FUNCTION (fn).function)) (car (x));}
629     case 2: {return ((SCM(*)(SCM,SCM))(FUNCTION (fn).function)) (car (x), cadr (x));}
630     case 3: {return ((SCM(*)(SCM,SCM,SCM))(FUNCTION (fn).function)) (car (x), cadr (x), car (cddr (x)));}
631 #if __GNUC__
632       // FIXME GNUC
633     case -1: {return ((SCM(*)(SCM))(FUNCTION (fn).function)) (x);}
634 #endif
635     default: {return ((SCM(*)(SCM))(FUNCTION (fn).function)) (x);}
636     }
637   return cell_unspecified;
638 }
639
640 SCM
641 gc_peek_frame ()
642 {
643   SCM frame = car (g_stack);
644   r1 = car (frame);
645 #if __GNUC__
646   r2 = cadr (frame);
647   r3 = car (cddr (frame));
648   r0 = cadr (cddr (frame));
649 #else
650   r2 = cdr (frame);
651   r2 = car (r2);
652
653   r3 = cdr (frame);
654   r3 = cdr (r3);
655   r3 = car (r3);
656
657   r0 = cdr (frame);
658   r0 = cdr (r0);
659   r0 = cdr (r0);
660   r0 = cdr (r0);
661   r0 = car (r0);
662 #endif
663   return frame;
664 }
665
666 SCM
667 gc_pop_frame ()
668 {
669   SCM frame = gc_peek_frame (g_stack);
670   g_stack = cdr (g_stack);
671   return frame;
672 }
673
674 SCM
675 mes_g_stack (SCM a) ///((internal))
676 {
677   r0 = a;
678   r1 = MAKE_CHAR (0);
679   r2 = MAKE_CHAR (0);
680   r3 = MAKE_CHAR (0);
681   g_stack = cons (cell_nil, cell_nil);
682   return r0;
683 }
684
685 //\f Environment setup
686 SCM
687 make_tmps (struct scm* cells)
688 {
689   tmp = g_free++;
690   cells[tmp].type = CHAR;
691   tmp_num = g_free++;
692   cells[tmp_num].type = NUMBER;
693   tmp_num2 = g_free++;
694   cells[tmp_num2].type = NUMBER;
695   return 0;
696 }
697
698 SCM
699 make_symbol_ (SCM s)
700 {
701   VALUE (tmp_num) = SYMBOL;
702   SCM x = make_cell (tmp_num, s, 0);
703   g_symbols = cons (x, g_symbols);
704   return x;
705 }
706
707 SCM
708 make_symbol (SCM s)
709 {
710 #if MES_MINI
711   SCM x = 0;
712 #else
713   SCM x = lookup_symbol_ (s);
714 #endif
715   return x ? x : make_symbol_ (s);
716 }
717
718 SCM
719 cstring_to_list (char const* s)
720 {
721   SCM p = cell_nil;
722   int i = strlen (s);
723   while (i--)
724     p = cons (MAKE_CHAR (s[i]), p);
725   return p;
726 }
727
728 SCM
729 acons (SCM key, SCM value, SCM alist)
730 {
731   return cons (cons (key, value), alist);
732 }
733
734 //\f Jam Collector
735 SCM g_symbol_max;
736
737 SCM
738 gc_init_cells ()
739 {
740   return 0;
741 //   g_cells = (scm *)malloc (2*ARENA_SIZE*sizeof(scm));
742
743 // #if __NYACC__ || FIXME_NYACC
744 //   TYPE (0) = TVECTOR;
745 // // #else
746 // //   TYPE (0) = VECTOR;
747 // #endif
748 //   LENGTH (0) = 1000;
749 //   VECTOR (0) = 0;
750 //   g_cells++;
751 //   TYPE (0) = CHAR;
752 //   VALUE (0) = 'c';
753 }
754
755 // INIT NEWS
756
757 SCM
758 mes_symbols () ///((internal))
759 {
760   gc_init_cells ();
761   //  gc_init_news ();
762
763 #if __GNUC__ && 0
764   //#include "mes.symbols.i"
765 #else
766 g_free++;
767 // g_cells[cell_nil] = scm_nil;
768
769 g_free++;
770 // g_cells[cell_f] = scm_f;
771
772 g_free++;
773 // g_cells[cell_t] = scm_t;
774
775 g_free++;
776 // g_cells[cell_dot] = scm_dot;
777
778 g_free++;
779 // g_cells[cell_arrow] = scm_arrow;
780
781 g_free++;
782 // g_cells[cell_undefined] = scm_undefined;
783
784 g_free++;
785 // g_cells[cell_unspecified] = scm_unspecified;
786
787 g_free++;
788 // g_cells[cell_closure] = scm_closure;
789
790 g_free++;
791 // g_cells[cell_circular] = scm_circular;
792
793 g_free++;
794 // g_cells[cell_begin] = scm_begin;
795
796 ///
797 g_free = 44;
798 g_free++;
799 // g_cells[cell_vm_apply] = scm_vm_apply;
800
801 g_free++;
802 // g_cells[cell_vm_apply2] = scm_vm_apply2;
803
804 g_free++;
805 // g_cells[cell_vm_eval] = scm_vm_eval;
806
807 ///
808 g_free = 55;
809 g_free++;
810 // g_cells[cell_vm_begin] = scm_vm_begin;
811
812 g_free++;
813 // g_cells[cell_vm_begin_read_input_file] = scm_vm_begin_read_input_file;
814
815 g_free++;
816 // g_cells[cell_vm_begin2] = scm_vm_begin2;
817
818 ///
819 g_free = 62;
820 g_free++;
821 // g_cells[cell_vm_return] = scm_vm_return;
822
823 #endif
824
825   g_symbol_max = g_free;
826   make_tmps (g_cells);
827
828   g_symbols = 0;
829   for (int i=1; i<g_symbol_max; i++)
830     g_symbols = cons (i, g_symbols);
831
832   SCM a = cell_nil;
833
834 #if __GNUC__ && 0
835   //#include "mes.symbol-names.i"
836 #else
837 // g_cells[cell_nil].car = cstring_to_list (scm_nil.name);
838 // g_cells[cell_f].car = cstring_to_list (scm_f.name);
839 // g_cells[cell_t].car = cstring_to_list (scm_t.name);
840 // g_cells[cell_dot].car = cstring_to_list (scm_dot.name);
841 // g_cells[cell_arrow].car = cstring_to_list (scm_arrow.name);
842 // g_cells[cell_undefined].car = cstring_to_list (scm_undefined.name);
843 // g_cells[cell_unspecified].car = cstring_to_list (scm_unspecified.name);
844 // g_cells[cell_closure].car = cstring_to_list (scm_closure.name);
845 // g_cells[cell_circular].car = cstring_to_list (scm_circular.name);
846 // g_cells[cell_begin].car = cstring_to_list (scm_begin.name);
847 #endif
848
849   // a = acons (cell_symbol_mes_version, MAKE_STRING (cstring_to_list (VERSION)), a);
850   // a = acons (cell_symbol_mes_prefix, MAKE_STRING (cstring_to_list (PREFIX)), a);
851
852   a = acons (cell_symbol_dot, cell_dot, a);
853   a = acons (cell_symbol_begin, cell_begin, a);
854   a = acons (cell_closure, a, a);
855
856   // a = acons (cell_symbol_call_with_current_continuation, cell_call_with_current_continuation, a);
857   // a = acons (cell_symbol_sc_expand, cell_f, a);
858
859   return a;
860 }
861
862 SCM
863 make_closure (SCM args, SCM body, SCM a)
864 {
865   return make_cell (tmp_num_ (CLOSURE), cell_f, cons (cons (cell_circular, a), cons (args, body)));
866 }
867
868 SCM
869 mes_environment () ///((internal))
870 {
871   SCM a = 0;
872   a = mes_symbols ();
873   a = mes_g_stack (a);
874   return a;
875 }
876
877 SCM
878 mes_builtins (SCM a)
879 {
880 #if 0
881   //__GNUC__
882 //#include "mes.i"
883
884 // #include "lib.i"
885 // #include "math.i"
886 // #include "posix.i"
887 // #include "reader.i"
888
889 // #include "lib.environment.i"
890 // #include "math.environment.i"
891 // #include "mes.environment.i"
892 // #include "posix.environment.i"
893 // #include "reader.environment.i"
894 #else
895
896 scm_make_cell.cdr = g_function;
897 g_functions[g_function++] = fun_make_cell;
898 cell_make_cell = g_free++;
899  g_cells[cell_make_cell] = scm_make_cell;
900  
901 scm_cons.cdr = g_function;
902 g_functions[g_function++] = fun_cons;
903 cell_cons = g_free++;
904 g_cells[cell_cons] = scm_cons;
905  
906 scm_car.cdr = g_function;
907 g_functions[g_function++] = fun_car;
908 cell_car = g_free++;
909 g_cells[cell_car] = scm_car;
910  
911 scm_cdr.cdr = g_function;
912 g_functions[g_function++] = fun_cdr;
913 cell_cdr = g_free++;
914 g_cells[cell_cdr] = scm_cdr;
915
916 // scm_make_cell.string = cstring_to_list (scm_make_cell.name);
917 // g_cells[cell_make_cell].string = MAKE_STRING (scm_make_cell.string);
918 // a = acons (make_symbol (scm_make_cell.string), cell_make_cell, a);
919
920 // scm_cons.string = cstring_to_list (scm_cons.name);
921 // g_cells[cell_cons].string = MAKE_STRING (scm_cons.string);
922 // a = acons (make_symbol (scm_cons.string), cell_cons, a);
923
924 // scm_car.string = cstring_to_list (scm_car.name);
925 // g_cells[cell_car].string = MAKE_STRING (scm_car.string);
926 // a = acons (make_symbol (scm_car.string), cell_car, a);
927
928 // scm_cdr.string = cstring_to_list (scm_cdr.name);
929 // g_cells[cell_cdr].string = MAKE_STRING (scm_cdr.string);
930 // a = acons (make_symbol (scm_cdr.string), cell_cdr, a);
931 #endif
932   return a;
933 }
934
935 SCM
936 bload_env (SCM a) ///((internal))
937 {
938   g_stdin = open ("module/mes/read-0.mo", 0);
939 #if __GNUC__
940   //FIXME GNUC
941   //g_stdin = g_stdin ? g_stdin : fopen (PREFIX "module/mes/read-0.mo", "r");
942 #endif
943   char *p = (char*)g_cells;
944   assert (getchar () == 'M');
945   assert (getchar () == 'E');
946   assert (getchar () == 'S');
947   g_stack = getchar () << 8;
948   g_stack += getchar ();
949   int c = getchar ();
950   while (c != EOF)
951     {
952       *p++ = c;
953       c = getchar ();
954     }
955   g_free = (p-(char*)g_cells) / sizeof (struct scm);
956   gc_peek_frame ();
957   g_symbols = r1;
958   g_stdin = STDIN;
959   r0 = mes_builtins (r0);
960   return r2;
961 }
962
963 SCM
964 fill ()
965 {
966   TYPE (0) = 0x6c6c6168;
967   CAR (0) = 0x6a746f6f;
968   CDR (0) = 0x00002165;
969
970   TYPE (1) = SYMBOL;
971   CAR (1) = 0x2d2d2d2d;
972   CDR (1) = 0x3e3e3e3e;
973
974   TYPE (9) = 0x2d2d2d2d;
975   CAR (9) = 0x2d2d2d2d;
976   CDR (9) = 0x3e3e3e3e;
977
978   // (cons 0 1)
979   TYPE (10) = PAIR;
980   CAR (10) = 11;
981   CDR (10) = 12;
982
983   TYPE (11) = TFUNCTION;
984   CAR (11) = 0x58585858;
985   // 0 = make_cell
986   // 1 = cons
987   // 2 = car
988   CDR (11) = 1;
989
990   TYPE (12) = PAIR;
991   CAR (12) = 13;
992   //CDR (12) = 1;
993   CDR (12) = 14;
994
995   TYPE (13) = NUMBER;
996   CAR (13) = 0x58585858;
997   CDR (13) = 0;
998
999   TYPE (14) = PAIR;
1000   CAR (14) = 15;
1001   CDR (14) = 1;
1002
1003   TYPE (15) = NUMBER;
1004   CAR (15) = 0x58585858;
1005   CDR (15) = 1;
1006
1007   return 0;
1008 }
1009
1010 SCM
1011 display_ (SCM x)
1012 {
1013   //puts ("<display>\n");
1014   switch (TYPE (x))
1015     {
1016     case CHAR:
1017       {
1018         //puts ("<char>\n");
1019         puts ("#\\");
1020         putchar (VALUE (x));
1021         break;
1022       }
1023     case TFUNCTION:
1024       {
1025         //puts ("<function>\n");
1026         if (VALUE (x) == 0)
1027           puts ("make-cell");
1028         if (VALUE (x) == 1)
1029           puts ("cons");
1030         if (VALUE (x) == 2)
1031           puts ("car");
1032         if (VALUE (x) == 3)
1033           puts ("cdr");
1034         break;
1035       }
1036     case NUMBER:
1037       {
1038         //puts ("<number>\n");
1039 #if __GNUC__
1040         putchar (48 + VALUE (x));
1041 #else
1042         int i;
1043         i = VALUE (x);
1044         i = i + 48;
1045         putchar (i);
1046 #endif
1047         break;
1048       }
1049     case PAIR:
1050       {
1051         //puts ("<pair>\n");
1052         //if (cont != cell_f) puts "(");
1053         puts ("(");
1054         if (x && x != cell_nil) display_ (CAR (x));
1055         if (CDR (x) && CDR (x) != cell_nil)
1056           {
1057 #if __GNUC__
1058             if (TYPE (CDR (x)) != PAIR)
1059               puts (" . ");
1060 #else
1061             int c;
1062             c = CDR (x);
1063             c = TYPE (c);
1064             if (c != PAIR)
1065               puts (" . ");
1066 #endif
1067             display_ (CDR (x));
1068           }
1069         //if (cont != cell_f) puts (")");
1070         puts (")");
1071         break;
1072       }
1073     default:
1074       {
1075         //puts ("<default>\n");
1076         puts ("_");
1077         break;
1078       }
1079     }
1080   return 0;
1081 }
1082
1083 SCM
1084 simple_bload_env (SCM a) ///((internal))
1085 {
1086   puts ("reading: ");
1087   char *mo = "module/mes/hack-32.mo";
1088   puts (mo);
1089   puts ("\n");
1090   g_stdin = open (mo, 0);
1091   if (g_stdin < 0) {eputs ("no such file: module/mes/read-0-32.mo\n");return 1;} 
1092
1093   char *p = (char*)g_cells;
1094   int c;
1095
1096 #if 0
1097   //__GNUC__
1098   puts ("fd: ");
1099   puts (itoa (g_stdin));
1100   puts ("\n");
1101 #endif
1102
1103   assert (getchar () == 'M');
1104   assert (getchar () == 'E');
1105   assert (getchar () == 'S');
1106   puts (" *GOT MES*\n");
1107   g_stack = getchar () << 8;
1108   g_stack += getchar ();
1109
1110 #if __GNUC__
1111   puts ("stack: ");
1112   puts (itoa (g_stack));
1113   puts ("\n");
1114 #endif
1115
1116   c = getchar ();
1117   while (c != -1)
1118     {
1119       *p++ = c;
1120       c = getchar ();
1121       putchar (c);
1122     }
1123
1124   puts ("read done\n");
1125
1126   g_free = (p-(char*)g_cells) / sizeof (struct scm);
1127   
1128   if (g_free != 15) exit (33);
1129   
1130 #if 0
1131   gc_peek_frame ();
1132   g_symbols = r1;
1133 #else
1134   g_symbols = 1;
1135 #endif
1136   g_stdin = STDIN;
1137   r0 = mes_builtins (r0);
1138   
1139   if (g_free != 19) exit (34);
1140   
1141 #if __GNUC__
1142   puts ("cells read: ");
1143   puts (itoa (g_free));
1144   puts ("\n");
1145
1146   puts ("symbols: ");
1147   puts (itoa (g_symbols));
1148   puts ("\n");
1149   // display_ (g_symbols);
1150   // puts ("\n");
1151 #endif
1152
1153   display_ (10);
1154   puts ("\n");
1155
1156   fill ();
1157   r2 = 10;
1158
1159   if (TYPE (12) != PAIR)
1160     exit (33);
1161
1162   puts ("program[");
1163 #if __GNUC__
1164   puts (itoa (r2));
1165 #endif
1166   puts ("]: ");
1167
1168   display_ (r2);
1169   //display_ (14);
1170   puts ("\n");
1171
1172   r0 = 1;
1173   //r2 = 10;
1174   return r2;
1175 }
1176
1177 char const*
1178 string_to_cstring (SCM s)
1179 {
1180   static char buf[1024];
1181   char *p = buf;
1182   s = STRING(s);
1183   while (s != cell_nil)
1184     {
1185       *p++ = VALUE (car (s));
1186       s = cdr (s);
1187     }
1188   *p = 0;
1189   return buf;
1190 }
1191
1192 SCM
1193 stderr_ (SCM x)
1194 {
1195   //SCM write;
1196 #if __NYACC__ || FIXME_NYACC
1197   if (TYPE (x) == TSTRING)
1198 // #else
1199 //   if (TYPE (x) == STRING)
1200 #endif
1201     eputs (string_to_cstring (x));
1202   // else if ((write = assq_ref_env (cell_symbol_write, r0)) != cell_undefined)
1203   //   apply (assq_ref_env (cell_symbol_display, r0), cons (x, cons (MAKE_NUMBER (2), cell_nil)), r0);
1204 #if __NYACC__ || FIXME_NYACC
1205   else if (TYPE (x) == SPECIAL || TYPE (x) == TSTRING || TYPE (x) == SYMBOL)
1206 // #else
1207 //   else if (TYPE (x) == SPECIAL || TYPE (x) == STRING || TYPE (x) == SYMBOL)
1208 #endif
1209     eputs (string_to_cstring (x));
1210   else if (TYPE (x) == NUMBER)
1211     eputs (itoa (VALUE (x)));
1212   else
1213     eputs ("display: undefined\n");
1214   return cell_unspecified;
1215 }
1216
1217 int
1218 main (int argc, char *argv[])
1219 {
1220   puts ("Hello cons-mes!\n");
1221   if (argc > 1 && !strcmp (argv[1], "--help")) return eputs ("Usage: mes [--dump|--load] < FILE");
1222 #if __GNUC__
1223   if (argc > 1 && !strcmp (argv[1], "--version")) {eputs ("Mes ");return eputs (VERSION);};
1224 #else
1225   if (argc > 1 && !strcmp (argv[1], "--version")) {eputs ("Mes ");return eputs ("0.4");};
1226 #endif
1227   g_stdin = STDIN;
1228
1229   r0 = mes_environment ();
1230   
1231 #if MES_MINI
1232   SCM program = simple_bload_env (r0);
1233 #else  
1234   SCM program = (argc > 1 && !strcmp (argv[1], "--load"))
1235     ? bload_env (r0) : load_env (r0);
1236   if (argc > 1 && !strcmp (argv[1], "--dump")) return dump ();
1237 #endif
1238
1239 #if __GNUC__
1240   puts ("g_free=");
1241   puts (itoa(g_free));
1242   puts ("\n");
1243 #endif
1244
1245   push_cc (r2, cell_unspecified, r0, cell_unspecified);
1246
1247 #if __GNUC__
1248
1249   puts ("g_free=");
1250   puts (itoa(g_free));
1251   puts ("\n");
1252
1253   puts ("g_stack=");
1254   puts (itoa(g_stack));
1255   puts ("\n");
1256
1257   puts ("r0=");
1258   puts (itoa(r0));
1259   puts ("\n");
1260
1261   puts ("r1=");
1262   puts (itoa(r1));
1263   puts ("\n");
1264
1265   puts ("r2=");
1266   puts (itoa(r2));
1267   puts ("\n");
1268
1269   puts ("r3=");
1270   puts (itoa(r3));
1271   puts ("\n");
1272 #endif
1273
1274   r3 = cell_vm_apply;
1275   r1 = eval_apply ();
1276   display_ (r1);
1277
1278   eputs ("\n");
1279 #if !MES_MINI
1280   gc (g_stack);
1281 #endif
1282 #if __GNUC__
1283   if (g_debug)
1284     {
1285       eputs ("\nstats: [");
1286       eputs (itoa (g_free));
1287       eputs ("]\n");
1288     }
1289 #endif
1290   return 0;
1291 }
1292
1293 #if __GNUC__
1294 void
1295 _start ()
1296 {
1297   int r;
1298   asm (
1299        "mov %%ebp,%%eax\n\t"
1300        "addl $8,%%eax\n\t"
1301        "push %%eax\n\t"
1302
1303        "mov %%ebp,%%eax\n\t"
1304        "addl $4,%%eax\n\t"
1305        "movzbl (%%eax),%%eax\n\t"
1306        "push %%eax\n\t"
1307
1308        "call main\n\t"
1309        "movl %%eax,%0\n\t"
1310        : "=r" (r)
1311        : //no inputs "" (&main)
1312        );
1313   exit (r);
1314 }
1315 #endif