use strict;
use warnings;
our %formula_per_k;
our $braces_re;
INIT {
\{
(?:
(?> [^{}]+ )
|
(??{ $braces_re })
)*
\}
}sx;
# List all functions that you want to allow in formulas. All other words will be interpretted as variables.
# Load the data via a file.
my $data = do {local $/; <DATA>};
# Parse K blocks
( (?: [^{}]+ | (??{ $braces_re }) )* ) # Matched braces only.
\}
}mgx) {
my ($name, $params) = ($1, $2);
# Parse LOL block
( (?: [^{}]+ | (??{ $braces_re }) )*? ) # Matched braces only.
\}
}mx;
my $lol = $1;
# Start building anonymous subroutine
my $conditions = '';
# Parse Conditions and Formulas
}gx) {
my ($cond, $formula) = ($1, $2);
# Remove Excess spacing and translate variable into perl scalar.
for ($cond, $formula) {
s/^\s+|\s+$//g;
my $var = $1;
$var = "\$hashref->{$var}" if ! grep {$var eq $_} @FORMULA_FUNCS; $var
}eg;
}
$conditions .= "return $formula if $cond; ";
}
my $code = "sub {my \$hashref = shift; ${conditions} return; }";
if ($@) {
die "Invalid formulas in $name: $@"; }
$formula_per_k{$name} = $sub;
}
}
sub formula_per_k {
my ($k, $vars) = @_;
die "Unrecognized K value '$k'" if ! exists $formula_per_k{$k};
return $formula_per_k{$k}($vars); }
print "'K1', {d => .1} = " . formula_per_k
('K1', {d
=> .1
}) . "\n"; print "'K1', {d => .05} = " . formula_per_k
('K1', {d
=> .05
}) . "\n"; print "'K3', {d => .02} = " . formula_per_k
('K3', {d
=> .02
}) . "\n"; print "'K3', {d => .021} = " . formula_per_k
('K3', {d
=> .021
}) . "\n";
__DATA__
... #OTHER STUFFS
K K1 {
LOL {
COND { d < 0.01 }
FORMULA
{ -0.2 + 3.3*sqrt(d
) } COND { d >= 0.01 }
FORMULA
{ -0.2 + 3.3*sqrt(d
+0.4) } }
}
... #OTHER STUFFS
K K2 {
LOL {
COND { d < 0.03 }
FORMULA
{ -2.2 + 1.3*sqrt(d
) } COND { d >= 0.03 }
FORMULA
{ -2.2 + 1.3*sqrt(d
+0.8) } }
}
... #OTHER STUFFS
K K3 {
LOL {
COND { d < 0.02 }
FORMULA
{ -4.3 + 0.3*sqrt(d
) } COND { d >= 0.02 }
FORMULA
{ -4.3 + 0.3*sqrt(d
+0.3) } }
}
... #OTHER STUFF
dXNlIHN0cmljdDsKdXNlIHdhcm5pbmdzOwoKb3VyICVmb3JtdWxhX3Blcl9rOwpvdXIgJGJyYWNlc19yZTsKSU5JVCB7CiAgICAkYnJhY2VzX3JlID0gcXJ7CiAgICAgICAgXHsKICAgICAgICAoPzoKICAgICAgICAgICAgKD8+IFtee31dKyApCiAgICAgICAgfAogICAgICAgICAgICAoPz97ICRicmFjZXNfcmUgfSkKICAgICAgICApKgogICAgICAgIFx9CiAgICB9c3g7CgogICAgIyBMaXN0IGFsbCBmdW5jdGlvbnMgdGhhdCB5b3Ugd2FudCB0byBhbGxvdyBpbiBmb3JtdWxhcy4gIEFsbCBvdGhlciB3b3JkcyB3aWxsIGJlIGludGVycHJldHRlZCBhcyB2YXJpYWJsZXMuCiAgICBteSBARk9STVVMQV9GVU5DUyA9IHF3KHNxcnQgZXhwIGxvZyk7CgogICAgIyBMb2FkIHRoZSBkYXRhIHZpYSBhIGZpbGUuCiAgICBteSAkZGF0YSA9IGRvIHtsb2NhbCAkLzsgPERBVEE+fTsKCiAgICAjIFBhcnNlIEsgYmxvY2tzCiAgICB3aGlsZSAoJGRhdGEgPX4gbXsKICAgICAgICBeSyBccysgKFx3KykgXHMqIFx7CiAgICAgICAgICAgICggKD86IFtee31dKyB8ICg/P3sgJGJyYWNlc19yZSB9KSApKiApICAgICAgICAgIyBNYXRjaGVkIGJyYWNlcyBvbmx5LgogICAgICAgIFx9CiAgICB9bWd4KSB7CiAgICAgICAgbXkgKCRuYW1lLCAkcGFyYW1zKSA9ICgkMSwgJDIpOwoKICAgICAgICAjIFBhcnNlIExPTCBibG9jawogICAgICAgIG5leHQgaWYgJHBhcmFtcyAhfiBtewogICAgICAgICAgICBMT0wgXHMqIFx7IAogICAgICAgICAgICAgICAgKCAoPzogW157fV0rIHwgKD8/eyAkYnJhY2VzX3JlIH0pICkqPyApICAgICMgTWF0Y2hlZCBicmFjZXMgb25seS4KICAgICAgICAgICAgXH0KICAgICAgICB9bXg7CiAgICAgICAgbXkgJGxvbCA9ICQxOwoKICAgICAgICAjIFN0YXJ0IGJ1aWxkaW5nIGFub255bW91cyBzdWJyb3V0aW5lCiAgICAgICAgbXkgJGNvbmRpdGlvbnMgPSAnJzsKCiAgICAgICAgIyBQYXJzZSBDb25kaXRpb25zIGFuZCBGb3JtdWxhcwogICAgICAgIHdoaWxlICgkbG9sID1+IG17CiAgICAgICAgICAgIENPTkQgXHMqIFx7ICguKj8pIFx9IFxzKiAKICAgICAgICAgICAgRk9STVVMQSBccyogXHsgKC4qPykgXH0KICAgICAgICB9Z3gpIHsKICAgICAgICAgICAgbXkgKCRjb25kLCAkZm9ybXVsYSkgPSAoJDEsICQyKTsKCiAgICAgICAgICAgICMgUmVtb3ZlIEV4Y2VzcyBzcGFjaW5nIGFuZCB0cmFuc2xhdGUgdmFyaWFibGUgaW50byBwZXJsIHNjYWxhci4KICAgICAgICAgICAgZm9yICgkY29uZCwgJGZvcm11bGEpIHsKICAgICAgICAgICAgICAgIHMvXlxzK3xccyskLy9nOwogICAgICAgICAgICAgICAgc3soW2EtekEtWl0rKX17CiAgICAgICAgICAgICAgICAgICAgbXkgJHZhciA9ICQxOwogICAgICAgICAgICAgICAgICAgICR2YXIgPSAiXCRoYXNocmVmLT57JHZhcn0iIGlmICEgZ3JlcCB7JHZhciBlcSAkX30gQEZPUk1VTEFfRlVOQ1M7CiAgICAgICAgICAgICAgICAgICAgJHZhcgogICAgICAgICAgICAgICAgfWVnOwogICAgICAgICAgICB9CgogICAgICAgICAgICAkY29uZGl0aW9ucyAuPSAicmV0dXJuICRmb3JtdWxhIGlmICRjb25kOyAiOwogICAgICAgIH0KCiAgICAgICAgbXkgJGNvZGUgPSAic3ViIHtteSBcJGhhc2hyZWYgPSBzaGlmdDsgJHtjb25kaXRpb25zfSByZXR1cm47IH0iOwoKICAgICAgICBteSAkc3ViID0gZXZhbCAkY29kZTsKICAgICAgICBpZiAoJEApIHsKICAgICAgICAgICAgZGllICJJbnZhbGlkIGZvcm11bGFzIGluICRuYW1lOiAkQCI7CiAgICAgICAgfQoKICAgICAgICAkZm9ybXVsYV9wZXJfa3skbmFtZX0gPSAkc3ViOwogICAgfQp9CgpzdWIgZm9ybXVsYV9wZXJfayB7CiAgICBteSAoJGssICR2YXJzKSA9IEBfOwoKICAgIGRpZSAiVW5yZWNvZ25pemVkIEsgdmFsdWUgJyRrJyIgaWYgISBleGlzdHMgJGZvcm11bGFfcGVyX2t7JGt9OwoKICAgIHJldHVybiAkZm9ybXVsYV9wZXJfa3ska30oJHZhcnMpOwp9CgpwcmludCAiJ0sxJywge2QgPT4gLjF9ICAgPSAiIC4gZm9ybXVsYV9wZXJfaygnSzEnLCB7ZCA9PiAuMX0pIC4gIlxuIjsKcHJpbnQgIidLMScsIHtkID0+IC4wNX0gID0gIiAuIGZvcm11bGFfcGVyX2soJ0sxJywge2QgPT4gLjA1fSkgLiAiXG4iOwpwcmludCAiJ0szJywge2QgPT4gLjAyfSAgPSAiIC4gZm9ybXVsYV9wZXJfaygnSzMnLCB7ZCA9PiAuMDJ9KSAuICJcbiI7CnByaW50ICInSzMnLCB7ZCA9PiAuMDIxfSA9ICIgLiBmb3JtdWxhX3Blcl9rKCdLMycsIHtkID0+IC4wMjF9KSAuICJcbiI7CgoKX19EQVRBX18KLi4uICNPVEhFUiBTVFVGRlMKSyBLMSB7CiAgICBMT0wgewogICAgICAgIENPTkQgeyBkIDwgMC4wMSB9CiAgICAgICAgRk9STVVMQSB7IC0wLjIgKyAzLjMqc3FydChkKSB9CiAgICAgICAgQ09ORCB7IGQgPj0gMC4wMSB9CiAgICAgICAgRk9STVVMQSB7IC0wLjIgKyAzLjMqc3FydChkKzAuNCkgfQogICAgfQp9Ci4uLiAjT1RIRVIgU1RVRkZTCksgSzIgewogICAgTE9MIHsKICAgICAgICBDT05EIHsgZCA8IDAuMDMgfQogICAgICAgIEZPUk1VTEEgeyAtMi4yICsgMS4zKnNxcnQoZCkgfQogICAgICAgIENPTkQgeyBkID49IDAuMDMgfQogICAgICAgIEZPUk1VTEEgeyAtMi4yICsgMS4zKnNxcnQoZCswLjgpIH0KICAgIH0KfQouLi4gI09USEVSIFNUVUZGUwpLIEszIHsKICAgIExPTCB7CiAgICAgICAgQ09ORCB7IGQgPCAwLjAyIH0KICAgICAgICBGT1JNVUxBIHsgLTQuMyArIDAuMypzcXJ0KGQpIH0KICAgICAgICBDT05EIHsgZCA+PSAwLjAyIH0KICAgICAgICBGT1JNVUxBIHsgLTQuMyArIDAuMypzcXJ0KGQrMC4zKSB9CiAgICB9Cn0KLi4uICNPVEhFUiBTVFVGRg==