runtime.h 8.74 KB
Newer Older
1
2
3
4
5
6

#ifndef __RUNTIME_H
#define __RUNTIME_H

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

12
#define __RT_HEAP_SIZE (4*1024)
13

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

mb0's avatar
mb0 committed
91
92
93
94
95
#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
96
97

#define __RECORD_END(Cname, n)\
mb0's avatar
mb0 committed
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
  {__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
117
118
119
120
121
122

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

mb0's avatar
mb0 committed
123
124
125
126
127
128
129
130
131
132
133
#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
134
135
136

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

mb0's avatar
mb0 committed
137
138
139
140
141
142
143
144
145
146
147
#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);}
148

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

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

mb0's avatar
mb0 committed
154
155
156
157
158
159
160
161
162
163
164
165
166
167
/** ## 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);}

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

mb0's avatar
mb0 committed
171
typedef union __header __header;
172
173
174
175
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
176
177
typedef uint64_t __word;
typedef int64_t __int;
mb0's avatar
mb0 committed
178
typedef uint8_t __char;
179
180
181
182
183

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

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

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

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

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

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

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

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

#define __RESERVED 0
@constructors@

/* ## Record field selectors */

#define ___blob 0
@fields@

/* ## Exported functions */

@exports@

/* ## Primitive runtime functions */

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

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

mb0's avatar
mb0 committed
307
308
309
310
311
312
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
313
       return (o);
mb0's avatar
mb0 committed
314
  }
mb0's avatar
mb0 committed
315
316
317
318
  if (field < __NFIELDS)
    __fatal("record-field '%s' not found",__fieldName(field));
  else
    __fatal("record-field '%zu' not found",field);
mb0's avatar
mb0 committed
319
320
}

mb0's avatar
mb0 committed
321
322
323
324
325
326
327
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
328
       return (0);
mb0's avatar
mb0 committed
329
330
331
332
333
334
335
    }
  }
  /* 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
336
  return (1);
mb0's avatar
mb0 committed
337
338
339
}

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

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

358
359
360
361
362
363
364
365
366
367
368
369
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
mb0 committed
370
__obj __consume (__obj);
mb0's avatar
mb0 committed
371
372
373
374
375
__obj __slice(__obj,__obj,__obj);
__obj __unconsume(__obj);
__obj __concat(__obj,__obj);
__obj __equal(__obj,__obj);
__obj __and(__obj,__obj);
mb0's avatar
Foo.    
mb0 committed
376
377
378
__obj __sx(__obj);
__obj __zx(__obj);
__obj __add(__obj,__obj);
mb0's avatar
mb0 committed
379
__obj __sub(__obj,__obj);
mb0's avatar
mb0 committed
380
381
382
383
384
385
386
387
__obj __raise(__obj);
__obj __not(__obj);
__obj __isNil(__obj);
__obj __printState();

/* ## API helpers */

int ___isNil(__obj);
388
389
390
__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
391
__obj __translate(__obj(*)(__obj,__obj),__obj);
mb0's avatar
mb0 committed
392
393

#endif /* __RUNTIME_H */
394
395
396
397
398

/* vim:cindent
 * vim:ts=2
 * vim:sw=2
 * vim:expandtab */