diff options
author | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2025-05-31 00:57:45 +0330 |
---|---|---|
committer | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2025-05-31 00:57:45 +0330 |
commit | b89fc3da7d9f1badde2f4879924b5df5522da203 (patch) | |
tree | 1d081ff63564fd2b7c42a374ef62d432761c4124 | |
parent | c91d3a8893b9c53c5c8e4c5cff72d7caf44cfee4 (diff) |
add ability to specify int type as extension
-rw-r--r-- | Makefile | 4 | ||||
-rw-r--r-- | code/main.felan | 13 | ||||
-rw-r--r-- | src/compiler/ast-tree.c | 64 | ||||
-rw-r--r-- | src/compiler/ast-tree.h | 1 | ||||
-rw-r--r-- | src/compiler/parser.c | 82 | ||||
-rw-r--r-- | src/compiler/parser.h | 20 | ||||
-rw-r--r-- | src/utils/string.c | 17 | ||||
-rw-r--r-- | src/utils/string.h | 3 |
8 files changed, 182 insertions, 22 deletions
@@ -20,9 +20,9 @@ INC_DIRS := $(SRC_DIR) INC_FLAGS := $(addprefix -I,$(INC_DIRS)) # OP_FLAG := -Ofast -# OP_FLAG := -O3 +OP_FLAG := -O3 # OP_FLAG := -Oz -OP_FLAG := -g +# OP_FLAG := -g LINK_FLAGS := -lffi diff --git a/code/main.felan b/code/main.felan index 239a201..3420e42 100644 --- a/code/main.felan +++ b/code/main.felan @@ -21,15 +21,8 @@ __get_item_address__ :: (left:*anytype,index:i64,item:@type_of(left.*)) -> (@typ return (left + index); }; -main :: ()->void{ - arr :array(@cast(10,u64),i64) = undefined; - arr.ptr = @stack_alloc(10,i64); - i := 0; - while i < 10 { - __set_item__(arr.ptr,i,0); - i += 1; - } - print(__get_item__(arr.ptr,1)); - free(@cast(arr.ptr,*void)); +main :: () -> void { + print(1234u64); + print(1234U64); }; diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index c778571..1018bfd 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -2452,8 +2452,7 @@ AstTree *astTreeParse(const ParserNode *parserNode) { case PARSER_TOKEN_IDENTIFIER: return astTreeParseIdentifier(parserNode); case PARSER_TOKEN_VALUE_INT: - return astTreeParseValue(parserNode, AST_TREE_TOKEN_VALUE_INT, - sizeof(AstTreeInt), NULL); + return astTreeParseIntValue(parserNode); case PARSER_TOKEN_VALUE_FLOAT: return astTreeParseValue(parserNode, AST_TREE_TOKEN_VALUE_FLOAT, sizeof(AstTreeFloat), NULL); @@ -2956,6 +2955,67 @@ AstTree *astTreeParseValue(const ParserNode *parserNode, AstTreeToken token, parserNode->str_end); } +AstTree *astTreeParseIntValue(const ParserNode *parserNode) { + ParserNodeIntMetadata *node_metadata = parserNode->metadata; + switch (node_metadata->type) { + case PARSER_NODE_INT_TYPE_UNKNOWN: { + AstTreeInt *metadata = a404m_malloc(sizeof(*metadata)); + *metadata = node_metadata->value; + return newAstTree(AST_TREE_TOKEN_VALUE_INT, metadata, NULL, + parserNode->str_begin, parserNode->str_end); + } + case PARSER_NODE_INT_TYPE_I8: { + i8 *metadata = a404m_malloc(sizeof(*metadata)); + *metadata = node_metadata->value; + return newAstTree(AST_TREE_TOKEN_RAW_VALUE, metadata, &AST_TREE_I8_TYPE, + parserNode->str_begin, parserNode->str_end); + } + case PARSER_NODE_INT_TYPE_U8: { + u8 *metadata = a404m_malloc(sizeof(*metadata)); + *metadata = node_metadata->value; + return newAstTree(AST_TREE_TOKEN_RAW_VALUE, metadata, &AST_TREE_I8_TYPE, + parserNode->str_begin, parserNode->str_end); + } + case PARSER_NODE_INT_TYPE_I16: { + i16 *metadata = a404m_malloc(sizeof(*metadata)); + *metadata = node_metadata->value; + return newAstTree(AST_TREE_TOKEN_RAW_VALUE, metadata, &AST_TREE_I16_TYPE, + parserNode->str_begin, parserNode->str_end); + } + case PARSER_NODE_INT_TYPE_U16: { + u16 *metadata = a404m_malloc(sizeof(*metadata)); + *metadata = node_metadata->value; + return newAstTree(AST_TREE_TOKEN_RAW_VALUE, metadata, &AST_TREE_I16_TYPE, + parserNode->str_begin, parserNode->str_end); + } + case PARSER_NODE_INT_TYPE_I32: { + i32 *metadata = a404m_malloc(sizeof(*metadata)); + *metadata = node_metadata->value; + return newAstTree(AST_TREE_TOKEN_RAW_VALUE, metadata, &AST_TREE_I32_TYPE, + parserNode->str_begin, parserNode->str_end); + } + case PARSER_NODE_INT_TYPE_U32: { + u32 *metadata = a404m_malloc(sizeof(*metadata)); + *metadata = node_metadata->value; + return newAstTree(AST_TREE_TOKEN_RAW_VALUE, metadata, &AST_TREE_I32_TYPE, + parserNode->str_begin, parserNode->str_end); + } + case PARSER_NODE_INT_TYPE_I64: { + i64 *metadata = a404m_malloc(sizeof(*metadata)); + *metadata = node_metadata->value; + return newAstTree(AST_TREE_TOKEN_RAW_VALUE, metadata, &AST_TREE_I64_TYPE, + parserNode->str_begin, parserNode->str_end); + } + case PARSER_NODE_INT_TYPE_U64: { + u64 *metadata = a404m_malloc(sizeof(*metadata)); + *metadata = node_metadata->value; + return newAstTree(AST_TREE_TOKEN_RAW_VALUE, metadata, &AST_TREE_I64_TYPE, + parserNode->str_begin, parserNode->str_end); + } + } + UNREACHABLE; +} + AstTree *astTreeParseString(const ParserNode *parserNode) { ParserNodeStringMetadata *node_metadata = parserNode->metadata; diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h index 6979201..aef4826 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -406,6 +406,7 @@ AstTree *astTreeParseFunctionCall(const ParserNode *parserNode); AstTree *astTreeParseIdentifier(const ParserNode *parserNode); AstTree *astTreeParseValue(const ParserNode *parserNode, AstTreeToken token, size_t metadata_size, AstTree *type); +AstTree *astTreeParseIntValue(const ParserNode *parserNode); AstTree *astTreeParseString(const ParserNode *parserNode); AstTree *astTreeParseKeyword(const ParserNode *parserNode, AstTreeToken token); AstTree *astTreeParseLoopControl(const ParserNode *parserNode, diff --git a/src/compiler/parser.c b/src/compiler/parser.c index 65fd3c9..903a8af 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -328,7 +328,7 @@ void parserNodePrint(const ParserNode *node, int indent) { goto RETURN_SUCCESS; case PARSER_TOKEN_VALUE_INT: { ParserNodeIntMetadata *metadata = node->metadata; - printf(",operand=%lld", *metadata); + printf(",operand=%lld,type=%d", metadata->value, metadata->type); } goto RETURN_SUCCESS; case PARSER_TOKEN_VALUE_FLOAT: { @@ -343,7 +343,7 @@ void parserNodePrint(const ParserNode *node, int indent) { goto RETURN_SUCCESS; case PARSER_TOKEN_VALUE_CHAR: { ParserNodeCharMetadata *metadata = node->metadata; - printf(",value=%c", (char)*metadata); + printf(",value=%c", (char)metadata->value); } goto RETURN_SUCCESS; case PARSER_TOKEN_VALUE_STRING: { @@ -1294,13 +1294,16 @@ ParserNode *parserNumber(LexerNode *node, ParserNode *parent) { switch (*(node->str_begin + 1)) { case 'x': case 'X': - u64 value = hexToU64(node->str_begin + 2, node->str_end, &success); + ParserNodeIntType type = getIntType(node->str_begin + 2, node->str_end); + u64 value = hexToU64(node->str_begin + 2, + node->str_end - getIntTypeSize(type), &success); if (!success) { printError(node->str_begin, node->str_end, "Error in parsing number"); return NULL; } ParserNodeIntMetadata *metadata = a404m_malloc(sizeof(*metadata)); - *metadata = value; + metadata->value = value; + metadata->type = type; parserNode = newParserNode(PARSER_TOKEN_VALUE_INT, node->str_begin, node->str_end, metadata, parent); break; @@ -1311,10 +1314,13 @@ ParserNode *parserNumber(LexerNode *node, ParserNode *parent) { } // fall through default: { - u64 value = decimalToU64(node->str_begin, node->str_end, &success); + ParserNodeIntType type = getIntType(node->str_begin, node->str_end); + u64 value = decimalToU64(node->str_begin, + node->str_end - getIntTypeSize(type), &success); if (success) { ParserNodeIntMetadata *metadata = a404m_malloc(sizeof(*metadata)); - *metadata = value; + metadata->value = value; + metadata->type = type; parserNode = newParserNode(PARSER_TOKEN_VALUE_INT, node->str_begin, node->str_end, metadata, parent); } else { @@ -1355,7 +1361,8 @@ ParserNode *parserChar(LexerNode *node, ParserNode *parent) { printError(node->str_begin, node->str_end, "Bad character"); goto RETURN_ERROR; } - *metadata = c; + metadata->value = c; + metadata->type = PARSER_NODE_INT_TYPE_U8; return node->parserNode = newParserNode(PARSER_TOKEN_VALUE_CHAR, node->str_begin, node->str_end, metadata, parent); @@ -2842,3 +2849,64 @@ char escapeChar(char const *begin, char const *end, bool *success) { return 0; } } + +ParserNodeIntType getIntType(char const *begin, char const *end) { + static const char I8[] = "i8"; + static const size_t I8_SIZE = sizeof(I8) / sizeof(*I8) - sizeof(*I8); + static const char U8[] = "u8"; + static const size_t U8_SIZE = sizeof(U8) / sizeof(*U8) - sizeof(*U8); + static const char I16[] = "i16"; + static const size_t I16_SIZE = sizeof(I16) / sizeof(*I16) - sizeof(*I16); + static const char U16[] = "u16"; + static const size_t U16_SIZE = sizeof(U16) / sizeof(*U16) - sizeof(*U16); + static const char I32[] = "i32"; + static const size_t I32_SIZE = sizeof(I32) / sizeof(*I32) - sizeof(*I32); + static const char U32[] = "u32"; + static const size_t U32_SIZE = sizeof(U32) / sizeof(*U32) - sizeof(*U32); + static const char I64[] = "i64"; + static const size_t I64_SIZE = sizeof(I64) / sizeof(*I64) - sizeof(*I64); + static const char U64[] = "u64"; + static const size_t U64_SIZE = sizeof(U64) / sizeof(*U64) - sizeof(*U64); + + if (end - begin < 3) { + return PARSER_NODE_INT_TYPE_UNKNOWN; + } + + if (strnEqualsCaseInsensitive(end - I8_SIZE, I8, I8_SIZE)) { + return PARSER_NODE_INT_TYPE_I8; + } else if (strnEqualsCaseInsensitive(end - U8_SIZE, U8, U8_SIZE)) { + return PARSER_NODE_INT_TYPE_U8; + } else if (strnEqualsCaseInsensitive(end - I16_SIZE, I16, I16_SIZE)) { + return PARSER_NODE_INT_TYPE_I16; + } else if (strnEqualsCaseInsensitive(end - U16_SIZE, U16, U16_SIZE)) { + return PARSER_NODE_INT_TYPE_U16; + } else if (strnEqualsCaseInsensitive(end - I32_SIZE, I32, I32_SIZE)) { + return PARSER_NODE_INT_TYPE_I32; + } else if (strnEqualsCaseInsensitive(end - U32_SIZE, U32, U32_SIZE)) { + return PARSER_NODE_INT_TYPE_U32; + } else if (strnEqualsCaseInsensitive(end - I64_SIZE, I64, I64_SIZE)) { + return PARSER_NODE_INT_TYPE_I64; + } else if (strnEqualsCaseInsensitive(end - U64_SIZE, U64, U64_SIZE)) { + return PARSER_NODE_INT_TYPE_U64; + } else { + return PARSER_NODE_INT_TYPE_UNKNOWN; + } +} + +size_t getIntTypeSize(ParserNodeIntType type) { + switch (type) { + case PARSER_NODE_INT_TYPE_UNKNOWN: + return 0; + case PARSER_NODE_INT_TYPE_I8: + case PARSER_NODE_INT_TYPE_U8: + return 2; + case PARSER_NODE_INT_TYPE_I16: + case PARSER_NODE_INT_TYPE_U16: + case PARSER_NODE_INT_TYPE_I32: + case PARSER_NODE_INT_TYPE_U32: + case PARSER_NODE_INT_TYPE_I64: + case PARSER_NODE_INT_TYPE_U64: + return 3; + } + UNREACHABLE; +} diff --git a/src/compiler/parser.h b/src/compiler/parser.h index fd40078..3f69454 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -176,7 +176,22 @@ typedef struct ParserNodeFunctionCall { typedef ParserNode ParserNodeSingleChildMetadata; -typedef u64 ParserNodeIntMetadata; +typedef enum ParserNodeIntType { + PARSER_NODE_INT_TYPE_UNKNOWN, + PARSER_NODE_INT_TYPE_I8, + PARSER_NODE_INT_TYPE_U8, + PARSER_NODE_INT_TYPE_I16, + PARSER_NODE_INT_TYPE_U16, + PARSER_NODE_INT_TYPE_I32, + PARSER_NODE_INT_TYPE_U32, + PARSER_NODE_INT_TYPE_I64, + PARSER_NODE_INT_TYPE_U64, +} ParserNodeIntType; + +typedef struct ParserNodeIntMetadata { + u64 value; + ParserNodeIntType type; +} ParserNodeIntMetadata; typedef f128 ParserNodeFloatMetadata; @@ -293,3 +308,6 @@ bool isType(ParserNode *node); bool isValue(ParserNode *node); char escapeChar(char const *begin, char const *end, bool *success); + +ParserNodeIntType getIntType(char const *begin, char const *end); +size_t getIntTypeSize(ParserNodeIntType type); diff --git a/src/utils/string.c b/src/utils/string.c index 1932d89..28c1600 100644 --- a/src/utils/string.c +++ b/src/utils/string.c @@ -1,5 +1,6 @@ #include "string.h" #include "memory.h" +#include "utils/log.h" #include "utils/type.h" size_t strLength(const char *str) { @@ -28,6 +29,16 @@ bool strnEquals(const char *left, const char *right, size_t len) { return true; } +bool strnEqualsCaseInsensitive(const char *left, const char *right, + size_t len) { + for (size_t i = 0; i < len; ++i) { + if (!charEqualsCaseInsensitive(left[i], right[i])) { + return false; + } + } + return true; +} + size_t searchInStringArray(const char *array[], size_t array_size, const char *str, size_t str_size) { for (size_t i = 0; i < array_size; ++i) { @@ -143,3 +154,9 @@ char *strClone(const char *str) { } return result; } + +bool charEqualsCaseInsensitive(char left, char right) { + return left == right || + ('A' <= right && right <= 'Z' && left == right + ('a' - 'A')) || + ('A' <= left && left <= 'Z' && right == left + ('a' - 'A')); +} diff --git a/src/utils/string.h b/src/utils/string.h index dd2209c..0b11dae 100644 --- a/src/utils/string.h +++ b/src/utils/string.h @@ -8,6 +8,7 @@ size_t strLength(const char *str); bool strEquals(const char *left, const char *right); bool strnEquals(const char *left, const char *right, size_t len); +bool strnEqualsCaseInsensitive(const char *left, const char *right, size_t len); size_t searchInStringArray(const char *array[], size_t array_size, const char *str, size_t str_size); @@ -18,3 +19,5 @@ f128 numberToFloat(char const*str_begin, char const*str_end, bool *success); char *u64ToString(u64 value); char *strClone(const char *str); + +bool charEqualsCaseInsensitive(char left,char right); |