4823bc6218449792c30144e6111e56dce1d3ca84
[mes.git] / scaffold / t.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 #if __GNUC__
22 void
23 exit (int code)
24 {
25   asm (
26        "movl %0,%%ebx\n\t"
27        "movl $1,%%eax\n\t"
28        "int  $0x80"
29        : // no outputs "=" (r)
30        : "" (code)
31        );
32   // not reached
33   exit (0);
34 }
35
36 void
37 write (int fd, char const* s, int n)
38 {
39   int r;
40   //syscall (SYS_write, fd, s, n));
41   asm (
42        "mov %0,%%ebx\n\t"
43        "mov %1,%%ecx\n\t"
44        "mov %2,%%edx\n\t"
45
46        "mov $0x4,%%eax\n\t"
47        "int $0x80\n\t"
48        : // no outputs "=" (r)
49        : "" (fd), "" (s), "" (n)
50        : "eax", "ebx", "ecx", "edx"
51        );
52 }
53
54 #define STDOUT 1
55
56 typedef long size_t;
57 size_t
58 strlen (char const* s)
59 {
60   int i = 0;
61   while (s[i]) i++;
62   return i;
63 }
64
65 int
66 puts (char const* s)
67 {
68   //write (STDOUT, s, strlen (s));
69   //int i = write (STDOUT, s, strlen (s));
70   int i = strlen (s);
71   write (1, s, i);
72   return 0;
73 }
74
75 int
76 putchar (int c)
77 {
78   //write (STDOUT, s, strlen (s));
79   //int i = write (STDOUT, s, strlen (s));
80   write (1, (char*)&c, 1);
81   return 0;
82 }
83
84 int
85 strcmp (char const* a, char const* b)
86 {
87   while (*a && *b && *a == *b) {a++;b++;}
88   return *a - *b;
89 }
90 #endif
91
92 struct scm {
93   int type;
94   int car;
95   int cdr;
96 };
97
98 char arena[200];
99 struct scm *g_cells = arena;
100 char *g_chars = arena;
101 char buf[200];
102
103 int foo () {puts ("t: foo\n"); return 0;};
104 int bar () {puts ("t: bar\n"); return 0;};
105 struct function {
106   int (*function) (void);
107   int arity;
108 };
109 struct function g_fun = {&exit, 1};
110 struct function g_foo = {&foo, 1};
111 struct function g_bar = {&bar, 1};
112
113 //void *functions[2];
114 int functions[2];
115
116 struct function g_functions[2];
117 int g_function = 0;
118
119 enum type_t {CHAR, CLOSURE, CONTINUATION, TFUNCTION, KEYWORD, MACRO, NUMBER, PAIR, REF, SPECIAL, TSTRING, SYMBOL, VALUES, TVECTOR, BROKEN_HEART};
120
121 typedef int SCM;
122 int g_free = 3;
123 SCM tmp;
124 SCM tmp_num;
125
126 #if 1
127 int
128 label (int c)
129 {
130  label:
131   if (c == 0) return c;
132   c--;
133   goto label;
134   return 1;
135 }
136
137 int
138 swits (int c)
139 {
140   int x = -1;
141
142   switch (c)
143     {
144     case CHAR: {goto next;}
145     case 1: {goto next;}
146     case 2: {goto next;}
147     default: {goto next;}
148     }
149
150   return 1;
151  next:
152   switch (c)
153     {
154       case 0:
155         {
156           x = 0;
157           c = 34;
158           break;
159         }
160       case 1:
161         {
162           x = 1;
163           break;
164         }
165       default:
166         {
167           x = 2;
168           break;
169         }
170     }
171   return x;
172 }
173
174 int g = 48;
175 int
176 get ()
177 {
178   int i = g;
179   g++;
180   return i;
181 }
182
183 int
184 read_test ()
185 {
186   puts ("read test\n");
187   char *p = (char*)g_chars;
188   int i = 0;
189   puts ("t: read 0123456789\n");
190   int c = get ();
191   while (i < 10) {
192     *p++ = c;
193     putchar (c);
194     c = get ();
195     i++;
196   }
197   puts ("\n");
198   if (strcmp (g_chars, "0123456789")) return 1;
199   return 0;
200 }
201
202 int
203 math_test ()
204 {
205   int i;
206   puts ("t: 4/2=");
207   i = 4 / 2;
208   if (i!=2) return 1;
209   i += 48;
210   putchar (i);
211   puts ("\n");
212   return read_test ();
213 }
214
215 int ARENA_SIZE = 200;
216 #define TYPE(x) (g_cells[x].type)
217 #define CAR(x) g_cells[x].car
218 #define CDR(x) g_cells[x].cdr
219 #define VALUE(x) g_cells[x].cdr
220
221 struct scm scm_fun = {TFUNCTION,0,0};
222 SCM cell_fun;
223
224 SCM
225 alloc (int n)
226 {
227   SCM x = g_free;
228   g_free += n;
229   return x;
230 }
231
232 SCM
233 make_cell (SCM type, SCM car, SCM cdr)
234 {
235   SCM x = alloc (1);
236   TYPE (x) = VALUE (type);
237   if (VALUE (type) == CHAR || VALUE (type) == NUMBER) {
238     if (car) CAR (x) = CAR (car);
239     if (cdr) CDR(x) = CDR(cdr);
240   }
241   else if (VALUE (type) == TFUNCTION) {
242     if (car) CAR (x) = car;
243     if (cdr) CDR(x) = CDR(cdr);
244   }
245   else {
246     CAR (x) = car;
247     CDR(x) = cdr;
248   }
249   return x;
250 }
251
252 SCM
253 make_cell_test ()
254 {
255   VALUE (tmp_num) = PAIR;
256   make_cell (tmp_num, 0, 1);
257   return math_test ();
258 }
259
260 SCM
261 make_tmps_test (struct scm* cells)
262 {
263   puts ("t: tmp = g_free++\n");
264   tmp = g_free++;
265   puts ("t: cells[tmp].type = CHAR\n");
266   cells[tmp].type = CHAR;
267   tmp_num = g_free++;
268   cells[tmp_num].type = NUMBER;
269
270   return make_cell_test();
271 }
272
273 int
274 struct_test ()
275 {
276   g_cells[3].type = 0x64;
277   if (g_cells[3].type != 0x64)
278     return g_cells[3].type;
279
280   TYPE (4) = 4;
281   if (TYPE (4) != 4)
282     return 4;
283   
284   CDR (3) = 0x22;
285   CDR (4) = 0x23;
286   if (CDR (3) != 0x22)
287     return CDR (3);
288
289   puts ("t: struct fun = {&exit, 1};\n");
290   struct function fun = {&exit, 1};
291
292   puts ("t: g_fun.arity != 1;\n");
293   if (g_fun.arity != 1) return 1;
294
295   puts ("t: g_fun.function != exit;\n");
296   if (g_fun.function != &exit) return 1;
297
298   puts ("t: fun.arity != 1;\n");
299   if (fun.arity != 1) return 1;
300
301   puts ("t: fun.function != exit;\n");
302   if (fun.function != &exit) return 1;
303
304   puts ("t: g_functions[g_function++] = g_foo;\n");
305   g_functions[g_function++] = g_foo;
306
307   int fn = 0;
308   puts ("t: g_functions[g_cells[fn].cdr].arity\n");
309   if (!g_functions[g_cells[fn].cdr].arity) return 1;
310
311   int (*functionx) (void) = 0;
312   functionx = g_functions[0].function;
313   puts ("t: *functionx == foo\n");
314   if (*functionx != foo) return 11;
315
316   puts ("t: (*functionx) () == foo\n");
317   if ((*functionx) () != 0) return 12;
318
319   fn++;
320   g_functions[0] = g_bar;
321   if (g_cells[fn].cdr != 0) return 13;
322   puts ("t: g_functions[g_cells[fn].cdr].function\n");
323   functionx = g_functions[g_cells[fn].cdr].function;
324   puts ("t: *functionx == bar\n");
325   if (*functionx != bar) return 15;
326   puts ("t: (*functionx) () == bar\n");
327   if ((*functionx) () != 0) return 16;
328
329   scm_fun.cdr = g_function;
330   g_functions[g_function++] = g_fun;
331   cell_fun = g_free++;
332   g_cells[cell_fun] = scm_fun;
333
334   return make_tmps_test  (g_cells);
335 }
336
337 int
338 test (char *p)
339 {
340   int f = 0;
341   int t = 1;
342   int one = 1;
343   char c = 'C';
344   int i=0;
345
346   char *x = arena;
347   char *y = g_chars;
348
349   puts ("t: if (0)\n");
350   if (0) return 1;
351
352   if (i)
353     return 1;
354   else
355     puts ("t: else 1\n");
356
357   if (i)
358     puts ("0");
359   else if (i == 1)
360     puts ("1");
361   else
362     puts ("t: else if 2\n");
363
364   puts ("t: if (f)\n");
365   if (f) return 1;
366
367   puts ("t: if (one > 1)\n");
368   if (one > 1) return 1;
369
370   puts ("t: if (one < 0)\n");
371   if (one < 0) return 1;
372
373   puts ("t: if (strlen (\"\"))\n");
374   if (strlen ("")) return 1;
375
376   puts ("t: if (strlen (p) != 4)\n");
377   if (strlen (p) != 4) return 1;
378
379   puts ("t: if (!strlen (\".\"))\n");
380   if (!strlen (".")) return 1;
381
382   puts ("t: if (strcmp (p, \"foo\"))\n");
383   if (!strcmp (p, "foo")) return 1;
384
385   puts ("t: if (strcmp (p, \"t.c\\n\"))\n");
386   if (strcmp (p, "t.c\n")) return 1;
387
388   puts ("t: if (!1)\n");
389   if (!1) return 1;
390
391   puts ("t: if (one == 0)\n");
392   if (one == 0) return 1;
393
394   puts ("t: if (f != 0)\n");
395   if (one != 1) return 1;
396
397   puts ("t: if (1 && 0)\n");
398   if (1 && 0) return 1;
399
400   puts ("t: if (!t && f)\n");
401   if (!t && f) return 1;
402
403   puts ("t: if (t && !one)\n");
404   if (t && !one) return 1;
405
406   puts ("t: if (f || !t)\n");
407   if (f || !t) return 1;
408
409   puts ("t: if (i++)\n");
410   if (i++) return 1;
411
412   puts ("t: if (--i)\n");
413   if (--i) return 1;
414
415   puts ("t: i += 2\n");
416   i += 2;
417   if (i != 2) return 1;
418
419   puts ("t: i -= 2\n");
420   i -= 2;
421   if (i != 0) return 1;
422
423   puts ("t: (one == 1) ?\n");
424   (one == 1) ? 1 : exit (1);
425
426   puts ("t: (f) ?\n");
427   (f) ? exit (1) : 1;
428
429   puts ("t: *g_chars != 'A'\n");
430   arena[0] = 'A';
431   if (*g_chars != 'A') return 1;
432
433   puts ("t: *x != 'A'\n");
434   if (*x != 'A') return 1;
435
436   puts ("t: *y != 'A'\n");
437   if (*y != 'A') return 1;
438
439   puts ("t: *x != 'Q'\n");
440   g_chars[0] = 'Q';
441   if (*x != 'Q') return 1;
442
443   puts ("t: *x++ != 'C'\n");
444   *x++ = c;
445   if (*g_chars != 'C') return 1;
446
447   puts ("t: goto label\n");
448   if (label (1) != 0) return 1;
449
450   puts ("t: switch 0\n");
451   if (swits (0) != 0) return swits (0);
452
453   puts ("t: switch 1\n");
454   if (swits (1) != 1) return 1;
455
456   puts ("t: switch -1\n");
457   if (swits (-1) != 2) return 1;
458
459   puts ("t: if (1)\n");
460   if (1) goto ok0;
461   return 1;
462  ok0:
463   
464   puts ("t: if (0); return 1; else;\n");
465   if (0) return 1; else goto ok01;
466  ok01:
467
468   puts ("t: if (t)\n");
469   if (t) goto ok1;
470   return 1;
471  ok1:
472
473   puts ("t: if (one > 0)\n");
474   if (one > 0) goto ok2;
475   return 1;
476  ok2:
477
478   puts ("t: if (one < 2)\n");
479   //if (one < 2) goto ok3;
480   if (one < 0x44) goto ok3;
481   return 1;
482  ok3:
483
484   puts ("t: if (strlen (\".\"))\n");
485   if (strlen (".")) goto ok4;
486   return 1;
487  ok4:
488
489   puts ("t: if (strlen (p) == 4)\n");
490   if (strlen (p) == 4) goto ok40;
491  ok40:
492
493   puts ("t: if (!strcmp (p, \"t.c\\n\"))\n");
494   if (!strcmp (p, "t.c\n")) goto ok41;
495   return 1;
496  ok41:
497
498   puts ("t: if (strcmp (p, \"foo\"))\n");
499   if (strcmp (p, "foo")) goto ok42;
500   return 1;
501  ok42:
502
503   puts ("t: if (!0)\n");
504   if (!0) goto ok5;
505   return 1;
506  ok5:
507
508   puts ("t: if (one == 1)\n");
509   if (one == 1) goto ok6;
510   return 1;
511  ok6:
512
513   puts ("t: if (one != 0)\n");
514   if (one != 0) goto ok7;
515   return 1;
516  ok7:
517
518   puts ("t: if (1 && !0)\n");
519   if (1 && !0) goto ok8;
520   return 1;
521  ok8:
522
523   puts ("t: if (f || t)\n");
524   if (f || t) goto ok80;
525   return 1;
526  ok80:
527
528   puts ("t: if (++i)\n");
529   if (++i) goto ok9;
530   return 1;
531  ok9:
532
533   puts ("t: if (i--)\n");
534   if (i--) goto ok10;
535   return 1;
536  ok10:
537
538   puts ("t: *g_chars == 'B'\n");
539   arena[0] = 'B';
540   if (*g_chars == 'B') goto ok11;
541   return 1;
542   ok11:
543
544   puts ("t: *x == 'B'\n");
545   x = arena;
546   if (*x == 'B') goto ok12;
547   return 1;
548  ok12:
549
550   puts ("t: *y == 'B'\n");
551   y = g_chars;
552   if (*y == 'B') goto ok13;
553   return 1;
554  ok13:
555
556   puts ("t: *x == 'R'\n");
557   g_chars[0] = 'R';
558   if (*x == 'R') goto ok14;
559   return 1;
560  ok14:
561
562   puts ("t: *x++ == 'C'\n");
563   *x++ = c;
564   if (*g_chars == 'C') goto ok15;
565   return 1;
566  ok15:
567
568   puts ("t: for (i=1; i<5; ++i)\n");
569   for (i=1; i<5; ++i);
570   if (i != 5) return i;
571
572   return struct_test ();
573 }
574 #endif
575
576 int
577 main (int argc, char *argv[])
578 {
579  //  main:
580  //  puts ("t.c\n");
581  //  if (argc == 0x22) return 11;
582  //  argc = 0x22;
583  //  goto main;
584  //  switch (0)
585  //    {
586  //    case 0: {goto next;}
587  //    // case 1: {goto next;}
588  //    // case 2: {goto next;}
589  //    // default: {goto next;}
590  //    }
591
592  //  return 1;
593  // next:
594   char *p = "t.c\n";
595   puts ("t.c\n");
596
597   if (argc > 1 && !strcmp (argv[1], "--help")) return 1;
598   puts ("t: if (argc > 1 && !strcmp (argv[1], \"--help\")\n");
599
600   // FIXME mescc?!
601   if (argc > 1) if (!strcmp (argv[1], "--help")) return 1;
602
603   return test (p);
604
605   return 22;
606 }
607
608 #if __GNUC__
609 void
610 _start ()
611 {
612   // int r=main ();
613   // exit (r);
614   int r;
615   asm (
616        "mov %%ebp,%%eax\n\t"
617        "addl $8,%%eax\n\t"
618        "push %%eax\n\t"
619
620        "mov %%ebp,%%eax\n\t"
621        "addl $4,%%eax\n\t"
622        "movzbl (%%eax),%%eax\n\t"
623        "push %%eax\n\t"
624
625        "call main\n\t"
626        
627        "movl %%eax,%0\n\t"
628        : "=r" (r)
629        : //no inputs "" (&main)
630        );
631   exit (r);
632 }
633 #endif