diff options
author | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2025-03-25 04:46:20 +0330 |
---|---|---|
committer | A404M <ahmadmahmoudiprogrammer@gmail.com> | 2025-03-25 04:46:20 +0330 |
commit | 3bd7d3498f12cfb8dbdf5fff7c0bc981bf8085e2 (patch) | |
tree | 0888de25c1e553896d817ca8d2c2405306b9d0ca | |
parent | 0d2065dfb49ed41110155ab1c29879c09c9d3dc7 (diff) |
add pointer type
-rw-r--r-- | code/main.felan | 12 | ||||
-rw-r--r-- | src/compiler/ast-tree.c | 114 | ||||
-rw-r--r-- | src/compiler/ast-tree.h | 9 | ||||
-rw-r--r-- | src/compiler/lexer.c | 14 | ||||
-rw-r--r-- | src/compiler/lexer.h | 2 | ||||
-rw-r--r-- | src/compiler/parser.c | 28 | ||||
-rw-r--r-- | src/compiler/parser.h | 4 | ||||
-rw-r--r-- | src/runner/runner.c | 2 |
8 files changed, 143 insertions, 42 deletions
diff --git a/code/main.felan b/code/main.felan index e2eaaa3..a45778c 100644 --- a/code/main.felan +++ b/code/main.felan @@ -1,15 +1,7 @@ main :: () -> void { + b :*u64 = null; a := f(b = 4,2); - if a == 0 - print_u64 10; - else if a == 1 - print_u64 11; - else if a == 2 - print_u64 12; - else if a == 3 - print_u64 13; - else - print_u64 14; + print_u64 a; }; f :: (a:u64,b:u64)->u64{ diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index c3854b9..1bfda8c 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -129,11 +129,12 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_TYPE_F64", "AST_TREE_TOKEN_TYPE_F128", "AST_TREE_TOKEN_TYPE_BOOL", + "AST_TREE_TOKEN_VALUE_VOID", "AST_TREE_TOKEN_FUNCTION_CALL", "AST_TREE_TOKEN_VARIABLE", "AST_TREE_TOKEN_VARIABLE_DEFINE", - "AST_TREE_TOKEN_VALUE_VOID", + "AST_TREE_TOKEN_VALUE_NULL", "AST_TREE_TOKEN_VALUE_INT", "AST_TREE_TOKEN_VALUE_FLOAT", "AST_TREE_TOKEN_VALUE_BOOL", @@ -152,6 +153,7 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_OPERATOR_SMALLER", "AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL", "AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL", + "AST_TREE_TOKEN_OPERATOR_POINTER", "AST_TREE_TOKEN_SCOPE", @@ -216,8 +218,10 @@ void astTreePrint(const AstTree *tree, int indent) { case AST_TREE_TOKEN_TYPE_F128: case AST_TREE_TOKEN_TYPE_BOOL: case AST_TREE_TOKEN_VALUE_VOID: + case AST_TREE_TOKEN_VALUE_NULL: case AST_TREE_TOKEN_VARIABLE_DEFINE: goto RETURN_SUCCESS; + case AST_TREE_TOKEN_OPERATOR_POINTER: case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: case AST_TREE_TOKEN_KEYWORD_PRINT_U64: @@ -447,6 +451,7 @@ void astTreeDestroy(AstTree tree) { case AST_TREE_TOKEN_TYPE_F64: case AST_TREE_TOKEN_TYPE_F128: case AST_TREE_TOKEN_TYPE_BOOL: + case AST_TREE_TOKEN_VALUE_NULL: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_BOOL: @@ -457,6 +462,7 @@ void astTreeDestroy(AstTree tree) { free(metadata); return; } + case AST_TREE_TOKEN_OPERATOR_POINTER: case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: case AST_TREE_TOKEN_KEYWORD_PRINT_U64: @@ -614,6 +620,7 @@ AstTree *copyAstTree(AstTree *tree) { case AST_TREE_TOKEN_TYPE_F32: case AST_TREE_TOKEN_TYPE_F64: case AST_TREE_TOKEN_TYPE_F128: + case AST_TREE_TOKEN_VALUE_NULL: case AST_TREE_TOKEN_VALUE_VOID: return tree; case AST_TREE_TOKEN_VALUE_INT: @@ -689,6 +696,7 @@ AstTree *copyAstTree(AstTree *tree) { return newAstTree(tree->token, new_metadata, copyAstTree(tree->type), tree->str_begin, tree->str_end); } + case AST_TREE_TOKEN_OPERATOR_POINTER: case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: case AST_TREE_TOKEN_KEYWORD_PRINT_U64: @@ -836,6 +844,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) { } switch (node_metadata->value->token) { + case PARSER_TOKEN_KEYWORD_NULL: case PARSER_TOKEN_VALUE_BOOL: case PARSER_TOKEN_VALUE_INT: case PARSER_TOKEN_VALUE_FLOAT: @@ -881,6 +890,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) { case PARSER_TOKEN_TYPE_F64: case PARSER_TOKEN_TYPE_F128: case PARSER_TOKEN_TYPE_BOOL: + case PARSER_TOKEN_OPERATOR_POINTER: goto AFTER_SWITCH; case PARSER_TOKEN_ROOT: case PARSER_TOKEN_KEYWORD_PRINT_U64: @@ -1056,6 +1066,8 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper) { AST_TREE_TOKEN_VALUE_BOOL, (void *)(AstTreeBool)(ParserNodeBoolMetadata)parserNode->metadata, &AST_TREE_BOOL_TYPE, parserNode->str_begin, parserNode->str_end); + case PARSER_TOKEN_KEYWORD_NULL: + return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_VALUE_NULL); case PARSER_TOKEN_KEYWORD_PRINT_U64: return astTreeParsePrintU64(parserNode, helper); case PARSER_TOKEN_KEYWORD_RETURN: @@ -1117,6 +1129,9 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper) { case PARSER_TOKEN_OPERATOR_MINUS: return astTreeParseUnaryOperator(parserNode, helper, AST_TREE_TOKEN_OPERATOR_MINUS); + case PARSER_TOKEN_OPERATOR_POINTER: + return astTreeParseUnaryOperator(parserNode, helper, + AST_TREE_TOKEN_OPERATOR_POINTER); case PARSER_TOKEN_VARIABLE: return astTreeParseVariable(parserNode, helper); case PARSER_TOKEN_KEYWORD_IF: @@ -1271,6 +1286,8 @@ AstTree *astTreeParseFunction(ParserNode *parserNode, AstTreeHelper *p_helper) { case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL: case PARSER_TOKEN_FUNCTION_DEFINITION: case PARSER_TOKEN_FUNCTION_CALL: + case PARSER_TOKEN_KEYWORD_NULL: + case PARSER_TOKEN_OPERATOR_POINTER: printError(node->str_begin, node->str_end, "Unexpected %s", PARSER_TOKEN_STRINGS[node->token]); goto RETURN_ERROR; @@ -1349,8 +1366,7 @@ AstTree *astTreeParseTypeFunction(ParserNode *parserNode, } if (!typeIsEqual(argument->type, &AST_TREE_TYPE_TYPE)) { - printError(argument->str_begin, argument->str_end, - "Not yet supported"); + printError(argument->str_begin, argument->str_end, "Not yet supported"); return NULL; } } @@ -1446,6 +1462,11 @@ AstTree *astTreeParseFloat(ParserNode *parserNode) { parserNode->str_begin, parserNode->str_end); } +AstTree *astTreeParseKeyword(ParserNode *parserNode, AstTreeToken token) { + return newAstTree(token, NULL, NULL, parserNode->str_begin, + parserNode->str_end); +} + AstTree *astTreeParsePrintU64(ParserNode *parserNode, AstTreeHelper *helper) { ParserNodeSingleChildMetadata *node_metadata = parserNode->metadata; @@ -1788,6 +1809,8 @@ AstTree *astTreeParseCurlyBracket(ParserNode *parserNode, case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL: case PARSER_TOKEN_FUNCTION_DEFINITION: case PARSER_TOKEN_FUNCTION_CALL: + case PARSER_TOKEN_KEYWORD_NULL: + case PARSER_TOKEN_OPERATOR_POINTER: printError(node->str_begin, node->str_end, "Unexpected %s", PARSER_TOKEN_STRINGS[node->token]); goto RETURN_ERROR; @@ -1883,6 +1906,7 @@ AstTreeFunction *getFunction(AstTree *value) { case AST_TREE_TOKEN_VALUE_BOOL: case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_OPERATOR_ASSIGN: + case AST_TREE_TOKEN_OPERATOR_POINTER: case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: case AST_TREE_TOKEN_OPERATOR_SUM: @@ -1899,6 +1923,7 @@ AstTreeFunction *getFunction(AstTree *value) { case AST_TREE_TOKEN_SCOPE: case AST_TREE_TOKEN_KEYWORD_WHILE: case AST_TREE_TOKEN_VALUE_FLOAT: + case AST_TREE_TOKEN_VALUE_NULL: return NULL; case AST_TREE_TOKEN_NONE: } @@ -1923,6 +1948,7 @@ bool isConst(AstTree *tree, AstTreeHelper *helper) { case AST_TREE_TOKEN_TYPE_F64: case AST_TREE_TOKEN_TYPE_F128: case AST_TREE_TOKEN_TYPE_BOOL: + case AST_TREE_TOKEN_VALUE_NULL: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_FLOAT: @@ -1971,6 +1997,10 @@ bool isConst(AstTree *tree, AstTreeHelper *helper) { AstTreeVariable *metadata = tree->metadata; return metadata->isConst; } + case AST_TREE_TOKEN_OPERATOR_POINTER: { + AstTreeSingleChild *metadata = tree->metadata; + return isConst(metadata, helper); + } case AST_TREE_TOKEN_NONE: } UNREACHABLE; @@ -1994,6 +2024,7 @@ AstTree *makeTypeOf(AstTree *value) { case AST_TREE_TOKEN_TYPE_F64: case AST_TREE_TOKEN_TYPE_F128: case AST_TREE_TOKEN_TYPE_BOOL: + case AST_TREE_TOKEN_OPERATOR_POINTER: return &AST_TREE_TYPE_TYPE; case AST_TREE_TOKEN_FUNCTION_CALL: { AstTreeFunctionCall *metadata = value->metadata; @@ -2071,6 +2102,7 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) { case AST_TREE_TOKEN_KEYWORD_IF: case AST_TREE_TOKEN_KEYWORD_WHILE: case AST_TREE_TOKEN_KEYWORD_COMPTIME: + case AST_TREE_TOKEN_VALUE_NULL: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_FLOAT: @@ -2108,6 +2140,14 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) { case AST_TREE_TOKEN_TYPE_F64: case AST_TREE_TOKEN_TYPE_F128: return type1->token == type0->token; + case AST_TREE_TOKEN_OPERATOR_POINTER: { + if (type1->token != AST_TREE_TOKEN_OPERATOR_POINTER) { + return false; + } + AstTreeSingleChild *type0_metadata = type0->metadata; + AstTreeSingleChild *type1_metadata = type1->metadata; + return typeIsEqual(type0_metadata, type1_metadata); + } case AST_TREE_TOKEN_TYPE_FUNCTION: if (type1->token != AST_TREE_TOKEN_TYPE_FUNCTION) { return false; @@ -2115,10 +2155,8 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) { AstTreeTypeFunction *type0_metadata = type0->metadata; AstTreeTypeFunction *type1_metadata = type1->metadata; if (!typeIsEqual(type0_metadata->returnType->type, - type1_metadata->returnType->type)) { - return false; - } - if (type0_metadata->arguments_size != type1_metadata->arguments_size) { + type1_metadata->returnType->type) || + type0_metadata->arguments_size != type1_metadata->arguments_size) { return false; } for (size_t i = 0; i < type0_metadata->arguments_size; ++i) { @@ -2163,6 +2201,7 @@ AstTree *getValue(AstTree *tree, AstTreeSetTypesHelper helper) { case AST_TREE_TOKEN_TYPE_F64: case AST_TREE_TOKEN_TYPE_F128: case AST_TREE_TOKEN_TYPE_BOOL: + case AST_TREE_TOKEN_VALUE_NULL: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_FLOAT: @@ -2183,6 +2222,7 @@ AstTree *getValue(AstTree *tree, AstTreeSetTypesHelper helper) { case AST_TREE_TOKEN_OPERATOR_SMALLER: case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: + case AST_TREE_TOKEN_OPERATOR_POINTER: case AST_TREE_TOKEN_KEYWORD_IF: case AST_TREE_TOKEN_KEYWORD_WHILE: case AST_TREE_TOKEN_KEYWORD_COMPTIME: @@ -2237,11 +2277,13 @@ bool isCircularDependenciesBack(AstTreeHelper *helper, case AST_TREE_TOKEN_TYPE_F64: case AST_TREE_TOKEN_TYPE_F128: case AST_TREE_TOKEN_TYPE_BOOL: + case AST_TREE_TOKEN_VALUE_NULL: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_FLOAT: case AST_TREE_TOKEN_VALUE_BOOL: return false; + case AST_TREE_TOKEN_OPERATOR_POINTER: case AST_TREE_TOKEN_KEYWORD_COMPTIME: case AST_TREE_TOKEN_OPERATOR_PLUS: case AST_TREE_TOKEN_OPERATOR_MINUS: { @@ -2403,6 +2445,8 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, return setTypesValueInt(tree, helper); case AST_TREE_TOKEN_VALUE_FLOAT: return setTypesValueFloat(tree, helper); + case AST_TREE_TOKEN_VALUE_NULL: + return setTypesValueNull(tree, helper); case AST_TREE_TOKEN_FUNCTION: return setTypesFunction(tree, helper); case AST_TREE_TOKEN_KEYWORD_PRINT_U64: @@ -2433,6 +2477,8 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: return setTypesOperatorInfixWithRet(tree, &AST_TREE_BOOL_TYPE, helper); + case AST_TREE_TOKEN_OPERATOR_POINTER: + return setTypesOperatorIndirection(tree, helper); case AST_TREE_TOKEN_VARIABLE_DEFINE: return setTypesVariableDefine(tree, helper); case AST_TREE_TOKEN_KEYWORD_IF: @@ -2446,15 +2492,17 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, case AST_TREE_TOKEN_NONE: break; } + printError(tree->str_begin, tree->str_end, "Unknown token %d", tree->token); UNREACHABLE; } bool setTypesValueInt(AstTree *tree, AstTreeSetTypesHelper helper) { - if (helper.lookingType == NULL || typeIsEqual(helper.lookingType,&AST_TREE_I64_TYPE)) { + if (helper.lookingType == NULL || + typeIsEqual(helper.lookingType, &AST_TREE_I64_TYPE)) { tree->type = &AST_TREE_I64_TYPE; - } else if (typeIsEqual(helper.lookingType,&AST_TREE_U64_TYPE)) { + } else if (typeIsEqual(helper.lookingType, &AST_TREE_U64_TYPE)) { tree->type = &AST_TREE_U64_TYPE; - } else if (typeIsEqual(helper.lookingType,&AST_TREE_I32_TYPE)) { + } else if (typeIsEqual(helper.lookingType, &AST_TREE_I32_TYPE)) { AstTreeInt value = (AstTreeInt)tree->metadata; i32 newValue = value; tree->metadata = (void *)(u64)newValue; @@ -2462,7 +2510,7 @@ bool setTypesValueInt(AstTree *tree, AstTreeSetTypesHelper helper) { printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); } tree->type = &AST_TREE_I32_TYPE; - } else if (typeIsEqual(helper.lookingType,&AST_TREE_U32_TYPE)) { + } else if (typeIsEqual(helper.lookingType, &AST_TREE_U32_TYPE)) { AstTreeInt value = (AstTreeInt)tree->metadata; u32 newValue = value; tree->metadata = (void *)(u64)newValue; @@ -2470,7 +2518,7 @@ bool setTypesValueInt(AstTree *tree, AstTreeSetTypesHelper helper) { printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); } tree->type = &AST_TREE_U32_TYPE; - } else if (typeIsEqual(helper.lookingType,&AST_TREE_I16_TYPE)) { + } else if (typeIsEqual(helper.lookingType, &AST_TREE_I16_TYPE)) { AstTreeInt value = (AstTreeInt)tree->metadata; i16 newValue = value; tree->metadata = (void *)(u64)newValue; @@ -2478,7 +2526,7 @@ bool setTypesValueInt(AstTree *tree, AstTreeSetTypesHelper helper) { printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); } tree->type = &AST_TREE_I16_TYPE; - } else if (typeIsEqual(helper.lookingType,&AST_TREE_U16_TYPE)) { + } else if (typeIsEqual(helper.lookingType, &AST_TREE_U16_TYPE)) { AstTreeInt value = (AstTreeInt)tree->metadata; u16 newValue = value; tree->metadata = (void *)(u64)newValue; @@ -2486,7 +2534,7 @@ bool setTypesValueInt(AstTree *tree, AstTreeSetTypesHelper helper) { printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); } tree->type = &AST_TREE_U16_TYPE; - } else if (typeIsEqual(helper.lookingType,&AST_TREE_I8_TYPE)) { + } else if (typeIsEqual(helper.lookingType, &AST_TREE_I8_TYPE)) { AstTreeInt value = (AstTreeInt)tree->metadata; i8 newValue = value; tree->metadata = (void *)(u64)newValue; @@ -2494,7 +2542,7 @@ bool setTypesValueInt(AstTree *tree, AstTreeSetTypesHelper helper) { printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); } tree->type = &AST_TREE_I8_TYPE; - } else if (typeIsEqual(helper.lookingType,&AST_TREE_U8_TYPE)) { + } else if (typeIsEqual(helper.lookingType, &AST_TREE_U8_TYPE)) { AstTreeInt value = (AstTreeInt)tree->metadata; u8 newValue = value; tree->metadata = (void *)(u64)newValue; @@ -2502,7 +2550,7 @@ bool setTypesValueInt(AstTree *tree, AstTreeSetTypesHelper helper) { printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); } tree->type = &AST_TREE_U8_TYPE; - } else if (typeIsEqual(helper.lookingType,&AST_TREE_F16_TYPE)) { + } else if (typeIsEqual(helper.lookingType, &AST_TREE_F16_TYPE)) { tree->token = AST_TREE_TOKEN_VALUE_FLOAT; AstTreeInt value = (AstTreeInt)tree->metadata; f16 newValue = value; @@ -2512,7 +2560,7 @@ bool setTypesValueInt(AstTree *tree, AstTreeSetTypesHelper helper) { printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); } tree->type = &AST_TREE_F16_TYPE; - } else if (typeIsEqual(helper.lookingType,&AST_TREE_F32_TYPE)) { + } else if (typeIsEqual(helper.lookingType, &AST_TREE_F32_TYPE)) { tree->token = AST_TREE_TOKEN_VALUE_FLOAT; AstTreeInt value = (AstTreeInt)tree->metadata; f32 newValue = value; @@ -2522,7 +2570,7 @@ bool setTypesValueInt(AstTree *tree, AstTreeSetTypesHelper helper) { printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); } tree->type = &AST_TREE_F32_TYPE; - } else if (typeIsEqual(helper.lookingType,&AST_TREE_F64_TYPE)) { + } else if (typeIsEqual(helper.lookingType, &AST_TREE_F64_TYPE)) { tree->token = AST_TREE_TOKEN_VALUE_FLOAT; AstTreeInt value = (AstTreeInt)tree->metadata; f64 newValue = value; @@ -2532,7 +2580,7 @@ bool setTypesValueInt(AstTree *tree, AstTreeSetTypesHelper helper) { printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); } tree->type = &AST_TREE_F64_TYPE; - } else if (typeIsEqual(helper.lookingType,&AST_TREE_F128_TYPE)) { + } else if (typeIsEqual(helper.lookingType, &AST_TREE_F128_TYPE)) { tree->token = AST_TREE_TOKEN_VALUE_FLOAT; AstTreeInt value = (AstTreeInt)tree->metadata; f128 newValue = value; @@ -2549,7 +2597,7 @@ bool setTypesValueInt(AstTree *tree, AstTreeSetTypesHelper helper) { } bool setTypesValueFloat(AstTree *tree, AstTreeSetTypesHelper helper) { - if (typeIsEqual(helper.lookingType,&AST_TREE_F16_TYPE)) { + if (typeIsEqual(helper.lookingType, &AST_TREE_F16_TYPE)) { tree->token = AST_TREE_TOKEN_VALUE_FLOAT; AstTreeFloat value = *(AstTreeFloat *)tree->metadata; f16 newValue = value; @@ -2558,7 +2606,7 @@ bool setTypesValueFloat(AstTree *tree, AstTreeSetTypesHelper helper) { printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); } tree->type = &AST_TREE_F16_TYPE; - } else if (typeIsEqual(helper.lookingType,&AST_TREE_F32_TYPE)) { + } else if (typeIsEqual(helper.lookingType, &AST_TREE_F32_TYPE)) { tree->token = AST_TREE_TOKEN_VALUE_FLOAT; AstTreeFloat value = *(AstTreeFloat *)tree->metadata; f32 newValue = value; @@ -2567,7 +2615,7 @@ bool setTypesValueFloat(AstTree *tree, AstTreeSetTypesHelper helper) { printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); } tree->type = &AST_TREE_F32_TYPE; - } else if (typeIsEqual(helper.lookingType,&AST_TREE_F64_TYPE) || + } else if (typeIsEqual(helper.lookingType, &AST_TREE_F64_TYPE) || helper.lookingType == NULL) { tree->token = AST_TREE_TOKEN_VALUE_FLOAT; AstTreeFloat value = *(AstTreeFloat *)tree->metadata; @@ -2577,7 +2625,7 @@ bool setTypesValueFloat(AstTree *tree, AstTreeSetTypesHelper helper) { printWarning(tree->str_begin, tree->str_end, "Value is overflowing"); } tree->type = &AST_TREE_F64_TYPE; - } else if (typeIsEqual(helper.lookingType,&AST_TREE_F128_TYPE)) { + } else if (typeIsEqual(helper.lookingType, &AST_TREE_F128_TYPE)) { tree->token = AST_TREE_TOKEN_VALUE_FLOAT; AstTreeFloat value = *(AstTreeFloat *)tree->metadata; f128 newValue = value; @@ -2593,6 +2641,14 @@ bool setTypesValueFloat(AstTree *tree, AstTreeSetTypesHelper helper) { return true; } +bool setTypesValueNull(AstTree *tree, AstTreeSetTypesHelper helper) { + if (helper.lookingType == NULL) { + return false; + } + tree->type = getValue(helper.lookingType, helper); + return tree->type != NULL; +} + bool setTypesFunction(AstTree *tree, AstTreeSetTypesHelper helper) { AstTreeFunction *metadata = tree->metadata; @@ -2842,6 +2898,18 @@ bool setTypesOperatorUnary(AstTree *tree, AstTreeSetTypesHelper helper) { } } +bool setTypesOperatorIndirection(AstTree *tree, AstTreeSetTypesHelper helper) { + AstTreeSingleChild *metadata = tree->metadata; + if (!setAllTypes(metadata, helper, NULL)) { + return false; + } else if (!typeIsEqual(metadata->type, &AST_TREE_TYPE_TYPE)) { + UNREACHABLE; + } + + tree->type = &AST_TREE_TYPE_TYPE; + return true; +} + bool setTypesVariableDefine(AstTree *tree, AstTreeSetTypesHelper helper) { AstTreeVariable *metadata = tree->metadata; tree->type = &AST_TREE_VOID_TYPE; diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h index 8fdeb53..dd845a2 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -30,12 +30,13 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_TYPE_F64, AST_TREE_TOKEN_TYPE_F128, AST_TREE_TOKEN_TYPE_BOOL, - AST_TREE_TOKEN_STATIC_VARS_END = AST_TREE_TOKEN_TYPE_BOOL, + AST_TREE_TOKEN_VALUE_VOID, + AST_TREE_TOKEN_STATIC_VARS_END = AST_TREE_TOKEN_VALUE_VOID, AST_TREE_TOKEN_FUNCTION_CALL, AST_TREE_TOKEN_VARIABLE, AST_TREE_TOKEN_VARIABLE_DEFINE, - AST_TREE_TOKEN_VALUE_VOID, + AST_TREE_TOKEN_VALUE_NULL, AST_TREE_TOKEN_VALUE_INT, AST_TREE_TOKEN_VALUE_FLOAT, AST_TREE_TOKEN_VALUE_BOOL, @@ -54,6 +55,7 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_OPERATOR_SMALLER, AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL, AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL, + AST_TREE_TOKEN_OPERATOR_POINTER, AST_TREE_TOKEN_SCOPE, @@ -207,6 +209,7 @@ AstTree *astTreeParseFunctionCall(ParserNode *parserNode, AstTreeHelper *helper); AstTree *astTreeParseIdentifier(ParserNode *parserNode, AstTreeHelper *helper); AstTree *astTreeParseFloat(ParserNode *parserNode); +AstTree *astTreeParseKeyword(ParserNode *parserNode,AstTreeToken token); AstTree *astTreeParsePrintU64(ParserNode *parserNode, AstTreeHelper *helper); AstTree *astTreeParseReturn(ParserNode *parserNode, AstTreeHelper *helper); AstTree *astTreeParseBinaryOperator(ParserNode *parserNode, @@ -241,6 +244,7 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunction *function); bool setTypesValueInt(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesValueFloat(AstTree *tree, AstTreeSetTypesHelper helper); +bool setTypesValueNull(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesFunction(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesPrintU64(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesReturn(AstTree *tree, AstTreeSetTypesHelper helper, @@ -253,6 +257,7 @@ bool setTypesOperatorInfix(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesOperatorInfixWithRet(AstTree *tree, AstTree *retType, AstTreeSetTypesHelper helper); bool setTypesOperatorUnary(AstTree *tree, AstTreeSetTypesHelper helper); +bool setTypesOperatorIndirection(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesVariableDefine(AstTree *tree, AstTreeSetTypesHelper helper); bool setTypesIf(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunction *function); diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index d702525..08eef75 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -35,6 +35,7 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_KEYWORD_ELSE", "LEXER_TOKEN_KEYWORD_WHILE", "LEXER_TOKEN_KEYWORD_COMPTIME", + "LEXER_TOKEN_KEYWORD_NULL", "LEXER_TOKEN_NUMBER", @@ -66,6 +67,7 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_SYMBOL_SMALLER", "LEXER_TOKEN_SYMBOL_GREATER_OR_EQUAL", "LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL", + "LEXER_TOKEN_SYMBOL_POINTER", "LEXER_TOKEN_NONE", }; @@ -91,7 +93,7 @@ const LexerToken LEXER_SYMBOL_TOKENS[] = { LEXER_TOKEN_SYMBOL_COMMA, LEXER_TOKEN_SYMBOL_PLUS, LEXER_TOKEN_SYMBOL_MINUS, - LEXER_TOKEN_SYMBOL_MULTIPLY, + LEXER_TOKEN_SYMBOL_POINTER, LEXER_TOKEN_SYMBOL_DIVIDE, LEXER_TOKEN_SYMBOL_MODULO, LEXER_TOKEN_SYMBOL_EQUAL, @@ -107,7 +109,7 @@ const size_t LEXER_SYMBOL_SIZE = const char *LEXER_KEYWORD_STRINGS[] = { "type", "void", "i8", "u8", "i16", "u16", "i32", "u32", "i64", "u64", "f16", "f32", "f64", "f128", "bool", "print_u64", - "return", "true", "false", "if", "else", "while", "comptime", + "return", "true", "false", "if", "else", "while", "comptime", "null", }; const LexerToken LEXER_KEYWORD_TOKENS[] = { LEXER_TOKEN_KEYWORD_TYPE, LEXER_TOKEN_KEYWORD_VOID, @@ -121,7 +123,7 @@ const LexerToken LEXER_KEYWORD_TOKENS[] = { LEXER_TOKEN_KEYWORD_RETURN, LEXER_TOKEN_KEYWORD_TRUE, LEXER_TOKEN_KEYWORD_FALSE, LEXER_TOKEN_KEYWORD_IF, LEXER_TOKEN_KEYWORD_ELSE, LEXER_TOKEN_KEYWORD_WHILE, - LEXER_TOKEN_KEYWORD_COMPTIME, + LEXER_TOKEN_KEYWORD_COMPTIME, LEXER_TOKEN_KEYWORD_NULL, }; const size_t LEXER_KEYWORD_SIZE = sizeof(LEXER_KEYWORD_TOKENS) / sizeof(*LEXER_KEYWORD_TOKENS); @@ -211,7 +213,9 @@ LexerNodeArray lexer(char *str) { } else { RETURN_ERROR: free(result.data); - printError(iter, iter + 1, "Unexpected character '%c' with code = %d at index %ld", c, c,iter-str); + printError(iter, iter + 1, + "Unexpected character '%c' with code = %d at index %ld", c, c, + iter - str); return LEXER_NODE_ARRAY_ERROR; } } @@ -271,6 +275,7 @@ void lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter, case LEXER_TOKEN_KEYWORD_ELSE: case LEXER_TOKEN_KEYWORD_WHILE: case LEXER_TOKEN_KEYWORD_COMPTIME: + case LEXER_TOKEN_KEYWORD_NULL: case LEXER_TOKEN_NUMBER: case LEXER_TOKEN_SYMBOL_EOL: case LEXER_TOKEN_SYMBOL_OPEN_PARENTHESIS: @@ -299,6 +304,7 @@ void lexerPushClear(LexerNodeArray *array, size_t *array_size, char *iter, case LEXER_TOKEN_SYMBOL_SMALLER: case LEXER_TOKEN_SYMBOL_GREATER_OR_EQUAL: case LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL: + case LEXER_TOKEN_SYMBOL_POINTER: if (*array_size == array->size) { *array_size += 1 + *array_size / 2; array->data = diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h index 7a6aa74..4789297 100644 --- a/src/compiler/lexer.h +++ b/src/compiler/lexer.h @@ -28,6 +28,7 @@ typedef enum LexerToken { LEXER_TOKEN_KEYWORD_ELSE, LEXER_TOKEN_KEYWORD_WHILE, LEXER_TOKEN_KEYWORD_COMPTIME, + LEXER_TOKEN_KEYWORD_NULL, LEXER_TOKEN_NUMBER, @@ -59,6 +60,7 @@ typedef enum LexerToken { LEXER_TOKEN_SYMBOL_SMALLER, LEXER_TOKEN_SYMBOL_GREATER_OR_EQUAL, LEXER_TOKEN_SYMBOL_SMALLER_OR_EQUAL, + LEXER_TOKEN_SYMBOL_POINTER, LEXER_TOKEN_NONE, } LexerToken; diff --git a/src/compiler/parser.c b/src/compiler/parser.c index 9d77462..327fab2 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -40,6 +40,7 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_KEYWORD_IF", "PARSER_TOKEN_KEYWORD_WHILE", "PARSER_TOKEN_KEYWORD_COMPTIME", + "PARSER_TOKEN_KEYWORD_NULL", "PARSER_TOKEN_CONSTANT", "PARSER_TOKEN_VARIABLE", @@ -68,6 +69,7 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_OPERATOR_SMALLER", "PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL", "PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL", + "PARSER_TOKEN_OPERATOR_POINTER", "PARSER_TOKEN_FUNCTION_DEFINITION", @@ -97,7 +99,7 @@ static constexpr ParserOrder PARSER_ORDER[] = { LEXER_TOKEN_KEYWORD_F64, LEXER_TOKEN_KEYWORD_F128, LEXER_TOKEN_KEYWORD_U64, LEXER_TOKEN_KEYWORD_BOOL, LEXER_TOKEN_KEYWORD_TRUE, LEXER_TOKEN_KEYWORD_FALSE, - LEXER_TOKEN_NUMBER, ), + LEXER_TOKEN_KEYWORD_NULL, LEXER_TOKEN_NUMBER, ), }, { .ltr = false, @@ -105,7 +107,8 @@ static constexpr ParserOrder PARSER_ORDER[] = { }, { .ltr = true, - ORDER_ARRAY(LEXER_TOKEN_SYMBOL_PLUS, LEXER_TOKEN_SYMBOL_MINUS, ), + ORDER_ARRAY(LEXER_TOKEN_SYMBOL_PLUS, LEXER_TOKEN_SYMBOL_MINUS, + LEXER_TOKEN_SYMBOL_POINTER, ), }, { .ltr = true, @@ -195,6 +198,7 @@ void parserNodePrint(const ParserNode *node, int indent) { case PARSER_TOKEN_TYPE_F32: case PARSER_TOKEN_TYPE_F64: case PARSER_TOKEN_TYPE_F128: + case PARSER_TOKEN_KEYWORD_NULL: goto RETURN_SUCCESS; case PARSER_TOKEN_VALUE_INT: { ParserNodeIntMetadata metadata = (ParserNodeIntMetadata)node->metadata; @@ -234,6 +238,7 @@ void parserNodePrint(const ParserNode *node, int indent) { printf(" "); } goto RETURN_SUCCESS; + case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_OPERATOR_PLUS: case PARSER_TOKEN_OPERATOR_MINUS: case PARSER_TOKEN_KEYWORD_PRINT_U64: @@ -443,6 +448,7 @@ void parserNodeDelete(ParserNode *node) { case PARSER_TOKEN_TYPE_F128: case PARSER_TOKEN_VALUE_INT: case PARSER_TOKEN_VALUE_BOOL: + case PARSER_TOKEN_KEYWORD_NULL: goto RETURN_SUCCESS; case PARSER_TOKEN_VALUE_FLOAT: { ParserNodeFloatMetadata *metadata = node->metadata; @@ -458,6 +464,7 @@ void parserNodeDelete(ParserNode *node) { free(metadata); } goto RETURN_SUCCESS; + case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_OPERATOR_PLUS: case PARSER_TOKEN_OPERATOR_MINUS: case PARSER_TOKEN_KEYWORD_PRINT_U64: @@ -676,6 +683,8 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_F64); case LEXER_TOKEN_KEYWORD_F128: return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_F128); + case LEXER_TOKEN_KEYWORD_NULL: + return parserNoMetadata(node, parent, PARSER_TOKEN_KEYWORD_NULL); case LEXER_TOKEN_KEYWORD_PRINT_U64: return parserPrintU64(node, end, parent); case LEXER_TOKEN_KEYWORD_RETURN: @@ -762,6 +771,13 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, *conti = result == NULL; return result; } + case LEXER_TOKEN_SYMBOL_POINTER: { + ParserNode *result = parserBinaryOrLeftOperator( + node, begin, end, parent, PARSER_TOKEN_OPERATOR_POINTER, + LEXER_TOKEN_SYMBOL_MULTIPLY); + *conti = result == NULL; + return result; + } case LEXER_TOKEN_KEYWORD_IF: return parserIf(node, end, parent); case LEXER_TOKEN_KEYWORD_WHILE: @@ -1157,6 +1173,7 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, case PARSER_TOKEN_TYPE_F32: case PARSER_TOKEN_TYPE_F64: case PARSER_TOKEN_TYPE_F128: + case PARSER_TOKEN_KEYWORD_NULL: case PARSER_TOKEN_KEYWORD_PRINT_U64: case PARSER_TOKEN_KEYWORD_RETURN: case PARSER_TOKEN_CONSTANT: @@ -1170,6 +1187,7 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, case PARSER_TOKEN_OPERATOR_MULTIPLY_ASSIGN: case PARSER_TOKEN_OPERATOR_DIVIDE_ASSIGN: case PARSER_TOKEN_OPERATOR_MODULO_ASSIGN: + case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_OPERATOR_PLUS: case PARSER_TOKEN_OPERATOR_MINUS: case PARSER_TOKEN_OPERATOR_SUM: @@ -1527,6 +1545,7 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_OPERATOR_MULTIPLY_ASSIGN: case PARSER_TOKEN_OPERATOR_DIVIDE_ASSIGN: case PARSER_TOKEN_OPERATOR_MODULO_ASSIGN: + case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_OPERATOR_PLUS: case PARSER_TOKEN_OPERATOR_MINUS: case PARSER_TOKEN_OPERATOR_SUM: @@ -1562,6 +1581,7 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_TYPE_F32: case PARSER_TOKEN_TYPE_F64: case PARSER_TOKEN_TYPE_F128: + case PARSER_TOKEN_KEYWORD_NULL: return true; case PARSER_TOKEN_ROOT: case PARSER_TOKEN_SYMBOL_EOL: @@ -1596,7 +1616,9 @@ bool isType(ParserNode *node) { case PARSER_TOKEN_FUNCTION_CALL: case PARSER_TOKEN_KEYWORD_IF: case PARSER_TOKEN_KEYWORD_COMPTIME: + case PARSER_TOKEN_OPERATOR_POINTER: return true; + case PARSER_TOKEN_KEYWORD_NULL: case PARSER_TOKEN_CONSTANT: case PARSER_TOKEN_VARIABLE: case PARSER_TOKEN_FUNCTION_DEFINITION: @@ -1649,6 +1671,7 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_OPERATOR_MULTIPLY_ASSIGN: case PARSER_TOKEN_OPERATOR_DIVIDE_ASSIGN: case PARSER_TOKEN_OPERATOR_MODULO_ASSIGN: + case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_OPERATOR_PLUS: case PARSER_TOKEN_OPERATOR_MINUS: case PARSER_TOKEN_OPERATOR_SUM: @@ -1678,6 +1701,7 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_TYPE_F32: case PARSER_TOKEN_TYPE_F64: case PARSER_TOKEN_TYPE_F128: + case PARSER_TOKEN_KEYWORD_NULL: case PARSER_TOKEN_KEYWORD_IF: case PARSER_TOKEN_KEYWORD_COMPTIME: case PARSER_TOKEN_SYMBOL_PARENTHESIS: diff --git a/src/compiler/parser.h b/src/compiler/parser.h index bb54099..0eb2112 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -36,6 +36,7 @@ typedef enum ParserToken { PARSER_TOKEN_KEYWORD_IF, PARSER_TOKEN_KEYWORD_WHILE, PARSER_TOKEN_KEYWORD_COMPTIME, + PARSER_TOKEN_KEYWORD_NULL, PARSER_TOKEN_CONSTANT, PARSER_TOKEN_VARIABLE, @@ -64,6 +65,7 @@ typedef enum ParserToken { PARSER_TOKEN_OPERATOR_SMALLER, PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL, PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL, + PARSER_TOKEN_OPERATOR_POINTER, PARSER_TOKEN_FUNCTION_DEFINITION, @@ -77,7 +79,7 @@ extern const char *PARSER_TOKEN_STRINGS[]; typedef struct ParserOrder { bool ltr; size_t size; - LexerToken data[20]; + LexerToken data[21]; } ParserOrder; typedef struct ParserNode { diff --git a/src/runner/runner.c b/src/runner/runner.c index 576ada5..d77e2b8 100644 --- a/src/runner/runner.c +++ b/src/runner/runner.c @@ -1001,10 +1001,12 @@ AstTree *runExpression(AstTree *expr, RunnerVariablePages *pages, case AST_TREE_TOKEN_TYPE_F32: case AST_TREE_TOKEN_TYPE_F64: case AST_TREE_TOKEN_TYPE_F128: + case AST_TREE_TOKEN_VALUE_NULL: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_BOOL: case AST_TREE_TOKEN_VALUE_FLOAT: + case AST_TREE_TOKEN_OPERATOR_POINTER: return copyAstTree(expr); case AST_TREE_TOKEN_VARIABLE: { AstTreeVariable *variable = expr->metadata; |