runtime.h 9.07 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
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
  ((__obj(*)(__obj,__obj,__obj,__obj,__obj,__obj,__obj))((o)->label.f))(closure, u, v, w, x, y, z)

#define __CALL1(f,x)\
  f(x)
#define __CALL2(f,x,y)\
  f(x,y)
#define __CALL3(f,x,y,z)\
  f(x,y,z)
#define __CALL4(f,w,x,y,z)\
  f(w,x,y,z)
#define __CALL5(f,v,w,x,y,z)\
  f(v,w,x,y,z)
#define __CALL6(f,u,v,w,x,y,z)\
  f(u,v,w,x,y,z)
#define __CALL7(f,t,u,v,w,x,y,z)\
  f(t,u,v,w,x,y,z)
#define __CALL8(f,s,t,u,v,w,x,y,z)\
  f(s,t,u,v,w,x,y,z)
#define __CALL9(f,r,s,t,u,v,w,x,y,z)\
  f(r,s,t,u,v,w,x,y,z)
mb0's avatar
mb0 committed
58

mb0's avatar
mb0 committed
59
60
/** ## Integers */

61
#define __INT_BEGIN(Cname)\
mb0's avatar
mb0 committed
62
  __CHECK_HEAP(1)
63
64

#define __INT_INIT(val)\
mb0's avatar
mb0 committed
65
66
67
  {__objref o = __ALLOC1();\
   o->z.header.tag = __INT;\
   o->z.value = val
68
69
   
#define __INT_END(Cname)\
mb0's avatar
mb0 committed
70
   Cname = __WRAP(o);}
71

mb0's avatar
mb0 committed
72
73
/** ## Labels */

74
#define __LABEL_BEGIN(Cname)\
mb0's avatar
mb0 committed
75
  __CHECK_HEAP(1)
76
77

#define __LABEL_INIT(val)\
mb0's avatar
mb0 committed
78
79
80
  {__objref o = __ALLOC1();\
   o->label.header.tag = __LABEL;\
   o->label.f = (__obj (*)(void)) val
81
82
   
#define __LABEL_END(Cname)\
mb0's avatar
mb0 committed
83
   Cname = __WRAP(o);}
84

mb0's avatar
mb0 committed
85
86
/** ## Closures */

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

#define __CLOSURE_ADD(value)\
mb0's avatar
mb0 committed
91
92
   {__objref o = __ALLOC1();\
    *o = *(__UNWRAP(value));}
93
94

#define __CLOSURE_END(Cname, n)\
mb0's avatar
mb0 committed
95
96
97
98
99
   {__objref o = __ALLOC1();\
    o->closure.header.tag = __CLOSURE;\
    o->closure.sz = n;\
    o->closure.env = o+1;\
    Cname = __WRAP(o);}
100
101
102

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

mb0's avatar
mb0 committed
103
104
105
/** ## Records */

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

mb0's avatar
mb0 committed
108
109
110
111
112
#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
113
114

#define __RECORD_END(Cname, n)\
mb0's avatar
mb0 committed
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
  {__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
134
135
136
137
138
139

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

mb0's avatar
mb0 committed
140
141
142
143
144
145
146
147
148
149
150
#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
151
152
153

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

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

mb0's avatar
mb0 committed
166
167
168
#define __TAGGED_BEGIN(Cname)\
  __CHECK_HEAP(1)

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

mb0's avatar
mb0 committed
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/** ## 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);}

185
186
187
#define __LOCAL0(Cname) __obj Cname
#define __LOCAL(Cname, body) __obj Cname = body

mb0's avatar
mb0 committed
188
typedef union __header __header;
189
190
191
192
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
193
194
typedef uint64_t __word;
typedef int64_t __int;
mb0's avatar
mb0 committed
195
typedef uint8_t __char;
196
197
198
199
200

enum __tag {
  __CLOSURE,
  __BV,
  __INT,
mb0's avatar
mb0 committed
201
202
  __TAGGED,
  __RECORD,
mb0's avatar
mb0 committed
203
204
  __NIL,
  __BLOB,
205
206
207
208
209
210
  __LABEL
};

union __header {
  enum __tag tag;
  __obj ignored;
mb0's avatar
mb0 committed
211
} __attribute__((aligned(8)));
212
213
214

union __unwrapped_obj {
  struct __unwrapped_immediate {
mb0's avatar
mb0 committed
215
    __header header;
216
  } object;
mb0's avatar
mb0 committed
217
218
219
220
221
  struct __unwrapped_tagged {
    __header header;
    __word tag;
    __obj payload;
  } tagged;
222
  struct __unwrapped_closure {
mb0's avatar
mb0 committed
223
224
    __header header;
    __word sz;
225
226
    __objref env;
  } closure;
mb0's avatar
mb0 committed
227
228
229
230
231
232
233
234
235
236
  struct __unwrapped_record {
    __header header;
    __word sz;
    __objref fields;
  } record;
  struct __unwrapped_bv {
    __header header;
    __word sz;
    __word vec;
  } bv;
237
  struct __unwrapped_label {
mb0's avatar
mb0 committed
238
239
    __header header;
    __obj (*f)(void);
240
  } label;
mb0's avatar
mb0 committed
241
242
243
244
245
  struct __unwrapped_blob {
    __header header;
    __char* blob;
    __word sz;
  } blob;
246
  struct __unwrapped_int {
mb0's avatar
mb0 committed
247
248
    __header header;
    __int value;
249
  } z;
mb0's avatar
mb0 committed
250
} __attribute__((aligned(8)));
251
252

union __wrapped_obj {
mb0's avatar
mb0 committed
253
254
255
256
  struct __tagged {
    __word tag;
    __obj payload;
  } tagged;
257
  struct __closure {
mb0's avatar
mb0 committed
258
    __word sz;
259
260
    __objref env;
  } closure;
mb0's avatar
mb0 committed
261
262
263
264
265
266
267
268
  struct __record {
    __word sz;
    __objref fields;
  } record;
  struct __bv {
    __word sz;
    __word vec;
  } bv;
269
  struct __label {
mb0's avatar
mb0 committed
270
    __obj (*f)(void);
271
  } label;
mb0's avatar
mb0 committed
272
273
274
275
  struct __blob {
    __char* blob;
    __word sz;
  } blob;
276
  struct __int {
mb0's avatar
mb0 committed
277
    __int value;
278
  } z;
mb0's avatar
mb0 committed
279
} __attribute__((aligned(8)));
280

mb0's avatar
mb0 committed
281
282
#define __WRAP(x) ((__obj)(((__header*)x)+1))
#define __UNWRAP(x) ((__objref)(((__header*)x)-1))
283
#define __TAG(x) ((__UNWRAP((__obj)x))->object.header.tag)
284
285

#ifndef RELAXEDFATAL
mb0's avatar
mb0 committed
286
#define __FATAL(type) __fatal("%s:%d:%s",__FILE__,__LINE__,#type)
287
288
289
290
291
#else
#define __FATAL(type)\
  {printf("%s:%d:%s\n",__FILE__,__LINE__,#type);\
   return (__UNIT);}
#endif
292

mb0's avatar
mb0 committed
293
void __fatal(char*,...) __attribute__((noreturn));
mb0's avatar
mb0 committed
294
__unwrapped_obj heap[__RT_HEAP_SIZE] __attribute__((aligned(8)));
mb0's avatar
mb0 committed
295
296
__objref hp;
__obj __UNIT;
297
298
__obj __TRUE;
__obj __FALSE;
mb0's avatar
mb0 committed
299

mb0's avatar
mb0 committed
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
/* ## Constructor tags */

#define __RESERVED 0
@constructors@

/* ## Record field selectors */

#define ___blob 0
@fields@

/* ## Exported functions */

@exports@

/* ## Primitive runtime functions */

mb0's avatar
mb0 committed
316
317
const __char* __tagName (__word i);
const __char* __fieldName (__word i);
mb0's avatar
mb0 committed
318
319
320
321

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

mb0's avatar
mb0 committed
324
325
326
327
328
329
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
330
       return (o);
mb0's avatar
mb0 committed
331
  }
mb0's avatar
mb0 committed
332
333
334
335
  if (field < __NFIELDS)
    __fatal("record-field '%s' not found",__fieldName(field));
  else
    __fatal("record-field '%zu' not found",field);
mb0's avatar
mb0 committed
336
337
}

mb0's avatar
mb0 committed
338
339
340
341
342
343
344
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
345
       return (0);
mb0's avatar
mb0 committed
346
347
348
349
350
351
352
    }
  }
  /* 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
353
  return (1);
mb0's avatar
mb0 committed
354
355
356
}

static inline void __recordCloneFields (struct __record* record) {
mb0's avatar
mb0 committed
357
358
359
360
361
  __word sz = record->sz;
  __objref fields = __ALLOCN(sz);
  memcpy(fields, record->fields, sz*sizeof(__unwrapped_obj));
}

mb0's avatar
mb0 committed
362
363
364
static inline __word __CASETAG (__obj o) {
  switch (__TAG(o)) {
    case __INT:
mb0's avatar
mb0 committed
365
      return ((__word)o->z.value);
mb0's avatar
mb0 committed
366
    case __TAGGED:
mb0's avatar
mb0 committed
367
      return (o->tagged.tag);
mb0's avatar
mb0 committed
368
    case __BV:
mb0's avatar
mb0 committed
369
      return (o->bv.vec);
mb0's avatar
mb0 committed
370
371
372
373
374
    default:
      __fatal("__CASETAG() applied to non-tagged object");
  }
}

375
376
377
378
379
380
381
382
383
384
385
386
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
387
__obj __consume (__obj);
mb0's avatar
mb0 committed
388
389
390
391
392
__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
393
394
395
__obj __sx(__obj);
__obj __zx(__obj);
__obj __add(__obj,__obj);
mb0's avatar
mb0 committed
396
397
398
399
400
401
402
403
__obj __raise(__obj);
__obj __not(__obj);
__obj __isNil(__obj);
__obj __printState();

/* ## API helpers */

int ___isNil(__obj);
404
405
406
__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
407
__obj __translate(__obj(*)(__obj,__obj),__obj);
mb0's avatar
mb0 committed
408
409

#endif /* __RUNTIME_H */
410
411
412
413
414

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