summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/ast-tree.c79
-rw-r--r--src/compiler/ast-tree.h7
-rw-r--r--src/compiler/parser.c7
3 files changed, 76 insertions, 17 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index 22b1103..aee480d 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -1898,6 +1898,7 @@ bool isConst(AstTree *tree, AstTreeHelper *helper) {
case AST_TREE_TOKEN_VALUE_FLOAT:
case AST_TREE_TOKEN_VALUE_BOOL:
case AST_TREE_TOKEN_KEYWORD_COMPTIME:
+ case AST_TREE_TOKEN_SCOPE:
return true;
case AST_TREE_TOKEN_KEYWORD_IF: {
AstTreeIf *metadata = tree->metadata;
@@ -1935,7 +1936,6 @@ bool isConst(AstTree *tree, AstTreeHelper *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_SCOPE:
return false;
case AST_TREE_TOKEN_VARIABLE: {
AstTreeVariable *metadata = tree->metadata;
@@ -2157,7 +2157,8 @@ AstTree *getValue(AstTree *tree, AstTreeSetTypesHelper helper) {
case AST_TREE_TOKEN_KEYWORD_WHILE:
case AST_TREE_TOKEN_KEYWORD_COMPTIME:
case AST_TREE_TOKEN_SCOPE: {
- AstTree *value = runExpression(tree, helper.pages);
+ bool shouldRet = false;
+ AstTree *value = runExpression(tree, helper.pages, &shouldRet);
if (value == NULL) {
printError(tree->str_begin, tree->str_end, "Unknown error");
}
@@ -2174,8 +2175,20 @@ AstTree *getValue(AstTree *tree, AstTreeSetTypesHelper helper) {
UNREACHABLE;
}
-bool isCircularDependencies(AstTreeHelper *helper, AstTreeVariable *variable,
- AstTree *tree) {
+bool isCircularDependencies(AstTreeHelper *helper, AstTreeVariable *variable) {
+ AstTreeVariables checkedVariables = {
+ .data = a404m_malloc(0),
+ .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_SCOPE:
case AST_TREE_TOKEN_TYPE_TYPE:
@@ -2203,7 +2216,8 @@ bool isCircularDependencies(AstTreeHelper *helper, AstTreeVariable *variable,
case AST_TREE_TOKEN_OPERATOR_PLUS:
case AST_TREE_TOKEN_OPERATOR_MINUS: {
AstTreeSingleChild *metadata = tree->metadata;
- return isCircularDependencies(helper, variable, metadata);
+ return isCircularDependenciesBack(helper, variable, metadata,
+ checkedVariables);
}
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
case AST_TREE_TOKEN_OPERATOR_SUM:
@@ -2218,24 +2232,31 @@ bool isCircularDependencies(AstTreeHelper *helper, AstTreeVariable *variable,
case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL:
case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: {
AstTreeInfix *metadata = tree->metadata;
- return isCircularDependencies(helper, variable, &metadata->left) ||
- isCircularDependencies(helper, variable, &metadata->right);
+ 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 (isCircularDependencies(helper, variable, metadata->parameters[i])) {
+ if (isCircularDependenciesBack(helper, variable, metadata->parameters[i],
+ checkedVariables)) {
return true;
}
}
- return isCircularDependencies(helper, variable, metadata->function);
+ 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) {
- if (helper->globalDeps[index].data[i] == variable) {
+ AstTreeVariable *currentVariable = helper->globalDeps[index].data[i];
+ if (currentVariable == variable ||
+ isCircularDependenciesVariable(helper, variable, currentVariable,
+ checkedVariables)) {
return true;
}
}
@@ -2257,10 +2278,46 @@ bool isCircularDependencies(AstTreeHelper *helper, AstTreeVariable *variable,
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, variable->value)) {
+ if (isCircularDependencies(helper, variable)) {
printError(variable->name_begin, variable->name_end,
"Circular dependecies");
return false;
diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h
index cc66ede..19ff9e9 100644
--- a/src/compiler/ast-tree.h
+++ b/src/compiler/ast-tree.h
@@ -224,8 +224,11 @@ AstTree *makeTypeOf(AstTree *value);
bool typeIsEqual(const AstTree *type0, const AstTree *type1);
AstTree *getValue(AstTree *tree, AstTreeSetTypesHelper helper);
-bool isCircularDependencies(AstTreeHelper *helper, AstTreeVariable *variable,
- 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,
diff --git a/src/compiler/parser.c b/src/compiler/parser.c
index 9d95c1d..d816ec9 100644
--- a/src/compiler/parser.c
+++ b/src/compiler/parser.c
@@ -136,7 +136,7 @@ static constexpr ParserOrder PARSER_ORDER[] = {
LEXER_TOKEN_SYMBOL_MODULO_ASSIGN, ),
},
{
- .ltr = true,
+ .ltr = false,
ORDER_ARRAY(LEXER_TOKEN_KEYWORD_RETURN, LEXER_TOKEN_KEYWORD_PRINT_U64,
LEXER_TOKEN_KEYWORD_COMPTIME, ),
},
@@ -145,10 +145,9 @@ static constexpr ParserOrder PARSER_ORDER[] = {
ORDER_ARRAY(LEXER_TOKEN_SYMBOL_EOL, LEXER_TOKEN_SYMBOL_COMMA, ),
},
{
- .ltr = true,
- ORDER_ARRAY(LEXER_TOKEN_KEYWORD_IF, LEXER_TOKEN_KEYWORD_WHILE, ),
+ .ltr = false,
+ ORDER_ARRAY(LEXER_TOKEN_KEYWORD_IF,LEXER_TOKEN_KEYWORD_WHILE, ),
},
-
};
static constexpr size_t PARSER_ORDER_SIZE =