1use ahash::HashSetExt;
2use xee_name::{Name, Namespaces, FN_NAMESPACE};
3
4use xee_interpreter::{context::StaticContext, error, interpreter};
5use xee_ir::{compile_xslt, ir, Bindings, Variables};
6use xee_xpath_ast::{ast as xpath_ast, pattern::transform_pattern, span::Spanned};
7use xee_xslt_ast::{ast, parse_transform};
8use xot::xmlname::NameStrInfo;
9
10use crate::{default_declarations::text_only_copy_declarations, priority::default_priority};
11
12struct IrConverter<'a> {
13 variables: Variables,
14 static_context: &'a StaticContext,
15}
16
17pub fn compile(
18 transform: ast::Transform,
19 static_context: StaticContext,
20) -> error::SpannedResult<interpreter::Program> {
21 let mut ir_converter = IrConverter::new(&static_context);
22 let declarations = ir_converter.transform(&transform)?;
23 compile_xslt(declarations, static_context)
24}
25
26pub fn parse(
27 static_context: StaticContext,
28 xslt: &str,
29) -> error::SpannedResult<interpreter::Program> {
30 let transform = parse_transform(xslt);
31 let mut transform = match transform {
33 Ok(transform) => transform,
34 Err(_e) => {
35 return Err(error::Error::Unsupported.into());
36 }
37 };
38 let mut declarations = text_only_copy_declarations().unwrap();
40 declarations.extend(transform.declarations);
41 transform.declarations = declarations;
42 compile(transform, static_context)
43}
44
45impl<'a> IrConverter<'a> {
46 fn new(static_context: &'a StaticContext) -> Self {
47 IrConverter {
48 variables: Variables::new(),
49 static_context,
50 }
51 }
52
53 fn main_sequence_constructor(&mut self) -> ast::SequenceConstructor {
54 vec![ast::SequenceConstructorItem::Instruction(
55 ast::SequenceConstructorInstruction::ApplyTemplates(Box::new(ast::ApplyTemplates {
56 mode: ast::ApplyTemplatesModeValue::Unnamed,
59 select: ast::Expression {
60 xpath: xee_xpath_ast::ast::XPath::parse(
61 "/",
62 &Namespaces::default(),
63 &xee_name::VariableNames::new(),
64 )
65 .unwrap(),
66 span: xee_xslt_ast::ast::Span::new(0, 0),
67 },
68 content: vec![],
69 span: xee_xslt_ast::ast::Span::new(0, 0),
70 })),
71 )]
72 }
73
74 fn simple_content_atom(&mut self) -> ir::Atom {
75 self.static_function_atom("simple-content", FN_NAMESPACE, 2)
76 }
77
78 fn concat_atom(&mut self, arity: u8) -> ir::Atom {
79 self.static_function_atom("concat", FN_NAMESPACE, arity)
80 }
81
82 fn static_function_atom(&mut self, name: &str, namespace: &str, arity: u8) -> ir::Atom {
87 ir::Atom::Const(ir::Const::StaticFunctionReference(
88 self.static_context
89 .function_id_by_name(
90 &Name::new(name.to_string(), namespace.to_string(), String::new()),
91 arity,
92 )
93 .unwrap(),
94 None,
95 ))
96 }
97
98 fn simple_content_expr(
99 &mut self,
100 select_atom: ir::AtomS,
101 separator_atom: ir::AtomS,
102 ) -> ir::Expr {
103 ir::Expr::FunctionCall(ir::FunctionCall {
104 atom: Spanned::new(self.simple_content_atom(), (0..0).into()),
105 args: vec![select_atom, separator_atom],
106 })
107 }
108
109 fn transform(&mut self, transform: &ast::Transform) -> error::SpannedResult<ir::Declarations> {
110 let main_sequence_constructor = self.main_sequence_constructor();
111 let main = self.sequence_constructor_function(&main_sequence_constructor)?;
112 let mut declarations = ir::Declarations::new(main);
113
114 for declaration in &transform.declarations {
115 self.declaration(&mut declarations, declaration)?;
116 }
117 Ok(declarations)
118 }
119
120 fn declaration(
121 &mut self,
122 declarations: &mut ir::Declarations,
123 declaration: &ast::Declaration,
124 ) -> error::SpannedResult<()> {
125 use ast::Declaration::*;
126 match declaration {
127 Template(template) => self.template(declarations, template),
128 Mode(mode) => self.mode(declarations, mode),
129 _ => Err(error::Error::Unsupported.into()),
130 }
131 }
132
133 fn template(
134 &mut self,
135 declarations: &mut ir::Declarations,
136 template: &ast::Template,
137 ) -> error::SpannedResult<()> {
138 if let Some(pattern) = &template.match_ {
139 let priority = if let Some(priority) = &template.priority {
140 *priority
141 } else {
142 let default_priorities = default_priority(&pattern.pattern).collect::<Vec<_>>();
143 if default_priorities.len() > 1 {
144 return Err(error::Error::Unsupported.into());
146 } else {
147 default_priorities.first().unwrap().1
148 }
149 };
150 let function_definition =
151 self.sequence_constructor_function(&template.sequence_constructor)?;
152
153 let modes = template
154 .mode
155 .iter()
156 .map(Self::ast_mode_value_to_ir_mode_value)
157 .collect();
158
159 declarations.rules.push(ir::Rule {
160 priority,
161 modes,
162 pattern: transform_pattern(&pattern.pattern, |expr| self.pattern_predicate(expr))?,
163 function_definition,
164 });
165 Ok(())
166 } else {
167 Err(error::Error::Unsupported.into())
168 }
169 }
170
171 fn mode(
172 &mut self,
173 declarations: &mut ir::Declarations,
174 mode: &ast::Mode,
175 ) -> error::SpannedResult<()> {
176 declarations.modes.insert(mode.name.clone(), ir::Mode {});
177 Ok(())
178 }
179
180 fn ast_mode_value_to_ir_mode_value(mode: &ast::ModeValue) -> ir::ModeValue {
181 match mode {
182 ast::ModeValue::EqName(name) => ir::ModeValue::Named(name.clone()),
183 ast::ModeValue::Unnamed => ir::ModeValue::Unnamed,
184 ast::ModeValue::All => ir::ModeValue::All,
185 }
186 }
187
188 fn sequence_constructor_function(
189 &mut self,
190 sequence_constructor: &ast::SequenceConstructor,
191 ) -> error::SpannedResult<ir::FunctionDefinition> {
192 let context_names = self.variables.push_context();
193 let bindings = self.sequence_constructor(sequence_constructor)?;
194 self.variables.pop_context();
195 let params = vec![
196 ir::Param {
197 name: context_names.item,
198 type_: None,
199 },
200 ir::Param {
201 name: context_names.position,
202 type_: None,
203 },
204 ir::Param {
205 name: context_names.last,
206 type_: None,
207 },
208 ];
209 Ok(ir::FunctionDefinition {
210 params,
211 return_type: None,
212 body: Box::new(bindings.expr()),
213 })
214 }
215
216 fn sequence_constructor(
217 &mut self,
218 sequence_constructor: &[ast::SequenceConstructorItem],
219 ) -> error::SpannedResult<Bindings> {
220 let mut items = sequence_constructor.iter();
221 let left = items.next();
222 if let Some(left) = left {
223 if let Some((name, var_bindings)) = self.variable(left)? {
224 let expr = ir::Expr::Let(ir::Let {
225 name,
226 var_expr: Box::new(var_bindings.expr()),
227 return_expr: Box::new(self.sequence_constructor(items.as_slice())?.expr()),
228 });
229 return Ok(Bindings::new(
230 self.variables.new_binding(expr, (0..0).into()),
231 ));
232 }
233 self.sequence_constructor_concat(left, items)
234 } else {
235 let empty_sequence = self.empty_sequence();
236 Ok(Bindings::new(
237 self.variables
238 .new_binding(empty_sequence.value, empty_sequence.span),
239 ))
240 }
241 }
242
243 fn sequence_constructor_concat<'b>(
244 &mut self,
245 left: &ast::SequenceConstructorItem,
246 items: impl Iterator<Item = &'b ast::SequenceConstructorItem>,
247 ) -> error::SpannedResult<Bindings> {
248 let left_bindings = Ok(self.sequence_constructor_item(left)?);
249 items.fold(left_bindings, |left, right| {
250 let mut left_bindings = left?;
251 let mut right_bindings = self.sequence_constructor_item(right)?;
252 let expr = ir::Expr::Binary(ir::Binary {
253 left: left_bindings.atom(),
254 op: ir::BinaryOperator::Comma,
255 right: right_bindings.atom(),
256 });
257 let binding = self.variables.new_binding_no_span(expr);
258 Ok(left_bindings.concat(right_bindings).bind(binding))
259 })
260 }
261
262 fn sequence_constructor_item(
263 &mut self,
264 item: &ast::SequenceConstructorItem,
265 ) -> error::SpannedResult<Bindings> {
266 match item {
267 ast::SequenceConstructorItem::Instruction(instruction) => {
268 self.sequence_constructor_instruction(instruction)
269 }
270 ast::SequenceConstructorItem::Content(content) => {
271 self.sequence_constructor_content(content)
272 }
273 }
274 }
275
276 fn sequence_constructor_instruction(
277 &mut self,
278 instruction: &ast::SequenceConstructorInstruction,
279 ) -> error::SpannedResult<Bindings> {
280 use ast::SequenceConstructorInstruction::*;
281 match instruction {
282 ApplyTemplates(apply_templates) => self.apply_templates(apply_templates),
283 ValueOf(value_of) => self.value_of(value_of),
284 If(if_) => self.if_(if_),
285 Choose(choose) => self.choose(choose),
286 ForEach(for_each) => self.for_each(for_each),
287 Copy(copy) => self.copy(copy),
288 CopyOf(copy_of) => self.copy_of(copy_of),
289 Sequence(sequence) => self.sequence(sequence),
290 Element(element) => self.element(element),
291 Text(text) => self.text(text),
292 Attribute(attribute) => self.attribute(attribute),
293 Namespace(namespace) => self.namespace(namespace),
294 Comment(comment) => self.comment(comment),
295 ProcessingInstruction(pi) => self.processing_instruction(pi),
296 Variable(_variable) => Err(error::Error::Unsupported.into()),
300 _ => Err(error::Error::Unsupported.into()),
301 }
302 }
303
304 fn sequence_constructor_content(
305 &mut self,
306 content: &ast::Content,
307 ) -> error::SpannedResult<Bindings> {
308 match content {
309 ast::Content::Element(element_node) => {
310 self.sequence_constructor_content_element(element_node)
311 }
312 ast::Content::Text(text) => {
313 let text_atom = Spanned::new(
314 ir::Atom::Const(ir::Const::String(text.clone())),
315 (0..0).into(),
316 );
317 let bindings = Bindings::empty();
318 Ok(bindings.bind_expr_no_span(
319 &mut self.variables,
320 ir::Expr::XmlText(ir::XmlText { value: text_atom }),
321 ))
322 }
323 ast::Content::Value(expression) => {
324 let (atom, bindings) = self.expression(expression)?.atom_bindings();
325 let expr = self.simple_content_expr(atom, self.space_separator_atom());
326 let (text_atom, bindings) = bindings
327 .bind_expr_no_span(&mut self.variables, expr)
328 .atom_bindings();
329 Ok(bindings.bind_expr_no_span(
330 &mut self.variables,
331 ir::Expr::XmlText(ir::XmlText { value: text_atom }),
332 ))
333 }
334 }
335 }
336
337 fn sequence_constructor_content_element(
338 &mut self,
339 element_node: &ast::ElementNode,
340 ) -> error::SpannedResult<Bindings> {
341 let (name_atom, bindings) = self.xml_name(&element_node.name)?.atom_bindings();
342 let name_expr = ir::Expr::XmlElement(ir::XmlElement { name: name_atom });
343 let (element_atom, mut bindings) = bindings
344 .bind_expr_no_span(&mut self.variables, name_expr)
345 .atom_bindings();
346 for (name, value) in &element_node.attributes {
347 let (value_atom, value_bindings) =
348 self.attribute_value_template(value)?.atom_bindings();
349 let (attribute_name_atom, attribute_bindings) = self.xml_name(name)?.atom_bindings();
350 let value_bindings = value_bindings.concat(attribute_bindings);
351 let attribute_expr = ir::Expr::XmlAttribute(ir::XmlAttribute {
352 name: attribute_name_atom,
353 value: value_atom,
354 });
355 let (attribute_atom, attribute_bindings) = value_bindings
356 .bind_expr_no_span(&mut self.variables, attribute_expr)
357 .atom_bindings();
358 let append_expr = ir::Expr::XmlAppend(ir::XmlAppend {
359 parent: element_atom.clone(),
360 child: attribute_atom,
361 });
362 let append_bindings =
363 attribute_bindings.bind_expr_no_span(&mut self.variables, append_expr);
364 bindings = bindings.concat(append_bindings);
365 }
366 let sequence_constructor_bindings = self.sequence_constructor_append(
367 element_atom.clone(),
368 &element_node.sequence_constructor,
369 )?;
370 let bindings = bindings.concat(sequence_constructor_bindings);
371 Ok(bindings)
372 }
373
374 fn sequence_constructor_append(
375 &mut self,
376 element_atom: ir::AtomS,
377 sequence_constructor: &ast::SequenceConstructor,
378 ) -> error::SpannedResult<Bindings> {
379 if !sequence_constructor.is_empty() {
380 let (atom, bindings) = self
381 .sequence_constructor(sequence_constructor)?
382 .atom_bindings();
383 let append = ir::Expr::XmlAppend(ir::XmlAppend {
384 parent: element_atom,
385 child: atom,
386 });
387 let bindings = bindings.bind_expr_no_span(&mut self.variables, append);
388 Ok(bindings)
389 } else {
390 Ok(Bindings::empty())
391 }
392 }
393
394 fn space_separator_atom(&self) -> ir::AtomS {
395 Spanned::new(
396 ir::Atom::Const(ir::Const::String(" ".to_string())),
397 (0..0).into(),
398 )
399 }
400
401 fn apply_templates(
402 &mut self,
403 apply_templates: &ast::ApplyTemplates,
404 ) -> error::SpannedResult<Bindings> {
405 let (select_atom, bindings) = self.expression(&apply_templates.select)?.atom_bindings();
406 let mode = match &apply_templates.mode {
407 ast::ApplyTemplatesModeValue::EqName(name) => {
408 ir::ApplyTemplatesModeValue::Named(name.clone())
409 }
410 ast::ApplyTemplatesModeValue::Unnamed => ir::ApplyTemplatesModeValue::Unnamed,
411 ast::ApplyTemplatesModeValue::Current => ir::ApplyTemplatesModeValue::Current,
412 };
413
414 Ok(bindings.bind_expr_no_span(
415 &mut self.variables,
416 ir::Expr::ApplyTemplates(ir::ApplyTemplates {
417 mode,
418 select: select_atom,
419 }),
420 ))
421 }
422
423 fn select_or_sequence_constructor(
424 &mut self,
425 instruction: &impl ast::SelectOrSequenceConstructor,
426 ) -> error::SpannedResult<Bindings> {
427 if let Some(select) = instruction.select() {
428 self.expression(select)
429 } else {
430 self.sequence_constructor(instruction.sequence_constructor())
431 }
432 }
433
434 fn select_or_sequence_constructor_simple_content(
435 &mut self,
436 instruction: &impl ast::SelectOrSequenceConstructor,
437 ) -> error::SpannedResult<Bindings> {
438 let (select_atom, bindings) = self
439 .select_or_sequence_constructor(instruction)?
440 .atom_bindings();
441
442 let separator_atom = self.space_separator_atom();
443 let expr = self.simple_content_expr(select_atom, separator_atom);
444 Ok(bindings.bind_expr_no_span(&mut self.variables, expr))
445 }
446
447 fn select_or_sequence_constructor_simple_content_with_separator(
448 &mut self,
449 instruction: &impl ast::SelectOrSequenceConstructor,
450 separator: &Option<ast::ValueTemplate<String>>,
451 ) -> error::SpannedResult<Bindings> {
452 let (select_atom, select_bindings) = self
453 .select_or_sequence_constructor(instruction)?
454 .atom_bindings();
455
456 let (separator_atom, separator_bindings) = if let Some(separator) = separator {
457 self.attribute_value_template(separator)?
458 } else {
459 Bindings::new(
460 self.variables
461 .new_binding_no_span(ir::Expr::Atom(self.space_separator_atom())),
462 )
463 }
464 .atom_bindings();
465 let bindings = select_bindings.concat(separator_bindings);
466 let expr = self.simple_content_expr(select_atom, separator_atom);
467 Ok(bindings.bind_expr_no_span(&mut self.variables, expr))
468 }
469
470 fn value_of(&mut self, value_of: &ast::ValueOf) -> error::SpannedResult<Bindings> {
471 let (text_atom, bindings) = self
472 .select_or_sequence_constructor_simple_content_with_separator(
473 value_of,
474 &value_of.separator,
475 )?
476 .atom_bindings();
477
478 Ok(bindings.bind_expr_no_span(
479 &mut self.variables,
480 ir::Expr::XmlText(ir::XmlText { value: text_atom }),
481 ))
482 }
483
484 fn attribute_value_template(
485 &mut self,
486 value_template: &ast::ValueTemplate<String>,
487 ) -> error::SpannedResult<Bindings> {
488 let mut all_bindings = Vec::new();
489 for item in &value_template.template {
490 let bindings = match item {
491 ast::ValueTemplateItem::String { text, span: _span } => {
492 let text_atom = Spanned::new(
493 ir::Atom::Const(ir::Const::String(text.clone())),
494 (0..0).into(),
495 );
496 let bindings = Bindings::empty();
497 bindings.bind_expr_no_span(&mut self.variables, ir::Expr::Atom(text_atom))
498 }
499 ast::ValueTemplateItem::Curly { c } => {
500 let text_atom = Spanned::new(
501 ir::Atom::Const(ir::Const::String(c.to_string())),
502 (0..0).into(),
503 );
504 let bindings = Bindings::empty();
505 bindings.bind_expr_no_span(&mut self.variables, ir::Expr::Atom(text_atom))
506 }
507 ast::ValueTemplateItem::Value { xpath, span: _ } => {
508 let (atom, bindings) = self.xpath(&xpath.0)?.atom_bindings();
509 let expr = self.simple_content_expr(atom, self.space_separator_atom());
510 bindings.bind_expr_no_span(&mut self.variables, expr)
511 }
512 };
513 all_bindings.push(bindings);
514 }
515 Ok(if all_bindings.is_empty() {
516 let bindings = Bindings::empty();
518 let empty_string = ir::Expr::Atom(self.empty_string());
519 bindings.bind_expr_no_span(&mut self.variables, empty_string)
520 } else if all_bindings.len() == 1 {
521 all_bindings.pop().unwrap()
523 } else {
524 let mut combined_bindings = Bindings::empty();
528 let mut atoms = Vec::new();
529 for binding in all_bindings {
530 let (atom, binding) = binding.atom_bindings();
531 combined_bindings = combined_bindings.concat(binding);
532 atoms.push(atom);
533 }
534 let concat_atom = self.concat_atom(atoms.len() as u8);
538 let expr = ir::Expr::FunctionCall(ir::FunctionCall {
539 atom: Spanned::new(concat_atom, (0..0).into()),
540 args: atoms,
541 });
542 combined_bindings.bind_expr_no_span(&mut self.variables, expr)
543 })
544 }
545
546 fn variable(
547 &mut self,
548 item: &ast::SequenceConstructorItem,
549 ) -> error::SpannedResult<Option<(ir::Name, Bindings)>> {
550 if let ast::SequenceConstructorItem::Instruction(
551 ast::SequenceConstructorInstruction::Variable(variable),
552 ) = item
553 {
554 let name = self.variables.new_var_name(&variable.name);
555 let var_bindings = if let Some(select) = &variable.select {
556 self.expression(select)?
557 } else {
558 self.sequence_constructor(&variable.sequence_constructor)?
559 };
560 Ok(Some((name, var_bindings)))
561 } else {
562 Ok(None)
563 }
564 }
565
566 fn empty_sequence(&mut self) -> ir::ExprS {
567 Spanned::new(
568 ir::Expr::Atom(Spanned::new(
569 ir::Atom::Const(ir::Const::EmptySequence),
570 (0..0).into(),
571 )),
572 (0..0).into(),
573 )
574 }
575
576 fn empty_string(&self) -> ir::AtomS {
577 Spanned::new(
578 ir::Atom::Const(ir::Const::String("".to_string())),
579 (0..0).into(),
580 )
581 }
582
583 fn if_(&mut self, if_: &ast::If) -> error::SpannedResult<Bindings> {
584 let (condition, bindings) = self.expression(&if_.test)?.atom_bindings();
585 let expr = ir::Expr::If(ir::If {
586 condition,
587 then: Box::new(self.sequence_constructor(&if_.sequence_constructor)?.expr()),
588 else_: Box::new(self.empty_sequence()),
589 });
590 Ok(bindings.bind_expr_no_span(&mut self.variables, expr))
591 }
592
593 fn choose(&mut self, choose: &ast::Choose) -> error::SpannedResult<Bindings> {
594 self.choose_when_otherwise(&choose.when, choose.otherwise.as_ref())
595 }
596
597 fn choose_when_otherwise(
598 &mut self,
599 when: &[ast::When],
600 otherwise: Option<&ast::Otherwise>,
601 ) -> error::SpannedResult<Bindings> {
602 let first = &when.first().unwrap();
603 let rest = &when[1..];
604
605 let (condition, bindings) = self.expression(&first.test)?.atom_bindings();
606 let else_expr = if !rest.is_empty() {
607 self.choose_when_otherwise(rest, otherwise)?.expr()
608 } else if let Some(otherwise) = otherwise {
609 self.sequence_constructor(&otherwise.sequence_constructor)?
610 .expr()
611 } else {
612 self.empty_sequence()
613 };
614
615 let expr = ir::Expr::If(ir::If {
616 condition,
617 then: Box::new(
618 self.sequence_constructor(&first.sequence_constructor)?
619 .expr(),
620 ),
621 else_: Box::new(else_expr),
622 });
623 Ok(bindings.bind_expr_no_span(&mut self.variables, expr))
624 }
625
626 fn for_each(&mut self, for_each: &ast::ForEach) -> error::SpannedResult<Bindings> {
627 let (var_atom, bindings) = self.expression(&for_each.select)?.atom_bindings();
628
629 let context_names = self.variables.push_context();
630 let return_bindings = self.sequence_constructor(&for_each.sequence_constructor)?;
631 self.variables.pop_context();
632 let expr = ir::Expr::Map(ir::Map {
633 context_names,
634 var_atom,
635 return_expr: Box::new(return_bindings.expr()),
636 });
637
638 Ok(bindings.bind_expr_no_span(&mut self.variables, expr))
639 }
640
641 fn copy(&mut self, copy: &ast::Copy) -> error::SpannedResult<Bindings> {
642 let (context_atom, bindings) = if let Some(select) = ©.select {
643 self.expression(select)?.atom_bindings()
644 } else {
645 self.variables.context_item((0..0).into())?.atom_bindings()
646 };
647 let expr = ir::Expr::CopyShallow(ir::CopyShallow {
649 select: context_atom,
650 });
651 let (copy_atom, bindings) = bindings
652 .bind_expr_no_span(&mut self.variables, expr)
653 .atom_bindings();
654
655 let is_element_expr = self.is_element_expr(copy_atom.clone());
660 let (is_element_atom, bindings) = bindings
661 .bind_expr_no_span(&mut self.variables, is_element_expr)
662 .atom_bindings();
663
664 let copy_expr = ir::Expr::Atom(copy_atom.clone());
665
666 let (sequence_constructor_atom, sequence_constructor_bindings) = self
667 .sequence_constructor(©.sequence_constructor)?
668 .atom_bindings();
669
670 let bindings = bindings.concat(sequence_constructor_bindings);
671
672 let append = ir::Expr::XmlAppend(ir::XmlAppend {
673 parent: copy_atom,
674 child: sequence_constructor_atom,
675 });
676
677 let if_expr = ir::Expr::If(ir::If {
678 condition: is_element_atom,
679 then: Box::new(Spanned::new(append, (0..0).into())),
680 else_: Box::new(Spanned::new(copy_expr, (0..0).into())),
681 });
682
683 Ok(bindings.bind_expr_no_span(&mut self.variables, if_expr))
684 }
685
686 fn is_element_expr(&self, atom: ir::AtomS) -> ir::Expr {
697 ir::Expr::InstanceOf(ir::InstanceOf {
698 atom,
699 sequence_type: xpath_ast::SequenceType::Item(xpath_ast::Item {
700 item_type: xpath_ast::ItemType::KindTest(xpath_ast::KindTest::Element(None)),
701 occurrence: xpath_ast::Occurrence::One,
702 }),
703 })
704 }
705
706 fn copy_of(&mut self, copy_of: &ast::CopyOf) -> error::SpannedResult<Bindings> {
707 let (atom, bindings) = self.expression(©_of.select)?.atom_bindings();
708 let copy_deep_expr = ir::Expr::CopyDeep(ir::CopyDeep { select: atom });
709 Ok(bindings.bind_expr_no_span(&mut self.variables, copy_deep_expr))
710 }
711
712 fn sequence(&mut self, sequence: &ast::Sequence) -> error::SpannedResult<Bindings> {
713 self.select_or_sequence_constructor(sequence)
714 }
715
716 fn xml_name(&mut self, name: &ast::Name) -> error::SpannedResult<Bindings> {
717 let local_name = Spanned::new(
718 ir::Atom::Const(ir::Const::String(name.local_name().to_string())),
719 (0..0).into(),
720 );
721 let namespace = self.empty_string();
722
723 let binding = self
724 .variables
725 .new_binding_no_span(ir::Expr::XmlName(ir::XmlName {
726 local_name,
727 namespace,
728 }));
729 Ok(Bindings::new(binding))
730 }
731
732 fn xml_name_dynamic(
733 &mut self,
734 name: &ast::ValueTemplate<String>,
735 namespace: &Option<ast::ValueTemplate<String>>,
736 ) -> error::SpannedResult<Bindings> {
737 let (localname_atom, bindings) = self.attribute_value_template(name)?.atom_bindings();
738 let (namespace_atom, namespace_bindings) = if let Some(namespace) = namespace {
739 self.attribute_value_template(namespace)?.atom_bindings()
740 } else {
741 let namespace_atom = self.empty_string();
742 (namespace_atom, Bindings::empty())
743 };
744 let bindings = bindings.concat(namespace_bindings);
745 let name = ir::Expr::XmlName(ir::XmlName {
746 local_name: localname_atom,
747 namespace: namespace_atom,
748 });
749 Ok(bindings.bind_expr_no_span(&mut self.variables, name))
750 }
751
752 fn ncname_dynamic(
753 &mut self,
754 name: &ast::ValueTemplate<String>,
755 ) -> error::SpannedResult<Bindings> {
756 self.attribute_value_template(name)
757 }
758
759 fn element(&mut self, element: &ast::Element) -> error::SpannedResult<Bindings> {
760 let (name_atom, bindings) = self
761 .xml_name_dynamic(&element.name, &element.namespace)?
762 .atom_bindings();
763
764 let expr = ir::Expr::XmlElement(ir::XmlElement { name: name_atom });
765 let (element_atom, bindings) = bindings
766 .bind_expr_no_span(&mut self.variables, expr)
767 .atom_bindings();
768 let sequence_constructor_bindings =
769 self.sequence_constructor_append(element_atom, &element.sequence_constructor)?;
770 Ok(bindings.concat(sequence_constructor_bindings))
771 }
772
773 fn text(&mut self, text: &ast::Text) -> error::SpannedResult<Bindings> {
774 let (atom, bindings) = self
775 .attribute_value_template(&text.content)?
776 .atom_bindings();
777 Ok(bindings.bind_expr_no_span(
778 &mut self.variables,
779 ir::Expr::XmlText(ir::XmlText { value: atom }),
780 ))
781 }
782
783 fn attribute(&mut self, attribute: &ast::Attribute) -> error::SpannedResult<Bindings> {
784 let (name_atom, name_bindings) = self
785 .xml_name_dynamic(&attribute.name, &attribute.namespace)?
786 .atom_bindings();
787 let (text_atom, text_bindings) = self
788 .select_or_sequence_constructor_simple_content_with_separator(
789 attribute,
790 &attribute.separator,
791 )?
792 .atom_bindings();
793 let bindings = name_bindings.concat(text_bindings);
794 Ok(bindings.bind_expr_no_span(
795 &mut self.variables,
796 ir::Expr::XmlAttribute(ir::XmlAttribute {
797 name: name_atom,
798 value: text_atom,
799 }),
800 ))
801 }
802
803 fn namespace(&mut self, namespace: &ast::Namespace) -> error::SpannedResult<Bindings> {
804 let (ncname_atom, ncname_bindings) = self.ncname_dynamic(&namespace.name)?.atom_bindings();
805 let (text_atom, text_bindings) = self
806 .select_or_sequence_constructor_simple_content(namespace)?
807 .atom_bindings();
808 let bindings = ncname_bindings.concat(text_bindings);
809 Ok(bindings.bind_expr_no_span(
810 &mut self.variables,
811 ir::Expr::XmlNamespace(ir::XmlNamespace {
812 prefix: ncname_atom,
813 namespace: text_atom,
814 }),
815 ))
816 }
817
818 fn comment(&mut self, comment: &ast::Comment) -> error::SpannedResult<Bindings> {
819 let (atom, bindings) = self
820 .select_or_sequence_constructor_simple_content(comment)?
821 .atom_bindings();
822 Ok(bindings.bind_expr_no_span(
823 &mut self.variables,
824 ir::Expr::XmlComment(ir::XmlComment { value: atom }),
825 ))
826 }
827
828 fn processing_instruction(
829 &mut self,
830 pi: &ast::ProcessingInstruction,
831 ) -> error::SpannedResult<Bindings> {
832 let (ncname_atom, ncname_bindings) = self.ncname_dynamic(&pi.name)?.atom_bindings();
833 let (content_atom, content_bindings) = self
834 .select_or_sequence_constructor_simple_content(pi)?
835 .atom_bindings();
836 let bindings = ncname_bindings.concat(content_bindings);
837 Ok(bindings.bind_expr_no_span(
838 &mut self.variables,
839 ir::Expr::XmlProcessingInstruction(ir::XmlProcessingInstruction {
840 target: ncname_atom,
841 content: content_atom,
842 }),
843 ))
844 }
845
846 fn expression(&mut self, expression: &ast::Expression) -> error::SpannedResult<Bindings> {
856 self.xpath(&expression.xpath.0)
857 }
858
859 fn xpath(&mut self, xpath: &xee_xpath_ast::ast::ExprS) -> error::SpannedResult<Bindings> {
860 let mut ir_converter =
861 xee_xpath_compiler::IrConverter::new(&mut self.variables, self.static_context);
862 ir_converter.expr(xpath)
863 }
864
865 fn pattern_predicate(
866 &mut self,
867 expr: &xpath_ast::ExprS,
868 ) -> error::SpannedResult<ir::FunctionDefinition> {
869 let context_names = self.variables.push_context();
870 let bindings = self.xpath(expr)?;
871 self.variables.pop_context();
872 let name = self.variables.new_name();
875 let var_atom = Spanned::new(ir::Atom::Variable(name.clone()), (0..0).into());
876 let filter = ir::Expr::PatternPredicate(ir::PatternPredicate {
877 context_names: context_names.clone(),
878 var_atom,
879 expr: Box::new(bindings.expr()),
880 });
881 let bindings = bindings.bind_expr(&mut self.variables, Spanned::new(filter, (0..0).into()));
882
883 let params = vec![
884 ir::Param {
885 name: context_names.item,
886 type_: None,
887 },
888 ir::Param {
889 name: context_names.position,
890 type_: None,
891 },
892 ir::Param {
893 name: context_names.last,
894 type_: None,
895 },
896 ];
897
898 Ok(ir::FunctionDefinition {
899 params,
900 return_type: None,
901 body: Box::new(bindings.expr()),
902 })
903 }
904}