-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathalloc.h
executable file
·107 lines (99 loc) · 4.17 KB
/
alloc.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#ifndef ALLOC_H
#define ALLOC_H
#include <math.h> // isnan
#include <stdint.h>
enum Type { BOXSTR_LIST=0xFFFF0001, // pointer to a pair of elements. Typically the second in the pair is a list.
BOXSTR_FORWARD=0xFFFF0002, // a forwarding pointer
BOXSTR_STRING=0xFFFF0003, // pointer to a STRHDR.
BOXSTR_STRHDR, // contains a character count and is immediately followed by said characters
BOXSTR_ARRAY, // pointer to an ARRHDR.
BOXSTR_ARRHDR, // contains an element count and is immediately followed by said elements
BOXSTR_BUILTIN, // contains a pointer to a built-in function
BOXSTR_SYMBOL, // points to an interned string.
BOXSTR_INT // contains an integer
};
typedef union element {
double num;
struct {
#if BIGENDIAN
Type type;
element* tptr;
#else
// This is known to satisfactorily put the pointer in the low
// bits of the double and put the Type in the high bits of
// the double, with G++ on x86.
element* tptr;
Type type;
#endif
};
uint16_t ch[4];
} element;
bool equal_data(const element& a, const element& b);
inline bool operator==(const element& a, const element& b)
{
return equal_data(a,b);
}
inline bool operator!=(const element& a, const element& b)
{
return !equal_data(a,b);
}
inline bool BoxIsList(const element& b) { return b.type == BOXSTR_LIST; }
inline bool BoxIsDouble(const element& b) { return !isnan(b.num); }
inline bool BoxIsForward(const element& b) { return b.type==BOXSTR_FORWARD; }
inline bool BoxIsString(const element& b) {return b.type==BOXSTR_STRING; }
inline bool BoxIsSymbol(const element& b) {return b.type==BOXSTR_SYMBOL; }
inline bool BoxIsInteger(const element& b) { return b.type==BOXSTR_INT; }
inline bool BoxIsHeader(const element& b) { return b.type==BOXSTR_STRHDR||b.type==BOXSTR_ARRHDR; }
inline bool BoxIsArray(const element& b) { return b.type==BOXSTR_ARRAY; }
inline bool BoxIsBuiltin(const element& b) { return b.type==BOXSTR_BUILTIN; }
inline int IntFromBox(const element& b) { return (int)(b.tptr); }
inline element BoxFromInt(int x) { element e; e.type = BOXSTR_INT; e.tptr = (element*)x; return e; }
inline element BoxFromDouble(double x) { element e; e.num = x; return e; }
inline element ElementFromInt(Type t, int i) { element e; e.type = t; e.tptr = (element*)i; return e; }
typedef element (*Builtin)(element);
inline element BoxFromBuiltIn(element (*fn)(element)) { element e; e.type = BOXSTR_BUILTIN; e.tptr = (element*)fn; return e;}
inline Builtin BuiltinFromBox(const element& b) { return (Builtin)b.tptr; }
#include <iosfwd>
std::ostream& operator<<(std::ostream& out, const element& elt);
element cons(element car, element cdr);
element car(element pair);
element cdr(element pair);
element newstr();
element newstr(const char* asciz);
element string_append_char(element str, element ch);
element string_append_string(element stra, element strb);
element string_get_char(element str, element index);
element string_get_substr(element str, element first);
element string_get_substr(element str, element first, element count);
element string_get_size(element str);
element symbol_create(const char* asciz);
element symbol_from_string(element str);
element array_create();
element array_create(element size);
element array_append_element(element array, element elt);
element array_get_element(element array, element index);
element array_set_element(element array, element index, element elt); // Can extend array
element array_get_size(element array);
element array_set_size(element array, element size); // can extend array
//void ShowCar(std::ostream& out, const element &car);
//void ShowList(std::ostream& out, const element& cons);
void ShowElement(std::ostream& os, element e);
void gc_add_root(element* root);
void gc_unroot(element* root);
void gc_collect();
void init_heap();
struct Rooter {
Rooter(element& elt) : elt(elt) { gc_add_root(&elt); }
~Rooter() { gc_unroot(&elt); }
element& elt;
};
// Awkward:
void dump_heap();
// Very Awkward:
void dump_new_heap();
// probably shouldn't be here:
//extern element space[];
//extern element* alloc;
//extern element* tospace;
//extern element* next;
#endif // ALLOC_H