aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2025-05-31 00:57:45 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2025-05-31 00:57:45 +0330
commitb89fc3da7d9f1badde2f4879924b5df5522da203 (patch)
tree1d081ff63564fd2b7c42a374ef62d432761c4124
parentc91d3a8893b9c53c5c8e4c5cff72d7caf44cfee4 (diff)
add ability to specify int type as extension
-rw-r--r--Makefile4
-rw-r--r--code/main.felan13
-rw-r--r--src/compiler/ast-tree.c64
-rw-r--r--src/compiler/ast-tree.h1
-rw-r--r--src/compiler/parser.c82
-rw-r--r--src/compiler/parser.h20
-rw-r--r--src/utils/string.c17
-rw-r--r--src/utils/string.h3
8 files changed, 182 insertions, 22 deletions
diff --git a/Makefile b/Makefile
index d713229..0fd74c4 100644
--- a/Makefile
+++ b/Makefile
@@ -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);