diff options
author | Bad Diode <bd@badd10de.dev> | 2024-06-16 20:19:56 +0200 |
---|---|---|
committer | Bad Diode <bd@badd10de.dev> | 2024-06-16 20:19:56 +0200 |
commit | b86d262b9fe27131d8163a6ba49957736691b1d0 (patch) | |
tree | cde0152015c4cb2403d6b99b92dccaed46ad0f2f /src/main.c | |
parent | d6e8c277b13ee5a9878c78dd7d0104699202a161 (diff) | |
download | bdl-b86d262b9fe27131d8163a6ba49957736691b1d0.tar.gz bdl-b86d262b9fe27131d8163a6ba49957736691b1d0.zip |
Add floating point number parsing
Diffstat (limited to 'src/main.c')
-rw-r--r-- | src/main.c | 45 |
1 files changed, 32 insertions, 13 deletions
@@ -39,19 +39,27 @@ print_tokens(Str path, Token *tokens) { | |||
39 | // | 39 | // |
40 | 40 | ||
41 | typedef enum NodeKind { | 41 | typedef enum NodeKind { |
42 | NODE_NUMBER, | 42 | NODE_NUM_INT, |
43 | NODE_NUM_FLOAT, | ||
43 | // TODO: probably want to handle ints/unsigneds/floats separately. | 44 | // TODO: probably want to handle ints/unsigneds/floats separately. |
44 | NODE_ADD, | 45 | NODE_ADD, |
45 | NODE_SUB, | 46 | NODE_SUB, |
46 | NODE_DIV, | 47 | NODE_DIV, |
47 | NODE_MUL, | 48 | NODE_MUL, |
48 | // TODO: MOD | 49 | NODE_MOD, |
49 | } NodeKind; | 50 | } NodeKind; |
50 | 51 | ||
51 | Str node_str[] = { | 52 | Str node_str[] = { |
52 | [NODE_NUMBER] = cstr("NUM"), [NODE_ADD] = cstr("ADD"), | 53 | // Arithmetic. |
53 | [NODE_SUB] = cstr("SUB"), [NODE_DIV] = cstr("DIV"), | 54 | [NODE_ADD] = cstr("ADD"), |
55 | [NODE_SUB] = cstr("SUB"), | ||
56 | [NODE_DIV] = cstr("DIV"), | ||
54 | [NODE_MUL] = cstr("MUL"), | 57 | [NODE_MUL] = cstr("MUL"), |
58 | [NODE_MOD] = cstr("MOD"), | ||
59 | |||
60 | // Literals. | ||
61 | [NODE_NUM_INT] = cstr("INT"), | ||
62 | [NODE_NUM_FLOAT] = cstr("FLOAT"), | ||
55 | }; | 63 | }; |
56 | 64 | ||
57 | typedef struct Node { | 65 | typedef struct Node { |
@@ -62,9 +70,7 @@ typedef struct Node { | |||
62 | NodeKind kind; | 70 | NodeKind kind; |
63 | union { | 71 | union { |
64 | f64 d; | 72 | f64 d; |
65 | f32 f; | ||
66 | sz i; | 73 | sz i; |
67 | u64 u; | ||
68 | } value; | 74 | } value; |
69 | struct Node *left; | 75 | struct Node *left; |
70 | struct Node *right; | 76 | struct Node *right; |
@@ -108,7 +114,7 @@ typedef enum { | |||
108 | PREC_EQUALITY, // == != | 114 | PREC_EQUALITY, // == != |
109 | PREC_COMPARISON, // < > <= >= | 115 | PREC_COMPARISON, // < > <= >= |
110 | PREC_TERM, // + - | 116 | PREC_TERM, // + - |
111 | PREC_FACTOR, // * / | 117 | PREC_FACTOR, // * / % |
112 | PREC_UNARY, // ! - | 118 | PREC_UNARY, // ! - |
113 | PREC_CALL, // . () | 119 | PREC_CALL, // . () |
114 | PREC_PRIMARY // highest precedence | 120 | PREC_PRIMARY // highest precedence |
@@ -136,7 +142,9 @@ ParseRule parse_rules[] = { | |||
136 | [TOK_ADD] = {NULL, parse_binary, PREC_TERM}, | 142 | [TOK_ADD] = {NULL, parse_binary, PREC_TERM}, |
137 | [TOK_DIV] = {NULL, parse_binary, PREC_FACTOR}, | 143 | [TOK_DIV] = {NULL, parse_binary, PREC_FACTOR}, |
138 | [TOK_MUL] = {NULL, parse_binary, PREC_FACTOR}, | 144 | [TOK_MUL] = {NULL, parse_binary, PREC_FACTOR}, |
139 | [TOK_NUMBER] = {parse_number, NULL, PREC_NONE}, | 145 | [TOK_MOD] = {NULL, parse_binary, PREC_FACTOR}, |
146 | [TOK_NUM_INT] = {parse_number, NULL, PREC_NONE}, | ||
147 | [TOK_NUM_FLOAT] = {parse_number, NULL, PREC_NONE}, | ||
140 | [TOK_EOF] = {NULL, NULL, PREC_NONE}, | 148 | [TOK_EOF] = {NULL, NULL, PREC_NONE}, |
141 | }; | 149 | }; |
142 | 150 | ||
@@ -201,7 +209,7 @@ parse_unary(Parser *parser) { | |||
201 | print("parsing unary "); | 209 | print("parsing unary "); |
202 | print_token(prev); | 210 | print_token(prev); |
203 | #endif | 211 | #endif |
204 | TokenKind kind = parser->previous.kind; | 212 | TokenKind kind = prev.kind; |
205 | parse_expr(parser, PREC_LOW); | 213 | parse_expr(parser, PREC_LOW); |
206 | // TODO: ... | 214 | // TODO: ... |
207 | switch (kind) { | 215 | switch (kind) { |
@@ -227,6 +235,7 @@ parse_binary(Parser *parser) { | |||
227 | case TOK_SUB: node = node_alloc(NODE_SUB, prev, parser->storage); break; | 235 | case TOK_SUB: node = node_alloc(NODE_SUB, prev, parser->storage); break; |
228 | case TOK_MUL: node = node_alloc(NODE_MUL, prev, parser->storage); break; | 236 | case TOK_MUL: node = node_alloc(NODE_MUL, prev, parser->storage); break; |
229 | case TOK_DIV: node = node_alloc(NODE_DIV, prev, parser->storage); break; | 237 | case TOK_DIV: node = node_alloc(NODE_DIV, prev, parser->storage); break; |
238 | case TOK_MOD: node = node_alloc(NODE_MOD, prev, parser->storage); break; | ||
230 | default: { | 239 | default: { |
231 | parse_emit_err(parser, prev, cstr("unreachable")); | 240 | parse_emit_err(parser, prev, cstr("unreachable")); |
232 | return; | 241 | return; |
@@ -244,9 +253,18 @@ parse_number(Parser *parser) { | |||
244 | print("parsing number "); | 253 | print("parsing number "); |
245 | print_token(prev); | 254 | print_token(prev); |
246 | #endif | 255 | #endif |
247 | Node *node = node_alloc(NODE_NUMBER, prev, parser->storage); | 256 | Node *node = NULL; |
248 | node->value.i = str_to_int(prev.val); | 257 | switch (prev.kind) { |
249 | // TODO: handle sign and/or floating point values. | 258 | case TOK_NUM_INT: { |
259 | node = node_alloc(NODE_NUM_INT, prev, parser->storage); | ||
260 | node->value.i = str_to_int(prev.val); | ||
261 | } break; | ||
262 | case TOK_NUM_FLOAT: { | ||
263 | node = node_alloc(NODE_NUM_FLOAT, prev, parser->storage); | ||
264 | node->value.d = str_to_float(prev.val); | ||
265 | } break; | ||
266 | default: break; | ||
267 | } | ||
250 | array_push(parser->nodes, node, parser->storage); | 268 | array_push(parser->nodes, node, parser->storage); |
251 | } | 269 | } |
252 | 270 | ||
@@ -268,7 +286,8 @@ graph_node(Node *node) { | |||
268 | print("%d [width=2.5,shape=Mrecord,label=\"", node->id); | 286 | print("%d [width=2.5,shape=Mrecord,label=\"", node->id); |
269 | print("<top> %s ", node_str[node->kind]); | 287 | print("<top> %s ", node_str[node->kind]); |
270 | switch (node->kind) { | 288 | switch (node->kind) { |
271 | case NODE_NUMBER: print("| Value: %d", node->value.i); break; | 289 | case NODE_NUM_INT: print("| Value: %d", node->value.i); break; |
290 | case NODE_NUM_FLOAT: print("| Value: %f{2}", node->value.d); break; | ||
272 | default: break; | 291 | default: break; |
273 | } | 292 | } |
274 | print("| Line: %d | Col: %d ", node->line, node->col); | 293 | print("| Line: %d | Col: %d ", node->line, node->col); |