aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2022-04-06 08:02:52 -0300
committerBad Diode <bd@badd10de.dev>2022-04-06 08:02:52 -0300
commit11df0f4556f526189234be216fa16a2fcb8c308b (patch)
treed9459ebf0b99ef1ecadf4101da147d60935e916f /src
parent77b309ba82d090094f5f753342c3aa401cbf657d (diff)
downloadbdl-11df0f4556f526189234be216fa16a2fcb8c308b.tar.gz
bdl-11df0f4556f526189234be216fa16a2fcb8c308b.zip
Add parsing of if statements
Diffstat (limited to 'src')
-rw-r--r--src/lexer.c10
-rw-r--r--src/lexer.h5
-rw-r--r--src/nodes.c14
-rw-r--r--src/nodes.h8
-rw-r--r--src/parser.c51
5 files changed, 86 insertions, 2 deletions
diff --git a/src/lexer.c b/src/lexer.c
index 729ea14..b4dcaf5 100644
--- a/src/lexer.c
+++ b/src/lexer.c
@@ -29,6 +29,11 @@ static const char* token_str[] = {
29 [TOKEN_NOT] = "TOKEN_NOT", 29 [TOKEN_NOT] = "TOKEN_NOT",
30 [TOKEN_AND] = "TOKEN_AND", 30 [TOKEN_AND] = "TOKEN_AND",
31 [TOKEN_OR] = "TOKEN_OR", 31 [TOKEN_OR] = "TOKEN_OR",
32 [TOKEN_EQ] = "TOKEN_EQ",
33 [TOKEN_LT] = "TOKEN_LT",
34 [TOKEN_GT] = "TOKEN_GT",
35 [TOKEN_LE] = "TOKEN_LE",
36 [TOKEN_GE] = "TOKEN_GE",
32 [TOKEN_COLON] = "TOKEN_COLON", 37 [TOKEN_COLON] = "TOKEN_COLON",
33 [TOKEN_DOT] = "TOKEN_DOT", 38 [TOKEN_DOT] = "TOKEN_DOT",
34 [TOKEN_AT] = "TOKEN_AT", 39 [TOKEN_AT] = "TOKEN_AT",
@@ -61,6 +66,11 @@ static const Keyword keywords[] = {
61 KEYWORD("not", TOKEN_NOT), 66 KEYWORD("not", TOKEN_NOT),
62 KEYWORD("and", TOKEN_AND), 67 KEYWORD("and", TOKEN_AND),
63 KEYWORD("or", TOKEN_OR), 68 KEYWORD("or", TOKEN_OR),
69 KEYWORD("=", TOKEN_EQ),
70 KEYWORD("<", TOKEN_LT),
71 KEYWORD(">", TOKEN_GT),
72 KEYWORD("<=", TOKEN_LE),
73 KEYWORD(">=", TOKEN_GE),
64}; 74};
65 75
66void 76void
diff --git a/src/lexer.h b/src/lexer.h
index fa43ebb..949abaf 100644
--- a/src/lexer.h
+++ b/src/lexer.h
@@ -41,6 +41,11 @@ typedef enum TokenType {
41 TOKEN_NOT, 41 TOKEN_NOT,
42 TOKEN_AND, 42 TOKEN_AND,
43 TOKEN_OR, 43 TOKEN_OR,
44 TOKEN_EQ,
45 TOKEN_LT,
46 TOKEN_GT,
47 TOKEN_LE,
48 TOKEN_GE,
44 49
45 // Special operators. 50 // Special operators.
46 TOKEN_COLON, 51 TOKEN_COLON,
diff --git a/src/nodes.c b/src/nodes.c
index 3a63246..af3b772 100644
--- a/src/nodes.c
+++ b/src/nodes.c
@@ -11,6 +11,9 @@ alloc_node(NodeType type) {
11 11
12void 12void
13print_node(Node *node) { 13print_node(Node *node) {
14 if (node == NULL) {
15 return;
16 }
14 switch (node->type) { 17 switch (node->type) {
15 case NODE_NUMBER: { 18 case NODE_NUMBER: {
16 if (node->number.negative) { 19 if (node->number.negative) {
@@ -73,6 +76,17 @@ print_node(Node *node) {
73 } 76 }
74 printf(" }"); 77 printf(" }");
75 } break; 78 } break;
79 case NODE_IF: {
80 printf("(if ");
81 print_node(node->ifexpr.cond);
82 printf(" ");
83 print_node(node->ifexpr.expr_true);
84 if (node->ifexpr.expr_false != NULL) {
85 printf(" ");
86 print_node(node->ifexpr.expr_false);
87 }
88 printf(")");
89 } break;
76 case NODE_FUN: { 90 case NODE_FUN: {
77 printf("(fun "); 91 printf("(fun ");
78 print_node(node->fun.name); 92 print_node(node->fun.name);
diff --git a/src/nodes.h b/src/nodes.h
index c1520b3..4fb48a1 100644
--- a/src/nodes.h
+++ b/src/nodes.h
@@ -12,6 +12,7 @@ typedef enum NodeType {
12 NODE_SET, 12 NODE_SET,
13 NODE_FUN, 13 NODE_FUN,
14 NODE_BLOCK, 14 NODE_BLOCK,
15 NODE_IF,
15} NodeType; 16} NodeType;
16 17
17typedef struct Node { 18typedef struct Node {
@@ -63,6 +64,13 @@ typedef struct Node {
63 struct { 64 struct {
64 struct Node **expr; 65 struct Node **expr;
65 } block; 66 } block;
67
68 // If statement.
69 struct {
70 struct Node *cond;
71 struct Node *expr_true;
72 struct Node *expr_false;
73 } ifexpr;
66 }; 74 };
67} Node; 75} Node;
68 76
diff --git a/src/parser.c b/src/parser.c
index 58ad722..b76e32f 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -291,7 +291,46 @@ parse_fun(Parser *parser) {
291 return NULL; 291 return NULL;
292 } 292 }
293 node->fun.body = body; 293 node->fun.body = body;
294 consume_rparen(parser); 294 if (!consume_rparen(parser)) {
295 return NULL;
296 }
297
298 return node;
299}
300
301Node *
302parse_if(Parser *parser) {
303 next_token(parser); // Skip keyword.
304
305 Node *node = alloc_node(NODE_IF);
306 node->ifexpr.cond = NULL;
307 node->ifexpr.expr_true = NULL;
308 node->ifexpr.expr_false = NULL;
309
310 Node *cond = parse_next(parser);
311 if (cond == NULL) {
312 return NULL;
313 }
314 Node *expr_true = parse_next(parser);
315 if (expr_true == NULL) {
316 return NULL;
317 }
318 node->ifexpr.cond = cond;
319 node->ifexpr.expr_true = expr_true;
320 Token tok = peek_token(parser);
321
322 // Optional else statement.
323 if (tok.type != TOKEN_RPAREN) {
324 Node *expr_false = parse_next(parser);
325 if (expr_false == NULL) {
326 return NULL;
327 }
328 node->ifexpr.expr_false = expr_false;
329 }
330
331 if (!consume_rparen(parser)) {
332 return NULL;
333 }
295 334
296 return node; 335 return node;
297} 336}
@@ -299,6 +338,7 @@ parse_fun(Parser *parser) {
299Node * 338Node *
300parse_paren(Parser *parser) { 339parse_paren(Parser *parser) {
301 next_token(parser); // Skip paren. 340 next_token(parser); // Skip paren.
341
302 Token tok = peek_token(parser); 342 Token tok = peek_token(parser);
303 343
304 switch (tok.type) { 344 switch (tok.type) {
@@ -310,11 +350,17 @@ parse_paren(Parser *parser) {
310 case TOKEN_MOD: 350 case TOKEN_MOD:
311 case TOKEN_NOT: 351 case TOKEN_NOT:
312 case TOKEN_AND: 352 case TOKEN_AND:
313 case TOKEN_OR: { return parse_builtin(parser); } break; 353 case TOKEN_OR:
354 case TOKEN_EQ:
355 case TOKEN_LT:
356 case TOKEN_GT:
357 case TOKEN_LE:
358 case TOKEN_GE: { return parse_builtin(parser); } break;
314 // Special functions. 359 // Special functions.
315 case TOKEN_DEF: { return parse_def(parser); } break; 360 case TOKEN_DEF: { return parse_def(parser); } break;
316 case TOKEN_SET: { return parse_set(parser); } break; 361 case TOKEN_SET: { return parse_set(parser); } break;
317 case TOKEN_FUN: { return parse_fun(parser); } break; 362 case TOKEN_FUN: { return parse_fun(parser); } break;
363 case TOKEN_IF: { return parse_if(parser); } break;
318 default: break; 364 default: break;
319 } 365 }
320 366
@@ -326,6 +372,7 @@ parse_paren(Parser *parser) {
326Node * 372Node *
327parse_block(Parser *parser) { 373parse_block(Parser *parser) {
328 next_token(parser); // Skip paren. 374 next_token(parser); // Skip paren.
375
329 Node *node = alloc_node(NODE_BLOCK); 376 Node *node = alloc_node(NODE_BLOCK);
330 array_init(node->block.expr, 0); 377 array_init(node->block.expr, 0);
331 while (true) { 378 while (true) {