diff options
-rw-r--r-- | src/compiler/ast-tree.c | 117 | ||||
-rw-r--r-- | src/compiler/ast-tree.h | 8 | ||||
-rw-r--r-- | src/compiler/parser.c | 2 | ||||
-rw-r--r-- | src/runner/runner.c | 66 | ||||
-rw-r--r-- | src/runner/runner.h | 2 | ||||
-rw-r--r-- | test/main.felan | 7 |
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; }; |