diff --git a/ast.cpp b/ast.cpp index d4a2972..a99954b 100644 --- a/ast.cpp +++ b/ast.cpp @@ -60,7 +60,7 @@ struct Ast{ }; struct Ast_Resolved_Type; -struct Ast_Expr:Ast{}; +struct Ast_Expr:Ast{ }; #define VALUE_FIELDS \ Ast_Resolved_Type *type; \ diff --git a/compiler.h b/compiler.h index bebf8f6..5fbc729 100644 --- a/compiler.h +++ b/compiler.h @@ -178,7 +178,6 @@ struct Parse_Ctx:Lexer{ Array packages; Ast_Scope *currently_parsed_scope; - Ast_Package *resolving_package; Array ordered_decls; S64 indent; diff --git a/lambdas.kl b/lambdas.kl index e480319..ef43d8e 100644 --- a/lambdas.kl +++ b/lambdas.kl @@ -1,5 +1,11 @@ package lambdas +Test :: struct + len: S64 + +test: Test +member := test.len + a_type :: S64 pointer_type :: *S64 // null_pointer: pointer_type = null diff --git a/main.obj b/main.obj deleted file mode 100644 index c654b32..0000000 Binary files a/main.obj and /dev/null differ diff --git a/order1.kl b/order1.kl index a8f2c5e..e173965 100644 --- a/order1.kl +++ b/order1.kl @@ -17,4 +17,5 @@ CONSTANT_VAL :: 10 global_thing: a_type = 10 -// arena: order2.Arena +arena: *order2.Arena +order1_arena: order2.Arena diff --git a/order2.kl b/order2.kl index 110c159..455091f 100644 --- a/order2.kl +++ b/order2.kl @@ -17,6 +17,7 @@ String16 :: struct len : S64 with_type: Arena = order2_arena +test_dot := with_type.len pointer := &with_type deref := *pointer diff --git a/parsing.cpp b/parsing.cpp index bfe70eb..943302e 100644 --- a/parsing.cpp +++ b/parsing.cpp @@ -594,7 +594,7 @@ parse_decl(B32 is_global){ } } else if(token_match(TK_Identifier, TK_Colon)){ - Ast_Expr *typespec = typespec = parse_expr(); + Ast_Expr *typespec = parse_expr(); Ast_Expr *expr = parse_assign_expr(); result = ast_var(tname, typespec, tname->intern_val, expr); } diff --git a/typechecking.cpp b/typechecking.cpp index d9b8cb3..5595a23 100644 --- a/typechecking.cpp +++ b/typechecking.cpp @@ -420,10 +420,15 @@ _search_for_decl(Ast_Scope *scope, Intern_String name){ return 0; } -FLAG32(Search_Flag) { - SEARCH_ONLY_CURRENT_SCOPE = bit_flag(1), - SEARCH_ALSO_FOR_PACKAGE = bit_flag(2), -}; +function Ast_Package * +search_for_package(Intern_String name){ + For(pctx->packages){ + if(name == it->name){ + return it; + } + } + return 0; +} function Ast_Decl * search_for_decl(Ast_Scope *scope, Intern_String name, Search_Flag flags = 0){ @@ -434,12 +439,7 @@ search_for_decl(Ast_Scope *scope, Intern_String name, Search_Flag flags = 0){ if(is_flag_set(flags, SEARCH_ONLY_CURRENT_SCOPE)) break; } if(!result && is_flag_set(flags, SEARCH_ALSO_FOR_PACKAGE)){ - For(pctx->packages){ - if(name == it->name){ - result = (Ast_Decl *)it; - break; - } - } + result = (Ast_Decl *)search_for_package(name); } return result; @@ -638,6 +638,50 @@ resolve_cast(Ast_Cast *node){ return expr; } +global Ast_Scope *field_access_scope; // @memes + +function Operand +resolve_field_access(Ast_Expr *node, Ast_Scope *context){ + Ast_Binary *current = 0; + Ast_Expr *next = 0; + if(node->kind == AST_BINARY){ + current = (Ast_Binary *)node; + next = current->right; + node = current->left; + } + + Ast_Scope *new_context = 0; + if(!context && node->kind == AST_IDENT){ + auto ident = (Ast_Atom *)node; + Ast_Package *package = search_for_package(ident->intern_val); + if(package) { + new_context = package; + } + } + + if(!new_context){ + field_access_scope = context; + Operand op = resolve_expr(node, AST_CANT_BE_NULL); + field_access_scope = 0; + + if(current) current->type = op.type; + if(is_pointer(op.type)) op.type = op.type->base; + type_complete(op.type); + + if(next && !is_struct(op.type)){ + compiler_error(node->pos, "Dot access"); + } + + if(!next) + return op; + + new_context = ((Ast_Decl *)op.type->ast)->scope; + } + + assert(next); + return resolve_field_access(next, new_context); +} + function Operand resolve_expr(Ast_Expr *ast, Resolve_Flag flags){ if(!ast && is_flag_set(flags, AST_CAN_BE_NULL)) return {}; @@ -646,6 +690,28 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags){ switch(ast->kind){ + CASE(IDENT, Atom){ + Ast_Scope *scope = node->parent_scope; + Search_Flag flags = 0; + if(field_access_scope){ + set_flag(flags, SEARCH_ONLY_CURRENT_SCOPE); + scope = field_access_scope; + } + Ast_Decl *decl = resolve_name(scope, node->pos, node->intern_val, flags); + + node->resolved_decl = decl; + Operand result = operand(decl); + if(decl->kind != AST_VAR){ + if(decl->kind == AST_CONST){ + rewrite_into_const(node, Ast_Atom, decl->value); + } + result.is_const = 1; + } + + return result; + BREAK(); + } + CASE(VALUE, Atom){ return operand_const_rvalue(node->value); BREAK(); @@ -677,28 +743,6 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags){ BREAK(); } - CASE(IDENT, Atom){ - Ast_Decl *decl = resolve_name(node->parent_scope, node->pos, node->intern_val); - - node->resolved_decl = decl; - Operand result = operand(decl); - if(decl->kind != AST_VAR){ - // @note - // There might be some problem with types getting rewritten - // I would like decls to be resolved to be of AST_TYPE ?? - // - // assert(decl->value.type != type_type); - // assert(!is_lambda(decl->value.type)); - if(decl->kind == AST_CONST){ - rewrite_into_const(node, Ast_Atom, decl->value); - } - result.is_const = 1; - } - - return result; - BREAK(); - } - CASE(BINARY, Binary){ if(token_is_assign(node->op)){ assert(is_flag_set(node->flags, AST_STMT)); @@ -708,8 +752,12 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags){ right.value = convert_untyped_to_typed(node->pos, right.value, left.type); if(left.type != right.type) compiler_error(node->pos, "Can't assign value when left is %s and right is %s", docname(left.type), docname(right.type)); + node->type = right.type; return {}; } + else if(node->op == TK_Dot){ + return resolve_field_access(node, 0); + } else{ Operand left = resolve_expr(node->left, AST_CANT_BE_NULL); Operand right = resolve_expr(node->right, AST_CANT_BE_NULL); @@ -837,9 +885,8 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags){ function void resolve_decl(Ast_Decl *ast){ - if(ast->state == DECL_RESOLVED){ - return; - } + if(ast->kind == AST_PACKAGE) return; + else if(ast->state == DECL_RESOLVED) return; else if(ast->state == DECL_RESOLVING){ compiler_error(ast->pos, "Cyclic dependency of %s", ast->name.str); return; @@ -947,8 +994,8 @@ resolve_decl(Ast_Decl *ast){ } function Ast_Decl * -resolve_name(Ast_Scope *scope, Token *pos, Intern_String name){ - Ast_Decl *decl = search_for_decl(scope, name); +resolve_name(Ast_Scope *scope, Token *pos, Intern_String name, Search_Flag search_flags){ + Ast_Decl *decl = search_for_decl(scope, name, search_flags); if(!decl) compiler_error(pos, "Unidentified name [%s]", name.str); resolve_decl(decl); return decl; diff --git a/typechecking.h b/typechecking.h index 800e793..d1b6e9f 100644 --- a/typechecking.h +++ b/typechecking.h @@ -11,9 +11,14 @@ FLAG32(Resolve_Flag){ RESOLVE_TYPESPEC_COMPLETE = bit_flag(2), }; +FLAG32(Search_Flag){ + SEARCH_ONLY_CURRENT_SCOPE = bit_flag(1), + SEARCH_ALSO_FOR_PACKAGE = bit_flag(2), +}; + function Operand resolve_expr(Ast_Expr *ast, Resolve_Flag flags); function void resolve_decl(Ast_Decl *ast); -function Ast_Decl *resolve_name(Ast_Scope *parent_scope, Token *pos, Intern_String name); +function Ast_Decl *resolve_name(Ast_Scope *parent_scope, Token *pos, Intern_String name, Search_Flag search_flags = 0); function Ast_Resolved_Type *resolve_typespec(Ast_Expr *ast, Resolve_Flag flags); //-----------------------------------------------------------------------------