diff options
author | Bad Diode <bd@badd10de.dev> | 2022-03-30 17:07:12 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2022-03-30 17:07:12 +0200 |
commit | 4b2cb6a1bdd2667ba827d17dde5fad955f2250bf (patch) | |
tree | 70a2038c2d823d0a54a70ab2f1633b51dc44967e /src | |
parent | f585af63190b3eb5a3337fb1667da72c7f5b5eca (diff) | |
download | bdl-4b2cb6a1bdd2667ba827d17dde5fad955f2250bf.tar.gz bdl-4b2cb6a1bdd2667ba827d17dde5fad955f2250bf.zip |
Add initial parsing of variable definitions
Diffstat (limited to 'src')
-rw-r--r-- | src/errors.c | 1 | ||||
-rw-r--r-- | src/errors.h | 1 | ||||
-rw-r--r-- | src/parser.c | 65 | ||||
-rw-r--r-- | src/parser.h | 10 |
4 files changed, 72 insertions, 5 deletions
diff --git a/src/errors.c b/src/errors.c index 10b5ce1..e69e4f9 100644 --- a/src/errors.c +++ b/src/errors.c | |||
@@ -6,6 +6,7 @@ static const char* error_msgs[] = { | |||
6 | [ERR_UNMATCHED_PAREN] = "error: unbalanced parentheses", | 6 | [ERR_UNMATCHED_PAREN] = "error: unbalanced parentheses", |
7 | [ERR_UNKNOWN_TOK_TYPE] = "error: unknown token type", | 7 | [ERR_UNKNOWN_TOK_TYPE] = "error: unknown token type", |
8 | [ERR_MALFORMED_NUMBER] = "error: malformed number token", | 8 | [ERR_MALFORMED_NUMBER] = "error: malformed number token", |
9 | [ERR_MALFORMED_EXPR] = "error: malformed expression", | ||
9 | [ERR_UNIMPLEMENTED] = "error: not implemented", | 10 | [ERR_UNIMPLEMENTED] = "error: not implemented", |
10 | }; | 11 | }; |
11 | 12 | ||
diff --git a/src/errors.h b/src/errors.h index 155bb98..25f9945 100644 --- a/src/errors.h +++ b/src/errors.h | |||
@@ -14,6 +14,7 @@ typedef enum ErrorValue { | |||
14 | ERR_UNKNOWN_TOK_TYPE, | 14 | ERR_UNKNOWN_TOK_TYPE, |
15 | ERR_UNMATCHED_PAREN, | 15 | ERR_UNMATCHED_PAREN, |
16 | ERR_MALFORMED_NUMBER, | 16 | ERR_MALFORMED_NUMBER, |
17 | ERR_MALFORMED_EXPR, | ||
17 | ERR_UNIMPLEMENTED, | 18 | ERR_UNIMPLEMENTED, |
18 | ERR_OK, | 19 | ERR_OK, |
19 | } ErrorValue; | 20 | } ErrorValue; |
diff --git a/src/parser.c b/src/parser.c index 9703061..0b62ce4 100644 --- a/src/parser.c +++ b/src/parser.c | |||
@@ -108,6 +108,14 @@ parse_string(Parser *parser) { | |||
108 | } | 108 | } |
109 | 109 | ||
110 | Node * | 110 | Node * |
111 | parse_symbol(Parser *parser) { | ||
112 | Token tok = next_token(parser); | ||
113 | Node *node = alloc_node(NODE_SYMBOL); | ||
114 | node->string = tok.value; | ||
115 | return node; | ||
116 | } | ||
117 | |||
118 | Node * | ||
111 | parse_bool(Parser *parser) { | 119 | parse_bool(Parser *parser) { |
112 | Token tok = next_token(parser); | 120 | Token tok = next_token(parser); |
113 | Node *node = alloc_node(NODE_BOOL); | 121 | Node *node = alloc_node(NODE_BOOL); |
@@ -138,11 +146,44 @@ parse_builtin(Parser *parser) { | |||
138 | } | 146 | } |
139 | 147 | ||
140 | Node * | 148 | Node * |
149 | parse_def(Parser *parser) { | ||
150 | Token op = next_token(parser); | ||
151 | Node *symbol = parse_next(parser); | ||
152 | if (symbol == NULL || symbol->type != NODE_SYMBOL) { | ||
153 | push_error(ERR_TYPE_PARSER, ERR_MALFORMED_EXPR, op.line, op.col); | ||
154 | return NULL; | ||
155 | } | ||
156 | |||
157 | // TODO: Check if it has type annotation. | ||
158 | |||
159 | Node *value = parse_next(parser); | ||
160 | if (value == NULL) { | ||
161 | push_error(ERR_TYPE_PARSER, ERR_MALFORMED_EXPR, op.line, op.col); | ||
162 | return NULL; | ||
163 | } | ||
164 | |||
165 | Token end = next_token(parser); | ||
166 | if (end.type != TOKEN_RPAREN) { | ||
167 | push_error(ERR_TYPE_PARSER, ERR_MALFORMED_EXPR, op.line, op.col); | ||
168 | return NULL; | ||
169 | } | ||
170 | |||
171 | Node *node = alloc_node(NODE_DEF); | ||
172 | node->def.symbol = symbol; | ||
173 | node->def.value = value; | ||
174 | |||
175 | // TODO: Register variable in symbol table. | ||
176 | |||
177 | return node; | ||
178 | } | ||
179 | |||
180 | Node * | ||
141 | parse_paren(Parser *parser) { | 181 | parse_paren(Parser *parser) { |
142 | next_token(parser); // Skip paren. | 182 | next_token(parser); // Skip paren. |
143 | Token tok = peek_token(parser); | 183 | Token tok = peek_token(parser); |
144 | // TODO: is keyword? | 184 | |
145 | switch (tok.type) { | 185 | switch (tok.type) { |
186 | // Builtin functions. | ||
146 | case TOKEN_ADD: | 187 | case TOKEN_ADD: |
147 | case TOKEN_SUB: | 188 | case TOKEN_SUB: |
148 | case TOKEN_MUL: | 189 | case TOKEN_MUL: |
@@ -153,11 +194,16 @@ parse_paren(Parser *parser) { | |||
153 | case TOKEN_OR: { | 194 | case TOKEN_OR: { |
154 | return parse_builtin(parser); | 195 | return parse_builtin(parser); |
155 | } break; | 196 | } break; |
197 | // Special functions. | ||
198 | case TOKEN_DEF: { | ||
199 | return parse_def(parser); | ||
200 | } break; | ||
156 | default: break; | 201 | default: break; |
157 | } | 202 | } |
158 | // print_token(tok); | 203 | |
159 | // TODO: is in symbol table and its value is a function? | 204 | // TODO: Lookup value on symbol table. |
160 | return NULL; // TODO: Not implemented | 205 | push_error(ERR_TYPE_PARSER, ERR_UNIMPLEMENTED, tok.line, tok.col); |
206 | return NULL; | ||
161 | } | 207 | } |
162 | 208 | ||
163 | Node * | 209 | Node * |
@@ -170,6 +216,9 @@ parse_next(Parser *parser) { | |||
170 | case TOKEN_STRING: { | 216 | case TOKEN_STRING: { |
171 | return parse_string(parser); | 217 | return parse_string(parser); |
172 | } break; | 218 | } break; |
219 | case TOKEN_SYMBOL: { | ||
220 | return parse_symbol(parser); | ||
221 | } break; | ||
173 | case TOKEN_TRUE: | 222 | case TOKEN_TRUE: |
174 | case TOKEN_FALSE: { | 223 | case TOKEN_FALSE: { |
175 | return parse_bool(parser); | 224 | return parse_bool(parser); |
@@ -200,6 +249,7 @@ print_node(Node *node) { | |||
200 | printf("%zu", node->number.integral); | 249 | printf("%zu", node->number.integral); |
201 | } | 250 | } |
202 | } break; | 251 | } break; |
252 | case NODE_SYMBOL: | ||
203 | case NODE_STRING: { | 253 | case NODE_STRING: { |
204 | sv_write(&node->string); | 254 | sv_write(&node->string); |
205 | } break; | 255 | } break; |
@@ -225,6 +275,13 @@ print_node(Node *node) { | |||
225 | } | 275 | } |
226 | printf(")"); | 276 | printf(")"); |
227 | } break; | 277 | } break; |
278 | case NODE_DEF: { | ||
279 | printf("(def "); | ||
280 | print_node(node->def.symbol); | ||
281 | printf(" "); | ||
282 | print_node(node->def.value); | ||
283 | printf(")"); | ||
284 | } break; | ||
228 | default: { printf("{#unk}"); } break; | 285 | default: { printf("{#unk}"); } break; |
229 | } | 286 | } |
230 | } | 287 | } |
diff --git a/src/parser.h b/src/parser.h index c275195..de712e1 100644 --- a/src/parser.h +++ b/src/parser.h | |||
@@ -9,11 +9,12 @@ typedef struct Parser { | |||
9 | } Parser; | 9 | } Parser; |
10 | 10 | ||
11 | typedef enum NodeType { | 11 | typedef enum NodeType { |
12 | // NODE_FUNCALL, | ||
13 | NODE_BUILTIN, | 12 | NODE_BUILTIN, |
14 | NODE_NUMBER, | 13 | NODE_NUMBER, |
15 | NODE_BOOL, | 14 | NODE_BOOL, |
16 | NODE_STRING, | 15 | NODE_STRING, |
16 | NODE_SYMBOL, | ||
17 | NODE_DEF, | ||
17 | } NodeType; | 18 | } NodeType; |
18 | 19 | ||
19 | typedef struct Node { | 20 | typedef struct Node { |
@@ -38,6 +39,13 @@ typedef struct Node { | |||
38 | TokenType type; | 39 | TokenType type; |
39 | struct Node **args; | 40 | struct Node **args; |
40 | } builtin; | 41 | } builtin; |
42 | |||
43 | // Variable definition. | ||
44 | struct { | ||
45 | struct Node *symbol; | ||
46 | struct Node *value; | ||
47 | // TODO: type information | ||
48 | } def; | ||
41 | }; | 49 | }; |
42 | } Node; | 50 | } Node; |
43 | 51 | ||