1use std::collections::BTreeMap;
15use std::path::Path;
16use std::rc::Rc;
17
18use crate::ast::rewrite::Rewriter;
19use crate::ast::walk::Walker;
20use crate::ast::{
21 BinaryExprType, BinaryOpDef, Expression, FormatArgs, FuncOpDef, Position, PositionedItem,
22 SelectDef, Shape, Statement, TemplatePart, Token, TokenType, Value,
23};
24use crate::build::format::{ExpressionTemplate, SimpleTemplate, TemplateParser};
25use crate::build::opcode::Primitive;
26use crate::build::opcode::{Hook, Op};
27
28pub struct AST();
29
30#[derive(Debug, PartialEq)]
31pub struct OpsMap {
32 pub ops: Vec<Op>,
33 pub pos: Vec<Position>,
34 pub shape_map: BTreeMap<Rc<str>, Shape>,
35 pub links: BTreeMap<Rc<str>, Position>,
36}
37
38impl OpsMap {
39 pub fn new() -> Self {
40 OpsMap {
41 ops: Vec::new(),
42 pos: Vec::new(),
43 shape_map: BTreeMap::new(),
45 links: BTreeMap::new(),
46 }
47 }
48
49 pub fn with_ops(mut self, ops: Vec<Op>, pos: Vec<Position>) -> Self {
50 self.ops = ops;
51 self.pos = pos;
52 self
53 }
54
55 pub fn add_link(&mut self, path: Rc<str>, pos: Position) {
56 self.links.insert(path, pos);
57 }
58
59 pub fn len(&self) -> usize {
60 self.ops.len()
61 }
62
63 pub fn push(&mut self, op: Op, pos: Position) {
64 self.ops.push(op);
65 self.pos.push(pos);
66 }
67
68 pub fn replace(&mut self, idx: usize, op: Op) {
69 self.ops[idx] = op;
70 }
71}
72
73impl AST {
74 pub fn translate<P: AsRef<Path>>(mut stmts: Vec<Statement>, root: &P) -> OpsMap {
75 let mut rewriter = Rewriter::new(root.as_ref());
76 let mut_stmts = stmts.iter_mut().collect();
77 rewriter.walk_statement_list(mut_stmts);
78 let mut ops = OpsMap::new();
79 Self::translate_stmts(stmts, &mut ops, root.as_ref());
80 return ops;
81 }
82
83 fn translate_stmt(stmt: Statement, mut ops: &mut OpsMap, root: &Path) {
84 match stmt {
85 Statement::Expression(expr) => {
86 let expr_pos = expr.pos().clone();
87 Self::translate_expr(expr, &mut ops, root);
88 ops.push(Op::Pop, expr_pos);
89 }
90 Statement::Assert(pos, expr) => {
91 Self::translate_expr(expr, &mut ops, root);
92 ops.push(Op::Runtime(Hook::Assert), pos);
93 }
94 Statement::Let(def) => {
95 let binding = def.name.fragment;
96 ops.push(Op::Sym(binding), def.name.pos);
97 Self::translate_expr(def.value, &mut ops, root);
98 ops.push(Op::Bind, def.pos);
99 }
100 Statement::Output(pos, tok, expr) => {
101 ops.push(Op::Val(Primitive::Str(tok.fragment)), tok.pos);
102 Self::translate_expr(expr, &mut ops, root);
103 ops.push(Op::Runtime(Hook::Out), pos);
104 }
105 Statement::Print(pos, tok, expr) => {
106 ops.push(Op::Val(Primitive::Str(tok.fragment)), tok.pos);
107 Self::translate_expr(expr, &mut ops, root);
108 ops.push(Op::Runtime(Hook::Convert), pos.clone());
109 ops.push(Op::Pop, pos);
110 }
111 }
112 }
113
114 fn translate_stmts(stmts: Vec<Statement>, mut ops: &mut OpsMap, root: &Path) {
115 for stmt in stmts {
116 Self::translate_stmt(stmt, &mut ops, root);
117 }
118 }
119
120 fn translate_expr(expr: Expression, mut ops: &mut OpsMap, root: &Path) {
121 match expr {
122 Expression::Simple(v) => {
123 Self::translate_value(v, &mut ops, root);
124 }
125 Expression::Binary(def) => {
126 match def.kind {
127 BinaryExprType::Add => {
128 Self::translate_expr(*def.right, &mut ops, root);
129 Self::translate_expr(*def.left, &mut ops, root);
130 ops.push(Op::Add, def.pos);
131 }
132 BinaryExprType::Sub => {
133 Self::translate_expr(*def.right, &mut ops, root);
134 Self::translate_expr(*def.left, &mut ops, root);
135 ops.push(Op::Sub, def.pos);
136 }
137 BinaryExprType::Div => {
138 Self::translate_expr(*def.right, &mut ops, root);
139 Self::translate_expr(*def.left, &mut ops, root);
140 ops.push(Op::Div, def.pos);
141 }
142 BinaryExprType::Mul => {
143 Self::translate_expr(*def.right, &mut ops, root);
144 Self::translate_expr(*def.left, &mut ops, root);
145 ops.push(Op::Mul, def.pos);
146 }
147 BinaryExprType::Equal => {
148 Self::translate_expr(*def.right, &mut ops, root);
149 Self::translate_expr(*def.left, &mut ops, root);
150 ops.push(Op::Equal, def.pos);
151 }
152 BinaryExprType::GT => {
153 Self::translate_expr(*def.right, &mut ops, root);
154 Self::translate_expr(*def.left, &mut ops, root);
155 ops.push(Op::Gt, def.pos);
156 }
157 BinaryExprType::LT => {
158 Self::translate_expr(*def.right, &mut ops, root);
159 Self::translate_expr(*def.left, &mut ops, root);
160 ops.push(Op::Lt, def.pos);
161 }
162 BinaryExprType::GTEqual => {
163 Self::translate_expr(*def.right, &mut ops, root);
164 Self::translate_expr(*def.left, &mut ops, root);
165 ops.push(Op::GtEq, def.pos);
166 }
167 BinaryExprType::LTEqual => {
168 Self::translate_expr(*def.right, &mut ops, root);
169 Self::translate_expr(*def.left, &mut ops, root);
170 ops.push(Op::LtEq, def.pos);
171 }
172 BinaryExprType::NotEqual => {
173 Self::translate_expr(*def.right, &mut ops, root);
174 Self::translate_expr(*def.left, &mut ops, root);
175 ops.push(Op::Equal, def.pos.clone());
176 ops.push(Op::Not, def.pos);
177 }
178 BinaryExprType::REMatch => {
179 Self::translate_expr(*def.right, &mut ops, root);
180 Self::translate_expr(*def.left, &mut ops, root);
181 ops.push(Op::Runtime(Hook::Regex), def.pos);
182 }
183 BinaryExprType::NotREMatch => {
184 Self::translate_expr(*def.right, &mut ops, root);
185 Self::translate_expr(*def.left, &mut ops, root);
186 ops.push(Op::Runtime(Hook::Regex), def.pos.clone());
187 ops.push(Op::Not, def.pos);
188 }
189 BinaryExprType::IS => {
190 Self::translate_expr(*def.right, &mut ops, root);
191 Self::translate_expr(*def.left, &mut ops, root);
192 ops.push(Op::Typ, def.pos.clone());
193 ops.push(Op::Equal, def.pos);
194 }
195 BinaryExprType::AND => {
196 Self::translate_expr(*def.left, &mut ops, root);
197 ops.push(Op::Noop, def.pos);
198 let idx = ops.len() - 1;
199 Self::translate_expr(*def.right, &mut ops, root);
200 let jptr = (ops.len() - 1 - idx) as i32;
201 ops.replace(idx, Op::And(jptr));
202 }
203 BinaryExprType::OR => {
204 Self::translate_expr(*def.left, &mut ops, root);
205 ops.push(Op::Noop, def.pos); let idx = ops.len() - 1;
207 Self::translate_expr(*def.right, &mut ops, root);
208 let jptr = (ops.len() - 1 - idx) as i32;
209 ops.replace(idx, Op::Or(jptr));
210 }
211 BinaryExprType::Mod => {
212 Self::translate_expr(*def.right, &mut ops, root);
213 Self::translate_expr(*def.left, &mut ops, root);
214 ops.push(Op::Mod, def.pos);
215 }
216 BinaryExprType::IN => {
217 Self::translate_expr(*def.right.clone(), &mut ops, root);
219 match *def.left.clone() {
222 Expression::Simple(Value::Symbol(name)) => {
223 let new_expr = Expression::Select(SelectDef {
227 val: Box::new(Expression::Binary(BinaryOpDef {
228 kind: BinaryExprType::IS,
229 right: Box::new(Expression::Simple(Value::Str(
230 PositionedItem::new(
231 "tuple".into(),
232 def.left.pos().clone(),
233 ),
234 ))),
235 left: def.right.clone(),
236 pos: def.left.pos().clone(),
237 })),
238 default: Some(Box::new(Expression::Simple(Value::Symbol(
239 name.clone(),
240 )))),
241 tuple: vec![(
242 Token::new("true", TokenType::BAREWORD, def.right.pos()),
243 None,
244 Expression::Simple(Value::Str(name)),
245 )],
246 pos: def.left.pos().clone(),
247 });
248 Self::translate_expr(new_expr, &mut ops, root);
249 }
250 expr => {
251 Self::translate_expr(expr, &mut ops, root);
252 }
253 }
254 ops.push(Op::Exist, def.pos.clone());
255 }
256 BinaryExprType::DOT => {
257 match *def.right {
260 Expression::Copy(copy_def) => {
261 Self::translate_expr(*def.left, &mut ops, root);
263 match copy_def.selector {
265 Value::Str(sym) | Value::Symbol(sym) => {
266 ops.push(Op::Val(Primitive::Str(sym.val)), sym.pos);
267 }
268 Value::Int(sym) => {
269 ops.push(Op::Val(Primitive::Int(sym.val)), sym.pos);
270 }
271 _ => unreachable!(),
272 }
273 ops.push(Op::Index, copy_def.pos.clone());
274 Self::translate_copy(ops, copy_def.fields, copy_def.pos, root);
275 return;
276 }
277 Expression::Call(call_def) => {
278 let count = call_def.arglist.len() as i64;
280 for e in call_def.arglist {
281 Self::translate_expr(e, &mut ops, root);
282 }
283 ops.push(Op::Val(Primitive::Int(count)), call_def.pos.clone());
284 Self::translate_expr(*def.left, &mut ops, root);
286 let func_pos = call_def.funcref.pos().clone();
288 match call_def.funcref {
289 Value::Str(sym) | Value::Symbol(sym) => {
290 ops.push(Op::Val(Primitive::Str(sym.val)), sym.pos);
291 }
292 Value::Int(sym) => {
293 ops.push(Op::Val(Primitive::Int(sym.val)), sym.pos);
294 }
295 _ => unreachable!(),
296 }
297 ops.push(Op::Index, def.pos);
298 ops.push(Op::FCall, func_pos);
299 return;
300 }
301 Expression::Simple(Value::Symbol(name)) => {
302 Self::translate_expr(*def.left, &mut ops, root);
304 Self::translate_expr(
305 Expression::Simple(Value::Str(name)),
306 &mut ops,
307 root,
308 );
309 }
310 expr => {
311 Self::translate_expr(*def.left, &mut ops, root);
313 Self::translate_expr(expr, &mut ops, root);
314 }
315 }
316 ops.push(Op::Index, def.pos);
317 }
318 };
319 }
320 Expression::Grouped(expr, _) => {
321 Self::translate_expr(*expr, &mut ops, root);
322 }
323 Expression::Fail(def) => {
324 let msg_pos = def.message.pos().clone();
325 Self::translate_expr(*def.message, &mut ops, root);
326 ops.push(Op::Val(Primitive::Str("UserDefined: ".into())), msg_pos);
327 ops.push(Op::Add, def.pos.clone());
328 ops.push(Op::Bang, def.pos);
329 }
330 Expression::Format(def) => {
331 match def.args {
332 FormatArgs::List(mut elems) => {
333 let formatter = SimpleTemplate::new();
334 let mut parts = formatter.parse(&def.template).unwrap();
337 elems.reverse();
340 parts.reverse();
341 let mut elems_iter = elems.drain(0..);
342 let mut parts_iter = parts.drain(0..);
343 Self::translate_template_part(
344 def.pos.clone(),
345 parts_iter.next().unwrap(),
346 &mut elems_iter,
347 &mut ops,
348 true,
349 root,
350 );
351 for p in parts_iter {
352 Self::translate_template_part(
353 def.pos.clone(),
354 p,
355 &mut elems_iter,
356 &mut ops,
357 true,
358 root,
359 );
360 ops.push(Op::Add, def.pos.clone());
363 }
364 }
365 FormatArgs::Single(expr) => {
366 let formatter = ExpressionTemplate::new();
367 let mut parts = formatter.parse(&def.template).unwrap();
370 parts.reverse();
371 let mut parts_iter = parts.drain(0..);
372 ops.push(Op::Noop, expr.pos().clone());
373 let scope_idx = ops.len() - 1;
374
375 let expr_pos = expr.pos().clone();
378 ops.push(Op::Sym("item".into()), expr.pos().clone());
379 Self::translate_expr(*expr, &mut ops, root);
380 ops.push(Op::BindOver, expr_pos.clone());
381 let mut elems = Vec::new();
382 let mut elems_iter = elems.drain(0..);
383 Self::translate_template_part(
384 def.pos.clone(),
385 parts_iter.next().unwrap(),
386 &mut elems_iter,
387 &mut ops,
388 false,
389 root,
390 );
391 for p in parts_iter {
392 Self::translate_template_part(
393 def.pos.clone(),
394 p,
395 &mut elems_iter,
396 &mut ops,
397 false,
398 root,
399 );
400 ops.push(Op::Add, expr_pos.clone());
401 }
402 ops.push(Op::Return, expr_pos);
403 let jump_idx = (ops.len() - 1 - scope_idx) as i32;
404 ops.replace(scope_idx, Op::NewScope(jump_idx));
405 }
406 }
407 }
408 Expression::Func(def) => {
409 ops.push(Op::InitList, def.pos.clone());
410 for (b, _constraint) in def.argdefs {
411 ops.push(Op::Sym(b.val), b.pos.clone());
414 ops.push(Op::Element, b.pos);
415 }
416 ops.push(Op::Noop, def.pos.clone());
417 let idx = ops.len() - 1;
418 Self::translate_expr(*def.fields, &mut ops, root);
419 ops.push(Op::Return, def.pos);
420 let jptr = ops.len() - 1 - idx;
421 ops.replace(idx, Op::Func(jptr as i32));
422 }
423 Expression::FuncOp(def) => {
424 match def {
425 FuncOpDef::Map(def) => {
426 Self::translate_expr(*def.func, &mut ops, root);
428 Self::translate_expr(*def.target, &mut ops, root);
430 ops.push(Op::Runtime(Hook::Map), def.pos);
432 }
433 FuncOpDef::Filter(def) => {
434 Self::translate_expr(*def.func, &mut ops, root);
436 Self::translate_expr(*def.target, &mut ops, root);
438 ops.push(Op::Runtime(Hook::Filter), def.pos);
440 }
441 FuncOpDef::Reduce(def) => {
442 Self::translate_expr(*def.func, &mut ops, root);
444 Self::translate_expr(*def.acc, &mut ops, root);
446 Self::translate_expr(*def.target, &mut ops, root);
448 ops.push(Op::Runtime(Hook::Reduce), def.pos);
450 }
451 }
452 }
453 Expression::Import(def) => {
454 let link_path = def.path.fragment.clone();
455 ops.add_link(link_path, def.path.pos.clone());
456 ops.push(Op::Val(Primitive::Str(def.path.fragment)), def.path.pos);
457 ops.push(Op::Runtime(Hook::Import), def.pos);
458 }
459 Expression::Include(def) => {
460 ops.push(Op::Val(Primitive::Str(def.typ.fragment)), def.typ.pos);
461 ops.push(Op::Val(Primitive::Str(def.path.fragment)), def.path.pos);
462 ops.push(Op::Runtime(Hook::Include), def.pos);
463 }
464 Expression::Module(def) => {
465 let argset = def.arg_set;
466 let out_expr = def.out_expr;
467 let stmts = def.statements;
468 ops.push(Op::InitTuple, def.pos.clone());
470 for (t, _constraint, e) in argset {
471 ops.push(Op::Sym(t.fragment), t.pos.clone());
474 Self::translate_expr(e, &mut ops, root);
475 ops.push(Op::Field, t.pos);
476 }
477 if let Some(expr) = out_expr {
479 let expr_pos = expr.pos().clone();
481 ops.push(Op::Noop, expr.pos().clone());
482 let idx = ops.len() - 1;
483 Self::translate_expr(*expr, &mut ops, root);
484 ops.push(Op::Return, expr_pos.clone());
485 let jptr = ops.len() - idx - 1;
486 ops.replace(idx, Op::InitThunk(jptr as i32));
487 }
488 ops.push(Op::Noop, def.pos.clone());
491 let idx = ops.len() - 1;
492 ops.push(Op::Bind, def.pos.clone());
494 Self::translate_stmts(stmts, &mut ops, root);
496 ops.push(Op::Return, def.pos);
498 let jptr = ops.len() - idx - 1;
499 ops.replace(idx, Op::Module(jptr as i32));
500 }
501 Expression::Not(def) => {
502 Self::translate_expr(*def.expr, &mut ops, root);
503 ops.push(Op::Not, def.pos);
504 }
505 Expression::Range(def) => {
506 Self::translate_expr(*def.end, &mut ops, root);
507 if let Some(expr) = def.step {
508 Self::translate_expr(*expr, &mut ops, root);
509 } else {
510 ops.push(Op::Val(Primitive::Empty), def.pos.clone());
511 }
512 Self::translate_expr(*def.start, &mut ops, root);
513 ops.push(Op::Runtime(Hook::Range), def.pos);
514 }
515 Expression::Select(def) => {
516 let default_pos = def.val.pos().clone();
517 Self::translate_expr(*def.val, &mut ops, root);
518 let mut jumps = Vec::new();
519 for (key, _constraint, val) in def.tuple {
520 ops.push(Op::Sym(key.fragment), key.pos.clone());
521 ops.push(Op::Noop, key.pos);
522 let idx = ops.len() - 1;
523 let expr_pos = val.pos().clone();
524 Self::translate_expr(val, &mut ops, root);
525 ops.push(Op::Noop, expr_pos);
526 jumps.push(ops.len() - 1);
527 let jptr = ops.len() - idx - 1;
528 ops.replace(idx, Op::SelectJump(jptr as i32));
529 }
530 ops.push(Op::Pop, def.pos.clone());
531 if let Some(default) = def.default {
532 Self::translate_expr(*default, &mut ops, root);
533 } else {
534 ops.push(
535 Op::Val(Primitive::Str(
536 "Unhandled select case with no default".into(),
537 )),
538 default_pos,
539 );
540 ops.push(Op::Bang, def.pos);
541 }
542 let end = ops.len() - 1;
543 for i in jumps {
544 let idx = end - i;
545 ops.replace(i, Op::Jump(idx as i32));
546 }
547 }
548 Expression::Call(call_def) => {
549 let count = call_def.arglist.len() as i64;
550 for e in call_def.arglist {
551 Self::translate_expr(e, &mut ops, root);
552 }
553 ops.push(Op::Val(Primitive::Int(count)), call_def.pos.clone());
554 let func_pos = call_def.funcref.pos().clone();
556 Self::translate_value(call_def.funcref, &mut ops, root);
557 ops.push(Op::FCall, func_pos);
558 }
559 Expression::Cast(cast_def) => {
560 Self::translate_expr(*cast_def.target, &mut ops, root);
561 ops.push(Op::Cast(cast_def.cast_type), cast_def.pos);
562 }
563 Expression::Copy(def) => {
564 Self::translate_value(def.selector, &mut ops, root);
565 Self::translate_copy(ops, def.fields, def.pos, root);
566 }
567 Expression::Debug(def) => {
568 let mut buffer: Vec<u8> = Vec::new();
569 {
570 let mut printer = crate::ast::printer::AstPrinter::new(2, &mut buffer);
571 let _ = printer.render_expr(&def.expr);
572 }
573 let expr_pretty = String::from_utf8(buffer).unwrap();
574 ops.push(Op::Val(Primitive::Str(expr_pretty.into())), def.pos.clone());
575 Self::translate_expr(*def.expr, &mut ops, root);
576 ops.push(Op::Runtime(Hook::Trace(def.pos.clone())), def.pos);
577 }
578 }
579 }
580
581 fn translate_template_part<EI: Iterator<Item = Expression>>(
582 pos: Position,
583 part: TemplatePart,
584 elems: &mut EI,
585 mut ops: &mut OpsMap,
586 place_holder: bool,
587 root: &Path,
588 ) {
589 match part {
590 TemplatePart::Str(s) => {
591 let part: String = s.into_iter().map(|c| c.to_string()).collect();
592 ops.push(Op::Val(Primitive::Str(part.into())), pos);
593 }
594 TemplatePart::PlaceHolder(_idx) => {
595 if !place_holder {
596 unreachable!();
598 } else {
599 Self::translate_expr(elems.next().unwrap(), &mut ops, root);
600 ops.push(Op::Render, pos);
601 }
602 }
603 TemplatePart::Expression(expr) => {
604 if place_holder {
605 unreachable!();
606 } else {
607 Self::translate_expr(expr, &mut ops, root);
608 ops.push(Op::Render, pos);
609 }
610 }
611 }
612 }
613
614 fn translate_copy(
615 mut ops: &mut OpsMap,
616 flds: Vec<(Token, Option<Expression>, Expression)>,
617 pos: Position,
618 root: &Path,
619 ) {
620 ops.push(Op::PushSelf, pos.clone());
621 ops.push(Op::InitTuple, pos.clone());
622 for (t, _constraint, e) in flds {
623 ops.push(Op::Sym(t.fragment), t.pos.clone());
624 Self::translate_expr(e, &mut ops, root);
625 ops.push(Op::Field, t.pos.clone());
626 }
627 ops.push(Op::Cp, pos.clone());
628 ops.push(Op::PopSelf, pos);
629 }
630
631 fn translate_value(value: Value, mut ops: &mut OpsMap, root: &Path) {
632 match value {
633 Value::Int(i) => ops.push(Op::Val(Primitive::Int(i.val)), i.pos),
634 Value::Float(f) => ops.push(Op::Val(Primitive::Float(f.val)), f.pos),
635 Value::Str(s) => ops.push(Op::Val(Primitive::Str(s.val)), s.pos),
636 Value::Empty(pos) => ops.push(Op::Val(Primitive::Empty), pos),
637 Value::Boolean(b) => ops.push(Op::Val(Primitive::Bool(b.val)), b.pos),
638 Value::Symbol(s) => {
639 ops.push(Op::DeRef(s.val), s.pos);
640 }
641 Value::Tuple(flds) => {
642 ops.push(Op::InitTuple, flds.pos);
643 for (k, _constraint, v) in flds.val {
644 ops.push(Op::Sym(k.fragment), k.pos.clone());
645 Self::translate_expr(v, &mut ops, root);
646 ops.push(Op::Field, k.pos.clone());
647 }
648 }
649 Value::List(els) => {
650 ops.push(Op::InitList, els.pos);
651 for el in els.elems {
652 let el_pos = el.pos().clone();
653 Self::translate_expr(el, &mut ops, root);
654 ops.push(Op::Element, el_pos);
655 }
656 }
657 }
658 }
659}