use v5.36;
use strict;
-my %names;
-my %vals;
+my %expr;
+my %val;
while (<>) {
chomp;
- my ($name, $rest) = split /:/;
- $names{$name} = $rest;
- $vals{$name} = 0+$rest if $rest =~ /\A\s*\d+\z/;
+ my ($name, $rest) = split /: /;
+ my @ops = split /\s+/, $rest;
+ if (@ops > 1) {
+ $expr{$name} = \@ops;
+ } else {
+ $val{$name} = $ops[0];
+ }
}
-while (!defined $vals{root}) {
- for my $n (keys %names) {
- next if defined $vals{$n};
- my $e = $names{$n};
- my $d = 1;
- for my $v (keys %vals) {
- $e =~ s/$v/$vals{$v}/g;
- }
- next if $e =~ /[a-z]/;
- say "eval $e";
- eval "\$vals{$n} = $e";
- say "set \$vals{$n} to $vals{$n}" unless $@;
+sub walk($var) {
+ return $val{$var} if defined $val{$var};
+ my ($arg1, $op, $arg2) = @{ $expr{$var} };
+ if ($op eq '+') {
+ return $val{$var} = walk($arg1) + walk($arg2);
+ } elsif ($op eq '-') {
+ return $val{$var} = walk($arg1) - walk($arg2);
+ } elsif ($op eq '*') {
+ return $val{$var} = walk($arg1) * walk($arg2);
+ } elsif ($op eq '/') {
+ return $val{$var} = walk($arg1) / walk($arg2);
}
- say " ================= ";
}
-say $vals{root};
+say walk('root');