summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2025-04-11 14:01:12 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2025-04-11 14:01:12 +0330
commit399256ab6f75b364773c299847ad2c57a96a7c41 (patch)
tree9219a6311305771c0af1e5ef776d627ece4c9c5f
parent3a4f7672a416a29fe528c01321858beea9781f47 (diff)
implement function overloading
-rw-r--r--code/main.felan30
-rw-r--r--src/compiler/ast-tree.c433
-rw-r--r--src/compiler/ast-tree.h19
-rw-r--r--src/runner/runner.c3
4 files changed, 210 insertions, 275 deletions
diff --git a/code/main.felan b/code/main.felan
index e69dc7c..f9ba848 100644
--- a/code/main.felan
+++ b/code/main.felan
@@ -17,20 +17,32 @@ long_double :: f128;
usize :: u64;
-
main :: () -> void {
- a:u64 = 97;
- b := @cast(a,u16);
- putc @cast(a,u8);
- putc @cast(b,u8);
- // print_u64_rev(1234);
+ a :i64 = 12;
+ b :u64 = 34;
+ print_rev(a);
+ print_rev(b);
+ a();
+};
+
+a :: () -> void {
+ putc 'x';
+};
+
+print_rev :: (value:u64) -> void {
+ putc 'a';
+ value := value;
+ while {
+ putc '0' + @cast(value % 10,u8);
+ value /= 10;
+ value != 0;
+ } {}
};
-print_u64_rev :: (value:u64) -> void {
+print_rev :: (value:i64) -> void {
+ putc 'b';
value := value;
- first_time := true;
while {
- first_time = false;
putc '0' + @cast(value % 10,u8);
value /= 10;
value != 0;
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index 0d52265..7310ce1 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -1176,6 +1176,14 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
a404m_malloc(nodes->size * sizeof(*root->variables.data));
root->variables.size = 0;
+ AstTreeVariables *variables = &root->variables;
+ static const size_t variables_size = 1;
+
+ AstTreeHelper helper = {
+ .variables = &variables,
+ .variables_size = variables_size,
+ };
+
for (size_t i = 0; i < nodes->size; ++i) {
ParserNode *eol = nodes->data[i];
if (eol->token != PARSER_TOKEN_SYMBOL_EOL) {
@@ -1195,7 +1203,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
variable->name_end = node_metadata->name->str_end;
variable->isConst = node->token == PARSER_TOKEN_CONSTANT;
- if (!pushVariable(NULL, &root->variables, variable)) {
+ if (!pushVariable(&helper, &root->variables, variable)) {
astTreeVariableDelete(variable);
goto RETURN_ERROR;
}
@@ -1214,22 +1222,6 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
sizeof(*root->variables.data));
root->trees.size = 0;
- AstTreeVariables *variables = &root->variables;
- static const size_t variables_size = 1;
-
- AstTreeHelper helper = {
- .variables = &variables,
- .variables_size = variables_size,
- .variable = NULL,
- .globalDeps = a404m_malloc(variables->size * sizeof(*helper.globalDeps)),
- };
-
- for (size_t i = 0; i < variables->size; ++i) {
- helper.globalDeps[i].size = 0;
- helper.globalDeps[i].data =
- a404m_malloc(helper.globalDeps->size * sizeof(*helper.globalDeps));
- }
-
for (size_t i = 0; i < nodes->size; ++i) {
ParserNode *eol = nodes->data[i];
if (eol->token != PARSER_TOKEN_SYMBOL_EOL) {
@@ -1251,7 +1243,6 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
}
for (size_t i = 0; i < nodes->size; ++i) {
- helper.variable = root->variables.data[i];
ParserNode *node =
(ParserNodeSingleChildMetadata *)nodes->data[i]->metadata;
ParserNodeVariableMetadata *node_metadata = node->metadata;
@@ -1370,16 +1361,10 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
}
}
- helper.variable = NULL;
if (!setAllTypesRoot(root, &helper)) {
goto RETURN_ERROR;
}
- for (size_t i = 0; i < variables->size; ++i) {
- free(helper.globalDeps[i].data);
- }
- free(helper.globalDeps);
-
return root;
RETURN_ERROR:
@@ -1394,16 +1379,17 @@ RETURN_ERROR:
bool pushVariable(AstTreeHelper *helper, AstTreeVariables *variables,
AstTreeVariable *variable) {
- (void)helper;
- for (size_t j = 0; j < variables->size; ++j) {
- char *var_begin = variables->data[j]->name_begin;
- char *var_end = variables->data[j]->name_end;
-
- if (variable->name_end - variable->name_begin == var_end - var_begin &&
- strncmp(var_begin, variable->name_begin,
- variable->name_end - variable->name_begin) == 0) {
- printError(variable->name_begin, variable->name_end, "Variable exists");
- return false;
+ if (helper->variables[0] != variables) {
+ for (size_t j = 0; j < variables->size; ++j) {
+ char *var_begin = variables->data[j]->name_begin;
+ char *var_end = variables->data[j]->name_end;
+
+ if (variable->name_end - variable->name_begin == var_end - var_begin &&
+ strncmp(var_begin, variable->name_begin,
+ variable->name_end - variable->name_begin) == 0) {
+ printError(variable->name_begin, variable->name_end, "Variable exists");
+ return false;
+ }
}
}
@@ -1419,8 +1405,13 @@ bool pushVariable(AstTreeHelper *helper, AstTreeVariables *variables,
return true;
}
-AstTreeVariable *getVariable(AstTreeHelper *helper, char *name_begin,
- char *name_end) {
+AstTreeVariables *getAllVariables(AstTreeHelper *helper, char *name_begin,
+ char *name_end) {
+ size_t variables_size = 0;
+ AstTreeVariables *variables = a404m_malloc(sizeof(*variables));
+ variables->data = a404m_malloc(variables_size * sizeof(*variables->data));
+ variables->size = 0;
+
for (size_t i = helper->variables_size - 1; i != (size_t)-1ULL; --i) {
AstTreeVariables vars = *helper->variables[i];
for (size_t j = 0; j < vars.size; ++j) {
@@ -1431,31 +1422,18 @@ AstTreeVariable *getVariable(AstTreeHelper *helper, char *name_begin,
if (name_end - name_begin == var_end - var_begin &&
strncmp(var_begin, name_begin, name_end - name_begin) == 0) {
-
- if (i == 0 && helper->variable != NULL) {
- for (size_t i = 0; i < helper->variables[0]->size; ++i) {
- if (helper->variables[0]->data[i] == helper->variable) {
- size_t globalDeps_size =
- a404m_malloc_usable_size(helper->globalDeps[i].data) /
- sizeof(*helper->globalDeps[i].data);
- if (globalDeps_size == helper->globalDeps[i].size) {
- globalDeps_size += globalDeps_size / 2 + 1;
- helper->globalDeps[i].data = a404m_realloc(
- helper->globalDeps[i].data,
- globalDeps_size * sizeof(*helper->globalDeps[i].data));
- }
- helper->globalDeps[i].data[helper->globalDeps[i].size] = variable;
- helper->globalDeps[i].size += 1;
- }
- }
+ if (variables_size == variables->size) {
+ variables_size += variables_size / 2 + 1;
+ variables->data = a404m_realloc(
+ variables->data, variables_size * sizeof(*variables->data));
}
-
- return variable;
+ variables->data[variables->size] = variable;
+ variables->size += 1;
}
}
}
- return NULL;
+ return variables;
}
AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper) {
@@ -1657,8 +1635,6 @@ AstTree *astTreeParseFunction(ParserNode *parserNode, AstTreeHelper *p_helper) {
AstTreeHelper helper = {
.variables = variables,
.variables_size = variables_size,
- .variable = p_helper->variable,
- .globalDeps = p_helper->globalDeps,
};
for (size_t i = 0; i < node_arguments->size; ++i) {
@@ -1936,15 +1912,15 @@ AstTree *astTreeParseFunctionCall(ParserNode *parserNode,
}
AstTree *astTreeParseIdentifier(ParserNode *parserNode, AstTreeHelper *helper) {
- AstTreeVariable *var =
- getVariable(helper, parserNode->str_begin, parserNode->str_end);
- if (var == NULL) {
+ AstTreeVariables *variables =
+ getAllVariables(helper, parserNode->str_begin, parserNode->str_end);
+ if (variables->size == 0) {
printError(parserNode->str_begin, parserNode->str_end,
"Variable not found");
return NULL;
}
- return newAstTree(AST_TREE_TOKEN_VARIABLE, var, NULL, parserNode->str_begin,
- parserNode->str_end);
+ return newAstTree(AST_TREE_TOKEN_VARIABLE, variables, NULL,
+ parserNode->str_begin, parserNode->str_end);
}
AstTree *astTreeParseValue(ParserNode *parserNode, AstTreeToken token,
@@ -2239,8 +2215,6 @@ AstTree *astTreeParseCurlyBracket(ParserNode *parserNode,
AstTreeHelper helper = {
.variables = variables,
.variables_size = variables_size,
- .variable = p_helper->variable,
- .globalDeps = p_helper->globalDeps,
};
for (size_t i = 0; i < body->size; ++i) {
@@ -3023,187 +2997,24 @@ AstTree *getValue(AstTree *tree) {
UNREACHABLE;
}
-bool isCircularDependencies(AstTreeHelper *helper, AstTreeVariable *variable) {
- AstTreeVariables checkedVariables = {
- .data = a404m_malloc(0),
- .size = 0,
+bool setAllTypesRoot(AstTreeRoot *root, AstTreeHelper *helper) {
+ AstTreeSetTypesHelper setTypesHelper = {
+ .lookingType = NULL,
+ .treeHelper = helper,
+ .dependencies =
+ {
+ .data = NULL,
+ .size = 0,
+ },
};
- bool ret = isCircularDependenciesBack(helper, variable, variable->value,
- &checkedVariables);
- free(checkedVariables.data);
- return ret;
-}
-
-bool isCircularDependenciesBack(AstTreeHelper *helper,
- AstTreeVariable *variable, AstTree *tree,
- AstTreeVariables *checkedVariables) {
- switch (tree->token) {
- case AST_TREE_TOKEN_BUILTIN:
- case AST_TREE_TOKEN_TYPE_TYPE:
- case AST_TREE_TOKEN_TYPE_FUNCTION:
- case AST_TREE_TOKEN_TYPE_VOID:
- case AST_TREE_TOKEN_TYPE_I8:
- case AST_TREE_TOKEN_TYPE_U8:
- case AST_TREE_TOKEN_TYPE_I16:
- case AST_TREE_TOKEN_TYPE_U16:
- case AST_TREE_TOKEN_TYPE_I32:
- case AST_TREE_TOKEN_TYPE_U32:
- case AST_TREE_TOKEN_TYPE_I64:
- case AST_TREE_TOKEN_TYPE_U64:
-#ifdef FLOAT_16_SUPPORT
- case AST_TREE_TOKEN_TYPE_F16:
-#endif
- case AST_TREE_TOKEN_TYPE_F32:
- 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_UNDEFINED:
- case AST_TREE_TOKEN_VALUE_VOID:
- case AST_TREE_TOKEN_VALUE_INT:
- case AST_TREE_TOKEN_VALUE_FLOAT:
- case AST_TREE_TOKEN_VALUE_BOOL:
- case AST_TREE_TOKEN_OPERATOR_ACCESS:
- return false;
- case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT:
- case AST_TREE_TOKEN_OPERATOR_POINTER:
- case AST_TREE_TOKEN_OPERATOR_ADDRESS:
- case AST_TREE_TOKEN_OPERATOR_DEREFERENCE:
- case AST_TREE_TOKEN_KEYWORD_COMPTIME:
- case AST_TREE_TOKEN_OPERATOR_PLUS:
- case AST_TREE_TOKEN_OPERATOR_MINUS: {
- AstTreeSingleChild *metadata = tree->metadata;
- return isCircularDependenciesBack(helper, variable, metadata,
- checkedVariables);
- }
- case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND:
- case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR:
- case AST_TREE_TOKEN_OPERATOR_ASSIGN:
- case AST_TREE_TOKEN_OPERATOR_SUM:
- case AST_TREE_TOKEN_OPERATOR_SUB:
- case AST_TREE_TOKEN_OPERATOR_MULTIPLY:
- case AST_TREE_TOKEN_OPERATOR_DIVIDE:
- case AST_TREE_TOKEN_OPERATOR_MODULO:
- case AST_TREE_TOKEN_OPERATOR_EQUAL:
- case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL:
- case AST_TREE_TOKEN_OPERATOR_GREATER:
- case AST_TREE_TOKEN_OPERATOR_SMALLER:
- case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL:
- case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: {
- AstTreeInfix *metadata = tree->metadata;
- return isCircularDependenciesBack(helper, variable, &metadata->left,
- checkedVariables) ||
- isCircularDependenciesBack(helper, variable, &metadata->right,
- checkedVariables);
- }
- case AST_TREE_TOKEN_FUNCTION_CALL: {
- AstTreeFunctionCall *metadata = tree->metadata;
- for (size_t i = 0; i < metadata->parameters_size; ++i) {
- if (isCircularDependenciesBack(helper, variable,
- metadata->parameters[i].value,
- checkedVariables)) {
- return true;
- }
- }
- return isCircularDependenciesBack(helper, variable, metadata->function,
- checkedVariables);
- }
- case AST_TREE_TOKEN_VARIABLE: {
- AstTreeVariable *metadata = tree->metadata;
- for (size_t index = 0; index < helper->variables[0]->size; ++index) {
- if (helper->variables[0]->data[index] == metadata) {
- for (size_t i = 0; i < helper->globalDeps[index].size; ++i) {
- AstTreeVariable *currentVariable = helper->globalDeps[index].data[i];
- if (currentVariable == variable ||
- isCircularDependenciesVariable(helper, variable, currentVariable,
- checkedVariables)) {
- return true;
- }
- }
- break;
- }
- }
- return false;
- }
- case AST_TREE_TOKEN_VALUE_OBJECT: {
- AstTreeObject *metadata = tree->metadata;
- for (size_t i = 0; i < metadata->variables.size; ++i) {
- AstTreeVariable *variable = metadata->variables.data[i];
- if (variable->value != NULL) {
- if (isCircularDependenciesBack(helper, variable, variable->value,
- checkedVariables)) {
- return true;
- }
- }
- }
- return false;
- }
- case AST_TREE_TOKEN_KEYWORD_STRUCT:
- case AST_TREE_TOKEN_FUNCTION: {
- return false;
- }
- case AST_TREE_TOKEN_SCOPE:
- case AST_TREE_TOKEN_KEYWORD_PUTC:
- case AST_TREE_TOKEN_KEYWORD_RETURN:
- case AST_TREE_TOKEN_VARIABLE_DEFINE:
- case AST_TREE_TOKEN_KEYWORD_IF:
- case AST_TREE_TOKEN_KEYWORD_WHILE:
- case AST_TREE_TOKEN_NONE:
- }
- UNREACHABLE;
-}
-
-bool isCircularDependenciesVariable(AstTreeHelper *helper,
- AstTreeVariable *toBeFound,
- AstTreeVariable *currentVariable,
- AstTreeVariables *checkedVariables) {
- for (size_t i = 0; i < checkedVariables->size; ++i) {
- if (currentVariable == checkedVariables->data[i]) {
- return false;
- }
- }
- const size_t capacity = a404m_malloc_usable_size(checkedVariables->data) /
- sizeof(*checkedVariables->data);
-
- if (capacity == checkedVariables->size) {
- checkedVariables->data = a404m_realloc(checkedVariables->data,
- (capacity + capacity / 2 + 1) *
- sizeof(*checkedVariables->data));
- }
- checkedVariables->data[checkedVariables->size] = currentVariable;
- checkedVariables->size += 1;
-
- for (size_t index = 0; index < helper->variables[0]->size; ++index) {
- if (helper->variables[0]->data[index] == currentVariable) {
- for (size_t i = 0; i < helper->globalDeps[index].size; ++i) {
- AstTreeVariable *var = helper->globalDeps[index].data[i];
- if (var == toBeFound || isCircularDependenciesVariable(
- helper, toBeFound, var, checkedVariables)) {
- return true;
- }
- }
- break;
- }
- }
- return false;
-}
-
-bool setAllTypesRoot(AstTreeRoot *root, AstTreeHelper *helper) {
for (size_t i = 0; i < root->variables.size; ++i) {
AstTreeVariable *variable = root->variables.data[i];
- if (isCircularDependencies(helper, variable)) {
- printError(variable->name_begin, variable->name_end,
- "Circular dependecies");
+ if (!setTypesAstVariable(variable, setTypesHelper)) {
return false;
}
}
- AstTreeSetTypesHelper setTypesHelper = {
- .lookingType = NULL,
- .treeHelper = helper,
- };
-
for (size_t i = 0; i < root->trees.size; ++i) {
AstTree *tree = root->trees.data[i];
if (!setAllTypes(tree, setTypesHelper, NULL, NULL)) {
@@ -3211,13 +3022,6 @@ bool setAllTypesRoot(AstTreeRoot *root, AstTreeHelper *helper) {
}
}
- for (size_t i = 0; i < root->variables.size; ++i) {
- AstTreeVariable *variable = root->variables.data[i];
- if (!setTypesAstVariable(variable, setTypesHelper)) {
- return false;
- }
- }
-
return true;
}
@@ -3269,7 +3073,7 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper,
case AST_TREE_TOKEN_FUNCTION_CALL:
return setTypesFunctionCall(tree, helper);
case AST_TREE_TOKEN_VARIABLE:
- return setTypesVariable(tree, helper);
+ return setTypesVariable(tree, helper, functionCall);
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
return setTypesOperatorAssign(tree, helper);
case AST_TREE_TOKEN_OPERATOR_PLUS:
@@ -3546,6 +3350,7 @@ bool setTypesPrintU64(AstTree *tree, AstTreeSetTypesHelper _helper) {
AstTreeSetTypesHelper helper = {
.lookingType = &AST_TREE_U8_TYPE,
.treeHelper = _helper.treeHelper,
+ .dependencies = _helper.dependencies,
};
if (!setAllTypes(metadata, helper, NULL, NULL)) {
return false;
@@ -3569,6 +3374,7 @@ bool setTypesReturn(AstTree *tree, AstTreeSetTypesHelper _helper,
AstTreeSetTypesHelper helper = {
.lookingType = getValue(function->returnType),
.treeHelper = _helper.treeHelper,
+ .dependencies = _helper.dependencies,
};
if (helper.lookingType == NULL) {
return false;
@@ -3612,9 +3418,22 @@ bool setTypesTypeFunction(AstTree *tree, AstTreeSetTypesHelper helper) {
return true;
}
-bool setTypesFunctionCall(AstTree *tree, AstTreeSetTypesHelper helper) {
+bool setTypesFunctionCall(AstTree *tree, AstTreeSetTypesHelper _helper) {
AstTreeFunctionCall *metadata = tree->metadata;
+ AstTreeSetTypesHelper helper = {
+ .lookingType = NULL,
+ .treeHelper = _helper.treeHelper,
+ .dependencies = _helper.dependencies,
+ };
+
+ for (size_t i = 0; i < metadata->parameters_size; ++i) {
+ AstTreeFunctionCallParam param = metadata->parameters[i];
+ if (!setAllTypes(param.value, helper, NULL, NULL)) {
+ return false;
+ }
+ }
+
if (!setAllTypes(metadata->function, helper, NULL, metadata)) {
return false;
} else if (!isFunction(metadata->function)) {
@@ -3651,6 +3470,7 @@ bool setTypesFunctionCall(AstTree *tree, AstTreeSetTypesHelper helper) {
AstTreeSetTypesHelper newHelper = {
.lookingType = arg.type,
.treeHelper = helper.treeHelper,
+ .dependencies = helper.dependencies,
};
if (!setAllTypes(param.value, newHelper, NULL, NULL)) {
@@ -3676,6 +3496,7 @@ bool setTypesFunctionCall(AstTree *tree, AstTreeSetTypesHelper helper) {
AstTreeSetTypesHelper newHelper = {
.lookingType = arg.type,
.treeHelper = helper.treeHelper,
+ .dependencies = helper.dependencies,
};
if (!setAllTypes(param.value, newHelper, NULL, NULL)) {
@@ -3707,13 +3528,102 @@ bool setTypesFunctionCall(AstTree *tree, AstTreeSetTypesHelper helper) {
return true;
}
-bool setTypesVariable(AstTree *tree, AstTreeSetTypesHelper helper) {
- AstTreeVariable *metadata = tree->metadata;
- if (!setTypesAstVariable(metadata, helper)) {
+bool setTypesVariable(AstTree *tree, AstTreeSetTypesHelper helper,
+ AstTreeFunctionCall *functionCall) {
+ AstTreeVariables *variables = tree->metadata;
+
+ AstTreeVariable *variable;
+ if (variables->size == 1 || functionCall == NULL) {
+ variable = variables->data[0];
+ } else {
+ for (size_t i = 0; i < variables->size; ++i) {
+ AstTreeVariable *var = variables->data[i];
+ if (!setTypesAstVariable(var, helper)) {
+ goto RETURN_ERROR;
+ }
+
+ if (var->type->token != AST_TREE_TOKEN_TYPE_FUNCTION) {
+ continue;
+ }
+
+ AstTreeTypeFunction *function = var->type->metadata;
+
+ AstTreeFunctionCallParam initedArguments[function->arguments_size];
+ size_t initedArguments_size = function->arguments_size;
+
+ for (size_t i = 0; i < initedArguments_size; ++i) {
+ initedArguments[i].value = NULL;
+ }
+
+ for (size_t i = 0; i < functionCall->parameters_size; ++i) {
+ AstTreeFunctionCallParam param = functionCall->parameters[i];
+ if (param.nameBegin != param.nameEnd) {
+ const size_t param_name_size = param.nameEnd - param.nameBegin;
+ for (size_t j = 0; j < function->arguments_size; ++j) {
+ AstTreeTypeFunctionArgument arg = function->arguments[j];
+ if ((size_t)(arg.name_end - arg.name_begin) == param_name_size &&
+ strncmp(arg.name_begin, param.nameBegin, param_name_size) ==
+ 0) {
+ if (!typeIsEqual(arg.type, param.value->type)) {
+ goto CONTINUE_OUTER;
+ }
+ initedArguments[j] = param;
+ goto END_OF_NAMED_FOR;
+ }
+ }
+ goto CONTINUE_OUTER;
+ }
+ END_OF_NAMED_FOR:
+ }
+
+ for (size_t i = 0; i < functionCall->parameters_size; ++i) {
+ AstTreeFunctionCallParam param = functionCall->parameters[i];
+ if (param.nameBegin == param.nameEnd) {
+ for (size_t j = 0; j < function->arguments_size; ++j) {
+ AstTreeTypeFunctionArgument arg = function->arguments[j];
+ if (initedArguments[j].value == NULL) {
+ if (!typeIsEqual(arg.type, param.value->type)) {
+ goto CONTINUE_OUTER;
+ }
+ initedArguments[j] = param;
+ goto END_OF_UNNAMED_FOR;
+ }
+ }
+ goto CONTINUE_OUTER;
+ }
+ END_OF_UNNAMED_FOR:
+ }
+
+ for (size_t i = 0; i < function->arguments_size; ++i) {
+ if (initedArguments[i].value == NULL) {
+ goto CONTINUE_OUTER;
+ }
+ }
+ variable = var;
+ goto END;
+ CONTINUE_OUTER:
+ }
+ printError(tree->str_begin, tree->str_end, "No candidate found");
+ goto RETURN_ERROR;
+ }
+
+END:
+ tree->metadata = variable;
+
+ free(variables->data);
+ free(variables);
+
+ if (!setTypesAstVariable(variable, helper)) {
return false;
}
- tree->type = copyAstTree(metadata->type);
+ tree->type = copyAstTree(variable->type);
return true;
+
+RETURN_ERROR:
+ tree->metadata = variables->data[0]; // for safe delete
+ free(variables->data);
+ free(variables);
+ return false;
}
bool setTypesOperatorAssign(AstTree *tree, AstTreeSetTypesHelper helper) {
@@ -3766,6 +3676,7 @@ bool setTypesOperatorInfixWithRetAndLooking(AstTree *tree, AstTree *lookingType,
AstTreeSetTypesHelper helper = {
.lookingType = lookingType,
.treeHelper = _helper.treeHelper,
+ .dependencies = helper.dependencies,
};
AstTreeInfix *infix = tree->metadata;
if (!setTypesAstInfix(infix, helper)) {
@@ -3795,6 +3706,7 @@ bool setTypesOperatorUnaryWithRetAndLooking(AstTree *tree, AstTree *lookingType,
AstTreeSetTypesHelper helper = {
.lookingType = lookingType,
.treeHelper = _helper.treeHelper,
+ .dependencies = helper.dependencies,
};
AstTreeSingleChild *operand = tree->metadata;
if (!setAllTypes(operand, helper, NULL, NULL)) {
@@ -3860,9 +3772,27 @@ bool setTypesVariableDefine(AstTree *tree, AstTreeSetTypesHelper helper) {
bool setTypesAstVariable(AstTreeVariable *variable,
AstTreeSetTypesHelper _helper) {
+ AstTreeVariable *deps[_helper.dependencies.size + 1];
+
+ for (size_t i = 0; i < _helper.dependencies.size; ++i) {
+ AstTreeVariable *depVar = _helper.dependencies.data[i];
+ if (variable == depVar) {
+ printError(variable->name_begin, variable->name_end,
+ "Circular dependency found");
+ return false;
+ }
+ deps[i] = depVar;
+ }
+ deps[_helper.dependencies.size] = variable;
+
AstTreeSetTypesHelper helper = {
.lookingType = &AST_TREE_TYPE_TYPE,
.treeHelper = _helper.treeHelper,
+ .dependencies =
+ {
+ .data = deps,
+ .size = _helper.dependencies.size + 1,
+ },
};
if (variable->type != NULL) {
@@ -4165,6 +4095,7 @@ bool setTypesAstInfix(AstTreeInfix *infix, AstTreeSetTypesHelper helper) {
AstTreeSetTypesHelper newHelper = {
.lookingType = infix->left.type,
.treeHelper = helper.treeHelper,
+ .dependencies = helper.dependencies,
};
return setAllTypes(&infix->right, newHelper, NULL, NULL);
diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h
index 6d11e16..0ae48f5 100644
--- a/src/compiler/ast-tree.h
+++ b/src/compiler/ast-tree.h
@@ -200,13 +200,12 @@ typedef struct AstTreeWhile {
typedef struct AstTreeHelper {
AstTreeVariables **variables;
size_t variables_size;
- AstTreeVariable *variable;
- AstTreeVariables *globalDeps;
} AstTreeHelper;
typedef struct AstTreeSetTypesHelper {
AstTree *lookingType;
AstTreeHelper *treeHelper;
+ AstTreeVariables dependencies;
} AstTreeSetTypesHelper;
typedef struct AstTreeStruct {
@@ -264,8 +263,8 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot);
bool pushVariable(AstTreeHelper *helper, AstTreeVariables *variables,
AstTreeVariable *variable);
-AstTreeVariable *getVariable(AstTreeHelper *helper, char *name_begin,
- char *name_end);
+AstTreeVariables *getAllVariables(AstTreeHelper *helper, char *name_begin,
+ char *name_end);
AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper);
AstTree *astTreeParseFunction(ParserNode *parserNode, AstTreeHelper *helper);
@@ -307,15 +306,6 @@ bool typeIsEqual(AstTree *type0, AstTree *type1);
bool typeIsEqualBack(const AstTree *type0, const AstTree *type1);
AstTree *getValue(AstTree *tree);
-bool isCircularDependencies(AstTreeHelper *helper, AstTreeVariable *variable);
-bool isCircularDependenciesBack(AstTreeHelper *helper,
- AstTreeVariable *variable, AstTree *tree,
- AstTreeVariables *checkedVariables);
-bool isCircularDependenciesVariable(AstTreeHelper *helper,
- AstTreeVariable *toBeFound,
- AstTreeVariable *currentVariable,
- AstTreeVariables *checkedVariables);
-
bool setAllTypesRoot(AstTreeRoot *root, AstTreeHelper *helper);
bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper,
AstTreeFunction *function, AstTreeFunctionCall *functionCall);
@@ -331,7 +321,8 @@ bool setTypesReturn(AstTree *tree, AstTreeSetTypesHelper helper,
AstTreeFunction *function);
bool setTypesTypeFunction(AstTree *tree, AstTreeSetTypesHelper helper);
bool setTypesFunctionCall(AstTree *tree, AstTreeSetTypesHelper helper);
-bool setTypesVariable(AstTree *tree, AstTreeSetTypesHelper helper);
+bool setTypesVariable(AstTree *tree, AstTreeSetTypesHelper helper,
+ AstTreeFunctionCall *functionCall);
bool setTypesOperatorAssign(AstTree *tree, AstTreeSetTypesHelper helper);
bool setTypesOperatorInfix(AstTree *tree, AstTreeSetTypesHelper helper);
bool setTypesOperatorInfixWithRet(AstTree *tree, AstTree *retType,
diff --git a/src/runner/runner.c b/src/runner/runner.c
index 818f21a..57d10fa 100644
--- a/src/runner/runner.c
+++ b/src/runner/runner.c
@@ -754,7 +754,8 @@ AstTree *runExpression(AstTree *expr, bool *shouldRet, bool isLeft) {
right->type == &AST_TREE_I8_TYPE) {
doOperation(left, right, %, AstTreeInt, i8);
} else {
- printError(expr->str_begin, expr->str_end, "Not supported");
+ printError(expr->str_begin, expr->str_end, "Not supported %s",
+ AST_TREE_TOKEN_STRINGS[right->type->token]);
UNREACHABLE;
}
astTreeDelete(right);