diff options
Diffstat (limited to 'src/bootstrap/objects.c')
-rw-r--r-- | src/bootstrap/objects.c | 156 |
1 files changed, 156 insertions, 0 deletions
diff --git a/src/bootstrap/objects.c b/src/bootstrap/objects.c new file mode 100644 index 0000000..985709a --- /dev/null +++ b/src/bootstrap/objects.c | |||
@@ -0,0 +1,156 @@ | |||
1 | typedef enum ObjectType { | ||
2 | OBJ_TYPE_FIXNUM, | ||
3 | OBJ_TYPE_BOOL, | ||
4 | OBJ_TYPE_NIL, | ||
5 | OBJ_TYPE_SYMBOL, | ||
6 | OBJ_TYPE_STRING, | ||
7 | OBJ_TYPE_PAIR, | ||
8 | OBJ_TYPE_PROCEDURE, | ||
9 | } ObjectType; | ||
10 | |||
11 | typedef struct Object { | ||
12 | ObjectType type; | ||
13 | union { | ||
14 | // OBJ_TYPE_FIXNUM | ||
15 | ssize_t fixnum; | ||
16 | |||
17 | // OBJ_TYPE_BOOL | ||
18 | bool boolean; | ||
19 | |||
20 | // OBJ_TYPE_STRING | ||
21 | struct { | ||
22 | char *string; | ||
23 | size_t string_n; | ||
24 | }; | ||
25 | |||
26 | // OBJ_TYPE_PAIR | ||
27 | struct { | ||
28 | struct Object *car; | ||
29 | struct Object *cdr; | ||
30 | }; | ||
31 | |||
32 | // OBJ_TYPE_SYMBOL | ||
33 | struct { | ||
34 | char *symbol; | ||
35 | size_t symbol_n; | ||
36 | }; | ||
37 | |||
38 | // OBJ_TYPE_PROCEDURE | ||
39 | struct Object *(*proc)(struct Object *args); | ||
40 | }; | ||
41 | } Object; | ||
42 | |||
43 | // | ||
44 | // Singletons. | ||
45 | // | ||
46 | |||
47 | Object *obj_nil; | ||
48 | Object *obj_true; | ||
49 | Object *obj_false; | ||
50 | |||
51 | // | ||
52 | // Constructors. | ||
53 | // | ||
54 | |||
55 | Object * | ||
56 | make_fixnum(ssize_t num) { | ||
57 | Object *obj = malloc(sizeof(Object)); | ||
58 | obj->type = OBJ_TYPE_FIXNUM; | ||
59 | obj->fixnum = num; | ||
60 | return obj; | ||
61 | } | ||
62 | |||
63 | Object * | ||
64 | make_boolean(bool b) { | ||
65 | Object *obj = malloc(sizeof(Object)); | ||
66 | obj->type = OBJ_TYPE_BOOL; | ||
67 | obj->boolean = b; | ||
68 | return obj; | ||
69 | } | ||
70 | |||
71 | Object * | ||
72 | make_empty_string(void) { | ||
73 | Object *obj = malloc(sizeof(Object)); | ||
74 | obj->type = OBJ_TYPE_STRING; | ||
75 | obj->string = NULL; | ||
76 | obj->string_n = 0; | ||
77 | return obj; | ||
78 | } | ||
79 | |||
80 | void | ||
81 | append_string(Object *string, StringView sv) { | ||
82 | assert(string != NULL); | ||
83 | assert(string->type == OBJ_TYPE_STRING); | ||
84 | |||
85 | if (sv.n == 0) { | ||
86 | return; | ||
87 | } | ||
88 | |||
89 | string->string = realloc(string->string, (string->string_n + sv.n) * sizeof(char)); | ||
90 | memcpy(string->string + string->string_n, sv.start, sv.n); | ||
91 | string->string_n += sv.n; | ||
92 | } | ||
93 | |||
94 | Object * | ||
95 | make_symbol(const char *str, size_t n) { | ||
96 | Object *obj = malloc(sizeof(Object)); | ||
97 | obj->type = OBJ_TYPE_SYMBOL; | ||
98 | obj->string = malloc(sizeof(char) * n); | ||
99 | memcpy(obj->string, str, n); | ||
100 | obj->string_n = n; | ||
101 | return obj; | ||
102 | } | ||
103 | |||
104 | Object * | ||
105 | make_empty_list(void) { | ||
106 | Object *obj = malloc(sizeof(Object)); | ||
107 | obj->type = OBJ_TYPE_NIL; | ||
108 | return obj; | ||
109 | } | ||
110 | |||
111 | Object * | ||
112 | make_procedure(Object *(*proc)(struct Object *args)) { | ||
113 | Object *obj = malloc(sizeof(Object)); | ||
114 | obj->type = OBJ_TYPE_PROCEDURE; | ||
115 | obj->proc = proc; | ||
116 | return obj; | ||
117 | } | ||
118 | |||
119 | Object * | ||
120 | make_pair(Object *car, Object *cdr) { | ||
121 | Object *obj = malloc(sizeof(Object)); | ||
122 | obj->type = OBJ_TYPE_PAIR; | ||
123 | obj->car = car; | ||
124 | obj->cdr = cdr; | ||
125 | return obj; | ||
126 | } | ||
127 | |||
128 | bool | ||
129 | symbol_eq(Object *a, Object *b) { | ||
130 | if (a->type != b->type || a->type != OBJ_TYPE_SYMBOL || a->symbol_n != b->symbol_n) { | ||
131 | return false; | ||
132 | } | ||
133 | for (size_t i = 0; i < a->symbol_n; i++) { | ||
134 | if (a->symbol[i] != b->symbol[i]) { | ||
135 | return false; | ||
136 | } | ||
137 | } | ||
138 | return true; | ||
139 | } | ||
140 | |||
141 | void display(Object *root); | ||
142 | |||
143 | void | ||
144 | display_pair(Object *root) { | ||
145 | display(root->car); | ||
146 | if (root->cdr->type == OBJ_TYPE_PAIR) { | ||
147 | printf(" "); | ||
148 | display_pair(root->cdr); | ||
149 | } else if (root->cdr->type == OBJ_TYPE_NIL) { | ||
150 | return; | ||
151 | } else { | ||
152 | printf(" . "); | ||
153 | display(root->cdr); | ||
154 | } | ||
155 | } | ||
156 | |||