aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2025-06-06 17:55:51 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2025-06-06 17:55:51 +0330
commitaec4aa1ba09ea654cd02ff8281ee730d98fd3212 (patch)
tree08110ce950616acdad1fb2afe866fbee5fa85545
parenta0988143abd3b725b4aaeea8262a6faa72753ee3 (diff)
moving duplicated codes to functions
-rw-r--r--code/main.felan11
-rw-r--r--src/compiler/ast-tree.c639
-rw-r--r--src/compiler/ast-tree.h8
3 files changed, 321 insertions, 337 deletions
diff --git a/code/main.felan b/code/main.felan
index 55e1252..e80b7fc 100644
--- a/code/main.felan
+++ b/code/main.felan
@@ -14,7 +14,7 @@ t :: (comptime formatter : string) macro -> string {
in += 1;
} else if c == '}' {
in -= 1;
- if in == 0{
+ if in == 0 {
return sub_string(formatter,opening,i);
} else if in < 0 {
in = 0;
@@ -26,11 +26,8 @@ t :: (comptime formatter : string) macro -> string {
};
main :: () -> void {
- file.foo();
- a := '2';
- // @insert("a = '3';a = '5';");
- s :: t("hello {a = '6';}");
- @insert(s);
- print_char(a);
+ arr :[10][]u8 = undefined;
+ arr[0] = "Hello";
+ print(arr[0]);
};
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index f077f0d..acbf8ed 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -4060,6 +4060,123 @@ bool isConst(AstTree *tree) {
UNREACHABLE;
}
+bool isLeftValue(AstTree *tree) {
+ switch (tree->token) {
+ case AST_TREE_TOKEN_VARIABLE:
+ case AST_TREE_TOKEN_OPERATOR_ACCESS:
+ case AST_TREE_TOKEN_OPERATOR_DEREFERENCE:
+ return true;
+ case AST_TREE_TOKEN_FUNCTION:
+ case AST_TREE_TOKEN_BUILTIN_CAST:
+ case AST_TREE_TOKEN_BUILTIN_TYPE_OF:
+ case AST_TREE_TOKEN_BUILTIN_SIZE_OF:
+ case AST_TREE_TOKEN_BUILTIN_IMPORT:
+ case AST_TREE_TOKEN_BUILTIN_IS_COMPTIME:
+ case AST_TREE_TOKEN_BUILTIN_STACK_ALLOC:
+ case AST_TREE_TOKEN_BUILTIN_HEAP_ALLOC:
+ case AST_TREE_TOKEN_BUILTIN_NEG:
+ case AST_TREE_TOKEN_BUILTIN_ADD:
+ case AST_TREE_TOKEN_BUILTIN_SUB:
+ case AST_TREE_TOKEN_BUILTIN_MUL:
+ case AST_TREE_TOKEN_BUILTIN_DIV:
+ case AST_TREE_TOKEN_BUILTIN_MOD:
+ case AST_TREE_TOKEN_BUILTIN_EQUAL:
+ case AST_TREE_TOKEN_BUILTIN_NOT_EQUAL:
+ case AST_TREE_TOKEN_BUILTIN_GREATER:
+ case AST_TREE_TOKEN_BUILTIN_SMALLER:
+ case AST_TREE_TOKEN_BUILTIN_GREATER_OR_EQUAL:
+ case AST_TREE_TOKEN_BUILTIN_SMALLER_OR_EQUAL:
+ case AST_TREE_TOKEN_BUILTIN_PUTC:
+ case AST_TREE_TOKEN_BUILTIN_C_LIBRARY:
+ case AST_TREE_TOKEN_BUILTIN_C_FUNCTION:
+ case AST_TREE_TOKEN_BUILTIN_BITWISE_NOT:
+ case AST_TREE_TOKEN_BUILTIN_BITWISE_AND:
+ case AST_TREE_TOKEN_BUILTIN_BITWISE_XOR:
+ case AST_TREE_TOKEN_BUILTIN_BITWISE_OR:
+ case AST_TREE_TOKEN_BUILTIN_SHIFT_LEFT:
+ case AST_TREE_TOKEN_BUILTIN_SHIFT_RIGHT:
+ case AST_TREE_TOKEN_BUILTIN_INSERT:
+ case AST_TREE_TOKEN_KEYWORD_RETURN:
+ case AST_TREE_TOKEN_KEYWORD_BREAK:
+ case AST_TREE_TOKEN_KEYWORD_CONTINUE:
+ 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_TYPE_FUNCTION:
+ case AST_TREE_TOKEN_TYPE_ARRAY:
+ case AST_TREE_TOKEN_TYPE_TYPE:
+ case AST_TREE_TOKEN_TYPE_ANY_TYPE:
+ case AST_TREE_TOKEN_TYPE_VOID:
+ case AST_TREE_TOKEN_TYPE_I8:
+ case AST_TREE_TOKEN_TYPE_U8:
+ case AST_TREE_TOKEN_TYPE_I16:
+ case AST_TREE_TOKEN_TYPE_U16:
+ case AST_TREE_TOKEN_TYPE_I32:
+ case AST_TREE_TOKEN_TYPE_U32:
+ case AST_TREE_TOKEN_TYPE_I64:
+ case AST_TREE_TOKEN_TYPE_U64:
+ case AST_TREE_TOKEN_TYPE_F16:
+ case AST_TREE_TOKEN_TYPE_F32:
+ case AST_TREE_TOKEN_TYPE_F64:
+ case AST_TREE_TOKEN_TYPE_F128:
+ case AST_TREE_TOKEN_TYPE_CODE:
+ 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_C_FUNCTION:
+ case AST_TREE_TOKEN_TYPE_BOOL:
+ case AST_TREE_TOKEN_VALUE_VOID:
+ case AST_TREE_TOKEN_FUNCTION_CALL:
+ case AST_TREE_TOKEN_VARIABLE_DEFINE:
+ case AST_TREE_TOKEN_VALUE_NULL:
+ case AST_TREE_TOKEN_VALUE_UNDEFINED:
+ 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_INT:
+ case AST_TREE_TOKEN_VALUE_FLOAT:
+ case AST_TREE_TOKEN_VALUE_BOOL:
+ case AST_TREE_TOKEN_VALUE_OBJECT:
+ case AST_TREE_TOKEN_RAW_VALUE:
+ case AST_TREE_TOKEN_RAW_VALUE_NOT_OWNED:
+ case AST_TREE_TOKEN_SHAPE_SHIFTER_ELEMENT:
+ case AST_TREE_TOKEN_OPERATOR_ASSIGN:
+ case AST_TREE_TOKEN_OPERATOR_PLUS:
+ case AST_TREE_TOKEN_OPERATOR_MINUS:
+ case AST_TREE_TOKEN_OPERATOR_SUM:
+ case AST_TREE_TOKEN_OPERATOR_SUB:
+ case AST_TREE_TOKEN_OPERATOR_MULTIPLY:
+ case AST_TREE_TOKEN_OPERATOR_DIVIDE:
+ case AST_TREE_TOKEN_OPERATOR_MODULO:
+ case AST_TREE_TOKEN_OPERATOR_EQUAL:
+ case AST_TREE_TOKEN_OPERATOR_NOT_EQUAL:
+ case AST_TREE_TOKEN_OPERATOR_GREATER:
+ case AST_TREE_TOKEN_OPERATOR_SMALLER:
+ case AST_TREE_TOKEN_OPERATOR_GREATER_OR_EQUAL:
+ case AST_TREE_TOKEN_OPERATOR_SMALLER_OR_EQUAL:
+ case AST_TREE_TOKEN_OPERATOR_POINTER:
+ case AST_TREE_TOKEN_OPERATOR_ADDRESS:
+ 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:
+ case AST_TREE_TOKEN_OPERATOR_BITWISE_OR:
+ case AST_TREE_TOKEN_OPERATOR_SHIFT_LEFT:
+ case AST_TREE_TOKEN_OPERATOR_SHIFT_RIGHT:
+ case AST_TREE_TOKEN_SCOPE:
+ return false;
+ case AST_TREE_TOKEN_NONE:
+ }
+ UNREACHABLE;
+}
+
AstTree *makeTypeOf(AstTree *value) {
switch (value->token) {
case AST_TREE_TOKEN_TYPE_TYPE:
@@ -5861,60 +5978,11 @@ bool setTypesFunctionCall(AstTree *tree, AstTreeSetTypesHelper _helper) {
return NULL;
}
- AstTreeFunctionCallParam initedArguments[function->arguments_size];
- size_t initedArguments_size = function->arguments_size;
-
- for (size_t i = 0; i < initedArguments_size; ++i) {
- initedArguments[i].value = NULL;
- }
-
- for (size_t i = 0; i < metadata->parameters_size; ++i) {
- AstTreeFunctionCallParam param = metadata->parameters[i];
- if (param.nameBegin != param.nameEnd) {
- const size_t param_name_size = param.nameEnd - param.nameBegin;
- for (size_t j = 0; j < function->arguments_size; ++j) {
- AstTreeTypeFunctionArgument arg = function->arguments[j];
- if ((size_t)(arg.name_end - arg.name_begin) == param_name_size &&
- strnEquals(arg.name_begin, param.nameBegin, param_name_size)) {
- initedArguments[j] = param;
- goto END_OF_NAMED_FOR;
- }
- }
- printError(param.value->str_begin, param.value->str_end,
- "Argument not found");
- return false;
- }
- END_OF_NAMED_FOR:
- }
-
- for (size_t i = 0; i < metadata->parameters_size; ++i) {
- AstTreeFunctionCallParam param = metadata->parameters[i];
- if (param.nameBegin == param.nameEnd) {
- for (size_t j = 0; j < function->arguments_size; ++j) {
- // AstTreeTypeFunctionArgument arg = function->arguments[j];
- if (initedArguments[j].value == NULL) {
- initedArguments[j] = param;
- goto END_OF_UNNAMED_FOR;
- }
- }
- printError(param.value->str_begin, param.value->str_end,
- "Too many arguments");
- return false;
- }
- END_OF_UNNAMED_FOR:
- }
-
- for (size_t i = 0; i < function->arguments_size; ++i) {
- AstTreeTypeFunctionArgument arg = function->arguments[i];
- if (initedArguments[i].value == NULL) {
- printError(arg.str_begin, arg.str_end, "Argument is not initialized");
- return false;
- }
+ if (!doesFunctionMatch(function, metadata, helper)) {
+ printError(tree->str_begin, tree->str_end, "Function call doesn't match");
+ return NULL;
}
- for (size_t i = 0; i < initedArguments_size; ++i) {
- metadata->parameters[i] = initedArguments[i];
- }
tree->type = copyAstTree(function->returnType);
} else if (metadata->function->type->token ==
AST_TREE_TOKEN_TYPE_SHAPE_SHIFTER) {
@@ -5932,67 +6000,13 @@ bool setTypesFunctionCall(AstTree *tree, AstTreeSetTypesHelper _helper) {
if (function == NULL) {
printError(tree->str_begin, tree->str_end, "Bad function");
return NULL;
- } else if (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);
- return NULL;
- }
-
- AstTreeFunctionCallParam initedArguments[function->arguments_size];
- size_t initedArguments_size = function->arguments_size;
-
- for (size_t i = 0; i < initedArguments_size; ++i) {
- initedArguments[i].value = NULL;
- }
-
- for (size_t i = 0; i < metadata->parameters_size; ++i) {
- AstTreeFunctionCallParam param = metadata->parameters[i];
- if (param.nameBegin != param.nameEnd) {
- const size_t param_name_size = param.nameEnd - param.nameBegin;
- for (size_t j = 0; j < function->arguments_size; ++j) {
- AstTreeTypeFunctionArgument arg = function->arguments[j];
- if ((size_t)(arg.name_end - arg.name_begin) == param_name_size &&
- strnEquals(arg.name_begin, param.nameBegin, param_name_size)) {
- initedArguments[j] = param;
- goto END_OF_NAMED_FOR2;
- }
- }
- printError(param.value->str_begin, param.value->str_end,
- "Argument not found");
- return false;
- }
- END_OF_NAMED_FOR2:
}
- for (size_t i = 0; i < metadata->parameters_size; ++i) {
- AstTreeFunctionCallParam param = metadata->parameters[i];
- if (param.nameBegin == param.nameEnd) {
- for (size_t j = 0; j < function->arguments_size; ++j) {
- // AstTreeTypeFunctionArgument arg = function->arguments[j];
- if (initedArguments[j].value == NULL) {
- initedArguments[j] = param;
- goto END_OF_UNNAMED_FOR2;
- }
- }
- printError(param.value->str_begin, param.value->str_end,
- "Too many arguments");
- return false;
- }
- END_OF_UNNAMED_FOR2:
- }
-
- for (size_t i = 0; i < function->arguments_size; ++i) {
- AstTreeTypeFunctionArgument arg = function->arguments[i];
- if (initedArguments[i].value == NULL) {
- printError(arg.str_begin, arg.str_end, "Argument is not initialized");
- return false;
- }
+ if (!doesFunctionMatch(function, metadata, helper)) {
+ printError(tree->str_begin, tree->str_end, "Function call doesn't match");
+ return NULL;
}
- for (size_t i = 0; i < initedArguments_size; ++i) {
- metadata->parameters[i] = initedArguments[i];
- }
tree->type = copyAstTree(function->returnType);
} else {
UNREACHABLE;
@@ -6110,7 +6124,6 @@ RETURN_ERROR:
bool setTypesOperatorAssign(AstTree *tree, AstTreeSetTypesHelper helper) {
AstTreePureInfix *infix = tree->metadata;
- // TODO: check left one for being left value
if (!setTypesAstInfix(infix, helper)) {
return false;
} else if (!typeIsEqual(infix->left->type, infix->right->type,
@@ -6120,6 +6133,10 @@ bool setTypesOperatorAssign(AstTree *tree, AstTreeSetTypesHelper helper) {
} else if (isConst(infix->left)) {
printError(tree->str_begin, tree->str_end, "Constants can't be assigned");
return false;
+ } else if (!isLeftValue(infix->left)) {
+ printError(infix->left->str_begin, infix->left->str_end,
+ "Need to be l-value");
+ return false;
} else {
tree->type = copyAstTree(infix->left->type);
return true;
@@ -7956,63 +7973,10 @@ AstTreeVariable *setTypesFindVariable(const char *name_begin,
if (var->type->token == AST_TREE_TOKEN_TYPE_FUNCTION) {
AstTreeTypeFunction *function = var->type->metadata;
- if (function->arguments_size != functionCall->parameters_size) {
+ if (!doesFunctionMatch(function, functionCall, helper)) {
continue;
}
- AstTreeFunctionCallParam initedArguments[function->arguments_size];
- size_t initedArguments_size = function->arguments_size;
-
- for (size_t i = 0; i < initedArguments_size; ++i) {
- initedArguments[i].value = NULL;
- }
-
- for (size_t i = 0; i < functionCall->parameters_size; ++i) {
- AstTreeFunctionCallParam param = functionCall->parameters[i];
- if (param.nameBegin != param.nameEnd) {
- const size_t param_name_size = param.nameEnd - param.nameBegin;
- for (size_t j = 0; j < function->arguments_size; ++j) {
- AstTreeTypeFunctionArgument arg = function->arguments[j];
- if ((size_t)(arg.name_end - arg.name_begin) == param_name_size &&
- strnEquals(arg.name_begin, param.nameBegin,
- param_name_size)) {
- if (!typeIsEqual(arg.type, param.value->type, helper.scope) ||
- (arg.isComptime && !isConst(param.value))) {
- goto CONTINUE_OUTER;
- }
- initedArguments[j] = param;
- goto END_OF_NAMED_FOR;
- }
- }
- goto CONTINUE_OUTER;
- }
- END_OF_NAMED_FOR:
- }
-
- for (size_t i = 0; i < functionCall->parameters_size; ++i) {
- AstTreeFunctionCallParam param = functionCall->parameters[i];
- if (param.nameBegin == param.nameEnd) {
- for (size_t j = 0; j < function->arguments_size; ++j) {
- AstTreeTypeFunctionArgument arg = function->arguments[j];
- if (initedArguments[j].value == NULL) {
- if (!typeIsEqual(arg.type, param.value->type, helper.scope) ||
- (arg.isComptime && !isConst(param.value))) {
- goto CONTINUE_OUTER;
- }
- initedArguments[j] = param;
- goto END_OF_UNNAMED_FOR;
- }
- }
- goto CONTINUE_OUTER;
- }
- END_OF_UNNAMED_FOR:
- }
-
- for (size_t i = 0; i < function->arguments_size; ++i) {
- if (initedArguments[i].value == NULL) {
- goto CONTINUE_OUTER;
- }
- }
if (variable.var != NULL && variable.op == 0) {
printError(name_begin, name_end, "Multiple candidates found for %.*s",
(int)(name_end - name_begin), name_begin);
@@ -8025,115 +7989,11 @@ AstTreeVariable *setTypesFindVariable(const char *name_begin,
continue;
}
AstTreeShapeShifter *shapeShifter = var->value->metadata;
- AstTreeFunction *function = shapeShifter->function;
- if (function->arguments.size != functionCall->parameters_size) {
+ if (!doesShapeShifterMatch(shapeShifter, functionCall, helper)) {
continue;
}
- AstTreeVariables arguments =
- copyAstTreeVariables(function->arguments, NULL, NULL, 0, true);
-
- AstTreeFunctionCallParam initedArguments[arguments.size];
- size_t initedArguments_size = arguments.size;
-
- for (size_t i = 0; i < initedArguments_size; ++i) {
- initedArguments[i].value = NULL;
- }
-
- AstTreeVariable
- *variableArguments[helper.variables.size + arguments.size];
-
- for (size_t i = 0; i < helper.variables.size; ++i) {
- variableArguments[i] = helper.variables.data[i];
- }
-
- for (size_t i = 0; i < arguments.size; ++i) {
- variableArguments[helper.variables.size + i] = arguments.data[i];
- }
-
- AstTreeSetTypesHelper newHelper = {
- .variables.data = variableArguments,
- .variables.size = helper.variables.size + arguments.size,
- .dependencies = helper.dependencies,
- .lookingType = NULL,
- .root = helper.root,
- .loops = helper.loops,
- .loops_size = helper.loops_size,
- .scope = helper.scope,
- .isInScope = false,
- };
-
- for (size_t i = 0; i < functionCall->parameters_size; ++i) {
- AstTreeFunctionCallParam param = functionCall->parameters[i];
- if (param.nameBegin != param.nameEnd) {
- const size_t param_name_size = param.nameEnd - param.nameBegin;
- for (size_t j = 0; j < arguments.size; ++j) {
- AstTreeVariable *arg = arguments.data[j];
- if ((size_t)(arg->name_end - arg->name_begin) ==
- param_name_size &&
- strnEquals(arg->name_begin, param.nameBegin,
- param_name_size)) {
- if (!setTypesAstVariable(arg, newHelper)) {
- goto CONTINUE_OUTER1;
- }
- if (arg->type != NULL && isConst(arg->type)) {
- if (!typeIsEqual(arg->type, param.value->type,
- helper.scope) ||
- (arg->isConst && !isConst(param.value))) {
- goto CONTINUE_OUTER1;
- }
- arg->value = copyAstTree(param.value);
- initedArguments[j] = param;
- goto END_OF_NAMED_FOR1;
- } else {
- goto CONTINUE_OUTER1;
- }
- } else {
- goto CONTINUE_OUTER1;
- }
- }
- goto CONTINUE_OUTER1;
- }
- END_OF_NAMED_FOR1:
- }
-
- for (size_t i = 0; i < functionCall->parameters_size; ++i) {
- AstTreeFunctionCallParam param = functionCall->parameters[i];
- if (param.nameBegin == param.nameEnd) {
- for (size_t j = 0; j < arguments.size; ++j) {
- AstTreeVariable *arg = arguments.data[j];
- if (!setTypesAstVariable(arg, newHelper)) {
- goto CONTINUE_OUTER1;
- }
- if (arg->type != NULL && isConst(arg->type)) {
- if (initedArguments[j].value == NULL) {
- if (!typeIsEqual(arg->type, param.value->type,
- helper.scope) ||
- (arg->isConst && !isConst(param.value))) {
- goto CONTINUE_OUTER1;
- }
- arg->value = copyAstTree(param.value);
- initedArguments[j] = param;
- goto END_OF_UNNAMED_FOR1;
- }
- } else {
- goto CONTINUE_OUTER1;
- }
- }
- goto CONTINUE_OUTER1;
- }
- END_OF_UNNAMED_FOR1:
- }
-
- for (size_t i = 0; i < arguments.size; ++i) {
- if (initedArguments[i].value == NULL) {
- goto CONTINUE_OUTER1;
- }
- astTreeVariableDelete(arguments.data[i]);
- }
- free(arguments.data);
-
if (variable.var != NULL) {
printError(name_begin, name_end, "Multiple candidates found for %.*s",
(int)(name_end - name_begin), name_begin);
@@ -8141,73 +8001,14 @@ AstTreeVariable *setTypesFindVariable(const char *name_begin,
}
variable.var = var;
variable.op = 1;
- continue;
- CONTINUE_OUTER1:
- for (size_t i = 0; i < arguments.size; ++i) {
- astTreeVariableDelete(arguments.data[i]);
- }
- free(arguments.data);
} else if (var->type->token == AST_TREE_TOKEN_TYPE_C_FUNCTION) {
AstTreeCFunctionType *cFunction = var->type->metadata;
AstTreeTypeFunction *function = cFunction->funcType->metadata;
- if (function->arguments_size != functionCall->parameters_size) {
+ if (!doesFunctionMatch(function, functionCall, helper)) {
continue;
}
- AstTreeFunctionCallParam initedArguments[function->arguments_size];
- size_t initedArguments_size = function->arguments_size;
-
- for (size_t i = 0; i < initedArguments_size; ++i) {
- initedArguments[i].value = NULL;
- }
-
- for (size_t i = 0; i < functionCall->parameters_size; ++i) {
- AstTreeFunctionCallParam param = functionCall->parameters[i];
- if (param.nameBegin != param.nameEnd) {
- const size_t param_name_size = param.nameEnd - param.nameBegin;
- for (size_t j = 0; j < function->arguments_size; ++j) {
- AstTreeTypeFunctionArgument arg = function->arguments[j];
- if ((size_t)(arg.name_end - arg.name_begin) == param_name_size &&
- strnEquals(arg.name_begin, param.nameBegin,
- param_name_size)) {
- if (!typeIsEqual(arg.type, param.value->type, helper.scope) ||
- (arg.isComptime && !isConst(param.value))) {
- goto CONTINUE_OUTER;
- }
- initedArguments[j] = param;
- goto END_OF_NAMED_FOR2;
- }
- }
- goto CONTINUE_OUTER;
- }
- END_OF_NAMED_FOR2:
- }
-
- for (size_t i = 0; i < functionCall->parameters_size; ++i) {
- AstTreeFunctionCallParam param = functionCall->parameters[i];
- if (param.nameBegin == param.nameEnd) {
- for (size_t j = 0; j < function->arguments_size; ++j) {
- AstTreeTypeFunctionArgument arg = function->arguments[j];
- if (initedArguments[j].value == NULL) {
- if (!typeIsEqual(arg.type, param.value->type, helper.scope) ||
- (arg.isComptime && !isConst(param.value))) {
- goto CONTINUE_OUTER;
- }
- initedArguments[j] = param;
- goto END_OF_UNNAMED_FOR2;
- }
- }
- goto CONTINUE_OUTER;
- }
- END_OF_UNNAMED_FOR2:
- }
-
- for (size_t i = 0; i < function->arguments_size; ++i) {
- if (initedArguments[i].value == NULL) {
- goto CONTINUE_OUTER;
- }
- }
if (variable.var != NULL && variable.op == 0) {
printError(name_begin, name_end, "Multiple candidates found for %.*s",
(int)(name_end - name_begin), name_begin);
@@ -8216,7 +8017,6 @@ AstTreeVariable *setTypesFindVariable(const char *name_begin,
variable.var = var;
variable.op = 0;
}
- CONTINUE_OUTER:
}
}
if (variable.var == NULL) {
@@ -8419,6 +8219,185 @@ AstTree *getShapeShifterElement(AstTreeFunctionCall *metadata,
return metadata->function;
}
+bool doesFunctionMatch(AstTreeTypeFunction *function,
+ AstTreeFunctionCall *functionCall,
+ AstTreeSetTypesHelper helper) {
+ if (function->arguments_size != functionCall->parameters_size) {
+ return false;
+ }
+
+ AstTreeFunctionCallParam initedArguments[function->arguments_size];
+ size_t initedArguments_size = function->arguments_size;
+
+ for (size_t i = 0; i < initedArguments_size; ++i) {
+ initedArguments[i].value = NULL;
+ }
+
+ for (size_t i = 0; i < functionCall->parameters_size; ++i) {
+ AstTreeFunctionCallParam param = functionCall->parameters[i];
+ if (param.nameBegin != param.nameEnd) {
+ const size_t param_name_size = param.nameEnd - param.nameBegin;
+ for (size_t j = 0; j < function->arguments_size; ++j) {
+ AstTreeTypeFunctionArgument arg = function->arguments[j];
+ if ((size_t)(arg.name_end - arg.name_begin) == param_name_size &&
+ strnEquals(arg.name_begin, param.nameBegin, param_name_size)) {
+ if (!typeIsEqual(arg.type, param.value->type, helper.scope) ||
+ (arg.isComptime && !isConst(param.value))) {
+ return false;
+ }
+ initedArguments[j] = param;
+ goto END_OF_NAMED_FOR;
+ }
+ }
+ return false;
+ }
+ END_OF_NAMED_FOR:
+ }
+
+ for (size_t i = 0; i < functionCall->parameters_size; ++i) {
+ AstTreeFunctionCallParam param = functionCall->parameters[i];
+ if (param.nameBegin == param.nameEnd) {
+ for (size_t j = 0; j < function->arguments_size; ++j) {
+ AstTreeTypeFunctionArgument arg = function->arguments[j];
+ if (initedArguments[j].value == NULL) {
+ if (!typeIsEqual(arg.type, param.value->type, helper.scope) ||
+ (arg.isComptime && !isConst(param.value))) {
+ return false;
+ }
+ initedArguments[j] = param;
+ goto END_OF_UNNAMED_FOR;
+ }
+ }
+ return false;
+ }
+ END_OF_UNNAMED_FOR:
+ }
+
+ for (size_t i = 0; i < function->arguments_size; ++i) {
+ if (initedArguments[i].value == NULL) {
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool doesShapeShifterMatch(AstTreeShapeShifter *shapeShifter,
+ AstTreeFunctionCall *functionCall,
+ AstTreeSetTypesHelper helper) {
+ AstTreeFunction *function = shapeShifter->function;
+
+ if (function->arguments.size != functionCall->parameters_size) {
+ return false;
+ }
+
+ AstTreeVariables arguments =
+ copyAstTreeVariables(function->arguments, NULL, NULL, 0, true);
+
+ AstTreeFunctionCallParam initedArguments[arguments.size];
+ size_t initedArguments_size = arguments.size;
+
+ for (size_t i = 0; i < initedArguments_size; ++i) {
+ initedArguments[i].value = NULL;
+ }
+
+ AstTreeVariable *variableArguments[helper.variables.size + arguments.size];
+
+ for (size_t i = 0; i < helper.variables.size; ++i) {
+ variableArguments[i] = helper.variables.data[i];
+ }
+
+ for (size_t i = 0; i < arguments.size; ++i) {
+ variableArguments[helper.variables.size + i] = arguments.data[i];
+ }
+
+ AstTreeSetTypesHelper newHelper = {
+ .variables.data = variableArguments,
+ .variables.size = helper.variables.size + arguments.size,
+ .dependencies = helper.dependencies,
+ .lookingType = NULL,
+ .root = helper.root,
+ .loops = helper.loops,
+ .loops_size = helper.loops_size,
+ .scope = helper.scope,
+ .isInScope = false,
+ };
+
+ for (size_t i = 0; i < functionCall->parameters_size; ++i) {
+ AstTreeFunctionCallParam param = functionCall->parameters[i];
+ if (param.nameBegin != param.nameEnd) {
+ const size_t param_name_size = param.nameEnd - param.nameBegin;
+ for (size_t j = 0; j < arguments.size; ++j) {
+ AstTreeVariable *arg = arguments.data[j];
+ if ((size_t)(arg->name_end - arg->name_begin) == param_name_size &&
+ strnEquals(arg->name_begin, param.nameBegin, param_name_size)) {
+ if (!setTypesAstVariable(arg, newHelper)) {
+ goto RETURN_FALSE;
+ }
+ if (arg->type != NULL && isConst(arg->type)) {
+ if (!typeIsEqual(arg->type, param.value->type, helper.scope) ||
+ (arg->isConst && !isConst(param.value))) {
+ goto RETURN_FALSE;
+ }
+ arg->value = copyAstTree(param.value);
+ initedArguments[j] = param;
+ goto END_OF_NAMED_FOR1;
+ } else {
+ goto RETURN_FALSE;
+ }
+ } else {
+ goto RETURN_FALSE;
+ }
+ }
+ goto RETURN_FALSE;
+ }
+ END_OF_NAMED_FOR1:
+ }
+
+ for (size_t i = 0; i < functionCall->parameters_size; ++i) {
+ AstTreeFunctionCallParam param = functionCall->parameters[i];
+ if (param.nameBegin == param.nameEnd) {
+ for (size_t j = 0; j < arguments.size; ++j) {
+ AstTreeVariable *arg = arguments.data[j];
+ if (!setTypesAstVariable(arg, newHelper)) {
+ goto RETURN_FALSE;
+ }
+ if (arg->type != NULL && isConst(arg->type)) {
+ if (initedArguments[j].value == NULL) {
+ if (!typeIsEqual(arg->type, param.value->type, helper.scope) ||
+ (arg->isConst && !isConst(param.value))) {
+ goto RETURN_FALSE;
+ }
+ arg->value = copyAstTree(param.value);
+ initedArguments[j] = param;
+ goto END_OF_UNNAMED_FOR1;
+ }
+ } else {
+ goto RETURN_FALSE;
+ }
+ }
+ goto RETURN_FALSE;
+ }
+ END_OF_UNNAMED_FOR1:
+ }
+
+ for (size_t i = 0; i < arguments.size; ++i) {
+ if (initedArguments[i].value == NULL) {
+ goto RETURN_FALSE;
+ }
+ astTreeVariableDelete(arguments.data[i]);
+ }
+ free(arguments.data);
+ return true;
+
+RETURN_FALSE:
+ for (size_t i = 0; i < arguments.size; ++i) {
+ astTreeVariableDelete(arguments.data[i]);
+ }
+ free(arguments.data);
+ return false;
+}
+
char *u8ArrayToCString(AstTree *tree) {
AstTreeScope scope = {
.expressions = a404m_malloc(0),
diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h
index cf868fd..0d63252 100644
--- a/src/compiler/ast-tree.h
+++ b/src/compiler/ast-tree.h
@@ -462,6 +462,7 @@ bool isFunction(AstTree *value);
bool isShapeShifter(AstTreeFunction *function);
bool hasAnyTypeInside(AstTree *type);
bool isConst(AstTree *tree);
+bool isLeftValue(AstTree *tree);
AstTree *makeTypeOf(AstTree *value);
AstTree *makeTypeOfFunction(AstTreeFunction *function, const char *str_begin,
const char *str_end);
@@ -557,6 +558,13 @@ AstTreeVariable *setTypesFindVariable(const char *name_begin,
AstTree *getShapeShifterElement(AstTreeFunctionCall *metadata,
AstTreeSetTypesHelper helper);
+bool doesFunctionMatch(AstTreeTypeFunction *function,
+ AstTreeFunctionCall *functionCall,
+ AstTreeSetTypesHelper helper);
+bool doesShapeShifterMatch(AstTreeShapeShifter *shapeShifter,
+ AstTreeFunctionCall *functionCall,
+ AstTreeSetTypesHelper helper);
+
char *u8ArrayToCString(AstTree *tree);
AstTree *makeStringType();