From 070a3687529954280cf26f294432037a03d1542e Mon Sep 17 00:00:00 2001 From: A404M Date: Wed, 16 Apr 2025 12:12:52 +0330 Subject: add .length to arrays --- code/main.felan | 15 ++++----- src/compiler/ast-tree.c | 88 +++++++++++++++++++++++-------------------------- src/runner/runner.c | 83 ++++++++++++++++++++++++++++++---------------- 3 files changed, 102 insertions(+), 84 deletions(-) diff --git a/code/main.felan b/code/main.felan index 470479f..132c24e 100644 --- a/code/main.felan +++ b/code/main.felan @@ -1,15 +1,12 @@ main :: () -> void { - a := "Hello world\n"; - i := 0; - while i < 12 { - putc a[i]; - i += 1; - } - print(a); + print("Hello world!\n"); }; print :: (value:[]u8)->void{ - i := 0; - putc 'h'; + i :u64= 0; + while i < value.length { + putc value[i]; + i += 1; + } }; diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index ab12408..c5268d7 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -3689,6 +3689,13 @@ bool setTypesValueUndefined(AstTree *tree, AstTreeSetTypesHelper helper) { if (helper.lookingType == NULL) { printError(tree->str_begin, tree->str_end, "Can't find type of undefined"); return false; + } else if (helper.lookingType->token == AST_TREE_TOKEN_TYPE_ARRAY) { + AstTreeBracket *array_metadata = helper.lookingType->metadata; + if (array_metadata->parameters.size == 0) { + printError(tree->str_begin, tree->str_end, + "Can't find size of array valued undefined"); + return false; + } } tree->type = copyAstTree(helper.lookingType); return true; @@ -3917,33 +3924,7 @@ bool setTypesVariable(AstTree *tree, AstTreeSetTypesHelper helper, AstTreeVariable *variable = NULL; size_t variable_index = -1ULL; - if (helper.lookingType != NULL) { - for (size_t i = 0; i < variables->size; ++i) { - AstTreeVariable *var = variables->data[i].variable; - size_t index = variables->data[i].index; - - if (!setTypesAstVariable(var, helper)) { - goto RETURN_ERROR; - } - - if (!typeIsEqual(var->type, helper.lookingType)) { - continue; - } - - if (variable != NULL) { - if (variable_index > index) { - continue; - } else if (variable != NULL && variable_index == index) { - printError(tree->str_begin, tree->str_end, - "Multiple candidates found"); - goto RETURN_ERROR; - } - } - - variable = var; - variable_index = index; - } - } else if (functionCall == NULL) { + if (functionCall == NULL) { for (size_t i = 0; i < variables->size; ++i) { AstTreeVariable *var = variables->data[i].variable; size_t index = variables->data[i].index; @@ -4384,29 +4365,44 @@ bool setTypesOperatorAccess(AstTree *tree, AstTreeSetTypesHelper helper) { AstTreeAccess *metadata = tree->metadata; if (!setAllTypes(metadata->object, helper, NULL, NULL)) { return false; - } else if (metadata->object->type->token != AST_TREE_TOKEN_KEYWORD_STRUCT) { - printError(metadata->object->str_begin, metadata->object->str_end, - "The object is not a struct"); - return false; - } - - AstTreeStruct *struc = metadata->object->type->metadata; - const size_t size = metadata->member.name.end - metadata->member.name.begin; - const char *str = metadata->member.name.begin; + } else if (metadata->object->type->token == AST_TREE_TOKEN_TYPE_ARRAY) { + const size_t size = metadata->member.name.end - metadata->member.name.begin; + const char *str = metadata->member.name.begin; - for (size_t i = 0; i < struc->variables.size; ++i) { - AstTreeVariable *member = struc->variables.data[i]; - const size_t member_size = member->name_end - member->name_begin; - if (member_size == size && strncmp(member->name_begin, str, size) == 0) { - metadata->member.index = i; - tree->type = copyAstTree(member->type); + const char LENGTH_STR[] = "length"; + const size_t LENGTH_STR_SIZE = strlen(LENGTH_STR); + if (LENGTH_STR_SIZE == size && strncmp(LENGTH_STR, str, size) == 0) { + metadata->member.index = 0; + tree->type = copyAstTree(&AST_TREE_U64_TYPE); return true; } - } - printError(metadata->member.name.begin, metadata->member.name.end, - "Member not found"); - return false; + printError(metadata->member.name.begin, metadata->member.name.end, + "Member not found"); + return false; + } else if (metadata->object->type->token == AST_TREE_TOKEN_KEYWORD_STRUCT) { + AstTreeStruct *struc = metadata->object->type->metadata; + const size_t size = metadata->member.name.end - metadata->member.name.begin; + const char *str = metadata->member.name.begin; + + for (size_t i = 0; i < struc->variables.size; ++i) { + AstTreeVariable *member = struc->variables.data[i]; + const size_t member_size = member->name_end - member->name_begin; + if (member_size == size && strncmp(member->name_begin, str, size) == 0) { + metadata->member.index = i; + tree->type = copyAstTree(member->type); + return true; + } + } + + printError(metadata->member.name.begin, metadata->member.name.end, + "Member not found"); + return false; + } else { + printError(metadata->object->str_begin, metadata->object->str_end, + "The object is not a struct"); + return false; + } } bool setTypesBuiltin(AstTree *tree, AstTreeSetTypesHelper helper, diff --git a/src/runner/runner.c b/src/runner/runner.c index 9490d91..f6e7e88 100644 --- a/src/runner/runner.c +++ b/src/runner/runner.c @@ -1167,44 +1167,69 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet, case AST_TREE_TOKEN_OPERATOR_ACCESS: { AstTreeAccess *metadata = expr->metadata; AstTree *tree = runExpression(metadata->object, scope, shouldRet, true); - if (tree->type->token != AST_TREE_TOKEN_KEYWORD_STRUCT && - tree->token != AST_TREE_TOKEN_VARIABLE) { + if (tree->token != AST_TREE_TOKEN_VARIABLE) { UNREACHABLE; } AstTreeVariable *variable = tree->metadata; astTreeDelete(tree); - if (variable->value->token == AST_TREE_TOKEN_VALUE_UNDEFINED) { - AstTreeStruct *struc = variable->type->metadata; - AstTreeObject *newMetadata = a404m_malloc(sizeof(*newMetadata)); + if (variable->type->token == AST_TREE_TOKEN_TYPE_ARRAY) { + AstTreeBracket *array_metadata = variable->type->metadata; + if (metadata->member.index != 0) { + UNREACHABLE; + } else if (variable->value->token == AST_TREE_TOKEN_VALUE_UNDEFINED) { + if (array_metadata->parameters.size == 0) { + UNREACHABLE; + } else { + AstTree *sizeTree = runExpression(array_metadata->parameters.data[0], + scope, shouldRet, false); + if (sizeTree->token != AST_TREE_TOKEN_VALUE_INT) { + UNREACHABLE; + } else { + return sizeTree; + } + } + } else if (variable->value->token == AST_TREE_TOKEN_VALUE_OBJECT) { + AstTreeObject *object = variable->value->metadata; + AstTreeInt *res_metadata = a404m_malloc(sizeof(*res_metadata)); + *res_metadata = object->variables.size; + return newAstTree(AST_TREE_TOKEN_VALUE_INT, res_metadata, + &AST_TREE_U64_TYPE, NULL, NULL); + } + } else if (variable->type->token == AST_TREE_TOKEN_KEYWORD_STRUCT) { + if (variable->value->token == AST_TREE_TOKEN_VALUE_UNDEFINED) { + AstTreeStruct *struc = variable->type->metadata; + AstTreeObject *newMetadata = a404m_malloc(sizeof(*newMetadata)); - newMetadata->variables = - copyAstTreeVariables(struc->variables, NULL, NULL, 0); + newMetadata->variables = + copyAstTreeVariables(struc->variables, NULL, NULL, 0); - for (size_t i = 0; i < newMetadata->variables.size; ++i) { - AstTreeVariable *member = newMetadata->variables.data[i]; - if (!member->isConst) { - runnerVariableSetValue(member, - newAstTree(AST_TREE_TOKEN_VALUE_UNDEFINED, - NULL, copyAstTree(member->type), - variable->value->str_begin, - variable->value->str_end)); + for (size_t i = 0; i < newMetadata->variables.size; ++i) { + AstTreeVariable *member = newMetadata->variables.data[i]; + if (!member->isConst) { + runnerVariableSetValue(member, + newAstTree(AST_TREE_TOKEN_VALUE_UNDEFINED, + NULL, copyAstTree(member->type), + variable->value->str_begin, + variable->value->str_end)); + } } - } - runnerVariableSetValue(variable, newAstTree(AST_TREE_TOKEN_VALUE_OBJECT, - newMetadata, - copyAstTree(variable->type), - variable->value->str_begin, - variable->value->str_end)); - } - AstTreeObject *object = variable->value->metadata; - AstTreeVariable *var = object->variables.data[metadata->member.index]; - if (isLeft) { - return newAstTree(AST_TREE_TOKEN_VARIABLE, var, copyAstTree(var->type), - var->name_begin, var->name_end); - } else { - return copyAstTree(var->value); + runnerVariableSetValue(variable, newAstTree(AST_TREE_TOKEN_VALUE_OBJECT, + newMetadata, + copyAstTree(variable->type), + variable->value->str_begin, + variable->value->str_end)); + } + AstTreeObject *object = variable->value->metadata; + AstTreeVariable *var = object->variables.data[metadata->member.index]; + if (isLeft) { + return newAstTree(AST_TREE_TOKEN_VARIABLE, var, copyAstTree(var->type), + var->name_begin, var->name_end); + } else { + return copyAstTree(var->value); + } } + UNREACHABLE; } case AST_TREE_TOKEN_KEYWORD_STRUCT: { expr = copyAstTree(expr); -- cgit v1.2.3