diff options
author | Bad Diode <bd@badd10de.dev> | 2022-03-30 16:06:01 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2022-03-30 16:06:01 +0200 |
commit | 5fc604279a9fb156dd3a8ade7bdf5c0936e9f9a7 (patch) | |
tree | f08d452ccfb51c7043a90a769f959cb970870d23 /src | |
parent | 138b466b897f94ea6a29a7b62c39caa717efafec (diff) | |
download | bdl-5fc604279a9fb156dd3a8ade7bdf5c0936e9f9a7.tar.gz bdl-5fc604279a9fb156dd3a8ade7bdf5c0936e9f9a7.zip |
Add parsing for builtin arithmetic ops
Diffstat (limited to 'src')
-rw-r--r-- | src/errors.c | 1 | ||||
-rw-r--r-- | src/errors.h | 1 | ||||
-rw-r--r-- | src/lexer.c | 10 | ||||
-rw-r--r-- | src/lexer.h | 7 | ||||
-rw-r--r-- | src/parser.c | 60 | ||||
-rw-r--r-- | src/parser.h | 20 |
6 files changed, 84 insertions, 15 deletions
diff --git a/src/errors.c b/src/errors.c index 254ff0a..10b5ce1 100644 --- a/src/errors.c +++ b/src/errors.c | |||
@@ -3,6 +3,7 @@ | |||
3 | static const char* error_msgs[] = { | 3 | static const char* error_msgs[] = { |
4 | [ERR_UNKNOWN] = "error: something unexpected happened", | 4 | [ERR_UNKNOWN] = "error: something unexpected happened", |
5 | [ERR_UNMATCHED_STRING] = "error: unmatched string delimiter", | 5 | [ERR_UNMATCHED_STRING] = "error: unmatched string delimiter", |
6 | [ERR_UNMATCHED_PAREN] = "error: unbalanced parentheses", | ||
6 | [ERR_UNKNOWN_TOK_TYPE] = "error: unknown token type", | 7 | [ERR_UNKNOWN_TOK_TYPE] = "error: unknown token type", |
7 | [ERR_MALFORMED_NUMBER] = "error: malformed number token", | 8 | [ERR_MALFORMED_NUMBER] = "error: malformed number token", |
8 | [ERR_UNIMPLEMENTED] = "error: not implemented", | 9 | [ERR_UNIMPLEMENTED] = "error: not implemented", |
diff --git a/src/errors.h b/src/errors.h index d66de46..155bb98 100644 --- a/src/errors.h +++ b/src/errors.h | |||
@@ -12,6 +12,7 @@ typedef enum ErrorValue { | |||
12 | ERR_UNKNOWN = 0, | 12 | ERR_UNKNOWN = 0, |
13 | ERR_UNMATCHED_STRING, | 13 | ERR_UNMATCHED_STRING, |
14 | ERR_UNKNOWN_TOK_TYPE, | 14 | ERR_UNKNOWN_TOK_TYPE, |
15 | ERR_UNMATCHED_PAREN, | ||
15 | ERR_MALFORMED_NUMBER, | 16 | ERR_MALFORMED_NUMBER, |
16 | ERR_UNIMPLEMENTED, | 17 | ERR_UNIMPLEMENTED, |
17 | ERR_OK, | 18 | ERR_OK, |
diff --git a/src/lexer.c b/src/lexer.c index ddf5d81..9346880 100644 --- a/src/lexer.c +++ b/src/lexer.c | |||
@@ -21,6 +21,11 @@ static const char* token_str[] = { | |||
21 | [TOKEN_SET] = "TOKEN_SET", | 21 | [TOKEN_SET] = "TOKEN_SET", |
22 | [TOKEN_FUN] = "TOKEN_FUN", | 22 | [TOKEN_FUN] = "TOKEN_FUN", |
23 | [TOKEN_STRUCT] = "TOKEN_STRUCT", | 23 | [TOKEN_STRUCT] = "TOKEN_STRUCT", |
24 | [TOKEN_ADD] = "TOKEN_ADD", | ||
25 | [TOKEN_SUB] = "TOKEN_SUB", | ||
26 | [TOKEN_MUL] = "TOKEN_MUL", | ||
27 | [TOKEN_DIV] = "TOKEN_DIV", | ||
28 | [TOKEN_MOD] = "TOKEN_MOD", | ||
24 | [TOKEN_COLON] = "TOKEN_COLON", | 29 | [TOKEN_COLON] = "TOKEN_COLON", |
25 | [TOKEN_DOT] = "TOKEN_DOT", | 30 | [TOKEN_DOT] = "TOKEN_DOT", |
26 | [TOKEN_AT] = "TOKEN_AT", | 31 | [TOKEN_AT] = "TOKEN_AT", |
@@ -45,6 +50,11 @@ static const Keyword keywords[] = { | |||
45 | KEYWORD("set!", TOKEN_SET), | 50 | KEYWORD("set!", TOKEN_SET), |
46 | KEYWORD("fun", TOKEN_FUN), | 51 | KEYWORD("fun", TOKEN_FUN), |
47 | KEYWORD("struct", TOKEN_STRUCT), | 52 | KEYWORD("struct", TOKEN_STRUCT), |
53 | KEYWORD("+", TOKEN_ADD), | ||
54 | KEYWORD("-", TOKEN_SUB), | ||
55 | KEYWORD("*", TOKEN_MUL), | ||
56 | KEYWORD("/", TOKEN_DIV), | ||
57 | KEYWORD("%", TOKEN_MOD), | ||
48 | }; | 58 | }; |
49 | 59 | ||
50 | void | 60 | void |
diff --git a/src/lexer.h b/src/lexer.h index d864a1d..a214096 100644 --- a/src/lexer.h +++ b/src/lexer.h | |||
@@ -30,6 +30,13 @@ typedef enum TokenType { | |||
30 | TOKEN_FUN, | 30 | TOKEN_FUN, |
31 | TOKEN_STRUCT, | 31 | TOKEN_STRUCT, |
32 | 32 | ||
33 | // Arithmetic ops. | ||
34 | TOKEN_ADD, | ||
35 | TOKEN_SUB, | ||
36 | TOKEN_MUL, | ||
37 | TOKEN_DIV, | ||
38 | TOKEN_MOD, | ||
39 | |||
33 | // Special operators. | 40 | // Special operators. |
34 | TOKEN_COLON, | 41 | TOKEN_COLON, |
35 | TOKEN_DOT, | 42 | TOKEN_DOT, |
diff --git a/src/parser.c b/src/parser.c index a82a97f..2a5e3e3 100644 --- a/src/parser.c +++ b/src/parser.c | |||
@@ -108,7 +108,44 @@ parse_string(Parser *parser) { | |||
108 | } | 108 | } |
109 | 109 | ||
110 | Node * | 110 | Node * |
111 | parse_builtin(Parser *parser) { | ||
112 | Token op = next_token(parser); | ||
113 | Node *node = alloc_node(NODE_BUILTIN); | ||
114 | node->builtin.type = op.type; | ||
115 | array_init(node->builtin.args, 0); | ||
116 | while (has_next(parser)) { | ||
117 | Token next = peek_token(parser); | ||
118 | if (next.type == TOKEN_RPAREN) { | ||
119 | next_token(parser); | ||
120 | return node; | ||
121 | } | ||
122 | Node *arg = parse_next(parser); | ||
123 | if (arg == NULL) { | ||
124 | break; | ||
125 | } | ||
126 | array_push(node->builtin.args, arg); | ||
127 | } | ||
128 | push_error(ERR_TYPE_PARSER, ERR_UNMATCHED_PAREN, op.line, op.col); | ||
129 | return NULL; | ||
130 | } | ||
131 | |||
132 | Node * | ||
111 | parse_paren(Parser *parser) { | 133 | parse_paren(Parser *parser) { |
134 | next_token(parser); // Skip paren. | ||
135 | Token tok = peek_token(parser); | ||
136 | // TODO: is keyword? | ||
137 | switch (tok.type) { | ||
138 | case TOKEN_ADD: | ||
139 | case TOKEN_SUB: | ||
140 | case TOKEN_MUL: | ||
141 | case TOKEN_DIV: | ||
142 | case TOKEN_MOD: { | ||
143 | return parse_builtin(parser); | ||
144 | } break; | ||
145 | default: break; | ||
146 | } | ||
147 | // print_token(tok); | ||
148 | // TODO: is in symbol table and its value is a function? | ||
112 | return NULL; // TODO: Not implemented | 149 | return NULL; // TODO: Not implemented |
113 | } | 150 | } |
114 | 151 | ||
@@ -143,14 +180,28 @@ print_node(Node *node) { | |||
143 | printf("-"); | 180 | printf("-"); |
144 | } | 181 | } |
145 | if (node->number.fractional != 0) { | 182 | if (node->number.fractional != 0) { |
146 | printf("%zu.%zu\n", node->number.integral, node->number.fractional); | 183 | printf("%zu.%zu", node->number.integral, node->number.fractional); |
147 | } else { | 184 | } else { |
148 | printf("%zu\n", node->number.integral); | 185 | printf("%zu", node->number.integral); |
149 | } | 186 | } |
150 | } break; | 187 | } break; |
151 | case NODE_STRING: { | 188 | case NODE_STRING: { |
152 | sv_write(&node->string); | 189 | sv_write(&node->string); |
153 | printf("\n"); | 190 | } break; |
191 | case NODE_BUILTIN: { | ||
192 | printf("("); | ||
193 | printf("{#%s}", token_str[node->builtin.type]); | ||
194 | size_t n_args = array_size(node->builtin.args); | ||
195 | if (n_args != 0) { | ||
196 | printf(" "); | ||
197 | } | ||
198 | for (size_t i = 0; i < n_args; ++i) { | ||
199 | print_node(node->builtin.args[i]); | ||
200 | if (i < n_args - 1) { | ||
201 | printf(" "); | ||
202 | } | ||
203 | } | ||
204 | printf(")"); | ||
154 | } break; | 205 | } break; |
155 | default: { printf("{#unk}"); } break; | 206 | default: { printf("{#unk}"); } break; |
156 | } | 207 | } |
@@ -164,9 +215,11 @@ parse(Token *tokens) { | |||
164 | }; | 215 | }; |
165 | 216 | ||
166 | // DEBUG: TOKENS | 217 | // DEBUG: TOKENS |
218 | printf("-- tokens --\n"); | ||
167 | for (size_t i = 0; i < array_size(tokens); i++) { | 219 | for (size_t i = 0; i < array_size(tokens); i++) { |
168 | print_token(tokens[i]); | 220 | print_token(tokens[i]); |
169 | } | 221 | } |
222 | printf("------------\n"); | ||
170 | 223 | ||
171 | while (has_next(&parser)) { | 224 | while (has_next(&parser)) { |
172 | Node *node = parse_next(&parser); | 225 | Node *node = parse_next(&parser); |
@@ -174,5 +227,6 @@ parse(Token *tokens) { | |||
174 | return; | 227 | return; |
175 | } | 228 | } |
176 | print_node(node); | 229 | print_node(node); |
230 | printf("\n"); | ||
177 | } | 231 | } |
178 | } | 232 | } |
diff --git a/src/parser.h b/src/parser.h index 5a9d5c8..2957356 100644 --- a/src/parser.h +++ b/src/parser.h | |||
@@ -10,14 +10,7 @@ typedef struct Parser { | |||
10 | 10 | ||
11 | typedef enum NodeType { | 11 | typedef enum NodeType { |
12 | // NODE_FUNCALL, | 12 | // NODE_FUNCALL, |
13 | // NODE_U64, | 13 | NODE_BUILTIN, |
14 | // NODE_U32, | ||
15 | // NODE_U16, | ||
16 | // NODE_U8, | ||
17 | // NODE_S64, | ||
18 | // NODE_S32, | ||
19 | // NODE_S16, | ||
20 | // NODE_S8, | ||
21 | NODE_NUMBER, | 14 | NODE_NUMBER, |
22 | NODE_STRING, | 15 | NODE_STRING, |
23 | } NodeType; | 16 | } NodeType; |
@@ -35,13 +28,16 @@ typedef struct Node { | |||
35 | 28 | ||
36 | // String. | 29 | // String. |
37 | StringView string; | 30 | StringView string; |
38 | // struct { | 31 | |
39 | // u8 *str; | 32 | // Builtin primitive. |
40 | // u64 n; | 33 | struct { |
41 | // } as_str; | 34 | TokenType type; |
35 | struct Node **args; | ||
36 | } builtin; | ||
42 | }; | 37 | }; |
43 | } Node; | 38 | } Node; |
44 | 39 | ||
45 | void parse(Token *tokens); | 40 | void parse(Token *tokens); |
41 | Node * parse_next(Parser *parser); | ||
46 | 42 | ||
47 | #endif // BDL_PARSER_H | 43 | #endif // BDL_PARSER_H |