From 5fc604279a9fb156dd3a8ade7bdf5c0936e9f9a7 Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Wed, 30 Mar 2022 16:06:01 +0200 Subject: Add parsing for builtin arithmetic ops --- src/errors.c | 1 + src/errors.h | 1 + src/lexer.c | 10 ++++++++++ src/lexer.h | 7 +++++++ src/parser.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- src/parser.h | 20 ++++++++------------ 6 files changed, 84 insertions(+), 15 deletions(-) (limited to 'src') 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 @@ static const char* error_msgs[] = { [ERR_UNKNOWN] = "error: something unexpected happened", [ERR_UNMATCHED_STRING] = "error: unmatched string delimiter", + [ERR_UNMATCHED_PAREN] = "error: unbalanced parentheses", [ERR_UNKNOWN_TOK_TYPE] = "error: unknown token type", [ERR_MALFORMED_NUMBER] = "error: malformed number token", [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 { ERR_UNKNOWN = 0, ERR_UNMATCHED_STRING, ERR_UNKNOWN_TOK_TYPE, + ERR_UNMATCHED_PAREN, ERR_MALFORMED_NUMBER, ERR_UNIMPLEMENTED, 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[] = { [TOKEN_SET] = "TOKEN_SET", [TOKEN_FUN] = "TOKEN_FUN", [TOKEN_STRUCT] = "TOKEN_STRUCT", + [TOKEN_ADD] = "TOKEN_ADD", + [TOKEN_SUB] = "TOKEN_SUB", + [TOKEN_MUL] = "TOKEN_MUL", + [TOKEN_DIV] = "TOKEN_DIV", + [TOKEN_MOD] = "TOKEN_MOD", [TOKEN_COLON] = "TOKEN_COLON", [TOKEN_DOT] = "TOKEN_DOT", [TOKEN_AT] = "TOKEN_AT", @@ -45,6 +50,11 @@ static const Keyword keywords[] = { KEYWORD("set!", TOKEN_SET), KEYWORD("fun", TOKEN_FUN), KEYWORD("struct", TOKEN_STRUCT), + KEYWORD("+", TOKEN_ADD), + KEYWORD("-", TOKEN_SUB), + KEYWORD("*", TOKEN_MUL), + KEYWORD("/", TOKEN_DIV), + KEYWORD("%", TOKEN_MOD), }; 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 { TOKEN_FUN, TOKEN_STRUCT, + // Arithmetic ops. + TOKEN_ADD, + TOKEN_SUB, + TOKEN_MUL, + TOKEN_DIV, + TOKEN_MOD, + // Special operators. TOKEN_COLON, TOKEN_DOT, diff --git a/src/parser.c b/src/parser.c index a82a97f..2a5e3e3 100644 --- a/src/parser.c +++ b/src/parser.c @@ -107,8 +107,45 @@ parse_string(Parser *parser) { return node; } +Node * +parse_builtin(Parser *parser) { + Token op = next_token(parser); + Node *node = alloc_node(NODE_BUILTIN); + node->builtin.type = op.type; + array_init(node->builtin.args, 0); + while (has_next(parser)) { + Token next = peek_token(parser); + if (next.type == TOKEN_RPAREN) { + next_token(parser); + return node; + } + Node *arg = parse_next(parser); + if (arg == NULL) { + break; + } + array_push(node->builtin.args, arg); + } + push_error(ERR_TYPE_PARSER, ERR_UNMATCHED_PAREN, op.line, op.col); + return NULL; +} + Node * parse_paren(Parser *parser) { + next_token(parser); // Skip paren. + Token tok = peek_token(parser); + // TODO: is keyword? + switch (tok.type) { + case TOKEN_ADD: + case TOKEN_SUB: + case TOKEN_MUL: + case TOKEN_DIV: + case TOKEN_MOD: { + return parse_builtin(parser); + } break; + default: break; + } + // print_token(tok); + // TODO: is in symbol table and its value is a function? return NULL; // TODO: Not implemented } @@ -143,14 +180,28 @@ print_node(Node *node) { printf("-"); } if (node->number.fractional != 0) { - printf("%zu.%zu\n", node->number.integral, node->number.fractional); + printf("%zu.%zu", node->number.integral, node->number.fractional); } else { - printf("%zu\n", node->number.integral); + printf("%zu", node->number.integral); } } break; case NODE_STRING: { sv_write(&node->string); - printf("\n"); + } break; + case NODE_BUILTIN: { + printf("("); + 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; default: { printf("{#unk}"); } break; } @@ -164,9 +215,11 @@ parse(Token *tokens) { }; // DEBUG: TOKENS + printf("-- tokens --\n"); for (size_t i = 0; i < array_size(tokens); i++) { print_token(tokens[i]); } + printf("------------\n"); while (has_next(&parser)) { Node *node = parse_next(&parser); @@ -174,5 +227,6 @@ parse(Token *tokens) { return; } print_node(node); + printf("\n"); } } 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 { typedef enum NodeType { // NODE_FUNCALL, - // NODE_U64, - // NODE_U32, - // NODE_U16, - // NODE_U8, - // NODE_S64, - // NODE_S32, - // NODE_S16, - // NODE_S8, + NODE_BUILTIN, NODE_NUMBER, NODE_STRING, } NodeType; @@ -35,13 +28,16 @@ typedef struct Node { // String. StringView string; - // struct { - // u8 *str; - // u64 n; - // } as_str; + + // Builtin primitive. + struct { + TokenType type; + struct Node **args; + } builtin; }; } Node; void parse(Token *tokens); +Node * parse_next(Parser *parser); #endif // BDL_PARSER_H -- cgit v1.2.1