summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2025-03-25 04:46:20 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2025-03-25 04:46:20 +0330
commit3bd7d3498f12cfb8dbdf5fff7c0bc981bf8085e2 (patch)
tree0888de25c1e553896d817ca8d2c2405306b9d0ca /src
parent0d2065dfb49ed41110155ab1c29879c09c9d3dc7 (diff)
add pointer type
Diffstat (limited to 'src')
-rw-r--r--src/compiler/ast-tree.c114
-rw-r--r--src/compiler/ast-tree.h9
-rw-r--r--src/compiler/lexer.c14
-rw-r--r--src/compiler/lexer.h2
-rw-r--r--src/compiler/parser.c28
-rw-r--r--src/compiler/parser.h4
-rw-r--r--src/runner/runner.c2
7 files changed, 141 insertions, 32 deletions
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;