diff options
Diffstat (limited to 'src/compiler/ast-tree.c')
-rw-r--r-- | src/compiler/ast-tree.c | 1030 |
1 files changed, 630 insertions, 400 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index acbf8ed..057e96d 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -175,6 +175,14 @@ AstTree AST_TREE_C_LIBRARY_TYPE = { .str_end = NULL, }; +AstTree AST_TREE_MACRO_TYPE = { + .token = AST_TREE_TOKEN_TYPE_MACRO, + .metadata = NULL, + .type = &AST_TREE_TYPE_TYPE, + .str_begin = NULL, + .str_end = NULL, +}; + AstTree AST_TREE_VOID_VALUE = { .token = AST_TREE_TOKEN_VALUE_VOID, .metadata = NULL, @@ -248,6 +256,7 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_TYPE_SHAPE_SHIFTER", "AST_TREE_TOKEN_TYPE_C_LIBRARY", "AST_TREE_TOKEN_TYPE_C_FUNCTION", + "AST_TREE_TOKEN_TYPE_MACRO", "AST_TREE_TOKEN_TYPE_BOOL", "AST_TREE_TOKEN_VALUE_VOID", @@ -260,6 +269,7 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER", "AST_TREE_TOKEN_VALUE_C_LIBRARY", "AST_TREE_TOKEN_VALUE_C_FUNCTION", + "AST_TREE_TOKEN_VALUE_MACRO", "AST_TREE_TOKEN_VALUE_INT", "AST_TREE_TOKEN_VALUE_FLOAT", "AST_TREE_TOKEN_VALUE_BOOL", @@ -411,7 +421,7 @@ void astTreePrint(const AstTree *tree, int indent) { case AST_TREE_TOKEN_RAW_VALUE_NOT_OWNED: goto RETURN_SUCCESS; case AST_TREE_TOKEN_TYPE_C_FUNCTION: - NOT_IMPLEMENTED; + goto RETURN_SUCCESS; case AST_TREE_TOKEN_KEYWORD_BREAK: case AST_TREE_TOKEN_KEYWORD_CONTINUE: { AstTreeLoopControl *meatadata = tree->metadata; @@ -544,8 +554,8 @@ void astTreePrint(const AstTree *tree, int indent) { for (int i = 0; i < indent; ++i) printf(" "); printf("paramters=[\n"); - for (size_t i = 0; i < metadata->parameters_size; ++i) { - AstTreeFunctionCallParam param = metadata->parameters[i]; + for (size_t i = 0; i < metadata->parameters.size; ++i) { + AstTreeFunctionCallParam param = metadata->parameters.data[i]; for (int i = 0; i < indent + 1; ++i) printf(" "); printf("{name:\"%.*s\",\n", (int)(param.nameEnd - param.nameBegin), @@ -601,7 +611,11 @@ void astTreePrint(const AstTree *tree, int indent) { for (int i = 0; i < indent; ++i) printf(" "); printf("elseBody=\n"); - astTreePrint(metadata->elseBody, indent + 1); + if (metadata->elseBody != NULL) { + astTreePrint(metadata->elseBody, indent + 1); + } else { + printf("null"); + } printf("\n"); for (int i = 0; i < indent; ++i) printf(" "); @@ -699,6 +713,8 @@ void astTreePrint(const AstTree *tree, int indent) { case AST_TREE_TOKEN_SHAPE_SHIFTER_ELEMENT: case AST_TREE_TOKEN_VALUE_C_LIBRARY: case AST_TREE_TOKEN_VALUE_C_FUNCTION: + case AST_TREE_TOKEN_TYPE_MACRO: + case AST_TREE_TOKEN_VALUE_MACRO: goto RETURN_SUCCESS; case AST_TREE_TOKEN_NONE: } @@ -769,6 +785,15 @@ void astTreeRootPrint(const AstTreeRoot *root) { } #endif +void astTreeTypeFunctionDestroy(AstTreeTypeFunction functionType) { + for (size_t i = 0; i < functionType.arguments_size; ++i) { + AstTreeTypeFunctionArgument arg = functionType.arguments[i]; + astTreeDelete(arg.type); + } + astTreeDelete(functionType.returnType); + free(functionType.arguments); +} + void astTreeScopeDestroy(AstTreeScope scope) { for (size_t i = 0; i < scope.expressions_size; ++i) { astTreeDelete(scope.expressions[i]); @@ -797,10 +822,10 @@ void astTreeDeleteFunctionCall(AstTreeFunctionCall *functionCall) { if (functionCall->function != NULL) { astTreeDelete(functionCall->function); } - for (size_t i = 0; i < functionCall->parameters_size; ++i) { - astTreeDelete(functionCall->parameters[i].value); + for (size_t i = 0; i < functionCall->parameters.size; ++i) { + astTreeDelete(functionCall->parameters.data[i].value); } - free(functionCall->parameters); + free(functionCall->parameters.data); free(functionCall); } @@ -865,6 +890,7 @@ void astTreeDestroy(AstTree tree) { case AST_TREE_TOKEN_TYPE_NAMESPACE: case AST_TREE_TOKEN_TYPE_SHAPE_SHIFTER: case AST_TREE_TOKEN_TYPE_C_LIBRARY: + case AST_TREE_TOKEN_TYPE_MACRO: case AST_TREE_TOKEN_TYPE_BOOL: case AST_TREE_TOKEN_VALUE_NULL: case AST_TREE_TOKEN_VALUE_UNDEFINED: @@ -890,12 +916,23 @@ void astTreeDestroy(AstTree tree) { for (size_t i = 0; i < metadata->generateds.size; ++i) { astTreeFunctionDestroy(*metadata->generateds.functions[i]); free(metadata->generateds.functions[i]); + for (size_t j = 0; j < metadata->generateds.calls[i].size; ++j) { + astTreeDelete(metadata->generateds.calls[i].data[j].value); + } + free(metadata->generateds.calls[i].data); } free(metadata->generateds.functions); free(metadata->generateds.calls); free(metadata); return; } + case AST_TREE_TOKEN_VALUE_MACRO: { + AstTreeMacro *metadata = tree.metadata; + astTreeFunctionDestroy(*metadata->function); + free(metadata->function); + free(metadata); + return; + } case AST_TREE_TOKEN_VALUE_BOOL: { AstTreeBool *metadata = tree.metadata; free(metadata); @@ -944,12 +981,7 @@ void astTreeDestroy(AstTree tree) { return; case AST_TREE_TOKEN_TYPE_FUNCTION: { AstTreeTypeFunction *metadata = tree.metadata; - for (size_t i = 0; i < metadata->arguments_size; ++i) { - AstTreeTypeFunctionArgument arg = metadata->arguments[i]; - astTreeDelete(arg.type); - } - astTreeDelete(metadata->returnType); - free(metadata->arguments); + astTreeTypeFunctionDestroy(*metadata); free(metadata); } return; @@ -1111,7 +1143,8 @@ bool astTreeShouldDelete(AstTree *tree) { tree != &AST_TREE_F128_TYPE && tree != &AST_TREE_CODE_TYPE && tree != &AST_TREE_NAMESPACE_TYPE && tree != &AST_TREE_SHAPE_SHIFTER_TYPE && - tree != &AST_TREE_C_LIBRARY_TYPE && tree != &AST_TREE_VOID_VALUE; + tree != &AST_TREE_C_LIBRARY_TYPE && tree != &AST_TREE_MACRO_TYPE && + tree != &AST_TREE_VOID_VALUE; } void astTreeRootDelete(AstTreeRoot *root) { @@ -1185,6 +1218,7 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], case AST_TREE_TOKEN_TYPE_NAMESPACE: case AST_TREE_TOKEN_TYPE_SHAPE_SHIFTER: case AST_TREE_TOKEN_TYPE_C_LIBRARY: + case AST_TREE_TOKEN_TYPE_MACRO: return tree; case AST_TREE_TOKEN_VALUE_VOID: if (tree == &AST_TREE_VOID_VALUE) { @@ -1264,7 +1298,19 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], new_metadata->generateds.functions[i] = copyAstTreeFunction(metadata->generateds.functions[i], oldVariables, newVariables, variables_size, false); - new_metadata->generateds.calls[i] = metadata->generateds.calls[i]; + + new_metadata->generateds.calls[i].size = + metadata->generateds.calls[i].size; + + new_metadata->generateds.calls[i].data = + a404m_malloc(sizeof(*new_metadata->generateds.calls[i].data) * + new_metadata->generateds.calls[i].size); + + for (size_t j = 0; j < new_metadata->generateds.calls[i].size; ++j) { + new_metadata->generateds.calls[i].data[j].value = + copyAstTreeBack(metadata->generateds.calls[i].data[j].value, + oldVariables, newVariables, variables_size, false); + } } return newAstTree(tree->token, new_metadata, @@ -1682,10 +1728,23 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], variables_size, safetyCheck), tree->str_begin, tree->str_end); } + case AST_TREE_TOKEN_VALUE_MACRO: { + AstTreeMacro *metadata = tree->metadata; + AstTreeMacro *new_metadata = a404m_malloc(sizeof(*new_metadata)); + + new_metadata->function = copyAstTreeFunction( + metadata->function, oldVariables, newVariables, variables_size, true); + + return newAstTree(tree->token, new_metadata, + copyAstTreeBack(tree->type, oldVariables, newVariables, + variables_size, safetyCheck), + tree->str_begin, tree->str_end); + } case AST_TREE_TOKEN_NONE: } printLog("Bad token %d", tree->token); UNREACHABLE; + return NULL; } AstTreeVariable *copyAstTreeBackFindVariable(AstTreeVariable *variable, @@ -1726,7 +1785,6 @@ AstTreeVariables copyAstTreeVariables(AstTreeVariables variables, result.data[i]->name_begin = variables.data[i]->name_begin; result.data[i]->name_end = variables.data[i]->name_end; result.data[i]->isConst = variables.data[i]->isConst; - result.data[i]->isLazy = variables.data[i]->isLazy; result.data[i]->type = copyAstTreeBack(variables.data[i]->type, new_oldVariables, new_newVariables, new_variables_size, safetyCheck); @@ -1811,14 +1869,16 @@ AstTreeFunctionCall *copyAstTreeFunctionCall(AstTreeFunctionCall *metadata, copyAstTreeBack(metadata->function, oldVariables, newVariables, variables_size, safetyCheck); - new_metadata->parameters_size = metadata->parameters_size; - new_metadata->parameters = a404m_malloc(metadata->parameters_size * - sizeof(*new_metadata->parameters)); - for (size_t i = 0; i < metadata->parameters_size; ++i) { - new_metadata->parameters[i].nameBegin = metadata->parameters[i].nameBegin; - new_metadata->parameters[i].nameEnd = metadata->parameters[i].nameEnd; - new_metadata->parameters[i].value = - copyAstTreeBack(metadata->parameters[i].value, oldVariables, + new_metadata->parameters.size = metadata->parameters.size; + new_metadata->parameters.data = a404m_malloc( + metadata->parameters.size * sizeof(*new_metadata->parameters.data)); + for (size_t i = 0; i < metadata->parameters.size; ++i) { + new_metadata->parameters.data[i].nameBegin = + metadata->parameters.data[i].nameBegin; + new_metadata->parameters.data[i].nameEnd = + metadata->parameters.data[i].nameEnd; + new_metadata->parameters.data[i].value = + copyAstTreeBack(metadata->parameters.data[i].value, oldVariables, newVariables, variables_size, safetyCheck); } @@ -1952,7 +2012,8 @@ bool astTreeDoImport(AstTreeRoots *roots, AstTreeRoot *root, AstTree *tree, .lookingType = NULL, .dependencies.data = NULL, .dependencies.size = 0, - .variables = root->variables, + .variables = &root->variables, + .variables_size = 1, .root = root, .loops = NULL, .loops_size = 0, @@ -1962,7 +2023,7 @@ bool astTreeDoImport(AstTreeRoots *roots, AstTreeRoot *root, AstTree *tree, if (!setAllTypes(tree, helper, NULL, NULL)) { return false; } - AstTree *parameter = tree_metadata->parameters[0].value; + AstTree *parameter = tree_metadata->parameters.data[0].value; if (!isConst(parameter)) { printError(parameter->str_begin, parameter->str_end, "Is not constant"); return false; @@ -2055,7 +2116,6 @@ AstTreeRoot *makeAstRoot(const ParserNode *parsedRoot, char *filePath) { variable->name_begin = node_metadata->name->str_begin; variable->name_end = node_metadata->name->str_end; variable->isConst = node->token == PARSER_TOKEN_CONSTANT; - variable->isLazy = node_metadata->isLazy; if (node_metadata->isComptime && !variable->isConst) { printError(node->str_begin, node->str_end, "Bad comptime %s", @@ -2105,7 +2165,7 @@ AstTreeRoot *makeAstRoot(const ParserNode *parsedRoot, char *filePath) { AstTreeFunctionCall *tree_metadata = tree->metadata; AstTree *operand = tree_metadata->function; if (operand->token == AST_TREE_TOKEN_BUILTIN_IMPORT) { - if (tree_metadata->parameters_size == 1) { + if (tree_metadata->parameters.size == 1) { goto PUSH; } } @@ -2618,7 +2678,6 @@ AstTree *astTreeParseFunction(const ParserNode *parserNode) { argument->name_begin = arg_metadata->name->str_begin; argument->name_end = arg_metadata->name->str_end; argument->isConst = arg_metadata->isComptime; - argument->isLazy = arg_metadata->isLazy; if (!pushVariable(&function->arguments, argument)) { astTreeVariableDelete(argument); @@ -2890,11 +2949,11 @@ AstTree *astTreeParseFunctionCall(const ParserNode *parserNode) { AstTreeFunctionCall *metadata = a404m_malloc(sizeof(*metadata)); metadata->function = function; - metadata->parameters = - a404m_malloc(sizeof(*metadata->parameters) * node_metadata->params->size); - metadata->parameters_size = node_metadata->params->size; + metadata->parameters.data = a404m_malloc(sizeof(*metadata->parameters.data) * + node_metadata->params->size); + metadata->parameters.size = node_metadata->params->size; - for (size_t i = 0; i < metadata->parameters_size; ++i) { + for (size_t i = 0; i < metadata->parameters.size; ++i) { const ParserNode *node_param = node_metadata->params->data[i]; if (node_param->token == PARSER_TOKEN_SYMBOL_COMMA) { node_param = (ParserNodeSingleChildMetadata *)node_param->metadata; @@ -2912,7 +2971,7 @@ AstTree *astTreeParseFunctionCall(const ParserNode *parserNode) { param.nameBegin = param.nameEnd = NULL; param.value = astTreeParse(node_param); PUSH_PARAM: - metadata->parameters[i] = param; + metadata->parameters.data[i] = param; } return newAstTree(AST_TREE_TOKEN_FUNCTION_CALL, metadata, NULL, @@ -2992,6 +3051,7 @@ AstTree *astTreeParseIntValue(const ParserNode *parserNode) { } } UNREACHABLE; + return NULL; } AstTree *astTreeParseString(const ParserNode *parserNode) { @@ -3078,15 +3138,15 @@ AstTree *astTreeParseAssignOperator(const ParserNode *parserNode, left->token = AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS_ASSIGN; AstTreeFunctionCall *metadata = left->metadata; - metadata->parameters = - a404m_realloc(metadata->parameters, (metadata->parameters_size + 1) * - sizeof(*metadata->parameters)); + metadata->parameters.data = a404m_realloc( + metadata->parameters.data, + (metadata->parameters.size + 1) * sizeof(*metadata->parameters.data)); - metadata->parameters[metadata->parameters_size].value = right; - metadata->parameters[metadata->parameters_size].nameBegin = NULL; - metadata->parameters[metadata->parameters_size].nameEnd = NULL; + metadata->parameters.data[metadata->parameters.size].value = right; + metadata->parameters.data[metadata->parameters.size].nameBegin = NULL; + metadata->parameters.data[metadata->parameters.size].nameEnd = NULL; - metadata->parameters_size += 1; + metadata->parameters.size += 1; return left; } else { @@ -3116,15 +3176,15 @@ AstTree *astTreeParseBinaryOperator(const ParserNode *parserNode, AstTreeFunctionCall *metadata = a404m_malloc(sizeof(*metadata)); - metadata->parameters_size = 2; - metadata->parameters = - a404m_malloc(metadata->parameters_size * sizeof(*metadata->parameters)); - metadata->parameters[0] = (AstTreeFunctionCallParam){ + metadata->parameters.size = 2; + metadata->parameters.data = a404m_malloc(metadata->parameters.size * + sizeof(*metadata->parameters.data)); + metadata->parameters.data[0] = (AstTreeFunctionCallParam){ .value = left, .nameBegin = NULL, .nameEnd = NULL, }; - metadata->parameters[1] = (AstTreeFunctionCallParam){ + metadata->parameters.data[1] = (AstTreeFunctionCallParam){ .value = right, .nameBegin = NULL, .nameEnd = NULL, @@ -3140,18 +3200,18 @@ AstTree *astTreeParseUnaryOperator(const ParserNode *parserNode, ParserNodeSingleChildMetadata *node_metadata = parserNode->metadata; AstTreeFunctionCall *metadata = a404m_malloc(sizeof(*metadata)); - metadata->parameters_size = 1; - metadata->parameters = - a404m_malloc(metadata->parameters_size * sizeof(*metadata->parameters)); + metadata->parameters.size = 1; + metadata->parameters.data = a404m_malloc(metadata->parameters.size * + sizeof(*metadata->parameters.data)); AstTree *operand = astTreeParse(node_metadata); if (operand == NULL) { - free(metadata->parameters); + free(metadata->parameters.data); free(metadata); return NULL; } - metadata->parameters[0] = (AstTreeFunctionCallParam){ + metadata->parameters.data[0] = (AstTreeFunctionCallParam){ .value = operand, .nameBegin = NULL, .nameEnd = NULL, @@ -3208,15 +3268,15 @@ AstTree *astTreeParseOperateAssignOperator(const ParserNode *parserNode, AstTreeFunctionCall *metadata = a404m_malloc(sizeof(*metadata)); - metadata->parameters_size = 2; - metadata->parameters = - a404m_malloc(metadata->parameters_size * sizeof(*metadata->parameters)); - metadata->parameters[0] = (AstTreeFunctionCallParam){ + metadata->parameters.size = 2; + metadata->parameters.data = a404m_malloc(metadata->parameters.size * + sizeof(*metadata->parameters.data)); + metadata->parameters.data[0] = (AstTreeFunctionCallParam){ .value = left, .nameBegin = NULL, .nameEnd = NULL, }; - metadata->parameters[1] = (AstTreeFunctionCallParam){ + metadata->parameters.data[1] = (AstTreeFunctionCallParam){ .value = right, .nameBegin = NULL, .nameEnd = NULL, @@ -3268,7 +3328,6 @@ bool astTreeParseConstant(const ParserNode *parserNode, variable->name_begin = node_metadata->name->str_begin; variable->name_end = node_metadata->name->str_end; variable->isConst = true; - variable->isLazy = node_metadata->isLazy; if (!pushVariable(variables, variable)) { astTreeVariableDelete(variable); @@ -3320,7 +3379,6 @@ AstTree *astTreeParseVariable(const ParserNode *parserNode, variable->name_begin = node_metadata->name->str_begin; variable->name_end = node_metadata->name->str_end; variable->isConst = false; - variable->isLazy = node_metadata->isLazy; if (!pushVariable(variables, variable)) { astTreeVariableDelete(variable); @@ -3642,7 +3700,6 @@ AstTree *astTreeParseStruct(const ParserNode *parserNode) { variable->initValue = NULL; variable->isConst = false; } - variable->isLazy = node_variable->isLazy; variables.data[i] = variable; } @@ -3689,6 +3746,11 @@ AstTree *astTreeParseBracket(const ParserNode *parserNode, AstTreeToken token) { metadata->operand = astTreeParse(node_metadata->operand); + if (metadata->operand == NULL) { + free(metadata); + return NULL; + } + metadata->parameters.size = node_metadata->params->size; metadata->parameters.data = a404m_malloc(sizeof(*metadata->parameters.data) * metadata->parameters.size); @@ -3701,6 +3763,11 @@ AstTree *astTreeParseBracket(const ParserNode *parserNode, AstTreeToken token) { } metadata->parameters.data[i] = astTreeParse(node_param); + + if (metadata->parameters.data[i] == NULL) { + free(metadata); + return NULL; + } } return newAstTree(token, metadata, NULL, parserNode->str_begin, @@ -3714,16 +3781,19 @@ AstTree *astTreeParseArrayAccessOperator(const ParserNode *parserNode) { metadata->function = NULL; - metadata->parameters_size = node_metadata->params->size + 1; - metadata->parameters = - a404m_malloc(metadata->parameters_size * sizeof(*metadata->parameters)); + metadata->parameters.size = node_metadata->params->size + 1; + metadata->parameters.data = a404m_malloc(metadata->parameters.size * + sizeof(*metadata->parameters.data)); - metadata->parameters[0].value = astTreeParse(node_metadata->operand); - metadata->parameters[0].nameBegin = NULL; - metadata->parameters[0].nameEnd = NULL; + AstTree *value = astTreeParse(node_metadata->operand); + metadata->parameters.data[0].value = + newAstTree(AST_TREE_TOKEN_OPERATOR_ADDRESS, value, NULL, value->str_begin, + value->str_end); + metadata->parameters.data[0].nameBegin = NULL; + metadata->parameters.data[0].nameEnd = NULL; - if (metadata->parameters[0].value == NULL) { - free(metadata->parameters); + if (metadata->parameters.data[0].value == NULL) { + free(metadata->parameters.data); free(metadata); return NULL; } @@ -3735,10 +3805,10 @@ AstTree *astTreeParseArrayAccessOperator(const ParserNode *parserNode) { node_param = (ParserNodeSingleChildMetadata *)node_param->metadata; } - metadata->parameters[i + 1].value = astTreeParse(node_param); - metadata->parameters[i + 1].nameBegin = NULL; - metadata->parameters[i + 1].nameEnd = NULL; - if (metadata->parameters[i + 1].value == NULL) { + metadata->parameters.data[i + 1].value = astTreeParse(node_param); + metadata->parameters.data[i + 1].nameBegin = NULL; + metadata->parameters.data[i + 1].nameEnd = NULL; + if (metadata->parameters.data[i + 1].value == NULL) { return NULL; } } @@ -3750,7 +3820,8 @@ AstTree *astTreeParseArrayAccessOperator(const ParserNode *parserNode) { bool isFunction(AstTree *value) { return value->type->token == AST_TREE_TOKEN_TYPE_FUNCTION || value->type->token == AST_TREE_TOKEN_TYPE_SHAPE_SHIFTER || - value->type->token == AST_TREE_TOKEN_TYPE_C_FUNCTION; + value->type->token == AST_TREE_TOKEN_TYPE_C_FUNCTION || + value->type->token == AST_TREE_TOKEN_TYPE_MACRO; } bool isShapeShifter(AstTreeFunction *function) { @@ -3819,6 +3890,7 @@ bool hasAnyTypeInside(AstTree *type) { case AST_TREE_TOKEN_TYPE_C_LIBRARY: case AST_TREE_TOKEN_TYPE_C_FUNCTION: case AST_TREE_TOKEN_TYPE_BOOL: + case AST_TREE_TOKEN_TYPE_MACRO: case AST_TREE_TOKEN_VALUE_NULL: case AST_TREE_TOKEN_VALUE_UNDEFINED: case AST_TREE_TOKEN_VALUE_VOID: @@ -3838,8 +3910,30 @@ bool hasAnyTypeInside(AstTree *type) { AstTreeBracket *metadata = type->metadata; return hasAnyTypeInside(metadata->operand); } + case AST_TREE_TOKEN_KEYWORD_STRUCT: { + AstTreeStruct *metadata = type->metadata; + for (size_t i = 0; i < metadata->variables.size; ++i) { + if (hasAnyTypeInside(metadata->variables.data[i]->type)) { + return true; + } + } + return false; + } + case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: + case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS_ASSIGN: + case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS_ADDRESS: + case AST_TREE_TOKEN_FUNCTION_CALL: { + AstTreeFunctionCall *metadata = type->metadata; + for (size_t i = 0; i < metadata->parameters.size; ++i) { + if (hasAnyTypeInside(metadata->parameters.data[i].value)) { + return true; + } + } + return false; + } case AST_TREE_TOKEN_VARIABLE: - case AST_TREE_TOKEN_FUNCTION_CALL: + case AST_TREE_TOKEN_OPERATOR_ADDRESS: + case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: return false; case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_KEYWORD_RETURN: @@ -3848,11 +3942,11 @@ bool hasAnyTypeInside(AstTree *type) { case AST_TREE_TOKEN_KEYWORD_IF: case AST_TREE_TOKEN_KEYWORD_WHILE: case AST_TREE_TOKEN_KEYWORD_COMPTIME: - case AST_TREE_TOKEN_KEYWORD_STRUCT: case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: case AST_TREE_TOKEN_VALUE_C_LIBRARY: case AST_TREE_TOKEN_VALUE_C_FUNCTION: + case AST_TREE_TOKEN_VALUE_MACRO: case AST_TREE_TOKEN_SHAPE_SHIFTER_ELEMENT: case AST_TREE_TOKEN_OPERATOR_ASSIGN: case AST_TREE_TOKEN_OPERATOR_PLUS: @@ -3868,15 +3962,10 @@ bool hasAnyTypeInside(AstTree *type) { case AST_TREE_TOKEN_OPERATOR_SMALLER: case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL: case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL: - case AST_TREE_TOKEN_OPERATOR_ADDRESS: - case AST_TREE_TOKEN_OPERATOR_DEREFERENCE: case AST_TREE_TOKEN_OPERATOR_ACCESS: case AST_TREE_TOKEN_OPERATOR_LOGICAL_NOT: case AST_TREE_TOKEN_OPERATOR_LOGICAL_AND: case AST_TREE_TOKEN_OPERATOR_LOGICAL_OR: - case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS: - case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS_ASSIGN: - case AST_TREE_TOKEN_OPERATOR_ARRAY_ACCESS_ADDRESS: case AST_TREE_TOKEN_OPERATOR_BITWISE_NOT: case AST_TREE_TOKEN_OPERATOR_BITWISE_AND: case AST_TREE_TOKEN_OPERATOR_BITWISE_XOR: @@ -3947,6 +4036,7 @@ bool isConst(AstTree *tree) { case AST_TREE_TOKEN_TYPE_SHAPE_SHIFTER: case AST_TREE_TOKEN_TYPE_C_LIBRARY: case AST_TREE_TOKEN_TYPE_C_FUNCTION: + case AST_TREE_TOKEN_TYPE_MACRO: case AST_TREE_TOKEN_TYPE_BOOL: case AST_TREE_TOKEN_VALUE_NULL: case AST_TREE_TOKEN_VALUE_UNDEFINED: @@ -4010,8 +4100,8 @@ bool isConst(AstTree *tree) { return true; } - for (size_t i = 0; i < metadata->parameters_size; ++i) { - if (!isConst(metadata->parameters[i].value)) { + for (size_t i = 0; i < metadata->parameters.size; ++i) { + if (!isConst(metadata->parameters.data[i].value)) { return false; } } @@ -4020,6 +4110,7 @@ bool isConst(AstTree *tree) { case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_VALUE_C_LIBRARY: case AST_TREE_TOKEN_VALUE_C_FUNCTION: + case AST_TREE_TOKEN_VALUE_MACRO: case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: case AST_TREE_TOKEN_SHAPE_SHIFTER_ELEMENT: { return true; @@ -4058,6 +4149,7 @@ bool isConst(AstTree *tree) { } printLog("Unknown token '%d'", tree->token); UNREACHABLE; + return NULL; } bool isLeftValue(AstTree *tree) { @@ -4116,7 +4208,9 @@ bool isLeftValue(AstTree *tree) { 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: @@ -4125,6 +4219,7 @@ bool isLeftValue(AstTree *tree) { case AST_TREE_TOKEN_TYPE_SHAPE_SHIFTER: case AST_TREE_TOKEN_TYPE_C_LIBRARY: case AST_TREE_TOKEN_TYPE_C_FUNCTION: + case AST_TREE_TOKEN_TYPE_MACRO: case AST_TREE_TOKEN_TYPE_BOOL: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_FUNCTION_CALL: @@ -4135,6 +4230,7 @@ bool isLeftValue(AstTree *tree) { case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: case AST_TREE_TOKEN_VALUE_C_LIBRARY: case AST_TREE_TOKEN_VALUE_C_FUNCTION: + case AST_TREE_TOKEN_VALUE_MACRO: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_FLOAT: case AST_TREE_TOKEN_VALUE_BOOL: @@ -4202,6 +4298,7 @@ AstTree *makeTypeOf(AstTree *value) { case AST_TREE_TOKEN_TYPE_SHAPE_SHIFTER: case AST_TREE_TOKEN_TYPE_C_LIBRARY: case AST_TREE_TOKEN_TYPE_C_FUNCTION: + case AST_TREE_TOKEN_TYPE_MACRO: case AST_TREE_TOKEN_TYPE_BOOL: case AST_TREE_TOKEN_OPERATOR_POINTER: case AST_TREE_TOKEN_KEYWORD_STRUCT: @@ -4354,6 +4451,7 @@ AstTree *makeTypeOf(AstTree *value) { case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: case AST_TREE_TOKEN_VALUE_C_LIBRARY: case AST_TREE_TOKEN_VALUE_C_FUNCTION: + case AST_TREE_TOKEN_VALUE_MACRO: case AST_TREE_TOKEN_RAW_VALUE: case AST_TREE_TOKEN_RAW_VALUE_NOT_OWNED: case AST_TREE_TOKEN_NONE: @@ -4450,6 +4548,7 @@ bool typeIsEqualBack(const AstTree *type0, const AstTree *type1, case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: case AST_TREE_TOKEN_VALUE_C_LIBRARY: case AST_TREE_TOKEN_VALUE_C_FUNCTION: + case AST_TREE_TOKEN_VALUE_MACRO: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_FLOAT: case AST_TREE_TOKEN_VALUE_BOOL: @@ -4513,6 +4612,7 @@ bool typeIsEqualBack(const AstTree *type0, const AstTree *type1, case AST_TREE_TOKEN_TYPE_NAMESPACE: case AST_TREE_TOKEN_TYPE_SHAPE_SHIFTER: case AST_TREE_TOKEN_TYPE_C_LIBRARY: + case AST_TREE_TOKEN_TYPE_MACRO: return type1->token == type0->token; case AST_TREE_TOKEN_TYPE_C_FUNCTION: { if (type1->token != type0->token) { @@ -4662,6 +4762,7 @@ AstTree *getValue(AstTree *tree, bool copy, AstTreeScope *scope) { case AST_TREE_TOKEN_TYPE_SHAPE_SHIFTER: case AST_TREE_TOKEN_TYPE_C_LIBRARY: case AST_TREE_TOKEN_TYPE_C_FUNCTION: + case AST_TREE_TOKEN_TYPE_MACRO: case AST_TREE_TOKEN_TYPE_BOOL: case AST_TREE_TOKEN_VALUE_NULL: case AST_TREE_TOKEN_VALUE_UNDEFINED: @@ -4731,6 +4832,7 @@ AstTree *getValue(AstTree *tree, bool copy, AstTreeScope *scope) { case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_VALUE_C_LIBRARY: case AST_TREE_TOKEN_VALUE_C_FUNCTION: + case AST_TREE_TOKEN_VALUE_MACRO: case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: { if (copy) { return copyAstTree(tree); @@ -4811,12 +4913,14 @@ bool isIntType(AstTree *type) { case AST_TREE_TOKEN_TYPE_SHAPE_SHIFTER: case AST_TREE_TOKEN_TYPE_C_LIBRARY: case AST_TREE_TOKEN_TYPE_C_FUNCTION: + case AST_TREE_TOKEN_TYPE_MACRO: case AST_TREE_TOKEN_TYPE_BOOL: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_NAMESPACE: case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: case AST_TREE_TOKEN_VALUE_C_LIBRARY: case AST_TREE_TOKEN_VALUE_C_FUNCTION: + case AST_TREE_TOKEN_VALUE_MACRO: case AST_TREE_TOKEN_FUNCTION_CALL: case AST_TREE_TOKEN_VARIABLE: case AST_TREE_TOKEN_VARIABLE_DEFINE: @@ -4930,12 +5034,14 @@ bool isFloatType(AstTree *type) { case AST_TREE_TOKEN_TYPE_SHAPE_SHIFTER: case AST_TREE_TOKEN_TYPE_C_LIBRARY: case AST_TREE_TOKEN_TYPE_C_FUNCTION: + case AST_TREE_TOKEN_TYPE_MACRO: case AST_TREE_TOKEN_TYPE_BOOL: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_NAMESPACE: case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: case AST_TREE_TOKEN_VALUE_C_LIBRARY: case AST_TREE_TOKEN_VALUE_C_FUNCTION: + case AST_TREE_TOKEN_VALUE_MACRO: case AST_TREE_TOKEN_FUNCTION_CALL: case AST_TREE_TOKEN_VARIABLE: case AST_TREE_TOKEN_VARIABLE_DEFINE: @@ -5015,6 +5121,7 @@ bool isEqual(AstTree *left, AstTree *right, AstTreeScope *scope) { case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_NULL: case AST_TREE_TOKEN_VALUE_UNDEFINED: + case AST_TREE_TOKEN_TYPE_MACRO: return true; case AST_TREE_TOKEN_TYPE_C_FUNCTION: { NOT_IMPLEMENTED; @@ -5044,6 +5151,23 @@ bool isEqual(AstTree *left, AstTree *right, AstTreeScope *scope) { return memcmp(left_metadata, right_metadata, getSizeOfType(left->type)) == 0; } + case AST_TREE_TOKEN_TYPE_ARRAY: { + AstTreeBracket *left_metadata = left->metadata; + AstTreeBracket *right_metadata = right->metadata; + + if (left_metadata->parameters.size != right_metadata->parameters.size) { + return false; + } + + for (size_t i = 0; i < left_metadata->parameters.size; ++i) { + if (!isEqual(left_metadata->parameters.data[i], + right_metadata->parameters.data[i], scope)) { + return false; + } + } + + return isEqual(left_metadata->operand, right_metadata->operand, scope); + } case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_BUILTIN_CAST: case AST_TREE_TOKEN_BUILTIN_TYPE_OF: @@ -5082,12 +5206,12 @@ bool isEqual(AstTree *left, AstTree *right, AstTreeScope *scope) { case AST_TREE_TOKEN_KEYWORD_COMPTIME: case AST_TREE_TOKEN_KEYWORD_STRUCT: case AST_TREE_TOKEN_TYPE_FUNCTION: - case AST_TREE_TOKEN_TYPE_ARRAY: case AST_TREE_TOKEN_FUNCTION_CALL: case AST_TREE_TOKEN_VARIABLE_DEFINE: case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: case AST_TREE_TOKEN_VALUE_C_LIBRARY: case AST_TREE_TOKEN_VALUE_C_FUNCTION: + case AST_TREE_TOKEN_VALUE_MACRO: case AST_TREE_TOKEN_VALUE_FLOAT: case AST_TREE_TOKEN_VALUE_BOOL: case AST_TREE_TOKEN_VALUE_OBJECT: @@ -5200,7 +5324,8 @@ bool setAllTypesRoot(AstTreeRoot *root) { .data = NULL, .size = 0, }, - .variables = variables, + .variables = &variables, + .variables_size = 1, .root = root, .loops = NULL, .loops_size = 0, @@ -5346,6 +5471,7 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, case AST_TREE_TOKEN_TYPE_NAMESPACE: case AST_TREE_TOKEN_TYPE_SHAPE_SHIFTER: case AST_TREE_TOKEN_TYPE_C_LIBRARY: + case AST_TREE_TOKEN_TYPE_MACRO: case AST_TREE_TOKEN_VALUE_VOID: return true; case AST_TREE_TOKEN_TYPE_C_FUNCTION: @@ -5515,6 +5641,7 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: case AST_TREE_TOKEN_VALUE_C_LIBRARY: case AST_TREE_TOKEN_VALUE_C_FUNCTION: + case AST_TREE_TOKEN_VALUE_MACRO: case AST_TREE_TOKEN_SHAPE_SHIFTER_ELEMENT: case AST_TREE_TOKEN_RAW_VALUE: case AST_TREE_TOKEN_RAW_VALUE_NOT_OWNED: @@ -5748,7 +5875,14 @@ bool setTypesValueObject(AstTree *tree, AstTreeSetTypesHelper helper) { bool setTypesFunction(AstTree *tree, AstTreeSetTypesHelper _helper) { AstTreeFunction *metadata = tree->metadata; - if (isShapeShifter(metadata)) { + if (metadata->isMacro) { + AstTreeMacro *new_metadata = a404m_malloc(sizeof(*new_metadata)); + new_metadata->function = metadata; + tree->metadata = new_metadata; + tree->token = AST_TREE_TOKEN_VALUE_MACRO; + tree->type = copyAstTree(&AST_TREE_MACRO_TYPE); + return true; + } else if (isShapeShifter(metadata)) { AstTreeShapeShifter *new_metadata = a404m_malloc(sizeof(*new_metadata)); new_metadata->function = metadata; new_metadata->generateds.size = 0; @@ -5760,91 +5894,7 @@ bool setTypesFunction(AstTree *tree, AstTreeSetTypesHelper _helper) { return true; } - // TODO: do something about macros - - AstTreeSetTypesHelper helper = { - .lookingType = NULL, - .dependencies = _helper.dependencies, - .variables.data = - a404m_malloc((_helper.variables.size + metadata->arguments.size + - metadata->scope.variables.size) * - sizeof(*helper.variables.data)), - .variables.size = _helper.variables.size, - .root = _helper.root, - .loops = NULL, - .loops_size = 0, - .scope = &metadata->scope, - .isInScope = true, - }; - - for (size_t i = 0; i < _helper.variables.size; ++i) { - helper.variables.data[i] = _helper.variables.data[i]; - } - - AstTreeVariable *deps[helper.dependencies.size]; - size_t deps_size = 0; - - for (size_t i = 0; i < metadata->arguments.size; ++i) { - AstTreeVariable *variable = metadata->arguments.data[i]; - if (!setTypesAstVariable(variable, helper)) { - return false; - } - helper.variables.data[helper.variables.size++] = variable; - } - - if (!setAllTypes(metadata->returnType, helper, NULL, NULL)) { - return false; - } - - tree->type = makeTypeOf(tree); - - for (size_t i = 0; i < helper.dependencies.size; ++i) { - AstTreeVariable *var = helper.dependencies.data[i]; - if (var->value == tree || var->initValue == tree) { - continue; - } - deps[deps_size] = helper.dependencies.data[i]; - deps_size += 1; - } - - helper.dependencies.data = deps; - helper.dependencies.size = deps_size; - - for (size_t i = 0; i < metadata->scope.variables.size; ++i) { - AstTreeVariable *variable = metadata->scope.variables.data[i]; - if (variable->isConst) { - if (!setTypesAstVariable(variable, helper)) { - return false; - } - helper.variables.data[helper.variables.size++] = variable; - } - } - - for (size_t i = 0; i < metadata->scope.expressions_size; ++i) { - AstTree *expr = metadata->scope.expressions[i]; - if (expr->token == AST_TREE_TOKEN_VARIABLE_DEFINE) { - AstTreeVariable *variable = expr->metadata; - if (!setTypesAstVariable(variable, helper)) { - return false; - } - size_t variables_capacity = - a404m_malloc_usable_size(helper.variables.data) / - sizeof(*helper.variables.data); - if (variables_capacity == helper.variables.size) { - variables_capacity += variables_capacity / 2 + 1; - helper.variables.data = - a404m_realloc(helper.variables.data, - variables_capacity * sizeof(*helper.variables.data)); - } - helper.variables.data[helper.variables.size++] = variable; - } - if (!setAllTypes(expr, helper, metadata, NULL)) { - return false; - } - } - - free(helper.variables.data); - return true; + return setTypesAstFunction(metadata, tree, _helper); } bool setTypesReturn(AstTree *tree, AstTreeSetTypesHelper _helper, @@ -5860,6 +5910,7 @@ bool setTypesReturn(AstTree *tree, AstTreeSetTypesHelper _helper, .lookingType = getValue(function->returnType, true, _helper.scope), .dependencies = _helper.dependencies, .variables = _helper.variables, + .variables_size = _helper.variables_size, .root = _helper.root, .loops = _helper.loops, .loops_size = _helper.loops_size, @@ -5946,6 +5997,7 @@ bool setTypesFunctionCall(AstTree *tree, AstTreeSetTypesHelper _helper) { .lookingType = NULL, .dependencies = _helper.dependencies, .variables = _helper.variables, + .variables_size = _helper.variables_size, .root = _helper.root, .loops = _helper.loops, .loops_size = _helper.loops_size, @@ -5953,8 +6005,8 @@ bool setTypesFunctionCall(AstTree *tree, AstTreeSetTypesHelper _helper) { .isInScope = false, }; - for (size_t i = 0; i < metadata->parameters_size; ++i) { - AstTreeFunctionCallParam param = metadata->parameters[i]; + for (size_t i = 0; i < metadata->parameters.size; ++i) { + AstTreeFunctionCallParam param = metadata->parameters.data[i]; if (!setAllTypes(param.value, helper, NULL, NULL)) { return false; } @@ -5971,10 +6023,10 @@ bool setTypesFunctionCall(AstTree *tree, AstTreeSetTypesHelper _helper) { if (metadata->function->type->token == AST_TREE_TOKEN_TYPE_FUNCTION) { AstTreeTypeFunction *function = metadata->function->type->metadata; if (function == NULL || - function->arguments_size != metadata->parameters_size) { + function->arguments_size != metadata->parameters.size) { printError(tree->str_begin, tree->str_end, "Arguments doesn't match %ld != %ld", function->arguments_size, - metadata->parameters_size); + metadata->parameters.size); return NULL; } @@ -6008,12 +6060,42 @@ bool setTypesFunctionCall(AstTree *tree, AstTreeSetTypesHelper _helper) { } tree->type = copyAstTree(function->returnType); + } else if (metadata->function->type->token == AST_TREE_TOKEN_TYPE_MACRO) { + metadata->function = getValue(metadata->function, false, helper.scope); + if (metadata->function->token != AST_TREE_TOKEN_VALUE_MACRO) { + UNREACHABLE; + } + AstTreeMacro *macro = metadata->function->metadata; + AstTreeFunction *function = + copyAstTreeFunction(macro->function, NULL, NULL, 0, true); + + if (!setTypesAstFunction(function, NULL, helper)) { + astTreeFunctionDestroy(*function); + free(function); + return false; + } + + AstTree *functionType = makeTypeOfFunction(function, NULL, NULL); + + if (!doesFunctionMatch(functionType->metadata, metadata, helper)) { + printError(tree->str_begin, tree->str_end, "Function call doesn't match"); + return NULL; + } + + const char *str_begin = metadata->function->str_begin; + const char *str_end = metadata->function->str_end; + astTreeDelete(metadata->function); + + metadata->function = newAstTree(AST_TREE_TOKEN_FUNCTION, function, + functionType, str_begin, str_end); + + tree->type = copyAstTree(function->returnType); } else { UNREACHABLE; } if (metadata->function->token == AST_TREE_TOKEN_BUILTIN_INSERT) { - char *code = u8ArrayToCString(metadata->parameters[0].value); + char *code = u8ArrayToCString(metadata->parameters.data[0].value); filePush("", code); LexerNodeArray lexerArray = lexer(code); if (lexerNodeArrayIsError(lexerArray)) { @@ -6151,6 +6233,7 @@ bool setTypesOperatorGeneral(AstTree *tree, AstTreeSetTypesHelper _helper, .lookingType = NULL, .dependencies = _helper.dependencies, .variables = _helper.variables, + .variables_size = _helper.variables_size, .root = _helper.root, .loops = _helper.loops, .loops_size = _helper.loops_size, @@ -6158,8 +6241,8 @@ bool setTypesOperatorGeneral(AstTree *tree, AstTreeSetTypesHelper _helper, .isInScope = false, }; - for (size_t i = 0; i < metadata->parameters_size; ++i) { - if (!setAllTypes(metadata->parameters[i].value, helper, NULL, NULL)) { + for (size_t i = 0; i < metadata->parameters.size; ++i) { + if (!setAllTypes(metadata->parameters.data[i].value, helper, NULL, NULL)) { return false; } } @@ -6180,6 +6263,36 @@ bool setTypesOperatorGeneral(AstTree *tree, AstTreeSetTypesHelper _helper, if (metadata->function->type->token == AST_TREE_TOKEN_TYPE_FUNCTION) { AstTreeTypeFunction *function = metadata->function->type->metadata; tree->type = copyAstTree(function->returnType); + } else if (metadata->function->type->token == AST_TREE_TOKEN_TYPE_MACRO) { + metadata->function = getValue(metadata->function, false, helper.scope); + if (metadata->function->token != AST_TREE_TOKEN_VALUE_MACRO) { + UNREACHABLE; + } + AstTreeMacro *macro = metadata->function->metadata; + AstTreeFunction *function = + copyAstTreeFunction(macro->function, NULL, NULL, 0, true); + + if (!setTypesAstFunction(function, NULL, helper)) { + astTreeFunctionDestroy(*function); + free(function); + return false; + } + + AstTree *functionType = makeTypeOfFunction(function, NULL, NULL); + + if (!doesFunctionMatch(functionType->metadata, metadata, helper)) { + printError(tree->str_begin, tree->str_end, "Function call doesn't match"); + return NULL; + } + + const char *str_begin = metadata->function->str_begin; + const char *str_end = metadata->function->str_end; + astTreeDelete(metadata->function); + + metadata->function = newAstTree(AST_TREE_TOKEN_FUNCTION, function, + functionType, str_begin, str_end); + + tree->type = copyAstTree(function->returnType); } else if (metadata->function->type->token == AST_TREE_TOKEN_TYPE_SHAPE_SHIFTER) { AstTree *function = getShapeShifterElement(metadata, helper); @@ -6190,6 +6303,7 @@ bool setTypesOperatorGeneral(AstTree *tree, AstTreeSetTypesHelper _helper, AstTreeTypeFunction *functionType = metadata->function->type->metadata; tree->type = copyAstTree(functionType->returnType); } else { + printLog("%s", AST_TREE_TOKEN_STRINGS[metadata->function->type->token]); UNREACHABLE; } @@ -6245,6 +6359,23 @@ bool setTypesVariableDefine(AstTree *tree, AstTreeSetTypesHelper helper) { bool setTypesAstVariable(AstTreeVariable *variable, AstTreeSetTypesHelper _helper) { + for (size_t i = 0; i < _helper.variables[0].size; ++i) { // TODO: change this + if (variable == _helper.variables[0].data[i]) { + _helper = (AstTreeSetTypesHelper){ + .root = _helper.root, + .variables = _helper.variables, + .variables_size = 1, + .dependencies = _helper.dependencies, + .lookingType = _helper.lookingType, + .loops = _helper.loops, + .loops_size = _helper.loops_size, + .scope = _helper.scope, + .isInScope = false, + }; + break; + } + } + AstTreeVariable *deps[_helper.dependencies.size + 1]; for (size_t i = 0; i < _helper.dependencies.size; ++i) { @@ -6263,6 +6394,7 @@ bool setTypesAstVariable(AstTreeVariable *variable, .dependencies.data = deps, .dependencies.size = _helper.dependencies.size + 1, .variables = _helper.variables, + .variables_size = _helper.variables_size, .root = _helper.root, .loops = _helper.loops, .loops_size = _helper.loops_size, @@ -6390,6 +6522,7 @@ bool setTypesIf(AstTree *tree, AstTreeSetTypesHelper helper, if (!setAllTypes(metadata->ifBody, helper, function, NULL) || (metadata->elseBody != NULL && !setAllTypes(metadata->elseBody, helper, function, NULL))) { + return false; } if (metadata->elseBody != NULL && @@ -6420,6 +6553,7 @@ bool setTypesWhile(AstTree *tree, AstTreeSetTypesHelper _helper, .lookingType = NULL, .dependencies = _helper.dependencies, .variables = _helper.variables, + .variables_size = _helper.variables_size, .root = _helper.root, .loops = loops, .loops_size = loops_size, @@ -6459,13 +6593,22 @@ bool setTypesScope(AstTree *tree, AstTreeSetTypesHelper _helper, AstTreeFunction *function) { AstTreeScope *metadata = tree->metadata; + AstTreeVariables variables[_helper.variables_size + 1]; + + for (size_t i = 0; i < _helper.variables_size; ++i) { + variables[i] = _helper.variables[i]; + } + + variables[_helper.variables_size].data = + a404m_malloc(metadata->variables.size * + sizeof(*variables[_helper.variables_size].data)); + variables[_helper.variables_size].size = 0; + AstTreeSetTypesHelper helper = { .lookingType = NULL, .dependencies = _helper.dependencies, - .variables.data = - a404m_malloc((_helper.variables.size + metadata->variables.size) * - sizeof(*helper.variables.data)), - .variables.size = _helper.variables.size, + .variables = variables, + .variables_size = _helper.variables_size + 1, .root = _helper.root, .loops = _helper.loops, .loops_size = _helper.loops_size, @@ -6473,17 +6616,14 @@ bool setTypesScope(AstTree *tree, AstTreeSetTypesHelper _helper, .isInScope = true, }; - for (size_t i = 0; i < _helper.variables.size; ++i) { - helper.variables.data[i] = _helper.variables.data[i]; - } - for (size_t i = 0; i < metadata->variables.size; ++i) { AstTreeVariable *variable = metadata->variables.data[i]; if (variable->isConst) { if (!setTypesAstVariable(variable, helper)) { return false; } - helper.variables.data[helper.variables.size++] = variable; + helper.variables[helper.variables_size - 1] + .data[helper.variables[helper.variables_size - 1].size++] = variable; } } @@ -6495,15 +6635,19 @@ bool setTypesScope(AstTree *tree, AstTreeSetTypesHelper _helper, return false; } size_t variables_capacity = - a404m_malloc_usable_size(helper.variables.data) / - sizeof(*helper.variables.data); - if (variables_capacity == helper.variables.size) { + a404m_malloc_usable_size( + helper.variables[helper.variables_size - 1].data) / + sizeof(*helper.variables[helper.variables_size - 1].data); + if (variables_capacity == + helper.variables[helper.variables_size - 1].size) { variables_capacity += variables_capacity / 2 + 1; - helper.variables.data = - a404m_realloc(helper.variables.data, - variables_capacity * sizeof(*helper.variables.data)); + helper.variables[helper.variables_size - 1].data = a404m_realloc( + helper.variables[helper.variables_size - 1].data, + variables_capacity * + sizeof(*helper.variables[helper.variables_size - 1].data)); } - helper.variables.data[helper.variables.size++] = variable; + helper.variables[helper.variables_size - 1] + .data[helper.variables[helper.variables_size - 1].size++] = variable; } if (!setAllTypes(expr, helper, function, NULL)) { return false; @@ -6517,7 +6661,7 @@ bool setTypesScope(AstTree *tree, AstTreeSetTypesHelper _helper, metadata->expressions[metadata->expressions_size - 1]->type); } - free(helper.variables.data); + free(helper.variables[helper.variables_size - 1].data); return true; } @@ -6607,7 +6751,8 @@ bool setTypesOperatorAccess(AstTree *tree, AstTreeSetTypesHelper helper) { AstTreeSetTypesHelper newHelper = { .root = helper.root->imports[namespace->importedIndex].root, .variables = - helper.root->imports[namespace->importedIndex].root->variables, + &helper.root->imports[namespace->importedIndex].root->variables, + .variables_size = 1, .dependencies = helper.dependencies, .lookingType = helper.lookingType, .loops = helper.loops, @@ -6645,7 +6790,7 @@ bool setTypesOperatorAccess(AstTree *tree, AstTreeSetTypesHelper helper) { bool setTypesBuiltinCast(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunctionCall *functionCall) { (void)helper; - if (functionCall->parameters_size == 2) { + if (functionCall->parameters.size == 2) { AstTree *from = NULL; AstTree *to = NULL; @@ -6656,8 +6801,8 @@ bool setTypesBuiltinCast(AstTree *tree, AstTreeSetTypesHelper helper, static const size_t TO_STR_SIZE = sizeof(TO_STR) / sizeof(*TO_STR) - sizeof(*TO_STR); - for (size_t i = 0; i < functionCall->parameters_size; ++i) { - AstTreeFunctionCallParam param = functionCall->parameters[i]; + for (size_t i = 0; i < functionCall->parameters.size; ++i) { + AstTreeFunctionCallParam param = functionCall->parameters.data[i]; const size_t param_name_size = param.nameEnd - param.nameBegin; if (param_name_size == 0) { @@ -6727,15 +6872,15 @@ bool setTypesBuiltinCast(AstTree *tree, AstTreeSetTypesHelper helper, bool setTypesBuiltinTypeOf(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunctionCall *functionCall) { (void)helper; - if (functionCall->parameters_size == 1) { + if (functionCall->parameters.size == 1) { AstTree *variable = NULL; static const char VARIABLE_STR[] = "variable"; static const size_t VARIABLE_STR_SIZE = sizeof(VARIABLE_STR) / sizeof(*VARIABLE_STR) - sizeof(*VARIABLE_STR); - for (size_t i = 0; i < functionCall->parameters_size; ++i) { - AstTreeFunctionCallParam param = functionCall->parameters[i]; + for (size_t i = 0; i < functionCall->parameters.size; ++i) { + AstTreeFunctionCallParam param = functionCall->parameters.data[i]; const size_t param_name_size = param.nameEnd - param.nameBegin; if (param_name_size == 0) { @@ -6790,15 +6935,15 @@ bool setTypesBuiltinTypeOf(AstTree *tree, AstTreeSetTypesHelper helper, bool setTypesBuiltinSizeOf(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunctionCall *functionCall) { (void)helper; - if (functionCall->parameters_size == 1) { + if (functionCall->parameters.size == 1) { AstTree *type = NULL; static const char TYPE_STR[] = "type"; static const size_t TYPE_STR_SIZE = sizeof(TYPE_STR) / sizeof(*TYPE_STR) - sizeof(*TYPE_STR); - for (size_t i = 0; i < functionCall->parameters_size; ++i) { - AstTreeFunctionCallParam param = functionCall->parameters[i]; + for (size_t i = 0; i < functionCall->parameters.size; ++i) { + AstTreeFunctionCallParam param = functionCall->parameters.data[i]; const size_t param_name_size = param.nameEnd - param.nameBegin; if (param_name_size == 0) { @@ -6857,15 +7002,15 @@ bool setTypesBuiltinSizeOf(AstTree *tree, AstTreeSetTypesHelper helper, bool setTypesBuiltinImport(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunctionCall *functionCall) { (void)helper; - if (functionCall->parameters_size == 1) { + if (functionCall->parameters.size == 1) { AstTree *file = NULL; static const char PATH_STR[] = "path"; static const size_t PATH_STR_SIZE = sizeof(PATH_STR) / sizeof(*PATH_STR) - sizeof(*PATH_STR); - for (size_t i = 0; i < functionCall->parameters_size; ++i) { - AstTreeFunctionCallParam param = functionCall->parameters[i]; + for (size_t i = 0; i < functionCall->parameters.size; ++i) { + AstTreeFunctionCallParam param = functionCall->parameters.data[i]; const size_t param_name_size = param.nameEnd - param.nameBegin; if (param_name_size == 0) { @@ -6935,7 +7080,7 @@ bool setTypesBuiltinIsComptime(AstTree *tree, AstTreeSetTypesHelper helper) { bool setTypesBuiltinStackAlloc(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunctionCall *functionCall) { (void)helper; - if (functionCall->parameters_size == 2) { + if (functionCall->parameters.size == 2) { AstTree *count = NULL; AstTree *type = NULL; @@ -6946,8 +7091,8 @@ bool setTypesBuiltinStackAlloc(AstTree *tree, AstTreeSetTypesHelper helper, static const size_t COUNT_STR_SIZE = sizeof(COUNT_STR) / sizeof(*COUNT_STR) - sizeof(*COUNT_STR); - for (size_t i = 0; i < functionCall->parameters_size; ++i) { - AstTreeFunctionCallParam param = functionCall->parameters[i]; + for (size_t i = 0; i < functionCall->parameters.size; ++i) { + AstTreeFunctionCallParam param = functionCall->parameters.data[i]; const size_t param_name_size = param.nameEnd - param.nameBegin; if (param_name_size == 0) { @@ -7036,14 +7181,14 @@ bool setTypesBuiltinHeapAlloc(AstTree *tree, AstTreeSetTypesHelper helper, bool setTypesBuiltinUnary(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunctionCall *functionCall) { (void)helper; - if (functionCall->parameters_size != 1) { + if (functionCall->parameters.size != 1) { printError(tree->str_begin, tree->str_end, "Too many or too few arguments"); return false; } - const char *str = functionCall->parameters[0].nameBegin; - const size_t str_size = functionCall->parameters[0].nameEnd - - functionCall->parameters[0].nameBegin; + const char *str = functionCall->parameters.data[0].nameBegin; + const size_t str_size = functionCall->parameters.data[0].nameEnd - + functionCall->parameters.data[0].nameBegin; static char VALUE_STR[] = "value"; static size_t VALUE_STR_SIZE = @@ -7051,12 +7196,12 @@ bool setTypesBuiltinUnary(AstTree *tree, AstTreeSetTypesHelper helper, if (str_size != 0 && (str_size != VALUE_STR_SIZE || !strnEquals(str, VALUE_STR, VALUE_STR_SIZE))) { - printError(functionCall->parameters[0].nameBegin, - functionCall->parameters[0].nameEnd, "Unknown parameter"); + printError(functionCall->parameters.data[0].nameBegin, + functionCall->parameters.data[0].nameEnd, "Unknown parameter"); return false; } - AstTree *type = functionCall->parameters[0].value->type; + AstTree *type = functionCall->parameters.data[0].value->type; switch (type->token) { case AST_TREE_TOKEN_TYPE_I8: case AST_TREE_TOKEN_TYPE_U8: @@ -7066,7 +7211,9 @@ bool setTypesBuiltinUnary(AstTree *tree, AstTreeSetTypesHelper helper, 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: @@ -7075,6 +7222,7 @@ bool setTypesBuiltinUnary(AstTree *tree, AstTreeSetTypesHelper helper, case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: case AST_TREE_TOKEN_VALUE_C_LIBRARY: case AST_TREE_TOKEN_VALUE_C_FUNCTION: + case AST_TREE_TOKEN_VALUE_MACRO: case AST_TREE_TOKEN_BUILTIN_CAST: case AST_TREE_TOKEN_BUILTIN_TYPE_OF: case AST_TREE_TOKEN_BUILTIN_SIZE_OF: @@ -7122,6 +7270,7 @@ bool setTypesBuiltinUnary(AstTree *tree, AstTreeSetTypesHelper helper, case AST_TREE_TOKEN_TYPE_C_LIBRARY: case AST_TREE_TOKEN_TYPE_C_FUNCTION: case AST_TREE_TOKEN_TYPE_BOOL: + case AST_TREE_TOKEN_TYPE_MACRO: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_NAMESPACE: case AST_TREE_TOKEN_FUNCTION_CALL: @@ -7169,8 +7318,8 @@ bool setTypesBuiltinUnary(AstTree *tree, AstTreeSetTypesHelper helper, case AST_TREE_TOKEN_SHAPE_SHIFTER_ELEMENT: case AST_TREE_TOKEN_NONE: } - printError(functionCall->parameters[0].nameBegin, - functionCall->parameters[0].nameEnd, "Bad argument"); + printError(functionCall->parameters.data[0].nameBegin, + functionCall->parameters.data[0].nameEnd, "Bad argument"); return false; AFTER_SWITCH: @@ -7199,8 +7348,7 @@ AFTER_SWITCH: bool setTypesBuiltinBinaryAlsoPointer(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunctionCall *functionCall) { - (void)helper; - if (functionCall->parameters_size != 2) { + if (functionCall->parameters.size != 2) { printError(tree->str_begin, tree->str_end, "Too many or too few arguments"); return false; } @@ -7214,8 +7362,8 @@ bool setTypesBuiltinBinaryAlsoPointer(AstTree *tree, static const size_t RIGHT_STR_SIZE = sizeof(RIGHT_STR) / sizeof(*RIGHT_STR) - sizeof(*RIGHT_STR); - for (size_t i = 0; i < functionCall->parameters_size; ++i) { - AstTreeFunctionCallParam param = functionCall->parameters[i]; + for (size_t i = 0; i < functionCall->parameters.size; ++i) { + AstTreeFunctionCallParam param = functionCall->parameters.data[i]; const size_t param_name_size = param.nameEnd - param.nameBegin; if (param_name_size == 0) { @@ -7289,8 +7437,7 @@ bool setTypesBuiltinBinaryAlsoPointer(AstTree *tree, bool setTypesBuiltinBinary(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunctionCall *functionCall) { - (void)helper; - if (functionCall->parameters_size != 2) { + if (functionCall->parameters.size != 2) { printError(tree->str_begin, tree->str_end, "Too many or too few arguments"); return false; } @@ -7304,8 +7451,8 @@ bool setTypesBuiltinBinary(AstTree *tree, AstTreeSetTypesHelper helper, static const size_t RIGHT_STR_SIZE = sizeof(RIGHT_STR) / sizeof(*RIGHT_STR) - sizeof(*RIGHT_STR); - for (size_t i = 0; i < functionCall->parameters_size; ++i) { - AstTreeFunctionCallParam param = functionCall->parameters[i]; + for (size_t i = 0; i < functionCall->parameters.size; ++i) { + AstTreeFunctionCallParam param = functionCall->parameters.data[i]; const size_t param_name_size = param.nameEnd - param.nameBegin; if (param_name_size == 0) { @@ -7374,7 +7521,7 @@ bool setTypesBuiltinBinaryWithRet(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunctionCall *functionCall, AstTree *retType) { (void)helper; - if (functionCall->parameters_size != 2) { + if (functionCall->parameters.size != 2) { printError(tree->str_begin, tree->str_end, "Too many or too few arguments"); return false; } @@ -7388,8 +7535,8 @@ bool setTypesBuiltinBinaryWithRet(AstTree *tree, AstTreeSetTypesHelper helper, static const size_t RIGHT_STR_SIZE = sizeof(RIGHT_STR) / sizeof(*RIGHT_STR) - sizeof(*RIGHT_STR); - for (size_t i = 0; i < functionCall->parameters_size; ++i) { - AstTreeFunctionCallParam param = functionCall->parameters[i]; + for (size_t i = 0; i < functionCall->parameters.size; ++i) { + AstTreeFunctionCallParam param = functionCall->parameters.data[i]; const size_t param_name_size = param.nameEnd - param.nameBegin; if (param_name_size == 0) { @@ -7453,15 +7600,14 @@ bool setTypesBuiltinBinaryWithRet(AstTree *tree, AstTreeSetTypesHelper helper, bool setTypesBuiltinPutc(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunctionCall *functionCall) { - (void)helper; - if (functionCall->parameters_size != 1) { + if (functionCall->parameters.size != 1) { printError(tree->str_begin, tree->str_end, "Too many or too few arguments"); return false; } - const char *str = functionCall->parameters[0].nameBegin; - const size_t str_size = functionCall->parameters[0].nameEnd - - functionCall->parameters[0].nameBegin; + const char *str = functionCall->parameters.data[0].nameBegin; + const size_t str_size = functionCall->parameters.data[0].nameEnd - + functionCall->parameters.data[0].nameBegin; static char VALUE_STR[] = "value"; static size_t VALUE_STR_SIZE = @@ -7469,15 +7615,15 @@ bool setTypesBuiltinPutc(AstTree *tree, AstTreeSetTypesHelper helper, if (str_size != 0 && (str_size != VALUE_STR_SIZE || !strnEquals(str, VALUE_STR, VALUE_STR_SIZE))) { - printError(functionCall->parameters[0].nameBegin, - functionCall->parameters[0].nameEnd, "Unknown parameter"); + printError(functionCall->parameters.data[0].nameBegin, + functionCall->parameters.data[0].nameEnd, "Unknown parameter"); return false; } - if (!typeIsEqual(functionCall->parameters[0].value->type, &AST_TREE_U8_TYPE, - helper.scope)) { - printError(functionCall->parameters[0].nameBegin, - functionCall->parameters[0].nameEnd, + if (!typeIsEqual(functionCall->parameters.data[0].value->type, + &AST_TREE_U8_TYPE, helper.scope)) { + printError(functionCall->parameters.data[0].nameBegin, + functionCall->parameters.data[0].nameEnd, "Bad argument (must have a type of u8)"); return false; } @@ -7506,16 +7652,15 @@ bool setTypesBuiltinPutc(AstTree *tree, AstTreeSetTypesHelper helper, bool setTypesBuiltinCLibrary(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunctionCall *functionCall) { - (void)helper; - if (functionCall->parameters_size == 1) { + if (functionCall->parameters.size == 1) { AstTree *path = NULL; static const char PATH_STR[] = "path"; static const size_t PATH_STR_SIZE = sizeof(PATH_STR) / sizeof(*PATH_STR) - sizeof(*PATH_STR); - for (size_t i = 0; i < functionCall->parameters_size; ++i) { - AstTreeFunctionCallParam param = functionCall->parameters[i]; + for (size_t i = 0; i < functionCall->parameters.size; ++i) { + AstTreeFunctionCallParam param = functionCall->parameters.data[i]; const size_t param_name_size = param.nameEnd - param.nameBegin; if (param_name_size == 0) { @@ -7576,8 +7721,7 @@ bool setTypesBuiltinCLibrary(AstTree *tree, AstTreeSetTypesHelper helper, bool setTypesBuiltinCFunction(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunctionCall *functionCall) { - (void)helper; - if (functionCall->parameters_size != 3) { + if (functionCall->parameters.size != 3) { printError(tree->str_begin, tree->str_end, "Too many or too few arguments"); return false; } @@ -7595,8 +7739,8 @@ bool setTypesBuiltinCFunction(AstTree *tree, AstTreeSetTypesHelper helper, static const size_t FUNC_TYPE_STR_SIZE = sizeof(FUNC_TYPE_STR) / sizeof(*FUNC_TYPE_STR) - sizeof(*FUNC_TYPE_STR); - for (size_t i = 0; i < functionCall->parameters_size; ++i) { - AstTreeFunctionCallParam param = functionCall->parameters[i]; + for (size_t i = 0; i < functionCall->parameters.size; ++i) { + AstTreeFunctionCallParam param = functionCall->parameters.data[i]; const size_t param_name_size = param.nameEnd - param.nameBegin; if (param_name_size == 0) { @@ -7697,15 +7841,14 @@ bool setTypesBuiltinCFunction(AstTree *tree, AstTreeSetTypesHelper helper, bool setTypesBuiltinInsert(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeFunctionCall *functionCall) { - (void)helper; - if (functionCall->parameters_size != 1) { + if (functionCall->parameters.size != 1) { printError(tree->str_begin, tree->str_end, "Too many or too few arguments"); return false; } - const char *str = functionCall->parameters[0].nameBegin; - const size_t str_size = functionCall->parameters[0].nameEnd - - functionCall->parameters[0].nameBegin; + const char *str = functionCall->parameters.data[0].nameBegin; + const size_t str_size = functionCall->parameters.data[0].nameEnd - + functionCall->parameters.data[0].nameBegin; static char CODE_STR[] = "code"; static size_t CODE_STR_SIZE = @@ -7713,22 +7856,22 @@ bool setTypesBuiltinInsert(AstTree *tree, AstTreeSetTypesHelper helper, if (str_size != 0 && (str_size != CODE_STR_SIZE || !strnEquals(str, CODE_STR, CODE_STR_SIZE))) { - printError(functionCall->parameters[0].nameBegin, - functionCall->parameters[0].nameEnd, "Unknown parameter"); + printError(functionCall->parameters.data[0].nameBegin, + functionCall->parameters.data[0].nameEnd, "Unknown parameter"); return false; } - AstTree *type = functionCall->parameters[0].value->type; + AstTree *type = functionCall->parameters.data[0].value->type; AstTree *stringType = makeStringType(); if (typeIsEqual(type->type, stringType, helper.scope)) { astTreeDelete(stringType); - printError(functionCall->parameters[0].nameBegin, - functionCall->parameters[0].nameEnd, + printError(functionCall->parameters.data[0].nameBegin, + functionCall->parameters.data[0].nameEnd, "Type mismatch it must be `code`"); return false; - } else if (!isConst(functionCall->parameters[0].value)) { - printError(functionCall->parameters[0].nameBegin, - functionCall->parameters[0].nameEnd, "Must be const"); + } else if (!isConst(functionCall->parameters.data[0].value)) { + printError(functionCall->parameters.data[0].nameBegin, + functionCall->parameters.data[0].nameEnd, "Must be const"); return false; } astTreeDelete(stringType); @@ -7780,6 +7923,7 @@ bool setTypesTypeArray(AstTree *tree, AstTreeSetTypesHelper helper) { .lookingType = &AST_TREE_U64_TYPE, .dependencies = helper.dependencies, .variables = helper.variables, + .variables_size = helper.variables_size, .root = helper.root, .loops = helper.loops, .loops_size = helper.loops_size, @@ -7820,6 +7964,7 @@ bool setTypesAstInfix(AstTreePureInfix *infix, AstTreeSetTypesHelper _helper) { .lookingType = NULL, .dependencies = _helper.dependencies, .variables = _helper.variables, + .variables_size = _helper.variables_size, .root = _helper.root, .loops = _helper.loops, .loops_size = _helper.loops_size, @@ -7836,61 +7981,70 @@ bool setTypesAstInfix(AstTreePureInfix *infix, AstTreeSetTypesHelper _helper) { return setAllTypes(infix->right, helper, NULL, NULL); } -bool setTypesAstFunction(AstTreeFunction *metadata, +bool setTypesAstFunction(AstTreeFunction *metadata, AstTree *tree, AstTreeSetTypesHelper _helper) { + AstTreeVariables variables[_helper.variables_size + 1]; + + for (size_t i = 0; i < _helper.variables_size; ++i) { + variables[i] = _helper.variables[i]; + } + + variables[_helper.variables_size].data = + a404m_malloc((metadata->arguments.size + metadata->scope.variables.size) * + sizeof(*variables[_helper.variables_size].data)); + variables[_helper.variables_size].size = 0; + AstTreeSetTypesHelper helper = { .lookingType = NULL, .dependencies = _helper.dependencies, - .variables.data = - a404m_malloc((_helper.variables.size + metadata->arguments.size + - metadata->scope.variables.size) * - sizeof(*_helper.variables.data)), - .variables.size = _helper.variables.size, + .variables = variables, + .variables_size = _helper.variables_size + 1, .root = _helper.root, - .loops = _helper.loops, - .loops_size = _helper.loops_size, + .loops = NULL, + .loops_size = 0, .scope = &metadata->scope, .isInScope = true, }; - for (size_t i = 0; i < _helper.variables.size; ++i) { - helper.variables.data[i] = _helper.variables.data[i]; - } - - AstTreeVariable *deps[helper.dependencies.size]; - size_t deps_size = 0; - for (size_t i = 0; i < metadata->arguments.size; ++i) { AstTreeVariable *variable = metadata->arguments.data[i]; if (!setTypesAstVariable(variable, helper)) { return false; } - helper.variables.data[helper.variables.size++] = variable; + helper.variables[helper.variables_size - 1] + .data[helper.variables[helper.variables_size - 1].size++] = variable; } if (!setAllTypes(metadata->returnType, helper, NULL, NULL)) { return false; } + metadata->returnType = getValue(metadata->returnType, false, helper.scope); - if (isConst(metadata->returnType)) { - metadata->returnType = getValue(metadata->returnType, false, helper.scope); - } + AstTreeVariable *deps[helper.dependencies.size]; + size_t deps_size = 0; + if (tree != NULL) { + tree->type = makeTypeOf(tree); - for (size_t i = 0; i < helper.dependencies.size; ++i) { - deps[deps_size] = helper.dependencies.data[i]; - deps_size += 1; + for (size_t i = 0; i < helper.dependencies.size; ++i) { + AstTreeVariable *var = helper.dependencies.data[i]; + if (var->value == tree || var->initValue == tree) { + continue; + } + deps[deps_size] = helper.dependencies.data[i]; + deps_size += 1; + } + helper.dependencies.data = deps; + helper.dependencies.size = deps_size; } - helper.dependencies.data = deps; - helper.dependencies.size = deps_size; - for (size_t i = 0; i < metadata->scope.variables.size; ++i) { AstTreeVariable *variable = metadata->scope.variables.data[i]; if (variable->isConst) { if (!setTypesAstVariable(variable, helper)) { return false; } - helper.variables.data[helper.variables.size++] = variable; + helper.variables[helper.variables_size - 1] + .data[helper.variables[helper.variables_size - 1].size++] = variable; } } @@ -7902,22 +8056,26 @@ bool setTypesAstFunction(AstTreeFunction *metadata, return false; } size_t variables_capacity = - a404m_malloc_usable_size(helper.variables.data) / - sizeof(*helper.variables.data); - if (variables_capacity == helper.variables.size) { + a404m_malloc_usable_size( + helper.variables[helper.variables_size - 1].data) / + sizeof(*helper.variables[helper.variables_size - 1].data); + if (variables_capacity == + helper.variables[helper.variables_size - 1].size) { variables_capacity += variables_capacity / 2 + 1; - helper.variables.data = - a404m_realloc(helper.variables.data, - variables_capacity * sizeof(*helper.variables.data)); + helper.variables[helper.variables_size - 1].data = a404m_realloc( + helper.variables[helper.variables_size - 1].data, + variables_capacity * + sizeof(*helper.variables[helper.variables_size - 1].data)); } - helper.variables.data[helper.variables.size++] = variable; + helper.variables[helper.variables_size - 1] + .data[helper.variables[helper.variables_size - 1].size++] = variable; } if (!setAllTypes(expr, helper, metadata, NULL)) { return false; } } - free(helper.variables.data); + free(helper.variables[helper.variables_size - 1].data); return true; } @@ -7937,93 +8095,140 @@ AstTreeVariable *setTypesFindVariable(const char *name_begin, const size_t str_size = name_end - name_begin; if (functionCall == NULL) { - for (size_t i = helper.variables.size - 1; i != -1ULL; --i) { - AstTreeVariable *var = helper.variables.data[i]; + for (size_t i = helper.variables_size - 1; i != -1ULL; --i) { + AstTreeVariables variables = helper.variables[i]; + for (size_t j = variables.size - 1; j != -1ULL; --j) { + AstTreeVariable *var = variables.data[j]; - const char *var_str = var->name_begin; - const size_t var_str_size = var->name_end - var->name_begin; + const char *var_str = var->name_begin; + const size_t var_str_size = var->name_end - var->name_begin; - if (var_str_size != str_size || !strnEquals(var_str, str, str_size)) { - continue; - } - - if (!setTypesAstVariable(var, helper)) { - return NULL; - } - - variable.var = var; - variable.op = 0; - break; - } - } else { - for (size_t i = helper.variables.size - 1; i != -1ULL; --i) { - AstTreeVariable *var = helper.variables.data[i]; - - const char *var_str = var->name_begin; - const size_t var_str_size = var->name_end - var->name_begin; - - if (var_str_size != str_size || !strnEquals(var_str, str, str_size)) { - continue; - } - - if (!setTypesAstVariable(var, helper)) { - return NULL; - } - - if (var->type->token == AST_TREE_TOKEN_TYPE_FUNCTION) { - AstTreeTypeFunction *function = var->type->metadata; - - if (!doesFunctionMatch(function, functionCall, helper)) { + if (var_str_size != str_size || !strnEquals(var_str, str, str_size)) { continue; } - if (variable.var != NULL && variable.op == 0) { - printError(name_begin, name_end, "Multiple candidates found for %.*s", - (int)(name_end - name_begin), name_begin); + if (!setTypesAstVariable(var, helper)) { return NULL; } + variable.var = var; variable.op = 0; - } else if (var->type->token == AST_TREE_TOKEN_TYPE_SHAPE_SHIFTER) { - if (variable.op < 1) { - continue; - } - AstTreeShapeShifter *shapeShifter = var->value->metadata; + goto END; + break; + } + } + } else { + for (size_t i = helper.variables_size - 1; i != -1ULL; --i) { + AstTreeVariables variables = helper.variables[i]; + for (size_t j = variables.size - 1; j != -1ULL; --j) { + AstTreeVariable *var = variables.data[j]; + + const char *var_str = var->name_begin; + const size_t var_str_size = var->name_end - var->name_begin; - if (!doesShapeShifterMatch(shapeShifter, functionCall, helper)) { + if (var_str_size != str_size || !strnEquals(var_str, str, str_size)) { continue; } - if (variable.var != NULL) { - printError(name_begin, name_end, "Multiple candidates found for %.*s", - (int)(name_end - name_begin), name_begin); + if (!setTypesAstVariable(var, helper)) { return NULL; } - variable.var = var; - variable.op = 1; - } else if (var->type->token == AST_TREE_TOKEN_TYPE_C_FUNCTION) { - AstTreeCFunctionType *cFunction = var->type->metadata; - AstTreeTypeFunction *function = cFunction->funcType->metadata; - if (!doesFunctionMatch(function, functionCall, helper)) { - continue; - } + if (var->type->token == AST_TREE_TOKEN_TYPE_FUNCTION) { + AstTreeTypeFunction *function = var->type->metadata; - if (variable.var != NULL && variable.op == 0) { - printError(name_begin, name_end, "Multiple candidates found for %.*s", - (int)(name_end - name_begin), name_begin); - return NULL; + if (!doesFunctionMatch(function, functionCall, helper)) { + continue; + } + + if (variable.var != NULL && variable.op == 0) { + printError(name_begin, name_end, + "Multiple candidates found for %.*s", + (int)(name_end - name_begin), name_begin); + return NULL; + } + variable.var = var; + variable.op = 0; + } else if (var->type->token == AST_TREE_TOKEN_TYPE_SHAPE_SHIFTER) { + if (variable.op < 1) { + continue; + } + AstTreeShapeShifter *shapeShifter = var->value->metadata; + + if (!doesShapeShifterMatch(shapeShifter, functionCall, helper)) { + continue; + } + + if (variable.var != NULL) { + printError(name_begin, name_end, + "Multiple candidates found for %.*s", + (int)(name_end - name_begin), name_begin); + return NULL; + } + variable.var = var; + variable.op = 1; + } else if (var->type->token == AST_TREE_TOKEN_TYPE_C_FUNCTION) { + AstTreeCFunctionType *cFunction = var->type->metadata; + AstTreeTypeFunction *function = cFunction->funcType->metadata; + + if (!doesFunctionMatch(function, functionCall, helper)) { + continue; + } + + if (variable.var != NULL && variable.op == 0) { + printError(name_begin, name_end, + "Multiple candidates found for %.*s", + (int)(name_end - name_begin), name_begin); + return NULL; + } + variable.var = var; + variable.op = 0; + } else if (var->type->token == AST_TREE_TOKEN_TYPE_MACRO) { + AstTreeMacro *macro = var->value->metadata; + AstTreeFunction *function = + copyAstTreeFunction(macro->function, NULL, NULL, 0, true); + + if (!setTypesAstFunction(function, NULL, helper)) { + astTreeFunctionDestroy(*function); + free(function); + return NULL; + } + + AstTree *functionType = makeTypeOfFunction(function, NULL, NULL); + + bool match = + doesFunctionMatch(functionType->metadata, functionCall, helper); + + astTreeDelete(functionType); + astTreeFunctionDestroy(*function); + free(function); + + if (!match) { + continue; + } + + if (variable.var != NULL && variable.op == 0) { + printError(name_begin, name_end, + "Multiple candidates found for %.*s", + (int)(name_end - name_begin), name_begin); + return NULL; + } + variable.var = var; + variable.op = 0; } - variable.var = var; - variable.op = 0; } } } if (variable.var == NULL) { + printLog("%ld", helper.variables_size); + for (size_t i = 0; i < helper.variables_size; ++i) { + printLog("is %ld", helper.variables[i].size); + } printError(name_begin, name_end, "No candidates found for %.*s", (int)(name_end - name_begin), name_begin); return NULL; } +END: return variable.var; } @@ -8046,8 +8251,6 @@ AstTree *getShapeShifterElement(AstTreeFunctionCall *metadata, AstTreeFunction *newFunction = copyAstTreeFunction(shapeShifter->function, NULL, NULL, 0, true); - newFunction->isMacro = shapeShifter->function->isMacro; - AstTreeFunctionCallParam initedArguments[newFunction->arguments.size]; size_t initedArguments_size = newFunction->arguments.size; @@ -8055,8 +8258,8 @@ AstTree *getShapeShifterElement(AstTreeFunctionCall *metadata, initedArguments[i].value = NULL; } - for (size_t i = 0; i < metadata->parameters_size; ++i) { - AstTreeFunctionCallParam param = metadata->parameters[i]; + for (size_t i = 0; i < metadata->parameters.size; ++i) { + AstTreeFunctionCallParam param = metadata->parameters.data[i]; if (param.nameBegin != param.nameEnd) { const size_t param_name_size = param.nameEnd - param.nameBegin; for (size_t j = 0; j < newFunction->arguments.size; ++j) { @@ -8081,8 +8284,8 @@ AstTree *getShapeShifterElement(AstTreeFunctionCall *metadata, END_OF_NAMED_FOR1: } - for (size_t i = 0; i < metadata->parameters_size; ++i) { - AstTreeFunctionCallParam param = metadata->parameters[i]; + for (size_t i = 0; i < metadata->parameters.size; ++i) { + AstTreeFunctionCallParam param = metadata->parameters.data[i]; if (param.nameBegin == param.nameEnd) { for (size_t j = 0; j < newFunction->arguments.size; ++j) { AstTreeVariable *arg = newFunction->arguments.data[j]; @@ -8114,20 +8317,21 @@ AstTree *getShapeShifterElement(AstTreeFunctionCall *metadata, } for (size_t i = 0; i < initedArguments_size; ++i) { - metadata->parameters[i] = initedArguments[i]; + metadata->parameters.data[i] = initedArguments[i]; } bool found = false; size_t element_index; for (size_t i = 0; i < shapeShifter->generateds.size; ++i) { - AstTreeFunctionCall *call = shapeShifter->generateds.calls[i]; - if (metadata->parameters_size != call->parameters_size) + AstTreeFunctionCallParams call = shapeShifter->generateds.calls[i]; + if (metadata->parameters.size != call.size) { continue; + } - for (size_t i = 0; i < metadata->parameters_size; ++i) { - AstTreeFunctionCallParam p0 = metadata->parameters[i]; - AstTreeFunctionCallParam p1 = call->parameters[i]; + for (size_t i = 0; i < metadata->parameters.size; ++i) { + AstTreeFunctionCallParam p0 = metadata->parameters.data[i]; + AstTreeFunctionCallParam p1 = call.data[i]; if (!typeIsEqual(p0.value->type, p1.value->type, helper.scope)) { goto SEARCH_LOOP_CONTINUE; } @@ -8154,21 +8358,19 @@ AstTree *getShapeShifterElement(AstTreeFunctionCall *metadata, } if (!found) { - AstTreeVariable - *variables[helper.variables.size + newFunction->arguments.size]; + AstTreeVariables variables[helper.variables_size + 1]; - for (size_t i = 0; i < helper.variables.size; ++i) { - variables[i] = helper.variables.data[i]; + for (size_t i = 0; i < helper.variables_size; ++i) { + variables[i] = helper.variables[i]; } - for (size_t i = 0; i < newFunction->arguments.size; ++i) { - variables[helper.variables.size + i] = newFunction->arguments.data[i]; - } + variables[helper.variables_size].data = newFunction->arguments.data; + variables[helper.variables_size].size = 0; AstTreeSetTypesHelper newHelper = { .root = helper.root, - .variables.data = variables, - .variables.size = helper.variables.size, + .variables = variables, + .variables_size = helper.variables_size + 1, .lookingType = NULL, .dependencies = helper.dependencies, .loops = helper.loops, @@ -8182,16 +8384,16 @@ AstTree *getShapeShifterElement(AstTreeFunctionCall *metadata, if (!setTypesAstVariable(var, newHelper)) { return NULL; } - newHelper.variables.size += 1; + newHelper.variables[newHelper.variables_size - 1].size += 1; } - if (!setTypesAstFunction(newFunction, helper)) { + if (!setTypesAstFunction(newFunction, NULL, helper)) { return NULL; } size_t generateds_size = - a404m_malloc_usable_size(shapeShifter->generateds.functions) / - sizeof(*shapeShifter->generateds.functions); + a404m_malloc_usable_size(shapeShifter->generateds.calls) / + sizeof(*shapeShifter->generateds.calls); if (generateds_size == shapeShifter->generateds.size) { generateds_size += generateds_size / 2 + 1; shapeShifter->generateds.functions = a404m_realloc( @@ -8203,7 +8405,29 @@ AstTree *getShapeShifterElement(AstTreeFunctionCall *metadata, } shapeShifter->generateds.functions[shapeShifter->generateds.size] = newFunction; - shapeShifter->generateds.calls[shapeShifter->generateds.size] = metadata; + + shapeShifter->generateds.calls[shapeShifter->generateds.size].size = + metadata->parameters.size; + shapeShifter->generateds.calls[shapeShifter->generateds.size].data = + a404m_malloc( + sizeof( + *shapeShifter->generateds.calls[shapeShifter->generateds.size] + .data) * + shapeShifter->generateds.calls[shapeShifter->generateds.size].size); + + for (size_t i = 0; + i < shapeShifter->generateds.calls[shapeShifter->generateds.size].size; + ++i) { + shapeShifter->generateds.calls[shapeShifter->generateds.size] + .data[i] + .value = copyAstTree(metadata->parameters.data[i].value); + shapeShifter->generateds.calls[shapeShifter->generateds.size] + .data[i] + .nameBegin = metadata->parameters.data[i].nameBegin; + shapeShifter->generateds.calls[shapeShifter->generateds.size] + .data[i] + .nameEnd = metadata->parameters.data[i].nameEnd; + } element_index = shapeShifter->generateds.size; shapeShifter->generateds.size += 1; @@ -8222,7 +8446,7 @@ AstTree *getShapeShifterElement(AstTreeFunctionCall *metadata, bool doesFunctionMatch(AstTreeTypeFunction *function, AstTreeFunctionCall *functionCall, AstTreeSetTypesHelper helper) { - if (function->arguments_size != functionCall->parameters_size) { + if (function->arguments_size != functionCall->parameters.size) { return false; } @@ -8233,8 +8457,8 @@ bool doesFunctionMatch(AstTreeTypeFunction *function, initedArguments[i].value = NULL; } - for (size_t i = 0; i < functionCall->parameters_size; ++i) { - AstTreeFunctionCallParam param = functionCall->parameters[i]; + for (size_t i = 0; i < functionCall->parameters.size; ++i) { + AstTreeFunctionCallParam param = functionCall->parameters.data[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) { @@ -8254,8 +8478,8 @@ bool doesFunctionMatch(AstTreeTypeFunction *function, END_OF_NAMED_FOR: } - for (size_t i = 0; i < functionCall->parameters_size; ++i) { - AstTreeFunctionCallParam param = functionCall->parameters[i]; + for (size_t i = 0; i < functionCall->parameters.size; ++i) { + AstTreeFunctionCallParam param = functionCall->parameters.data[i]; if (param.nameBegin == param.nameEnd) { for (size_t j = 0; j < function->arguments_size; ++j) { AstTreeTypeFunctionArgument arg = function->arguments[j]; @@ -8287,7 +8511,7 @@ bool doesShapeShifterMatch(AstTreeShapeShifter *shapeShifter, AstTreeSetTypesHelper helper) { AstTreeFunction *function = shapeShifter->function; - if (function->arguments.size != functionCall->parameters_size) { + if (function->arguments.size != functionCall->parameters.size) { return false; } @@ -8301,19 +8525,17 @@ bool doesShapeShifterMatch(AstTreeShapeShifter *shapeShifter, initedArguments[i].value = NULL; } - AstTreeVariable *variableArguments[helper.variables.size + arguments.size]; + AstTreeVariables variables[helper.variables_size + 1]; - for (size_t i = 0; i < helper.variables.size; ++i) { - variableArguments[i] = helper.variables.data[i]; + for (size_t i = 0; i < helper.variables_size; ++i) { + variables[i] = helper.variables[i]; } - for (size_t i = 0; i < arguments.size; ++i) { - variableArguments[helper.variables.size + i] = arguments.data[i]; - } + variables[helper.variables_size] = arguments; AstTreeSetTypesHelper newHelper = { - .variables.data = variableArguments, - .variables.size = helper.variables.size + arguments.size, + .variables = variables, + .variables_size = helper.variables_size + 1, .dependencies = helper.dependencies, .lookingType = NULL, .root = helper.root, @@ -8323,8 +8545,8 @@ bool doesShapeShifterMatch(AstTreeShapeShifter *shapeShifter, .isInScope = false, }; - for (size_t i = 0; i < functionCall->parameters_size; ++i) { - AstTreeFunctionCallParam param = functionCall->parameters[i]; + for (size_t i = 0; i < functionCall->parameters.size; ++i) { + AstTreeFunctionCallParam param = functionCall->parameters.data[i]; if (param.nameBegin != param.nameEnd) { const size_t param_name_size = param.nameEnd - param.nameBegin; for (size_t j = 0; j < arguments.size; ++j) { @@ -8340,6 +8562,8 @@ bool doesShapeShifterMatch(AstTreeShapeShifter *shapeShifter, goto RETURN_FALSE; } arg->value = copyAstTree(param.value); + astTreeDelete(arg->type); + arg->type = copyAstTree(param.value->type); initedArguments[j] = param; goto END_OF_NAMED_FOR1; } else { @@ -8354,8 +8578,8 @@ bool doesShapeShifterMatch(AstTreeShapeShifter *shapeShifter, END_OF_NAMED_FOR1: } - for (size_t i = 0; i < functionCall->parameters_size; ++i) { - AstTreeFunctionCallParam param = functionCall->parameters[i]; + for (size_t i = 0; i < functionCall->parameters.size; ++i) { + AstTreeFunctionCallParam param = functionCall->parameters.data[i]; if (param.nameBegin == param.nameEnd) { for (size_t j = 0; j < arguments.size; ++j) { AstTreeVariable *arg = arguments.data[j]; @@ -8369,6 +8593,8 @@ bool doesShapeShifterMatch(AstTreeShapeShifter *shapeShifter, goto RETURN_FALSE; } arg->value = copyAstTree(param.value); + astTreeDelete(arg->type); + arg->type = copyAstTree(param.value->type); initedArguments[j] = param; goto END_OF_UNNAMED_FOR1; } @@ -8462,7 +8688,9 @@ size_t getSizeOfType(AstTree *type) { return 1; case AST_TREE_TOKEN_TYPE_I16: case AST_TREE_TOKEN_TYPE_U16: +#ifdef FLOAT_16_SUPPORT case AST_TREE_TOKEN_TYPE_F16: +#endif return 2; case AST_TREE_TOKEN_TYPE_I32: case AST_TREE_TOKEN_TYPE_U32: @@ -8497,6 +8725,7 @@ size_t getSizeOfType(AstTree *type) { case AST_TREE_TOKEN_TYPE_SHAPE_SHIFTER: case AST_TREE_TOKEN_TYPE_C_LIBRARY: case AST_TREE_TOKEN_TYPE_C_FUNCTION: + case AST_TREE_TOKEN_TYPE_MACRO: case AST_TREE_TOKEN_FUNCTION: case AST_TREE_TOKEN_BUILTIN_CAST: case AST_TREE_TOKEN_BUILTIN_TYPE_OF: @@ -8543,6 +8772,7 @@ size_t getSizeOfType(AstTree *type) { case AST_TREE_TOKEN_VALUE_SHAPE_SHIFTER: case AST_TREE_TOKEN_VALUE_C_LIBRARY: case AST_TREE_TOKEN_VALUE_C_FUNCTION: + case AST_TREE_TOKEN_VALUE_MACRO: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_FLOAT: case AST_TREE_TOKEN_VALUE_BOOL: |