diff options
| author | Mustafa Quraish <[email protected]> | 2022-02-02 23:49:46 -0500 |
|---|---|---|
| committer | Mustafa Quraish <[email protected]> | 2022-02-02 23:49:46 -0500 |
| commit | 3f083b4286d8e2ed990d72f61febb7f5f4f96626 (patch) | |
| tree | 553680d0ed918853d06e7843f6c40bcb54e911fa /src/parser.c | |
| parent | Remove default initialization to 0 for variable declarations (diff) | |
| download | cup-3f083b4286d8e2ed990d72f61febb7f5f4f96626.tar.xz cup-3f083b4286d8e2ed990d72f61febb7f5f4f96626.zip | |
Add support for `char` type + string/char literals
This commit does a few things in one go:
- Add support for a `char` type + some changes to support the new size
- Add support for character literals. We need some escaping here to be
able to use `\n` and `\0`, etc.
- Add support for string literals. These are all stored in the `.data`
section. Fortunately NASM already handles the escape characters.
- Fix some bugs with code generation, specifically using `movsx` to sign
extend the smaller types into 64-bit registers.
Diffstat (limited to 'src/parser.c')
| -rw-r--r-- | src/parser.c | 30 |
1 files changed, 23 insertions, 7 deletions
diff --git a/src/parser.c b/src/parser.c index 435191d..3ee8abf 100644 --- a/src/parser.c +++ b/src/parser.c @@ -74,19 +74,20 @@ Node *builtin_putc; void initialize_builtins() { + // FIXME: The `TYPE_ANY` is a hack builtin_print = Node_new(AST_BUILTIN); builtin_print->func.name = "print"; builtin_print->func.return_type = type_new(TYPE_INT); builtin_print->func.num_args = 1; builtin_print->func.args = (Variable *)calloc(sizeof(Variable), 1); - builtin_print->func.args[0] = (Variable){"val", type_new(TYPE_INT), 0}; + builtin_print->func.args[0] = (Variable){"val", type_new(TYPE_ANY), 0}; builtin_putc = Node_new(AST_BUILTIN); builtin_putc->func.name = "putc"; builtin_putc->func.return_type = type_new(TYPE_INT); builtin_putc->func.num_args = 1; builtin_putc->func.args = (Variable *)calloc(sizeof(Variable), 2); - builtin_putc->func.args[0] = (Variable){"arg", type_new(TYPE_INT), 0}; + builtin_putc->func.args[0] = (Variable){"arg", type_new(TYPE_ANY), 0}; } Node *find_builtin_function(Token *token) @@ -184,10 +185,13 @@ Type *parse_type(Lexer *lexer) Type *type; Token token = Lexer_peek(lexer); if (token.type == TOKEN_INT) { + Lexer_next(lexer); type = type_new(TYPE_INT); + } else if (token.type == TOKEN_CHAR) { Lexer_next(lexer); + type = type_new(TYPE_CHAR); } else { - type = type_new(TYPE_NONE); + die_location(token.loc, "Unexpected type found: %s", token_type_to_str(token.type)); } for (;;) { @@ -218,10 +222,22 @@ Type *parse_type(Lexer *lexer) Node *parse_literal(Lexer *lexer) { Node *node = Node_new(AST_LITERAL); - Token token = assert_token(Lexer_next(lexer), TOKEN_INTLIT); - node->literal.type = type_new(TYPE_INT); + + Token token = Lexer_next(lexer); + if (token.type == TOKEN_INTLIT) { + node->literal.type = type_new(TYPE_INT); + node->literal.as_int = token.value.as_int; + } else if (token.type == TOKEN_STRINGLIT) { + node->literal.type = type_new(TYPE_PTR); + node->literal.type->ptr = type_new(TYPE_CHAR); + node->literal.as_string = token.value.as_string; + } else if (token.type == TOKEN_CHARLIT) { + node->literal.type = type_new(TYPE_CHAR); + node->literal.as_char = token.value.as_char; + } else { + assert(false && "Invalid literal type in parse_literal\n"); + } node->expr_type = node->literal.type; - node->literal.as_int = token.value.as_int; return node; } @@ -380,7 +396,7 @@ Node *parse_factor(Lexer *lexer) Lexer_next(lexer); expr = parse_expression(lexer); assert_token(Lexer_next(lexer), TOKEN_CLOSE_PAREN); - } else if (token.type == TOKEN_INTLIT) { + } else if (is_literal_token(token.type)) { expr = parse_literal(lexer); } else if (token.type == TOKEN_IDENTIFIER) { expr = parse_identifier(lexer); |