diff options
author | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2025-05-23 09:59:14 +0330 |
---|---|---|
committer | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2025-05-23 09:59:14 +0330 |
commit | 093c3bece426686b175db9ddaecd6abc8908fd87 (patch) | |
tree | 4af50cb8b98df96095526ded3fb0996ec56f8fbf | |
parent | 368d75dbd68f0f0e204d1d2575f8e7c6fbe9b49d (diff) |
add @size_of
-rw-r--r-- | code/main.felan | 12 | ||||
-rw-r--r-- | src/compiler/ast-tree.c | 129 | ||||
-rw-r--r-- | src/compiler/ast-tree.h | 7 | ||||
-rw-r--r-- | src/compiler/lexer.c | 6 | ||||
-rw-r--r-- | src/compiler/lexer.h | 1 | ||||
-rw-r--r-- | src/compiler/parser.c | 27 | ||||
-rw-r--r-- | src/compiler/parser.h | 3 | ||||
-rw-r--r-- | src/runner/runner.c | 17 |
8 files changed, 196 insertions, 6 deletions
diff --git a/code/main.felan b/code/main.felan index ec02627..c2e573c 100644 --- a/code/main.felan +++ b/code/main.felan @@ -49,15 +49,21 @@ fun3 :: ()->void{ @putc(@cast(a.a,u8)+'0'); }; +fun4 :: ()->void{ + p := @size_of(123); + @putc(@cast(p,u8)+'0'); +}; + /* -libc :: @c_lib("/lib/libc.so"); +libc :: @c_library("/lib/libc.so"); putchar : (i8)->void : @c_function(libc,"putchar"); */ main :: ()->void{ // fun0(); - fun1(); + // fun1(); // fun2(); - //fun3(); + // fun3(); + fun4(); }; diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index d5c3d85..23d047f 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -170,6 +170,7 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_BUILTIN_CAST", "AST_TREE_TOKEN_BUILTIN_TYPE_OF", + "AST_TREE_TOKEN_BUILTIN_SIZE_OF", "AST_TREE_TOKEN_BUILTIN_IMPORT", "AST_TREE_TOKEN_BUILTIN_IS_COMPTIME", "AST_TREE_TOKEN_BUILTIN_STACK_ALLOC", @@ -187,6 +188,8 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL", "AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL", "AST_TREE_TOKEN_BUILTIN_PUTC", + "AST_TREE_TOKEN_BUILTIN_C_LIBRARY", + "AST_TREE_TOKEN_BUILTIN_C_FUNCTION", "AST_TREE_TOKEN_KEYWORD_RETURN", "AST_TREE_TOKEN_KEYWORD_BREAK", @@ -314,6 +317,7 @@ void astTreePrint(const AstTree *tree, int indent) { goto RETURN_SUCCESS; case AST_TREE_TOKEN_BUILTIN_CAST: case AST_TREE_TOKEN_BUILTIN_TYPE_OF: + case AST_TREE_TOKEN_BUILTIN_SIZE_OF: case AST_TREE_TOKEN_BUILTIN_IMPORT: case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: @@ -331,6 +335,8 @@ void astTreePrint(const AstTree *tree, int indent) { case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_PUTC: + case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: + case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_VOID: case AST_TREE_TOKEN_TYPE_I8: @@ -746,6 +752,7 @@ void astTreeDestroy(AstTree tree) { return; case AST_TREE_TOKEN_BUILTIN_CAST: case AST_TREE_TOKEN_BUILTIN_TYPE_OF: + case AST_TREE_TOKEN_BUILTIN_SIZE_OF: case AST_TREE_TOKEN_BUILTIN_IMPORT: case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: @@ -763,6 +770,8 @@ void astTreeDestroy(AstTree tree) { case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_PUTC: + case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: + case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_VOID: case AST_TREE_TOKEN_TYPE_I8: @@ -1099,6 +1108,7 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], case AST_TREE_TOKEN_VALUE_UNDEFINED: case AST_TREE_TOKEN_BUILTIN_CAST: case AST_TREE_TOKEN_BUILTIN_TYPE_OF: + case AST_TREE_TOKEN_BUILTIN_SIZE_OF: case AST_TREE_TOKEN_BUILTIN_IMPORT: case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: @@ -1116,6 +1126,8 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_PUTC: + case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: + case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: return newAstTree(tree->token, NULL, copyAstTreeBack(tree->type, oldVariables, newVariables, variables_size, safetyCheck), @@ -2069,6 +2081,7 @@ AstTreeRoot *makeAstRoot(const ParserNode *parsedRoot, char *filePath) { case PARSER_TOKEN_KEYWORD_STRUCT: case PARSER_TOKEN_BUILTIN_CAST: case PARSER_TOKEN_BUILTIN_TYPE_OF: + case PARSER_TOKEN_BUILTIN_SIZE_OF: case PARSER_TOKEN_BUILTIN_IMPORT: case PARSER_TOKEN_BUILTIN_IS_COMPTIME: case PARSER_TOKEN_BUILTIN_STACK_ALLOC: @@ -2086,6 +2099,8 @@ AstTreeRoot *makeAstRoot(const ParserNode *parsedRoot, char *filePath) { case PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL: case PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case PARSER_TOKEN_BUILTIN_PUTC: + case PARSER_TOKEN_BUILTIN_C_LIBRARY: + case PARSER_TOKEN_BUILTIN_C_FUNCTION: case PARSER_TOKEN_SYMBOL_BRACKET_LEFT: case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT: goto AFTER_SWITCH; @@ -2173,6 +2188,8 @@ AstTree *astTreeParse(const ParserNode *parserNode) { return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_CAST); case PARSER_TOKEN_BUILTIN_TYPE_OF: return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_TYPE_OF); + case PARSER_TOKEN_BUILTIN_SIZE_OF: + return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_SIZE_OF); case PARSER_TOKEN_BUILTIN_IMPORT: return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_IMPORT); case PARSER_TOKEN_BUILTIN_IS_COMPTIME: @@ -2209,6 +2226,10 @@ AstTree *astTreeParse(const ParserNode *parserNode) { AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL); case PARSER_TOKEN_BUILTIN_PUTC: return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_PUTC); + case PARSER_TOKEN_BUILTIN_C_LIBRARY: + return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_C_LIBRARY); + case PARSER_TOKEN_BUILTIN_C_FUNCTION: + return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_C_FUNCTION); case PARSER_TOKEN_TYPE_TYPE: return &AST_TREE_TYPE_TYPE; case PARSER_TOKEN_TYPE_FUNCTION: @@ -2517,6 +2538,7 @@ AstTree *astTreeParseFunction(const ParserNode *parserNode) { case PARSER_TOKEN_OPERATOR_LOGICAL_OR: case PARSER_TOKEN_BUILTIN_CAST: case PARSER_TOKEN_BUILTIN_TYPE_OF: + case PARSER_TOKEN_BUILTIN_SIZE_OF: case PARSER_TOKEN_BUILTIN_IMPORT: case PARSER_TOKEN_BUILTIN_IS_COMPTIME: case PARSER_TOKEN_BUILTIN_STACK_ALLOC: @@ -2534,6 +2556,8 @@ AstTree *astTreeParseFunction(const ParserNode *parserNode) { case PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL: case PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case PARSER_TOKEN_BUILTIN_PUTC: + case PARSER_TOKEN_BUILTIN_C_LIBRARY: + case PARSER_TOKEN_BUILTIN_C_FUNCTION: case PARSER_TOKEN_SYMBOL_BRACKET_LEFT: case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT: printError(node->str_begin, node->str_end, "Unexpected %s", @@ -3130,6 +3154,7 @@ AstTree *astTreeParseCurlyBracket(const ParserNode *parserNode) { case PARSER_TOKEN_OPERATOR_LOGICAL_OR: case PARSER_TOKEN_BUILTIN_CAST: case PARSER_TOKEN_BUILTIN_TYPE_OF: + case PARSER_TOKEN_BUILTIN_SIZE_OF: case PARSER_TOKEN_BUILTIN_IMPORT: case PARSER_TOKEN_BUILTIN_IS_COMPTIME: case PARSER_TOKEN_BUILTIN_STACK_ALLOC: @@ -3147,6 +3172,8 @@ AstTree *astTreeParseCurlyBracket(const ParserNode *parserNode) { case PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL: case PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case PARSER_TOKEN_BUILTIN_PUTC: + case PARSER_TOKEN_BUILTIN_C_LIBRARY: + case PARSER_TOKEN_BUILTIN_C_FUNCTION: case PARSER_TOKEN_SYMBOL_BRACKET_LEFT: case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT: printError(node->str_begin, node->str_end, "Unexpected %s", @@ -3351,6 +3378,7 @@ bool isConst(AstTree *tree) { switch (tree->token) { case AST_TREE_TOKEN_BUILTIN_CAST: case AST_TREE_TOKEN_BUILTIN_TYPE_OF: + case AST_TREE_TOKEN_BUILTIN_SIZE_OF: case AST_TREE_TOKEN_BUILTIN_IMPORT: case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: @@ -3368,6 +3396,8 @@ bool isConst(AstTree *tree) { case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_PUTC: + case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: + case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_FUNCTION: case AST_TREE_TOKEN_TYPE_VOID: @@ -3421,7 +3451,8 @@ bool isConst(AstTree *tree) { case AST_TREE_TOKEN_FUNCTION_CALL: { AstTreeFunctionCall *metadata = tree->metadata; - if (metadata->function->token == AST_TREE_TOKEN_BUILTIN_TYPE_OF) { + if (metadata->function->token == AST_TREE_TOKEN_BUILTIN_TYPE_OF || + metadata->function->token == AST_TREE_TOKEN_BUILTIN_SIZE_OF) { return true; } @@ -3652,6 +3683,7 @@ AstTree *makeTypeOf(AstTree *value) { } case AST_TREE_TOKEN_BUILTIN_CAST: case AST_TREE_TOKEN_BUILTIN_TYPE_OF: + case AST_TREE_TOKEN_BUILTIN_SIZE_OF: case AST_TREE_TOKEN_BUILTIN_IMPORT: case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: @@ -3669,6 +3701,8 @@ AstTree *makeTypeOf(AstTree *value) { case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_PUTC: + case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: + case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: case AST_TREE_TOKEN_VALUE_OBJECT: case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_KEYWORD_RETURN: @@ -3733,6 +3767,7 @@ bool typeIsEqualBack(const AstTree *type0, const AstTree *type1) { switch (type0->token) { case AST_TREE_TOKEN_BUILTIN_CAST: case AST_TREE_TOKEN_BUILTIN_TYPE_OF: + case AST_TREE_TOKEN_BUILTIN_SIZE_OF: case AST_TREE_TOKEN_BUILTIN_IMPORT: case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: @@ -3750,6 +3785,8 @@ bool typeIsEqualBack(const AstTree *type0, const AstTree *type1) { case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_PUTC: + case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: + case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_BREAK: @@ -3903,6 +3940,7 @@ AstTree *getValue(AstTree *tree, bool copy) { switch (tree->token) { case AST_TREE_TOKEN_BUILTIN_CAST: case AST_TREE_TOKEN_BUILTIN_TYPE_OF: + case AST_TREE_TOKEN_BUILTIN_SIZE_OF: case AST_TREE_TOKEN_BUILTIN_IMPORT: case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: @@ -3920,6 +3958,8 @@ AstTree *getValue(AstTree *tree, bool copy) { case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_PUTC: + case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: + case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: case AST_TREE_TOKEN_TYPE_FUNCTION: case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_VOID: @@ -4044,6 +4084,7 @@ bool isIntType(AstTree *type) { case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_BUILTIN_CAST: case AST_TREE_TOKEN_BUILTIN_TYPE_OF: + case AST_TREE_TOKEN_BUILTIN_SIZE_OF: case AST_TREE_TOKEN_BUILTIN_IMPORT: case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: @@ -4061,6 +4102,8 @@ bool isIntType(AstTree *type) { case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_PUTC: + case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: + case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_BREAK: case AST_TREE_TOKEN_KEYWORD_CONTINUE: @@ -4146,6 +4189,7 @@ bool isFloatType(AstTree *type) { case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_BUILTIN_CAST: case AST_TREE_TOKEN_BUILTIN_TYPE_OF: + case AST_TREE_TOKEN_BUILTIN_SIZE_OF: case AST_TREE_TOKEN_BUILTIN_IMPORT: case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: @@ -4163,6 +4207,8 @@ bool isFloatType(AstTree *type) { case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_PUTC: + case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: + case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_BREAK: case AST_TREE_TOKEN_KEYWORD_CONTINUE: @@ -4279,6 +4325,7 @@ bool isEqual(AstTree *left, AstTree *right) { case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_BUILTIN_CAST: case AST_TREE_TOKEN_BUILTIN_TYPE_OF: + case AST_TREE_TOKEN_BUILTIN_SIZE_OF: case AST_TREE_TOKEN_BUILTIN_IMPORT: case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: @@ -4296,6 +4343,8 @@ bool isEqual(AstTree *left, AstTree *right) { case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_PUTC: + case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: + case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_BREAK: case AST_TREE_TOKEN_KEYWORD_CONTINUE: @@ -4613,6 +4662,8 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, return setTypesBuiltinCast(tree, helper, functionCall); case AST_TREE_TOKEN_BUILTIN_TYPE_OF: return setTypesBuiltinTypeOf(tree, helper, functionCall); + case AST_TREE_TOKEN_BUILTIN_SIZE_OF: + return setTypesBuiltinSizeOf(tree, helper, functionCall); case AST_TREE_TOKEN_BUILTIN_IMPORT: return setTypesBuiltinImport(tree, helper, functionCall); case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: @@ -4639,6 +4690,10 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, &AST_TREE_BOOL_TYPE); case AST_TREE_TOKEN_BUILTIN_PUTC: return setTypesBuiltinPutc(tree, helper, functionCall); + case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: + NOT_IMPLEMENTED; + case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: + NOT_IMPLEMENTED; case AST_TREE_TOKEN_TYPE_ARRAY: return setTypesTypeArray(tree, helper); case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: @@ -6012,6 +6067,72 @@ bool setTypesBuiltinTypeOf(AstTree *tree, AstTreeSetTypesHelper helper, } } +bool setTypesBuiltinSizeOf(AstTree *tree, AstTreeSetTypesHelper helper, + AstTreeFunctionCall *functionCall) { + (void)helper; + if (functionCall->parameters_size == 1) { + AstTree *type = NULL; + + static const char TYPE_STR[] = "type"; + static const size_t TYPE_STR_SIZE = + sizeof(TYPE_STR) / sizeof(*TYPE_STR) - sizeof(*TYPE_STR); + + for (size_t i = 0; i < functionCall->parameters_size; ++i) { + AstTreeFunctionCallParam param = functionCall->parameters[i]; + const size_t param_name_size = param.nameEnd - param.nameBegin; + + if (param_name_size == 0) { + if (type == NULL) { + type = param.value; + } else { + printError(param.value->str_begin, param.value->str_end, + "Bad paramter"); + return false; + } + } else if (param_name_size == TYPE_STR_SIZE && + strnEquals(param.nameBegin, TYPE_STR, TYPE_STR_SIZE) && + type == NULL) { + type = param.value; + } else { + printError(param.value->str_begin, param.value->str_end, + "Bad paramter"); + return false; + } + } + + if (type == NULL) { + return false; + } else if (!typeIsEqual(type, &AST_TREE_TYPE_TYPE)) { + printError(type->str_begin, type->str_end, + "Type missmatch, the argument should be `type`"); + return false; + } + + AstTreeTypeFunction *type_metadata = a404m_malloc(sizeof(*type_metadata)); + type_metadata->arguments_size = 1; + type_metadata->arguments = a404m_malloc(type_metadata->arguments_size * + sizeof(*type_metadata->arguments)); + + type_metadata->returnType = copyAstTree(&AST_TREE_U64_TYPE); + + type_metadata->arguments[0] = (AstTreeTypeFunctionArgument){ + .type = copyAstTree(&AST_TREE_TYPE_TYPE), + .name_begin = TYPE_STR, + .name_end = TYPE_STR + TYPE_STR_SIZE, + .str_begin = NULL, + .str_end = NULL, + .isComptime = false, + }; + + tree->type = newAstTree(AST_TREE_TOKEN_TYPE_FUNCTION, type_metadata, + &AST_TREE_TYPE_TYPE, NULL, NULL); + return true; + } else { + printError(tree->str_begin, tree->str_end, "Too many or too few arguments"); + return false; + } +} + bool setTypesBuiltinImport(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunctionCall *functionCall) { (void)helper; @@ -6139,6 +6260,7 @@ bool setTypesBuiltinUnary(AstTree *tree, AstTreeSetTypesHelper helper, case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: case AST_TREE_TOKEN_BUILTIN_CAST: case AST_TREE_TOKEN_BUILTIN_TYPE_OF: + case AST_TREE_TOKEN_BUILTIN_SIZE_OF: case AST_TREE_TOKEN_BUILTIN_IMPORT: case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: @@ -6156,6 +6278,8 @@ bool setTypesBuiltinUnary(AstTree *tree, AstTreeSetTypesHelper helper, case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_PUTC: + case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: + case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_BREAK: case AST_TREE_TOKEN_KEYWORD_CONTINUE: @@ -6934,6 +7058,7 @@ size_t getSizeOfType(AstTree *type) { case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_BUILTIN_CAST: case AST_TREE_TOKEN_BUILTIN_TYPE_OF: + case AST_TREE_TOKEN_BUILTIN_SIZE_OF: case AST_TREE_TOKEN_BUILTIN_IMPORT: case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: @@ -6951,6 +7076,8 @@ size_t getSizeOfType(AstTree *type) { case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_PUTC: + case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: + case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: case AST_TREE_TOKEN_KEYWORD_RETURN: case AST_TREE_TOKEN_KEYWORD_BREAK: case AST_TREE_TOKEN_KEYWORD_CONTINUE: diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h index 7bf9811..d05db7b 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -9,6 +9,7 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_BUILTIN_CAST, AST_TREE_TOKEN_BUILTIN_BEGIN = AST_TREE_TOKEN_BUILTIN_CAST, AST_TREE_TOKEN_BUILTIN_TYPE_OF, + AST_TREE_TOKEN_BUILTIN_SIZE_OF, AST_TREE_TOKEN_BUILTIN_IMPORT, AST_TREE_TOKEN_BUILTIN_IS_COMPTIME, AST_TREE_TOKEN_BUILTIN_STACK_ALLOC, @@ -26,7 +27,9 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL, AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL, AST_TREE_TOKEN_BUILTIN_PUTC, - AST_TREE_TOKEN_BUILTIN_END = AST_TREE_TOKEN_BUILTIN_PUTC, + AST_TREE_TOKEN_BUILTIN_C_LIBRARY, + AST_TREE_TOKEN_BUILTIN_C_FUNCTION, + AST_TREE_TOKEN_BUILTIN_END = AST_TREE_TOKEN_BUILTIN_C_FUNCTION, AST_TREE_TOKEN_KEYWORD_RETURN, AST_TREE_TOKEN_KEYWORD_BREAK, @@ -456,6 +459,8 @@ bool setTypesBuiltinCast(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunctionCall *functionCall); bool setTypesBuiltinTypeOf(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunctionCall *functionCall); +bool setTypesBuiltinSizeOf(AstTree *tree, AstTreeSetTypesHelper helper, + AstTreeFunctionCall *functionCall); bool setTypesBuiltinImport(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunctionCall *functionCall); bool setTypesBuiltinIsComptime(AstTree *tree, AstTreeSetTypesHelper helper); diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index 23a827e..577b009 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -13,6 +13,7 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_BUILTIN", "LEXER_TOKEN_BUILTIN_CAST", "LEXER_TOKEN_BUILTIN_TYPE_OF", + "LEXER_TOKEN_BUILTIN_SIZE_OF", "LEXER_TOKEN_BUILTIN_IMPORT", "LEXER_TOKEN_BUILTIN_IS_COMPTIME", "LEXER_TOKEN_BUILTIN_STACK_ALLOC", @@ -202,6 +203,7 @@ static const size_t LEXER_KEYWORD_SIZE = static const char *LEXER_BUILTIN_STRINGS[] = { "cast", "type_of", + "size_of", "import", "is_comptime", "stack_alloc", @@ -225,6 +227,7 @@ static const char *LEXER_BUILTIN_STRINGS[] = { static const LexerToken LEXER_BUILTIN_TOKENS[] = { LEXER_TOKEN_BUILTIN_CAST, LEXER_TOKEN_BUILTIN_TYPE_OF, + LEXER_TOKEN_BUILTIN_SIZE_OF, LEXER_TOKEN_BUILTIN_IMPORT, LEXER_TOKEN_BUILTIN_IS_COMPTIME, LEXER_TOKEN_BUILTIN_STACK_ALLOC, @@ -511,6 +514,9 @@ lexerPushClear(LexerNodeArray *array, size_t *array_size, char const *iter, case LEXER_TOKEN_BUILTIN_GREATER_OR_EQUAL: case LEXER_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case LEXER_TOKEN_BUILTIN_PUTC: + case LEXER_TOKEN_BUILTIN_SIZE_OF: + case LEXER_TOKEN_BUILTIN_C_LIBRARY: + case LEXER_TOKEN_BUILTIN_C_FUNCTION: case LEXER_TOKEN_SYMBOL_CLOSE_BRACKET: case LEXER_TOKEN_SYMBOL_OPEN_BRACKET: case LEXER_TOKEN_KEYWORD_SHAPE_SHIFTER: diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h index d07f7e7..3523a5f 100644 --- a/src/compiler/lexer.h +++ b/src/compiler/lexer.h @@ -15,6 +15,7 @@ typedef enum LexerToken { LEXER_TOKEN_BUILTIN, LEXER_TOKEN_BUILTIN_CAST, LEXER_TOKEN_BUILTIN_TYPE_OF, + LEXER_TOKEN_BUILTIN_SIZE_OF, LEXER_TOKEN_BUILTIN_IMPORT, LEXER_TOKEN_BUILTIN_IS_COMPTIME, LEXER_TOKEN_BUILTIN_STACK_ALLOC, diff --git a/src/compiler/parser.c b/src/compiler/parser.c index e8772fb..ba7a4a0 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -14,6 +14,7 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_BUILTIN_CAST", "PARSER_TOKEN_BUILTIN_TYPE_OF", + "PARSER_TOKEN_BUILTIN_SIZE_OF", "PARSER_TOKEN_BUILTIN_IMPORT", "PARSER_TOKEN_BUILTIN_IS_COMPTIME", "PARSER_TOKEN_BUILTIN_STACK_ALLOC", @@ -31,6 +32,8 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL", "PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL", "PARSER_TOKEN_BUILTIN_PUTC", + "PARSER_TOKEN_BUILTIN_C_LIBRARY", + "PARSER_TOKEN_BUILTIN_C_FUNCTION", "PARSER_TOKEN_VALUE_INT", "PARSER_TOKEN_VALUE_FLOAT", @@ -244,6 +247,7 @@ void parserNodePrint(const ParserNode *node, int indent) { case PARSER_TOKEN_IDENTIFIER: case PARSER_TOKEN_BUILTIN_CAST: case PARSER_TOKEN_BUILTIN_TYPE_OF: + case PARSER_TOKEN_BUILTIN_SIZE_OF: case PARSER_TOKEN_BUILTIN_IMPORT: case PARSER_TOKEN_BUILTIN_IS_COMPTIME: case PARSER_TOKEN_BUILTIN_STACK_ALLOC: @@ -261,6 +265,8 @@ void parserNodePrint(const ParserNode *node, int indent) { case PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL: case PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case PARSER_TOKEN_BUILTIN_PUTC: + case PARSER_TOKEN_BUILTIN_C_LIBRARY: + case PARSER_TOKEN_BUILTIN_C_FUNCTION: case PARSER_TOKEN_TYPE_TYPE: case PARSER_TOKEN_TYPE_VOID: case PARSER_TOKEN_TYPE_BOOL: @@ -549,6 +555,7 @@ void parserNodeDelete(ParserNode *node) { case PARSER_TOKEN_IDENTIFIER: case PARSER_TOKEN_BUILTIN_CAST: case PARSER_TOKEN_BUILTIN_TYPE_OF: + case PARSER_TOKEN_BUILTIN_SIZE_OF: case PARSER_TOKEN_BUILTIN_IMPORT: case PARSER_TOKEN_BUILTIN_IS_COMPTIME: case PARSER_TOKEN_BUILTIN_STACK_ALLOC: @@ -566,6 +573,8 @@ void parserNodeDelete(ParserNode *node) { case PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL: case PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case PARSER_TOKEN_BUILTIN_PUTC: + case PARSER_TOKEN_BUILTIN_C_LIBRARY: + case PARSER_TOKEN_BUILTIN_C_FUNCTION: case PARSER_TOKEN_TYPE_TYPE: case PARSER_TOKEN_TYPE_VOID: case PARSER_TOKEN_TYPE_BOOL: @@ -854,6 +863,8 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_CAST); case LEXER_TOKEN_BUILTIN_TYPE_OF: return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_TYPE_OF); + case LEXER_TOKEN_BUILTIN_SIZE_OF: + return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_SIZE_OF); case LEXER_TOKEN_BUILTIN_IMPORT: return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_IMPORT); case LEXER_TOKEN_BUILTIN_IS_COMPTIME: @@ -890,6 +901,10 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL); case LEXER_TOKEN_BUILTIN_PUTC: return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_PUTC); + case LEXER_TOKEN_BUILTIN_C_LIBRARY: + return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_C_LIBRARY); + case LEXER_TOKEN_BUILTIN_C_FUNCTION: + return parserNoMetadata(node, parent, PARSER_TOKEN_BUILTIN_C_FUNCTION); case LEXER_TOKEN_KEYWORD_TYPE: return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_TYPE); case LEXER_TOKEN_KEYWORD_VOID: @@ -1659,6 +1674,7 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, case PARSER_TOKEN_IDENTIFIER: case PARSER_TOKEN_BUILTIN_CAST: case PARSER_TOKEN_BUILTIN_TYPE_OF: + case PARSER_TOKEN_BUILTIN_SIZE_OF: case PARSER_TOKEN_BUILTIN_IMPORT: case PARSER_TOKEN_BUILTIN_IS_COMPTIME: case PARSER_TOKEN_BUILTIN_STACK_ALLOC: @@ -1676,6 +1692,8 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, case PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL: case PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case PARSER_TOKEN_BUILTIN_PUTC: + case PARSER_TOKEN_BUILTIN_C_LIBRARY: + case PARSER_TOKEN_BUILTIN_C_FUNCTION: case PARSER_TOKEN_VALUE_INT: case PARSER_TOKEN_VALUE_FLOAT: case PARSER_TOKEN_VALUE_BOOL: @@ -2160,6 +2178,7 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_IDENTIFIER: case PARSER_TOKEN_BUILTIN_CAST: case PARSER_TOKEN_BUILTIN_TYPE_OF: + case PARSER_TOKEN_BUILTIN_SIZE_OF: case PARSER_TOKEN_BUILTIN_IMPORT: case PARSER_TOKEN_BUILTIN_IS_COMPTIME: case PARSER_TOKEN_BUILTIN_STACK_ALLOC: @@ -2177,6 +2196,8 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL: case PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case PARSER_TOKEN_BUILTIN_PUTC: + case PARSER_TOKEN_BUILTIN_C_LIBRARY: + case PARSER_TOKEN_BUILTIN_C_FUNCTION: case PARSER_TOKEN_CONSTANT: case PARSER_TOKEN_VARIABLE: case PARSER_TOKEN_SYMBOL_PARENTHESIS: @@ -2293,6 +2314,7 @@ bool isType(ParserNode *node) { return true; case PARSER_TOKEN_BUILTIN_CAST: case PARSER_TOKEN_BUILTIN_TYPE_OF: + case PARSER_TOKEN_BUILTIN_SIZE_OF: case PARSER_TOKEN_BUILTIN_IMPORT: case PARSER_TOKEN_BUILTIN_IS_COMPTIME: case PARSER_TOKEN_BUILTIN_STACK_ALLOC: @@ -2310,6 +2332,8 @@ bool isType(ParserNode *node) { case PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL: case PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case PARSER_TOKEN_BUILTIN_PUTC: + case PARSER_TOKEN_BUILTIN_C_LIBRARY: + case PARSER_TOKEN_BUILTIN_C_FUNCTION: case PARSER_TOKEN_OPERATOR_ADDRESS: case PARSER_TOKEN_KEYWORD_NULL: case PARSER_TOKEN_KEYWORD_UNDEFINED: @@ -2369,6 +2393,7 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_IDENTIFIER: case PARSER_TOKEN_BUILTIN_CAST: case PARSER_TOKEN_BUILTIN_TYPE_OF: + case PARSER_TOKEN_BUILTIN_SIZE_OF: case PARSER_TOKEN_BUILTIN_IMPORT: case PARSER_TOKEN_BUILTIN_IS_COMPTIME: case PARSER_TOKEN_BUILTIN_STACK_ALLOC: @@ -2386,6 +2411,8 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL: case PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case PARSER_TOKEN_BUILTIN_PUTC: + case PARSER_TOKEN_BUILTIN_C_LIBRARY: + case PARSER_TOKEN_BUILTIN_C_FUNCTION: case PARSER_TOKEN_OPERATOR_ACCESS: case PARSER_TOKEN_OPERATOR_ASSIGN: case PARSER_TOKEN_OPERATOR_SUM_ASSIGN: diff --git a/src/compiler/parser.h b/src/compiler/parser.h index 463b6a9..1967dd6 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -11,6 +11,7 @@ typedef enum ParserToken { PARSER_TOKEN_BUILTIN_CAST, PARSER_TOKEN_BUILTIN_TYPE_OF, + PARSER_TOKEN_BUILTIN_SIZE_OF, PARSER_TOKEN_BUILTIN_IMPORT, PARSER_TOKEN_BUILTIN_IS_COMPTIME, PARSER_TOKEN_BUILTIN_STACK_ALLOC, @@ -28,6 +29,8 @@ typedef enum ParserToken { PARSER_TOKEN_BUILTIN_GREATER_OR_EQUAL, PARSER_TOKEN_BUILTIN_SMALLER_OR_EQUAL, PARSER_TOKEN_BUILTIN_PUTC, + PARSER_TOKEN_BUILTIN_C_LIBRARY, + PARSER_TOKEN_BUILTIN_C_FUNCTION, PARSER_TOKEN_VALUE_INT, PARSER_TOKEN_VALUE_FLOAT, diff --git a/src/runner/runner.c b/src/runner/runner.c index 24e8e3b..faeb956 100644 --- a/src/runner/runner.c +++ b/src/runner/runner.c @@ -231,6 +231,13 @@ AstTree *runAstTreeBuiltin(AstTree *tree, AstTreeScope *scope, AstTree *variable = arguments[0]; return copyAstTree(variable->type); } + case AST_TREE_TOKEN_BUILTIN_SIZE_OF: { + AstTree *type = arguments[0]; + AstTreeRawValue *value = a404m_malloc(getSizeOfType(&AST_TREE_U64_TYPE)); + *(u64 *)value = getSizeOfType(type); + return newAstTree(AST_TREE_TOKEN_RAW_VALUE, value, &AST_TREE_U64_TYPE, NULL, + NULL); + } case AST_TREE_TOKEN_BUILTIN_NEG: { AstTree *left = arguments[0]; AstTreeRawValue *ret = a404m_malloc(getSizeOfType(left->type)); @@ -922,7 +929,7 @@ AstTree *runAstTreeBuiltin(AstTree *tree, AstTreeScope *scope, return ret; } case AST_TREE_TOKEN_BUILTIN_PUTC: { - putchar(*(u8*)arguments[0]->metadata); + putchar(*(u8 *)arguments[0]->metadata); return copyAstTree(&AST_TREE_VOID_VALUE); } case AST_TREE_TOKEN_BUILTIN_IMPORT: @@ -1250,6 +1257,7 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet, case AST_TREE_TOKEN_TYPE_ARRAY: case AST_TREE_TOKEN_BUILTIN_CAST: case AST_TREE_TOKEN_BUILTIN_TYPE_OF: + case AST_TREE_TOKEN_BUILTIN_SIZE_OF: case AST_TREE_TOKEN_BUILTIN_IMPORT: case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC: case AST_TREE_TOKEN_BUILTIN_HEAP_ALLOC: @@ -1266,6 +1274,8 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet, case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL: case AST_TREE_TOKEN_BUILTIN_PUTC: + case AST_TREE_TOKEN_BUILTIN_C_LIBRARY: + case AST_TREE_TOKEN_BUILTIN_C_FUNCTION: return copyAstTree(expr); case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME: { AstTreeBool *metadata = a404m_malloc(sizeof(*metadata)); @@ -1615,6 +1625,7 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet, } case AST_TREE_TOKEN_NONE: } + printLog("%s", AST_TREE_TOKEN_STRINGS[expr->token]); UNREACHABLE; } @@ -1666,12 +1677,16 @@ AstTree *toRawValue(AstTree *value) { switch (value->token) { case AST_TREE_TOKEN_TYPE_F16: *(f16 *)rawValue = *(f128 *)value->metadata; + break; case AST_TREE_TOKEN_TYPE_F32: *(f32 *)rawValue = *(f128 *)value->metadata; + break; case AST_TREE_TOKEN_TYPE_F64: *(f64 *)rawValue = *(f128 *)value->metadata; + break; case AST_TREE_TOKEN_TYPE_F128: *(f128 *)rawValue = *(f128 *)value->metadata; + break; default: UNREACHABLE; } |