diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 110e83ef2..11ccf2dab 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -3437,6 +3437,13 @@ Entity *check_selector(CheckerContext *c, Operand *operand, Ast *node, Type *typ Entity *entity = nullptr; Selection sel = {}; // NOTE(bill): Not used if it's an import name + if (!c->allow_arrow_right_selector_expr && se->token.kind == Token_ArrowRight) { + error(node, "Illegal use of -> selector shorthand outside of a call"); + operand->mode = Addressing_Invalid; + operand->expr = node; + return nullptr; + } + operand->expr = node; Ast *op_expr = se->expr; @@ -9492,8 +9499,13 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type // // NOTE(bill, 2020-05-22): I'm going to regret this decision, ain't I? + bool allow_arrow_right_selector_expr; + allow_arrow_right_selector_expr = c->allow_arrow_right_selector_expr; + c->allow_arrow_right_selector_expr = true; Operand x = {}; ExprKind kind = check_expr_base(c, &x, se->expr, nullptr); + c->allow_arrow_right_selector_expr = allow_arrow_right_selector_expr; + if (x.mode == Addressing_Invalid || x.type == t_invalid) { o->mode = Addressing_Invalid; o->type = t_invalid; @@ -9594,7 +9606,11 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type ce->args = modified_args; se->modified_call = true; + allow_arrow_right_selector_expr = c->allow_arrow_right_selector_expr; + c->allow_arrow_right_selector_expr = true; check_expr_base(c, o, se->call, type_hint); + c->allow_arrow_right_selector_expr = allow_arrow_right_selector_expr; + o->expr = node; return Expr_Expr; case_end; diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index a480e0fdf..4cafa8df5 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -858,8 +858,7 @@ void check_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) { token.pos = ast_token(ss->body).pos; token.string = str_lit("true"); - x.expr = gb_alloc_item(permanent_allocator(), Ast); - x.expr->kind = Ast_Ident; + x.expr = alloc_ast_node(nullptr, Ast_Ident); x.expr->Ident.token = token; } diff --git a/src/checker.hpp b/src/checker.hpp index ed4809748..e6111d2af 100644 --- a/src/checker.hpp +++ b/src/checker.hpp @@ -45,7 +45,7 @@ enum StmtFlag { Stmt_TypeSwitch = 1<<4, - Stmt_CheckScopeDecls = 1<<5, + Stmt_CheckScopeDecls = 1<<5, }; enum BuiltinProcPkg { @@ -316,6 +316,7 @@ struct CheckerContext { bool no_polymorphic_errors; bool hide_polymorphic_errors; bool in_polymorphic_specialization; + bool allow_arrow_right_selector_expr; Scope * polymorphic_scope; Ast *assignment_lhs_hint; diff --git a/src/main.cpp b/src/main.cpp index 97fecb094..67dc5da00 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1876,9 +1876,6 @@ int main(int arg_count, char const **arg_ptr) { SIZE_T virtual_mem_used_by_me = pmc.PrivateUsage; gb_printf_err("virtual_memory_used: %tu B\n", virtual_mem_used_by_me); - gb_printf_err("total_allocated_node_memory: %lld B\n", total_allocated_node_memory.value); - gb_printf_err("total_subtype_node_memory_test: %lld B\n", total_subtype_node_memory_test.value); - gb_printf_err("fraction: %.6f\n", (f64)total_subtype_node_memory_test.value/(f64)total_allocated_node_memory.value); Parser *p = checker.parser; isize lines = p->total_line_count; isize tokens = p->total_token_count; diff --git a/src/parser.cpp b/src/parser.cpp index 5e04aea17..476504d52 100644 --- a/src/parser.cpp +++ b/src/parser.cpp @@ -109,9 +109,6 @@ Token ast_token(Ast *node) { } -gb_global gbAtomic64 total_allocated_node_memory = {0}; -gb_global gbAtomic64 total_subtype_node_memory_test = {0}; - isize ast_node_size(AstKind kind) { return align_formula_isize(gb_size_of(AstCommonStuff) + ast_variant_sizes[kind], gb_align_of(void *)); @@ -122,10 +119,6 @@ Ast *alloc_ast_node(AstFile *f, AstKind kind) { isize size = ast_node_size(kind); - gb_atomic64_fetch_add(&total_allocated_node_memory, cast(i64)(gb_size_of(Ast))); - gb_atomic64_fetch_add(&total_subtype_node_memory_test, cast(i64)(gb_size_of(AstCommonStuff) + ast_variant_sizes[kind])); - - // Ast *node = gb_alloc_item(a, Ast); Ast *node = cast(Ast *)gb_alloc(a, size); node->kind = kind; node->file = f; @@ -2511,7 +2504,15 @@ Ast *parse_call_expr(AstFile *f, Ast *operand) { f->expr_level--; close_paren = expect_closing(f, Token_CloseParen, str_lit("argument list")); - return ast_call_expr(f, operand, args, open_paren, close_paren, ellipsis); + + Ast *call = ast_call_expr(f, operand, args, open_paren, close_paren, ellipsis); + + Ast *o = unparen_expr(operand); + if (o->kind == Ast_SelectorExpr && o->SelectorExpr.token.kind == Token_ArrowRight) { + return ast_selector_call_expr(f, o->SelectorExpr.token, o, call); + } + + return call; } Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) { @@ -2563,11 +2564,10 @@ Ast *parse_atom_expr(AstFile *f, Ast *operand, bool lhs) { case Token_ArrowRight: { Token token = advance_token(f); - // syntax_error(token, "Selector expressions use '.' rather than '->'"); - Ast *sel = ast_selector_expr(f, token, operand, parse_ident(f)); - Ast *call = parse_call_expr(f, sel); - operand = ast_selector_call_expr(f, token, sel, call); + operand = ast_selector_expr(f, token, operand, parse_ident(f)); + // Ast *call = parse_call_expr(f, sel); + // operand = ast_selector_call_expr(f, token, sel, call); break; }