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 }