-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathobject.h
More file actions
193 lines (164 loc) · 7.01 KB
/
object.h
File metadata and controls
193 lines (164 loc) · 7.01 KB
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
#ifndef clox_object_h
#define clox_object_h
#include "chunk.h"
#include "table.h"
#include "value.h"
#include "native.h"
////////////////////////////////////////////////////////////////////////////////////////////////////
// Object accessors
////////////////////////////////////////////////////////////////////////////////////////////////////
#define OBJ_TYPE(value) (AS_OBJ(value)->type)
#define IS_BOUND(value) isObjType(value, OBJ_BOUND)
#define IS_CLASS(value) isObjType(value, OBJ_CLASS)
#define IS_CLOSURE(value) isObjType(value, OBJ_CLOSURE)
#define IS_DYNVAR(value) isObjType(value, OBJ_DYNVAR)
#define IS_FUNCTION(value) isObjType(value, OBJ_FUNCTION)
#define IS_INSTANCE(value) isObjType(value, OBJ_INSTANCE)
#define IS_ITERATOR(value) isObjType(value, OBJ_ITERATOR)
#define IS_LIST(value) isObjType(value, OBJ_LIST)
#define IS_NATIVE(value) isObjType(value, OBJ_NATIVE)
#define IS_REAL(value) isObjType(value, OBJ_REAL)
#define IS_STRING(value) isObjType(value, OBJ_STRING)
#define AS_BOUND(value) ((ObjBound*)AS_OBJ(value))
#define AS_CLASS(value) ((ObjClass*)AS_OBJ(value))
#define AS_CLOSURE(value) ((ObjClosure*)AS_OBJ(value))
#define AS_DYNVAR(value) ((ObjDynvar*)AS_OBJ(value))
#define AS_FUNCTION(value) ((ObjFunction*)AS_OBJ(value))
#define AS_INSTANCE(value) ((ObjInstance*)AS_OBJ(value))
#define AS_ITERATOR(value) ((ObjIterator*)AS_OBJ(value))
#define AS_LIST(value) ((ObjList*)AS_OBJ(value))
#define AS_NATIVE(value) (((ObjNative*)AS_OBJ(value))->native)
#define AS_REAL(value) (((ObjReal*)AS_OBJ(value))->content)
#define AS_STRING(value) ((ObjString*)AS_OBJ(value))
#define AS_CSTRING(value) (((ObjString*)AS_OBJ(value))->chars)
////////////////////////////////////////////////////////////////////////////////////////////////////
// Object types
////////////////////////////////////////////////////////////////////////////////////////////////////
// keep enum order for type tests
typedef enum { // visible to user | callable | leaf object | creation (Init, Compile, Runtime)
OBJ_DYNVAR, // . | . | . | R
OBJ_FUNCTION, // . | . | . | C
OBJ_UPVALUE, // . | . | . | R
OBJ_INSTANCE, // X | . | . | R
OBJ_LIST, // X | . | . | R
OBJ_ITERATOR, // X | . | . | R
OBJ_BOUND, // X | X | . | R
OBJ_CLASS, // X | X | . | R
OBJ_CLOSURE, // X | X | . | R
OBJ_NATIVE, // X | X | X | I
OBJ_REAL, // X | . | X | C,R
OBJ_STRING, // X | . | X | I,C,R
} ObjType;
// The IDE68K C compiler doesn't seem to like including struct Obj in the following structures
// and generates wrong code when casting, so we expand struct Obj manually.
#define OBJ_HEADER \
Obj* nextObj; \
uint8_t type; \
uint8_t isMarked;
struct Obj {
OBJ_HEADER
};
struct ObjBound {
OBJ_HEADER
Value receiver; // actually always an ObjInstance*
ObjClosure* method;
};
struct ObjClass {
OBJ_HEADER
ObjString* name;
ObjClass* superClass; // nil when no superclass
Table methods;
};
struct ObjClosure {
OBJ_HEADER
int16_t upvalueCount; // too big, but keep alignment
ObjFunction* function;
ObjUpvalue* upvalues[]; // array embedded in structure
};
struct ObjDynvar {
OBJ_HEADER
Value varName; // actually always an ObjString*
Value previous; // EMPTY_VAL when nothing to unbind
};
struct ObjFunction {
OBJ_HEADER
uint8_t arity; // lower 7 bits arity, highest bit rest parameter flag
uint8_t upvalueCount;
Chunk chunk;
Value name; // string for named functions, int for anonymous, nil for script
ObjClass* klass; // defining class for method, nil for normal function
};
struct ObjInstance {
OBJ_HEADER
ObjClass* klass; // never nil
Table fields;
};
struct ObjIterator {
OBJ_HEADER
int16_t position; // -1: before first; -2: after last; else valid position
ObjInstance* instance;
};
struct ObjList {
OBJ_HEADER
ValueArray arr;
};
struct ObjNative {
OBJ_HEADER
const Native* native; // Pointer into ROM table, not GCed
};
struct ObjReal {
OBJ_HEADER
Real content;
};
struct ObjString {
OBJ_HEADER
int16_t length;
uint32_t hash;
char chars[]; // single alloc for strings, as embedded char array
};
struct ObjUpvalue {
OBJ_HEADER
Value* location; // pointer into value stack or to my 'uv.closed' field
union { // only one of those is needed at any time:
ObjUpvalue* next; // next in a list of open upvalues
Value closed; // storage for closed upvalue migrated from value stack
} uv;
};
////////////////////////////////////////////////////////////////////////////////////////////////////
// Object functions
////////////////////////////////////////////////////////////////////////////////////////////////////
ObjBound* makeBound(Value receiver, ObjClosure* method);
ObjClass* makeClass(ObjString* name);
ObjClosure* makeClosure(ObjFunction* function);
ObjDynvar* makeDynvar(Value varName, Value previous);
ObjFunction* makeFunction(void);
ObjInstance* makeInstance(ObjClass* klass);
ObjIterator* makeIterator(ObjInstance* instance);
ObjList* makeList(int len, Value* items, int numCopy, int stride);
ObjNative* makeNative(const Native* native);
Value makeReal(Real val);
ObjString* makeString0(const char* chars);
ObjString* makeString(const char* chars, int length);
ObjUpvalue* makeUpvalue(Value* slot);
void printObject(Value value, int flags);
bool isObjType(Value value, ObjType type);
bool isCallable(Value value);
const char* typeName(ObjType type);
const char* functionName(ObjFunction* function);
bool validateIndex(int len, int* index);
void insertIntoList(ObjList* list, Value value, int index);
void deleteFromList(ObjList* list, int index);
ObjList* sliceFromList(ObjList* list, int begin, int end);
ObjList* concatLists(ObjList* a, ObjList* b);
ObjString* sliceFromString(ObjString* string, int begin, int end);
ObjString* concatStrings(ObjString* a, ObjString* b);
ObjString* mapString(ObjString* a, int (*mapChar)(int));
const char* formatReal(Real val);
const char* formatInt(Int val);
const char* formatHex(Int val);
const char* formatBin(Int val);
Value parseInt(const char* start, bool checkLen);
void putstrn(int len, const char* str);
char* readLine(void);
extern char buffer[];
#endif