Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[examples/algebra] imported example showing off OPTable

  • Loading branch information...
commit eb5b2d0ecb76a679ed0f5553588f00011aad0f8e 1 parent ee39566
@masak authored
Showing with 55 additions and 0 deletions.
  1. +55 −0 examples/algebra
View
55 examples/algebra
@@ -0,0 +1,55 @@
+use v6;
+use GGE::Exp;
+use GGE::OPTable;
+
+class Algebra::Literal is GGE::Exp does ShowContents {
+ method evaluate() {
+ +$.ast;
+ }
+}
+
+class Algebra::BinOp is GGE::Exp does ShowContents {
+}
+
+class Algebra::Addition is Algebra::BinOp {
+ method evaluate() {
+ $.llist[0].evaluate() + $.llist[1].evaluate();
+ }
+}
+
+class Algebra::Multiplication is Algebra::BinOp {
+ method evaluate() {
+ $.llist[0].evaluate() * $.llist[1].evaluate();
+ }
+}
+
+class Algebra {
+ sub parse_term($mob) {
+ my $m = Algebra::Literal.new($mob);
+ $m.from = $mob.to;
+ $m.to = -1;
+ my $target = $m.target.substr($m.from);
+ return $m
+ unless $target ~~ / ^ <Perl6::Grammar::number> /;
+ $m.to = $m.from + $<Perl6::Grammar::number>.chars;
+ $m;
+ }
+}
+
+given GGE::OPTable.new() -> $optable {
+ $optable.newtok('term:', :precedence<=>, :parsed(&Algebra::parse_term));
+ $optable.newtok('infix:+', :looser<term:>, :match(Algebra::Addition));
+ $optable.newtok('infix:*', :tighter<infix:+>,
+ :match(Algebra::Multiplication));
+
+ while prompt('> ') -> $input {
+ my $match = $optable.parse($input);
+ if $match.to < $input.chars {
+ say 'Could not parse the arithmetic expression';
+ next;
+ }
+ my $expr = $match<expr>;
+ say $expr.evaluate;
+ }
+ say '';
+}
Please sign in to comment.
Something went wrong with that request. Please try again.