diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/badlib.h | 2 | ||||
-rw-r--r-- | src/lexer.c | 39 | ||||
-rw-r--r-- | src/main.c | 88 |
3 files changed, 31 insertions, 98 deletions
diff --git a/src/badlib.h b/src/badlib.h index 4944d2e..9802278 100644 --- a/src/badlib.h +++ b/src/badlib.h | |||
@@ -970,7 +970,7 @@ platform_read_file(Str path, Arena *a) { | |||
970 | 970 | ||
971 | // Read the entire file into memory. | 971 | // Read the entire file into memory. |
972 | sz file_size = 0; | 972 | sz file_size = 0; |
973 | FILE *fp = fopen((char*)path_str.mem, "rb+"); | 973 | FILE *fp = fopen((char *)path_str.mem, "rb+"); |
974 | if (!fp) { | 974 | if (!fp) { |
975 | return (FileContents){ | 975 | return (FileContents){ |
976 | .path = path, | 976 | .path = path, |
diff --git a/src/lexer.c b/src/lexer.c index 6a5621c..404082b 100644 --- a/src/lexer.c +++ b/src/lexer.c | |||
@@ -406,18 +406,12 @@ scan_token(Scanner *scanner) { | |||
406 | Scanner current = *scanner; | 406 | Scanner current = *scanner; |
407 | char c = scan_next(scanner); | 407 | char c = scan_next(scanner); |
408 | switch (c) { | 408 | switch (c) { |
409 | case '(': | 409 | case '(': return emit_token(current, scanner, TOK_LPAREN); |
410 | return emit_token(current, scanner, TOK_LPAREN); | 410 | case ')': return emit_token(current, scanner, TOK_RPAREN); |
411 | case ')': | 411 | case '[': return emit_token(current, scanner, TOK_LSQUARE); |
412 | return emit_token(current, scanner, TOK_RPAREN); | 412 | case ']': return emit_token(current, scanner, TOK_RSQUARE); |
413 | case '[': | 413 | case '{': return emit_token(current, scanner, TOK_LCURLY); |
414 | return emit_token(current, scanner, TOK_LSQUARE); | 414 | case '}': return emit_token(current, scanner, TOK_RCURLY); |
415 | case ']': | ||
416 | return emit_token(current, scanner, TOK_RSQUARE); | ||
417 | case '{': | ||
418 | return emit_token(current, scanner, TOK_LCURLY); | ||
419 | case '}': | ||
420 | return emit_token(current, scanner, TOK_RCURLY); | ||
421 | case '+': { | 415 | case '+': { |
422 | char p = scan_peek(scanner); | 416 | char p = scan_peek(scanner); |
423 | if (p >= '0' && p <= '9') { | 417 | if (p >= '0' && p <= '9') { |
@@ -434,12 +428,9 @@ scan_token(Scanner *scanner) { | |||
434 | } | 428 | } |
435 | return emit_token(current, scanner, TOK_SUB); | 429 | return emit_token(current, scanner, TOK_SUB); |
436 | }; | 430 | }; |
437 | case '*': | 431 | case '*': return emit_token(current, scanner, TOK_MUL); |
438 | return emit_token(current, scanner, TOK_MUL); | 432 | case '/': return emit_token(current, scanner, TOK_DIV); |
439 | case '/': | 433 | case '%': return emit_token(current, scanner, TOK_MOD); |
440 | return emit_token(current, scanner, TOK_DIV); | ||
441 | case '%': | ||
442 | return emit_token(current, scanner, TOK_MOD); | ||
443 | case '!': { | 434 | case '!': { |
444 | if (scan_peek(scanner) == '=') { | 435 | if (scan_peek(scanner) == '=') { |
445 | scan_next(scanner); | 436 | scan_next(scanner); |
@@ -478,8 +469,7 @@ scan_token(Scanner *scanner) { | |||
478 | } | 469 | } |
479 | return emit_token(current, scanner, TOK_GT); | 470 | return emit_token(current, scanner, TOK_GT); |
480 | }; | 471 | }; |
481 | case '~': | 472 | case '~': return emit_token(current, scanner, TOK_BITNOT); |
482 | return emit_token(current, scanner, TOK_BITNOT); | ||
483 | case '&': { | 473 | case '&': { |
484 | if (scan_peek(scanner) == '&') { | 474 | if (scan_peek(scanner) == '&') { |
485 | scan_next(scanner); | 475 | scan_next(scanner); |
@@ -494,12 +484,9 @@ scan_token(Scanner *scanner) { | |||
494 | } | 484 | } |
495 | return emit_token(current, scanner, TOK_BITOR); | 485 | return emit_token(current, scanner, TOK_BITOR); |
496 | }; | 486 | }; |
497 | case ':': | 487 | case ':': return emit_token(current, scanner, TOK_COLON); |
498 | return emit_token(current, scanner, TOK_COLON); | 488 | case '.': return emit_token(current, scanner, TOK_DOT); |
499 | case '.': | 489 | case '@': return emit_token(current, scanner, TOK_AT); |
500 | return emit_token(current, scanner, TOK_DOT); | ||
501 | case '@': | ||
502 | return emit_token(current, scanner, TOK_AT); | ||
503 | case '"': { | 490 | case '"': { |
504 | while (scan_has_next(scanner)) { | 491 | while (scan_has_next(scanner)) { |
505 | c = scan_next(scanner); | 492 | c = scan_next(scanner); |
@@ -81,49 +81,6 @@ node_alloc(NodeKind kind, Token tok, Arena *a) { | |||
81 | return node; | 81 | return node; |
82 | } | 82 | } |
83 | 83 | ||
84 | void | ||
85 | print_node(Node *node) { | ||
86 | if (!node) { | ||
87 | return; | ||
88 | } | ||
89 | switch (node->kind) { | ||
90 | case NODE_NUMBER: { | ||
91 | print("%d", node->value.i); | ||
92 | } break; | ||
93 | case NODE_ADD: { | ||
94 | print("(+ "); | ||
95 | print_node(node->left); | ||
96 | print(" "); | ||
97 | print_node(node->right); | ||
98 | print(")"); | ||
99 | } break; | ||
100 | case NODE_SUB: { | ||
101 | print("(- "); | ||
102 | print_node(node->left); | ||
103 | print(" "); | ||
104 | print_node(node->right); | ||
105 | print(")"); | ||
106 | } break; | ||
107 | case NODE_DIV: { | ||
108 | print("(/ "); | ||
109 | print_node(node->left); | ||
110 | print(" "); | ||
111 | print_node(node->right); | ||
112 | print(")"); | ||
113 | } break; | ||
114 | case NODE_MUL: { | ||
115 | print("(* "); | ||
116 | print_node(node->left); | ||
117 | print(" "); | ||
118 | print_node(node->right); | ||
119 | print(")"); | ||
120 | } break; | ||
121 | default: { | ||
122 | eprintln("error: unknown node kind: %d", node->kind); | ||
123 | } break; | ||
124 | } | ||
125 | } | ||
126 | |||
127 | // | 84 | // |
128 | // Parsing. | 85 | // Parsing. |
129 | // | 86 | // |
@@ -239,47 +196,39 @@ parse_prec(Parser *parser, ParsePrecedence precedence) { | |||
239 | 196 | ||
240 | void | 197 | void |
241 | parse_unary(Parser *parser) { | 198 | parse_unary(Parser *parser) { |
199 | Token prev = parser->previous; | ||
242 | #if DEBUG == 1 | 200 | #if DEBUG == 1 |
243 | print("parsing unary "); | 201 | print("parsing unary "); |
244 | print_token(parser->previous); | 202 | print_token(prev); |
245 | #endif | 203 | #endif |
246 | parse_prec(parser, PREC_ASSIGNMENT); | ||
247 | TokenKind kind = parser->previous.kind; | 204 | TokenKind kind = parser->previous.kind; |
248 | parse_expr(parser); | 205 | parse_expr(parser); |
249 | // TODO: ... | 206 | // TODO: ... |
250 | switch (kind) { | 207 | switch (kind) { |
251 | // case TOKEN_MINUS: emitByte(OP_NEGATE); break; | 208 | // case TOKEN_MINUS: emitByte(OP_NEGATE); break; |
252 | default: | 209 | default: return; // Unreachable. |
253 | return; // Unreachable. | ||
254 | } | 210 | } |
255 | } | 211 | } |
256 | 212 | ||
257 | void | 213 | void |
258 | parse_binary(Parser *parser) { | 214 | parse_binary(Parser *parser) { |
215 | Token prev = parser->previous; | ||
259 | #if DEBUG == 1 | 216 | #if DEBUG == 1 |
260 | print("parsing binary "); | 217 | print("parsing binary "); |
261 | print_token(parser->previous); | 218 | print_token(prev); |
262 | #endif | 219 | #endif |
263 | TokenKind kind = parser->previous.kind; | 220 | TokenKind kind = prev.kind; |
264 | ParseRule rule = parse_rules[kind]; | 221 | ParseRule rule = parse_rules[kind]; |
265 | parse_prec(parser, rule.precedence + 1); | 222 | parse_prec(parser, rule.precedence + 1); |
266 | 223 | ||
267 | Node *node; | 224 | Node *node; |
268 | switch (kind) { | 225 | switch (kind) { |
269 | case TOK_ADD: { | 226 | case TOK_ADD: node = node_alloc(NODE_ADD, prev, parser->storage); break; |
270 | node = node_alloc(NODE_ADD, parser->previous, parser->storage); | 227 | case TOK_SUB: node = node_alloc(NODE_SUB, prev, parser->storage); break; |
271 | } break; | 228 | case TOK_MUL: node = node_alloc(NODE_MUL, prev, parser->storage); break; |
272 | case TOK_SUB: { | 229 | case TOK_DIV: node = node_alloc(NODE_DIV, prev, parser->storage); break; |
273 | node = node_alloc(NODE_SUB, parser->previous, parser->storage); | ||
274 | } break; | ||
275 | case TOK_MUL: { | ||
276 | node = node_alloc(NODE_MUL, parser->previous, parser->storage); | ||
277 | } break; | ||
278 | case TOK_DIV: { | ||
279 | node = node_alloc(NODE_DIV, parser->previous, parser->storage); | ||
280 | } break; | ||
281 | default: { | 230 | default: { |
282 | parse_emit_err(parser, parser->previous, cstr("unreachable")); | 231 | parse_emit_err(parser, prev, cstr("unreachable")); |
283 | return; | 232 | return; |
284 | } | 233 | } |
285 | } | 234 | } |
@@ -290,12 +239,13 @@ parse_binary(Parser *parser) { | |||
290 | 239 | ||
291 | void | 240 | void |
292 | parse_number(Parser *parser) { | 241 | parse_number(Parser *parser) { |
242 | Token prev = parser->previous; | ||
293 | #if DEBUG == 1 | 243 | #if DEBUG == 1 |
294 | print("parsing number "); | 244 | print("parsing number "); |
295 | print_token(parser->previous); | 245 | print_token(prev); |
296 | #endif | 246 | #endif |
297 | Node *node = node_alloc(NODE_NUMBER, parser->previous, parser->storage); | 247 | Node *node = node_alloc(NODE_NUMBER, prev, parser->storage); |
298 | node->value.i = str_to_int(parser->previous.val); | 248 | node->value.i = str_to_int(prev.val); |
299 | // TODO: handle sign and/or floating point values. | 249 | // TODO: handle sign and/or floating point values. |
300 | array_push(parser->nodes, node, parser->storage); | 250 | array_push(parser->nodes, node, parser->storage); |
301 | } | 251 | } |
@@ -324,11 +274,8 @@ graph_node(Node *node) { | |||
324 | print("%d [width=2.5,shape=Mrecord,label=\"", node->id); | 274 | print("%d [width=2.5,shape=Mrecord,label=\"", node->id); |
325 | print("<top> %s ", node_str[node->kind]); | 275 | print("<top> %s ", node_str[node->kind]); |
326 | switch (node->kind) { | 276 | switch (node->kind) { |
327 | case NODE_NUMBER: { | 277 | case NODE_NUMBER: print("| Value: %d", node->value.i); break; |
328 | print("| Value: %d", node->value.i); | 278 | default: break; |
329 | } break; | ||
330 | default: | ||
331 | break; | ||
332 | } | 279 | } |
333 | print("| Line: %d | Col: %d ", node->line, node->col); | 280 | print("| Line: %d | Col: %d ", node->line, node->col); |
334 | println("\"];"); | 281 | println("\"];"); |
@@ -415,7 +362,6 @@ process_file(Str path) { | |||
415 | for (sz i = 0; i < n_roots; i++) { | 362 | for (sz i = 0; i < n_roots; i++) { |
416 | // The parser stores the root nodes as a stack. | 363 | // The parser stores the root nodes as a stack. |
417 | Node *root = parser.nodes[i]; | 364 | Node *root = parser.nodes[i]; |
418 | print_node(root); println(""); | ||
419 | (void)root; | 365 | (void)root; |
420 | } | 366 | } |
421 | parse_consume(&parser, TOK_EOF, cstr("expected end of file")); | 367 | parse_consume(&parser, TOK_EOF, cstr("expected end of file")); |