aboutsummaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2025-05-16 15:09:41 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2025-05-16 16:24:06 +0330
commit0375ec4478101337ff1a30f583262a38055f9103 (patch)
treed50b9580b2e41a80c2cd1ab3af7714e4cf771e21 /src/compiler
parent42eb5e5d3f10c3a9187dcf8edd7c023a3ea10dcd (diff)
break now works
removed unused helper in ast to make code cleaner now you can't define variables everywhere
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/ast-tree.c406
-rw-r--r--src/compiler/ast-tree.h70
-rw-r--r--src/compiler/parser.c8
3 files changed, 255 insertions, 229 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index 1d0613b..e0c9c71 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -150,6 +150,7 @@ const char *AST_TREE_TOKEN_STRINGS[] = {
"AST_TREE_TOKEN_KEYWORD_PUTC",
"AST_TREE_TOKEN_KEYWORD_RETURN",
+ "AST_TREE_TOKEN_KEYWORD_BREAK",
"AST_TREE_TOKEN_KEYWORD_IF",
"AST_TREE_TOKEN_KEYWORD_WHILE",
"AST_TREE_TOKEN_KEYWORD_COMPTIME",
@@ -311,6 +312,7 @@ void astTreePrint(const AstTree *tree, int indent) {
case AST_TREE_TOKEN_VALUE_NULL:
case AST_TREE_TOKEN_VALUE_UNDEFINED:
case AST_TREE_TOKEN_VARIABLE_DEFINE:
+ case AST_TREE_TOKEN_KEYWORD_BREAK:
goto RETURN_SUCCESS;
case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT:
case AST_TREE_TOKEN_OPERATOR_PLUS:
@@ -592,6 +594,9 @@ void astTreePrint(const AstTree *tree, int indent) {
}
goto RETURN_SUCCESS;
case AST_TREE_TOKEN_NONE:
+ case AST_TREE_TOKEN_VALUE_NAMESPACE:
+ case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER:
+ case AST_TREE_TOKEN_SHAPE_SHIFTER_ELEMENT:
}
UNREACHABLE;
@@ -729,6 +734,7 @@ void astTreeDestroy(AstTree tree) {
case AST_TREE_TOKEN_VALUE_UNDEFINED:
case AST_TREE_TOKEN_VALUE_VOID:
case AST_TREE_TOKEN_VARIABLE_DEFINE:
+ case AST_TREE_TOKEN_KEYWORD_BREAK:
return;
case AST_TREE_TOKEN_VALUE_NAMESPACE: {
AstTreeNamespace *metadata = tree.metadata;
@@ -1013,6 +1019,7 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[],
return tree;
case AST_TREE_TOKEN_VALUE_NULL:
case AST_TREE_TOKEN_VALUE_UNDEFINED:
+ case AST_TREE_TOKEN_KEYWORD_BREAK:
case AST_TREE_TOKEN_BUILTIN_CAST:
case AST_TREE_TOKEN_BUILTIN_TYPE_OF:
case AST_TREE_TOKEN_BUILTIN_IMPORT:
@@ -1619,6 +1626,8 @@ AstTreeRoot *getAstTreeRoot(char *filePath, AstTreeRoots *roots
.dependencies.size = 0,
.variables = root->variables,
.root = root,
+ .loops = NULL,
+ .loops_size = 0,
};
if (!setAllTypes(tree, helper, NULL, NULL)) {
goto RETURN_ERROR;
@@ -1694,6 +1703,8 @@ AstTreeRoot *getAstTreeRoot(char *filePath, AstTreeRoots *roots
.dependencies.size = 0,
.variables = root->variables,
.root = root,
+ .loops = NULL,
+ .loops_size = 0,
};
if (!setAllTypes(tree, helper, NULL, NULL)) {
goto RETURN_ERROR;
@@ -1787,14 +1798,6 @@ AstTreeRoot *makeAstRoot(const ParserNode *parsedRoot, char *filePath) {
root->imports_size = 0;
root->filePath = filePath;
- 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) {
const ParserNode *eol = nodes->data[i];
if (eol->token != PARSER_TOKEN_SYMBOL_EOL) {
@@ -1822,7 +1825,7 @@ AstTreeRoot *makeAstRoot(const ParserNode *parsedRoot, char *filePath) {
goto RETURN_ERROR;
}
- if (!pushVariable(&helper, &root->variables, variable)) {
+ if (!pushVariable(&root->variables, variable)) {
astTreeVariableDelete(variable);
goto RETURN_ERROR;
}
@@ -1851,12 +1854,12 @@ AstTreeRoot *makeAstRoot(const ParserNode *parsedRoot, char *filePath) {
const ParserNode *node = (ParserNodeSingleChildMetadata *)eol->metadata;
AstTree *tree;
if (node->token == PARSER_TOKEN_KEYWORD_COMPTIME) {
- tree = astTreeParse(node, &helper);
+ tree = astTreeParse(node);
if (tree == NULL) {
goto RETURN_ERROR;
}
} else if (node->token == PARSER_TOKEN_FUNCTION_CALL) {
- tree = astTreeParse(node, &helper);
+ tree = astTreeParse(node);
if (tree == NULL) {
goto RETURN_ERROR;
}
@@ -1980,6 +1983,7 @@ AstTreeRoot *makeAstRoot(const ParserNode *parsedRoot, char *filePath) {
case PARSER_TOKEN_ROOT:
case PARSER_TOKEN_KEYWORD_PUTC:
case PARSER_TOKEN_KEYWORD_RETURN:
+ case PARSER_TOKEN_KEYWORD_BREAK:
case PARSER_TOKEN_CONSTANT:
case PARSER_TOKEN_VARIABLE:
case PARSER_TOKEN_SYMBOL_EOL:
@@ -1996,14 +2000,14 @@ AstTreeRoot *makeAstRoot(const ParserNode *parsedRoot, char *filePath) {
AFTER_SWITCH:
- AstTree *value = astTreeParse(node_metadata->value, &helper);
+ AstTree *value = astTreeParse(node_metadata->value);
if (value == NULL) {
goto RETURN_ERROR;
}
AstTree *type;
if (node_metadata->type != NULL) {
- type = astTreeParse(node_metadata->type, &helper);
+ type = astTreeParse(node_metadata->type);
if (type == NULL) {
goto RETURN_ERROR;
}
@@ -2039,22 +2043,7 @@ RETURN_ERROR:
return NULL;
}
-bool pushVariable(AstTreeHelper *helper, AstTreeVariables *variables,
- AstTreeVariable *variable) {
- if (helper->variables[0] != variables) {
- for (size_t j = 0; j < variables->size; ++j) {
- const char *var_begin = variables->data[j]->name_begin;
- const char *var_end = variables->data[j]->name_end;
-
- if (variable->name_end - variable->name_begin == var_end - var_begin &&
- strnEquals(var_begin, variable->name_begin,
- variable->name_end - variable->name_begin)) {
- printError(variable->name_begin, variable->name_end, "Variable exists");
- return false;
- }
- }
- }
-
+bool pushVariable(AstTreeVariables *variables, AstTreeVariable *variable) {
size_t variables_size =
a404m_malloc_usable_size(variables->data) / sizeof(*variables->data);
if (variables_size == variables->size) {
@@ -2067,10 +2056,10 @@ bool pushVariable(AstTreeHelper *helper, AstTreeVariables *variables,
return true;
}
-AstTree *astTreeParse(const ParserNode *parserNode, AstTreeHelper *helper) {
+AstTree *astTreeParse(const ParserNode *parserNode) {
switch (parserNode->token) {
case PARSER_TOKEN_FUNCTION_DEFINITION:
- return astTreeParseFunction(parserNode, helper);
+ return astTreeParseFunction(parserNode);
case PARSER_TOKEN_BUILTIN_CAST:
return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_BUILTIN_CAST);
case PARSER_TOKEN_BUILTIN_TYPE_OF:
@@ -2112,7 +2101,7 @@ AstTree *astTreeParse(const ParserNode *parserNode, AstTreeHelper *helper) {
case PARSER_TOKEN_TYPE_TYPE:
return &AST_TREE_TYPE_TYPE;
case PARSER_TOKEN_TYPE_FUNCTION:
- return astTreeParseTypeFunction(parserNode, helper);
+ return astTreeParseTypeFunction(parserNode);
case PARSER_TOKEN_TYPE_VOID:
return &AST_TREE_VOID_TYPE;
case PARSER_TOKEN_TYPE_I8:
@@ -2150,9 +2139,9 @@ AstTree *astTreeParse(const ParserNode *parserNode, AstTreeHelper *helper) {
case PARSER_TOKEN_TYPE_BOOL:
return &AST_TREE_BOOL_TYPE;
case PARSER_TOKEN_FUNCTION_CALL:
- return astTreeParseFunctionCall(parserNode, helper);
+ return astTreeParseFunctionCall(parserNode);
case PARSER_TOKEN_IDENTIFIER:
- return astTreeParseIdentifier(parserNode, helper);
+ return astTreeParseIdentifier(parserNode);
case PARSER_TOKEN_VALUE_INT:
return astTreeParseValue(parserNode, AST_TREE_TOKEN_VALUE_INT,
sizeof(AstTreeInt), NULL);
@@ -2166,115 +2155,111 @@ AstTree *astTreeParse(const ParserNode *parserNode, AstTreeHelper *helper) {
return astTreeParseValue(parserNode, AST_TREE_TOKEN_VALUE_INT,
sizeof(AstTreeInt), &AST_TREE_U8_TYPE);
case PARSER_TOKEN_VALUE_STRING:
- return astTreeParseString(parserNode, helper);
+ return astTreeParseString(parserNode);
case PARSER_TOKEN_KEYWORD_NULL:
return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_VALUE_NULL);
case PARSER_TOKEN_KEYWORD_UNDEFINED:
return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_VALUE_UNDEFINED);
+ case PARSER_TOKEN_KEYWORD_BREAK:
+ return astTreeParseKeyword(parserNode, AST_TREE_TOKEN_KEYWORD_BREAK);
case PARSER_TOKEN_KEYWORD_PUTC:
- return astTreeParsePutc(parserNode, helper);
+ return astTreeParsePutc(parserNode);
case PARSER_TOKEN_KEYWORD_RETURN:
- return astTreeParseReturn(parserNode, helper);
+ return astTreeParseReturn(parserNode);
case PARSER_TOKEN_OPERATOR_ASSIGN:
- return astTreeParseBinaryOperator(parserNode, helper,
+ return astTreeParseBinaryOperator(parserNode,
AST_TREE_TOKEN_OPERATOR_ASSIGN);
case PARSER_TOKEN_OPERATOR_SUM_ASSIGN:
- return astTreeParseOperateAssignOperator(parserNode, helper,
+ return astTreeParseOperateAssignOperator(parserNode,
AST_TREE_TOKEN_OPERATOR_SUM);
case PARSER_TOKEN_OPERATOR_SUB_ASSIGN:
- return astTreeParseOperateAssignOperator(parserNode, helper,
+ return astTreeParseOperateAssignOperator(parserNode,
AST_TREE_TOKEN_OPERATOR_SUB);
case PARSER_TOKEN_OPERATOR_MULTIPLY_ASSIGN:
- return astTreeParseOperateAssignOperator(parserNode, helper,
+ return astTreeParseOperateAssignOperator(parserNode,
AST_TREE_TOKEN_OPERATOR_MULTIPLY);
case PARSER_TOKEN_OPERATOR_DIVIDE_ASSIGN:
- return astTreeParseOperateAssignOperator(parserNode, helper,
+ return astTreeParseOperateAssignOperator(parserNode,
AST_TREE_TOKEN_OPERATOR_DIVIDE);
case PARSER_TOKEN_OPERATOR_MODULO_ASSIGN:
- return astTreeParseOperateAssignOperator(parserNode, helper,
+ return astTreeParseOperateAssignOperator(parserNode,
AST_TREE_TOKEN_OPERATOR_MODULO);
case PARSER_TOKEN_OPERATOR_SUM:
- return astTreeParseBinaryOperator(parserNode, helper,
- AST_TREE_TOKEN_OPERATOR_SUM);
+ return astTreeParseBinaryOperator(parserNode, AST_TREE_TOKEN_OPERATOR_SUM);
case PARSER_TOKEN_OPERATOR_SUB:
- return astTreeParseBinaryOperator(parserNode, helper,
- AST_TREE_TOKEN_OPERATOR_SUB);
+ return astTreeParseBinaryOperator(parserNode, AST_TREE_TOKEN_OPERATOR_SUB);
case PARSER_TOKEN_OPERATOR_MULTIPLY:
- return astTreeParseBinaryOperator(parserNode, helper,
+ return astTreeParseBinaryOperator(parserNode,
AST_TREE_TOKEN_OPERATOR_MULTIPLY);
case PARSER_TOKEN_OPERATOR_DIVIDE:
- return astTreeParseBinaryOperator(parserNode, helper,
+ return astTreeParseBinaryOperator(parserNode,
AST_TREE_TOKEN_OPERATOR_DIVIDE);
case PARSER_TOKEN_OPERATOR_MODULO:
- return astTreeParseBinaryOperator(parserNode, helper,
+ return astTreeParseBinaryOperator(parserNode,
AST_TREE_TOKEN_OPERATOR_MODULO);
case PARSER_TOKEN_OPERATOR_EQUAL:
- return astTreeParseBinaryOperator(parserNode, helper,
+ return astTreeParseBinaryOperator(parserNode,
AST_TREE_TOKEN_OPERATOR_EQUAL);
case PARSER_TOKEN_OPERATOR_NOT_EQUAL:
- return astTreeParseBinaryOperator(parserNode, helper,
+ return astTreeParseBinaryOperator(parserNode,
AST_TREE_TOKEN_OPERATOR_NOT_EQUAL);
case PARSER_TOKEN_OPERATOR_GREATER:
- return astTreeParseBinaryOperator(parserNode, helper,
+ return astTreeParseBinaryOperator(parserNode,
AST_TREE_TOKEN_OPERATOR_GREATER);
case PARSER_TOKEN_OPERATOR_SMALLER:
- return astTreeParseBinaryOperator(parserNode, helper,
+ return astTreeParseBinaryOperator(parserNode,
AST_TREE_TOKEN_OPERATOR_SMALLER);
case PARSER_TOKEN_OPERATOR_GREATER_OR_EQUAL:
- return astTreeParseBinaryOperator(parserNode, helper,
+ return astTreeParseBinaryOperator(parserNode,
AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL);
case PARSER_TOKEN_OPERATOR_SMALLER_OR_EQUAL:
- return astTreeParseBinaryOperator(parserNode, helper,
+ return astTreeParseBinaryOperator(parserNode,
AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL);
case PARSER_TOKEN_OPERATOR_ACCESS:
- return astTreeParseAccessOperator(parserNode, helper,
+ return astTreeParseAccessOperator(parserNode,
AST_TREE_TOKEN_OPERATOR_ACCESS);
case PARSER_TOKEN_OPERATOR_LOGICAL_AND:
- return astTreeParseBinaryOperator(parserNode, helper,
+ return astTreeParseBinaryOperator(parserNode,
AST_TREE_TOKEN_OPERATOR_LOGICAL_AND);
case PARSER_TOKEN_OPERATOR_LOGICAL_OR:
- return astTreeParseBinaryOperator(parserNode, helper,
+ return astTreeParseBinaryOperator(parserNode,
AST_TREE_TOKEN_OPERATOR_LOGICAL_OR);
case PARSER_TOKEN_OPERATOR_LOGICAL_NOT:
- return astTreeParseUnaryOperator(parserNode, helper,
+ return astTreeParseUnaryOperator(parserNode,
AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT);
case PARSER_TOKEN_OPERATOR_PLUS:
- return astTreeParseUnaryOperator(parserNode, helper,
- AST_TREE_TOKEN_OPERATOR_PLUS);
+ return astTreeParseUnaryOperator(parserNode, AST_TREE_TOKEN_OPERATOR_PLUS);
case PARSER_TOKEN_OPERATOR_MINUS:
- return astTreeParseUnaryOperator(parserNode, helper,
- AST_TREE_TOKEN_OPERATOR_MINUS);
+ return astTreeParseUnaryOperator(parserNode, AST_TREE_TOKEN_OPERATOR_MINUS);
case PARSER_TOKEN_OPERATOR_POINTER:
- return astTreeParseUnaryOperator(parserNode, helper,
+ return astTreeParseUnaryOperator(parserNode,
AST_TREE_TOKEN_OPERATOR_POINTER);
case PARSER_TOKEN_OPERATOR_ADDRESS:
return astTreeParseUnaryOperatorSingleChild(
- parserNode, helper, AST_TREE_TOKEN_OPERATOR_ADDRESS);
+ parserNode, AST_TREE_TOKEN_OPERATOR_ADDRESS);
case PARSER_TOKEN_OPERATOR_DEREFERENCE:
return astTreeParseUnaryOperatorSingleChild(
- parserNode, helper, AST_TREE_TOKEN_OPERATOR_DEREFERENCE);
- case PARSER_TOKEN_VARIABLE:
- return astTreeParseVariable(parserNode, helper);
+ parserNode, AST_TREE_TOKEN_OPERATOR_DEREFERENCE);
case PARSER_TOKEN_KEYWORD_IF:
- return astTreeParseIf(parserNode, helper);
+ return astTreeParseIf(parserNode);
case PARSER_TOKEN_KEYWORD_WHILE:
- return astTreeParseWhile(parserNode, helper);
+ return astTreeParseWhile(parserNode);
case PARSER_TOKEN_KEYWORD_COMPTIME:
- return astTreeParseComptime(parserNode, helper);
+ return astTreeParseComptime(parserNode);
case PARSER_TOKEN_SYMBOL_EOL:
- return astTreeParse((ParserNodeSingleChildMetadata *)parserNode->metadata,
- helper);
+ return astTreeParse((ParserNodeSingleChildMetadata *)parserNode->metadata);
case PARSER_TOKEN_SYMBOL_CURLY_BRACKET:
- return astTreeParseCurlyBracket(parserNode, helper);
+ return astTreeParseCurlyBracket(parserNode);
case PARSER_TOKEN_SYMBOL_PARENTHESIS:
- return astTreeParseParenthesis(parserNode, helper);
+ return astTreeParseParenthesis(parserNode);
case PARSER_TOKEN_KEYWORD_STRUCT:
- return astTreeParseStruct(parserNode, helper);
+ return astTreeParseStruct(parserNode);
case PARSER_TOKEN_SYMBOL_BRACKET_LEFT:
- return astTreeParseBracket(parserNode, helper, AST_TREE_TOKEN_TYPE_ARRAY);
+ return astTreeParseBracket(parserNode, AST_TREE_TOKEN_TYPE_ARRAY);
case PARSER_TOKEN_SYMBOL_BRACKET_RIGHT:
- return astTreeParseBracket(parserNode, helper,
+ return astTreeParseBracket(parserNode,
AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS);
+ case PARSER_TOKEN_VARIABLE:
case PARSER_TOKEN_CONSTANT:
case PARSER_TOKEN_SYMBOL_COMMA:
case PARSER_TOKEN_NONE:
@@ -2285,8 +2270,7 @@ AstTree *astTreeParse(const ParserNode *parserNode, AstTreeHelper *helper) {
return NULL;
}
-AstTree *astTreeParseFunction(const ParserNode *parserNode,
- AstTreeHelper *p_helper) {
+AstTree *astTreeParseFunction(const ParserNode *parserNode) {
ParserNodeFunctionDefnitionMetadata *node_metadata = parserNode->metadata;
const ParserNodeArray *node_arguments = node_metadata->arguments->metadata;
const ParserNodeArray *body = node_metadata->body->metadata;
@@ -2305,19 +2289,6 @@ AstTree *astTreeParseFunction(const ParserNode *parserNode,
function->arguments.data = a404m_malloc(0);
function->arguments.size = 0;
- size_t variables_size = p_helper->variables_size + 2;
- AstTreeVariables *variables[variables_size];
- 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;
-
- AstTreeHelper helper = {
- .variables = variables,
- .variables_size = variables_size,
- };
-
for (size_t i = 0; i < node_arguments->size; ++i) {
const ParserNode *arg = node_arguments->data[i];
if (arg->token == PARSER_TOKEN_SYMBOL_COMMA) {
@@ -2331,7 +2302,7 @@ AstTree *astTreeParseFunction(const ParserNode *parserNode,
goto RETURN_ERROR;
}
- AstTree *type = astTreeParse(arg_metadata->type, &helper);
+ AstTree *type = astTreeParse(arg_metadata->type);
if (type == NULL) {
goto RETURN_ERROR;
}
@@ -2345,14 +2316,14 @@ AstTree *astTreeParseFunction(const ParserNode *parserNode,
argument->isConst = arg_metadata->isComptime;
argument->isLazy = arg_metadata->isLazy;
- if (!pushVariable(&helper, &function->arguments, argument)) {
+ if (!pushVariable(&function->arguments, argument)) {
astTreeVariableDelete(argument);
goto RETURN_ERROR;
}
}
- if ((function->returnType =
- astTreeParse(node_metadata->returnType, &helper)) == NULL) {
+ if ((function->returnType = astTreeParse(node_metadata->returnType)) ==
+ NULL) {
goto RETURN_ERROR;
}
@@ -2395,6 +2366,7 @@ AstTree *astTreeParseFunction(const ParserNode *parserNode,
case PARSER_TOKEN_TYPE_BOOL:
case PARSER_TOKEN_KEYWORD_PUTC:
case PARSER_TOKEN_KEYWORD_RETURN:
+ case PARSER_TOKEN_KEYWORD_BREAK:
case PARSER_TOKEN_KEYWORD_COMPTIME:
case PARSER_TOKEN_KEYWORD_STRUCT:
case PARSER_TOKEN_CONSTANT:
@@ -2461,11 +2433,16 @@ AstTree *astTreeParseFunction(const ParserNode *parserNode,
OK_NODE:
if (node->token == PARSER_TOKEN_CONSTANT) {
- if (!astTreeParseConstant(node, &helper)) {
+ if (!astTreeParseConstant(node, &scope.variables)) {
goto RETURN_ERROR;
}
} else {
- AstTree *tree = astTreeParse(node, &helper);
+ AstTree *tree;
+ if (node->token == PARSER_TOKEN_VARIABLE) {
+ tree = astTreeParseVariable(node, &scope.variables);
+ } else {
+ tree = astTreeParse(node);
+ }
if (tree == NULL) {
goto RETURN_ERROR;
@@ -2497,8 +2474,7 @@ RETURN_ERROR:
return NULL;
}
-AstTree *astTreeParseTypeFunction(const ParserNode *parserNode,
- AstTreeHelper *helper) {
+AstTree *astTreeParseTypeFunction(const ParserNode *parserNode) {
ParserNodeTypeFunctionMetadata *metadata = parserNode->metadata;
const ParserNodeArray *node_arguments = metadata->arguments->metadata;
@@ -2531,7 +2507,7 @@ AstTree *astTreeParseTypeFunction(const ParserNode *parserNode,
argument.name_begin = variable_metadata->name->str_begin;
argument.name_end = variable_metadata->name->str_end;
- argument.type = astTreeParse(variable_metadata->type, helper);
+ argument.type = astTreeParse(variable_metadata->type);
if (variable_metadata->value != NULL) {
printError(node_argument->str_begin, node_argument->str_end,
"Cannot have value in function type");
@@ -2542,7 +2518,7 @@ AstTree *astTreeParseTypeFunction(const ParserNode *parserNode,
}
argument.isComptime = variable_metadata->isComptime;
} else {
- argument.type = astTreeParse(node_argument, helper);
+ argument.type = astTreeParse(node_argument);
if (argument.type == NULL) {
return NULL;
}
@@ -2566,8 +2542,7 @@ AstTree *astTreeParseTypeFunction(const ParserNode *parserNode,
typeFunction->arguments_size += 1;
}
- if ((typeFunction->returnType = astTreeParse(metadata->returnType, helper)) ==
- NULL) {
+ if ((typeFunction->returnType = astTreeParse(metadata->returnType)) == NULL) {
goto RETURN_ERROR;
}
@@ -2578,10 +2553,9 @@ RETURN_ERROR:
return NULL;
}
-AstTree *astTreeParseFunctionCall(const ParserNode *parserNode,
- AstTreeHelper *helper) {
+AstTree *astTreeParseFunctionCall(const ParserNode *parserNode) {
ParserNodeFunctionCall *node_metadata = parserNode->metadata;
- AstTree *function = astTreeParse(node_metadata->function, helper);
+ AstTree *function = astTreeParse(node_metadata->function);
if (function == NULL) {
return NULL;
}
@@ -2604,12 +2578,12 @@ AstTree *astTreeParseFunctionCall(const ParserNode *parserNode,
if (assign->left->token == PARSER_TOKEN_IDENTIFIER) {
param.nameBegin = assign->left->str_begin;
param.nameEnd = assign->left->str_end;
- param.value = astTreeParse(assign->right, helper);
+ param.value = astTreeParse(assign->right);
goto PUSH_PARAM;
}
}
param.nameBegin = param.nameEnd = NULL;
- param.value = astTreeParse(node_param, helper);
+ param.value = astTreeParse(node_param);
PUSH_PARAM:
metadata->parameters[i] = param;
}
@@ -2618,9 +2592,7 @@ AstTree *astTreeParseFunctionCall(const ParserNode *parserNode,
parserNode->str_begin, parserNode->str_end);
}
-AstTree *astTreeParseIdentifier(const ParserNode *parserNode,
- AstTreeHelper *helper) {
- (void)helper;
+AstTree *astTreeParseIdentifier(const ParserNode *parserNode) {
return newAstTree(AST_TREE_TOKEN_VARIABLE, NULL, NULL, parserNode->str_begin,
parserNode->str_end);
}
@@ -2636,9 +2608,7 @@ AstTree *astTreeParseValue(const ParserNode *parserNode, AstTreeToken token,
parserNode->str_end);
}
-AstTree *astTreeParseString(const ParserNode *parserNode,
- AstTreeHelper *helper) {
- (void)helper;
+AstTree *astTreeParseString(const ParserNode *parserNode) {
ParserNodeStringMetadata *node_metadata = parserNode->metadata;
AstTreeObject *metadata = a404m_malloc(sizeof(*metadata));
@@ -2688,10 +2658,10 @@ AstTree *astTreeParseKeyword(const ParserNode *parserNode, AstTreeToken token) {
parserNode->str_end);
}
-AstTree *astTreeParsePutc(const ParserNode *parserNode, AstTreeHelper *helper) {
+AstTree *astTreeParsePutc(const ParserNode *parserNode) {
ParserNodeSingleChildMetadata *node_metadata = parserNode->metadata;
- AstTree *operand = astTreeParse(node_metadata, helper);
+ AstTree *operand = astTreeParse(node_metadata);
if (operand == NULL) {
return NULL;
}
@@ -2700,15 +2670,14 @@ AstTree *astTreeParsePutc(const ParserNode *parserNode, AstTreeHelper *helper) {
NULL, parserNode->str_begin, parserNode->str_end);
}
-AstTree *astTreeParseReturn(const ParserNode *parserNode,
- AstTreeHelper *helper) {
+AstTree *astTreeParseReturn(const ParserNode *parserNode) {
ParserNodeReturnMetadata *node_metadata = parserNode->metadata;
AstTree *value;
if (node_metadata->value == NULL) {
value = NULL;
} else {
- value = astTreeParse(node_metadata->value, helper);
+ value = astTreeParse(node_metadata->value);
if (value == NULL) {
return NULL;
}
@@ -2722,14 +2691,14 @@ AstTree *astTreeParseReturn(const ParserNode *parserNode,
}
AstTree *astTreeParseBinaryOperator(const ParserNode *parserNode,
- AstTreeHelper *helper, AstTreeToken token) {
+ AstTreeToken token) {
ParserNodeInfixMetadata *node_metadata = parserNode->metadata;
- AstTree *left = astTreeParse(node_metadata->left, helper);
+ AstTree *left = astTreeParse(node_metadata->left);
if (left == NULL) {
return NULL;
}
- AstTree *right = astTreeParse(node_metadata->right, helper);
+ AstTree *right = astTreeParse(node_metadata->right);
if (right == NULL) {
return NULL;
}
@@ -2745,11 +2714,11 @@ AstTree *astTreeParseBinaryOperator(const ParserNode *parserNode,
}
AstTree *astTreeParseUnaryOperator(const ParserNode *parserNode,
- AstTreeHelper *helper, AstTreeToken token) {
+ AstTreeToken token) {
ParserNodeSingleChildMetadata *node_metadata = parserNode->metadata;
AstTreeUnary *metadata = a404m_malloc(sizeof(*metadata));
- metadata->operand = astTreeParse(node_metadata, helper);
+ metadata->operand = astTreeParse(node_metadata);
if (metadata->operand == NULL) {
free(metadata);
return NULL;
@@ -2761,11 +2730,10 @@ AstTree *astTreeParseUnaryOperator(const ParserNode *parserNode,
}
AstTree *astTreeParseUnaryOperatorSingleChild(const ParserNode *parserNode,
- AstTreeHelper *helper,
AstTreeToken token) {
ParserNodeSingleChildMetadata *node_metadata = parserNode->metadata;
- AstTreeSingleChild *metadata = astTreeParse(node_metadata, helper);
+ AstTreeSingleChild *metadata = astTreeParse(node_metadata);
if (metadata == NULL) {
return NULL;
}
@@ -2775,15 +2743,14 @@ AstTree *astTreeParseUnaryOperatorSingleChild(const ParserNode *parserNode,
}
AstTree *astTreeParseOperateAssignOperator(const ParserNode *parserNode,
- AstTreeHelper *helper,
AstTreeToken token) {
ParserNodeInfixMetadata *node_metadata = parserNode->metadata;
- AstTree *left = astTreeParse(node_metadata->left, helper);
+ AstTree *left = astTreeParse(node_metadata->left);
if (left == NULL) {
return NULL;
}
- AstTree *right = astTreeParse(node_metadata->right, helper);
+ AstTree *right = astTreeParse(node_metadata->right);
if (right == NULL) {
return NULL;
}
@@ -2796,7 +2763,7 @@ AstTree *astTreeParseOperateAssignOperator(const ParserNode *parserNode,
AstTreeInfix *assignMetadata = a404m_malloc(sizeof(*assignMetadata));
- AstTree *assignLeft = astTreeParse(node_metadata->left, helper);
+ AstTree *assignLeft = astTreeParse(node_metadata->left);
AstTree *assignRight = newAstTree(token, metadata, NULL,
parserNode->str_begin, parserNode->str_end);
@@ -2808,7 +2775,8 @@ AstTree *astTreeParseOperateAssignOperator(const ParserNode *parserNode,
parserNode->str_begin, parserNode->str_end);
}
-bool astTreeParseConstant(const ParserNode *parserNode, AstTreeHelper *helper) {
+bool astTreeParseConstant(const ParserNode *parserNode,
+ AstTreeVariables *variables) {
ParserNodeVariableMetadata *node_metadata = parserNode->metadata;
if (node_metadata->value == NULL ||
@@ -2817,7 +2785,7 @@ bool astTreeParseConstant(const ParserNode *parserNode, AstTreeHelper *helper) {
return NULL;
}
- AstTree *value = astTreeParse(node_metadata->value, helper);
+ AstTree *value = astTreeParse(node_metadata->value);
if (value == NULL) {
goto RETURN_ERROR;
}
@@ -2826,7 +2794,7 @@ bool astTreeParseConstant(const ParserNode *parserNode, AstTreeHelper *helper) {
if (node_metadata->type == NULL) {
type = NULL;
} else {
- type = astTreeParse(node_metadata->type, helper);
+ type = astTreeParse(node_metadata->type);
if (type == NULL) {
goto RETURN_ERROR;
}
@@ -2841,8 +2809,7 @@ bool astTreeParseConstant(const ParserNode *parserNode, AstTreeHelper *helper) {
variable->isConst = true;
variable->isLazy = node_metadata->isLazy;
- if (!pushVariable(helper, helper->variables[helper->variables_size - 1],
- variable)) {
+ if (!pushVariable(variables, variable)) {
astTreeVariableDelete(variable);
goto RETURN_ERROR;
}
@@ -2853,7 +2820,7 @@ RETURN_ERROR:
}
AstTree *astTreeParseVariable(const ParserNode *parserNode,
- AstTreeHelper *helper) {
+ AstTreeVariables *variables) {
ParserNodeVariableMetadata *node_metadata = parserNode->metadata;
if (node_metadata->isComptime) {
@@ -2870,7 +2837,7 @@ AstTree *astTreeParseVariable(const ParserNode *parserNode,
return NULL;
}
- AstTree *value = astTreeParse(node_metadata->value, helper);
+ AstTree *value = astTreeParse(node_metadata->value);
if (value == NULL) {
goto RETURN_ERROR;
}
@@ -2879,7 +2846,7 @@ AstTree *astTreeParseVariable(const ParserNode *parserNode,
if (node_metadata->type == NULL) {
type = NULL;
} else {
- type = astTreeParse(node_metadata->type, helper);
+ type = astTreeParse(node_metadata->type);
if (type == NULL) {
goto RETURN_ERROR;
}
@@ -2894,8 +2861,7 @@ AstTree *astTreeParseVariable(const ParserNode *parserNode,
variable->isConst = false;
variable->isLazy = node_metadata->isLazy;
- if (!pushVariable(helper, helper->variables[helper->variables_size - 1],
- variable)) {
+ if (!pushVariable(variables, variable)) {
astTreeVariableDelete(variable);
goto RETURN_ERROR;
}
@@ -2906,22 +2872,22 @@ RETURN_ERROR:
return NULL;
}
-AstTree *astTreeParseIf(const ParserNode *parserNode, AstTreeHelper *helper) {
+AstTree *astTreeParseIf(const ParserNode *parserNode) {
ParserNodeIfMetadata *node_metadata = parserNode->metadata;
- AstTree *condition = astTreeParse(node_metadata->condition, helper);
+ AstTree *condition = astTreeParse(node_metadata->condition);
if (condition == NULL) {
return NULL;
}
- AstTree *ifBody = astTreeParse(node_metadata->ifBody, helper);
+ AstTree *ifBody = astTreeParse(node_metadata->ifBody);
if (ifBody == NULL) {
return NULL;
}
AstTree *elseBody;
if (node_metadata->elseBody != NULL) {
- elseBody = astTreeParse(node_metadata->elseBody, helper);
+ elseBody = astTreeParse(node_metadata->elseBody);
if (elseBody == NULL) {
return NULL;
}
@@ -2938,16 +2904,15 @@ AstTree *astTreeParseIf(const ParserNode *parserNode, AstTreeHelper *helper) {
parserNode->str_begin, parserNode->str_end);
}
-AstTree *astTreeParseWhile(const ParserNode *parserNode,
- AstTreeHelper *helper) {
+AstTree *astTreeParseWhile(const ParserNode *parserNode) {
ParserNodeWhileMetadata *node_metadata = parserNode->metadata;
- AstTree *condition = astTreeParse(node_metadata->condition, helper);
+ AstTree *condition = astTreeParse(node_metadata->condition);
if (condition == NULL) {
return NULL;
}
- AstTree *body = astTreeParse(node_metadata->body, helper);
+ AstTree *body = astTreeParse(node_metadata->body);
if (body == NULL) {
return NULL;
}
@@ -2960,19 +2925,17 @@ AstTree *astTreeParseWhile(const ParserNode *parserNode,
parserNode->str_begin, parserNode->str_end);
}
-AstTree *astTreeParseComptime(const ParserNode *parserNode,
- AstTreeHelper *helper) {
+AstTree *astTreeParseComptime(const ParserNode *parserNode) {
ParserNodeSingleChildMetadata *node_metadata = parserNode->metadata;
- AstTreeSingleChild *metadata = (AstTreeSingleChild *)astTreeParse(
- (const ParserNode *)node_metadata, helper);
+ AstTreeSingleChild *metadata =
+ (AstTreeSingleChild *)astTreeParse((const ParserNode *)node_metadata);
return newAstTree(AST_TREE_TOKEN_KEYWORD_COMPTIME, metadata, NULL,
parserNode->str_begin, parserNode->str_end);
}
-AstTree *astTreeParseCurlyBracket(const ParserNode *parserNode,
- AstTreeHelper *p_helper) {
+AstTree *astTreeParseCurlyBracket(const ParserNode *parserNode) {
const ParserNodeArray *body = parserNode->metadata;
size_t expressions_size = 0;
@@ -2983,18 +2946,6 @@ AstTree *astTreeParseCurlyBracket(const ParserNode *parserNode,
scope->expressions = a404m_malloc(0);
scope->expressions_size = 0;
- size_t variables_size = p_helper->variables_size + 1;
- AstTreeVariables *variables[variables_size];
- for (size_t i = 0; i < p_helper->variables_size; ++i) {
- variables[i] = p_helper->variables[i];
- }
- variables[variables_size - 1] = &scope->variables;
-
- AstTreeHelper helper = {
- .variables = variables,
- .variables_size = variables_size,
- };
-
for (size_t i = 0; i < body->size; ++i) {
const ParserNode *node = body->data[i];
switch (node->token) {
@@ -3034,6 +2985,7 @@ AstTree *astTreeParseCurlyBracket(const ParserNode *parserNode,
case PARSER_TOKEN_TYPE_BOOL:
case PARSER_TOKEN_KEYWORD_PUTC:
case PARSER_TOKEN_KEYWORD_RETURN:
+ case PARSER_TOKEN_KEYWORD_BREAK:
case PARSER_TOKEN_KEYWORD_COMPTIME:
case PARSER_TOKEN_KEYWORD_STRUCT:
case PARSER_TOKEN_CONSTANT:
@@ -3100,11 +3052,16 @@ AstTree *astTreeParseCurlyBracket(const ParserNode *parserNode,
OK_NODE:
if (node->token == PARSER_TOKEN_CONSTANT) {
- if (!astTreeParseConstant(node, &helper)) {
+ if (!astTreeParseConstant(node, &scope->variables)) {
goto RETURN_ERROR;
}
} else {
- AstTree *tree = astTreeParse(node, &helper);
+ AstTree *tree;
+ if (node->token == PARSER_TOKEN_VARIABLE) {
+ tree = astTreeParseVariable(node, &scope->variables);
+ } else {
+ tree = astTreeParse(node);
+ }
if (tree == NULL) {
goto RETURN_ERROR;
@@ -3136,20 +3093,18 @@ RETURN_ERROR:
return NULL;
}
-AstTree *astTreeParseParenthesis(const ParserNode *parserNode,
- AstTreeHelper *helper) {
+AstTree *astTreeParseParenthesis(const ParserNode *parserNode) {
const ParserNodeArray *metadata = parserNode->metadata;
if (metadata->size != 1) {
printError(parserNode->str_begin, parserNode->str_end, "Bad parenthesis");
return NULL;
} else {
- return astTreeParse(metadata->data[0], helper);
+ return astTreeParse(metadata->data[0]);
}
}
-AstTree *astTreeParseStruct(const ParserNode *parserNode,
- AstTreeHelper *helper) {
+AstTree *astTreeParseStruct(const ParserNode *parserNode) {
const ParserNode *body = parserNode->metadata;
const ParserNodeArray *body_metadata = body->metadata;
AstTreeVariables variables = {
@@ -3178,7 +3133,7 @@ AstTree *astTreeParseStruct(const ParserNode *parserNode,
variable->name_begin = node_variable->name->str_begin;
variable->name_end = node_variable->name->str_end;
if (node_variable->type != NULL) {
- variable->type = astTreeParse(node_variable->type, helper);
+ variable->type = astTreeParse(node_variable->type);
} else {
variable->type = NULL;
}
@@ -3188,7 +3143,7 @@ AstTree *astTreeParseStruct(const ParserNode *parserNode,
printError(node->str_begin, node->str_end, "Constants must have value");
NOT_IMPLEMENTED;
}
- variable->value = astTreeParse(node_variable->value, helper);
+ variable->value = astTreeParse(node_variable->value);
variable->initValue = NULL;
variable->isConst = true;
} else {
@@ -3218,10 +3173,10 @@ AstTree *astTreeParseStruct(const ParserNode *parserNode,
}
AstTree *astTreeParseAccessOperator(const ParserNode *parserNode,
- AstTreeHelper *helper, AstTreeToken token) {
+ AstTreeToken token) {
ParserNodeInfixMetadata *node_metadata = parserNode->metadata;
- AstTree *object = astTreeParse(node_metadata->left, helper);
+ AstTree *object = astTreeParse(node_metadata->left);
if (object == NULL) {
return NULL;
}
@@ -3244,13 +3199,12 @@ AstTree *astTreeParseAccessOperator(const ParserNode *parserNode,
parserNode->str_end);
}
-AstTree *astTreeParseBracket(const ParserNode *parserNode,
- AstTreeHelper *helper, AstTreeToken token) {
+AstTree *astTreeParseBracket(const ParserNode *parserNode, AstTreeToken token) {
ParserNodeBracketMetadata *node_metadata = parserNode->metadata;
AstTreeBracket *metadata = a404m_malloc(sizeof(*metadata));
- metadata->operand = astTreeParse(node_metadata->operand, helper);
+ metadata->operand = astTreeParse(node_metadata->operand);
metadata->parameters.size = node_metadata->params->size;
metadata->parameters.data = a404m_malloc(sizeof(*metadata->parameters.data) *
@@ -3263,7 +3217,7 @@ AstTree *astTreeParseBracket(const ParserNode *parserNode,
node_param = (ParserNodeSingleChildMetadata *)node_param->metadata;
}
- metadata->parameters.data[i] = astTreeParse(node_param, helper);
+ metadata->parameters.data[i] = astTreeParse(node_param);
}
return newAstTree(token, metadata, NULL, parserNode->str_begin,
@@ -3372,6 +3326,7 @@ bool isConst(AstTree *tree) {
case AST_TREE_TOKEN_KEYWORD_WHILE:
case AST_TREE_TOKEN_KEYWORD_PUTC:
case AST_TREE_TOKEN_KEYWORD_RETURN:
+ case AST_TREE_TOKEN_KEYWORD_BREAK:
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_OPERATOR_ASSIGN:
case AST_TREE_TOKEN_OPERATOR_PLUS:
@@ -3596,6 +3551,7 @@ AstTree *makeTypeOf(AstTree *value) {
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_KEYWORD_PUTC:
case AST_TREE_TOKEN_KEYWORD_RETURN:
+ case AST_TREE_TOKEN_KEYWORD_BREAK:
case AST_TREE_TOKEN_KEYWORD_IF:
case AST_TREE_TOKEN_KEYWORD_WHILE:
case AST_TREE_TOKEN_SCOPE:
@@ -3672,6 +3628,7 @@ bool typeIsEqualBack(const AstTree *type0, const AstTree *type1) {
case AST_TREE_TOKEN_FUNCTION:
case AST_TREE_TOKEN_KEYWORD_PUTC:
case AST_TREE_TOKEN_KEYWORD_RETURN:
+ case AST_TREE_TOKEN_KEYWORD_BREAK:
case AST_TREE_TOKEN_KEYWORD_IF:
case AST_TREE_TOKEN_KEYWORD_WHILE:
case AST_TREE_TOKEN_KEYWORD_COMPTIME:
@@ -3895,6 +3852,7 @@ AstTree *getValue(AstTree *tree, bool copy) {
case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS:
case AST_TREE_TOKEN_SHAPE_SHIFTER_ELEMENT: {
bool shouldRet = false;
+ u32 breakCount = 0;
AstTreeScope *scope = a404m_malloc(sizeof(*scope));
scope->expressions = a404m_malloc(0);
scope->expressions_size = 0;
@@ -3909,7 +3867,8 @@ AstTree *getValue(AstTree *tree, bool copy) {
.str_end = NULL,
};
- AstTree *value = runExpression(tree, scope, &shouldRet, false, true);
+ AstTree *value =
+ runExpression(tree, scope, &shouldRet, false, true, &breakCount);
if (!copy) {
astTreeDelete(tree);
@@ -3933,6 +3892,7 @@ AstTree *getValue(AstTree *tree, bool copy) {
}
case AST_TREE_TOKEN_KEYWORD_PUTC:
case AST_TREE_TOKEN_KEYWORD_RETURN:
+ case AST_TREE_TOKEN_KEYWORD_BREAK:
case AST_TREE_TOKEN_VARIABLE_DEFINE:
case AST_TREE_TOKEN_NONE:
}
@@ -3971,6 +3931,7 @@ bool isIntType(AstTree *type) {
case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL:
case AST_TREE_TOKEN_KEYWORD_PUTC:
case AST_TREE_TOKEN_KEYWORD_RETURN:
+ case AST_TREE_TOKEN_KEYWORD_BREAK:
case AST_TREE_TOKEN_KEYWORD_IF:
case AST_TREE_TOKEN_KEYWORD_WHILE:
case AST_TREE_TOKEN_KEYWORD_COMPTIME:
@@ -4098,6 +4059,7 @@ bool isEqual(AstTree *left, AstTree *right) {
case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL:
case AST_TREE_TOKEN_KEYWORD_PUTC:
case AST_TREE_TOKEN_KEYWORD_RETURN:
+ case AST_TREE_TOKEN_KEYWORD_BREAK:
case AST_TREE_TOKEN_KEYWORD_IF:
case AST_TREE_TOKEN_KEYWORD_WHILE:
case AST_TREE_TOKEN_KEYWORD_COMPTIME:
@@ -4211,6 +4173,8 @@ bool setAllTypesRoot(AstTreeRoot *root) {
},
.variables = variables,
.root = root,
+ .loops = NULL,
+ .loops_size = 0,
};
for (size_t i = 0; i < root->variables.size; ++i) {
@@ -4338,6 +4302,8 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper,
return setTypesPutc(tree, helper);
case AST_TREE_TOKEN_KEYWORD_RETURN:
return setTypesReturn(tree, helper, function);
+ case AST_TREE_TOKEN_KEYWORD_BREAK:
+ return setTypesBreak(tree, helper);
case AST_TREE_TOKEN_TYPE_FUNCTION:
return setTypesTypeFunction(tree, helper);
case AST_TREE_TOKEN_FUNCTION_CALL:
@@ -4667,6 +4633,8 @@ bool setTypesFunction(AstTree *tree, AstTreeSetTypesHelper _helper) {
.variables.data = variables,
.variables.size = _helper.variables.size,
.root = _helper.root,
+ .loops = NULL,
+ .loops_size = 0,
};
AstTreeVariable *deps[helper.dependencies.size];
@@ -4732,6 +4700,8 @@ bool setTypesPutc(AstTree *tree, AstTreeSetTypesHelper _helper) {
.dependencies = _helper.dependencies,
.variables = _helper.variables,
.root = _helper.root,
+ .loops = _helper.loops,
+ .loops_size = _helper.loops_size,
};
if (!setAllTypes(metadata, helper, NULL, NULL)) {
return false;
@@ -4748,6 +4718,7 @@ bool setTypesReturn(AstTree *tree, AstTreeSetTypesHelper _helper,
AstTreeFunction *function) {
if (function == NULL) {
printError(tree->str_begin, tree->str_end, "Return can't be here");
+ return false;
}
AstTreeReturn *metadata = tree->metadata;
@@ -4757,6 +4728,8 @@ bool setTypesReturn(AstTree *tree, AstTreeSetTypesHelper _helper,
.dependencies = _helper.dependencies,
.variables = _helper.variables,
.root = _helper.root,
+ .loops = _helper.loops,
+ .loops_size = _helper.loops_size,
};
if (helper.lookingType == NULL) {
return false;
@@ -4775,6 +4748,17 @@ bool setTypesReturn(AstTree *tree, AstTreeSetTypesHelper _helper,
return true;
}
+bool setTypesBreak(AstTree *tree, AstTreeSetTypesHelper helper) {
+ if (helper.loops_size == 0) {
+ printError(tree->str_begin, tree->str_end,
+ "`break` can't be here, it needs to be inside a loop");
+ return false;
+ }
+
+ tree->type = &AST_TREE_VOID_TYPE;
+ return true;
+}
+
bool setTypesTypeFunction(AstTree *tree, AstTreeSetTypesHelper helper) {
AstTreeTypeFunction *metadata = tree->metadata;
@@ -4782,7 +4766,7 @@ bool setTypesTypeFunction(AstTree *tree, AstTreeSetTypesHelper helper) {
AstTreeTypeFunctionArgument arg = metadata->arguments[i];
if (!setAllTypes(arg.type, helper, NULL, NULL)) {
return false;
- } else if (!typeIsEqual(arg.type, &AST_TREE_TYPE_TYPE)) {
+ } else if (!typeIsEqual(arg.type->type, &AST_TREE_TYPE_TYPE)) {
printError(arg.str_begin, arg.str_end, "Expected a type");
return false;
}
@@ -4807,6 +4791,8 @@ bool setTypesFunctionCall(AstTree *tree, AstTreeSetTypesHelper _helper) {
.dependencies = _helper.dependencies,
.variables = _helper.variables,
.root = _helper.root,
+ .loops = _helper.loops,
+ .loops_size = _helper.loops_size,
};
for (size_t i = 0; i < metadata->parameters_size; ++i) {
@@ -5015,6 +5001,8 @@ bool setTypesFunctionCall(AstTree *tree, AstTreeSetTypesHelper _helper) {
.variables.size = helper.variables.size,
.lookingType = NULL,
.dependencies = helper.dependencies,
+ .loops = helper.loops,
+ .loops_size = helper.loops_size,
};
for (size_t i = 0; i < newFunction->arguments.size; ++i) {
@@ -5112,6 +5100,8 @@ bool setTypesOperatorInfix(AstTree *tree, AstTreeSetTypesHelper _helper,
.dependencies = _helper.dependencies,
.variables = _helper.variables,
.root = _helper.root,
+ .loops = _helper.loops,
+ .loops_size = _helper.loops_size,
};
if (!setAllTypes(metadata->left, helper, NULL, NULL) ||
@@ -5174,6 +5164,8 @@ bool setTypesOperatorInfixWithRetAndLooking(AstTree *tree, AstTree *lookingType,
.dependencies = _helper.dependencies,
.variables = _helper.variables,
.root = _helper.root,
+ .loops = _helper.loops,
+ .loops_size = _helper.loops_size,
};
return setTypesOperatorInfixWithRet(tree, retType, helper);
}
@@ -5287,6 +5279,8 @@ bool setTypesAstVariable(AstTreeVariable *variable,
.dependencies.size = _helper.dependencies.size + 1,
.variables = _helper.variables,
.root = _helper.root,
+ .loops = _helper.loops,
+ .loops_size = _helper.loops_size,
};
// previously done
@@ -5388,10 +5382,27 @@ bool setTypesIf(AstTree *tree, AstTreeSetTypesHelper helper,
return true;
}
-bool setTypesWhile(AstTree *tree, AstTreeSetTypesHelper helper,
+bool setTypesWhile(AstTree *tree, AstTreeSetTypesHelper _helper,
AstTreeFunction *function) {
AstTreeWhile *metadata = tree->metadata;
+ const size_t loops_size = _helper.loops_size + 1;
+ AstTreeWhile *loops[loops_size];
+
+ for (size_t i = 0; i < _helper.loops_size; ++i) {
+ loops[i] = _helper.loops[i];
+ }
+ loops[_helper.loops_size] = metadata;
+
+ AstTreeSetTypesHelper helper = {
+ .lookingType = NULL,
+ .dependencies = _helper.dependencies,
+ .variables = _helper.variables,
+ .root = _helper.root,
+ .loops = loops,
+ .loops_size = loops_size,
+ };
+
if (!setAllTypes(metadata->condition, helper, function, NULL) ||
!setAllTypes(metadata->body, helper, function, NULL)) {
return false;
@@ -5423,6 +5434,8 @@ bool setTypesScope(AstTree *tree, AstTreeSetTypesHelper _helper,
.variables.data = variables,
.variables.size = _helper.variables.size,
.root = _helper.root,
+ .loops = _helper.loops,
+ .loops_size = _helper.loops_size,
};
for (size_t i = 0; i < metadata->variables.size; ++i) {
@@ -5536,6 +5549,8 @@ bool setTypesOperatorAccess(AstTree *tree, AstTreeSetTypesHelper helper) {
helper.root->imports[namespace->importedIndex].root->variables,
.dependencies = helper.dependencies,
.lookingType = helper.lookingType,
+ .loops = helper.loops,
+ .loops_size = helper.loops_size,
};
astTreeDelete(value);
@@ -5778,11 +5793,17 @@ bool setTypesBuiltinIsComptime(AstTree *tree, AstTreeSetTypesHelper helper) {
bool setTypesBuiltinStackAlloc(AstTree *tree, AstTreeSetTypesHelper helper,
AstTreeFunctionCall *functionCall) {
+ (void)tree;
+ (void)helper;
+ (void)functionCall;
NOT_IMPLEMENTED;
}
bool setTypesBuiltinHeapAlloc(AstTree *tree, AstTreeSetTypesHelper helper,
AstTreeFunctionCall *functionCall) {
+ (void)tree;
+ (void)helper;
+ (void)functionCall;
NOT_IMPLEMENTED;
}
@@ -5846,6 +5867,7 @@ bool setTypesBuiltinUnary(AstTree *tree, AstTreeSetTypesHelper helper,
case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL:
case AST_TREE_TOKEN_KEYWORD_PUTC:
case AST_TREE_TOKEN_KEYWORD_RETURN:
+ case AST_TREE_TOKEN_KEYWORD_BREAK:
case AST_TREE_TOKEN_KEYWORD_IF:
case AST_TREE_TOKEN_KEYWORD_WHILE:
case AST_TREE_TOKEN_KEYWORD_COMPTIME:
@@ -6099,6 +6121,8 @@ bool setTypesTypeArray(AstTree *tree, AstTreeSetTypesHelper helper) {
.dependencies = helper.dependencies,
.variables = helper.variables,
.root = helper.root,
+ .loops = helper.loops,
+ .loops_size = helper.loops_size,
};
for (size_t i = 0; i < metadata->parameters.size; ++i) {
@@ -6129,6 +6153,8 @@ bool setTypesArrayAccess(AstTree *tree, AstTreeSetTypesHelper _helper) {
.dependencies = _helper.dependencies,
.variables = _helper.variables,
.root = _helper.root,
+ .loops = _helper.loops,
+ .loops_size = _helper.loops_size,
};
if (!setAllTypes(metadata->operand, helper, NULL, NULL)) {
@@ -6168,6 +6194,8 @@ bool setTypesAstInfix(AstTreeInfix *infix, AstTreeSetTypesHelper _helper) {
.dependencies = _helper.dependencies,
.variables = _helper.variables,
.root = _helper.root,
+ .loops = _helper.loops,
+ .loops_size = _helper.loops_size,
};
if (!setAllTypes(infix->left, helper, NULL, NULL)) {
@@ -6194,6 +6222,8 @@ bool setTypesAstFunction(AstTreeFunction *metadata,
.variables.data = variables,
.variables.size = _helper.variables.size,
.root = _helper.root,
+ .loops = _helper.loops,
+ .loops_size = _helper.loops_size,
};
AstTreeVariable *deps[helper.dependencies.size];
@@ -6389,6 +6419,8 @@ AstTreeVariable *setTypesFindVariable(const char *name_begin,
.dependencies = helper.dependencies,
.lookingType = NULL,
.root = helper.root,
+ .loops = helper.loops,
+ .loops_size = helper.loops_size,
};
for (size_t i = 0; i < functionCall->parameters_size; ++i) {
diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h
index 7d6dd5f..fd1f123 100644
--- a/src/compiler/ast-tree.h
+++ b/src/compiler/ast-tree.h
@@ -27,6 +27,7 @@ typedef enum AstTreeToken {
AST_TREE_TOKEN_KEYWORD_PUTC,
AST_TREE_TOKEN_KEYWORD_RETURN,
+ AST_TREE_TOKEN_KEYWORD_BREAK,
AST_TREE_TOKEN_KEYWORD_IF,
AST_TREE_TOKEN_KEYWORD_WHILE,
AST_TREE_TOKEN_KEYWORD_COMPTIME,
@@ -247,16 +248,13 @@ typedef struct AstTreeWhile {
AstTree *body;
} AstTreeWhile;
-typedef struct AstTreeHelper {
- AstTreeVariables **variables;
- size_t variables_size;
-} AstTreeHelper;
-
typedef struct AstTreeSetTypesHelper {
AstTree *lookingType;
AstTreeVariables dependencies;
AstTreeVariables variables;
AstTreeRoot *root;
+ AstTreeWhile **loops;
+ size_t loops_size;
} AstTreeSetTypesHelper;
typedef struct AstTreeStruct {
@@ -349,53 +347,40 @@ AstTreeRoot *getAstTreeRoot(char *filePath, AstTreeRoots *roots
);
AstTreeRoot *makeAstRoot(const ParserNode *parsedRoot, char *filePath);
-bool pushVariable(AstTreeHelper *helper, AstTreeVariables *variables,
- AstTreeVariable *variable);
-
-AstTree *astTreeParse(const ParserNode *parserNode, AstTreeHelper *helper);
-AstTree *astTreeParseFunction(const ParserNode *parserNode,
- AstTreeHelper *helper);
-AstTree *astTreeParseTypeFunction(const ParserNode *parserNode,
- AstTreeHelper *helper);
-AstTree *astTreeParseFunctionCall(const ParserNode *parserNode,
- AstTreeHelper *helper);
-AstTree *astTreeParseIdentifier(const ParserNode *parserNode,
- AstTreeHelper *helper);
+bool pushVariable(AstTreeVariables *variables, AstTreeVariable *variable);
+
+AstTree *astTreeParse(const ParserNode *parserNode);
+AstTree *astTreeParseFunction(const ParserNode *parserNode);
+AstTree *astTreeParseTypeFunction(const ParserNode *parserNode);
+AstTree *astTreeParseFunctionCall(const ParserNode *parserNode);
+AstTree *astTreeParseIdentifier(const ParserNode *parserNode);
AstTree *astTreeParseValue(const ParserNode *parserNode, AstTreeToken token,
size_t metadata_size, AstTree *type);
-AstTree *astTreeParseString(const ParserNode *parserNode,
- AstTreeHelper *helper);
+AstTree *astTreeParseString(const ParserNode *parserNode);
AstTree *astTreeParseKeyword(const ParserNode *parserNode, AstTreeToken token);
-AstTree *astTreeParsePutc(const ParserNode *parserNode, AstTreeHelper *helper);
-AstTree *astTreeParseReturn(const ParserNode *parserNode,
- AstTreeHelper *helper);
+AstTree *astTreeParsePutc(const ParserNode *parserNode);
+AstTree *astTreeParseReturn(const ParserNode *parserNode);
AstTree *astTreeParseBinaryOperator(const ParserNode *parserNode,
- AstTreeHelper *helper, AstTreeToken token);
+ AstTreeToken token);
AstTree *astTreeParseUnaryOperator(const ParserNode *parserNode,
- AstTreeHelper *helper, AstTreeToken token);
+ AstTreeToken token);
AstTree *astTreeParseUnaryOperatorSingleChild(const ParserNode *parserNode,
- AstTreeHelper *helper,
AstTreeToken token);
AstTree *astTreeParseOperateAssignOperator(const ParserNode *parserNode,
- AstTreeHelper *helper,
AstTreeToken token);
-bool astTreeParseConstant(const ParserNode *parserNode, AstTreeHelper *helper);
+bool astTreeParseConstant(const ParserNode *parserNode,
+ AstTreeVariables *variables);
AstTree *astTreeParseVariable(const ParserNode *parserNode,
- AstTreeHelper *helper);
-AstTree *astTreeParseIf(const ParserNode *parserNode, AstTreeHelper *helper);
-AstTree *astTreeParseWhile(const ParserNode *parserNode, AstTreeHelper *helper);
-AstTree *astTreeParseComptime(const ParserNode *parserNode,
- AstTreeHelper *helper);
-AstTree *astTreeParseCurlyBracket(const ParserNode *parserNode,
- AstTreeHelper *helper);
-AstTree *astTreeParseParenthesis(const ParserNode *parserNode,
- AstTreeHelper *helper);
-AstTree *astTreeParseStruct(const ParserNode *parserNode,
- AstTreeHelper *helper);
+ AstTreeVariables *variables);
+AstTree *astTreeParseIf(const ParserNode *parserNode);
+AstTree *astTreeParseWhile(const ParserNode *parserNode);
+AstTree *astTreeParseComptime(const ParserNode *parserNode);
+AstTree *astTreeParseCurlyBracket(const ParserNode *parserNode);
+AstTree *astTreeParseParenthesis(const ParserNode *parserNode);
+AstTree *astTreeParseStruct(const ParserNode *parserNode);
AstTree *astTreeParseAccessOperator(const ParserNode *parserNode,
- AstTreeHelper *helper, AstTreeToken token);
-AstTree *astTreeParseBracket(const ParserNode *parserNode,
- AstTreeHelper *helper, AstTreeToken token);
+ AstTreeToken token);
+AstTree *astTreeParseBracket(const ParserNode *parserNode, AstTreeToken token);
bool isFunction(AstTree *value);
bool isShapeShifter(AstTreeFunction *function);
@@ -405,7 +390,7 @@ AstTree *makeTypeOfFunction(AstTreeFunction *function, const char *str_begin,
const char *str_end);
bool typeIsEqual(AstTree *type0, AstTree *type1);
bool typeIsEqualBack(const AstTree *type0, const AstTree *type1);
-AstTree *getValue(AstTree *tree,bool copy);
+AstTree *getValue(AstTree *tree, bool copy);
bool isIntType(AstTree *type);
bool isEqual(AstTree *left, AstTree *right);
bool isEqualVariable(AstTreeVariable *left, AstTreeVariable *right);
@@ -425,6 +410,7 @@ bool setTypesFunction(AstTree *tree, AstTreeSetTypesHelper helper);
bool setTypesPutc(AstTree *tree, AstTreeSetTypesHelper helper);
bool setTypesReturn(AstTree *tree, AstTreeSetTypesHelper helper,
AstTreeFunction *function);
+bool setTypesBreak(AstTree *tree, AstTreeSetTypesHelper helper);
bool setTypesTypeFunction(AstTree *tree, AstTreeSetTypesHelper helper);
bool setTypesFunctionCall(AstTree *tree, AstTreeSetTypesHelper helper);
bool setTypesVariable(AstTree *tree, AstTreeSetTypesHelper helper,
diff --git a/src/compiler/parser.c b/src/compiler/parser.c
index ebfd66f..4193fd3 100644
--- a/src/compiler/parser.c
+++ b/src/compiler/parser.c
@@ -281,6 +281,7 @@ void parserNodePrint(const ParserNode *node, int indent) {
case PARSER_TOKEN_TYPE_SHAPE_SHIFTER:
case PARSER_TOKEN_KEYWORD_NULL:
case PARSER_TOKEN_KEYWORD_UNDEFINED:
+ case PARSER_TOKEN_KEYWORD_BREAK:
goto RETURN_SUCCESS;
case PARSER_TOKEN_VALUE_INT: {
ParserNodeIntMetadata *metadata = node->metadata;
@@ -584,6 +585,7 @@ void parserNodeDelete(ParserNode *node) {
case PARSER_TOKEN_TYPE_SHAPE_SHIFTER:
case PARSER_TOKEN_KEYWORD_NULL:
case PARSER_TOKEN_KEYWORD_UNDEFINED:
+ case PARSER_TOKEN_KEYWORD_BREAK:
goto RETURN_SUCCESS;
case PARSER_TOKEN_VALUE_BOOL: {
ParserNodeBoolMetadata *metadata = node->metadata;
@@ -925,6 +927,8 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end,
return parserNoMetadata(node, parent, PARSER_TOKEN_KEYWORD_NULL);
case LEXER_TOKEN_KEYWORD_UNDEFINED:
return parserNoMetadata(node, parent, PARSER_TOKEN_KEYWORD_UNDEFINED);
+ case LEXER_TOKEN_KEYWORD_BREAK:
+ return parserNoMetadata(node, parent, PARSER_TOKEN_KEYWORD_BREAK);
case LEXER_TOKEN_KEYWORD_PUTC:
return parserPutc(node, end, parent);
case LEXER_TOKEN_KEYWORD_RETURN:
@@ -1715,6 +1719,7 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end,
case PARSER_TOKEN_TYPE_SHAPE_SHIFTER:
case PARSER_TOKEN_KEYWORD_NULL:
case PARSER_TOKEN_KEYWORD_UNDEFINED:
+ case PARSER_TOKEN_KEYWORD_BREAK:
case PARSER_TOKEN_KEYWORD_PUTC:
case PARSER_TOKEN_KEYWORD_RETURN:
case PARSER_TOKEN_KEYWORD_STRUCT:
@@ -2252,6 +2257,7 @@ bool isExpression(ParserNode *node) {
case PARSER_TOKEN_TYPE_SHAPE_SHIFTER:
case PARSER_TOKEN_KEYWORD_NULL:
case PARSER_TOKEN_KEYWORD_UNDEFINED:
+ case PARSER_TOKEN_KEYWORD_BREAK:
case PARSER_TOKEN_KEYWORD_STRUCT:
return true;
case PARSER_TOKEN_ROOT:
@@ -2333,6 +2339,7 @@ bool isType(ParserNode *node) {
case PARSER_TOKEN_VALUE_STRING:
case PARSER_TOKEN_KEYWORD_PUTC:
case PARSER_TOKEN_KEYWORD_RETURN:
+ case PARSER_TOKEN_KEYWORD_BREAK:
case PARSER_TOKEN_OPERATOR_ASSIGN:
case PARSER_TOKEN_OPERATOR_SUM_ASSIGN:
case PARSER_TOKEN_OPERATOR_SUB_ASSIGN:
@@ -2455,6 +2462,7 @@ bool isValue(ParserNode *node) {
case PARSER_TOKEN_SYMBOL_COMMA:
case PARSER_TOKEN_KEYWORD_PUTC:
case PARSER_TOKEN_KEYWORD_RETURN:
+ case PARSER_TOKEN_KEYWORD_BREAK:
case PARSER_TOKEN_KEYWORD_WHILE:
return false;
case PARSER_TOKEN_NONE: