1use crate::core::adaptive::{BlockState, GrammarState, RuleId};
2use crate::core::cache::Allocs;
3use crate::core::context::ParserContext;
4use crate::core::parser::Parser;
5use crate::core::pos::Pos;
6use crate::core::state::ParserState;
7use crate::error::error_printer::ErrorLabel;
8use crate::error::ParseError;
9use crate::grammar::action_result::ActionResult;
10use crate::grammar::RuleExpr;
11use crate::parser::parser_rule_expr::parser_expr;
12use std::fmt::{Debug, Formatter};
13use std::iter;
14use std::ptr::null;
15
16#[derive(Default, Copy, Clone)]
17pub struct VarMap<'arn, 'grm>(Option<&'arn VarMapNode<'arn, 'grm>>);
18
19impl<'arn, 'grm> Debug for VarMap<'arn, 'grm> {
20 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
21 writeln!(f, "Printing varmap:")?;
22 for (name, value) in self.iter_cloned() {
23 writeln!(f, "- {name}: {value:?}")?;
24 }
25 Ok(())
26 }
27}
28
29#[derive(Copy, Clone)]
30pub struct VarMapNode<'arn, 'grm> {
31 next: Option<&'arn Self>,
32 key: &'arn str,
33 value: VarMapValue<'arn, 'grm>,
34}
35
36pub struct VarMapIterator<'arn, 'grm> {
37 current: Option<&'arn VarMapNode<'arn, 'grm>>,
38}
39
40impl<'arn, 'grm> Iterator for VarMapIterator<'arn, 'grm> {
41 type Item = (&'arn str, VarMapValue<'arn, 'grm>);
42
43 fn next(&mut self) -> Option<Self::Item> {
44 match self.current {
45 None => None,
46 Some(node) => {
47 self.current = node.next;
48 Some((node.key, node.value))
49 }
50 }
51 }
52}
53
54impl<'arn, 'grm> VarMap<'arn, 'grm> {
55 pub fn get<'a>(&'a self, k: &str) -> Option<&'a VarMapValue<'arn, 'grm>> {
56 let mut node = self.0?;
57 loop {
58 if node.key == k {
59 return Some(&node.value);
60 }
61 node = node.next?;
62 }
63 }
64
65 pub fn iter_cloned(&self) -> impl Iterator<Item = (&'arn str, VarMapValue<'arn, 'grm>)> {
66 VarMapIterator { current: self.0 }
67 }
68
69 #[must_use]
70 pub fn insert(
71 self,
72 key: &'arn str,
73 value: VarMapValue<'arn, 'grm>,
74 alloc: Allocs<'arn>,
75 ) -> Self {
76 self.extend(iter::once((key, value)), alloc)
77 }
78
79 #[must_use]
80 pub fn extend<T: IntoIterator<Item = (&'arn str, VarMapValue<'arn, 'grm>)>>(
81 mut self,
82 iter: T,
83 alloc: Allocs<'arn>,
84 ) -> Self {
85 for (key, value) in iter {
86 self.0 = Some(alloc.alloc(VarMapNode {
87 next: self.0,
88 key,
89 value,
90 }))
91 }
92 self
93 }
94
95 pub fn from_iter<T: IntoIterator<Item = (&'arn str, VarMapValue<'arn, 'grm>)>>(
96 iter: T,
97 alloc: Allocs<'arn>,
98 ) -> Self {
99 let s = Self::default();
100 s.extend(iter, alloc)
101 }
102
103 pub fn as_ptr(&self) -> *const VarMapNode {
104 self.0.map(|r| r as *const VarMapNode).unwrap_or(null())
105 }
106}
107
108pub type BlockCtx<'arn, 'grm> = (&'arn [BlockState<'arn, 'grm>], VarMap<'arn, 'grm>);
109
110#[derive(Copy, Clone)]
111pub struct CapturedExpr<'arn, 'grm> {
112 pub expr: &'arn RuleExpr<'arn, 'grm>,
113 pub block_ctx: BlockCtx<'arn, 'grm>,
114 pub vars: VarMap<'arn, 'grm>,
115}
116
117#[derive(Copy, Clone)]
118pub enum VarMapValue<'arn, 'grm> {
119 Expr(CapturedExpr<'arn, 'grm>),
120 Value(&'arn ActionResult<'arn, 'grm>),
121}
122
123impl<'arm, 'grm> Debug for VarMapValue<'arm, 'grm> {
124 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
125 match self {
126 VarMapValue::Expr(_) => write!(f, "{{expr}}"),
127 VarMapValue::Value(ar) => write!(f, "{ar:?}"),
128 }
129 }
130}
131
132impl<'arn, 'grm> VarMapValue<'arn, 'grm> {
133 pub fn new_rule(rule: RuleId, alloc: Allocs<'arn>) -> Self {
134 Self::Value(alloc.alloc(ActionResult::RuleId(rule)))
135 }
136
137 pub fn as_value(&self) -> Option<&ActionResult<'arn, 'grm>> {
138 if let VarMapValue::Value(value) = self {
139 Some(value)
140 } else {
141 None
142 }
143 }
144
145 pub fn run_to_ar<'a, E: ParseError<L = ErrorLabel<'grm>> + 'grm>(
146 &'a self,
147 rules: &'arn GrammarState<'arn, 'grm>,
148 state: &mut ParserState<'arn, 'grm, E>,
149 context: ParserContext,
150 ) -> Option<&'arn ActionResult<'arn, 'grm>> {
151 Some(match self {
152 VarMapValue::Expr(captured_expr) => {
153 parser_expr(
154 rules,
155 captured_expr.block_ctx,
156 captured_expr.expr,
157 captured_expr.vars,
158 )
159 .parse(Pos::invalid(), state, context)
160 .ok()?
161 .rtrn
162 }
163 VarMapValue::Value(v) => v,
164 })
165 }
166
167 pub fn as_rule_id(&self) -> Option<RuleId> {
168 let VarMapValue::Value(ar) = self else {
169 return None;
170 };
171 let ActionResult::RuleId(rule) = ar else {
172 return None;
173 };
174 Some(*rule)
175 }
176}