summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2025-02-12 09:19:32 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2025-02-12 09:19:32 +0330
commit217b2c70adfd60756591dd6b06b60279f805a596 (patch)
treec3855291e212b6beb990fa128968fc1a95e00d42 /src/compiler
parentdecaf9321cbf119d1efea0c4667f49b0ab2e8c96 (diff)
fix circular dependency problem
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/ast-tree.c288
-rw-r--r--src/compiler/ast-tree.h54
-rw-r--r--src/compiler/parser.c1
3 files changed, 215 insertions, 128 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index 3fd1dd5..4976750 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -526,7 +526,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
variable->name_end = node_metadata->name->str_end;
variable->isConst = node->token == PARSER_TOKEN_CONSTANT;
- if (!pushVariable(&root->variables, variable)) {
+ if (!pushVariable(NULL, &root->variables, variable)) {
astTreeVariableDelete(variable);
goto RETURN_ERROR;
}
@@ -535,7 +535,21 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
AstTreeVariables *variables = &root->variables;
constexpr 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) {
+ helper.variable = root->variables.data[i];
ParserNode *node =
(ParserNodeSingleChildMetadata *)nodes->data[i]->metadata;
ParserNodeVariableMetadata *node_metadata = node->metadata;
@@ -558,9 +572,18 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
case PARSER_TOKEN_VALUE_U64:
case PARSER_TOKEN_FUNCTION_DEFINITION:
case PARSER_TOKEN_FUNCTION_CALL:
+ case PARSER_TOKEN_IDENTIFIER:
+ case PARSER_TOKEN_OPERATOR_ASSIGN:
+ case PARSER_TOKEN_OPERATOR_PLUS:
+ case PARSER_TOKEN_OPERATOR_MINUS:
+ case PARSER_TOKEN_OPERATOR_SUM:
+ case PARSER_TOKEN_OPERATOR_SUB:
+ case PARSER_TOKEN_OPERATOR_MULTIPLY:
+ case PARSER_TOKEN_OPERATOR_DIVIDE:
+ case PARSER_TOKEN_OPERATOR_MODULO:
+ case PARSER_TOKEN_SYMBOL_PARENTHESIS:
goto AFTER_SWITCH;
case PARSER_TOKEN_ROOT:
- case PARSER_TOKEN_IDENTIFIER:
case PARSER_TOKEN_TYPE_TYPE:
case PARSER_TOKEN_TYPE_FUNCTION:
case PARSER_TOKEN_TYPE_VOID:
@@ -572,16 +595,7 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
case PARSER_TOKEN_VARIABLE:
case PARSER_TOKEN_SYMBOL_EOL:
case PARSER_TOKEN_SYMBOL_CURLY_BRACKET:
- case PARSER_TOKEN_SYMBOL_PARENTHESIS:
case PARSER_TOKEN_SYMBOL_COMMA:
- case PARSER_TOKEN_OPERATOR_ASSIGN:
- case PARSER_TOKEN_OPERATOR_PLUS:
- case PARSER_TOKEN_OPERATOR_MINUS:
- case PARSER_TOKEN_OPERATOR_SUM:
- case PARSER_TOKEN_OPERATOR_SUB:
- case PARSER_TOKEN_OPERATOR_MULTIPLY:
- case PARSER_TOKEN_OPERATOR_DIVIDE:
- case PARSER_TOKEN_OPERATOR_MODULO:
printError(node->str_begin, node->str_end, "Should not be here");
goto RETURN_ERROR;
case PARSER_TOKEN_NONE:
@@ -592,15 +606,14 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
AFTER_SWITCH:
- AstTree *value =
- astTreeParse(node_metadata->value, &variables, variables_size);
+ AstTree *value = astTreeParse(node_metadata->value, &helper);
if (value == NULL) {
goto RETURN_ERROR;
}
AstTree *type;
if (node_metadata->type != NULL) {
- type = astTreeParse(node_metadata->type, &variables, variables_size);
+ type = astTreeParse(node_metadata->type, &helper);
if (type == NULL) {
goto RETURN_ERROR;
}
@@ -612,10 +625,14 @@ AstTreeRoot *makeAstTree(ParserNode *parsedRoot) {
root->variables.data[i]->value = value;
}
- if (!setAllTypesRoot(root) || !astTreeCleanRoot(root)) {
+ helper.variable = NULL;
+ if (!setAllTypesRoot(root, &helper) || !astTreeCleanRoot(root)) {
goto RETURN_ERROR;
}
+ free(helper.globalDeps->data);
+ free(helper.globalDeps);
+
return root;
RETURN_ERROR:
@@ -624,7 +641,8 @@ RETURN_ERROR:
return NULL;
}
-bool pushVariable(AstTreeVariables *variables, AstTreeVariable *variable) {
+bool pushVariable(AstTreeHelper *helper, AstTreeVariables *variables,
+ AstTreeVariable *variable) {
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;
@@ -649,18 +667,38 @@ bool pushVariable(AstTreeVariables *variables, AstTreeVariable *variable) {
return true;
}
-AstTreeVariable *getVariable(AstTreeVariables **variables,
- size_t variables_size, char *name_begin,
+AstTreeVariable *getVariable(AstTreeHelper *helper, char *name_begin,
char *name_end) {
- for (size_t i = variables_size - 1; i != (size_t)-1ULL; --i) {
- AstTreeVariables vars = *variables[i];
+ 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) {
char *var_begin = vars.data[j]->name_begin;
char *var_end = vars.data[j]->name_end;
+ AstTreeVariable *variable = vars.data[j];
+
if (name_end - name_begin == var_end - var_begin &&
strncmp(var_begin, name_begin, name_end - name_begin) == 0) {
- return vars.data[j];
+
+ 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;
+ }
+ }
+ }
+
+ return variable;
}
}
}
@@ -668,15 +706,14 @@ AstTreeVariable *getVariable(AstTreeVariables **variables,
return NULL;
}
-AstTree *astTreeParse(ParserNode *parserNode, AstTreeVariables **variables,
- size_t variables_size) {
+AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper) {
switch (parserNode->token) {
case PARSER_TOKEN_FUNCTION_DEFINITION:
- return astTreeParseFunction(parserNode, variables, variables_size);
+ return astTreeParseFunction(parserNode, helper);
case PARSER_TOKEN_TYPE_TYPE:
return &AST_TREE_TYPE_TYPE;
case PARSER_TOKEN_TYPE_FUNCTION:
- return astTreeParseTypeFunction(parserNode, variables, variables_size);
+ return astTreeParseTypeFunction(parserNode, helper);
case PARSER_TOKEN_TYPE_VOID:
return &AST_TREE_VOID_TYPE;
case PARSER_TOKEN_TYPE_U64:
@@ -684,9 +721,9 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeVariables **variables,
case PARSER_TOKEN_TYPE_BOOL:
return &AST_TREE_BOOL_TYPE;
case PARSER_TOKEN_FUNCTION_CALL:
- return astTreeParseFunctionCall(parserNode, variables, variables_size);
+ return astTreeParseFunctionCall(parserNode, helper);
case PARSER_TOKEN_IDENTIFIER:
- return astTreeParseIdentifier(parserNode, variables, variables_size);
+ return astTreeParseIdentifier(parserNode, helper);
case PARSER_TOKEN_VALUE_U64:
return newAstTree(
AST_TREE_TOKEN_VALUE_U64,
@@ -698,35 +735,35 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeVariables **variables,
(void *)(AstTreeBool)(ParserNodeBoolMetadata)parserNode->metadata,
&AST_TREE_BOOL_TYPE, parserNode->str_begin, parserNode->str_end);
case PARSER_TOKEN_KEYWORD_PRINT_U64:
- return astTreeParsePrintU64(parserNode, variables, variables_size);
+ return astTreeParsePrintU64(parserNode, helper);
case PARSER_TOKEN_KEYWORD_RETURN:
- return astTreeParseReturn(parserNode, variables, variables_size);
+ return astTreeParseReturn(parserNode, helper);
case PARSER_TOKEN_OPERATOR_ASSIGN:
- return astTreeParseBinaryOperator(parserNode, variables, variables_size,
+ return astTreeParseBinaryOperator(parserNode, helper,
AST_TREE_TOKEN_OPERATOR_ASSIGN);
case PARSER_TOKEN_OPERATOR_SUM:
- return astTreeParseBinaryOperator(parserNode, variables, variables_size,
+ return astTreeParseBinaryOperator(parserNode, helper,
AST_TREE_TOKEN_OPERATOR_SUM);
case PARSER_TOKEN_OPERATOR_SUB:
- return astTreeParseBinaryOperator(parserNode, variables, variables_size,
+ return astTreeParseBinaryOperator(parserNode, helper,
AST_TREE_TOKEN_OPERATOR_SUB);
case PARSER_TOKEN_OPERATOR_MULTIPLY:
- return astTreeParseBinaryOperator(parserNode, variables, variables_size,
+ return astTreeParseBinaryOperator(parserNode, helper,
AST_TREE_TOKEN_OPERATOR_MULTIPLY);
case PARSER_TOKEN_OPERATOR_DIVIDE:
- return astTreeParseBinaryOperator(parserNode, variables, variables_size,
+ return astTreeParseBinaryOperator(parserNode, helper,
AST_TREE_TOKEN_OPERATOR_DIVIDE);
case PARSER_TOKEN_OPERATOR_MODULO:
- return astTreeParseBinaryOperator(parserNode, variables, variables_size,
+ return astTreeParseBinaryOperator(parserNode, helper,
AST_TREE_TOKEN_OPERATOR_MODULO);
case PARSER_TOKEN_OPERATOR_PLUS:
- return astTreeParseUnaryOperator(parserNode, variables, variables_size,
+ return astTreeParseUnaryOperator(parserNode, helper,
AST_TREE_TOKEN_OPERATOR_PLUS);
case PARSER_TOKEN_OPERATOR_MINUS:
- return astTreeParseUnaryOperator(parserNode, variables, variables_size,
+ return astTreeParseUnaryOperator(parserNode, helper,
AST_TREE_TOKEN_OPERATOR_MINUS);
case PARSER_TOKEN_VARIABLE:
- return astTreeParseVariable(parserNode, variables, variables_size);
+ return astTreeParseVariable(parserNode, helper);
case PARSER_TOKEN_CONSTANT:
case PARSER_TOKEN_SYMBOL_EOL:
case PARSER_TOKEN_SYMBOL_PARENTHESIS:
@@ -740,9 +777,7 @@ AstTree *astTreeParse(ParserNode *parserNode, AstTreeVariables **variables,
return NULL;
}
-AstTree *astTreeParseFunction(ParserNode *parserNode,
- AstTreeVariables **p_variables,
- size_t p_variables_size) {
+AstTree *astTreeParseFunction(ParserNode *parserNode, AstTreeHelper *p_helper) {
ParserNodeFunctionDefnitionMetadata *node_metadata = parserNode->metadata;
ParserNodeArray *node_arguments = node_metadata->arguments->metadata;
ParserNodeArray *body = node_metadata->body->metadata;
@@ -761,16 +796,23 @@ AstTree *astTreeParseFunction(ParserNode *parserNode,
function->arguments.data = a404m_malloc(0);
function->arguments.size = 0;
- size_t variables_size = p_variables_size + 2;
+ size_t variables_size = p_helper->variables_size + 2;
AstTreeVariables *variables[variables_size];
- for (size_t i = 0; i < p_variables_size; ++i) {
- variables[i] = p_variables[i];
+ for (size_t i = 0; i < p_helper->variables_size; ++i) {
+ variables[i] = p_helper->variables[i];
}
variables[variables_size - 2] = &function->arguments;
variables[variables_size - 1] = &scope.variables;
- if ((function->returnType = astTreeParse(node_metadata->returnType, variables,
- variables_size)) == NULL) {
+ AstTreeHelper helper = {
+ .variables = variables,
+ .variables_size = variables_size,
+ .variable = p_helper->variable,
+ .globalDeps = p_helper->globalDeps,
+ };
+
+ if ((function->returnType =
+ astTreeParse(node_metadata->returnType, &helper)) == NULL) {
goto RETURN_ERROR;
}
@@ -787,7 +829,7 @@ AstTree *astTreeParseFunction(ParserNode *parserNode,
goto RETURN_ERROR;
}
- AstTree *type = astTreeParse(arg_metadata->type, variables, variables_size);
+ AstTree *type = astTreeParse(arg_metadata->type, &helper);
if (type == NULL) {
goto RETURN_ERROR;
}
@@ -799,7 +841,7 @@ AstTree *astTreeParseFunction(ParserNode *parserNode,
argument->name_end = arg_metadata->name->str_end;
argument->isConst = false; // all arguments are not constants
- if (!pushVariable(&function->arguments, argument)) {
+ if (!pushVariable(&helper, &function->arguments, argument)) {
astTreeVariableDelete(argument);
goto RETURN_ERROR;
}
@@ -815,11 +857,11 @@ AstTree *astTreeParseFunction(ParserNode *parserNode,
ParserNode *node = (ParserNodeSingleChildMetadata *)eol->metadata;
if (node->token == PARSER_TOKEN_CONSTANT) {
- if (!astTreeParseConstant(node, variables, variables_size)) {
+ if (!astTreeParseConstant(node, &helper)) {
goto RETURN_ERROR;
}
} else {
- AstTree *tree = astTreeParse(node, variables, variables_size);
+ AstTree *tree = astTreeParse(node, &helper);
if (tree == NULL) {
goto RETURN_ERROR;
@@ -852,8 +894,7 @@ RETURN_ERROR:
}
AstTree *astTreeParseTypeFunction(ParserNode *parserNode,
- AstTreeVariables **variables,
- size_t variables_size) {
+ AstTreeHelper *helper) {
ParserNodeTypeFunctionMetadata *metadata = parserNode->metadata;
ParserNodeArray *node_arguments = metadata->arguments->metadata;
@@ -878,7 +919,7 @@ AstTree *astTreeParseTypeFunction(ParserNode *parserNode,
goto RETURN_ERROR;
}
- AstTree *type = astTreeParse(arg_metadata->type, variables, variables_size);
+ AstTree *type = astTreeParse(arg_metadata->type, helper);
if (type == NULL) {
goto RETURN_ERROR;
}
@@ -894,8 +935,8 @@ AstTree *astTreeParseTypeFunction(ParserNode *parserNode,
typeFunction->arguments_size += 1;
}
- if ((typeFunction->returnType = astTreeParse(metadata->returnType, variables,
- variables_size)) == NULL) {
+ if ((typeFunction->returnType = astTreeParse(metadata->returnType, helper)) ==
+ NULL) {
goto RETURN_ERROR;
}
@@ -908,11 +949,9 @@ RETURN_ERROR:
}
AstTree *astTreeParseFunctionCall(ParserNode *parserNode,
- AstTreeVariables **variables,
- size_t variables_size) {
+ AstTreeHelper *helper) {
ParserNodeFunctionCall *node_metadata = parserNode->metadata;
- AstTree *function =
- astTreeParse(node_metadata->function, variables, variables_size);
+ AstTree *function = astTreeParse(node_metadata->function, helper);
if (function == NULL) {
return NULL;
}
@@ -933,18 +972,16 @@ AstTree *astTreeParseFunctionCall(ParserNode *parserNode,
if (param->token == PARSER_TOKEN_SYMBOL_COMMA) {
param = (ParserNodeSingleChildMetadata *)param->metadata;
}
- metadata->parameters[i] = astTreeParse(param, variables, variables_size);
+ metadata->parameters[i] = astTreeParse(param, helper);
}
return newAstTree(AST_TREE_TOKEN_FUNCTION_CALL, metadata, NULL,
parserNode->str_begin, parserNode->str_end);
}
-AstTree *astTreeParseIdentifier(ParserNode *parserNode,
- AstTreeVariables **variables,
- size_t variables_size) {
- AstTreeVariable *var = getVariable(
- variables, variables_size, parserNode->str_begin, parserNode->str_end);
+AstTree *astTreeParseIdentifier(ParserNode *parserNode, AstTreeHelper *helper) {
+ AstTreeVariable *var =
+ getVariable(helper, parserNode->str_begin, parserNode->str_end);
if (var == NULL) {
printError(parserNode->str_begin, parserNode->str_end,
"Variable not found");
@@ -954,12 +991,10 @@ AstTree *astTreeParseIdentifier(ParserNode *parserNode,
parserNode->str_end);
}
-AstTree *astTreeParsePrintU64(ParserNode *parserNode,
- AstTreeVariables **variables,
- size_t variables_size) {
+AstTree *astTreeParsePrintU64(ParserNode *parserNode, AstTreeHelper *helper) {
ParserNodeSingleChildMetadata *node_metadata = parserNode->metadata;
- AstTree *operand = astTreeParse(node_metadata, variables, variables_size);
+ AstTree *operand = astTreeParse(node_metadata, helper);
if (operand == NULL) {
return NULL;
}
@@ -969,16 +1004,14 @@ AstTree *astTreeParsePrintU64(ParserNode *parserNode,
parserNode->str_end);
}
-AstTree *astTreeParseReturn(ParserNode *parserNode,
- AstTreeVariables **variables,
- size_t variables_size) {
+AstTree *astTreeParseReturn(ParserNode *parserNode, AstTreeHelper *helper) {
ParserNodeReturnMetadata *node_metadata = parserNode->metadata;
AstTree *value;
if (node_metadata->value == NULL) {
value = NULL;
} else {
- value = astTreeParse(node_metadata->value, variables, variables_size);
+ value = astTreeParse(node_metadata->value, helper);
if (value == NULL) {
return NULL;
}
@@ -992,16 +1025,14 @@ AstTree *astTreeParseReturn(ParserNode *parserNode,
}
AstTree *astTreeParseBinaryOperator(ParserNode *parserNode,
- AstTreeVariables **variables,
- size_t variables_size, AstTreeToken token) {
+ AstTreeHelper *helper, AstTreeToken token) {
ParserNodeInfixMetadata *node_metadata = parserNode->metadata;
- AstTree *left = astTreeParse(node_metadata->left, variables, variables_size);
+ AstTree *left = astTreeParse(node_metadata->left, helper);
if (left == NULL) {
return NULL;
}
- AstTree *right =
- astTreeParse(node_metadata->right, variables, variables_size);
+ AstTree *right = astTreeParse(node_metadata->right, helper);
if (right == NULL) {
return NULL;
}
@@ -1019,12 +1050,10 @@ AstTree *astTreeParseBinaryOperator(ParserNode *parserNode,
}
AstTree *astTreeParseUnaryOperator(ParserNode *parserNode,
- AstTreeVariables **variables,
- size_t variables_size, AstTreeToken token) {
+ AstTreeHelper *helper, AstTreeToken token) {
ParserNodeSingleChildMetadata *node_metadata = parserNode->metadata;
- AstTreeSingleChild *metadata =
- astTreeParse(node_metadata, variables, variables_size);
+ AstTreeSingleChild *metadata = astTreeParse(node_metadata, helper);
if (metadata == NULL) {
return NULL;
}
@@ -1033,8 +1062,7 @@ AstTree *astTreeParseUnaryOperator(ParserNode *parserNode,
parserNode->str_end);
}
-bool astTreeParseConstant(ParserNode *parserNode, AstTreeVariables **variables,
- size_t variables_size) {
+bool astTreeParseConstant(ParserNode *parserNode, AstTreeHelper *helper) {
ParserNodeVariableMetadata *node_metadata = parserNode->metadata;
if (node_metadata->value == NULL ||
@@ -1043,8 +1071,7 @@ bool astTreeParseConstant(ParserNode *parserNode, AstTreeVariables **variables,
return NULL;
}
- AstTree *value =
- astTreeParse(node_metadata->value, variables, variables_size);
+ AstTree *value = astTreeParse(node_metadata->value, helper);
if (value == NULL) {
goto RETURN_ERROR;
}
@@ -1053,7 +1080,7 @@ bool astTreeParseConstant(ParserNode *parserNode, AstTreeVariables **variables,
if (node_metadata->type == NULL) {
type = NULL;
} else {
- type = astTreeParse(node_metadata->type, variables, variables_size);
+ type = astTreeParse(node_metadata->type, helper);
if (type == NULL) {
goto RETURN_ERROR;
}
@@ -1066,7 +1093,8 @@ bool astTreeParseConstant(ParserNode *parserNode, AstTreeVariables **variables,
variable->name_end = node_metadata->name->str_end;
variable->isConst = true;
- if (!pushVariable(variables[variables_size - 1], variable)) {
+ if (!pushVariable(helper, helper->variables[helper->variables_size - 1],
+ variable)) {
astTreeVariableDelete(variable);
goto RETURN_ERROR;
}
@@ -1076,9 +1104,7 @@ RETURN_ERROR:
return false;
}
-AstTree *astTreeParseVariable(ParserNode *parserNode,
- AstTreeVariables **variables,
- size_t variables_size) {
+AstTree *astTreeParseVariable(ParserNode *parserNode, AstTreeHelper *helper) {
ParserNodeVariableMetadata *node_metadata = parserNode->metadata;
if (node_metadata->value == NULL ||
@@ -1087,8 +1113,7 @@ AstTree *astTreeParseVariable(ParserNode *parserNode,
return NULL;
}
- AstTree *value =
- astTreeParse(node_metadata->value, variables, variables_size);
+ AstTree *value = astTreeParse(node_metadata->value, helper);
if (value == NULL) {
goto RETURN_ERROR;
}
@@ -1097,7 +1122,7 @@ AstTree *astTreeParseVariable(ParserNode *parserNode,
if (node_metadata->type == NULL) {
type = NULL;
} else {
- type = astTreeParse(node_metadata->type, variables, variables_size);
+ type = astTreeParse(node_metadata->type, helper);
if (type == NULL) {
goto RETURN_ERROR;
}
@@ -1110,7 +1135,8 @@ AstTree *astTreeParseVariable(ParserNode *parserNode,
variable->name_end = node_metadata->name->str_end;
variable->isConst = false;
- if (!pushVariable(variables[variables_size - 1], variable)) {
+ if (!pushVariable(helper, helper->variables[helper->variables_size - 1],
+ variable)) {
astTreeVariableDelete(variable);
goto RETURN_ERROR;
}
@@ -1313,7 +1339,77 @@ bool typeIsEqual(const AstTree *type0, const AstTree *type1) {
UNREACHABLE;
}
-bool setAllTypesRoot(AstTreeRoot *root) {
+bool isCircularDependencies(AstTreeHelper *helper, AstTreeVariable *variable,
+ AstTree *tree) {
+ switch (tree->token) {
+ case AST_TREE_TOKEN_TYPE_TYPE:
+ case AST_TREE_TOKEN_TYPE_FUNCTION:
+ case AST_TREE_TOKEN_TYPE_VOID:
+ case AST_TREE_TOKEN_TYPE_U64:
+ case AST_TREE_TOKEN_TYPE_BOOL:
+ case AST_TREE_TOKEN_VALUE_VOID:
+ case AST_TREE_TOKEN_VALUE_U64:
+ case AST_TREE_TOKEN_VALUE_BOOL:
+ return false;
+ case AST_TREE_TOKEN_OPERATOR_PLUS:
+ case AST_TREE_TOKEN_OPERATOR_MINUS: {
+ AstTreeSingleChild *metadata = tree->metadata;
+ return isCircularDependencies(helper, variable, metadata);
+ }
+ 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: {
+ AstTreeInfix *metadata = tree->metadata;
+ return isCircularDependencies(helper, variable, &metadata->left) ||
+ isCircularDependencies(helper, variable, &metadata->right);
+ }
+ case AST_TREE_TOKEN_FUNCTION_CALL: {
+ AstTreeFunctionCall *metadata = tree->metadata;
+ for (size_t i = 0; i < metadata->parameters_size; ++i) {
+ if (isCircularDependencies(helper, variable, metadata->parameters[i])) {
+ return true;
+ }
+ }
+ return isCircularDependencies(helper, variable, metadata->function);
+ }
+ 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) {
+ if (helper->globalDeps[index].data[i] == variable) {
+ return true;
+ }
+ }
+ break;
+ }
+ }
+ return false;
+ }
+ case AST_TREE_TOKEN_FUNCTION: {
+ return false;
+ }
+ case AST_TREE_TOKEN_NONE:
+ case AST_TREE_TOKEN_KEYWORD_PRINT_U64:
+ case AST_TREE_TOKEN_KEYWORD_RETURN:
+ case AST_TREE_TOKEN_VARIABLE_DEFINE:
+ }
+ UNREACHABLE;
+}
+
+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, variable->value)) {
+ printError(variable->name_begin, variable->name_end,
+ "Circular dependecies");
+ return false;
+ }
+ }
+
for (size_t i = 0; i < root->variables.size; ++i) {
AstTreeVariable *variable = root->variables.data[i];
if (!setTypesAstVariable(variable)) {
diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h
index 00e8c75..579d919 100644
--- a/src/compiler/ast-tree.h
+++ b/src/compiler/ast-tree.h
@@ -106,6 +106,13 @@ typedef struct AstTreeReturn {
AstTree *value;
} AstTreeReturn;
+typedef struct AstTreeHelper {
+ AstTreeVariables **variables;
+ size_t variables_size;
+ AstTreeVariable *variable;
+ AstTreeVariables *globalDeps;
+} AstTreeHelper;
+
void astTreePrint(const AstTree *tree, int indent);
void astTreeRootPrint(const AstTreeRoot *root);
@@ -122,58 +129,43 @@ AstTreeVariables copyAstTreeVariables(AstTreeVariables variables);
AstTreeRoot *makeAstTree(ParserNode *parsedRoot);
-bool pushVariable(AstTreeVariables *variables, AstTreeVariable *variable);
-AstTreeVariable *getVariable(AstTreeVariables **variables,
- size_t variables_size, char *name_begin,
+bool pushVariable(AstTreeHelper *helper,AstTreeVariables *variables, AstTreeVariable *variable);
+AstTreeVariable *getVariable(AstTreeHelper *helper, char *name_begin,
char *name_end);
-AstTree *astTreeParse(ParserNode *parserNode, AstTreeVariables **variables,
- size_t variables_size);
+AstTree *astTreeParse(ParserNode *parserNode, AstTreeHelper *helper);
-AstTree *astTreeParseFunction(ParserNode *parserNode,
- AstTreeVariables **variables,
- size_t variables_size);
+AstTree *astTreeParseFunction(ParserNode *parserNode, AstTreeHelper *helper);
AstTree *astTreeParseTypeFunction(ParserNode *parserNode,
- AstTreeVariables **variables,
- size_t variables_size);
+ AstTreeHelper *helper);
AstTree *astTreeParseFunctionCall(ParserNode *parserNode,
- AstTreeVariables **variables,
- size_t variables_size);
+ AstTreeHelper *helper);
-AstTree *astTreeParseIdentifier(ParserNode *parserNode,
- AstTreeVariables **variables,
- size_t variables_size);
+AstTree *astTreeParseIdentifier(ParserNode *parserNode, AstTreeHelper *helper);
-AstTree *astTreeParsePrintU64(ParserNode *parserNode,
- AstTreeVariables **variables,
- size_t variables_size);
-AstTree *astTreeParseReturn(ParserNode *parserNode,
- AstTreeVariables **variables,
- size_t variables_size);
+AstTree *astTreeParsePrintU64(ParserNode *parserNode, AstTreeHelper *helper);
+AstTree *astTreeParseReturn(ParserNode *parserNode, AstTreeHelper *helper);
AstTree *astTreeParseBinaryOperator(ParserNode *parserNode,
- AstTreeVariables **variables,
- size_t variables_size, AstTreeToken token);
+ AstTreeHelper *helper, AstTreeToken token);
AstTree *astTreeParseUnaryOperator(ParserNode *parserNode,
- AstTreeVariables **variables,
- size_t variables_size, AstTreeToken token);
+ AstTreeHelper *helper, AstTreeToken token);
-bool astTreeParseConstant(ParserNode *parserNode, AstTreeVariables **variables,
- size_t variables_size);
+bool astTreeParseConstant(ParserNode *parserNode, AstTreeHelper *helper);
-AstTree *astTreeParseVariable(ParserNode *parserNode,
- AstTreeVariables **variables,
- size_t variables_size);
+AstTree *astTreeParseVariable(ParserNode *parserNode, AstTreeHelper *helper);
AstTreeFunction *getFunction(AstTree *value);
bool isConst(AstTree *value);
AstTree *makeTypeOf(AstTree *value);
bool typeIsEqual(const AstTree *type0, const AstTree *type1);
-bool setAllTypesRoot(AstTreeRoot *root);
+bool isCircularDependencies(AstTreeHelper *helper,AstTreeVariable *variable,AstTree *tree);
+
+bool setAllTypesRoot(AstTreeRoot *root,AstTreeHelper *helper);
bool setAllTypes(AstTree *tree, AstTreeFunction *function);
bool setTypesFunction(AstTree *tree);
bool setTypesPrintU64(AstTree *tree);
diff --git a/src/compiler/parser.c b/src/compiler/parser.c
index 24b4984..9cdf141 100644
--- a/src/compiler/parser.c
+++ b/src/compiler/parser.c
@@ -1049,7 +1049,6 @@ ParserNode *parserBinaryOrLeftOperator(LexerNode *node, LexerNode *begin,
return NULL;
}
- printLog("here");
return right->parent = node->parserNode =
newParserNode(token, node->str_begin, right->str_end,
(ParserNodeSingleChildMetadata *)right, parent);