1 
2 //          Copyright Tim Schendekehl 2023.
3 // Distributed under the Boost Software License, Version 1.0.
4 //    (See accompanying file LICENSE_1_0.txt or copy at
5 //          https://www.boost.org/LICENSE_1_0.txt)
6 
7 module dparsergen.core.parsestackelem;
8 
9 /**
10 Value for nonterminal or token with start location stored on parse stack.
11 */
12 struct ParseStackElem(Location, T)
13 {
14     alias LocationDiff = typeof(Location.init - Location.init);
15 
16     /**
17     Start location.
18     */
19     Location start;
20 
21     /**
22     Value for nonterminal or token.
23     */
24     T val;
25 
26     /**
27     Constructor.
28     */
29     this(Location start, T val)
30     {
31         this.start = start;
32         this.val = val;
33     }
34 
35     /**
36     Length of the value.
37     */
38     LocationDiff inputLength()() const
39     {
40         static if (is(typeof(val.inputLength)))
41         {
42             static if (__traits(compiles, tree is null))
43                 if (val is null)
44                     return LocationDiff();
45             return val.inputLength;
46         }
47         else static if (is(T == string))
48         {
49             return LocationDiff.fromStr(val);
50         }
51         else static if (is(T == X[], X))
52         {
53             assert(false);
54         }
55         else static if (is(T == typeof(null)))
56             return LocationDiff();
57         else
58             static assert(0, T.stringof);
59     }
60 
61     /**
62     End location for the location.
63     */
64     Location end()() const
65     {
66         static if (is(typeof(val.end)))
67         {
68             static if (__traits(compiles, tree is null))
69                 if (val is null)
70                     return Location.invalid;
71             return val.end;
72         }
73         else
74             return start + inputLength;
75     }
76 }