From 4b2cb6a1bdd2667ba827d17dde5fad955f2250bf Mon Sep 17 00:00:00 2001 From: Bad Diode Date: Wed, 30 Mar 2022 17:07:12 +0200 Subject: Add initial parsing of variable definitions --- src/errors.c | 1 + src/errors.h | 1 + src/parser.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++---- src/parser.h | 10 +++++++++- 4 files changed, 72 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/errors.c b/src/errors.c index 10b5ce1..e69e4f9 100644 --- a/src/errors.c +++ b/src/errors.c @@ -6,6 +6,7 @@ static const char* error_msgs[] = { [ERR_UNMATCHED_PAREN] = "error: unbalanced parentheses", [ERR_UNKNOWN_TOK_TYPE] = "error: unknown token type", [ERR_MALFORMED_NUMBER] = "error: malformed number token", + [ERR_MALFORMED_EXPR] = "error: malformed expression", [ERR_UNIMPLEMENTED] = "error: not implemented", }; diff --git a/src/errors.h b/src/errors.h index 155bb98..25f9945 100644 --- a/src/errors.h +++ b/src/errors.h @@ -14,6 +14,7 @@ typedef enum ErrorValue { ERR_UNKNOWN_TOK_TYPE, ERR_UNMATCHED_PAREN, ERR_MALFORMED_NUMBER, + ERR_MALFORMED_EXPR, ERR_UNIMPLEMENTED, ERR_OK, } ErrorValue; diff --git a/src/parser.c b/src/parser.c index 9703061..0b62ce4 100644 --- a/src/parser.c +++ b/src/parser.c @@ -107,6 +107,14 @@ parse_string(Parser *parser) { return node; } +Node * +parse_symbol(Parser *parser) { + Token tok = next_token(parser); + Node *node = alloc_node(NODE_SYMBOL); + node->string = tok.value; + return node; +} + Node * parse_bool(Parser *parser) { Token tok = next_token(parser); @@ -137,12 +145,45 @@ parse_builtin(Parser *parser) { return NULL; } +Node * +parse_def(Parser *parser) { + Token op = next_token(parser); + Node *symbol = parse_next(parser); + if (symbol == NULL || symbol->type != NODE_SYMBOL) { + push_error(ERR_TYPE_PARSER, ERR_MALFORMED_EXPR, op.line, op.col); + return NULL; + } + + // TODO: Check if it has type annotation. + + Node *value = parse_next(parser); + if (value == NULL) { + push_error(ERR_TYPE_PARSER, ERR_MALFORMED_EXPR, op.line, op.col); + return NULL; + } + + Token end = next_token(parser); + if (end.type != TOKEN_RPAREN) { + push_error(ERR_TYPE_PARSER, ERR_MALFORMED_EXPR, op.line, op.col); + return NULL; + } + + Node *node = alloc_node(NODE_DEF); + node->def.symbol = symbol; + node->def.value = value; + + // TODO: Register variable in symbol table. + + return node; +} + Node * parse_paren(Parser *parser) { next_token(parser); // Skip paren. Token tok = peek_token(parser); - // TODO: is keyword? + switch (tok.type) { + // Builtin functions. case TOKEN_ADD: case TOKEN_SUB: case TOKEN_MUL: @@ -153,11 +194,16 @@ parse_paren(Parser *parser) { case TOKEN_OR: { return parse_builtin(parser); } break; + // Special functions. + case TOKEN_DEF: { + return parse_def(parser); + } break; default: break; } - // print_token(tok); - // TODO: is in symbol table and its value is a function? - return NULL; // TODO: Not implemented + + // TODO: Lookup value on symbol table. + push_error(ERR_TYPE_PARSER, ERR_UNIMPLEMENTED, tok.line, tok.col); + return NULL; } Node * @@ -170,6 +216,9 @@ parse_next(Parser *parser) { case TOKEN_STRING: { return parse_string(parser); } break; + case TOKEN_SYMBOL: { + return parse_symbol(parser); + } break; case TOKEN_TRUE: case TOKEN_FALSE: { return parse_bool(parser); @@ -200,6 +249,7 @@ print_node(Node *node) { printf("%zu", node->number.integral); } } break; + case NODE_SYMBOL: case NODE_STRING: { sv_write(&node->string); } break; @@ -225,6 +275,13 @@ print_node(Node *node) { } printf(")"); } break; + case NODE_DEF: { + printf("(def "); + print_node(node->def.symbol); + printf(" "); + print_node(node->def.value); + printf(")"); + } break; default: { printf("{#unk}"); } break; } } diff --git a/src/parser.h b/src/parser.h index c275195..de712e1 100644 --- a/src/parser.h +++ b/src/parser.h @@ -9,11 +9,12 @@ typedef struct Parser { } Parser; typedef enum NodeType { - // NODE_FUNCALL, NODE_BUILTIN, NODE_NUMBER, NODE_BOOL, NODE_STRING, + NODE_SYMBOL, + NODE_DEF, } NodeType; typedef struct Node { @@ -38,6 +39,13 @@ typedef struct Node { TokenType type; struct Node **args; } builtin; + + // Variable definition. + struct { + struct Node *symbol; + struct Node *value; + // TODO: type information + } def; }; } Node; -- cgit v1.2.1