From 483a64aa0c5ee8dc925b7957e39c42744b892288 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Thu, 31 Mar 2022 08:18:36 +0200 Subject: Add type signature to def statements Currently mandatory, may be optional once we have type inference. --- src/main.c | 1 + src/nodes.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ src/nodes.h | 45 ++++++++++++++++++++++++++++++++++++ src/parser.c | 75 +++++++++++------------------------------------------------- src/parser.h | 42 +--------------------------------- 5 files changed, 121 insertions(+), 103 deletions(-) create mode 100644 src/nodes.c create mode 100644 src/nodes.h (limited to 'src') 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 @@ #include "string_view.c" #include "errors.c" #include "lexer.c" +#include "nodes.c" #include "parser.c" // #include "ir.h" // #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 @@ +#include "nodes.h" + +Node * +alloc_node(NodeType type) { + // TODO: Use a bump allocator? + // TODO: Free memory! + Node *node = malloc(sizeof(Node)); + node->type = type; + return node; +} + +void +print_node(Node *node) { + switch (node->type) { + case NODE_NUMBER: { + if (node->number.negative) { + printf("-"); + } + if (node->number.fractional != 0) { + printf("%zu.%zu", node->number.integral, node->number.fractional); + } else { + printf("%zu", node->number.integral); + } + } break; + case NODE_SYMBOL: + case NODE_STRING: { + sv_write(&node->string); + } break; + case NODE_BOOL: { + if (node->boolean) { + printf("true"); + } else { + printf("false"); + } + } break; + case NODE_BUILTIN: { + printf("({%s}", token_str[node->builtin.type]); + size_t n_args = array_size(node->builtin.args); + if (n_args != 0) { + printf(" "); + } + for (size_t i = 0; i < n_args; ++i) { + print_node(node->builtin.args[i]); + if (i < n_args - 1) { + printf(" "); + } + } + printf(")"); + } break; + case NODE_DEF: { + printf("(def "); + print_node(node->def.symbol); + printf(":"); + sv_write(&node->def.type); + printf(" "); + print_node(node->def.value); + printf(")"); + } break; + default: { printf("{#unknown#}"); } break; + } +} 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 @@ +#ifndef BDL_NODES_H +#define BDL_NODES_H + +typedef enum NodeType { + NODE_BUILTIN, + NODE_NUMBER, + NODE_BOOL, + NODE_STRING, + NODE_SYMBOL, + NODE_DEF, +} NodeType; + +typedef struct Node { + NodeType type; + + union { + // Numbers. + struct { + bool negative; + size_t integral; + size_t fractional; + } number; + + // String/symbol. + StringView string; + + // Boolean. + bool boolean; + + // Builtin primitive. + struct { + TokenType type; + struct Node **args; + } builtin; + + // Variable definition. + struct { + struct Node *symbol; + struct Node *value; + StringView type; + } def; + }; +} Node; + +#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 @@ #include "parser.h" #include "darray.h" -Node * -alloc_node(NodeType type) { - // TODO: Use a bump allocator? - // TODO: Free memory! - Node *node = malloc(sizeof(Node)); - node->type = type; - return node; -} - Token next_token(Parser *parser) { return parser->tokens[parser->current++]; @@ -154,7 +145,18 @@ parse_def(Parser *parser) { return NULL; } - // TODO: Check if it has type annotation. + // TODO: Making type checking mandatory for now until we introduce + // type inference. + Token next = next_token(parser); + if (next.type != TOKEN_COLON) { + push_error(ERR_TYPE_PARSER, ERR_MALFORMED_EXPR, op.line, op.col); + return NULL; + } + Token type_name = next_token(parser); + if (type_name.type != TOKEN_SYMBOL) { + push_error(ERR_TYPE_PARSER, ERR_MALFORMED_EXPR, op.line, op.col); + return NULL; + } Node *value = parse_next(parser); if (value == NULL) { @@ -171,9 +173,7 @@ parse_def(Parser *parser) { Node *node = alloc_node(NODE_DEF); node->def.symbol = symbol; node->def.value = value; - - // TODO: Register variable in symbol table. - + node->def.type = type_name.value; return node; } @@ -220,55 +220,6 @@ parse_next(Parser *parser) { } } -void -print_node(Node *node) { - switch (node->type) { - case NODE_NUMBER: { - if (node->number.negative) { - printf("-"); - } - if (node->number.fractional != 0) { - printf("%zu.%zu", node->number.integral, node->number.fractional); - } else { - printf("%zu", node->number.integral); - } - } break; - case NODE_SYMBOL: - case NODE_STRING: { - sv_write(&node->string); - } break; - case NODE_BOOL: { - if (node->boolean) { - printf("true"); - } else { - printf("false"); - } - } break; - case NODE_BUILTIN: { - printf("({%s}", token_str[node->builtin.type]); - size_t n_args = array_size(node->builtin.args); - if (n_args != 0) { - printf(" "); - } - for (size_t i = 0; i < n_args; ++i) { - print_node(node->builtin.args[i]); - if (i < n_args - 1) { - printf(" "); - } - } - printf(")"); - } break; - case NODE_DEF: { - printf("(def "); - print_node(node->def.symbol); - printf(" "); - print_node(node->def.value); - printf(")"); - } break; - default: { printf("{#unknown#}"); } break; - } -} - void parse(Token *tokens) { Parser parser = { 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 @@ #define BDL_PARSER_H #include "lexer.h" +#include "nodes.h" typedef struct Parser { Token *tokens; size_t current; } Parser; -typedef enum NodeType { - NODE_BUILTIN, - NODE_NUMBER, - NODE_BOOL, - NODE_STRING, - NODE_SYMBOL, - NODE_DEF, -} NodeType; - -typedef struct Node { - NodeType type; - - union { - // Numbers. - struct { - bool negative; - size_t integral; - size_t fractional; - } number; - - // String/symbol. - StringView string; - - // Boolean. - bool boolean; - - // Builtin primitive. - struct { - TokenType type; - struct Node **args; - } builtin; - - // Variable definition. - struct { - struct Node *symbol; - struct Node *value; - // TODO: type information - } def; - }; -} Node; - void parse(Token *tokens); Node * parse_next(Parser *parser); -- cgit v1.2.1