From a15c0fa88878231efe13b1551c51967b38dc5a06 Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Mon, 6 Jun 2022 13:55:51 -0700 Subject: [PATCH] Added simple scientific units --- .../Reducer_Peggy_GeneratedParser.peggy | 5 ++- .../ReducerInterface_DateTime.res | 35 +++++++++++++++++++ 2 files changed, 39 insertions(+), 1 deletion(-) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy index 61016ca9..8c853ff4 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy @@ -264,6 +264,9 @@ basicLiteral identifier 'identifier' = ([_a-z]+[_a-z0-9]i*) {return nodeIdentifier(text())} +unitIdentifier 'identifier' + = ([_a-zA-Z]+[_a-z0-9]i*) {return nodeIdentifier(text())} + dollarIdentifier '$identifier' = ([\$_a-z]+[\$_a-z0-9]i*) {return nodeIdentifier(text())} @@ -271,7 +274,7 @@ string 'string' = characters:("'" @([^'])* "'") {return nodeString(characters.join(''))} / characters:('"' @([^"])* '"') {return nodeString(characters.join(''))} -number = number:(float / integer) unit:identifier? +number = number:(float / integer) unit:unitIdentifier? { if (unit === null) { return number } diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_DateTime.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_DateTime.res index fe30b0f8..334bee6c 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_DateTime.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_DateTime.res @@ -26,10 +26,45 @@ let dateDispatch = (call: EV.functionCall, _: DistributionOperation.env): option } } +module ScientificUnit = { + let nameToMultiplier = str => + switch str { + | "n" => Some(1E-9) + | "m" => Some(1E-3) + | "k" => Some(1E3) + | "M" => Some(1E6) + | "B" => Some(1E9) + | "G" => Some(1E9) + | "T" => Some(1E12) + | "P" => Some(1E15) + | _ => None + } + + let getMultiplier = (r: string) => { + let match = Js.String2.match_(r, %re(`/fromUnit_([_a-zA-Z]*)/`)) + switch match { + | Some([_, unit]) => nameToMultiplier(unit) + | _ => None + } + } +} + let durationDispatch = (call: EV.functionCall, _: DistributionOperation.env): option< result, > => { switch call { + | ( + ("fromUnit_n" + | "fromUnit_m" + | "fromUnit_k" + | "fromUnit_M" + | "fromUnit_B" + | "fromUnit_G" + | "fromUnit_T" + | "fromUnit_P") as op, + [EvNumber(f)], + ) => + op->ScientificUnit.getMultiplier->E.O2.fmap(multiplier => EV.EvNumber(f *. multiplier)->Ok) | ("toString", [EvTimeDuration(t)]) => EV.EvString(DateTime.Duration.toString(t))->Ok->Some | ("minutes", [EvNumber(f)]) => EV.EvTimeDuration(DateTime.Duration.fromMinutes(f))->Ok->Some | ("fromUnit_minutes", [EvNumber(f)]) =>