aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-08 13:20:00 +0200
committerBad Diode <bd@badd10de.dev>2021-10-08 13:20:00 +0200
commitaa699fc05d0945528c9ccf2b9b3d7e53e425d186 (patch)
tree521cd4c2f421c67497bcaeb193ed1a0e039dbfd7
parentbaaef414186e60dbb127662d5f4ffab10ebf225e (diff)
downloadbdl-aa699fc05d0945528c9ccf2b9b3d7e53e425d186.tar.gz
bdl-aa699fc05d0945528c9ccf2b9b3d7e53e425d186.zip
Add initial ast construction for fixnum/bool
-rwxr-xr-xsrc/bootstrap/main.c198
1 files changed, 184 insertions, 14 deletions
diff --git a/src/bootstrap/main.c b/src/bootstrap/main.c
index 98f313b..b346cca 100755
--- a/src/bootstrap/main.c
+++ b/src/bootstrap/main.c
@@ -1,5 +1,7 @@
1#include <stdio.h>
2#include <ctype.h> 1#include <ctype.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <string.h>
3 5
4#include "shorthand.h" 6#include "shorthand.h"
5 7
@@ -15,6 +17,19 @@ sv_write(StringView sv) {
15 } 17 }
16} 18}
17 19
20bool
21sv_equal(StringView a, StringView b) {
22 if (a.n == b.n) {
23 for (size_t i = 0; i < a.n; i++) {
24 if (a.start[i] != b.start[i]) {
25 return false;
26 }
27 }
28 return true;
29 }
30 return false;
31}
32
18StringView 33StringView
19read_line(void) { 34read_line(void) {
20 #define RL_BUF_SIZE 1024 35 #define RL_BUF_SIZE 1024
@@ -121,6 +136,7 @@ tokenize(StringView sv) {
121 .n = 1, 136 .n = 1,
122 }; 137 };
123 } break; 138 } break;
139 // TODO: Handle double quotes and escaped quotes.
124 default: { 140 default: {
125 token_n++; 141 token_n++;
126 } break; 142 } break;
@@ -134,23 +150,174 @@ tokenize(StringView sv) {
134 }; 150 };
135 } 151 }
136 152
153 return (Tokens){.start = (StringView *)&tokens_buf, .n = n};
154}
155
156typedef enum ObjectType {
157 OBJ_TYPE_FIXNUM,
158 OBJ_TYPE_BOOL,
159 OBJ_TYPE_NIL,
160 OBJ_TYPE_SYMBOL,
161 OBJ_TYPE_STRING,
162 OBJ_TYPE_PAIR,
163 OBJ_TYPE_LIST,
164} ObjectType;
165
166typedef struct Object {
167 ObjectType type;
168 union {
169 // OBJ_TYPE_FIXNUM
170 ssize_t fixnum;
171
172 // OBJ_TYPE_BOOL
173 bool boolean;
174
175 // OBJ_TYPE_STRING
176 struct {
177 char *string;
178 size_t string_n;
179 };
180
181 // OBJ_TYPE_PAIR
182 struct {
183 struct Object *car;
184 struct Object *cdr;
185 };
186
187 // OBJ_TYPE_LIST
188 struct {
189 struct Object **list_elems;
190 size_t list_n;
191 };
192 };
193} Object;
194
195Object *
196make_fixnum(ssize_t num) {
197 Object *obj = malloc(sizeof(Object));
198 obj->type = OBJ_TYPE_FIXNUM;
199 obj->fixnum = num;
200 return obj;
201}
202
203Object *
204make_boolean(bool b) {
205 Object *obj = malloc(sizeof(Object));
206 obj->type = OBJ_TYPE_BOOL;
207 obj->boolean = b;
208 return obj;
209}
210
211Object *
212make_string(const char *str, size_t n) {
213 Object *obj = malloc(sizeof(Object));
214 obj->type = OBJ_TYPE_STRING;
215 obj->string = malloc(sizeof(char) * n);
216 memcpy(obj->string, str, n);
217 obj->string_n = n;
218 return obj;
219}
220
221Object *
222make_empty_list(void) {
223 Object *obj = malloc(sizeof(Object));
224 obj->type = OBJ_TYPE_LIST;
225 obj->list_elems = NULL;
226 obj->list_n = 0;
227 return obj;
228}
229
230void
231push_obj_to_list(Object *list, Object obj) {
232 assert(false && "todo: Not implemented");
233}
234
235bool
236token_is_fixnum(StringView token) {
237 for (size_t i = 0; i < token.n; i++) {
238 char c = token.start[i];
239 if (i == 0 && c == '-') {
240 continue;
241 }
242 if (!isdigit(c)) {
243 return false;
244 }
245 }
246 return true;
247}
248
249#define TRUE_TOKEN (StringView){"true", 4}
250#define FALSE_TOKEN (StringView){"false", 5}
251
252Object *
253build_ast(Tokens tokens) {
137 // DEBUG: Printing tokens. 254 // DEBUG: Printing tokens.
138 printf("N_TOKENS: %ld\n", n); 255 // printf("N_TOKENS: %ld\n", tokens.n);
139 for (size_t i = 0; i < n; i++) { 256 // for (size_t i = 0; i < tokens.n; i++) {
140 printf("TOKEN: "); 257 // printf("TOKEN: ");
141 sv_write(tokens_buf[i]); 258 // sv_write(tokens.start[i]);
142 printf("\tN: %ld", tokens_buf[i].n); 259 // printf("\tN: %ld", tokens.start[i].n);
143 printf("\n"); 260 // printf("\n");
261 // }
262
263 // TODO: Report error if we haven't consumed all the tokens?
264 for (size_t i = 0; i < tokens.n; i++) {
265 StringView token = tokens.start[i];
266
267 // OBJ_TYPE_FIXNUM
268 if (token_is_fixnum(token)) {
269 // Convert token to fixnum.
270 ssize_t num = 0;
271 int sign = 1;
272 for (size_t i = 0; i < token.n; i++) {
273 char c = token.start[i];
274 if (c == '-') {
275 sign = -1;
276 continue;
277 }
278 num = num * 10 + (c - '0');
279 }
280 return make_fixnum(num * sign);
281 }
282
283 // OBJ_TYPE_BOOL
284 if (sv_equal(token, TRUE_TOKEN)) {
285 return make_boolean(true);
286 }
287 if (sv_equal(token, FALSE_TOKEN)) {
288 return make_boolean(false);
289 }
144 } 290 }
145 291
146 return (Tokens){.start = (StringView *)&tokens_buf, .n = n}; 292 return NULL;
147} 293}
148 294
149void 295void
150display(StringView sv) { 296display(Object *root) {
151 if (sv.n != 0) { 297 if (root == NULL) {
152 sv_write(sv); 298 return;
153 printf("\n"); 299 }
300
301 switch (root->type) {
302 case OBJ_TYPE_FIXNUM: {
303 printf("%zd", root->fixnum);
304 } break;
305 case OBJ_TYPE_BOOL: {
306 if (root->boolean) {
307 printf("true");
308 } else {
309 printf("false");
310 }
311 } break;
312 case OBJ_TYPE_NIL: {
313 printf("()");
314 } break;
315 case OBJ_TYPE_STRING: {
316 printf("\"%.*s\"", (int)root->string_n, root->string);
317 } break;
318 default: {
319 printf("TYPE NOT IMPLEMENTED FOR DISPLAY\n");
320 } break;
154 } 321 }
155} 322}
156 323
@@ -162,8 +329,11 @@ main(void) {
162 while (true) { 329 while (true) {
163 printf(REPL_PROMPT); 330 printf(REPL_PROMPT);
164 StringView line = read_line(); 331 StringView line = read_line();
165 tokenize(line); 332 Object *ast = build_ast(tokenize(line));
166 display(line); 333 if (ast) {
334 display(ast);
335 printf("\n");
336 }
167 } 337 }
168 return 0; 338 return 0;
169} 339}