aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2022-04-03 17:16:26 -0300
committerBad Diode <bd@badd10de.dev>2022-04-03 17:16:26 -0300
commit496ec36c8002a85dc0c3bb62de6d176e369b40af (patch)
treec9247f637ae77bd07516490f4101becaad6a0111 /src
parent483a64aa0c5ee8dc925b7957e39c42744b892288 (diff)
downloadbdl-496ec36c8002a85dc0c3bb62de6d176e369b40af.tar.gz
bdl-496ec36c8002a85dc0c3bb62de6d176e369b40af.zip
Add parsing for (set ...) statements
Diffstat (limited to 'src')
-rw-r--r--src/lexer.c2
-rw-r--r--src/nodes.c7
-rw-r--r--src/nodes.h6
-rw-r--r--src/parser.c33
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
13typedef struct Node { 14typedef 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
180Node * 180Node *
181parse_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
207Node *
181parse_paren(Parser *parser) { 208parse_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
205Node * 238Node *
206parse_next(Parser *parser) { 239parse_next(Parser *parser) {
207 Token tok = peek_token(parser); 240 Token tok = peek_token(parser);