50 lines
2.1 KiB
Rust
50 lines
2.1 KiB
Rust
|
|
use nyash_rust::ast::{ASTNode, BinaryOperator, Span};
|
||
|
|
use crate::r#macro::pattern::{TemplatePattern, AstBuilder, MacroPattern};
|
||
|
|
use std::collections::HashMap;
|
||
|
|
|
||
|
|
#[test]
|
||
|
|
fn template_pattern_matches_and_unquotes() {
|
||
|
|
// Build a template: ($x + 1) == $y (Binary(Equal, Binary(Add, $x, 1), $y))
|
||
|
|
let tpl = ASTNode::BinaryOp {
|
||
|
|
operator: BinaryOperator::Equal,
|
||
|
|
left: Box::new(ASTNode::BinaryOp {
|
||
|
|
operator: BinaryOperator::Add,
|
||
|
|
left: Box::new(ASTNode::Variable { name: "$x".into(), span: Span::unknown() }),
|
||
|
|
right: Box::new(ASTNode::Literal { value: nyash_rust::ast::LiteralValue::Integer(1), span: Span::unknown() }),
|
||
|
|
span: Span::unknown(),
|
||
|
|
}),
|
||
|
|
right: Box::new(ASTNode::Variable { name: "$y".into(), span: Span::unknown() }),
|
||
|
|
span: Span::unknown(),
|
||
|
|
};
|
||
|
|
let pat = TemplatePattern::new(tpl);
|
||
|
|
|
||
|
|
// Target: (a + 1) == b
|
||
|
|
let target = ASTNode::BinaryOp {
|
||
|
|
operator: BinaryOperator::Equal,
|
||
|
|
left: Box::new(ASTNode::BinaryOp {
|
||
|
|
operator: BinaryOperator::Add,
|
||
|
|
left: Box::new(ASTNode::Variable { name: "a".into(), span: Span::unknown() }),
|
||
|
|
right: Box::new(ASTNode::Literal { value: nyash_rust::ast::LiteralValue::Integer(1), span: Span::unknown() }),
|
||
|
|
span: Span::unknown(),
|
||
|
|
}),
|
||
|
|
right: Box::new(ASTNode::Variable { name: "b".into(), span: Span::unknown() }),
|
||
|
|
span: Span::unknown(),
|
||
|
|
};
|
||
|
|
let binds = pat.match_ast(&target).expect("pattern match");
|
||
|
|
assert!(binds.contains_key("x"));
|
||
|
|
assert!(binds.contains_key("y"));
|
||
|
|
|
||
|
|
// Unquote a template: return $y
|
||
|
|
let builder = AstBuilder::new();
|
||
|
|
let tpl2 = ASTNode::Return { value: Some(Box::new(ASTNode::Variable { name: "$y".into(), span: Span::unknown() })), span: Span::unknown() };
|
||
|
|
let out = builder.unquote(&tpl2, &binds);
|
||
|
|
match out {
|
||
|
|
ASTNode::Return { value: Some(v), .. } => match *v {
|
||
|
|
ASTNode::Variable { name, .. } => assert_eq!(name, "b"),
|
||
|
|
_ => panic!("expected variable"),
|
||
|
|
}
|
||
|
|
_ => panic!("expected return"),
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|