Line data Source code
1 : //! The semantic values on the parser stack.
2 : //!
3 : //! Every value is `Copy`: node lists and n-ary expressions live in arenas of the parse context and are referenced by id.
4 :
5 : use crate::names::NameId;
6 : use dashql_buffers::parser::{AttributeKey, JoinType, Node, NumericType};
7 :
8 : /// The text of a keyword token
9 : pub type Str = &'static str;
10 :
11 : /// A temporary list of nodes in the parse context
12 : #[derive(Clone, Copy, Debug, PartialEq, Eq)]
13 : pub struct NodeList(pub(crate) u32);
14 :
15 : /// An expression that is either a materialized node or an n-ary expression that may still be
16 : /// flattened into an enclosing AND / OR
17 : #[derive(Clone, Copy, Debug, PartialEq)]
18 : pub enum ExprVariant {
19 : Node(Node),
20 : Nary(u32),
21 : }
22 :
23 : impl From<Node> for ExprVariant {
24 1215 : fn from(node: Node) -> Self {
25 1215 : ExprVariant::Node(node)
26 1215 : }
27 : }
28 :
29 : /// A value on the parser stack
30 : #[derive(Clone, Copy, Debug, Default, PartialEq)]
31 : pub enum Value {
32 : /// The value of untyped symbols, and of typed symbols whose action does not set one
33 : #[default]
34 : Empty,
35 : Node(Node),
36 : List(NodeList),
37 : Key(AttributeKey),
38 : Expr(ExprVariant),
39 : Bool(bool),
40 : Join(JoinType),
41 : Numeric(NumericType),
42 : Str(Str),
43 : Name(NameId),
44 : }
45 :
46 : macro_rules! value_from {
47 : ($t:ty, $variant:ident) => {
48 : impl From<$t> for Value {
49 902733 : fn from(v: $t) -> Self {
50 902733 : Value::$variant(v)
51 902733 : }
52 : }
53 : };
54 : }
55 :
56 : value_from!(Node, Node);
57 : value_from!(NodeList, List);
58 : value_from!(AttributeKey, Key);
59 : value_from!(ExprVariant, Expr);
60 : value_from!(bool, Bool);
61 : value_from!(JoinType, Join);
62 : value_from!(NumericType, Numeric);
63 : value_from!(Str, Str);
64 : value_from!(NameId, Name);
65 :
66 : impl From<()> for Value {
67 13489 : fn from(_: ()) -> Self {
68 13489 : Value::Empty
69 13489 : }
70 : }
71 :
72 : /// Read a typed value from the stack.
73 : ///
74 : /// An [`ExprVariant`] accepts a node, and a symbol whose action did not set a value holds a
75 : /// default-constructed one.
76 : pub trait FromValue: Sized {
77 : fn from_value(v: Value) -> Self;
78 : }
79 :
80 : #[cold]
81 0 : fn type_mismatch(expected: &str, v: Value) -> ! {
82 0 : panic!("parser value type mismatch: expected {expected}, found {v:?}")
83 : }
84 :
85 : impl FromValue for Value {
86 0 : fn from_value(v: Value) -> Self {
87 0 : v
88 0 : }
89 : }
90 :
91 : impl FromValue for Node {
92 443962 : fn from_value(v: Value) -> Self {
93 443962 : match v {
94 443962 : Value::Node(n) => n,
95 0 : Value::Empty => Node::default(),
96 0 : v => type_mismatch("Node", v),
97 : }
98 443962 : }
99 : }
100 :
101 : impl FromValue for ExprVariant {
102 241703 : fn from_value(v: Value) -> Self {
103 241703 : match v {
104 152795 : Value::Expr(e) => e,
105 88908 : Value::Node(n) => ExprVariant::Node(n),
106 0 : Value::Empty => ExprVariant::Node(Node::default()),
107 0 : v => type_mismatch("ExprVariant", v),
108 : }
109 241703 : }
110 : }
111 :
112 : macro_rules! from_value {
113 : ($t:ty, $variant:ident) => {
114 : impl FromValue for $t {
115 103344 : fn from_value(v: Value) -> Self {
116 103344 : match v {
117 103344 : Value::$variant(x) => x,
118 0 : Value::Empty => <$t>::default(),
119 0 : v => type_mismatch(stringify!($t), v),
120 : }
121 103344 : }
122 : }
123 : };
124 : }
125 :
126 : from_value!(AttributeKey, Key);
127 : from_value!(bool, Bool);
128 : from_value!(JoinType, Join);
129 : from_value!(NumericType, Numeric);
130 : from_value!(Str, Str);
131 : from_value!(NameId, Name);
132 :
133 : impl FromValue for NodeList {
134 261018 : fn from_value(v: Value) -> Self {
135 261018 : match v {
136 261018 : Value::List(l) => l,
137 0 : v => type_mismatch("NodeList", v),
138 : }
139 261018 : }
140 : }
|