diff options
author | Bad Diode <bd@badd10de.dev> | 2022-04-03 17:16:26 -0300 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2022-04-03 17:16:26 -0300 |
commit | 496ec36c8002a85dc0c3bb62de6d176e369b40af (patch) | |
tree | c9247f637ae77bd07516490f4101becaad6a0111 /src | |
parent | 483a64aa0c5ee8dc925b7957e39c42744b892288 (diff) | |
download | bdl-496ec36c8002a85dc0c3bb62de6d176e369b40af.tar.gz bdl-496ec36c8002a85dc0c3bb62de6d176e369b40af.zip |
Add parsing for (set ...) statements
Diffstat (limited to 'src')
-rw-r--r-- | src/lexer.c | 2 | ||||
-rw-r--r-- | src/nodes.c | 7 | ||||
-rw-r--r-- | src/nodes.h | 6 | ||||
-rw-r--r-- | src/parser.c | 33 |
4 files changed, 47 insertions, 1 deletions
diff --git a/src/lexer.c b/src/lexer.c index 2ccd577..729ea14 100644 --- a/src/lexer.c +++ b/src/lexer.c | |||
@@ -50,7 +50,7 @@ static const Keyword keywords[] = { | |||
50 | KEYWORD("lambda", TOKEN_LAMBDA), | 50 | KEYWORD("lambda", TOKEN_LAMBDA), |
51 | KEYWORD("if", TOKEN_IF), | 51 | KEYWORD("if", TOKEN_IF), |
52 | KEYWORD("def", TOKEN_DEF), | 52 | KEYWORD("def", TOKEN_DEF), |
53 | KEYWORD("set!", TOKEN_SET), | 53 | KEYWORD("set", TOKEN_SET), |
54 | KEYWORD("fun", TOKEN_FUN), | 54 | KEYWORD("fun", TOKEN_FUN), |
55 | KEYWORD("struct", TOKEN_STRUCT), | 55 | KEYWORD("struct", TOKEN_STRUCT), |
56 | KEYWORD("+", TOKEN_ADD), | 56 | KEYWORD("+", TOKEN_ADD), |
diff --git a/src/nodes.c b/src/nodes.c index 63e9b1f..855d186 100644 --- a/src/nodes.c +++ b/src/nodes.c | |||
@@ -56,6 +56,13 @@ print_node(Node *node) { | |||
56 | print_node(node->def.value); | 56 | print_node(node->def.value); |
57 | printf(")"); | 57 | printf(")"); |
58 | } break; | 58 | } break; |
59 | case NODE_SET: { | ||
60 | printf("(set "); | ||
61 | print_node(node->def.symbol); | ||
62 | printf(" "); | ||
63 | print_node(node->def.value); | ||
64 | printf(")"); | ||
65 | } break; | ||
59 | default: { printf("{#unknown#}"); } break; | 66 | default: { printf("{#unknown#}"); } break; |
60 | } | 67 | } |
61 | } | 68 | } |
diff --git a/src/nodes.h b/src/nodes.h index e6ceb50..566d6d3 100644 --- a/src/nodes.h +++ b/src/nodes.h | |||
@@ -8,6 +8,7 @@ typedef enum NodeType { | |||
8 | NODE_STRING, | 8 | NODE_STRING, |
9 | NODE_SYMBOL, | 9 | NODE_SYMBOL, |
10 | NODE_DEF, | 10 | NODE_DEF, |
11 | NODE_SET, | ||
11 | } NodeType; | 12 | } NodeType; |
12 | 13 | ||
13 | typedef struct Node { | 14 | typedef struct Node { |
@@ -39,6 +40,11 @@ typedef struct Node { | |||
39 | struct Node *value; | 40 | struct Node *value; |
40 | StringView type; | 41 | StringView type; |
41 | } def; | 42 | } def; |
43 | |||
44 | struct { | ||
45 | struct Node *symbol; | ||
46 | struct Node *value; | ||
47 | } set; | ||
42 | }; | 48 | }; |
43 | } Node; | 49 | } Node; |
44 | 50 | ||
diff --git a/src/parser.c b/src/parser.c index cc94fd2..b36ddc9 100644 --- a/src/parser.c +++ b/src/parser.c | |||
@@ -178,6 +178,33 @@ parse_def(Parser *parser) { | |||
178 | } | 178 | } |
179 | 179 | ||
180 | Node * | 180 | Node * |
181 | parse_set(Parser *parser) { | ||
182 | Token op = next_token(parser); | ||
183 | Node *symbol = parse_next(parser); | ||
184 | if (symbol == NULL || symbol->type != NODE_SYMBOL) { | ||
185 | push_error(ERR_TYPE_PARSER, ERR_MALFORMED_EXPR, op.line, op.col); | ||
186 | return NULL; | ||
187 | } | ||
188 | |||
189 | Node *value = parse_next(parser); | ||
190 | if (value == NULL) { | ||
191 | push_error(ERR_TYPE_PARSER, ERR_MALFORMED_EXPR, op.line, op.col); | ||
192 | return NULL; | ||
193 | } | ||
194 | |||
195 | Token end = next_token(parser); | ||
196 | if (end.type != TOKEN_RPAREN) { | ||
197 | push_error(ERR_TYPE_PARSER, ERR_MALFORMED_EXPR, op.line, op.col); | ||
198 | return NULL; | ||
199 | } | ||
200 | |||
201 | Node *node = alloc_node(NODE_SET); | ||
202 | node->set.symbol = symbol; | ||
203 | node->set.value = value; | ||
204 | return node; | ||
205 | } | ||
206 | |||
207 | Node * | ||
181 | parse_paren(Parser *parser) { | 208 | parse_paren(Parser *parser) { |
182 | next_token(parser); // Skip paren. | 209 | next_token(parser); // Skip paren. |
183 | Token tok = peek_token(parser); | 210 | Token tok = peek_token(parser); |
@@ -194,6 +221,7 @@ parse_paren(Parser *parser) { | |||
194 | case TOKEN_OR: { return parse_builtin(parser); } break; | 221 | case TOKEN_OR: { return parse_builtin(parser); } break; |
195 | // Special functions. | 222 | // Special functions. |
196 | case TOKEN_DEF: { return parse_def(parser); } break; | 223 | case TOKEN_DEF: { return parse_def(parser); } break; |
224 | case TOKEN_SET: { return parse_set(parser); } break; | ||
197 | default: break; | 225 | default: break; |
198 | } | 226 | } |
199 | 227 | ||
@@ -202,6 +230,11 @@ parse_paren(Parser *parser) { | |||
202 | return NULL; | 230 | return NULL; |
203 | } | 231 | } |
204 | 232 | ||
233 | |||
234 | // TODO: Parse if: (def ...) shouldn't be allowed for now on if statements. In | ||
235 | // the future, an if can create a new block and thus a fresh scope which would | ||
236 | // make the decision of what variables are active trivial. | ||
237 | |||
205 | Node * | 238 | Node * |
206 | parse_next(Parser *parser) { | 239 | parse_next(Parser *parser) { |
207 | Token tok = peek_token(parser); | 240 | Token tok = peek_token(parser); |