-
-
Save ShimmerFairy/30a3d44da2af9254eda1 to your computer and use it in GitHub Desktop.
First try at a slang
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sub EXPORT(|) { | |
enum Dimensions « Meter Kilogram Second Ampere Kelvin Mole Candela »; | |
class Unit { | |
has $.magnitude; | |
has Dimensions $.dimension; | |
} | |
my %prefixes := {Y => 24, | |
Z => 21, | |
E => 18, | |
P => 15, | |
T => 12, | |
G => 9, | |
M => 6, | |
k => 3, | |
h => 2, | |
da => 1, | |
d => -1, | |
c => -2, | |
m => -3, | |
μ => -6, | |
n => -9, | |
p => -12, | |
f => -15, | |
a => -18, | |
z => -21, | |
y => -24}; | |
sub unprefix($amt, $pfx) { | |
$amt * 10 ** (%prefixes{$pfx}) | |
} | |
role SI::Grammar { | |
token postfix:<SI_unit> { | |
[ <SI_base> | <SI_prefix> <SI_base> ] | |
<O('%methodcall')> | |
} | |
token SI_base { < m g s A K mol cd > } | |
token SI_prefix { < Y Z E P T G M k h da d c m μ n p f a z y > } | |
method arg_flat_nok(|c) { | |
say c.map: *.Str; | |
nextsame; | |
} | |
} | |
role SI::Actions { | |
method SI_base($/) { | |
given ~$/ { | |
when 'm' { make Dimensions::Meter } | |
when 'g' { make Dimensions::Kilogram } | |
when 's' { make Dimensions::Second } | |
when 'A' { make Dimensions::Ampere } | |
when 'K' { make Dimensions::Kelvin } | |
when 'mol' { make Dimensions::Mole } | |
when 'cd' { make Dimensions::Candela } | |
} | |
} | |
method postfix:<SI_unit>($/) { | |
my $qast; | |
if $<SI_prefix> { | |
$qast := QAST::Op.new( | |
:op<call>, | |
:name<&unprefix>, | |
$*W.add_string_constant(~$<SI_prefix>)); | |
} | |
$qast := QAST::Op.new( | |
:op<callmethod>, | |
:name<new>, | |
Unit, | |
dimension => $<SI_base>.ast, | |
magnitude => $<SI_base>.ast eqv Dimensions::Kilogram | |
?? QAST::Op.new( | |
:op<call>, | |
:name('&infix:</>'), | |
$qast, | |
1000) | |
!! $qast); | |
make $qast; | |
} | |
} | |
nqp::bindkey(%*LANG, 'MAIN', nqp::atkey(%*LANG, 'MAIN').HOW.mixin(nqp::atkey(%*LANG, 'MAIN'), SI::Grammar)); | |
nqp::bindkey(%*LANG, 'MAIN-actions', nqp::atkey(%*LANG, 'MAIN-actions').HOW.mixin(nqp::atkey(%*LANG, 'MAIN'), SI::Actions)); | |
{} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment