aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2021-10-30 08:51:46 +0200
committerBad Diode <bd@badd10de.dev>2021-10-30 08:51:46 +0200
commitc0520617a974abd27c413fb21ecd64ca2d11d135 (patch)
treec284b450c7532303c1eb138bcf6fb45a8540603f
parentf17b11003fe384b49a7bf844824f23167b6095e0 (diff)
downloadbdl-c0520617a974abd27c413fb21ecd64ca2d11d135.tar.gz
bdl-c0520617a974abd27c413fb21ecd64ca2d11d135.zip
Add parsing for def/set! expressions
-rwxr-xr-xsrc/lexer.c4
-rwxr-xr-xsrc/lexer.h2
-rw-r--r--src/parser.c97
-rwxr-xr-xsrc/parser.h11
4 files changed, 99 insertions, 15 deletions
diff --git a/src/lexer.c b/src/lexer.c
index cbcc175..704ee66 100755
--- a/src/lexer.c
+++ b/src/lexer.c
@@ -13,6 +13,8 @@ static const char* token_str[] = {
13 [TOKEN_FALSE] = "TOKEN_FALSE", 13 [TOKEN_FALSE] = "TOKEN_FALSE",
14 [TOKEN_LAMBDA] = "TOKEN_LAMBDA", 14 [TOKEN_LAMBDA] = "TOKEN_LAMBDA",
15 [TOKEN_IF] = "TOKEN_IF", 15 [TOKEN_IF] = "TOKEN_IF",
16 [TOKEN_DEF] = "TOKEN_DEF",
17 [TOKEN_SET] = "TOKEN_SET",
16 [TOKEN_EOF] = "TOKEN_EOF", 18 [TOKEN_EOF] = "TOKEN_EOF",
17}; 19};
18 20
@@ -128,6 +130,8 @@ find_primitive_type(const StringView value) {
128 if (TOKEN_IS_KEYWORD(value, "false")) { return TOKEN_FALSE; } 130 if (TOKEN_IS_KEYWORD(value, "false")) { return TOKEN_FALSE; }
129 if (TOKEN_IS_KEYWORD(value, "lambda")) { return TOKEN_LAMBDA; } 131 if (TOKEN_IS_KEYWORD(value, "lambda")) { return TOKEN_LAMBDA; }
130 if (TOKEN_IS_KEYWORD(value, "if")) { return TOKEN_IF; } 132 if (TOKEN_IS_KEYWORD(value, "if")) { return TOKEN_IF; }
133 if (TOKEN_IS_KEYWORD(value, "def")) { return TOKEN_DEF; }
134 if (TOKEN_IS_KEYWORD(value, "set!")) { return TOKEN_SET; }
131 135
132 return TOKEN_SYMBOL; 136 return TOKEN_SYMBOL;
133} 137}
diff --git a/src/lexer.h b/src/lexer.h
index 4798a2b..f187526 100755
--- a/src/lexer.h
+++ b/src/lexer.h
@@ -21,6 +21,8 @@ typedef enum TokenType {
21 // Keywords. 21 // Keywords.
22 TOKEN_LAMBDA, 22 TOKEN_LAMBDA,
23 TOKEN_IF, 23 TOKEN_IF,
24 TOKEN_DEF,
25 TOKEN_SET,
24 26
25 // End of file. 27 // End of file.
26 TOKEN_EOF, 28 TOKEN_EOF,
diff --git a/src/parser.c b/src/parser.c
index 5551dd2..f831e50 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -122,7 +122,7 @@ parse_lambda(Parser *parser, Errors *errors) {
122Object * 122Object *
123parse_if(Parser *parser, Errors *errors) { 123parse_if(Parser *parser, Errors *errors) {
124 Token start = next_token(parser); 124 Token start = next_token(parser);
125 Object *obj_if = object_alloc(start, OBJ_TYPE_IF); 125 Object *ret = object_alloc(start, OBJ_TYPE_IF);
126 126
127 Token tok = peek_token(parser); 127 Token tok = peek_token(parser);
128 if (tok.type == TOKEN_RPAREN) { 128 if (tok.type == TOKEN_RPAREN) {
@@ -134,7 +134,7 @@ parse_if(Parser *parser, Errors *errors) {
134 }); 134 });
135 return NULL; 135 return NULL;
136 } 136 }
137 obj_if->condition = parse_tree(parser, errors); 137 ret->condition = parse_tree(parser, errors);
138 138
139 tok = peek_token(parser); 139 tok = peek_token(parser);
140 if (tok.type == TOKEN_RPAREN) { 140 if (tok.type == TOKEN_RPAREN) {
@@ -146,16 +146,16 @@ parse_if(Parser *parser, Errors *errors) {
146 }); 146 });
147 return NULL; 147 return NULL;
148 } 148 }
149 obj_if->expr_true = parse_tree(parser, errors); 149 ret->expr_true = parse_tree(parser, errors);
150 150
151 // Optional else expression. 151 // Optional else expression.
152 tok = peek_token(parser); 152 tok = peek_token(parser);
153 if (tok.type == TOKEN_RPAREN) { 153 if (tok.type == TOKEN_RPAREN) {
154 next_token(parser); 154 next_token(parser);
155 obj_if->expr_false = NULL; 155 ret->expr_false = NULL;
156 return obj_if; 156 return ret;
157 } 157 }
158 obj_if->expr_false = parse_tree(parser, errors); 158 ret->expr_false = parse_tree(parser, errors);
159 159
160 tok = peek_token(parser); 160 tok = peek_token(parser);
161 if (tok.type != TOKEN_RPAREN) { 161 if (tok.type != TOKEN_RPAREN) {
@@ -168,7 +168,62 @@ parse_if(Parser *parser, Errors *errors) {
168 return NULL; 168 return NULL;
169 } 169 }
170 next_token(parser); 170 next_token(parser);
171 return obj_if; 171 return ret;
172}
173
174Object *
175parse_var(Parser *parser, Errors *errors) {
176 Token start = next_token(parser);
177 ObjectType type = start.type == TOKEN_DEF ? OBJ_TYPE_DEF : OBJ_TYPE_SET;
178 Object *ret = object_alloc(start, type);
179
180 // Variable name.
181 Token tok = peek_token(parser);
182 if (tok.type == TOKEN_RPAREN) {
183 error_push(errors, (Error){
184 .type = ERR_TYPE_PARSER,
185 .value = ERR_NOT_ENOUGH_ARGS,
186 .line = tok.line,
187 .col = tok.col,
188 });
189 return NULL;
190 }
191 if (tok.type != TOKEN_SYMBOL) {
192 error_push(errors, (Error){
193 .type = ERR_TYPE_PARSER,
194 .value = ERR_WRONG_ARG_TYPE,
195 .line = tok.line,
196 .col = tok.col,
197 });
198 return NULL;
199 }
200 ret->var_name = parse_tree(parser, errors);
201
202 // Variable value (expression).
203 tok = peek_token(parser);
204 if (tok.type == TOKEN_RPAREN) {
205 error_push(errors, (Error){
206 .type = ERR_TYPE_PARSER,
207 .value = ERR_NOT_ENOUGH_ARGS,
208 .line = tok.line,
209 .col = tok.col,
210 });
211 return NULL;
212 }
213 ret->var_expr = parse_tree(parser, errors);
214
215 tok = peek_token(parser);
216 if (tok.type != TOKEN_RPAREN) {
217 error_push(errors, (Error){
218 .type = ERR_TYPE_PARSER,
219 .value = ERR_TOO_MANY_ARGS,
220 .line = tok.line,
221 .col = tok.col,
222 });
223 return NULL;
224 }
225 next_token(parser);
226 return ret;
172} 227}
173 228
174Object * 229Object *
@@ -188,12 +243,10 @@ parse_list(Parser *parser, Errors *errors) {
188 }); 243 });
189 return NULL; 244 return NULL;
190 } break; 245 } break;
191 case TOKEN_LAMBDA: { 246 case TOKEN_LAMBDA: { return parse_lambda(parser, errors); } break;
192 return parse_lambda(parser, errors); 247 case TOKEN_IF: { return parse_if(parser, errors); } break;
193 } break; 248 case TOKEN_DEF: { return parse_var(parser, errors); } break;
194 case TOKEN_IF: { 249 case TOKEN_SET: { return parse_var(parser, errors); } break;
195 return parse_if(parser, errors);
196 } break;
197 default: break; 250 default: break;
198 } 251 }
199 252
@@ -386,7 +439,7 @@ object_display(Object *obj) {
386 printf(")"); 439 printf(")");
387 } break; 440 } break;
388 case OBJ_TYPE_LAMBDA: { 441 case OBJ_TYPE_LAMBDA: {
389 printf("#{ lambda( "); 442 printf("#{ lambda ( ");
390 for (size_t i = 0; i < array_size(obj->params); i++) { 443 for (size_t i = 0; i < array_size(obj->params); i++) {
391 object_display(obj->params[i]); 444 object_display(obj->params[i]);
392 printf(" "); 445 printf(" ");
@@ -408,7 +461,21 @@ object_display(Object *obj) {
408 object_display(obj->expr_false); 461 object_display(obj->expr_false);
409 } 462 }
410 printf(" }"); 463 printf(" }");
411 }; 464 } break;
465 case OBJ_TYPE_DEF: {
466 printf("#{ def ");
467 object_display(obj->var_name);
468 printf(" ");
469 object_display(obj->var_expr);
470 printf(" }");
471 } break;
472 case OBJ_TYPE_SET: {
473 printf("#{ set! ");
474 object_display(obj->var_name);
475 printf(" ");
476 object_display(obj->var_expr);
477 printf(" }");
478 } break;
412 } 479 }
413 return; 480 return;
414} 481}
diff --git a/src/parser.h b/src/parser.h
index b2b07c8..14d9df5 100755
--- a/src/parser.h
+++ b/src/parser.h
@@ -13,6 +13,8 @@ typedef enum ObjectType {
13 OBJ_TYPE_PAIR, 13 OBJ_TYPE_PAIR,
14 OBJ_TYPE_LAMBDA, 14 OBJ_TYPE_LAMBDA,
15 OBJ_TYPE_IF, 15 OBJ_TYPE_IF,
16 OBJ_TYPE_DEF,
17 OBJ_TYPE_SET,
16} ObjectType; 18} ObjectType;
17 19
18typedef struct Object { 20typedef struct Object {
@@ -43,6 +45,13 @@ typedef struct Object {
43 struct Object *expr_true; 45 struct Object *expr_true;
44 struct Object *expr_false; 46 struct Object *expr_false;
45 }; 47 };
48
49 // OBJ_TYPE_DEF
50 // OBJ_TYPE_SET
51 struct {
52 struct Object *var_name;
53 struct Object *var_expr;
54 };
46 }; 55 };
47 56
48 size_t line; 57 size_t line;
@@ -71,6 +80,8 @@ Object * parse_bool(Token tok);
71Object * parse_fixnum(Token tok); 80Object * parse_fixnum(Token tok);
72Object * parse_list(Parser *parser, Errors *errors); 81Object * parse_list(Parser *parser, Errors *errors);
73Object * parse_lambda(Parser *parser, Errors *errors); 82Object * parse_lambda(Parser *parser, Errors *errors);
83Object * parse_if(Parser *parser, Errors *errors);
84Object * parse_var(Parser *parser, Errors *errors);
74Root * parse(Token *tokens, Errors *errors); 85Root * parse(Token *tokens, Errors *errors);
75 86
76// Object operations. 87// Object operations.