39884362c973e0c233fd1eab5e05c06099a7c9df
[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 int test (char *p);
91 #endif
92
93 // struct scm {
94 //   int type;
95 //   int car;
96 //   int cdr;
97 // };
98
99 char arena[20];
100 char *g_cells = arena;
101
102 int
103 main (int argc, char *argv[])
104 {
105   char *p = "t.c\n";
106   puts ("t.c\n");
107
108   if (argc > 1 && !strcmp (argv[1], "--help")) return 1;
109   puts ("t: if (argc > 1 && !strcmp (argv[1], \"--help\")\n");
110
111   // FIXME mescc?!
112   if (argc > 1) if (!strcmp (argv[1], "--help")) return 1;
113
114   return test (p);
115   return 22;
116 }
117
118 int
119 swits (int c)
120 {
121   int x = -1;
122   switch (c)
123     {
124       case 0:
125         {
126           x = 0;
127           c = 34;
128           break;
129         }
130       case 1:
131         {
132           x = 1;
133           break;
134         }
135       default:
136         {
137           x = 2;
138           break;
139         }
140     }
141   return x;
142 }
143
144 int
145 test (char *p)
146 {
147   int f = 0;
148   int t = 1;
149   int one = 1;
150   char c = 'C';
151
152   puts ("t: if (0)\n");
153   if (0) return 1;
154
155   puts ("t: if (f)\n");
156   if (f) return 1;
157
158   puts ("t: if (one > 1)\n");
159   if (one > 1) return 1;
160
161   puts ("t: if (one < 0)\n");
162   if (one < 0) return 1;
163
164   puts ("t: if (strlen (\"\"))\n");
165   if (strlen ("")) return 1;
166
167   puts ("t: if (strlen (p) != 4)\n");
168   if (strlen (p) != 4) return 1;
169
170   puts ("t: if (!strlen (\".\"))\n");
171   if (!strlen (".")) return 1;
172
173   puts ("t: if (strcmp (p, \"foo\"))\n");
174   if (!strcmp (p, "foo")) return 1;
175
176   puts ("t: if (strcmp (p, \"t.c\\n\"))\n");
177   if (strcmp (p, "t.c\n")) return 1;
178
179   puts ("t: if (!1)\n");
180   if (!1) return 1;
181
182   puts ("t: if (one == 0)\n");
183   if (one == 0) return 1;
184
185   puts ("t: if (f != 0)\n");
186   if (one != 1) return 1;
187
188   puts ("t: if (1 && 0)\n");
189   if (1 && 0) return 1;
190
191   puts ("t: if (!t && f)\n");
192   if (!t && f) return 1;
193
194   puts ("t: if (t && !one)\n");
195   if (t && !one) return 1;
196
197   int i=0;
198   puts ("t: if (i++)\n");
199   if (i++) return 1;
200
201   puts ("t: if (--i)\n");
202   if (--i) return 1;
203
204   puts ("t: (one == 1) ?\n");
205   (one == 1) ? 1 : exit (1);
206
207   puts ("t: (f) ?\n");
208   (f) ? exit (1) : 1;
209
210   puts ("t: *g_cells != 'A'\n");
211   arena[0] = 'A';
212   if (*g_cells != 'A') return 1;
213
214   puts ("t: *x != 'A'\n");
215   char *x = g_cells;
216   if (*x != 'A') return 1;
217
218   puts ("t: *x != 'Q'\n");
219   g_cells[0] = 'Q';
220   if (*x != 'Q') return 1;
221
222   puts ("t: *x++ != 'C'\n");
223   *x++ = c;
224   if (*g_cells != 'C') return 1;
225
226   puts ("t: switch 0\n");
227   if (swits (0) != 0) return swits (0);
228
229   puts ("t: switch 1\n");
230   if (swits (1) != 1) return 1;
231
232   puts ("t: switch -1\n");
233   if (swits (-1) != 2) return 1;
234
235   puts ("t: if (1)\n");
236   if (1) goto ok0;
237   return 1;
238  ok0:
239   
240   puts ("t: if (t)\n");
241   if (t) goto ok1;
242   return 1;
243  ok1:
244
245   puts ("t: if (one > 0)\n");
246   if (one > 0) goto ok2;
247   return 1;
248  ok2:
249
250   puts ("t: if (one < 2)\n");
251   if (one < 2) goto ok3;
252   return 1;
253  ok3:
254
255   puts ("t: if (strlen (\".\"))\n");
256   if (strlen (".")) goto ok4;
257   return 1;
258  ok4:
259
260   puts ("t: if (strlen (p) == 4)\n");
261   if (strlen (p) == 4) goto ok40;
262  ok40:
263
264   puts ("t: if (!strcmp (p, \"t.c\\n\"))\n");
265   if (!strcmp (p, "t.c\n")) goto ok41;
266   return 1;
267  ok41:
268
269   puts ("t: if (strcmp (p, \"foo\"))\n");
270   if (strcmp (p, "foo")) goto ok42;
271   return 1;
272  ok42:
273
274   puts ("t: if (!0)\n");
275   if (!0) goto ok5;
276   return 1;
277  ok5:
278
279   puts ("t: if (one == 1)\n");
280   if (one == 1) goto ok6;
281   return 1;
282  ok6:
283
284   puts ("t: if (one != 0)\n");
285   if (one != 0) goto ok7;
286   return 1;
287  ok7:
288
289   puts ("t: if (1 && !0)\n");
290   if (1 && !0) goto ok8;
291   return 1;
292  ok8:
293
294   puts ("t: if (++i)\n");
295   if (++i) goto ok9;
296   return 1;
297  ok9:
298
299   puts ("t: if (i--)\n");
300   if (i--) goto ok10;
301   return 1;
302  ok10:
303
304   puts ("t: *g_cells == 'B'\n");
305   arena[0] = 'B';
306   if (*g_cells == 'B') goto ok11;
307   return 1;
308  ok11:
309
310   puts ("t: *x == 'B'\n");
311   x = g_cells;
312   if (*x == 'B') goto ok12;
313   return 1;
314  ok12:
315
316   puts ("t: *x == 'R'\n");
317   g_cells[0] = 'R';
318   x = g_cells;
319   if (*x == 'R') goto ok13;
320   return 1;
321  ok13:
322
323   puts ("t: *x++ == 'C'\n");
324   *x++ = c;
325   if (*g_cells == 'C') goto ok14;
326   return 1;
327  ok14:
328
329   puts ("t: for (i=0; i<4; ++i)\n");
330   for (i=0; i<4; ++i);
331   if (i != 4) return i;
332
333   return 0;
334 }
335
336 #if __GNUC__
337 void
338 _start ()
339 {
340   // int r=main ();
341   // exit (r);
342   int r;
343   asm (
344        "mov %%ebp,%%eax\n\t"
345        "addl $8,%%eax\n\t"
346        "push %%eax\n\t"
347
348        "mov %%ebp,%%eax\n\t"
349        "addl $4,%%eax\n\t"
350        "movzbl (%%eax),%%eax\n\t"
351        "push %%eax\n\t"
352
353        "call main\n\t"
354        
355        "movl %%eax,%0\n\t"
356        : "=r" (r)
357        : //no inputs "" (&main)
358        );
359   exit (r);
360 }
361 #endif