/
algebra
45 lines (39 loc) · 1.19 KB
/
algebra
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
use v6;
use GGE::Exp;
use GGE::OPTable;
class Algebra::Literal is GGE::Exp does GGE::ShowContents {
method evaluate() {
+$.ast;
}
}
class Algebra::BinOp is GGE::Exp does GGE::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();
}
}
given GGE::OPTable.new() -> $optable {
$optable.newtok('term:', :precedence<=>,
:parsed(&Perl6::Grammar::number),
:match(Algebra::Literal));
$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 {
warn 'Could not parse the arithmetic expression';
next;
}
my $expr = $match.hash-access('expr');
say $expr.evaluate;
}
say '';
}