-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathI2PIR.trg
100 lines (76 loc) · 2.13 KB
/
I2PIR.trg
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
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
{ # Example of support code
use List::Util qw(reduce);
my %Op = (PLUS=>'+', MINUS => '-', TIMES=>'*', DIV => '/');
}
algebra = fold wxz zxw neg;
fold: /TIMES|PLUS|DIV|MINUS/:b(NUM, NUM) => {
my $op = $Op{ref($b)};
croak "Unexpected tree shape: ".$_[0]->str." can't find number in the expected place\n" unless exists ($NUM[0]->{attr}) && ($NUM[0]->{attr} =~ /^\d+/);
$NUM[0]->{attr} = eval "$NUM[0]->{attr} $op $NUM[1]->{attr}";
$_[0] = $NUM[0];
}
zxw: TIMES(NUM, .) and {$NUM->{attr} == 0} => { $_[0] = $NUM }
wxz: TIMES(., NUM) and {$NUM->{attr} == 0} => { $_[0] = $NUM }
neg: NEG(NUM) => { $NUM->{attr} = -$NUM->{attr}; $_[0] = $NUM }
{{
my $num = 1; # closure
sub new_N_register {
return '$N'.$num++;
}
}}
reg_assign: $x => {
if (ref($x) =~ /VAR|NUM/) {
$x->{reg} = $x->{attr};
return 1;
}
if (ref($x) =~ /ASSIGN/) {
$x->{reg} = $x->child(0)->{attr};
return 1;
}
$_[0]->{reg} = new_N_register();
}
translation = t_num t_var t_op t_neg t_assign t_list t_print;
t_num: NUM => { $NUM->{tr} = $NUM->{attr} }
{ our %s; }
t_var: VAR => {
croak "Unexpected tree shape: ".$_[0]->str." can't find identifier in VAR node\n" unless exists $_[0]->{attr};
$s{$_[0]->{attr}} = "num";
$_[0]->{tr} = $_[0]->{attr};
}
t_op: /TIMES|PLUS|DIV|MINUS/:b($x, $y) => {
my $op = $Op{ref($b)};
$b->{tr} = "$b->{reg} = $x->{reg} $op $y->{reg}";
}
t_neg: NEG($exp) => { $NEG->{tr} = "$NEG->{reg} = - $exp->{reg}"; }
t_assign: ASSIGN($v, $e) => {
$s{$v->{attr}} = "num";
$ASSIGN->{tr} = "$v->{reg} = $e->{reg}"
}
{ my $cr = '\\n'; }
t_print: PRINT(., $var) => {
$s{$var->{attr}} = "num";
$PRINT->{tr} =<<"EOP";
print "$var->{attr} = "
print $var->{attr}
print "$cr"
EOP
}
{
# Concatenates the translations of the subtrees
sub cat_trans {
my $t = shift;
my $tr = "";
for ($t->children) {
(ref($_) =~ m{NUM|VAR|TERMINAL})
or $tr .= cat_trans($_)."\n"
}
$tr .= $t->{tr} ;
}
}
t_list: EXPS(@S)
=> {
$EXPS->{tr} = "";
my @tr = map { cat_trans($_) } @S;
$EXPS->{tr} =
reduce { "$a\n$b" } @tr if @tr;
}