1 /// Copyright: Copyright (c) 2022 Andrey Penechko. 2 /// License: $(WEB boost.org/LICENSE_1_0.txt, Boost License 1.0). 3 /// Authors: Andrey Penechko. 4 module vox.fe.ast.expr.named_argument; 5 6 import vox.all; 7 8 enum NamedArgumentFlags : ushort 9 { 10 isSymResolved = AstFlags.userFlag << 0, 11 } 12 13 @(AstType.expr_named_argument) 14 struct NamedArgumenExprNode { 15 mixin AstNodeData!(AstType.expr_named_argument, 0, AstNodeState.name_register_self_done); 16 union 17 { 18 private Identifier _id; // used when not yet resolved 19 private ushort _paramIndex; // used when resolved 20 } 21 AstIndex expr; 22 23 bool isSymResolved() { return cast(bool)(flags & NamedArgumentFlags.isSymResolved); } 24 25 this(TokenIndex loc, Identifier id, AstIndex expr) 26 { 27 this.loc = loc; 28 this.astType = AstType.expr_named_argument; 29 this.state = AstNodeState.name_register_self_done; 30 this._id = id; 31 this.expr = expr; 32 } 33 34 Identifier getId(CompilationContext* c) { 35 c.assertf(!isSymResolved, loc, "Getting id of resolved NamedArgumenExprNode"); 36 return _id; 37 } 38 39 ushort getParamIndex(CompilationContext* c) { 40 c.assertf(isSymResolved, loc, "Getting paramIndex of unresolved NamedArgumenExprNode"); 41 return _paramIndex; 42 } 43 44 void resolve(ushort paramIndex, CompilationContext* c) { 45 c.assertf(!isSymResolved, loc, "Already resolved"); 46 this._paramIndex = paramIndex; 47 this.flags |= NamedArgumentFlags.isSymResolved; 48 } 49 } 50 51 void print_named_argument(NamedArgumenExprNode* node, ref AstPrintState state) 52 { 53 if (node.isSymResolved) 54 state.print(node.getParamIndex(state.context), ": "); 55 else 56 state.print(state.context.idString(node._id), ": "); 57 print_ast(node.expr, state); 58 } 59 60 void post_clone_named_argument(NamedArgumenExprNode* node, ref CloneState state) 61 { 62 state.fixAstIndex(node.expr); 63 } 64 65 void name_register_nested_named_argument(NamedArgumenExprNode* node, ref NameRegisterState state) { 66 node.state = AstNodeState.name_register_nested; 67 require_name_register(node.expr, state); 68 node.state = AstNodeState.name_register_nested_done; 69 } 70 71 void name_resolve_named_argument(NamedArgumenExprNode* node, ref NameResolveState state) { 72 node.state = AstNodeState.name_resolve; 73 require_name_resolve(node.expr, state); 74 node.state = AstNodeState.name_resolve_done; 75 } 76 77 void type_check_named_argument(NamedArgumenExprNode* node, ref TypeCheckState state) { 78 node.state = AstNodeState.type_check; 79 require_type_check(node.expr, state); 80 node.state = AstNodeState.type_check_done; 81 }