zen_expression/compiler/
compiler.rs

1use crate::compiler::error::{CompilerError, CompilerResult};
2use crate::compiler::opcode::{FetchFastTarget, Jump};
3use crate::compiler::{Opcode, TypeCheckKind, TypeConversionKind};
4use crate::lexer::{ArithmeticOperator, ComparisonOperator, LogicalOperator, Operator};
5use crate::parser::{BuiltInFunction, Node};
6use rust_decimal::prelude::ToPrimitive;
7use rust_decimal::Decimal;
8use rust_decimal_macros::dec;
9use std::sync::Arc;
10
11#[derive(Debug)]
12pub struct Compiler {
13    bytecode: Vec<Opcode>,
14}
15
16impl Compiler {
17    pub fn new() -> Self {
18        Self {
19            bytecode: Default::default(),
20        }
21    }
22
23    pub fn compile(&mut self, root: &Node) -> CompilerResult<&[Opcode]> {
24        self.bytecode.clear();
25
26        CompilerInner::new(&mut self.bytecode, root).compile()?;
27        Ok(self.bytecode.as_slice())
28    }
29
30    pub fn get_bytecode(&self) -> &[Opcode] {
31        self.bytecode.as_slice()
32    }
33}
34
35#[derive(Debug)]
36struct CompilerInner<'arena, 'bytecode_ref> {
37    root: &'arena Node<'arena>,
38    bytecode: &'bytecode_ref mut Vec<Opcode>,
39}
40
41impl<'arena, 'bytecode_ref> CompilerInner<'arena, 'bytecode_ref> {
42    pub fn new(bytecode: &'bytecode_ref mut Vec<Opcode>, root: &'arena Node<'arena>) -> Self {
43        Self { root, bytecode }
44    }
45
46    pub fn compile(&mut self) -> CompilerResult<()> {
47        self.compile_node(self.root)?;
48        Ok(())
49    }
50
51    fn emit(&mut self, op: Opcode) -> usize {
52        self.bytecode.push(op);
53        self.bytecode.len()
54    }
55
56    fn emit_loop<F>(&mut self, body: F) -> CompilerResult<()>
57    where
58        F: FnOnce(&mut Self) -> CompilerResult<()>,
59    {
60        let begin = self.bytecode.len();
61        let end = self.emit(Opcode::Jump(Jump::IfEnd, 0));
62
63        body(self)?;
64
65        self.emit(Opcode::IncrementIt);
66        let e = self.emit(Opcode::Jump(
67            Jump::Backward,
68            self.calc_backward_jump(begin) as u32,
69        ));
70        self.replace(end, Opcode::Jump(Jump::IfEnd, (e - end) as u32));
71        Ok(())
72    }
73
74    fn emit_cond<F>(&mut self, mut body: F)
75    where
76        F: FnMut(&mut Self),
77    {
78        let noop = self.emit(Opcode::Jump(Jump::IfFalse, 0));
79        self.emit(Opcode::Pop);
80
81        body(self);
82
83        let jmp = self.emit(Opcode::Jump(Jump::Forward, 0));
84        self.replace(noop, Opcode::Jump(Jump::IfFalse, (jmp - noop) as u32));
85        let e = self.emit(Opcode::Pop);
86        self.replace(jmp, Opcode::Jump(Jump::Forward, (e - jmp) as u32));
87    }
88
89    fn replace(&mut self, at: usize, op: Opcode) {
90        let _ = std::mem::replace(&mut self.bytecode[at - 1], op);
91    }
92
93    fn calc_backward_jump(&self, to: usize) -> usize {
94        self.bytecode.len() + 1 - to
95    }
96
97    fn compile_argument(
98        &mut self,
99        builtin: &BuiltInFunction,
100        arguments: &[&'arena Node<'arena>],
101        index: usize,
102    ) -> CompilerResult<usize> {
103        let arg = arguments
104            .get(index)
105            .ok_or_else(|| CompilerError::ArgumentNotFound {
106                index,
107                builtin: builtin.to_string(),
108            })?;
109
110        self.compile_node(arg)
111    }
112
113    fn compile_member_fast(&mut self, node: &'arena Node<'arena>) -> Option<Vec<FetchFastTarget>> {
114        match node {
115            Node::Root => Some(vec![FetchFastTarget::Root]),
116            Node::Identifier(v) => Some(vec![
117                FetchFastTarget::Root,
118                FetchFastTarget::String(Arc::from(*v)),
119            ]),
120            Node::Member { node, property } => {
121                let mut path = self.compile_member_fast(node)?;
122                match property {
123                    Node::String(v) => {
124                        path.push(FetchFastTarget::String(Arc::from(*v)));
125                        Some(path)
126                    }
127                    Node::Number(v) => {
128                        if let Some(idx) = v.to_u32() {
129                            path.push(FetchFastTarget::Number(idx));
130                            Some(path)
131                        } else {
132                            None
133                        }
134                    }
135                    _ => None,
136                }
137            }
138            _ => None,
139        }
140    }
141
142    fn compile_node(&mut self, node: &'arena Node<'arena>) -> CompilerResult<usize> {
143        match node {
144            Node::Null => Ok(self.emit(Opcode::PushNull)),
145            Node::Bool(v) => Ok(self.emit(Opcode::PushBool(*v))),
146            Node::Number(v) => Ok(self.emit(Opcode::PushNumber(*v))),
147            Node::String(v) => Ok(self.emit(Opcode::PushString(Arc::from(*v)))),
148            Node::Pointer => Ok(self.emit(Opcode::Pointer)),
149            Node::Root => Ok(self.emit(Opcode::FetchRootEnv)),
150            Node::Array(v) => {
151                v.iter()
152                    .try_for_each(|&n| self.compile_node(n).map(|_| ()))?;
153                self.emit(Opcode::PushNumber(Decimal::from(v.len())));
154                Ok(self.emit(Opcode::Array))
155            }
156            Node::Object(v) => {
157                v.iter().try_for_each(|&(key, value)| {
158                    self.compile_node(key).map(|_| ())?;
159                    self.emit(Opcode::TypeConversion(TypeConversionKind::String));
160                    self.compile_node(value).map(|_| ())?;
161                    Ok(())
162                })?;
163
164                self.emit(Opcode::PushNumber(Decimal::from(v.len())));
165                Ok(self.emit(Opcode::Object))
166            }
167            Node::Identifier(v) => Ok(self.emit(Opcode::FetchEnv(Arc::from(*v)))),
168            Node::Closure(v) => self.compile_node(v),
169            Node::Parenthesized(v) => self.compile_node(v),
170            Node::Member {
171                node: n,
172                property: p,
173            } => {
174                if let Some(path) = self.compile_member_fast(node) {
175                    Ok(self.emit(Opcode::FetchFast(path)))
176                } else {
177                    self.compile_node(n)?;
178                    self.compile_node(p)?;
179                    Ok(self.emit(Opcode::Fetch))
180                }
181            }
182            Node::TemplateString(parts) => {
183                parts.iter().try_for_each(|&n| {
184                    self.compile_node(n).map(|_| ())?;
185                    self.emit(Opcode::TypeConversion(TypeConversionKind::String));
186                    Ok(())
187                })?;
188
189                self.emit(Opcode::PushNumber(Decimal::from(parts.len())));
190                self.emit(Opcode::Array);
191                self.emit(Opcode::PushString(Arc::from("")));
192                Ok(self.emit(Opcode::Join))
193            }
194            Node::Slice { node, to, from } => {
195                self.compile_node(node)?;
196                if let Some(t) = to {
197                    self.compile_node(t)?;
198                } else {
199                    self.emit(Opcode::Len);
200                    self.emit(Opcode::PushNumber(dec!(1)));
201                    self.emit(Opcode::Subtract);
202                }
203
204                if let Some(f) = from {
205                    self.compile_node(f)?;
206                } else {
207                    self.emit(Opcode::PushNumber(dec!(0)));
208                }
209
210                Ok(self.emit(Opcode::Slice))
211            }
212            Node::Interval {
213                left,
214                right,
215                left_bracket,
216                right_bracket,
217            } => {
218                self.compile_node(left)?;
219                self.compile_node(right)?;
220                Ok(self.emit(Opcode::Interval {
221                    left_bracket: *left_bracket,
222                    right_bracket: *right_bracket,
223                }))
224            }
225            Node::Conditional {
226                condition,
227                on_true,
228                on_false,
229            } => {
230                self.compile_node(condition)?;
231                let otherwise = self.emit(Opcode::Jump(Jump::IfFalse, 0));
232
233                self.emit(Opcode::Pop);
234                self.compile_node(on_true)?;
235                let end = self.emit(Opcode::Jump(Jump::Forward, 0));
236
237                self.replace(
238                    otherwise,
239                    Opcode::Jump(Jump::IfFalse, (end - otherwise) as u32),
240                );
241                self.emit(Opcode::Pop);
242                let b = self.compile_node(on_false)?;
243                self.replace(end, Opcode::Jump(Jump::Forward, (b - end) as u32));
244
245                Ok(b)
246            }
247            Node::Unary { node, operator } => {
248                let curr = self.compile_node(node)?;
249                match *operator {
250                    Operator::Arithmetic(ArithmeticOperator::Add) => Ok(curr),
251                    Operator::Arithmetic(ArithmeticOperator::Subtract) => {
252                        Ok(self.emit(Opcode::Negate))
253                    }
254                    Operator::Logical(LogicalOperator::Not) => Ok(self.emit(Opcode::Not)),
255                    _ => Err(CompilerError::UnknownUnaryOperator {
256                        operator: operator.to_string(),
257                    }),
258                }
259            }
260            Node::Binary {
261                left,
262                right,
263                operator,
264            } => match *operator {
265                Operator::Comparison(ComparisonOperator::Equal) => {
266                    self.compile_node(left)?;
267                    self.compile_node(right)?;
268
269                    Ok(self.emit(Opcode::Equal))
270                }
271                Operator::Comparison(ComparisonOperator::NotEqual) => {
272                    self.compile_node(left)?;
273                    self.compile_node(right)?;
274
275                    self.emit(Opcode::Equal);
276                    Ok(self.emit(Opcode::Not))
277                }
278                Operator::Logical(LogicalOperator::Or) => {
279                    self.compile_node(left)?;
280                    let end = self.emit(Opcode::Jump(Jump::IfTrue, 0));
281                    self.emit(Opcode::Pop);
282                    let r = self.compile_node(right)?;
283                    self.replace(end, Opcode::Jump(Jump::IfTrue, (r - end) as u32));
284
285                    Ok(r)
286                }
287                Operator::Logical(LogicalOperator::And) => {
288                    self.compile_node(left)?;
289                    let end = self.emit(Opcode::Jump(Jump::IfFalse, 0));
290                    self.emit(Opcode::Pop);
291                    let r = self.compile_node(right)?;
292                    self.replace(end, Opcode::Jump(Jump::IfFalse, (r - end) as u32));
293
294                    Ok(r)
295                }
296                Operator::Logical(LogicalOperator::NullishCoalescing) => {
297                    self.compile_node(left)?;
298                    let end = self.emit(Opcode::Jump(Jump::IfNotNull, 0));
299                    self.emit(Opcode::Pop);
300                    let r = self.compile_node(right)?;
301                    self.replace(end, Opcode::Jump(Jump::IfNotNull, (r - end) as u32));
302
303                    Ok(r)
304                }
305                Operator::Comparison(ComparisonOperator::In) => {
306                    self.compile_node(left)?;
307                    self.compile_node(right)?;
308                    Ok(self.emit(Opcode::In))
309                }
310                Operator::Comparison(ComparisonOperator::NotIn) => {
311                    self.compile_node(left)?;
312                    self.compile_node(right)?;
313                    self.emit(Opcode::In);
314                    Ok(self.emit(Opcode::Not))
315                }
316                Operator::Comparison(ComparisonOperator::LessThan) => {
317                    self.compile_node(left)?;
318                    self.compile_node(right)?;
319                    Ok(self.emit(Opcode::Less))
320                }
321                Operator::Comparison(ComparisonOperator::LessThanOrEqual) => {
322                    self.compile_node(left)?;
323                    self.compile_node(right)?;
324                    Ok(self.emit(Opcode::LessOrEqual))
325                }
326                Operator::Comparison(ComparisonOperator::GreaterThan) => {
327                    self.compile_node(left)?;
328                    self.compile_node(right)?;
329                    Ok(self.emit(Opcode::More))
330                }
331                Operator::Comparison(ComparisonOperator::GreaterThanOrEqual) => {
332                    self.compile_node(left)?;
333                    self.compile_node(right)?;
334                    Ok(self.emit(Opcode::MoreOrEqual))
335                }
336                Operator::Arithmetic(ArithmeticOperator::Add) => {
337                    self.compile_node(left)?;
338                    self.compile_node(right)?;
339                    Ok(self.emit(Opcode::Add))
340                }
341                Operator::Arithmetic(ArithmeticOperator::Subtract) => {
342                    self.compile_node(left)?;
343                    self.compile_node(right)?;
344                    Ok(self.emit(Opcode::Subtract))
345                }
346                Operator::Arithmetic(ArithmeticOperator::Multiply) => {
347                    self.compile_node(left)?;
348                    self.compile_node(right)?;
349                    Ok(self.emit(Opcode::Multiply))
350                }
351                Operator::Arithmetic(ArithmeticOperator::Divide) => {
352                    self.compile_node(left)?;
353                    self.compile_node(right)?;
354                    Ok(self.emit(Opcode::Divide))
355                }
356                Operator::Arithmetic(ArithmeticOperator::Modulus) => {
357                    self.compile_node(left)?;
358                    self.compile_node(right)?;
359                    Ok(self.emit(Opcode::Modulo))
360                }
361                Operator::Arithmetic(ArithmeticOperator::Power) => {
362                    self.compile_node(left)?;
363                    self.compile_node(right)?;
364                    Ok(self.emit(Opcode::Exponent))
365                }
366                _ => Err(CompilerError::UnknownBinaryOperator {
367                    operator: operator.to_string(),
368                }),
369            },
370            Node::BuiltIn { kind, arguments } => match kind {
371                BuiltInFunction::Len => {
372                    self.compile_argument(kind, arguments, 0)?;
373                    self.emit(Opcode::Len);
374                    self.emit(Opcode::Rot);
375                    Ok(self.emit(Opcode::Pop))
376                }
377                BuiltInFunction::Trim => {
378                    self.compile_argument(kind, arguments, 0)?;
379                    Ok(self.emit(Opcode::Trim))
380                }
381                BuiltInFunction::Date => {
382                    self.compile_argument(kind, arguments, 0)?;
383                    Ok(self.emit(Opcode::ParseDateTime))
384                }
385                BuiltInFunction::Time => {
386                    self.compile_argument(kind, arguments, 0)?;
387                    Ok(self.emit(Opcode::ParseTime))
388                }
389                BuiltInFunction::Duration => {
390                    self.compile_argument(kind, arguments, 0)?;
391                    Ok(self.emit(Opcode::ParseDuration))
392                }
393                BuiltInFunction::StartsWith => {
394                    self.compile_argument(kind, arguments, 0)?;
395                    self.compile_argument(kind, arguments, 1)?;
396                    Ok(self.emit(Opcode::StartsWith))
397                }
398                BuiltInFunction::EndsWith => {
399                    self.compile_argument(kind, arguments, 0)?;
400                    self.compile_argument(kind, arguments, 1)?;
401                    Ok(self.emit(Opcode::EndsWith))
402                }
403                BuiltInFunction::Contains => {
404                    self.compile_argument(kind, arguments, 0)?;
405                    self.compile_argument(kind, arguments, 1)?;
406                    Ok(self.emit(Opcode::Contains))
407                }
408                BuiltInFunction::Matches => {
409                    self.compile_argument(kind, arguments, 0)?;
410                    self.compile_argument(kind, arguments, 1)?;
411                    Ok(self.emit(Opcode::Matches))
412                }
413                BuiltInFunction::FuzzyMatch => {
414                    self.compile_argument(kind, arguments, 0)?;
415                    self.compile_argument(kind, arguments, 1)?;
416                    Ok(self.emit(Opcode::FuzzyMatch))
417                }
418                BuiltInFunction::Split => {
419                    self.compile_argument(kind, arguments, 0)?;
420                    self.compile_argument(kind, arguments, 1)?;
421
422                    Ok(self.emit(Opcode::Split))
423                }
424                BuiltInFunction::Extract => {
425                    self.compile_argument(kind, arguments, 0)?;
426                    self.compile_argument(kind, arguments, 1)?;
427                    Ok(self.emit(Opcode::Extract))
428                }
429                BuiltInFunction::Flatten => {
430                    self.compile_argument(kind, arguments, 0)?;
431                    Ok(self.emit(Opcode::Flatten))
432                }
433                BuiltInFunction::Upper => {
434                    self.compile_argument(kind, arguments, 0)?;
435                    Ok(self.emit(Opcode::Uppercase))
436                }
437                BuiltInFunction::Lower => {
438                    self.compile_argument(kind, arguments, 0)?;
439                    Ok(self.emit(Opcode::Lowercase))
440                }
441                BuiltInFunction::Abs => {
442                    self.compile_argument(kind, arguments, 0)?;
443                    Ok(self.emit(Opcode::Abs))
444                }
445                BuiltInFunction::Avg => {
446                    self.compile_argument(kind, arguments, 0)?;
447                    Ok(self.emit(Opcode::Average))
448                }
449                BuiltInFunction::Median => {
450                    self.compile_argument(kind, arguments, 0)?;
451                    Ok(self.emit(Opcode::Median))
452                }
453                BuiltInFunction::Mode => {
454                    self.compile_argument(kind, arguments, 0)?;
455                    Ok(self.emit(Opcode::Mode))
456                }
457                BuiltInFunction::Max => {
458                    self.compile_argument(kind, arguments, 0)?;
459                    Ok(self.emit(Opcode::Max))
460                }
461                BuiltInFunction::Min => {
462                    self.compile_argument(kind, arguments, 0)?;
463                    Ok(self.emit(Opcode::Min))
464                }
465                BuiltInFunction::Sum => {
466                    self.compile_argument(kind, arguments, 0)?;
467                    Ok(self.emit(Opcode::Sum))
468                }
469                BuiltInFunction::Floor => {
470                    self.compile_argument(kind, arguments, 0)?;
471                    Ok(self.emit(Opcode::Floor))
472                }
473                BuiltInFunction::Ceil => {
474                    self.compile_argument(kind, arguments, 0)?;
475                    Ok(self.emit(Opcode::Ceil))
476                }
477                BuiltInFunction::Round => {
478                    self.compile_argument(kind, arguments, 0)?;
479                    Ok(self.emit(Opcode::Round))
480                }
481                BuiltInFunction::Rand => {
482                    self.compile_argument(kind, arguments, 0)?;
483                    Ok(self.emit(Opcode::Random))
484                }
485                BuiltInFunction::String => {
486                    self.compile_argument(kind, arguments, 0)?;
487                    Ok(self.emit(Opcode::TypeConversion(TypeConversionKind::String)))
488                }
489                BuiltInFunction::Number => {
490                    self.compile_argument(kind, arguments, 0)?;
491                    Ok(self.emit(Opcode::TypeConversion(TypeConversionKind::Number)))
492                }
493                BuiltInFunction::Bool => {
494                    self.compile_argument(kind, arguments, 0)?;
495                    Ok(self.emit(Opcode::TypeConversion(TypeConversionKind::Bool)))
496                }
497                BuiltInFunction::IsNumeric => {
498                    self.compile_argument(kind, arguments, 0)?;
499                    Ok(self.emit(Opcode::TypeCheck(TypeCheckKind::Numeric)))
500                }
501                BuiltInFunction::Type => {
502                    self.compile_argument(kind, arguments, 0)?;
503                    Ok(self.emit(Opcode::GetType))
504                }
505                BuiltInFunction::Keys => {
506                    self.compile_argument(kind, arguments, 0)?;
507                    Ok(self.emit(Opcode::Keys))
508                }
509                BuiltInFunction::Values => {
510                    self.compile_argument(kind, arguments, 0)?;
511                    Ok(self.emit(Opcode::Values))
512                }
513                BuiltInFunction::StartOf | BuiltInFunction::EndOf => {
514                    self.compile_argument(kind, arguments, 0)?;
515                    self.compile_argument(kind, arguments, 1)?;
516                    Ok(
517                        self.emit(Opcode::DateFunction(Arc::from(Into::<&'static str>::into(
518                            kind,
519                        )))),
520                    )
521                }
522                BuiltInFunction::DayOfWeek
523                | BuiltInFunction::DayOfMonth
524                | BuiltInFunction::DayOfYear
525                | BuiltInFunction::WeekOfYear
526                | BuiltInFunction::MonthOfYear
527                | BuiltInFunction::MonthString
528                | BuiltInFunction::WeekdayString
529                | BuiltInFunction::Year
530                | BuiltInFunction::DateString => {
531                    self.compile_argument(kind, arguments, 0)?;
532                    Ok(self.emit(Opcode::DateManipulation(Arc::from(
533                        Into::<&'static str>::into(kind),
534                    ))))
535                }
536                BuiltInFunction::All => {
537                    self.compile_argument(kind, arguments, 0)?;
538                    self.emit(Opcode::Begin);
539                    let mut loop_break: usize = 0;
540                    self.emit_loop(|c| {
541                        c.compile_argument(kind, arguments, 1)?;
542                        loop_break = c.emit(Opcode::Jump(Jump::IfFalse, 0));
543                        c.emit(Opcode::Pop);
544                        Ok(())
545                    })?;
546                    let e = self.emit(Opcode::PushBool(true));
547                    self.replace(
548                        loop_break,
549                        Opcode::Jump(Jump::IfFalse, (e - loop_break) as u32),
550                    );
551                    Ok(self.emit(Opcode::End))
552                }
553                BuiltInFunction::None => {
554                    self.compile_argument(kind, arguments, 0)?;
555                    self.emit(Opcode::Begin);
556                    let mut loop_break: usize = 0;
557                    self.emit_loop(|c| {
558                        c.compile_argument(kind, arguments, 1)?;
559                        c.emit(Opcode::Not);
560                        loop_break = c.emit(Opcode::Jump(Jump::IfFalse, 0));
561                        c.emit(Opcode::Pop);
562                        Ok(())
563                    })?;
564                    let e = self.emit(Opcode::PushBool(true));
565                    self.replace(
566                        loop_break,
567                        Opcode::Jump(Jump::IfFalse, (e - loop_break) as u32),
568                    );
569                    Ok(self.emit(Opcode::End))
570                }
571                BuiltInFunction::Some => {
572                    self.compile_argument(kind, arguments, 0)?;
573                    self.emit(Opcode::Begin);
574                    let mut loop_break: usize = 0;
575                    self.emit_loop(|c| {
576                        c.compile_argument(kind, arguments, 1)?;
577                        loop_break = c.emit(Opcode::Jump(Jump::IfTrue, 0));
578                        c.emit(Opcode::Pop);
579                        Ok(())
580                    })?;
581                    let e = self.emit(Opcode::PushBool(false));
582                    self.replace(
583                        loop_break,
584                        Opcode::Jump(Jump::IfTrue, (e - loop_break) as u32),
585                    );
586                    Ok(self.emit(Opcode::End))
587                }
588                BuiltInFunction::One => {
589                    self.compile_argument(kind, arguments, 0)?;
590                    self.emit(Opcode::Begin);
591                    self.emit_loop(|c| {
592                        c.compile_argument(kind, arguments, 1)?;
593                        c.emit_cond(|c| {
594                            c.emit(Opcode::IncrementCount);
595                        });
596                        Ok(())
597                    })?;
598                    self.emit(Opcode::GetCount);
599                    self.emit(Opcode::PushNumber(dec!(1)));
600                    self.emit(Opcode::Equal);
601                    Ok(self.emit(Opcode::End))
602                }
603                BuiltInFunction::Filter => {
604                    self.compile_argument(kind, arguments, 0)?;
605                    self.emit(Opcode::Begin);
606                    self.emit_loop(|c| {
607                        c.compile_argument(kind, arguments, 1)?;
608                        c.emit_cond(|c| {
609                            c.emit(Opcode::IncrementCount);
610                            c.emit(Opcode::Pointer);
611                        });
612                        Ok(())
613                    })?;
614                    self.emit(Opcode::GetCount);
615                    self.emit(Opcode::End);
616                    Ok(self.emit(Opcode::Array))
617                }
618                BuiltInFunction::Map => {
619                    self.compile_argument(kind, arguments, 0)?;
620                    self.emit(Opcode::Begin);
621                    self.emit_loop(|c| {
622                        c.compile_argument(kind, arguments, 1)?;
623                        Ok(())
624                    })?;
625                    self.emit(Opcode::GetLen);
626                    self.emit(Opcode::End);
627                    Ok(self.emit(Opcode::Array))
628                }
629                BuiltInFunction::FlatMap => {
630                    self.compile_argument(kind, arguments, 0)?;
631                    self.emit(Opcode::Begin);
632                    self.emit_loop(|c| {
633                        c.compile_argument(kind, arguments, 1)?;
634                        Ok(())
635                    })?;
636                    self.emit(Opcode::GetLen);
637                    self.emit(Opcode::End);
638                    self.emit(Opcode::Array);
639                    Ok(self.emit(Opcode::Flatten))
640                }
641                BuiltInFunction::Count => {
642                    self.compile_argument(kind, arguments, 0)?;
643                    self.emit(Opcode::Begin);
644                    self.emit_loop(|c| {
645                        c.compile_argument(kind, arguments, 1)?;
646                        c.emit_cond(|c| {
647                            c.emit(Opcode::IncrementCount);
648                        });
649                        Ok(())
650                    })?;
651                    self.emit(Opcode::GetCount);
652                    Ok(self.emit(Opcode::End))
653                }
654            },
655            Node::Error { .. } => Err(CompilerError::UnexpectedErrorNode),
656        }
657    }
658}