initial commit
[mim.git] / main.c
1 /*
2 Copyright (C) 2017-2018 Keziah Wesley
3
4 You can redistribute and/or modify this file under the terms of the
5 GNU Affero General Public License as published by the Free Software
6 Foundation, either version 3 of the License, or (at your option) any
7 later version.
8
9 This file is distributed in the hope that it will be useful, but
10 WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Affero General Public License for more details.
13
14 You should have received a copy of the GNU Affero General Public
15 License along with this file. If not, see
16 <http://www.gnu.org/licenses/>.
17 */
18
19 #include <assert.h>
20 #include <stdint.h>
21 #include <stdio.h>
22 #include <string.h>
23
24 enum {
25   PT_UNBOUND,
26   PT_FIX = (1 << 16),
27   PT_MASK = (0x7fff << 16),
28 };
29
30 enum {
31   TT_UNBOUND = PT_UNBOUND,
32   TT_FIX = PT_FIX,
33 };
34
35 enum {
36   B_IF,
37   B_IF_NOT,
38 };
39
40 enum {
41   R_STACK = 0xff,
42 };
43
44 typedef struct {
45   uint32_t type;
46   uint32_t _stuff;
47   union {
48     int64_t fix;
49   };
50 } object;
51
52 inline static int64_t GETFIX (object o) {
53   assert ((o.type & PT_MASK) == PT_FIX);
54   return o.fix;
55 }
56 inline static object NEWFIX (int64_t v) {
57   return (object){ .type = TT_FIX, .fix = (v) };
58 }
59 #define RESULT(i) (&bp[(p[i] == R_STACK) ? sp++ : p[i]])
60 #define JUMP(off) do { p = (off < 0) ? oldp + off : p + off; } while (0)
61
62 int snprint_op_disasm (char ** buf, size_t outlen, const uint8_t ** p, size_t inlen);
63 void run (const uint8_t * op, const uint8_t * p, object * bp, int sp);
64
65 static void trace(const uint8_t * p0, const uint8_t * p)
66 {
67   char buf[512];
68   char *b = buf;
69   b += snprintf(buf, 512, "%ld: ", p-p0);
70   int n = snprint_op_disasm (&b, 512, &p, (size_t)-1);
71   assert (!n);
72   printf(buf);
73 }
74
75 enum {
76   EOKAY,
77   EBADOPCODE,
78   EBADOPARGS,
79 };
80
81 #define TRACE(p0, p) trace(p0, p)
82
83 #include "gen.c"
84
85 int main ()
86 {
87   // hand-assembled iterative factorial:
88   uint8_t locl_N = 0;
89   uint8_t locl_TMP1 = 1;
90   uint8_t progn[] = {
91     I_GRTRB, locl_N, 1, B_IF, 1,             //      <GRTR? N 1 + LOOP>
92     I_HALT,                                  //      <HALT>
93     I_MUL, locl_N, locl_TMP1, locl_TMP1,     // LOOP <MUL N TMP1 = TMP1>
94     I_SUBB, locl_N, 1, locl_N,               //      <SUB N 1 = N>
95     I_GRTRB, locl_N, 1, B_IF, (uint8_t)-8,   //      <GRTR? N 1 + LOOP>
96     I_HALT,                                  //      <HALT>
97   };
98
99   object stack[128];
100   memset(stack, '\0', 128 * sizeof(*stack));
101   stack[0] = NEWFIX(7);
102   stack[1] = NEWFIX(1);
103
104   run (progn, progn, stack, 2);
105   printf("%lu", GETFIX(stack[1]));
106   return 0;
107 }