runtime.h 8.82 KB
Newer Older
mb0's avatar
Up.    
mb0 committed
1
/* vim:cindent:ts=2:sw=2:expandtab */
2
3
4
5
6
7

#ifndef __RUNTIME_H
#define __RUNTIME_H

#include <stdlib.h>
#include <stdio.h>
mb0's avatar
mb0 committed
8
9
#include <stdint.h>
#include <stdarg.h>
mb0's avatar
mb0 committed
10
#include <stddef.h>
mb0's avatar
mb0 committed
11
#include <string.h>
12

13
#define __RT_HEAP_SIZE (4*1024)
14

mb0's avatar
mb0 committed
15
#define __CHECK_HEAP(n) /* TODO: check for heap-overflow */
16
#define __ALLOC1() --hp /* TODO: check for heap-overflow */
mb0's avatar
mb0 committed
17
#define __ALLOC0() hp /* TODO: check for heap-overfl(4*1024) */
mb0's avatar
mb0 committed
18
19
20
#define __ALLOCN(n) hp-=n /* TODO: check for heap-overflow */

#define __INVOKE1(o, closure)\
21
  ((__obj(*)(__obj))((o)->label.f))(closure)
22

mb0's avatar
mb0 committed
23
#define __INVOKE2(o, closure, x)\
24
  ((__obj(*)(__obj,__obj))((o)->label.f))(closure, x)
mb0's avatar
mb0 committed
25
26

#define __INVOKE3(o, closure, x, y)\
27
  ((__obj(*)(__obj,__obj,__obj))((o)->label.f))(closure, x, y)
mb0's avatar
mb0 committed
28
29

#define __INVOKE4(o, closure, x, y, z)\
30
  ((__obj(*)(__obj,__obj,__obj,__obj))((o)->label.f))(closure, x, y, z)
mb0's avatar
mb0 committed
31

mb0's avatar
mb0 committed
32
#define __INVOKE5(o, closure, w, x, y, z)\
33
  ((__obj(*)(__obj,__obj,__obj,__obj,__obj))((o)->label.f))(closure, w, x, y, z)
mb0's avatar
mb0 committed
34
35

#define __INVOKE6(o, closure, v, w, x, y, z)\
36
  ((__obj(*)(__obj,__obj,__obj,__obj,__obj,__obj))((o)->label.f))(closure, v, w, x, y, z)
mb0's avatar
mb0 committed
37
38

#define __INVOKE7(o, closure, u, v, w, x, y, z)\
39
40
  ((__obj(*)(__obj,__obj,__obj,__obj,__obj,__obj,__obj))((o)->label.f))(closure, u, v, w, x, y, z)

mb0's avatar
mb0 committed
41
#define __FCALL(f,...) f(__VA_ARGS__)
mb0's avatar
mb0 committed
42

mb0's avatar
mb0 committed
43
44
/** ## Integers */

45
#define __INT_BEGIN(Cname)\
mb0's avatar
mb0 committed
46
  __CHECK_HEAP(1)
47
48

#define __INT_INIT(val)\
mb0's avatar
mb0 committed
49
50
51
  {__objref o = __ALLOC1();\
   o->z.header.tag = __INT;\
   o->z.value = val
52
53
   
#define __INT_END(Cname)\
mb0's avatar
mb0 committed
54
   Cname = __WRAP(o);}
55

mb0's avatar
mb0 committed
56
57
/** ## Labels */

58
#define __LABEL_BEGIN(Cname)\
mb0's avatar
mb0 committed
59
  __CHECK_HEAP(1)
60
61

#define __LABEL_INIT(val)\
mb0's avatar
mb0 committed
62
63
64
  {__objref o = __ALLOC1();\
   o->label.header.tag = __LABEL;\
   o->label.f = (__obj (*)(void)) val
65
66
   
#define __LABEL_END(Cname)\
mb0's avatar
mb0 committed
67
   Cname = __WRAP(o);}
68

mb0's avatar
mb0 committed
69
70
/** ## Closures */

71
#define __CLOSURE_BEGIN(Cname, n)\
mb0's avatar
mb0 committed
72
   __CHECK_HEAP(n+1)
73
74

#define __CLOSURE_ADD(value)\
mb0's avatar
mb0 committed
75
76
   {__objref o = __ALLOC1();\
    *o = *(__UNWRAP(value));}
77
78

#define __CLOSURE_END(Cname, n)\
mb0's avatar
mb0 committed
79
80
81
82
83
   {__objref o = __ALLOC1();\
    o->closure.header.tag = __CLOSURE;\
    o->closure.sz = n;\
    o->closure.env = o+1;\
    Cname = __WRAP(o);}
84
85
86

#define __CLOSURE_REF(Cname, n) (__WRAP(&(Cname->closure.env[n])))

mb0's avatar
mb0 committed
87
88
89
/** ## Records */

#define __RECORD_BEGIN(Cname, n)\
mb0's avatar
mb0 committed
90
  __CHECK_HEAP(n+1)
mb0's avatar
mb0 committed
91

mb0's avatar
mb0 committed
92
93
94
95
96
#define __RECORD_ADD(field, value)\
  {__objref o = __ALLOC1();\
   o->tagged.header.tag = __TAGGED;\
   o->tagged.tag = field;\
   o->tagged.payload = value;}
mb0's avatar
mb0 committed
97
98

#define __RECORD_END(Cname, n)\
mb0's avatar
mb0 committed
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
  {__objref o = __ALLOC1();\
   o->record.header.tag = __RECORD;\
   o->record.sz = n;\
   o->record.fields = o+1;\
   Cname = __WRAP(o);}

#define __RECORD_BEGIN_UPDATE(Cdst, Csrc)\
  {__recordCloneFields((struct __record*)Csrc);\
   __word n = Csrc->record.sz

#define __RECORD_UPDATE(tag, value)\
   n += __recordUpdate(__ALLOC0(),n,tag,value)

#define __RECORD_END_UPDATE(Cdst)\
  {__objref o = __ALLOC1();\
   o->record.header.tag = __RECORD;\
   o->record.sz = n;\
   o->record.fields = o+1;\
   Cdst = __WRAP(o);}}
mb0's avatar
mb0 committed
118
119
120
121
122
123

#define __RECORD_SELECT(Cname, field)\
  __recordLookup(((struct __record*)Cname), field)->tagged.payload
   
/** ## Bitvectors */

mb0's avatar
mb0 committed
124
125
126
127
128
129
130
131
132
133
134
#define __BV_BEGIN(Cname, n)\
  __CHECK_HEAP(1)

#define __BV_INIT(value)\
  {__objref o = __ALLOC1();\
   o->bv.header.tag = __BV;\
   o->bv.vec = value;\

#define __BV_END(Cname, n)\
   o->bv.sz = n;\
   Cname = __WRAP(o);}
mb0's avatar
mb0 committed
135
136
137

/** ## Tagged values (datatypes) */

mb0's avatar
mb0 committed
138
139
140
141
142
143
144
145
146
147
148
#define __TAGGED_BEGIN(Cname)\
  __CHECK_HEAP(1)

#define __TAGGED_INIT(con, value)\
  {__objref o = __ALLOC1();\
   o->tagged.header.tag = __TAGGED;\
   o->tagged.tag = con;\
   o->tagged.payload = value;

#define __TAGGED_END(Cname)\
   Cname = __WRAP(o);}
149

mb0's avatar
mb0 committed
150
151
152
#define __TAGGED_BEGIN(Cname)\
  __CHECK_HEAP(1)

mb0's avatar
mb0 committed
153
154
#define __DECON(o) (o)->tagged.payload

mb0's avatar
mb0 committed
155
156
157
158
159
160
161
162
163
164
165
166
167
168
/** ## Blobs */

#define __BLOB_BEGIN(Cname)\
  __CHECK_HEAP(1)

#define __BLOB_INIT(buf, size)\
  {__objref o = __ALLOC1();\
   o->blob.header.tag = __BLOB;\
   o->blob.blob = buf;\
   o->blob.sz = size;

#define __BLOB_END(Cname)\
   Cname = __WRAP(o);}

169
170
171
#define __LOCAL0(Cname) __obj Cname
#define __LOCAL(Cname, body) __obj Cname = body

mb0's avatar
mb0 committed
172
typedef union __header __header;
173
174
175
176
typedef union __unwrapped_obj __unwrapped_obj;
typedef union __wrapped_obj __wrapped_obj;
typedef __unwrapped_obj* __objref;
typedef __wrapped_obj* __obj;
mb0's avatar
mb0 committed
177
178
typedef uint64_t __word;
typedef int64_t __int;
mb0's avatar
mb0 committed
179
typedef uint8_t __char;
180
181
182
183
184

enum __tag {
  __CLOSURE,
  __BV,
  __INT,
mb0's avatar
mb0 committed
185
186
  __TAGGED,
  __RECORD,
mb0's avatar
mb0 committed
187
188
  __NIL,
  __BLOB,
189
190
191
192
193
194
  __LABEL
};

union __header {
  enum __tag tag;
  __obj ignored;
mb0's avatar
mb0 committed
195
} __attribute__((aligned(8)));
196
197
198

union __unwrapped_obj {
  struct __unwrapped_immediate {
mb0's avatar
mb0 committed
199
    __header header;
200
  } object;
mb0's avatar
mb0 committed
201
202
203
204
205
  struct __unwrapped_tagged {
    __header header;
    __word tag;
    __obj payload;
  } tagged;
206
  struct __unwrapped_closure {
mb0's avatar
mb0 committed
207
208
    __header header;
    __word sz;
209
210
    __objref env;
  } closure;
mb0's avatar
mb0 committed
211
212
213
214
215
216
217
218
219
220
  struct __unwrapped_record {
    __header header;
    __word sz;
    __objref fields;
  } record;
  struct __unwrapped_bv {
    __header header;
    __word sz;
    __word vec;
  } bv;
221
  struct __unwrapped_label {
mb0's avatar
mb0 committed
222
223
    __header header;
    __obj (*f)(void);
224
  } label;
mb0's avatar
mb0 committed
225
226
227
228
229
  struct __unwrapped_blob {
    __header header;
    __char* blob;
    __word sz;
  } blob;
230
  struct __unwrapped_int {
mb0's avatar
mb0 committed
231
232
    __header header;
    __int value;
233
  } z;
mb0's avatar
mb0 committed
234
} __attribute__((aligned(8)));
235
236

union __wrapped_obj {
mb0's avatar
mb0 committed
237
238
239
240
  struct __tagged {
    __word tag;
    __obj payload;
  } tagged;
241
  struct __closure {
mb0's avatar
mb0 committed
242
    __word sz;
243
244
    __objref env;
  } closure;
mb0's avatar
mb0 committed
245
246
247
248
249
250
251
252
  struct __record {
    __word sz;
    __objref fields;
  } record;
  struct __bv {
    __word sz;
    __word vec;
  } bv;
253
  struct __label {
mb0's avatar
mb0 committed
254
    __obj (*f)(void);
255
  } label;
mb0's avatar
mb0 committed
256
257
258
259
  struct __blob {
    __char* blob;
    __word sz;
  } blob;
260
  struct __int {
mb0's avatar
mb0 committed
261
    __int value;
262
  } z;
mb0's avatar
mb0 committed
263
} __attribute__((aligned(8)));
264

mb0's avatar
mb0 committed
265
266
#define __WRAP(x) ((__obj)(((__header*)x)+1))
#define __UNWRAP(x) ((__objref)(((__header*)x)-1))
267
#define __TAG(x) ((__UNWRAP((__obj)x))->object.header.tag)
268
269

#ifndef RELAXEDFATAL
mb0's avatar
mb0 committed
270
#define __FATAL(type) __fatal("%s:%d:%s",__FILE__,__LINE__,#type)
271
272
273
274
275
#else
#define __FATAL(type)\
  {printf("%s:%d:%s\n",__FILE__,__LINE__,#type);\
   return (__UNIT);}
#endif
276

mb0's avatar
mb0 committed
277
void __fatal(char*,...) __attribute__((noreturn));
mb0's avatar
mb0 committed
278
__unwrapped_obj heap[__RT_HEAP_SIZE] __attribute__((aligned(8)));
mb0's avatar
mb0 committed
279
280
__objref hp;
__obj __UNIT;
281
282
__obj __TRUE;
__obj __FALSE;
mb0's avatar
mb0 committed
283

mb0's avatar
mb0 committed
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
/* ## Constructor tags */

#define __RESERVED 0
@constructors@

/* ## Record field selectors */

#define ___blob 0
@fields@

/* ## Exported functions */

@exports@

/* ## Primitive runtime functions */

mb0's avatar
mb0 committed
300
301
const __char* __tagName (__word i);
const __char* __fieldName (__word i);
mb0's avatar
mb0 committed
302
303
304
305

__obj __halt (__obj,__obj);
__obj __print (__obj);
__obj __println (__obj);
mb0's avatar
mb0 committed
306
__obj __traceln (const char*,__obj);
mb0's avatar
mb0 committed
307

mb0's avatar
mb0 committed
308
309
310
311
312
313
static inline __objref __recordLookup (struct __record* record, __word field) {
  __word i, sz = record->sz;
  __objref fields = record->fields;
  for (i = 0; i < sz; i++) {
    __objref o = &fields[i];
    if (o->tagged.tag == field)
mb0's avatar
mb0 committed
314
       return (o);
mb0's avatar
mb0 committed
315
  }
mb0's avatar
mb0 committed
316
317
318
319
  if (field < __NFIELDS)
    __fatal("record-field '%s' not found",__fieldName(field));
  else
    __fatal("record-field '%zu' not found",field);
mb0's avatar
mb0 committed
320
321
}

mb0's avatar
mb0 committed
322
323
324
325
326
327
328
static inline __word __recordUpdate (__objref fields, __word n, __word field, __obj value) {
  __word i;
  for (i = 0; i < n; i++) {
    __objref o = &fields[i];
    if (o->tagged.tag == field) {
       /* Overwriting already exisiting field */
       o->tagged.payload = value;
mb0's avatar
mb0 committed
329
       return (0);
mb0's avatar
mb0 committed
330
331
332
333
334
335
336
    }
  }
  /* Allocating new record field */
  __objref o = __ALLOC1();
  o->tagged.header.tag = __TAGGED;
  o->tagged.tag = field;
  o->tagged.payload = value;
mb0's avatar
mb0 committed
337
  return (1);
mb0's avatar
mb0 committed
338
339
340
}

static inline void __recordCloneFields (struct __record* record) {
mb0's avatar
mb0 committed
341
342
343
344
345
  __word sz = record->sz;
  __objref fields = __ALLOCN(sz);
  memcpy(fields, record->fields, sz*sizeof(__unwrapped_obj));
}

mb0's avatar
mb0 committed
346
347
348
static inline __word __CASETAG (__obj o) {
  switch (__TAG(o)) {
    case __INT:
mb0's avatar
mb0 committed
349
      return ((__word)o->z.value);
mb0's avatar
mb0 committed
350
    case __TAGGED:
mb0's avatar
mb0 committed
351
      return (o->tagged.tag);
mb0's avatar
mb0 committed
352
    case __BV:
mb0's avatar
mb0 committed
353
      return (o->bv.vec);
mb0's avatar
mb0 committed
354
355
356
357
358
    default:
      __fatal("__CASETAG() applied to non-tagged object");
  }
}

359
360
361
362
363
364
365
366
367
368
369
370
static inline int __isTrue (__obj o) {
   return (o == __TRUE); /* TODO: or isBitVec(o)&&value='1' */
}

static inline int __isFalse (__obj o) {
   return (o == __FALSE); /* TODO: or isBitVec(o)&&value='0' */
}

static inline void __resetHeap() {
  hp = &heap[__RT_HEAP_SIZE];
}

mb0's avatar
Up.    
mb0 committed
371
372
373
374
375
376
__obj __consume8(__obj);
__obj __unconsume8(__obj);
__obj __consume16(__obj);
__obj __unconsume16(__obj);
__obj __consume32(__obj);
__obj __unconsume32(__obj);
mb0's avatar
mb0 committed
377
378
379
380
__obj __slice(__obj,__obj,__obj);
__obj __concat(__obj,__obj);
__obj __equal(__obj,__obj);
__obj __and(__obj,__obj);
mb0's avatar
Foo.    
mb0 committed
381
382
383
__obj __sx(__obj);
__obj __zx(__obj);
__obj __add(__obj,__obj);
mb0's avatar
mb0 committed
384
__obj __sub(__obj,__obj);
mb0's avatar
mb0 committed
385
386
387
388
389
390
391
392
__obj __raise(__obj);
__obj __not(__obj);
__obj __isNil(__obj);
__obj __printState();

/* ## API helpers */

int ___isNil(__obj);
393
394
395
__obj __runWithState(__obj(*)(__obj,__obj),__obj);
__obj __eval(__obj(*)(__obj,__obj),__char*, __word);
__word __decode(__obj(*)(__obj,__obj),__char*,__word,__obj*);
mb0's avatar
Foo.    
mb0 committed
396
__obj __translate(__obj(*)(__obj,__obj),__obj);
mb0's avatar
mb0 committed
397
398

#endif /* __RUNTIME_H */
399