From f5dfb8ca90a014a6b7667e5ded62e0bae1d60367 Mon Sep 17 00:00:00 2001 From: A404M Date: Fri, 9 May 2025 23:01:00 +0330 Subject: add named imports --- src/compiler/ast-tree.c | 238 +++++++++++++++++++++++++++++++++++++++++++----- src/compiler/ast-tree.h | 13 ++- src/compiler/lexer.c | 6 +- src/compiler/lexer.h | 1 + src/compiler/parser.c | 10 ++ src/compiler/parser.h | 1 + src/runner/runner.c | 2 + 7 files changed, 246 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/compiler/ast-tree.c b/src/compiler/ast-tree.c index 2f47e8b..56daf7d 100644 --- a/src/compiler/ast-tree.c +++ b/src/compiler/ast-tree.c @@ -108,6 +108,12 @@ AstTree AST_TREE_CODE_TYPE = { .type = &AST_TREE_TYPE_TYPE, }; +AstTree AST_TREE_NAMESPACE_TYPE = { + .token = AST_TREE_TOKEN_TYPE_NAMESPACE, + .metadata = NULL, + .type = &AST_TREE_TYPE_TYPE, +}; + AstTree AST_TREE_VOID_VALUE = { .token = AST_TREE_TOKEN_VALUE_VOID, .metadata = NULL, @@ -162,6 +168,7 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_TYPE_F64", "AST_TREE_TOKEN_TYPE_F128", "AST_TREE_TOKEN_TYPE_CODE", + "AST_TREE_TOKEN_TYPE_NAMESPACE", "AST_TREE_TOKEN_TYPE_BOOL", "AST_TREE_TOKEN_VALUE_VOID", @@ -170,6 +177,7 @@ const char *AST_TREE_TOKEN_STRINGS[] = { "AST_TREE_TOKEN_VARIABLE_DEFINE", "AST_TREE_TOKEN_VALUE_NULL", "AST_TREE_TOKEN_VALUE_UNDEFINED", + "AST_TREE_TOKEN_VALUE_NAMESPACE", "AST_TREE_TOKEN_VALUE_INT", "AST_TREE_TOKEN_VALUE_FLOAT", "AST_TREE_TOKEN_VALUE_BOOL", @@ -257,6 +265,18 @@ void astTreePrint(const AstTree *tree, int indent) { 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_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_VOID: case AST_TREE_TOKEN_TYPE_I8: @@ -274,6 +294,7 @@ void astTreePrint(const AstTree *tree, int indent) { 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_BOOL: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_NULL: @@ -686,12 +707,18 @@ void astTreeDestroy(AstTree tree) { 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_BOOL: case AST_TREE_TOKEN_VALUE_NULL: case AST_TREE_TOKEN_VALUE_UNDEFINED: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VARIABLE_DEFINE: return; + case AST_TREE_TOKEN_VALUE_NAMESPACE: { + AstTreeNamespace *metadata = tree.metadata; + free(metadata); + return; + } case AST_TREE_TOKEN_VALUE_BOOL: { AstTreeBool *metadata = tree.metadata; free(metadata); @@ -938,6 +965,7 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], 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_VALUE_VOID: return tree; case AST_TREE_TOKEN_VALUE_NULL: @@ -964,6 +992,16 @@ AstTree *copyAstTreeBack(AstTree *tree, AstTreeVariables oldVariables[], tree->token, NULL, copyAstTreeBack(tree->type, oldVariables, newVariables, variables_size), tree->str_begin, tree->str_end); + + case AST_TREE_TOKEN_VALUE_NAMESPACE: { + AstTreeNamespace *metadata = tree->metadata; + AstTreeNamespace *newMetadata = a404m_malloc(sizeof(*newMetadata)); + newMetadata->importedIndex = metadata->importedIndex; + return newAstTree( + tree->token, newMetadata, + copyAstTreeBack(tree->type, oldVariables, newVariables, variables_size), + tree->str_begin, tree->str_end); + } case AST_TREE_TOKEN_VALUE_BOOL: { AstTreeBool *metadata = tree->metadata; AstTreeBool *newMetadata = a404m_malloc(sizeof(*newMetadata)); @@ -1433,6 +1471,7 @@ AstTreeRoot *getAstTreeRoot(char *filePath, AstTreeRoots *roots .dependencies.data = NULL, .dependencies.size = 0, .variables = root->variables, + .root = root, }; if (!setAllTypes(tree, helper, NULL, NULL)) { goto RETURN_ERROR; @@ -1483,13 +1522,102 @@ AstTreeRoot *getAstTreeRoot(char *filePath, AstTreeRoots *roots goto RETURN_ERROR; } - root->imports[root->imports_size++] = import; + root->imports[root->imports_size].root = import; + root->imports[root->imports_size].visible = true; + root->imports_size += 1; astTreeDelete(type); } } } + for (size_t i = 0; i < root->variables.size; ++i) { + AstTreeVariable *variable = root->variables.data[i]; + if (!variable->isConst) { + continue; + } + AstTree *tree = variable->value; + if (tree->token == AST_TREE_TOKEN_FUNCTION_CALL) { + AstTreeFunctionCall *tree_metadata = tree->metadata; + AstTree *operand = tree_metadata->function; + if (operand->token == AST_TREE_TOKEN_BUILTIN_IMPORT) { + AstTreeSetTypesHelper helper = { + .lookingType = NULL, + .dependencies.data = NULL, + .dependencies.size = 0, + .variables = root->variables, + .root = root, + }; + if (!setAllTypes(tree, helper, NULL, NULL)) { + goto RETURN_ERROR; + } + AstTree *parameter = tree_metadata->parameters[0].value; + if (!isConstByValue(parameter)) { + printError(parameter->str_begin, parameter->str_end, + "Is not constant"); + goto RETURN_ERROR; + } + parameter = getValue(parameter); + if (parameter == NULL) { + goto RETURN_ERROR; + } + + AstTreeBracket *type_metadata = a404m_malloc(sizeof(*type_metadata)); + type_metadata->operand = &AST_TREE_U8_TYPE; + + type_metadata->parameters.size = 0; + type_metadata->parameters.data = + a404m_malloc(0 * sizeof(*type_metadata->parameters.data)); + + AstTree *type = newAstTree(AST_TREE_TOKEN_TYPE_ARRAY, type_metadata, + &AST_TREE_TYPE_TYPE, NULL, NULL); + + if (!typeIsEqual(type, parameter->type)) { + printError(parameter->str_begin, parameter->str_end, + "Type mismatch (must be a []u8 aka string)"); + astTreeDelete(type); + goto RETURN_ERROR; + } + astTreeDelete(type); + + char *str = u8ArrayToCString(parameter); + astTreeDelete(parameter); + + const size_t imports_size = + a404m_malloc_usable_size(root->imports) / sizeof(*root->imports); + if (imports_size == root->imports_size) { + root->imports = a404m_realloc(root->imports, + (imports_size + imports_size / 2 + 1) * + sizeof(*root->imports)); + } + + AstTreeRoot *import = getAstTreeRoot(joinToPathOf(filePath, str), roots, + lexingTime, parsingTime); + free(str); + + if (import == NULL) { + goto RETURN_ERROR; + } + + AstTreeNamespace *value_metadata = + a404m_malloc(sizeof(*value_metadata)); + value_metadata->importedIndex = root->imports_size; + + root->imports[root->imports_size].root = import; + root->imports[root->imports_size].visible = false; + root->imports_size += 1; + + AstTree *oldValue = variable->value; + variable->value = + newAstTree(AST_TREE_TOKEN_VALUE_NAMESPACE, value_metadata, + copyAstTree(&AST_TREE_NAMESPACE_TYPE), + oldValue->str_begin, oldValue->str_end); + + astTreeDelete(oldValue); + } + } + } + return root; RETURN_ERROR: @@ -1668,6 +1796,7 @@ AstTreeRoot *makeAstRoot(const ParserNode *parsedRoot, char *filePath) { case PARSER_TOKEN_TYPE_F64: case PARSER_TOKEN_TYPE_F128: case PARSER_TOKEN_TYPE_CODE: + case PARSER_TOKEN_TYPE_NAMESPACE: case PARSER_TOKEN_TYPE_BOOL: case PARSER_TOKEN_OPERATOR_POINTER: case PARSER_TOKEN_OPERATOR_ADDRESS: @@ -1860,6 +1989,8 @@ AstTree *astTreeParse(const ParserNode *parserNode, AstTreeHelper *helper) { return &AST_TREE_F128_TYPE; case PARSER_TOKEN_TYPE_CODE: return &AST_TREE_CODE_TYPE; + case PARSER_TOKEN_TYPE_NAMESPACE: + return &AST_TREE_NAMESPACE_TYPE; case PARSER_TOKEN_TYPE_BOOL: return &AST_TREE_BOOL_TYPE; case PARSER_TOKEN_FUNCTION_CALL: @@ -2102,6 +2233,7 @@ AstTree *astTreeParseFunction(const ParserNode *parserNode, case PARSER_TOKEN_TYPE_F64: case PARSER_TOKEN_TYPE_F128: case PARSER_TOKEN_TYPE_CODE: + case PARSER_TOKEN_TYPE_NAMESPACE: case PARSER_TOKEN_TYPE_BOOL: case PARSER_TOKEN_KEYWORD_PUTC: case PARSER_TOKEN_KEYWORD_RETURN: @@ -2733,6 +2865,7 @@ AstTree *astTreeParseCurlyBracket(const ParserNode *parserNode, case PARSER_TOKEN_TYPE_F64: case PARSER_TOKEN_TYPE_F128: case PARSER_TOKEN_TYPE_CODE: + case PARSER_TOKEN_TYPE_NAMESPACE: case PARSER_TOKEN_TYPE_BOOL: case PARSER_TOKEN_KEYWORD_PUTC: case PARSER_TOKEN_KEYWORD_RETURN: @@ -3013,10 +3146,12 @@ bool isConst(AstTree *tree) { 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_BOOL: case AST_TREE_TOKEN_VALUE_NULL: case AST_TREE_TOKEN_VALUE_UNDEFINED: case AST_TREE_TOKEN_VALUE_VOID: + case AST_TREE_TOKEN_VALUE_NAMESPACE: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_FLOAT: case AST_TREE_TOKEN_VALUE_BOOL: @@ -3145,10 +3280,12 @@ bool isConstByValue(AstTree *tree) { 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_BOOL: case AST_TREE_TOKEN_VALUE_NULL: case AST_TREE_TOKEN_VALUE_UNDEFINED: case AST_TREE_TOKEN_VALUE_VOID: + case AST_TREE_TOKEN_VALUE_NAMESPACE: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_FLOAT: case AST_TREE_TOKEN_VALUE_BOOL: @@ -3256,6 +3393,7 @@ AstTree *makeTypeOf(AstTree *value) { 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_BOOL: case AST_TREE_TOKEN_OPERATOR_POINTER: case AST_TREE_TOKEN_KEYWORD_STRUCT: @@ -3303,6 +3441,8 @@ AstTree *makeTypeOf(AstTree *value) { } case AST_TREE_TOKEN_VALUE_VOID: return &AST_TREE_VOID_TYPE; + case AST_TREE_TOKEN_VALUE_NAMESPACE: + return &AST_TREE_NAMESPACE_TYPE; case AST_TREE_TOKEN_VALUE_INT: return &AST_TREE_U64_TYPE; case AST_TREE_TOKEN_VALUE_FLOAT: @@ -3446,6 +3586,7 @@ bool typeIsEqualBack(const AstTree *type0, const AstTree *type1) { case AST_TREE_TOKEN_VALUE_NULL: case AST_TREE_TOKEN_VALUE_UNDEFINED: case AST_TREE_TOKEN_VALUE_VOID: + case AST_TREE_TOKEN_VALUE_NAMESPACE: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_FLOAT: case AST_TREE_TOKEN_VALUE_BOOL: @@ -3494,6 +3635,7 @@ bool typeIsEqualBack(const AstTree *type0, const AstTree *type1) { case AST_TREE_TOKEN_TYPE_F64: case AST_TREE_TOKEN_TYPE_F128: case AST_TREE_TOKEN_TYPE_CODE: + case AST_TREE_TOKEN_TYPE_NAMESPACE: return type1->token == type0->token; case AST_TREE_TOKEN_OPERATOR_POINTER: { if (type1->token != type0->token) { @@ -3616,10 +3758,12 @@ AstTree *getValue(AstTree *tree) { 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_BOOL: case AST_TREE_TOKEN_VALUE_NULL: case AST_TREE_TOKEN_VALUE_UNDEFINED: case AST_TREE_TOKEN_VALUE_VOID: + case AST_TREE_TOKEN_VALUE_NAMESPACE: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_FLOAT: case AST_TREE_TOKEN_VALUE_BOOL: @@ -3736,8 +3880,10 @@ bool isIntType(AstTree *type) { 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_BOOL: case AST_TREE_TOKEN_VALUE_VOID: + case AST_TREE_TOKEN_VALUE_NAMESPACE: case AST_TREE_TOKEN_FUNCTION_CALL: case AST_TREE_TOKEN_VARIABLE: case AST_TREE_TOKEN_VARIABLE_DEFINE: @@ -3798,11 +3944,18 @@ bool isEqual(AstTree *left, AstTree *right) { 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_BOOL: case AST_TREE_TOKEN_VALUE_VOID: case AST_TREE_TOKEN_VALUE_NULL: case AST_TREE_TOKEN_VALUE_UNDEFINED: return true; + case AST_TREE_TOKEN_VALUE_NAMESPACE: { + AstTreeNamespace *left_metadata = left->metadata; + AstTreeNamespace *right_metadata = right->metadata; + + return left_metadata->importedIndex == right_metadata->importedIndex; + } case AST_TREE_TOKEN_VALUE_INT: { AstTreeInt *left_metadata = left->metadata; AstTreeInt *right_metadata = right->metadata; @@ -3921,7 +4074,9 @@ void allOfVariablesWithImport(AstTreeVariables *variables, AstTreeRoot *root, } for (size_t i = 0; i < root->imports_size; ++i) { - allOfVariablesWithImport(variables, root->imports[i], checkedRoots); + if (root->imports[i].visible) { + allOfVariablesWithImport(variables, root->imports[i].root, checkedRoots); + } } } @@ -3943,6 +4098,7 @@ bool setAllTypesRoot(AstTreeRoot *root) { .size = 0, }, .variables = variables, + .root = root, }; for (size_t i = 0; i < root->variables.size; ++i) { @@ -4046,8 +4202,11 @@ bool setAllTypes(AstTree *tree, AstTreeSetTypesHelper helper, 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_VALUE_VOID: return true; + case AST_TREE_TOKEN_VALUE_NAMESPACE: + NOT_IMPLEMENTED; case AST_TREE_TOKEN_VALUE_BOOL: return setTypesValueBool(tree, helper); case AST_TREE_TOKEN_VALUE_INT: @@ -4380,6 +4539,7 @@ bool setTypesFunction(AstTree *tree, AstTreeSetTypesHelper _helper) { .dependencies = _helper.dependencies, .variables.data = variables, .variables.size = _helper.variables.size, + .root = _helper.root, }; AstTreeVariable *deps[helper.dependencies.size]; @@ -4444,6 +4604,7 @@ bool setTypesPrintU64(AstTree *tree, AstTreeSetTypesHelper _helper) { .lookingType = &AST_TREE_U8_TYPE, .dependencies = _helper.dependencies, .variables = _helper.variables, + .root = _helper.root, }; if (!setAllTypes(metadata, helper, NULL, NULL)) { return false; @@ -4468,6 +4629,7 @@ bool setTypesReturn(AstTree *tree, AstTreeSetTypesHelper _helper, .lookingType = getValue(function->returnType), .dependencies = _helper.dependencies, .variables = _helper.variables, + .root = _helper.root, }; if (helper.lookingType == NULL) { return false; @@ -4518,6 +4680,7 @@ bool setTypesFunctionCall(AstTree *tree, AstTreeSetTypesHelper _helper) { .lookingType = NULL, .dependencies = _helper.dependencies, .variables = _helper.variables, + .root = _helper.root, }; for (size_t i = 0; i < metadata->parameters_size; ++i) { @@ -4649,6 +4812,7 @@ bool setTypesOperatorInfix(AstTree *tree, AstTreeSetTypesHelper _helper, .lookingType = NULL, .dependencies = _helper.dependencies, .variables = _helper.variables, + .root = _helper.root, }; if (!setAllTypes(metadata->left, helper, NULL, NULL) || @@ -4709,6 +4873,7 @@ bool setTypesOperatorInfixWithRetAndLooking(AstTree *tree, AstTree *lookingType, .lookingType = lookingType, .dependencies = _helper.dependencies, .variables = _helper.variables, + .root = _helper.root, }; return setTypesOperatorInfixWithRet(tree, retType, helper); } @@ -4823,6 +4988,7 @@ bool setTypesAstVariable(AstTreeVariable *variable, .size = _helper.dependencies.size + 1, }, .variables = _helper.variables, + .root = _helper.root, }; // previously done @@ -4880,12 +5046,10 @@ bool setTypesAstVariable(AstTreeVariable *variable, AST_TREE_TOKEN_STRINGS[value->type->token], AST_TREE_TOKEN_STRINGS[variable->type->token]); return false; - } else if (variable->isConst) { - if (!isConst(value)) { - printError(value->str_begin, value->str_end, - "Can't initialize constant with non constant value"); - return false; - } + } else if (variable->isConst && !isConst(value)) { + printError(value->str_begin, value->str_end, + "Can't initialize constant with non constant value"); + return false; } } @@ -4953,6 +5117,7 @@ bool setTypesScope(AstTree *tree, AstTreeSetTypesHelper _helper, .dependencies = _helper.dependencies, .variables.data = variables, .variables.size = _helper.variables.size, + .root = _helper.root, }; for (size_t i = 0; i < metadata->variables.size; ++i) { @@ -5061,9 +5226,35 @@ bool setTypesOperatorAccess(AstTree *tree, AstTreeSetTypesHelper helper) { printError(metadata->member.name.begin, metadata->member.name.end, "Member not found"); return false; - } else if (typeIsEqual(metadata->object->type, &AST_TREE_CODE_TYPE)) { - printError(metadata->object->str_begin, metadata->object->str_end, "Here"); - UNREACHABLE; + } else if (typeIsEqual(metadata->object->type, &AST_TREE_NAMESPACE_TYPE)) { + AstTree *value = getValue(metadata->object); + AstTreeNamespace *namespace = value->metadata; + AstTreeSetTypesHelper newHelper = { + .root = helper.root->imports[namespace->importedIndex].root, + .variables = + helper.root->imports[namespace->importedIndex].root->variables, + .dependencies = helper.dependencies, + .lookingType = helper.lookingType, + }; + astTreeDelete(value); + + AstTreeVariable *var = + setTypesFindVariable(metadata->member.name.begin, + metadata->member.name.end, newHelper, NULL); + if (var == NULL) { + printError(metadata->member.name.begin, metadata->member.name.end, + "Is not found"); + return false; + } + astTreeDestroy(*tree); + *tree = (AstTree){ + .token = AST_TREE_TOKEN_VARIABLE, + .metadata = var, + .type = copyAstTree(var->type), + .str_begin = var->name_begin, + .str_end = var->name_end, + }; + return true; } else { printError(metadata->object->str_begin, metadata->object->str_end, "The object is not a struct %s", @@ -5149,7 +5340,6 @@ bool setTypesBuiltinCast(AstTree *tree, AstTreeSetTypesHelper helper, printError(tree->str_begin, tree->str_end, "Too many or too few arguments"); return false; } - return false; } bool setTypesBuiltinTypeOf(AstTree *tree, AstTreeSetTypesHelper helper, @@ -5211,7 +5401,6 @@ bool setTypesBuiltinTypeOf(AstTree *tree, AstTreeSetTypesHelper helper, printError(tree->str_begin, tree->str_end, "Too many or too few arguments"); return false; } - return false; } bool setTypesBuiltinImport(AstTree *tree, AstTreeSetTypesHelper helper, @@ -5220,9 +5409,9 @@ bool setTypesBuiltinImport(AstTree *tree, AstTreeSetTypesHelper helper, if (functionCall->parameters_size == 1) { AstTree *file = NULL; - static const char VARIABLE_STR[] = "variable"; - static const size_t VARIABLE_STR_SIZE = - sizeof(VARIABLE_STR) / sizeof(*VARIABLE_STR) - sizeof(*VARIABLE_STR); + 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]; @@ -5236,8 +5425,8 @@ bool setTypesBuiltinImport(AstTree *tree, AstTreeSetTypesHelper helper, "Bad paramter"); return false; } - } else if (param_name_size == VARIABLE_STR_SIZE && - strnEquals(param.nameBegin, VARIABLE_STR, VARIABLE_STR_SIZE) && + } else if (param_name_size == PATH_STR_SIZE && + strnEquals(param.nameBegin, PATH_STR, PATH_STR_SIZE) && file == NULL) { file = param.value; } else { @@ -5256,24 +5445,24 @@ bool setTypesBuiltinImport(AstTree *tree, AstTreeSetTypesHelper helper, type_metadata->arguments = a404m_malloc(type_metadata->arguments_size * sizeof(*type_metadata->arguments)); - type_metadata->returnType = copyAstTree(&AST_TREE_CODE_TYPE); + type_metadata->returnType = copyAstTree(&AST_TREE_NAMESPACE_TYPE); type_metadata->arguments[0] = (AstTreeTypeFunctionArgument){ .type = copyAstTree(file->type), - .name_begin = VARIABLE_STR, - .name_end = VARIABLE_STR + VARIABLE_STR_SIZE, + .name_begin = PATH_STR, + .name_end = PATH_STR + PATH_STR_SIZE, .str_begin = NULL, .str_end = NULL, }; tree->type = newAstTree(AST_TREE_TOKEN_TYPE_FUNCTION, type_metadata, &AST_TREE_TYPE_TYPE, NULL, NULL); + return true; } else { printError(tree->str_begin, tree->str_end, "Too many or too few arguments"); return false; } - return false; } bool setTypesBuiltinIsComptime(AstTree *tree, AstTreeSetTypesHelper helper) { @@ -5360,8 +5549,10 @@ bool setTypesBuiltinUnary(AstTree *tree, AstTreeSetTypesHelper helper, case AST_TREE_TOKEN_TYPE_TYPE: case AST_TREE_TOKEN_TYPE_VOID: case AST_TREE_TOKEN_TYPE_CODE: + case AST_TREE_TOKEN_TYPE_NAMESPACE: case AST_TREE_TOKEN_TYPE_BOOL: case AST_TREE_TOKEN_VALUE_VOID: + case AST_TREE_TOKEN_VALUE_NAMESPACE: case AST_TREE_TOKEN_FUNCTION_CALL: case AST_TREE_TOKEN_VARIABLE: case AST_TREE_TOKEN_VARIABLE_DEFINE: @@ -5594,6 +5785,7 @@ bool setTypesTypeArray(AstTree *tree, AstTreeSetTypesHelper helper) { .lookingType = &AST_TREE_U64_TYPE, .dependencies = helper.dependencies, .variables = helper.variables, + .root = helper.root, }; for (size_t i = 0; i < metadata->parameters.size; ++i) { @@ -5623,6 +5815,7 @@ bool setTypesArrayAccess(AstTree *tree, AstTreeSetTypesHelper _helper) { .lookingType = NULL, .dependencies = _helper.dependencies, .variables = _helper.variables, + .root = _helper.root, }; if (!setAllTypes(metadata->operand, helper, NULL, NULL)) { @@ -5661,6 +5854,7 @@ bool setTypesAstInfix(AstTreeInfix *infix, AstTreeSetTypesHelper _helper) { .lookingType = NULL, .dependencies = _helper.dependencies, .variables = _helper.variables, + .root = _helper.root, }; if (!setAllTypes(infix->left, helper, NULL, NULL)) { diff --git a/src/compiler/ast-tree.h b/src/compiler/ast-tree.h index 4d81616..91beae3 100644 --- a/src/compiler/ast-tree.h +++ b/src/compiler/ast-tree.h @@ -52,6 +52,7 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_TYPE_F64, AST_TREE_TOKEN_TYPE_F128, AST_TREE_TOKEN_TYPE_CODE, + AST_TREE_TOKEN_TYPE_NAMESPACE, AST_TREE_TOKEN_TYPE_BOOL, AST_TREE_TOKEN_VALUE_VOID, AST_TREE_TOKEN_STATIC_VARS_END = AST_TREE_TOKEN_VALUE_VOID, @@ -61,6 +62,7 @@ typedef enum AstTreeToken { AST_TREE_TOKEN_VARIABLE_DEFINE, AST_TREE_TOKEN_VALUE_NULL, AST_TREE_TOKEN_VALUE_UNDEFINED, + AST_TREE_TOKEN_VALUE_NAMESPACE, AST_TREE_TOKEN_VALUE_INT, AST_TREE_TOKEN_VALUE_FLOAT, AST_TREE_TOKEN_VALUE_BOOL, @@ -122,6 +124,7 @@ extern AstTree AST_TREE_F32_TYPE; extern AstTree AST_TREE_F64_TYPE; extern AstTree AST_TREE_F128_TYPE; extern AstTree AST_TREE_CODE_TYPE; +extern AstTree AST_TREE_NAMESPACE_TYPE; extern AstTree AST_TREE_VOID_VALUE; typedef struct AstTreeVariable { @@ -148,7 +151,10 @@ typedef struct AstTreeRoot { char *filePath; AstTreeVariables variables; AstTrees trees; - struct AstTreeRoot **imports; + struct { + struct AstTreeRoot *root; + bool visible; + } *imports; size_t imports_size; } AstTreeRoot; @@ -244,6 +250,7 @@ typedef struct AstTreeSetTypesHelper { AstTree *lookingType; AstTreeVariables dependencies; AstTreeVariables variables; + AstTreeRoot *root; } AstTreeSetTypesHelper; typedef struct AstTreeStruct { @@ -269,6 +276,10 @@ typedef struct AstTreeBracket { AstTrees parameters; } AstTreeBracket; +typedef struct AstTreeNamespace { + size_t importedIndex; +} AstTreeNamespace; + #ifdef PRINT_COMPILE_TREE void astTreePrint(const AstTree *tree, int indent); void astTreeVariablePrint(const AstTreeVariable *variable, int indent); diff --git a/src/compiler/lexer.c b/src/compiler/lexer.c index 79eeff0..edf5805 100644 --- a/src/compiler/lexer.c +++ b/src/compiler/lexer.c @@ -50,6 +50,7 @@ const char *LEXER_TOKEN_STRINGS[] = { "LEXER_TOKEN_KEYWORD_FALSE", "LEXER_TOKEN_KEYWORD_NULL", "LEXER_TOKEN_KEYWORD_CODE", + "LEXER_TOKEN_KEYWORD_NAMESPACE", "LEXER_TOKEN_NUMBER", "LEXER_TOKEN_CHAR", "LEXER_TOKEN_STRING", @@ -167,7 +168,7 @@ static const char *LEXER_KEYWORD_STRINGS[] = { #endif "f32", "f64", "f128", "bool", "putc", "return", "true", "false", "if", "else", "while", "comptime", - "null", "struct", "undefined", "code", "lazy", + "null", "struct", "undefined", "code", "lazy", "namespace", }; static const LexerToken LEXER_KEYWORD_TOKENS[] = { LEXER_TOKEN_KEYWORD_TYPE, LEXER_TOKEN_KEYWORD_VOID, @@ -186,7 +187,7 @@ static const LexerToken LEXER_KEYWORD_TOKENS[] = { LEXER_TOKEN_KEYWORD_WHILE, LEXER_TOKEN_KEYWORD_COMPTIME, LEXER_TOKEN_KEYWORD_NULL, LEXER_TOKEN_KEYWORD_STRUCT, LEXER_TOKEN_KEYWORD_UNDEFINED, LEXER_TOKEN_KEYWORD_CODE, - LEXER_TOKEN_KEYWORD_LAZY, + LEXER_TOKEN_KEYWORD_LAZY, LEXER_TOKEN_KEYWORD_NAMESPACE, }; static const size_t LEXER_KEYWORD_SIZE = sizeof(LEXER_KEYWORD_TOKENS) / sizeof(*LEXER_KEYWORD_TOKENS); @@ -440,6 +441,7 @@ lexerPushClear(LexerNodeArray *array, size_t *array_size, char const *iter, case LEXER_TOKEN_KEYWORD_STRUCT: case LEXER_TOKEN_KEYWORD_UNDEFINED: case LEXER_TOKEN_KEYWORD_CODE: + case LEXER_TOKEN_KEYWORD_NAMESPACE: case LEXER_TOKEN_KEYWORD_LAZY: case LEXER_TOKEN_NUMBER: case LEXER_TOKEN_CHAR: diff --git a/src/compiler/lexer.h b/src/compiler/lexer.h index 9d86462..844906e 100644 --- a/src/compiler/lexer.h +++ b/src/compiler/lexer.h @@ -53,6 +53,7 @@ typedef enum LexerToken { LEXER_TOKEN_KEYWORD_FALSE, LEXER_TOKEN_KEYWORD_NULL, LEXER_TOKEN_KEYWORD_CODE, + LEXER_TOKEN_KEYWORD_NAMESPACE, LEXER_TOKEN_NUMBER, LEXER_TOKEN_CHAR, LEXER_TOKEN_STRING, diff --git a/src/compiler/parser.c b/src/compiler/parser.c index 4776b29..7bb0f1d 100644 --- a/src/compiler/parser.c +++ b/src/compiler/parser.c @@ -56,6 +56,7 @@ const char *PARSER_TOKEN_STRINGS[] = { "PARSER_TOKEN_TYPE_F64", "PARSER_TOKEN_TYPE_F128", "PARSER_TOKEN_TYPE_CODE", + "PARSER_TOKEN_TYPE_NAMESPACE", "PARSER_TOKEN_KEYWORD_PUTC", "PARSER_TOKEN_KEYWORD_RETURN", @@ -274,6 +275,7 @@ void parserNodePrint(const ParserNode *node, int indent) { case PARSER_TOKEN_TYPE_F64: case PARSER_TOKEN_TYPE_F128: case PARSER_TOKEN_TYPE_CODE: + case PARSER_TOKEN_TYPE_NAMESPACE: case PARSER_TOKEN_KEYWORD_NULL: case PARSER_TOKEN_KEYWORD_UNDEFINED: goto RETURN_SUCCESS; @@ -575,6 +577,7 @@ void parserNodeDelete(ParserNode *node) { case PARSER_TOKEN_TYPE_F64: case PARSER_TOKEN_TYPE_F128: case PARSER_TOKEN_TYPE_CODE: + case PARSER_TOKEN_TYPE_NAMESPACE: case PARSER_TOKEN_KEYWORD_NULL: case PARSER_TOKEN_KEYWORD_UNDEFINED: goto RETURN_SUCCESS; @@ -911,6 +914,8 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_F128); case LEXER_TOKEN_KEYWORD_CODE: return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_CODE); + case LEXER_TOKEN_KEYWORD_NAMESPACE: + return parserNoMetadata(node, parent, PARSER_TOKEN_TYPE_NAMESPACE); case LEXER_TOKEN_KEYWORD_NULL: return parserNoMetadata(node, parent, PARSER_TOKEN_KEYWORD_NULL); case LEXER_TOKEN_KEYWORD_UNDEFINED: @@ -1050,6 +1055,7 @@ ParserNode *parseNode(LexerNode *node, LexerNode *begin, LexerNode *end, return parserComptime(node, end, parent); case LEXER_TOKEN_KEYWORD_STRUCT: return parserStruct(node, end, parent); + case LEXER_TOKEN_KEYWORD_LAZY: case LEXER_TOKEN_KEYWORD_ELSE: case LEXER_TOKEN_BUILTIN: case LEXER_TOKEN_SYMBOL: @@ -1699,6 +1705,7 @@ ParserNode *parserFunction(LexerNode *node, LexerNode *begin, LexerNode *end, case PARSER_TOKEN_TYPE_F64: case PARSER_TOKEN_TYPE_F128: case PARSER_TOKEN_TYPE_CODE: + case PARSER_TOKEN_TYPE_NAMESPACE: case PARSER_TOKEN_KEYWORD_NULL: case PARSER_TOKEN_KEYWORD_UNDEFINED: case PARSER_TOKEN_KEYWORD_PUTC: @@ -2224,6 +2231,7 @@ bool isExpression(ParserNode *node) { case PARSER_TOKEN_TYPE_F64: case PARSER_TOKEN_TYPE_F128: case PARSER_TOKEN_TYPE_CODE: + case PARSER_TOKEN_TYPE_NAMESPACE: case PARSER_TOKEN_KEYWORD_NULL: case PARSER_TOKEN_KEYWORD_UNDEFINED: case PARSER_TOKEN_KEYWORD_STRUCT: @@ -2258,6 +2266,7 @@ bool isType(ParserNode *node) { case PARSER_TOKEN_TYPE_F64: case PARSER_TOKEN_TYPE_F128: case PARSER_TOKEN_TYPE_CODE: + case PARSER_TOKEN_TYPE_NAMESPACE: case PARSER_TOKEN_TYPE_BOOL: case PARSER_TOKEN_IDENTIFIER: case PARSER_TOKEN_SYMBOL_PARENTHESIS: @@ -2408,6 +2417,7 @@ bool isValue(ParserNode *node) { case PARSER_TOKEN_TYPE_F64: case PARSER_TOKEN_TYPE_F128: case PARSER_TOKEN_TYPE_CODE: + case PARSER_TOKEN_TYPE_NAMESPACE: case PARSER_TOKEN_KEYWORD_NULL: case PARSER_TOKEN_KEYWORD_UNDEFINED: case PARSER_TOKEN_KEYWORD_IF: diff --git a/src/compiler/parser.h b/src/compiler/parser.h index ef6330e..05409fb 100644 --- a/src/compiler/parser.h +++ b/src/compiler/parser.h @@ -53,6 +53,7 @@ typedef enum ParserToken { PARSER_TOKEN_TYPE_F64, PARSER_TOKEN_TYPE_F128, PARSER_TOKEN_TYPE_CODE, + PARSER_TOKEN_TYPE_NAMESPACE, PARSER_TOKEN_KEYWORD_PUTC, PARSER_TOKEN_KEYWORD_RETURN, diff --git a/src/runner/runner.c b/src/runner/runner.c index 6199244..7b09b9b 100644 --- a/src/runner/runner.c +++ b/src/runner/runner.c @@ -1315,9 +1315,11 @@ AstTree *runExpression(AstTree *expr, AstTreeScope *scope, bool *shouldRet, 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_VALUE_NULL: case AST_TREE_TOKEN_VALUE_UNDEFINED: case AST_TREE_TOKEN_VALUE_VOID: + case AST_TREE_TOKEN_VALUE_NAMESPACE: case AST_TREE_TOKEN_VALUE_INT: case AST_TREE_TOKEN_VALUE_BOOL: case AST_TREE_TOKEN_VALUE_FLOAT: -- cgit v1.2.3