Skip to content

Instantly share code, notes, and snippets.

@ShimmerFairy
Created December 17, 2015 08:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ShimmerFairy/30a3d44da2af9254eda1 to your computer and use it in GitHub Desktop.
Save ShimmerFairy/30a3d44da2af9254eda1 to your computer and use it in GitHub Desktop.
First try at a slang
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