summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA404M <ahmadmahmoudiprogrammer@gmail.com>2025-03-20 17:47:28 +0330
committerA404M <ahmadmahmoudiprogrammer@gmail.com>2025-03-20 17:47:28 +0330
commit69310fa04d9370841c7b4f30c7278fb138b7b2e2 (patch)
tree34c153ca254ff9a3687d461a13d84aa35e358235
parent624a73ae10eb3aaa535eb41c023c59919df28c99 (diff)
added named paramters
-rw-r--r--src/compiler/ast-tree.c117
-rw-r--r--src/compiler/ast-tree.h8
-rw-r--r--src/compiler/parser.c2
-rw-r--r--src/runner/runner.c66
-rw-r--r--src/runner/runner.h2
-rw-r--r--test/main.felan7
6 files changed, 169 insertions, 33 deletions
diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c
index 6d9440b..1437767 100644
--- a/src/compiler/ast-tree.c
+++ b/src/compiler/ast-tree.c
@@ -4,7 +4,6 @@
#include "runner/runner.h"
#include "utils/log.h"
#include "utils/memory.h"
-#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -284,8 +283,16 @@ void astTreePrint(const AstTree *tree, int indent) {
printf(" ");
printf("paramters=[\n");
for (size_t i = 0; i < metadata->parameters_size; ++i) {
- astTreePrint(metadata->parameters[i], indent + 1);
- printf(",\n");
+ AstTreeFunctionCallParam param = metadata->parameters[i];
+ for (int i = 0; i < indent + 1; ++i)
+ printf(" ");
+ printf("{name:\"%.*s\",\n", (int)(param.nameEnd - param.nameBegin),
+ param.nameBegin);
+ astTreePrint(param.value, indent + 2);
+ printf("\n");
+ for (int i = 0; i < indent + 1; ++i)
+ printf(" ");
+ printf("},\n");
}
for (int i = 0; i < indent; ++i)
printf(" ");
@@ -480,7 +487,7 @@ void astTreeDestroy(AstTree tree) {
AstTreeFunctionCall *metadata = tree.metadata;
astTreeDelete(metadata->function);
for (size_t i = 0; i < metadata->parameters_size; ++i) {
- astTreeDelete(metadata->parameters[i]);
+ astTreeDelete(metadata->parameters[i].value);
}
free(metadata->parameters);
free(metadata);
@@ -538,7 +545,6 @@ void astTreeDestroy(AstTree tree) {
free(metadata);
}
return;
-
case AST_TREE_TOKEN_NONE:
}
printLog("token = %d", tree.token);
@@ -715,7 +721,10 @@ AstTree *copyAstTree(AstTree *tree) {
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] = copyAstTree(metadata->parameters[i]);
+ new_metadata->parameters[i].nameBegin = metadata->parameters[i].nameBegin;
+ new_metadata->parameters[i].nameEnd = metadata->parameters[i].nameEnd;
+ new_metadata->parameters[i].value =
+ copyAstTree(metadata->parameters[i].value);
}
return newAstTree(tree->token, new_metadata, copyAstTree(tree->type),
tree->str_begin, tree->str_end);
@@ -1382,11 +1391,24 @@ AstTree *astTreeParseFunctionCall(ParserNode *parserNode,
metadata->parameters_size = node_metadata->params->size;
for (size_t i = 0; i < metadata->parameters_size; ++i) {
- ParserNode *param = node_metadata->params->data[i];
- if (param->token == PARSER_TOKEN_SYMBOL_COMMA) {
- param = (ParserNodeSingleChildMetadata *)param->metadata;
+ ParserNode *node_param = node_metadata->params->data[i];
+ if (node_param->token == PARSER_TOKEN_SYMBOL_COMMA) {
+ node_param = (ParserNodeSingleChildMetadata *)node_param->metadata;
+ }
+ AstTreeFunctionCallParam param;
+ if (node_param->token == PARSER_TOKEN_OPERATOR_ASSIGN) {
+ ParserNodeInfixMetadata *assign = node_param->metadata;
+ if (assign->left->token == PARSER_TOKEN_IDENTIFIER) {
+ param.nameBegin = assign->left->str_begin;
+ param.nameEnd = assign->left->str_end;
+ param.value = astTreeParse(assign->right, helper);
+ goto PUSH_PARAM;
+ }
}
- metadata->parameters[i] = astTreeParse(param, helper);
+ param.nameBegin = param.nameEnd = NULL;
+ param.value = astTreeParse(node_param, helper);
+ PUSH_PARAM:
+ metadata->parameters[i] = param;
}
return newAstTree(AST_TREE_TOKEN_FUNCTION_CALL, metadata, NULL,
@@ -1909,7 +1931,7 @@ bool isConst(AstTree *tree, AstTreeHelper *helper) {
case AST_TREE_TOKEN_FUNCTION_CALL: {
AstTreeFunctionCall *metadata = tree->metadata;
for (size_t i = 0; i < metadata->parameters_size; ++i) {
- if (!isConst(metadata->parameters[i], helper)) {
+ if (!isConst(metadata->parameters[i].value, helper)) {
return false;
}
}
@@ -2240,7 +2262,8 @@ bool isCircularDependenciesBack(AstTreeHelper *helper,
case AST_TREE_TOKEN_FUNCTION_CALL: {
AstTreeFunctionCall *metadata = tree->metadata;
for (size_t i = 0; i < metadata->parameters_size; ++i) {
- if (isCircularDependenciesBack(helper, variable, metadata->parameters[i],
+ if (isCircularDependenciesBack(helper, variable,
+ metadata->parameters[i].value,
checkedVariables)) {
return true;
}
@@ -2673,21 +2696,73 @@ bool setTypesFunctionCall(AstTree *tree, AstTreeSetTypesHelper helper) {
return NULL;
}
- for (size_t i = 0; i < metadata->parameters_size; ++i) {
- AstTreeVariable *arg = function->arguments.data[i];
- AstTree *param = metadata->parameters[i];
+ bool initedArguments[function->arguments.size];
+ size_t initedArguments_size = function->arguments.size;
- AstTreeSetTypesHelper newHelper = {
- .lookingType = arg->type,
- .pages = helper.pages,
- .treeHelper = helper.treeHelper,
- };
+ for (size_t i = 0; i < initedArguments_size; ++i) {
+ initedArguments[i] = false;
+ }
- if (!setAllTypes(param, newHelper, 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) {
+ AstTreeVariable *arg = function->arguments.data[j];
+ if ((size_t)(arg->name_end - arg->name_begin) == param_name_size &&
+ strncmp(arg->name_begin, param.nameBegin, param_name_size) == 0) {
+ initedArguments[j] = true;
+ AstTreeSetTypesHelper newHelper = {
+ .lookingType = arg->type,
+ .pages = helper.pages,
+ .treeHelper = helper.treeHelper,
+ };
+
+ if (!setAllTypes(param.value, newHelper, NULL)) {
+ return false;
+ }
+ 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) {
+ AstTreeVariable *arg = function->arguments.data[j];
+ if (!initedArguments[j]) {
+ initedArguments[j] = true;
+ AstTreeSetTypesHelper newHelper = {
+ .lookingType = arg->type,
+ .pages = helper.pages,
+ .treeHelper = helper.treeHelper,
+ };
+
+ if (!setAllTypes(param.value, newHelper, NULL)) {
+ return false;
+ }
+ 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) {
+ AstTreeVariable *arg = function->arguments.data[i];
+ if (!initedArguments[i] && arg->value == NULL) {
+ printError(arg->name_begin, arg->name_end, "Argument is not initialized");
+ return false;
+ }
}
tree->type = copyAstTree(function->returnType);
diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h
index 19ff9e9..8fdeb53 100644
--- a/src/compiler/ast-tree.h
+++ b/src/compiler/ast-tree.h
@@ -122,9 +122,15 @@ typedef struct AstTreeTypeFunction {
AstTree *returnType;
} AstTreeTypeFunction;
+typedef struct AstTreeFunctionCallParam {
+ char *nameBegin;
+ char *nameEnd;
+ AstTree *value;
+} AstTreeFunctionCallParam;
+
typedef struct AstTreeFunctionCall {
AstTree *function;
- AstTree **parameters;
+ AstTreeFunctionCallParam *parameters;
size_t parameters_size;
} AstTreeFunctionCall;
diff --git a/src/compiler/parser.c b/src/compiler/parser.c
index d816ec9..08f262c 100644
--- a/src/compiler/parser.c
+++ b/src/compiler/parser.c
@@ -912,7 +912,7 @@ ParserNode *parserNumber(LexerNode *node, ParserNode *parent) {
// fall through
default: {
bool success;
- uint64_t value = decimalToU64(node->str_begin, node->str_end, &success);
+ u64 value = decimalToU64(node->str_begin, node->str_end, &success);
if (success) {
parserNode =
newParserNode(PARSER_TOKEN_VALUE_INT, node->str_begin, node->str_end,
diff --git a/src/runner/runner.c b/src/runner/runner.c
index 36c84e5..576ada5 100644
--- a/src/runner/runner.c
+++ b/src/runner/runner.c
@@ -172,7 +172,7 @@ bool runAstTree(AstTreeRoot *root) {
return false;
}
-AstTree *runAstTreeFunction(AstTree *tree, AstTree **arguments,
+AstTree *runAstTreeFunction(AstTree *tree, AstTreeFunctionCallParam *arguments,
size_t arguments_size,
RunnerVariablePages *_pages) {
AstTreeFunction *function = tree->metadata;
@@ -193,11 +193,67 @@ AstTree *runAstTreeFunction(AstTree *tree, AstTree **arguments,
bool shouldRet = false;
+ bool initedArguments[function->arguments.size];
+ size_t initedArguments_size = function->arguments.size;
+
+ for (size_t i = 0; i < initedArguments_size; ++i) {
+ initedArguments[i] = false;
+ }
+
for (size_t i = 0; i < arguments_size; ++i) {
- AstTreeVariable *variable = function->arguments.data[i];
- AstTree *value = runExpression(arguments[i], &pages, &shouldRet);
- runnerVariablePush(pages.data[pages.size - 1], variable);
- runnerVariableSetValue(&pages, variable, value);
+ AstTreeFunctionCallParam param = arguments[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) {
+ AstTreeVariable *arg = function->arguments.data[j];
+ if ((size_t)(arg->name_end - arg->name_begin) == param_name_size &&
+ strncmp(arg->name_begin, param.nameBegin, param_name_size) == 0) {
+ initedArguments[j] = true;
+
+ AstTree *value = runExpression(param.value, &pages, &shouldRet);
+ runnerVariablePush(pages.data[pages.size - 1], arg);
+ runnerVariableSetValue(&pages, arg, value);
+ goto END_OF_NAMED_FOR;
+ }
+ }
+ printError(param.value->str_begin, param.value->str_end,
+ "Argument not found");
+ UNREACHABLE;
+ }
+ END_OF_NAMED_FOR:
+ }
+
+ for (size_t i = 0; i < arguments_size; ++i) {
+ AstTreeFunctionCallParam param = arguments[i];
+ if (param.nameBegin == param.nameEnd) {
+ for (size_t j = 0; j < function->arguments.size; ++j) {
+ AstTreeVariable *arg = function->arguments.data[j];
+ if (!initedArguments[j]) {
+ initedArguments[j] = true;
+
+ AstTree *value = runExpression(param.value, &pages, &shouldRet);
+ runnerVariablePush(pages.data[pages.size - 1], arg);
+ runnerVariableSetValue(&pages, arg, value);
+ goto END_OF_UNNAMED_FOR;
+ }
+ }
+ printError(param.value->str_begin, param.value->str_end,
+ "Too many arguments");
+ UNREACHABLE;
+ }
+ END_OF_UNNAMED_FOR:
+ }
+
+ for (size_t i = 0; i < function->arguments.size; ++i) {
+ AstTreeVariable *arg = function->arguments.data[i];
+ if (!initedArguments[i]) {
+ if (arg->value == NULL) {
+ printError(arg->name_begin, arg->name_end,
+ "Argument is not initialized");
+ } else {
+ runnerVariablePush(pages.data[pages.size - 1], arg);
+ }
+ }
}
shouldRet = false;
diff --git a/src/runner/runner.h b/src/runner/runner.h
index 060821c..fd64d1e 100644
--- a/src/runner/runner.h
+++ b/src/runner/runner.h
@@ -31,7 +31,7 @@ void destroyRootPages(RunnerVariablePages pages);
bool runAstTree(AstTreeRoot *root);
-AstTree *runAstTreeFunction(AstTree *tree, AstTree **arguments,
+AstTree *runAstTreeFunction(AstTree *tree, AstTreeFunctionCallParam *arguments,
size_t arguments_size, RunnerVariablePages *pages);
AstTree *runExpression(AstTree *expr, RunnerVariablePages *pages,
diff --git a/test/main.felan b/test/main.felan
index 111da65..3c13579 100644
--- a/test/main.felan
+++ b/test/main.felan
@@ -2,9 +2,8 @@ main :: () -> void {
print_u64 a;
};
-a :: f(2);
+a :: f(b=4,a=5);
-f :: (arg:u64)->u64{
- b:=arg;
- return b;
+f :: (a:u64,b:u64)->u64{
+ return a-b;
};