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}