1. my class Grammar is Cursor {
  2. # cache cursor initialization lookup
  3. my $cursor-init := Cursor.^lookup("!cursor_init");
  4. method parse(\target, :$rule, :$args, Mu :$actions) {
  5. nqp::decont(nqp::getlexdyn('$/') =
  6. nqp::if(
  7. (my $cursor := nqp::if(
  8. $rule,
  9. nqp::if(
  10. $args,
  11. self!cursor-init(target, %_).set_actions($actions)."$rule"(|$args.Capture),
  12. self!cursor-init(target, %_).set_actions($actions)."$rule"()
  13. ),
  14. nqp::if(
  15. $args,
  16. self!cursor-init(target, %_).set_actions($actions).TOP(|$args.Capture),
  17. self!cursor-init(target, %_).set_actions($actions).TOP()
  18. ),
  19. )),
  20. nqp::stmts(
  21. (my $match := $cursor.MATCH),
  22. nqp::while(
  23. $match && nqp::isne_i(
  24. nqp::getattr_i(($match := $cursor.MATCH),Match,'$!to'),
  25. target.chars
  26. ),
  27. $match := ($cursor := $cursor.'!cursor_next'()).MATCH
  28. ),
  29. $match || Nil
  30. ),
  31. Nil
  32. )
  33. )
  34. }
  35. method subparse(\target, :$rule, :$args, Mu :$actions) {
  36. nqp::decont(nqp::getlexdyn('$/') =
  37. nqp::if(
  38. $rule,
  39. nqp::if(
  40. $args,
  41. self!cursor-init(target, %_).set_actions($actions)."$rule"(|$args.Capture).MATCH,
  42. self!cursor-init(target, %_).set_actions($actions)."$rule"().MATCH,
  43. ),
  44. nqp::if(
  45. $args,
  46. self!cursor-init(target, %_).set_actions($actions).TOP(|$args.Capture).MATCH,
  47. self!cursor-init(target, %_).set_actions($actions).TOP().MATCH
  48. ),
  49. )
  50. )
  51. }
  52. method parsefile(Str(Cool) $filename, :$enc) {
  53. nqp::decont(nqp::getlexdyn('$/') = nqp::if(
  54. nqp::elems(nqp::getattr(%_,Map,'$!storage')),
  55. self.parse($filename.IO.slurp(:$enc), |%_),
  56. self.parse($filename.IO.slurp(:$enc))
  57. ))
  58. }
  59. method !cursor-init(\target, %opts) is raw {
  60. nqp::if(
  61. nqp::elems(nqp::getattr(%opts,Map,'$!storage')),
  62. $cursor-init(self, target, |%opts),
  63. $cursor-init(self, target)
  64. )
  65. }
  66. }