1use ahash::{HashMap, HashMapExt};
6use ibig::IBig;
7use ordered_float::OrderedFloat;
8use rust_decimal::Decimal;
9
10pub use xee_interpreter::function::Name;
11use xee_interpreter::function::{CastType, Signature, StaticFunctionId};
12use xee_interpreter::xml;
13use xee_schema_type::Xs;
14pub use xee_xpath_ast::ast::{BinaryOperator, SequenceType, UnaryOperator};
15use xee_xpath_ast::span::Spanned;
16use xee_xpath_ast::Pattern;
17use xot::xmlname;
18
19pub type AtomS = Spanned<Atom>;
20pub type ExprS = Spanned<Expr>;
21
22#[derive(Debug, Clone, PartialEq, Eq)]
23pub enum Expr {
24 Atom(AtomS),
25 Let(Let),
26 If(If),
27 Binary(Binary),
28 Unary(Unary),
29 FunctionDefinition(FunctionDefinition),
30 FunctionCall(FunctionCall),
31 Lookup(Lookup),
32 WildcardLookup(WildcardLookup),
33 Step(Step),
34 Deduplicate(Box<ExprS>),
35 Map(Map),
36 Filter(Filter),
37 PatternPredicate(PatternPredicate),
38 Quantified(Quantified),
39 Cast(Cast),
40 Castable(Castable),
41 InstanceOf(InstanceOf),
42 Treat(Treat),
43 MapConstructor(MapConstructor),
44 ArrayConstructor(ArrayConstructor),
45 XmlName(XmlName),
46 XmlDocument(XmlRoot),
47 XmlElement(XmlElement),
48 XmlAttribute(XmlAttribute),
49 XmlNamespace(XmlNamespace),
50 XmlText(XmlText),
51 XmlComment(XmlComment),
52 XmlProcessingInstruction(XmlProcessingInstruction),
53 XmlAppend(XmlAppend),
54 ApplyTemplates(ApplyTemplates),
55 CopyShallow(CopyShallow),
56 CopyDeep(CopyDeep),
57}
58
59#[derive(Debug, Clone, PartialEq, Eq)]
61pub enum Atom {
62 Const(Const),
63 Variable(Name),
64}
65
66#[derive(Debug, Clone, PartialEq, Eq)]
67pub enum Const {
68 Integer(IBig),
69 String(String),
70 Double(OrderedFloat<f64>),
71 Decimal(Decimal),
72 StaticFunctionReference(StaticFunctionId, Option<ContextNames>),
73 EmptySequence,
75}
76
77#[derive(Debug, Clone, PartialEq, Eq)]
78pub struct ContextNames {
79 pub item: Name,
80 pub position: Name,
81 pub last: Name,
82}
83
84#[derive(Debug, Clone, PartialEq, Eq)]
85pub struct Let {
86 pub name: Name,
87 pub var_expr: Box<ExprS>,
88 pub return_expr: Box<ExprS>,
89}
90
91#[derive(Debug, Clone, PartialEq, Eq)]
92pub struct If {
93 pub condition: AtomS,
94 pub then: Box<ExprS>,
95 pub else_: Box<ExprS>,
96}
97
98#[derive(Debug, Clone, PartialEq, Eq)]
99pub struct Binary {
100 pub left: AtomS,
101 pub op: BinaryOperator,
102 pub right: AtomS,
103}
104
105#[derive(Debug, Clone, PartialEq, Eq)]
106pub struct Unary {
107 pub op: UnaryOperator,
108 pub atom: AtomS,
109}
110
111#[derive(Debug, Clone, PartialEq, Eq)]
112pub struct FunctionDefinition {
113 pub params: Vec<Param>,
114 pub return_type: Option<SequenceType>,
115 pub body: Box<ExprS>,
116}
117
118impl FunctionDefinition {
119 pub fn signature(&self) -> Signature {
120 Signature::new(
121 self.params
122 .iter()
123 .map(|param| param.type_.clone())
124 .collect(),
125 self.return_type.clone(),
126 )
127 }
128}
129
130#[derive(Debug, Clone, PartialEq, Eq)]
131pub struct Param {
132 pub name: Name,
133 pub type_: Option<SequenceType>,
134}
135
136#[derive(Debug, Clone, PartialEq, Eq)]
137pub struct FunctionCall {
138 pub atom: AtomS,
139 pub args: Vec<AtomS>,
140}
141
142#[derive(Debug, Clone, PartialEq, Eq)]
143pub struct Lookup {
144 pub atom: AtomS,
145 pub arg_atom: AtomS,
146}
147
148#[derive(Debug, Clone, PartialEq, Eq)]
149pub struct WildcardLookup {
150 pub atom: AtomS,
151}
152
153#[derive(Debug, Clone, PartialEq, Eq)]
154pub struct Step {
155 pub step: xml::Step,
156 pub context: AtomS,
157}
158
159#[derive(Debug, Clone, PartialEq, Eq)]
160pub struct Map {
161 pub context_names: ContextNames,
162 pub var_atom: AtomS,
163 pub return_expr: Box<ExprS>,
164}
165
166#[derive(Debug, Clone, PartialEq, Eq)]
167pub struct Filter {
168 pub context_names: ContextNames,
169 pub var_atom: AtomS,
170 pub return_expr: Box<ExprS>,
171}
172
173#[derive(Debug, Clone, PartialEq, Eq)]
174pub struct PatternPredicate {
175 pub context_names: ContextNames,
176 pub var_atom: AtomS,
177 pub expr: Box<ExprS>,
178}
179
180#[derive(Debug, Clone, PartialEq, Eq)]
181pub struct Quantified {
182 pub quantifier: Quantifier,
183 pub context_names: ContextNames,
184 pub var_atom: AtomS,
185 pub satisifies_expr: Box<ExprS>,
186}
187
188#[derive(Debug, Clone, PartialEq, Eq)]
189pub enum Quantifier {
190 Some,
191 Every,
192}
193
194#[derive(Debug, Clone, PartialEq, Eq)]
195pub struct Cast {
196 pub atom: AtomS,
197 pub xs: Xs,
198 pub empty_sequence_allowed: bool,
199}
200
201impl Cast {
202 pub fn cast_type(&self) -> CastType {
203 CastType {
204 xs: self.xs,
205 empty_sequence_allowed: self.empty_sequence_allowed,
206 }
207 }
208}
209
210#[derive(Debug, Clone, PartialEq, Eq)]
211pub struct Castable {
212 pub atom: AtomS,
213 pub xs: Xs,
214 pub empty_sequence_allowed: bool,
215}
216
217impl Castable {
218 pub fn cast_type(&self) -> CastType {
219 CastType {
220 xs: self.xs,
221 empty_sequence_allowed: self.empty_sequence_allowed,
222 }
223 }
224}
225
226#[derive(Debug, Clone, PartialEq, Eq)]
227pub struct InstanceOf {
228 pub atom: AtomS,
229 pub sequence_type: SequenceType,
230}
231
232#[derive(Debug, Clone, PartialEq, Eq)]
233pub struct Treat {
234 pub atom: AtomS,
235 pub sequence_type: SequenceType,
236}
237
238#[derive(Debug, Clone, PartialEq, Eq)]
239pub struct MapConstructor {
240 pub members: Vec<(AtomS, AtomS)>,
241}
242
243#[derive(Debug, Clone, PartialEq, Eq)]
244pub enum ArrayConstructor {
245 Square(Vec<AtomS>),
246 Curly(AtomS),
247}
248
249#[derive(Debug, Clone, PartialEq, Eq)]
252pub struct XmlName {
253 pub local_name: AtomS,
254 pub namespace: AtomS,
255}
256
257#[derive(Debug, Clone, PartialEq, Eq)]
258pub struct XmlRoot {}
259
260#[derive(Debug, Clone, PartialEq, Eq)]
261pub struct XmlElement {
262 pub name: AtomS,
263}
264
265#[derive(Debug, Clone, PartialEq, Eq)]
266pub struct XmlAttribute {
267 pub name: AtomS,
268 pub value: AtomS,
269}
270
271#[derive(Debug, Clone, PartialEq, Eq)]
272pub struct XmlNamespace {
273 pub prefix: AtomS,
274 pub namespace: AtomS,
275}
276
277#[derive(Debug, Clone, PartialEq, Eq)]
278pub struct XmlText {
279 pub value: AtomS,
280}
281
282#[derive(Debug, Clone, PartialEq, Eq)]
283pub struct XmlComment {
284 pub value: AtomS,
285}
286
287#[derive(Debug, Clone, PartialEq, Eq)]
288pub struct XmlProcessingInstruction {
289 pub target: AtomS,
290 pub content: AtomS,
291}
292
293#[derive(Debug, Clone, PartialEq, Eq)]
294pub struct XmlAppend {
295 pub parent: AtomS,
296 pub child: AtomS,
297}
298
299#[derive(Debug, Clone, PartialEq, Eq)]
300pub struct ApplyTemplates {
301 pub mode: ApplyTemplatesModeValue,
302 pub select: AtomS,
303}
304
305#[derive(Debug, Clone, PartialEq, Eq, Hash)]
306pub enum ApplyTemplatesModeValue {
307 Named(xmlname::OwnedName),
308 Unnamed,
309 Current,
310}
311
312#[derive(Debug, Clone, PartialEq, Eq)]
313pub struct CopyShallow {
314 pub select: AtomS,
315}
316
317#[derive(Debug, Clone, PartialEq, Eq)]
318pub struct CopyDeep {
319 pub select: AtomS,
320}
321
322#[derive(Debug, Clone, PartialEq, Eq)]
323pub struct Rule {
324 pub modes: Vec<ModeValue>,
325 pub priority: Decimal,
326 pub pattern: Pattern<FunctionDefinition>,
327 pub function_definition: FunctionDefinition,
328}
329
330#[derive(Debug, Clone, PartialEq, Eq, Hash)]
331pub enum ModeValue {
332 Named(xmlname::OwnedName),
333 Unnamed,
334 All,
335}
336
337#[derive(Debug, Clone, PartialEq, Eq)]
338pub struct Mode {}
339
340#[derive(Debug, Clone, PartialEq, Eq)]
341pub struct Declarations {
342 pub rules: Vec<Rule>,
343 pub modes: HashMap<Option<xmlname::OwnedName>, Mode>,
344 pub functions: Vec<FunctionBinding>,
345 pub main: FunctionDefinition,
346}
347
348impl Declarations {
349 pub fn new(main: FunctionDefinition) -> Self {
350 Self {
351 rules: Vec::new(),
352 modes: HashMap::new(),
353 functions: Vec::new(),
354 main,
355 }
356 }
357}
358
359#[derive(Debug, Clone, PartialEq, Eq)]
360pub struct FunctionBinding {
361 pub name: Name,
362 pub main: FunctionDefinition,
363}