aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorBad Diode <bd@badd10de.dev>2022-03-31 08:18:36 +0200
committerBad Diode <bd@badd10de.dev>2022-03-31 08:18:36 +0200
commit483a64aa0c5ee8dc925b7957e39c42744b892288 (patch)
tree86564a19bfc3255a04872815f7e1ac76d3b19cdc /src
parent4d5d49b0d1282df08e3dc7dec3c550c544fbfccb (diff)
downloadbdl-483a64aa0c5ee8dc925b7957e39c42744b892288.tar.gz
bdl-483a64aa0c5ee8dc925b7957e39c42744b892288.zip
Add type signature to def statements
Currently mandatory, may be optional once we have type inference.
Diffstat (limited to 'src')
-rw-r--r--src/main.c1
-rw-r--r--src/nodes.c61
-rw-r--r--src/nodes.h45
-rw-r--r--src/parser.c75
-rw-r--r--src/parser.h42
5 files changed, 121 insertions, 103 deletions
diff --git a/src/main.c b/src/main.c
index 7a24895..c545f6a 100644
--- a/src/main.c
+++ b/src/main.c
@@ -7,6 +7,7 @@
7#include "string_view.c" 7#include "string_view.c"
8#include "errors.c" 8#include "errors.c"
9#include "lexer.c" 9#include "lexer.c"
10#include "nodes.c"
10#include "parser.c" 11#include "parser.c"
11// #include "ir.h" 12// #include "ir.h"
12// #include "compiler.h" 13// #include "compiler.h"
diff --git a/src/nodes.c b/src/nodes.c
new file mode 100644
index 0000000..63e9b1f
--- /dev/null
+++ b/src/nodes.c
@@ -0,0 +1,61 @@
1#include "nodes.h"
2
3Node *
4alloc_node(NodeType type) {
5 // TODO: Use a bump allocator?
6 // TODO: Free memory!
7 Node *node = malloc(sizeof(Node));
8 node->type = type;
9 return node;
10}
11
12void
13print_node(Node *node) {
14 switch (node->type) {
15 case NODE_NUMBER: {
16 if (node->number.negative) {
17 printf("-");
18 }
19 if (node->number.fractional != 0) {
20 printf("%zu.%zu", node->number.integral, node->number.fractional);
21 } else {
22 printf("%zu", node->number.integral);
23 }
24 } break;
25 case NODE_SYMBOL:
26 case NODE_STRING: {
27 sv_write(&node->string);
28 } break;
29 case NODE_BOOL: {
30 if (node->boolean) {
31 printf("true");
32 } else {
33 printf("false");
34 }
35 } break;
36 case NODE_BUILTIN: {
37 printf("({%s}", token_str[node->builtin.type]);
38 size_t n_args = array_size(node->builtin.args);
39 if (n_args != 0) {
40 printf(" ");
41 }
42 for (size_t i = 0; i < n_args; ++i) {
43 print_node(node->builtin.args[i]);
44 if (i < n_args - 1) {
45 printf(" ");
46 }
47 }
48 printf(")");
49 } break;
50 case NODE_DEF: {
51 printf("(def ");
52 print_node(node->def.symbol);
53 printf(":");
54 sv_write(&node->def.type);
55 printf(" ");
56 print_node(node->def.value);
57 printf(")");
58 } break;
59 default: { printf("{#unknown#}"); } break;
60 }
61}
diff --git a/src/nodes.h b/src/nodes.h
new file mode 100644
index 0000000..e6ceb50
--- /dev/null
+++ b/src/nodes.h
@@ -0,0 +1,45 @@
1#ifndef BDL_NODES_H
2#define BDL_NODES_H
3
4typedef enum NodeType {
5 NODE_BUILTIN,
6 NODE_NUMBER,
7 NODE_BOOL,
8 NODE_STRING,
9 NODE_SYMBOL,
10 NODE_DEF,
11} NodeType;
12
13typedef struct Node {
14 NodeType type;
15
16 union {
17 // Numbers.
18 struct {
19 bool negative;
20 size_t integral;
21 size_t fractional;
22 } number;
23
24 // String/symbol.
25 StringView string;
26
27 // Boolean.
28 bool boolean;
29
30 // Builtin primitive.
31 struct {
32 TokenType type;
33 struct Node **args;
34 } builtin;
35
36 // Variable definition.
37 struct {
38 struct Node *symbol;
39 struct Node *value;
40 StringView type;
41 } def;
42 };
43} Node;
44
45#endif // BDL_NODES_H
diff --git a/src/parser.c b/src/parser.c
index 434ae98..cc94fd2 100644
--- a/src/parser.c
+++ b/src/parser.c
@@ -1,15 +1,6 @@
1#include "parser.h" 1#include "parser.h"
2#include "darray.h" 2#include "darray.h"
3 3
4Node *
5alloc_node(NodeType type) {
6 // TODO: Use a bump allocator?
7 // TODO: Free memory!
8 Node *node = malloc(sizeof(Node));
9 node->type = type;
10 return node;
11}
12
13Token 4Token
14next_token(Parser *parser) { 5next_token(Parser *parser) {
15 return parser->tokens[parser->current++]; 6 return parser->tokens[parser->current++];
@@ -154,7 +145,18 @@ parse_def(Parser *parser) {
154 return NULL; 145 return NULL;
155 } 146 }
156 147
157 // TODO: Check if it has type annotation. 148 // TODO: Making type checking mandatory for now until we introduce
149 // type inference.
150 Token next = next_token(parser);
151 if (next.type != TOKEN_COLON) {
152 push_error(ERR_TYPE_PARSER, ERR_MALFORMED_EXPR, op.line, op.col);
153 return NULL;
154 }
155 Token type_name = next_token(parser);
156 if (type_name.type != TOKEN_SYMBOL) {
157 push_error(ERR_TYPE_PARSER, ERR_MALFORMED_EXPR, op.line, op.col);
158 return NULL;
159 }
158 160
159 Node *value = parse_next(parser); 161 Node *value = parse_next(parser);
160 if (value == NULL) { 162 if (value == NULL) {
@@ -171,9 +173,7 @@ parse_def(Parser *parser) {
171 Node *node = alloc_node(NODE_DEF); 173 Node *node = alloc_node(NODE_DEF);
172 node->def.symbol = symbol; 174 node->def.symbol = symbol;
173 node->def.value = value; 175 node->def.value = value;
174 176 node->def.type = type_name.value;
175 // TODO: Register variable in symbol table.
176
177 return node; 177 return node;
178} 178}
179 179
@@ -221,55 +221,6 @@ parse_next(Parser *parser) {
221} 221}
222 222
223void 223void
224print_node(Node *node) {
225 switch (node->type) {
226 case NODE_NUMBER: {
227 if (node->number.negative) {
228 printf("-");
229 }
230 if (node->number.fractional != 0) {
231 printf("%zu.%zu", node->number.integral, node->number.fractional);
232 } else {
233 printf("%zu", node->number.integral);
234 }
235 } break;
236 case NODE_SYMBOL:
237 case NODE_STRING: {
238 sv_write(&node->string);
239 } break;
240 case NODE_BOOL: {
241 if (node->boolean) {
242 printf("true");
243 } else {
244 printf("false");
245 }
246 } break;
247 case NODE_BUILTIN: {
248 printf("({%s}", token_str[node->builtin.type]);
249 size_t n_args = array_size(node->builtin.args);
250 if (n_args != 0) {
251 printf(" ");
252 }
253 for (size_t i = 0; i < n_args; ++i) {
254 print_node(node->builtin.args[i]);
255 if (i < n_args - 1) {
256 printf(" ");
257 }
258 }
259 printf(")");
260 } break;
261 case NODE_DEF: {
262 printf("(def ");
263 print_node(node->def.symbol);
264 printf(" ");
265 print_node(node->def.value);
266 printf(")");
267 } break;
268 default: { printf("{#unknown#}"); } break;
269 }
270}
271
272void
273parse(Token *tokens) { 224parse(Token *tokens) {
274 Parser parser = { 225 Parser parser = {
275 .tokens = tokens, 226 .tokens = tokens,
diff --git a/src/parser.h b/src/parser.h
index 6a4401e..47316b9 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -2,53 +2,13 @@
2#define BDL_PARSER_H 2#define BDL_PARSER_H
3 3
4#include "lexer.h" 4#include "lexer.h"
5#include "nodes.h"
5 6
6typedef struct Parser { 7typedef struct Parser {
7 Token *tokens; 8 Token *tokens;
8 size_t current; 9 size_t current;
9} Parser; 10} Parser;
10 11
11typedef enum NodeType {
12 NODE_BUILTIN,
13 NODE_NUMBER,
14 NODE_BOOL,
15 NODE_STRING,
16 NODE_SYMBOL,
17 NODE_DEF,
18} NodeType;
19
20typedef struct Node {
21 NodeType type;
22
23 union {
24 // Numbers.
25 struct {
26 bool negative;
27 size_t integral;
28 size_t fractional;
29 } number;
30
31 // String/symbol.
32 StringView string;
33
34 // Boolean.
35 bool boolean;
36
37 // Builtin primitive.
38 struct {
39 TokenType type;
40 struct Node **args;
41 } builtin;
42
43 // Variable definition.
44 struct {
45 struct Node *symbol;
46 struct Node *value;
47 // TODO: type information
48 } def;
49 };
50} Node;
51
52void parse(Token *tokens); 12void parse(Token *tokens);
53Node * parse_next(Parser *parser); 13Node * parse_next(Parser *parser);
54 14