module HTMLQuote { our sub html-escape($_ is copy) { s:g/\&/&/; s:g/\/>/; s:g/\"/"/; s:g/\'/'/; $_; } } sub EXPORT(*@) { use nqp; use QAST:from; role Grammar { method tweak_html($v) { $v ?? self.add-postproc("html") !! self } } role Actions { sub visit-children(QAST::Children $node is raw) { my $num = nqp::elems($node); for (^$num) { nqp::bindpos($node, $_, visit(nqp::atpos($node, $_))); } $node; } multi sub visit(QAST::Op $node is raw) { if $node.op eq "callmethod" && $node.name eq "Stringy" { QAST::Op.new( :op, :node(Match.new), QAST::Op.new( :op, :name, QAST::Op.new( :op, QAST::Var.new( :name, :scope, #FIXME ), ), QAST::SVal.new(:value<&html-escape>), ), $node); } else { nextsame; } } multi sub visit(QAST::Node $node is raw) { if (nqp::istype($node, QAST::Children)) { visit-children($node); } else { $node } } multi sub visit($node is raw) { $node; } method postprocess_html(Mu $cap is raw, Mu $ast is raw) { note "BEFORE: " ~ $ast.dump; $ast := visit $ast; note "AFTER: " ~ $ast.dump; $ast; } } $*LANG.define_slang("Quote", %*LANG but Grammar, %*LANG but Actions); #{ "&html-escape" => &HTMLQuote::html-escape } {} }