diff options
author | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2025-04-08 19:17:04 +0330 |
---|---|---|
committer | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2025-04-08 19:17:04 +0330 |
commit | d76c19e0bea07806c49175c91d19eb38cfb230dd (patch) | |
tree | 79d84779328c8d0cfb416c2016b9feea64d201e5 | |
parent | 46d0c9025eb000670dd6a99f0e74fc928269a3c3 (diff) |
add characters
-rw-r--r-- | code/main.felan | 18 | ||||
-rw-r--r-- | src/compiler/ast-tree.c | 18 | ||||
-rw-r--r-- | src/compiler/ast-tree.h | 2 | ||||
-rw-r--r-- | src/compiler/lexer.c | 33 | ||||
-rw-r--r-- | src/compiler/lexer.h | 2 | ||||
-rw-r--r-- | src/compiler/parser.c | 37 | ||||
-rw-r--r-- | src/compiler/parser.h | 8 |
7 files changed, 91 insertions, 27 deletions
diff --git a/code/main.felan b/code/main.felan index e7348c7..5609e27 100644 --- a/code/main.felan +++ b/code/main.felan @@ -17,21 +17,7 @@ long_double :: f128; usize :: u64; -array :: (t:type) -> type { - return struct { - ptr : *t; - length : usize; - }; -}; - -array_int :: array(u64); -array_int1 :: array(u64); -array_int2 :: array(i64); - main :: () -> void { - print_u64 (if array_int == array_int1 1 else 0); - print_u64 (if array_int == array_int2 1 else 0); -}; - -comptime { + a := 'a'; + print_u64 (if a == 97 1 else 0); }; diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index 239f9b4..678c533 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -1237,6 +1237,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) { case PARSER_TOKEN_VALUE_BOOL: case PARSER_TOKEN_VALUE_INT: case PARSER_TOKEN_VALUE_FLOAT: + case PARSER_TOKEN_VALUE_CHAR: case PARSER_TOKEN_FUNCTION_DEFINITION: case PARSER_TOKEN_FUNCTION_CALL: case PARSER_TOKEN_IDENTIFIER: @@ -1462,13 +1463,16 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper) { return astTreeParseIdentifier(parserNode, helper); case PARSER_TOKEN_VALUE_INT: return astTreeParseValue(parserNode, AST_TREE_TOKEN_VALUE_INT, - sizeof(AstTreeInt)); + sizeof(AstTreeInt), NULL); case PARSER_TOKEN_VALUE_FLOAT: return astTreeParseValue(parserNode, AST_TREE_TOKEN_VALUE_FLOAT, - sizeof(AstTreeFloat)); + sizeof(AstTreeFloat), NULL); case PARSER_TOKEN_VALUE_BOOL: return astTreeParseValue(parserNode, AST_TREE_TOKEN_VALUE_BOOL, - sizeof(AstTreeBool)); + sizeof(AstTreeBool), NULL); + case PARSER_TOKEN_VALUE_CHAR: + return astTreeParseValue(parserNode, AST_TREE_TOKEN_VALUE_INT, + sizeof(AstTreeInt), &AST_TREE_U8_TYPE); case PARSER_TOKEN_KEYWORD_NULL: return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_VALUE_NULL); case PARSER_TOKEN_KEYWORD_UNDEFINED: @@ -1657,6 +1661,7 @@ AstTree *astTreeParseFunction(ParserNode *parserNode, AstTreeHelper *p_helper) { case PARSER_TOKEN_VALUE_INT: case PARSER_TOKEN_VALUE_FLOAT: case PARSER_TOKEN_VALUE_BOOL: + case PARSER_TOKEN_VALUE_CHAR: case PARSER_TOKEN_TYPE_TYPE: case PARSER_TOKEN_TYPE_FUNCTION: case PARSER_TOKEN_TYPE_VOID: @@ -1893,11 +1898,11 @@ AstTree *astTreeParseIdentifier(ParserNode *parserNode, AstTreeHelper *helper) { } AstTree *astTreeParseValue(ParserNode *parserNode, AstTreeToken token, - size_t metadata_size) { + size_t metadata_size, AstTree *type) { void *metadata = a404m_malloc(metadata_size); memcpy(metadata, parserNode->metadata, metadata_size); - return newAstTree(token, metadata, NULL, parserNode->str_begin, + return newAstTree(token, metadata, type, parserNode->str_begin, parserNode->str_end); } @@ -2203,6 +2208,7 @@ AstTree *astTreeParseCurlyBracket(ParserNode *parserNode, case PARSER_TOKEN_VALUE_INT: case PARSER_TOKEN_VALUE_FLOAT: case PARSER_TOKEN_VALUE_BOOL: + case PARSER_TOKEN_VALUE_CHAR: case PARSER_TOKEN_TYPE_TYPE: case PARSER_TOKEN_TYPE_FUNCTION: case PARSER_TOKEN_TYPE_VOID: @@ -3344,7 +3350,7 @@ bool setTypesValueFloat(AstTree *tree, AstTreeSetTypesHelper helper) { printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); } tree->type = &AST_TREE_F16_TYPE; - #endif +#endif } else if (typeIsEqual(helper.lookingType, &AST_TREE_F32_TYPE)) { tree->token = AST_TREE_TOKEN_VALUE_FLOAT; AstTreeFloat value = *(AstTreeFloat *)tree->metadata; diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h index 4617ce4..fb708af 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -260,7 +260,7 @@ AstTree *astTreeParseFunctionCall(ParserNode *parserNode, AstTreeHelper *helper); AstTree *astTreeParseIdentifier(ParserNode *parserNode, AstTreeHelper *helper); AstTree *astTreeParseValue(ParserNode *parserNode, AstTreeToken token, - size_t metadata_size); + size_t metadata_size,AstTree *type); AstTree *astTreeParseKeyword(ParserNode *parserNode, AstTreeToken token); AstTree *astTreeParsePrintU64(ParserNode *parserNode, AstTreeHelper *helper); AstTree *astTreeParseReturn(ParserNode *parserNode, AstTreeHelper *helper); diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index 0f971d7..43ea4c1 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -41,6 +41,7 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_KEYWORD_UNDEFINED", "LEXER_TOKEN_NUMBER", + "LEXER_TOKEN_CHAR", "LEXER_TOKEN_SYMBOL", "LEXER_TOKEN_SYMBOL_EOL", @@ -193,12 +194,15 @@ LexerNodeArray lexer(char *str) { &node_token, LEXER_TOKEN_NONE); ++iter; int in = 1; + char *openingIter = iter - 2; + for (; in != 0; ++iter) { if (*iter == '*' && *(iter + 1) == '/') { --in; } else if (*iter == '/' && *(iter + 1) == '*') { ++in; } else if (*iter == '\0') { + printError(openingIter, openingIter + 2, "No closing */ found"); goto RETURN_ERROR; } } @@ -211,6 +215,23 @@ LexerNodeArray lexer(char *str) { if (isSpace(c)) { lexerPushClear(&result, &result_size, iter, &node_str_begin, &node_token, LEXER_TOKEN_NONE); + } else if (isString(c)) { + lexerPushClear(&result, &result_size, iter, &node_str_begin, &node_token, + LEXER_TOKEN_CHAR); + const char opening = c; + char *openingIter = iter; + ++iter; + for (;; ++iter) { + if (*iter == '\0') { + printError(openingIter, openingIter + 1, "No closing `%c` found", + opening); + goto RETURN_ERROR; + } else if (*iter == '\\') { + ++iter; + } else if (*iter == '\'') { + break; + } + } } else if (isIdentifier(c) || (node_token == LEXER_TOKEN_IDENTIFIER && isNumber(c))) { if (node_token != LEXER_TOKEN_IDENTIFIER && @@ -300,6 +321,7 @@ void lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter, case LEXER_TOKEN_KEYWORD_STRUCT: case LEXER_TOKEN_KEYWORD_UNDEFINED: case LEXER_TOKEN_NUMBER: + case LEXER_TOKEN_CHAR: case LEXER_TOKEN_SYMBOL_EOL: case LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS: case LEXER_TOKEN_SYMBOL_CLOSE_PARENTHESIS: @@ -397,6 +419,17 @@ bool isSpace(char c) { case ' ': case '\n': case '\t': + case '\v': + return true; + default: + return false; + } +} + +extern bool isString(char c) { + switch (c) { + case '\'': + case '\"': return true; default: return false; diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h index 8759e10..42f7aa8 100644 --- a/src/compiler/lexer.h +++ b/src/compiler/lexer.h @@ -36,6 +36,7 @@ typedef enum LexerToken { LEXER_TOKEN_KEYWORD_UNDEFINED, LEXER_TOKEN_NUMBER, + LEXER_TOKEN_CHAR, LEXER_TOKEN_SYMBOL, LEXER_TOKEN_SYMBOL_EOL, @@ -114,3 +115,4 @@ extern bool isNumber(char c); extern bool isSymbol(char c); extern bool isCompleteSymbol(char *str, size_t str_size); extern bool isSpace(char c); +extern bool isString(char c); diff --git a/src/compiler/parser.c b/src/compiler/parser.c index 951d3b4..8df9b2d 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -17,6 +17,7 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_VALUE_INT", "PARSER_TOKEN_VALUE_FLOAT", "PARSER_TOKEN_VALUE_BOOL", + "PARSER_TOKEN_VALUE_CHAR", "PARSER_TOKEN_TYPE_TYPE", "PARSER_TOKEN_TYPE_FUNCTION", @@ -109,7 +110,8 @@ static const ParserOrder PARSER_ORDER[] = { LEXER_TOKEN_KEYWORD_F128, LEXER_TOKEN_KEYWORD_U64, LEXER_TOKEN_KEYWORD_BOOL, LEXER_TOKEN_KEYWORD_TRUE, LEXER_TOKEN_KEYWORD_FALSE, LEXER_TOKEN_KEYWORD_NULL, - LEXER_TOKEN_NUMBER, LEXER_TOKEN_KEYWORD_UNDEFINED, ), + LEXER_TOKEN_NUMBER, LEXER_TOKEN_CHAR, + LEXER_TOKEN_KEYWORD_UNDEFINED, ), }, { .ltr = false, @@ -234,6 +236,11 @@ void parserNodePrint(const ParserNode *node, int indent) { printf(",value=%b", *metadata); } goto RETURN_SUCCESS; + case PARSER_TOKEN_VALUE_CHAR: { + ParserNodeCharMetadata *metadata = node->metadata; + printf(",value=%c", (char)*metadata); + } + goto RETURN_SUCCESS; case PARSER_TOKEN_CONSTANT: case PARSER_TOKEN_VARIABLE: { const ParserNodeVariableMetadata *metadata = node->metadata; @@ -479,7 +486,6 @@ void parserNodeDelete(ParserNode *node) { free(metadata); } goto RETURN_SUCCESS; - case PARSER_TOKEN_VALUE_INT: { ParserNodeIntMetadata *metadata = node->metadata; free(metadata); @@ -490,6 +496,11 @@ void parserNodeDelete(ParserNode *node) { free(metadata); } goto RETURN_SUCCESS; + case PARSER_TOKEN_VALUE_CHAR: { + ParserNodeCharMetadata *metadata = node->metadata; + free(metadata); + } + goto RETURN_SUCCESS; case PARSER_TOKEN_CONSTANT: case PARSER_TOKEN_VARIABLE: { ParserNodeVariableMetadata *metadata = node->metadata; @@ -749,6 +760,8 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, return parserComma(node, begin, parent); case LEXER_TOKEN_NUMBER: return parserNumber(node, parent); + case LEXER_TOKEN_CHAR: + return parserChar(node, parent); case LEXER_TOKEN_SYMBOL_ASSIGN: return parserBinaryOperator(node, begin, end, parent, PARSER_TOKEN_OPERATOR_ASSIGN); @@ -1011,6 +1024,22 @@ ParserNode *parserNumber(LexerNode *node, ParserNode *parent) { return node->parserNode = parserNode; } +ParserNode *parserChar(LexerNode *node, ParserNode *parent) { + const size_t size = node->str_end - 1 - node->str_begin - 1; + ParserNodeCharMetadata *metadata = a404m_malloc(sizeof(*metadata)); + if (size == 1) { + *metadata = *(node->str_begin + 1); + } else if (size > 1) { + NOT_IMPLEMENTED; + } else { + printError(node->str_begin, node->str_end, + "Bad character: Character can't be empty"); + } + return node->parserNode = + newParserNode(PARSER_TOKEN_VALUE_CHAR, node->str_begin, + node->str_end, metadata, parent); +} + ParserNode *parserBoolValue(LexerNode *node, ParserNode *parent) { ParserNodeBoolMetadata *metadata = a404m_malloc(sizeof(*metadata)); *metadata = node->token == LEXER_TOKEN_KEYWORD_TRUE; @@ -1218,6 +1247,7 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, case PARSER_TOKEN_VALUE_INT: case PARSER_TOKEN_VALUE_FLOAT: case PARSER_TOKEN_VALUE_BOOL: + case PARSER_TOKEN_VALUE_CHAR: case PARSER_TOKEN_TYPE_TYPE: case PARSER_TOKEN_TYPE_FUNCTION: case PARSER_TOKEN_TYPE_VOID: @@ -1700,6 +1730,7 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_VALUE_INT: case PARSER_TOKEN_VALUE_FLOAT: case PARSER_TOKEN_VALUE_BOOL: + case PARSER_TOKEN_VALUE_CHAR: case PARSER_TOKEN_KEYWORD_IF: case PARSER_TOKEN_KEYWORD_WHILE: case PARSER_TOKEN_KEYWORD_COMPTIME: @@ -1777,6 +1808,7 @@ bool isType(ParserNode *node) { case PARSER_TOKEN_VALUE_INT: case PARSER_TOKEN_VALUE_FLOAT: case PARSER_TOKEN_VALUE_BOOL: + case PARSER_TOKEN_VALUE_CHAR: case PARSER_TOKEN_KEYWORD_PRINT_U64: case PARSER_TOKEN_KEYWORD_RETURN: case PARSER_TOKEN_OPERATOR_ASSIGN: @@ -1813,6 +1845,7 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_VALUE_INT: case PARSER_TOKEN_VALUE_FLOAT: case PARSER_TOKEN_VALUE_BOOL: + case PARSER_TOKEN_VALUE_CHAR: case PARSER_TOKEN_IDENTIFIER: case PARSER_TOKEN_OPERATOR_ACCESS: case PARSER_TOKEN_OPERATOR_ASSIGN: diff --git a/src/compiler/parser.h b/src/compiler/parser.h index 8eaea77..cb7af45 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -13,6 +13,7 @@ typedef enum ParserToken { PARSER_TOKEN_VALUE_INT, PARSER_TOKEN_VALUE_FLOAT, PARSER_TOKEN_VALUE_BOOL, + PARSER_TOKEN_VALUE_CHAR, PARSER_TOKEN_TYPE_TYPE, PARSER_TOKEN_TYPE_FUNCTION, @@ -28,7 +29,7 @@ typedef enum ParserToken { PARSER_TOKEN_TYPE_U64, #ifdef FLOAT_16_SUPPORT PARSER_TOKEN_TYPE_F16, - #endif +#endif PARSER_TOKEN_TYPE_F32, PARSER_TOKEN_TYPE_F64, PARSER_TOKEN_TYPE_F128, @@ -86,7 +87,7 @@ extern const char *PARSER_TOKEN_STRINGS[]; typedef struct ParserOrder { bool ltr; size_t size; - LexerToken data[22]; + LexerToken data[23]; } ParserOrder; typedef struct ParserNode { @@ -130,6 +131,8 @@ typedef u64 ParserNodeIntMetadata; typedef f128 ParserNodeFloatMetadata; +typedef ParserNodeIntMetadata ParserNodeCharMetadata; + typedef struct ParserNodeInfixMetadata { ParserNode *left; ParserNode *right; @@ -177,6 +180,7 @@ ParserNode *parserNoMetadata(LexerNode *node, ParserNode *parent, ParserNode *parserPrintU64(LexerNode *node, LexerNode *end, ParserNode *parent); ParserNode *parserReturn(LexerNode *node, LexerNode *end, ParserNode *parent); ParserNode *parserNumber(LexerNode *node, ParserNode *parent); +ParserNode *parserChar(LexerNode *node, ParserNode *parent); ParserNode *parserBoolValue(LexerNode *node, ParserNode *parent); ParserNode *parserEol(LexerNode *node, LexerNode *begin, ParserNode *parent); ParserNode *parserComma(LexerNode *node, LexerNode *begin, ParserNode *parent); |