Simple dateTime integration
This commit is contained in:
parent
4dd79eb018
commit
364190dc7b
|
@ -189,6 +189,18 @@ const SquiggleItem: React.FC<SquiggleItemProps> = ({
|
||||||
{expression.value.map((r) => `"${r}"`).join(", ")}
|
{expression.value.map((r) => `"${r}"`).join(", ")}
|
||||||
</VariableBox>
|
</VariableBox>
|
||||||
);
|
);
|
||||||
|
case "date":
|
||||||
|
return (
|
||||||
|
<VariableBox heading="Date" showTypes={showTypes}>
|
||||||
|
{expression.value.toString()}
|
||||||
|
</VariableBox>
|
||||||
|
);
|
||||||
|
case "timeDuration":
|
||||||
|
return (
|
||||||
|
<VariableBox heading="Time Duration" showTypes={showTypes}>
|
||||||
|
<NumberShower precision={3} number={expression.value} />
|
||||||
|
</VariableBox>
|
||||||
|
);
|
||||||
case "lambda":
|
case "lambda":
|
||||||
return (
|
return (
|
||||||
<FunctionChart
|
<FunctionChart
|
||||||
|
|
|
@ -181,5 +181,9 @@ function createTsExport(
|
||||||
return tag("string", x.value);
|
return tag("string", x.value);
|
||||||
case "EvSymbol":
|
case "EvSymbol":
|
||||||
return tag("symbol", x.value);
|
return tag("symbol", x.value);
|
||||||
|
case "EvDate":
|
||||||
|
return tag("date", x.value);
|
||||||
|
case "EvTimeDuration":
|
||||||
|
return tag("timeDuration", x.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,6 +55,14 @@ export type rescriptExport =
|
||||||
| {
|
| {
|
||||||
TAG: 9; // EvSymbol
|
TAG: 9; // EvSymbol
|
||||||
_0: string;
|
_0: string;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
TAG: 10; // EvDate
|
||||||
|
_0: Date;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
TAG: 11; // EvTimeDuration
|
||||||
|
_0: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
type rescriptDist =
|
type rescriptDist =
|
||||||
|
@ -86,7 +94,9 @@ export type squiggleExpression =
|
||||||
| tagged<"boolean", boolean>
|
| tagged<"boolean", boolean>
|
||||||
| tagged<"distribution", Distribution>
|
| tagged<"distribution", Distribution>
|
||||||
| tagged<"number", number>
|
| tagged<"number", number>
|
||||||
| tagged<"record", { [key: string]: squiggleExpression }>;
|
| tagged<"date", Date>
|
||||||
|
| tagged<"timeDuration", number>
|
||||||
|
| tagged<"record", { [key: string]: squiggleExpression }>
|
||||||
|
|
||||||
export { lambdaValue };
|
export { lambdaValue };
|
||||||
|
|
||||||
|
@ -127,6 +137,10 @@ export function convertRawToTypescript(
|
||||||
return tag("string", result._0);
|
return tag("string", result._0);
|
||||||
case 9: // EvSymbol
|
case 9: // EvSymbol
|
||||||
return tag("symbol", result._0);
|
return tag("symbol", result._0);
|
||||||
|
case 10: // EvDate
|
||||||
|
return tag("date", result._0);
|
||||||
|
case 11: // EvTimeDuration
|
||||||
|
return tag("number", result._0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,62 @@
|
||||||
|
module ExpressionValue = ReducerInterface_ExpressionValue
|
||||||
|
type expressionValue = ExpressionValue.expressionValue
|
||||||
|
|
||||||
|
let dateDispatch = (call: ExpressionValue.functionCall, env: DistributionOperation.env): option<
|
||||||
|
result<expressionValue, QuriSquiggleLang.Reducer_ErrorValue.errorValue>,
|
||||||
|
> => {
|
||||||
|
switch call {
|
||||||
|
| ("toString", [EvDate(t)]) => EvString(E.Date.toString(t))->Ok->Some
|
||||||
|
| ("makeDateFromYear", [EvNumber(year)]) =>
|
||||||
|
EvDate(E.Date.makeWithYM(~year, ~month=0.0, ()))->Ok->Some
|
||||||
|
| ("fromMilliseconds", [EvNumber(f)]) => EvDate(E.Date.fromFloat(f))->Ok->Some
|
||||||
|
| ("toMilliseconds", [EvDate(f)]) => EvNumber(E.Date.toFloat(f))->Ok->Some
|
||||||
|
| ("subtract", [EvDate(d1), EvDate(d2)]) =>
|
||||||
|
switch E.Date.subtract(d1, d2) {
|
||||||
|
| Ok(d) => EvTimeDuration(d)->Ok
|
||||||
|
| Error(e) => Error(RETodo(e))
|
||||||
|
}->Some
|
||||||
|
| ("subtract", [EvDate(d1), EvTimeDuration(d2)]) =>
|
||||||
|
EvDate(E.Date.subtractDuration(d1, d2))->Ok->Some
|
||||||
|
| ("add", [EvDate(d1), EvTimeDuration(d2)]) => EvDate(E.Date.addDuration(d1, d2))->Ok->Some
|
||||||
|
| _ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let durationDispatch = (call: ExpressionValue.functionCall, env: DistributionOperation.env): option<
|
||||||
|
result<expressionValue, QuriSquiggleLang.Reducer_ErrorValue.errorValue>,
|
||||||
|
> => {
|
||||||
|
switch call {
|
||||||
|
| ("toString", [EvTimeDuration(t)]) => EvString(E.Duration.toString(t))->Ok->Some
|
||||||
|
| ("hours", [EvNumber(f)]) => EvTimeDuration(E.Duration.fromHours(f))->Ok->Some
|
||||||
|
| ("years", [EvNumber(f)]) => EvTimeDuration(E.Duration.fromYears(f))->Ok->Some
|
||||||
|
| ("toHours", [EvTimeDuration(f)]) => EvNumber(E.Duration.toHours(f))->Ok->Some
|
||||||
|
| ("toYears", [EvTimeDuration(f)]) => EvNumber(E.Duration.toYears(f))->Ok->Some
|
||||||
|
| (
|
||||||
|
("add" | "subtract" | "multiply" | "divide") as op,
|
||||||
|
[EvTimeDuration(d1), EvTimeDuration(d2)],
|
||||||
|
) => {
|
||||||
|
let op = switch op {
|
||||||
|
| "subtract" => E.Duration.subtract
|
||||||
|
| "multiply" => E.Duration.multiply
|
||||||
|
| "divide" => E.Duration.divide
|
||||||
|
| "add"
|
||||||
|
| _ => E.Duration.add
|
||||||
|
}
|
||||||
|
EvTimeDuration(op(d1, d2))->Ok->Some
|
||||||
|
}
|
||||||
|
| _ => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let dispatch = (call: ExpressionValue.functionCall, env: DistributionOperation.env): option<
|
||||||
|
result<expressionValue, QuriSquiggleLang.Reducer_ErrorValue.errorValue>,
|
||||||
|
> => {
|
||||||
|
switch dateDispatch(call, env) {
|
||||||
|
| Some(r) => Some(r)
|
||||||
|
| None =>
|
||||||
|
switch durationDispatch(call, env) {
|
||||||
|
| Some(r) => Some(r)
|
||||||
|
| None => None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,6 +20,8 @@ type rec expressionValue =
|
||||||
| EvRecord(record)
|
| EvRecord(record)
|
||||||
| EvString(string)
|
| EvString(string)
|
||||||
| EvSymbol(string)
|
| EvSymbol(string)
|
||||||
|
| EvDate(Js.Date.t)
|
||||||
|
| EvTimeDuration(float)
|
||||||
and record = Js.Dict.t<expressionValue>
|
and record = Js.Dict.t<expressionValue>
|
||||||
and externalBindings = record
|
and externalBindings = record
|
||||||
and lambdaValue = {
|
and lambdaValue = {
|
||||||
|
@ -51,6 +53,8 @@ let rec toString = aValue =>
|
||||||
| EvSymbol(aString) => `:${aString}`
|
| EvSymbol(aString) => `:${aString}`
|
||||||
| EvRecord(aRecord) => aRecord->toStringRecord
|
| EvRecord(aRecord) => aRecord->toStringRecord
|
||||||
| EvDistribution(dist) => GenericDist.toString(dist)
|
| EvDistribution(dist) => GenericDist.toString(dist)
|
||||||
|
| EvDate(date) => E.Date.toString(date)
|
||||||
|
| EvTimeDuration(t) => E.Duration.toString(t)
|
||||||
}
|
}
|
||||||
and toStringRecord = aRecord => {
|
and toStringRecord = aRecord => {
|
||||||
let pairs =
|
let pairs =
|
||||||
|
@ -73,6 +77,8 @@ let toStringWithType = aValue =>
|
||||||
| EvRecord(_) => `Record::${toString(aValue)}`
|
| EvRecord(_) => `Record::${toString(aValue)}`
|
||||||
| EvString(_) => `String::${toString(aValue)}`
|
| EvString(_) => `String::${toString(aValue)}`
|
||||||
| EvSymbol(_) => `Symbol::${toString(aValue)}`
|
| EvSymbol(_) => `Symbol::${toString(aValue)}`
|
||||||
|
| EvDate(_) => `Date::${toString(aValue)}`
|
||||||
|
| EvTimeDuration(_) => `Date::${toString(aValue)}`
|
||||||
}
|
}
|
||||||
|
|
||||||
let argsToString = (args: array<expressionValue>): string => {
|
let argsToString = (args: array<expressionValue>): string => {
|
||||||
|
@ -116,6 +122,8 @@ type expressionValueType =
|
||||||
| EvtRecord
|
| EvtRecord
|
||||||
| EvtString
|
| EvtString
|
||||||
| EvtSymbol
|
| EvtSymbol
|
||||||
|
| EvtDate
|
||||||
|
| EvtTimeDuration
|
||||||
|
|
||||||
type functionCallSignature = CallSignature(string, array<expressionValueType>)
|
type functionCallSignature = CallSignature(string, array<expressionValueType>)
|
||||||
type functionDefinitionSignature =
|
type functionDefinitionSignature =
|
||||||
|
@ -133,6 +141,8 @@ let valueToValueType = value =>
|
||||||
| EvRecord(_) => EvtRecord
|
| EvRecord(_) => EvtRecord
|
||||||
| EvString(_) => EvtArray
|
| EvString(_) => EvtArray
|
||||||
| EvSymbol(_) => EvtSymbol
|
| EvSymbol(_) => EvtSymbol
|
||||||
|
| EvDate(_) => EvtDate
|
||||||
|
| EvTimeDuration(_) => EvtTimeDuration
|
||||||
}
|
}
|
||||||
|
|
||||||
let functionCallToCallSignature = (functionCall: functionCall): functionCallSignature => {
|
let functionCallToCallSignature = (functionCall: functionCall): functionCallSignature => {
|
||||||
|
@ -152,6 +162,8 @@ let valueTypeToString = (valueType: expressionValueType): string =>
|
||||||
| EvtRecord => `Record`
|
| EvtRecord => `Record`
|
||||||
| EvtString => `String`
|
| EvtString => `String`
|
||||||
| EvtSymbol => `Symbol`
|
| EvtSymbol => `Symbol`
|
||||||
|
| EvtDate => `Date`
|
||||||
|
| EvtTimeDuration => `Duration`
|
||||||
}
|
}
|
||||||
|
|
||||||
let functionCallSignatureToString = (functionCallSignature: functionCallSignature): string => {
|
let functionCallSignatureToString = (functionCallSignature: functionCallSignature): string => {
|
||||||
|
|
|
@ -18,9 +18,11 @@ let dispatch = (call: ExpressionValue.functionCall, environment, chain): result<
|
||||||
expressionValue,
|
expressionValue,
|
||||||
'e,
|
'e,
|
||||||
> =>
|
> =>
|
||||||
ReducerInterface_GenericDistribution.dispatch(call, environment) |> E.O.default(
|
switch ReducerInterface_GenericDistribution.dispatch(call, environment) {
|
||||||
chain(call, environment),
|
| Some(r) => r
|
||||||
)
|
| None =>
|
||||||
|
ReducerInterface_DateTime.dispatch(call, environment) |> E.O.default(chain(call, environment))
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
If your dispatch is too big you can divide it into smaller dispatches and pass the call so that it gets called finally.
|
If your dispatch is too big you can divide it into smaller dispatches and pass the call so that it gets called finally.
|
||||||
|
|
||||||
|
|
|
@ -833,3 +833,46 @@ module JsArray = {
|
||||||
|> Js.Array.map(O.toExn("Warning: This should not have happened"))
|
|> Js.Array.map(O.toExn("Warning: This should not have happened"))
|
||||||
let filter = Js.Array.filter
|
let filter = Js.Array.filter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module Duration = {
|
||||||
|
//Stores in Unix milliseconds
|
||||||
|
type t = float
|
||||||
|
let minute = Belt.Float.fromInt(60 * 1000)
|
||||||
|
let hour = Belt.Float.fromInt(60 * 60 * 1000)
|
||||||
|
let day = Belt.Float.fromInt(24 * 60 * 60 * 1000)
|
||||||
|
let year = Belt.Float.fromInt(24 * 60 * 60 * 1000 * 365)
|
||||||
|
let fromFloat = (f: float): t => f
|
||||||
|
let toFloat = (d: t): float => d
|
||||||
|
let fromHours = (h: float): t => h *. hour
|
||||||
|
let fromDays = (d: float): t => d *. day
|
||||||
|
let fromYears = (y: float): t => y *. year
|
||||||
|
let toHours = (t: t): float => t /. hour
|
||||||
|
let toDays = (t: t): float => t /. day
|
||||||
|
let toYears = (t: t): float => t /. year
|
||||||
|
let toString = (t: t) => `${Float.with2DigitsPrecision(t)}ms`
|
||||||
|
let add = (t1, t2): t => t1 +. t2
|
||||||
|
let subtract = (t1, t2): t => t1 -. t2
|
||||||
|
let multiply = (t1, t2): t => t1 *. t2
|
||||||
|
let divide = (t1, t2): t => t1 /. t2
|
||||||
|
}
|
||||||
|
|
||||||
|
module Date = {
|
||||||
|
type t = Js.Date.t
|
||||||
|
type year
|
||||||
|
let makeWithYM = Js.Date.makeWithYM
|
||||||
|
let toString = Js.Date.toString
|
||||||
|
let fromFloat = Js.Date.fromFloat
|
||||||
|
let toFloat = Js.Date.getTime
|
||||||
|
let fmap = (t: t, fn: float => float) => t->toFloat->fn->fromFloat
|
||||||
|
let subtract = (t1: t, t2: t) => {
|
||||||
|
let (f1, f2) = (toFloat(t1), toFloat(t2))
|
||||||
|
let diff = f1 -. f2
|
||||||
|
if diff < 0.0 {
|
||||||
|
Error("Cannot subtract a date by one that is in its future")
|
||||||
|
} else {
|
||||||
|
Ok(Duration.fromFloat(diff))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let addDuration = (t: t, duration: Duration.t) => fmap(t, t => t +. duration)
|
||||||
|
let subtractDuration = (t: t, duration: Duration.t) => fmap(t, t => t -. duration)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user