use strict;
use warnings;
our %formula_per_k;
INIT {
my $braces_re;
(?:
(?> [^{}]+ )
|
\{ (??{ $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
while ( $data =~ m{ ^K \
s+ (\w+) \
s* \
{ ( $braces_re ) \
} }mgx
) { my ( $name, $params ) = ( $1, $2 );
# Parse LOL block
next if $params !~ m{ LOL \
s* \
{ ( $braces_re ) \
} }mx
; my $lol = $1;
# Start building anonymous subroutine
my $conditions = '';
# Parse Conditions and Formulas
while (
}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
dXNlIHN0cmljdDsKdXNlIHdhcm5pbmdzOwoKb3VyICVmb3JtdWxhX3Blcl9rOwpJTklUIHsKICAgIG15ICRicmFjZXNfcmU7CiAgICAkYnJhY2VzX3JlID0gcXJ7CiAgICAgICAgKD86CiAgICAgICAgICAgICg/PiBbXnt9XSsgKQogICAgICAgIHwKICAgICAgICAgICAgXHsgKD8/eyAkYnJhY2VzX3JlIH0pIFx9CiAgICAgICAgKSoKICAgIH1zeDsKCiAgICAjIExpc3QgYWxsIGZ1bmN0aW9ucyB0aGF0IHlvdSB3YW50IHRvIGFsbG93IGluIGZvcm11bGFzLiAgQWxsIG90aGVyIHdvcmRzIHdpbGwgYmUgaW50ZXJwcmV0dGVkIGFzIHZhcmlhYmxlcy4KICAgIG15IEBGT1JNVUxBX0ZVTkNTID0gcXcoc3FydCBleHAgbG9nKTsKCiAgICAjIExvYWQgdGhlIGRhdGEgdmlhIGEgZmlsZS4KICAgIG15ICRkYXRhID0gZG8geyBsb2NhbCAkLzsgPERBVEE+IH07CgogICAgIyBQYXJzZSBLIGJsb2NrcwogICAgd2hpbGUgKCAkZGF0YSA9fiBteyBeSyBccysgKFx3KykgXHMqIFx7ICggJGJyYWNlc19yZSApIFx9IH1tZ3ggKSB7CiAgICAgICAgbXkgKCAkbmFtZSwgJHBhcmFtcyApID0gKCAkMSwgJDIgKTsKCiAgICAgICAgIyBQYXJzZSBMT0wgYmxvY2sKICAgICAgICBuZXh0IGlmICRwYXJhbXMgIX4gbXsgTE9MIFxzKiBceyAoICRicmFjZXNfcmUgKSBcfSB9bXg7CiAgICAgICAgbXkgJGxvbCA9ICQxOwoKICAgICAgICAjIFN0YXJ0IGJ1aWxkaW5nIGFub255bW91cyBzdWJyb3V0aW5lCiAgICAgICAgbXkgJGNvbmRpdGlvbnMgPSAnJzsKCiAgICAgICAgIyBQYXJzZSBDb25kaXRpb25zIGFuZCBGb3JtdWxhcwogICAgICAgIHdoaWxlICgKICAgICAgICAgICAgJGxvbCA9fiBtewogICAgICAgICAgICAgICAgICAgIENPTkQgXHMqIFx7ICguKj8pIFx9IFxzKiAKICAgICAgICAgICAgICAgICAgICBGT1JNVUxBIFxzKiBceyAoLio/KSBcfQogICAgICAgICAgICAgICAgfWd4CiAgICAgICAgICAgICkKICAgICAgICB7CiAgICAgICAgICAgIG15ICggJGNvbmQsICRmb3JtdWxhICkgPSAoICQxLCAkMiApOwoKICAgICAgICAgICAgIyBSZW1vdmUgRXhjZXNzIHNwYWNpbmcgYW5kIHRyYW5zbGF0ZSB2YXJpYWJsZSBpbnRvIHBlcmwgc2NhbGFyLgogICAgICAgICAgICBmb3IgKCAkY29uZCwgJGZvcm11bGEgKSB7CiAgICAgICAgICAgICAgICBzL15ccyt8XHMrJC8vZzsKICAgICAgICAgICAgICAgIHN7KFthLXpBLVpdKyl9ewogICAgICAgICAgICAgICAgICAgIG15ICR2YXIgPSAkMTsKICAgICAgICAgICAgICAgICAgICAkdmFyID0gIlwkaGFzaHJlZi0+eyR2YXJ9IiBpZiAhIGdyZXAgeyR2YXIgZXEgJF99IEBGT1JNVUxBX0ZVTkNTOwogICAgICAgICAgICAgICAgICAgICR2YXIKICAgICAgICAgICAgICAgIH1lZzsKICAgICAgICAgICAgfQoKICAgICAgICAgICAgJGNvbmRpdGlvbnMgLj0gInJldHVybiAkZm9ybXVsYSBpZiAkY29uZDsgIjsKICAgICAgICB9CgogICAgICAgIG15ICRjb2RlID0gInN1YiB7bXkgXCRoYXNocmVmID0gc2hpZnQ7ICR7Y29uZGl0aW9uc30gcmV0dXJuOyB9IjsKCiAgICAgICAgbXkgJHN1YiA9IGV2YWwgJGNvZGU7CiAgICAgICAgaWYgKCRAKSB7CiAgICAgICAgICAgIGRpZSAiSW52YWxpZCBmb3JtdWxhcyBpbiAkbmFtZTogJEAiOwogICAgICAgIH0KCiAgICAgICAgJGZvcm11bGFfcGVyX2t7JG5hbWV9ID0gJHN1YjsKICAgIH0KfQoKc3ViIGZvcm11bGFfcGVyX2sgewogICAgbXkgKCAkaywgJHZhcnMgKSA9IEBfOwoKICAgIGRpZSAiVW5yZWNvZ25pemVkIEsgdmFsdWUgJyRrJyIgaWYgIWV4aXN0cyAkZm9ybXVsYV9wZXJfa3ska307CgogICAgcmV0dXJuICRmb3JtdWxhX3Blcl9reyRrfSgkdmFycyk7Cn0KCnByaW50ICInSzEnLCB7ZCA9PiAuMX0gICA9ICIgLiBmb3JtdWxhX3Blcl9rKCAnSzEnLCB7IGQgPT4gLjEgfSApIC4gIlxuIjsKcHJpbnQgIidLMScsIHtkID0+IC4wNX0gID0gIiAuIGZvcm11bGFfcGVyX2soICdLMScsIHsgZCA9PiAuMDUgfSApIC4gIlxuIjsKcHJpbnQgIidLMycsIHtkID0+IC4wMn0gID0gIiAuIGZvcm11bGFfcGVyX2soICdLMycsIHsgZCA9PiAuMDIgfSApIC4gIlxuIjsKcHJpbnQgIidLMycsIHtkID0+IC4wMjF9ID0gIiAuIGZvcm11bGFfcGVyX2soICdLMycsIHsgZCA9PiAuMDIxIH0gKSAuICJcbiI7CgpfX0RBVEFfXwouLi4gI09USEVSIFNUVUZGUwpLIEsxIHsKICAgIExPTCB7CiAgICAgICAgQ09ORCB7IGQgPCAwLjAxIH0KICAgICAgICBGT1JNVUxBIHsgLTAuMiArIDMuMypzcXJ0KGQpIH0KICAgICAgICBDT05EIHsgZCA+PSAwLjAxIH0KICAgICAgICBGT1JNVUxBIHsgLTAuMiArIDMuMypzcXJ0KGQrMC40KSB9CiAgICB9Cn0KLi4uICNPVEhFUiBTVFVGRlMKSyBLMiB7CiAgICBMT0wgewogICAgICAgIENPTkQgeyBkIDwgMC4wMyB9CiAgICAgICAgRk9STVVMQSB7IC0yLjIgKyAxLjMqc3FydChkKSB9CiAgICAgICAgQ09ORCB7IGQgPj0gMC4wMyB9CiAgICAgICAgRk9STVVMQSB7IC0yLjIgKyAxLjMqc3FydChkKzAuOCkgfQogICAgfQp9Ci4uLiAjT1RIRVIgU1RVRkZTCksgSzMgewogICAgTE9MIHsKICAgICAgICBDT05EIHsgZCA8IDAuMDIgfQogICAgICAgIEZPUk1VTEEgeyAtNC4zICsgMC4zKnNxcnQoZCkgfQogICAgICAgIENPTkQgeyBkID49IDAuMDIgfQogICAgICAgIEZPUk1VTEEgeyAtNC4zICsgMC4zKnNxcnQoZCswLjMpIH0KICAgIH0KfQouLi4gI09USEVSIFNUVUZGCg==