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