From 376e272c08fa38b55de01ec5c3ca88a7948a589d Mon Sep 17 00:00:00 2001 From: Conor Barnes Date: Mon, 22 Aug 2022 11:42:21 -0300 Subject: [PATCH 01/55] add offset --- .gitignore | 3 +++ packages/components/src/lib/distributionSpecBuilder.ts | 1 + 2 files changed, 4 insertions(+) diff --git a/.gitignore b/.gitignore index 5b48f91c..c05ec659 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,6 @@ yarn-error.log **/.sync.ffs_db .direnv .log + +.vscode +todo.txt \ No newline at end of file diff --git a/packages/components/src/lib/distributionSpecBuilder.ts b/packages/components/src/lib/distributionSpecBuilder.ts index 2b3ac952..aec730f3 100644 --- a/packages/components/src/lib/distributionSpecBuilder.ts +++ b/packages/components/src/lib/distributionSpecBuilder.ts @@ -239,6 +239,7 @@ export function buildVegaSpec( x: { scale: "xscale", field: "x", + offset: 0.5, }, y: { scale: "yscale", From 90ad0fdbdc6d3f3065f193eb57f7cc08126ecd5c Mon Sep 17 00:00:00 2001 From: Conor Barnes Date: Mon, 22 Aug 2022 12:00:28 -0300 Subject: [PATCH 02/55] announcer for hover values --- .../src/components/DistributionChart.tsx | 2 ++ .../src/lib/distributionSpecBuilder.ts | 34 +++++++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index 79536e12..1bfa64fe 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -47,6 +47,8 @@ export function makePlot(record: { export const DistributionChart: React.FC = (props) => { const { plot, height, showSummary, width, logX, actions = false } = props; + // const [xAxis, setXAxis] = React.useState<"dateAndTime" | "numbers">("dateAndTime") + const [sized] = useSize((size) => { let shapes = flattenResult( plot.distributions.map((x) => diff --git a/packages/components/src/lib/distributionSpecBuilder.ts b/packages/components/src/lib/distributionSpecBuilder.ts index aec730f3..143c10d6 100644 --- a/packages/components/src/lib/distributionSpecBuilder.ts +++ b/packages/components/src/lib/distributionSpecBuilder.ts @@ -91,7 +91,21 @@ export function buildVegaSpec( name: "domain", }, ], - signals: [], + signals: [ + { + "name": "hover", + "value": null, + "on": [ + {"events": "symbol:mouseover", "update": "datum"}, + {"events": "symbol:mouseout", "update": "null"} + ] + }, + { + "name": "announcer", + "value": "", + "update": "hover ? 'Probability: ' + hover.y + ', Value: ' + hover.x : ''" + } + ], scales: [ xScale, expY ? expYScale : linearYScale, @@ -239,7 +253,7 @@ export function buildVegaSpec( x: { scale: "xscale", field: "x", - offset: 0.5, + offset: 0.5, // if this is not included, the circles are slightly left of center. }, y: { scale: "yscale", @@ -256,6 +270,22 @@ export function buildVegaSpec( }, ], }, + { + "type": "text", + "interactive": false, + "encode": { + "enter": { + "x": {"signal": "width", "offset": 1}, + "y": {"value": 0}, + "fill": {"value": "black"}, + "fontSize": {"value": 20}, + "align": {"value": "right"} + }, + "update": { + "text": {"signal": "announcer"} + } + } + } ], legends: [ { From d0468f9ea3f744b31b854ebf1eeab7bfa1f371d2 Mon Sep 17 00:00:00 2001 From: Conor Barnes Date: Tue, 23 Aug 2022 11:05:02 -0300 Subject: [PATCH 03/55] sample points below --- .../src/lib/distributionSpecBuilder.ts | 76 +++++++++++++++---- 1 file changed, 62 insertions(+), 14 deletions(-) diff --git a/packages/components/src/lib/distributionSpecBuilder.ts b/packages/components/src/lib/distributionSpecBuilder.ts index 143c10d6..ec3c8462 100644 --- a/packages/components/src/lib/distributionSpecBuilder.ts +++ b/packages/components/src/lib/distributionSpecBuilder.ts @@ -84,27 +84,34 @@ export function buildVegaSpec( height: 100, padding: 5, data: [ - { - name: "data", - }, - { - name: "domain", - }, + {name: "data",}, + { name: "domain",}, ], signals: [ { "name": "hover", "value": null, "on": [ - {"events": "symbol:mouseover", "update": "datum"}, - {"events": "symbol:mouseout", "update": "null"} + {"events": "mouseover", "update": "datum"}, + {"events": "mouseout", "update": "null"} ] }, { - "name": "announcer", - "value": "", - "update": "hover ? 'Probability: ' + hover.y + ', Value: ' + hover.x : ''" - } + "name": "position", + "value": "[0, 0]", + "on": [ + { "events": "mousemove", "update": "hover ? xy() : null"}, + { "events": "mouseout", "update": "null"}, + ] + }, + + // { + // "name": "announcer", + // "value": "", + // "update": "hover ? 'Value: ' + hover.x : ''" + // }, + + ], scales: [ xScale, @@ -134,6 +141,7 @@ export function buildVegaSpec( }, ], marks: [ + { name: "all_distributions", type: "group", @@ -145,6 +153,7 @@ export function buildVegaSpec( }, }, marks: [ + { name: "continuous_distribution", type: "group", @@ -203,6 +212,22 @@ export function buildVegaSpec( }, }, marks: [ + { + "name": "samples", + "type": "rect", + "from": {"data": "discrete_facet"}, + "encode": { + "enter": { + "x": {"scale": "xscale", "field":"x"}, + "width": {"value": 1}, + + "y": {"value": 25, "offset": {"signal": "height"}}, + "height": {"value": 5}, + "fill": {"value": "steelblue"}, + "fillOpacity": {"value": 0.8} + } + } + }, { type: "rect", from: { @@ -241,6 +266,7 @@ export function buildVegaSpec( }, encode: { enter: { + shape: { value: "circle", }, @@ -282,10 +308,32 @@ export function buildVegaSpec( "align": {"value": "right"} }, "update": { - "text": {"signal": "announcer"} + "text": {"signal": "position ? position[0]/width : ''"} } } - } + }, + // { + // "type": "rule", + // "encode": { + // "enter": { + // x: {value: 0}, + // "y": {"scale": "yscale", "value":0}, + + // y2: { + // signal: "height", + // offset: 2 + // }, + // "strokeDash": {"value": [5, 5]}, + // }, + + // "update": { + // "x": {"signal": "position[0] < 0 ? null : position[0] > width ? null : position[0]"}, + + // "opacity": {"signal": "position ? 1 : 0"} + // }, + // } + + // } ], legends: [ { From 10db239920d2af1f81662e85a2f78fff4cd8b042 Mon Sep 17 00:00:00 2001 From: Conor Barnes Date: Tue, 23 Aug 2022 12:04:35 -0300 Subject: [PATCH 04/55] hover line --- .../src/lib/distributionSpecBuilder.ts | 67 ++++++++++--------- 1 file changed, 35 insertions(+), 32 deletions(-) diff --git a/packages/components/src/lib/distributionSpecBuilder.ts b/packages/components/src/lib/distributionSpecBuilder.ts index ec3c8462..5fdc0803 100644 --- a/packages/components/src/lib/distributionSpecBuilder.ts +++ b/packages/components/src/lib/distributionSpecBuilder.ts @@ -16,7 +16,7 @@ export type DistributionChartSpecOptions = { format?: string; }; -export let linearXScale: LinearScale = { +export const linearXScale: LinearScale = { name: "xscale", clamp: true, type: "linear", @@ -25,7 +25,7 @@ export let linearXScale: LinearScale = { nice: false, domain: { data: "domain", field: "x" }, }; -export let linearYScale: LinearScale = { +export const linearYScale: LinearScale = { name: "yscale", type: "linear", range: "height", @@ -33,7 +33,7 @@ export let linearYScale: LinearScale = { domain: { data: "domain", field: "y" }, }; -export let logXScale: LogScale = { +export const logXScale: LogScale = { name: "xscale", type: "log", range: "width", @@ -44,7 +44,7 @@ export let logXScale: LogScale = { domain: { data: "domain", field: "x" }, }; -export let expYScale: PowScale = { +export const expYScale: PowScale = { name: "yscale", type: "pow", exponent: 0.1, @@ -77,7 +77,7 @@ export function buildVegaSpec( xScale = { ...xScale, domainMax: maxX }; } - let spec: VisualizationSpec = { + const spec: VisualizationSpec = { $schema: "https://vega.github.io/schema/vega/v5.json", description: "Squiggle plot chart", width: 500, @@ -100,16 +100,20 @@ export function buildVegaSpec( "name": "position", "value": "[0, 0]", "on": [ - { "events": "mousemove", "update": "hover ? xy() : null"}, + { "events": "mousemove", "update": "xy() "}, { "events": "mouseout", "update": "null"}, ] }, - - // { - // "name": "announcer", - // "value": "", - // "update": "hover ? 'Value: ' + hover.x : ''" - // }, + { + "name": "position_scaled", + "value": 0, + "update": "position ? invert('xscale', position[0]) : null" + }, + { + "name": "announcer", + "value": "", + "update": "hover ? 'Value: ' + hover.x : ''" + }, ], @@ -302,38 +306,37 @@ export function buildVegaSpec( "encode": { "enter": { "x": {"signal": "width", "offset": 1}, - "y": {"value": 0}, "fill": {"value": "black"}, "fontSize": {"value": 20}, "align": {"value": "right"} }, "update": { - "text": {"signal": "position ? position[0]/width : ''"} + "text": {"signal": "position_scaled ? position_scaled : ''", } } } }, - // { - // "type": "rule", - // "encode": { - // "enter": { - // x: {value: 0}, - // "y": {"scale": "yscale", "value":0}, + { + "type": "rule", + "encode": { + "enter": { + x: {value: 0}, + "y": {"scale": "yscale", "value":0}, - // y2: { - // signal: "height", - // offset: 2 - // }, - // "strokeDash": {"value": [5, 5]}, - // }, + y2: { + signal: "height", + offset: 2 + }, + "strokeDash": {"value": [5, 5]}, + }, - // "update": { - // "x": {"signal": "position[0] < 0 ? null : position[0] > width ? null : position[0]"}, + "update": { + "x": {"signal": "position ? position[0] < 0 ? null : position[0] > width ? null : position[0]: null"}, - // "opacity": {"signal": "position ? 1 : 0"} - // }, - // } + "opacity": {"signal": "position ? 1 : 0"} + }, + } - // } + } ], legends: [ { From 865b01f48dd1b2c9b9943cda8555f7e67f91e3d6 Mon Sep 17 00:00:00 2001 From: Conor Barnes Date: Wed, 24 Aug 2022 13:57:35 -0300 Subject: [PATCH 05/55] significant digits on hover value --- packages/components/src/lib/distributionSpecBuilder.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/components/src/lib/distributionSpecBuilder.ts b/packages/components/src/lib/distributionSpecBuilder.ts index 5fdc0803..228159ab 100644 --- a/packages/components/src/lib/distributionSpecBuilder.ts +++ b/packages/components/src/lib/distributionSpecBuilder.ts @@ -311,7 +311,7 @@ export function buildVegaSpec( "align": {"value": "right"} }, "update": { - "text": {"signal": "position_scaled ? position_scaled : ''", } + "text": {"signal": "position_scaled ? format(position_scaled, ',.4r') : ''", } } } }, From f8e5396d579efcaed62d41945fd5332c129f1cc1 Mon Sep 17 00:00:00 2001 From: Conor Barnes Date: Wed, 24 Aug 2022 15:26:47 -0300 Subject: [PATCH 06/55] use domain to feed sample for bottom band --- .../src/components/DistributionChart.tsx | 5 +- .../src/lib/distributionSpecBuilder.ts | 47 ++++++++++++------- 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index 1bfa64fe..52172d22 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -48,9 +48,8 @@ export function makePlot(record: { export const DistributionChart: React.FC = (props) => { const { plot, height, showSummary, width, logX, actions = false } = props; // const [xAxis, setXAxis] = React.useState<"dateAndTime" | "numbers">("dateAndTime") - const [sized] = useSize((size) => { - let shapes = flattenResult( + const shapes = flattenResult( plot.distributions.map((x) => resultMap(x.distribution.pointSet(), (shape) => ({ name: x.name, @@ -60,6 +59,7 @@ export const DistributionChart: React.FC = (props) => { })) ) ); + if (shapes.tag === "Error") { return ( @@ -81,6 +81,7 @@ export const DistributionChart: React.FC = (props) => { shape.discrete.concat(shape.continuous) ); + console.log({domain, data: shapes.value}) return (
{logX && shapes.value.some(hasMassBelowZero) ? ( diff --git a/packages/components/src/lib/distributionSpecBuilder.ts b/packages/components/src/lib/distributionSpecBuilder.ts index 228159ab..65820cf2 100644 --- a/packages/components/src/lib/distributionSpecBuilder.ts +++ b/packages/components/src/lib/distributionSpecBuilder.ts @@ -145,7 +145,35 @@ export function buildVegaSpec( }, ], marks: [ - + { + name: "sample_distributions", + "type": "group", + from: { + facet: { + name: "distribution_facet", + data: "domain", + groupby: ["name"], + }, + }, + marks: [ + { + "name": "samples", + "type": "rect", + "from": {"data": "distribution_facet"}, + "encode": { + "enter": { + "x": {"scale": "xscale", "field":"x"}, + "width": {"value": 0.5}, + + "y": {"value": 25, "offset": {"signal": "height"}}, + "height": {"value": 5}, + "fill": {"value": "steelblue"}, + "fillOpacity": {"value": 0.8} + } + } + }, + ] + }, { name: "all_distributions", type: "group", @@ -216,22 +244,7 @@ export function buildVegaSpec( }, }, marks: [ - { - "name": "samples", - "type": "rect", - "from": {"data": "discrete_facet"}, - "encode": { - "enter": { - "x": {"scale": "xscale", "field":"x"}, - "width": {"value": 1}, - - "y": {"value": 25, "offset": {"signal": "height"}}, - "height": {"value": 5}, - "fill": {"value": "steelblue"}, - "fillOpacity": {"value": 0.8} - } - } - }, + { type: "rect", from: { From a99ee96f5c266404bf392e9cd9434fb58dfac41b Mon Sep 17 00:00:00 2001 From: Conor Barnes Date: Wed, 24 Aug 2022 20:56:22 -0300 Subject: [PATCH 07/55] announce x-axis date properly --- .../src/components/DistributionChart.tsx | 126 +++++- .../src/lib/dateDistributionSpecBuilder.ts | 361 ++++++++++++++++++ .../src/lib/distributionSpecBuilder.ts | 143 ++++--- 3 files changed, 545 insertions(+), 85 deletions(-) create mode 100644 packages/components/src/lib/dateDistributionSpecBuilder.ts diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index 52172d22..6b4bdbd6 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -15,6 +15,7 @@ import { buildVegaSpec, DistributionChartSpecOptions, } from "../lib/distributionSpecBuilder"; +import { buildDateVegaSpec } from "../lib/dateDistributionSpecBuilder"; import { NumberShower } from "./NumberShower"; import { Plot, parsePlot } from "../lib/plotParser"; import { flattenResult } from "../lib/utility"; @@ -30,6 +31,7 @@ export type DistributionChartProps = { plot: Plot; width?: number; height: number; + xAxis?: "number" | "dateTime"; } & DistributionPlottingSettings; export function defaultPlot(distribution: Distribution): Plot { @@ -45,8 +47,102 @@ export function makePlot(record: { } } +const DateDistributionChart: React.FC = (props) => { + const { + plot, + height, + showSummary, + width, + logX, + actions = false, + xAxis = "dateTime", + } = props; + // const [xAxis, setXAxis] = React.useState<"dateAndTime" | "numbers">("dateAndTime") + const [sized] = useSize((size) => { + const shapes = flattenResult( + plot.distributions.map((x) => + resultMap(x.distribution.pointSet(), (shape) => ({ + name: x.name, + // color: x.color, // not supported yet + continuous: shape.continuous, + discrete: shape.discrete, + })) + ) + ); + + if (shapes.tag === "Error") { + return ( + + {distributionErrorToString(shapes.value)} + + ); + } + + const spec = buildDateVegaSpec(props); + + let widthProp = width ? width : size.width; + if (widthProp < 20) { + console.warn( + `Width of Distribution is set to ${widthProp}, which is too small` + ); + widthProp = 20; + } + const domain = shapes.value.flatMap((shape) => + shape.discrete.concat(shape.continuous) + ); + + const dateData = { + name: "default", + continuous: [], + discrete: [ + { dateTime: new Date().getTime() - 1000000, y: 0.3 }, + { dateTime: new Date().getTime(), y: 0.5 }, + { dateTime: new Date().getTime() + 1000000, y: 0.7 }, + ], + }; + + const dateDomain = [ + { dateTime: new Date().getTime() - 1000000, y: 0.2 }, + { dateTime: new Date().getTime(), y: 0.5 }, + { dateTime: new Date().getTime() + 1000000, y: 0.7 }, + ]; + + return ( +
+ {logX && shapes.value.some(hasMassBelowZero) ? ( + + Cannot graph distribution with negative values on logarithmic scale. + + ) : ( + + )} +
+ {showSummary && plot.distributions.length === 1 && ( + + )} +
+
+ ); + }); + return sized; +}; + export const DistributionChart: React.FC = (props) => { - const { plot, height, showSummary, width, logX, actions = false } = props; + const { + plot, + height, + showSummary, + width, + logX, + actions = false, + xAxis = "number", + } = props; // const [xAxis, setXAxis] = React.useState<"dateAndTime" | "numbers">("dateAndTime") const [sized] = useSize((size) => { const shapes = flattenResult( @@ -81,7 +177,6 @@ export const DistributionChart: React.FC = (props) => { shape.discrete.concat(shape.continuous) ); - console.log({domain, data: shapes.value}) return (
{logX && shapes.value.some(hasMassBelowZero) ? ( @@ -89,13 +184,26 @@ export const DistributionChart: React.FC = (props) => { Cannot graph distribution with negative values on logarithmic scale. ) : ( - + <> + +
+ +
+ )}
{showSummary && plot.distributions.length === 1 && ( diff --git a/packages/components/src/lib/dateDistributionSpecBuilder.ts b/packages/components/src/lib/dateDistributionSpecBuilder.ts new file mode 100644 index 00000000..140dd954 --- /dev/null +++ b/packages/components/src/lib/dateDistributionSpecBuilder.ts @@ -0,0 +1,361 @@ +import { VisualizationSpec } from "react-vega"; +import type { LogScale, LinearScale, PowScale, TimeScale } from "vega"; + +export type DistributionChartSpecOptions = { + /** Set the x scale to be logarithmic by deault */ + logX: boolean; + /** Set the y scale to be exponential by deault */ + expY: boolean; + /** The minimum x coordinate shown on the chart */ + minX?: number; + /** The maximum x coordinate shown on the chart */ + maxX?: number; + /** The title of the chart */ + title?: string; + /** The formatting of the ticks */ + format?: string; +}; + +export const timeXScale: TimeScale = { + name: "xscale", + clamp: true, + type: "time", + range: "width", + nice: false, + domain: { data: "domain", field: "dateTime" }, +}; +export const timeYScale: TimeScale = { + name: "yscale", + type: "time", + range: "height", + domain: { data: "domain", field: "y" }, +}; + +export const defaultTickFormat = "%b %d, %Y %H:%M"; + +export function buildDateVegaSpec( + specOptions: DistributionChartSpecOptions +): VisualizationSpec { + const { + format = defaultTickFormat, + title, + minX, + maxX, + logX, + expY, + } = specOptions; + + let xScale = timeXScale; + if (minX !== undefined && Number.isFinite(minX)) { + xScale = { ...xScale, domainMin: minX }; + } + + if (maxX !== undefined && Number.isFinite(maxX)) { + xScale = { ...xScale, domainMax: maxX }; + } + + const spec: VisualizationSpec = { + $schema: "https://vega.github.io/schema/vega/v5.json", + description: "Squiggle plot chart", + width: 500, + height: 100, + padding: 5, + data: [{ name: "data" }, { name: "domain" }], + signals: [ + { + name: "hover", + value: null, + on: [ + { events: "mouseover", update: "datum" }, + { events: "mouseout", update: "null" }, + ], + }, + { + name: "position", + value: "[0, 0]", + on: [ + { events: "mousemove", update: "xy() " }, + { events: "mouseout", update: "null" }, + ], + }, + { + name: "position_scaled", + value: null, + update: "isArray(position) ? invert('xscale', position[0]) : ''", + }, + ], + scales: [ + xScale, + timeYScale, + { + name: "color", + type: "ordinal", + domain: { + data: "data", + field: "name", + }, + range: { scheme: "blues" }, + }, + ], + axes: [ + { + orient: "bottom", + scale: "xscale", + labelColor: "#727d93", + tickColor: "#fff", + tickOpacity: 0.0, + domainColor: "#fff", + domainOpacity: 0.0, + format: format, + tickCount: 3, + labelOverlap: "greedy", + }, + ], + marks: [ + { + name: "sample_distributions", + type: "group", + from: { + facet: { + name: "distribution_facet", + data: "domain", + groupby: ["name"], + }, + }, + marks: [ + { + name: "samples", + type: "rect", + from: { data: "distribution_facet" }, + encode: { + enter: { + x: { scale: "xscale", field: "dateTime" }, + width: { value: 0.5 }, + + y: { value: 25, offset: { signal: "height" } }, + height: { value: 5 }, + fill: { value: "steelblue" }, + fillOpacity: { value: 0.8 }, + }, + }, + }, + ], + }, + { + name: "all_distributions", + type: "group", + from: { + facet: { + name: "distribution_facet", + data: "data", + groupby: ["name"], + }, + }, + marks: [ + { + name: "continuous_distribution", + type: "group", + from: { + facet: { + name: "continuous_facet", + data: "distribution_facet", + field: "continuous", + }, + }, + encode: { + update: {}, + }, + marks: [ + { + name: "continuous_area", + type: "area", + from: { + data: "continuous_facet", + }, + encode: { + update: { + // interpolate: { value: "linear" }, + x: { + scale: "xscale", + field: "dateTime", + }, + y: { + scale: "yscale", + field: "y", + }, + fill: { + scale: "color", + field: { parent: "name" }, + }, + y2: { + scale: "yscale", + value: 0, + }, + fillOpacity: { + value: 1, + }, + }, + }, + }, + ], + }, + { + name: "discrete_distribution", + type: "group", + from: { + facet: { + name: "discrete_facet", + data: "distribution_facet", + field: "discrete", + }, + }, + marks: [ + { + type: "rect", + from: { + data: "discrete_facet", + }, + encode: { + enter: { + width: { + value: 1, + }, + }, + update: { + x: { + scale: "xscale", + field: "dateTime", + }, + y: { + scale: "yscale", + field: "y", + }, + y2: { + scale: "yscale", + value: 0, + }, + fill: { + scale: "color", + field: { parent: "name" }, + }, + }, + }, + }, + { + type: "symbol", + from: { + data: "discrete_facet", + }, + encode: { + enter: { + shape: { + value: "circle", + }, + size: [{ value: 100 }], + tooltip: { + signal: + "{ probability: datum.y, value: datetime(datum.dateTime) }", + }, + }, + update: { + x: { + scale: "xscale", + field: "dateTime", + offset: 0.5, // if this is not included, the circles are slightly left of center. + }, + y: { + scale: "yscale", + field: "y", + }, + fill: { + scale: "color", + field: { parent: "name" }, + }, + }, + }, + }, + ], + }, + ], + }, + { + type: "text", + interactive: false, + encode: { + enter: { + text: { + signal: "", + }, + x: { signal: "width", offset: 1 }, + fill: { value: "black" }, + fontSize: { value: 20 }, + align: { value: "right" }, + }, + update: { + text: { + signal: + "position_scaled ? utcyear(position_scaled) + '-' + utcmonth(position_scaled) + '-' + utcdate(position_scaled) + 'T' + utchours(position_scaled)+':' +utcminutes(position_scaled) : ''", + }, + }, + }, + }, + { + type: "rule", + encode: { + enter: { + x: { value: 0 }, + y: { scale: "yscale", value: 0 }, + + y2: { + signal: "height", + offset: 2, + }, + strokeDash: { value: [5, 5] }, + }, + + update: { + x: { + signal: + "position ? position[0] < 0 ? null : position[0] > width ? null : position[0]: null", + }, + + opacity: { signal: "position ? 1 : 0" }, + }, + }, + }, + ], + legends: [ + { + fill: "color", + orient: "top", + labelFontSize: 12, + encode: { + symbols: { + update: { + fill: [ + { test: "length(domain('color')) == 1", value: "transparent" }, + { scale: "color", field: "value" }, + ], + }, + }, + labels: { + interactive: true, + update: { + fill: [ + { test: "length(domain('color')) == 1", value: "transparent" }, + { value: "black" }, + ], + }, + }, + }, + }, + ], + ...(title && { + title: { + text: title, + }, + }), + }; + + return spec; +} diff --git a/packages/components/src/lib/distributionSpecBuilder.ts b/packages/components/src/lib/distributionSpecBuilder.ts index 65820cf2..03673882 100644 --- a/packages/components/src/lib/distributionSpecBuilder.ts +++ b/packages/components/src/lib/distributionSpecBuilder.ts @@ -83,39 +83,29 @@ export function buildVegaSpec( width: 500, height: 100, padding: 5, - data: [ - {name: "data",}, - { name: "domain",}, - ], + data: [{ name: "data" }, { name: "domain" }], signals: [ { - "name": "hover", - "value": null, - "on": [ - {"events": "mouseover", "update": "datum"}, - {"events": "mouseout", "update": "null"} - ] + name: "hover", + value: null, + on: [ + { events: "mouseover", update: "datum" }, + { events: "mouseout", update: "null" }, + ], }, { - "name": "position", - "value": "[0, 0]", - "on": [ - { "events": "mousemove", "update": "xy() "}, - { "events": "mouseout", "update": "null"}, - ] + name: "position", + value: "[0, 0]", + on: [ + { events: "mousemove", update: "xy() " }, + { events: "mouseout", update: "null" }, + ], }, { - "name": "position_scaled", - "value": 0, - "update": "position ? invert('xscale', position[0]) : null" + name: "position_scaled", + value: 0, + update: "position ? invert('xscale', position[0]) : null", }, - { - "name": "announcer", - "value": "", - "update": "hover ? 'Value: ' + hover.x : ''" - }, - - ], scales: [ xScale, @@ -147,32 +137,32 @@ export function buildVegaSpec( marks: [ { name: "sample_distributions", - "type": "group", + type: "group", from: { facet: { name: "distribution_facet", data: "domain", groupby: ["name"], }, - }, + }, marks: [ { - "name": "samples", - "type": "rect", - "from": {"data": "distribution_facet"}, - "encode": { - "enter": { - "x": {"scale": "xscale", "field":"x"}, - "width": {"value": 0.5}, - - "y": {"value": 25, "offset": {"signal": "height"}}, - "height": {"value": 5}, - "fill": {"value": "steelblue"}, - "fillOpacity": {"value": 0.8} - } - } + name: "samples", + type: "rect", + from: { data: "distribution_facet" }, + encode: { + enter: { + x: { scale: "xscale", field: "x" }, + width: { value: 0.5 }, + + y: { value: 25, offset: { signal: "height" } }, + height: { value: 5 }, + fill: { value: "steelblue" }, + fillOpacity: { value: 0.8 }, + }, + }, }, - ] + ], }, { name: "all_distributions", @@ -185,7 +175,6 @@ export function buildVegaSpec( }, }, marks: [ - { name: "continuous_distribution", type: "group", @@ -244,7 +233,6 @@ export function buildVegaSpec( }, }, marks: [ - { type: "rect", from: { @@ -283,7 +271,6 @@ export function buildVegaSpec( }, encode: { enter: { - shape: { value: "circle", }, @@ -296,7 +283,7 @@ export function buildVegaSpec( x: { scale: "xscale", field: "x", - offset: 0.5, // if this is not included, the circles are slightly left of center. + offset: 0.5, // if this is not included, the circles are slightly left of center. }, y: { scale: "yscale", @@ -314,42 +301,46 @@ export function buildVegaSpec( ], }, { - "type": "text", - "interactive": false, - "encode": { - "enter": { - "x": {"signal": "width", "offset": 1}, - "fill": {"value": "black"}, - "fontSize": {"value": 20}, - "align": {"value": "right"} + type: "text", + interactive: false, + encode: { + enter: { + x: { signal: "width", offset: 1 }, + fill: { value: "black" }, + fontSize: { value: 20 }, + align: { value: "right" }, }, - "update": { - "text": {"signal": "position_scaled ? format(position_scaled, ',.4r') : ''", } - } - } + update: { + text: { + signal: "position_scaled ? format(position_scaled, ',.4r') : ''", + }, + }, + }, }, { - "type": "rule", - "encode": { - "enter": { - x: {value: 0}, - "y": {"scale": "yscale", "value":0}, + type: "rule", + encode: { + enter: { + x: { value: 0 }, + y: { scale: "yscale", value: 0 }, y2: { - signal: "height", - offset: 2 + signal: "height", + offset: 2, }, - "strokeDash": {"value": [5, 5]}, - }, - - "update": { - "x": {"signal": "position ? position[0] < 0 ? null : position[0] > width ? null : position[0]: null"}, - - "opacity": {"signal": "position ? 1 : 0"} + strokeDash: { value: [5, 5] }, }, - } - - } + + update: { + x: { + signal: + "position ? position[0] < 0 ? null : position[0] > width ? null : position[0]: null", + }, + + opacity: { signal: "position ? 1 : 0" }, + }, + }, + }, ], legends: [ { From a9e43ee7cfd7cfffff3008c7b243968660095e22 Mon Sep 17 00:00:00 2001 From: Conor Barnes Date: Wed, 24 Aug 2022 21:13:50 -0300 Subject: [PATCH 08/55] bring back the stems --- .../src/components/DistributionChart.tsx | 2 +- .../src/lib/dateDistributionSpecBuilder.ts | 29 +++++++++++++++++-- .../src/lib/distributionSpecBuilder.ts | 1 + 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index 6b4bdbd6..13bac83b 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -95,7 +95,7 @@ const DateDistributionChart: React.FC = (props) => { name: "default", continuous: [], discrete: [ - { dateTime: new Date().getTime() - 1000000, y: 0.3 }, + { dateTime: new Date().getTime() - 1000000, y: 0.2 }, { dateTime: new Date().getTime(), y: 0.5 }, { dateTime: new Date().getTime() + 1000000, y: 0.7 }, ], diff --git a/packages/components/src/lib/dateDistributionSpecBuilder.ts b/packages/components/src/lib/dateDistributionSpecBuilder.ts index 140dd954..5e64a18b 100644 --- a/packages/components/src/lib/dateDistributionSpecBuilder.ts +++ b/packages/components/src/lib/dateDistributionSpecBuilder.ts @@ -24,10 +24,33 @@ export const timeXScale: TimeScale = { nice: false, domain: { data: "domain", field: "dateTime" }, }; -export const timeYScale: TimeScale = { + +export const linearYScale: LinearScale = { name: "yscale", - type: "time", + type: "linear", range: "height", + zero: true, + domain: { data: "domain", field: "y" }, +}; + +export const logXScale: LogScale = { + name: "xscale", + type: "log", + range: "width", + zero: false, + base: 10, + nice: false, + clamp: true, + domain: { data: "domain", field: "x" }, +}; + +export const expYScale: PowScale = { + name: "yscale", + type: "pow", + exponent: 0.1, + range: "height", + zero: true, + nice: false, domain: { data: "domain", field: "y" }, }; @@ -86,7 +109,7 @@ export function buildDateVegaSpec( ], scales: [ xScale, - timeYScale, + expY ? expYScale : linearYScale, { name: "color", type: "ordinal", diff --git a/packages/components/src/lib/distributionSpecBuilder.ts b/packages/components/src/lib/distributionSpecBuilder.ts index 03673882..cbab3039 100644 --- a/packages/components/src/lib/distributionSpecBuilder.ts +++ b/packages/components/src/lib/distributionSpecBuilder.ts @@ -25,6 +25,7 @@ export const linearXScale: LinearScale = { nice: false, domain: { data: "domain", field: "x" }, }; + export const linearYScale: LinearScale = { name: "yscale", type: "linear", From 754fc8531f8afa935ad4aa89e26a2c500ef94c50 Mon Sep 17 00:00:00 2001 From: Conor Barnes Date: Wed, 24 Aug 2022 21:45:46 -0300 Subject: [PATCH 09/55] combined distribution chart component --- .../src/components/DistributionChart.tsx | 141 ++++-------------- 1 file changed, 32 insertions(+), 109 deletions(-) diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index 13bac83b..783de071 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -47,92 +47,6 @@ export function makePlot(record: { } } -const DateDistributionChart: React.FC = (props) => { - const { - plot, - height, - showSummary, - width, - logX, - actions = false, - xAxis = "dateTime", - } = props; - // const [xAxis, setXAxis] = React.useState<"dateAndTime" | "numbers">("dateAndTime") - const [sized] = useSize((size) => { - const shapes = flattenResult( - plot.distributions.map((x) => - resultMap(x.distribution.pointSet(), (shape) => ({ - name: x.name, - // color: x.color, // not supported yet - continuous: shape.continuous, - discrete: shape.discrete, - })) - ) - ); - - if (shapes.tag === "Error") { - return ( - - {distributionErrorToString(shapes.value)} - - ); - } - - const spec = buildDateVegaSpec(props); - - let widthProp = width ? width : size.width; - if (widthProp < 20) { - console.warn( - `Width of Distribution is set to ${widthProp}, which is too small` - ); - widthProp = 20; - } - const domain = shapes.value.flatMap((shape) => - shape.discrete.concat(shape.continuous) - ); - - const dateData = { - name: "default", - continuous: [], - discrete: [ - { dateTime: new Date().getTime() - 1000000, y: 0.2 }, - { dateTime: new Date().getTime(), y: 0.5 }, - { dateTime: new Date().getTime() + 1000000, y: 0.7 }, - ], - }; - - const dateDomain = [ - { dateTime: new Date().getTime() - 1000000, y: 0.2 }, - { dateTime: new Date().getTime(), y: 0.5 }, - { dateTime: new Date().getTime() + 1000000, y: 0.7 }, - ]; - - return ( -
- {logX && shapes.value.some(hasMassBelowZero) ? ( - - Cannot graph distribution with negative values on logarithmic scale. - - ) : ( - - )} -
- {showSummary && plot.distributions.length === 1 && ( - - )} -
-
- ); - }); - return sized; -}; - export const DistributionChart: React.FC = (props) => { const { plot, @@ -143,7 +57,6 @@ export const DistributionChart: React.FC = (props) => { actions = false, xAxis = "number", } = props; - // const [xAxis, setXAxis] = React.useState<"dateAndTime" | "numbers">("dateAndTime") const [sized] = useSize((size) => { const shapes = flattenResult( plot.distributions.map((x) => @@ -164,7 +77,8 @@ export const DistributionChart: React.FC = (props) => { ); } - const spec = buildVegaSpec(props); + const spec = + xAxis === "dateTime" ? buildDateVegaSpec(props) : buildVegaSpec(props); let widthProp = width ? width : size.width; if (widthProp < 20) { @@ -173,10 +87,32 @@ export const DistributionChart: React.FC = (props) => { ); widthProp = 20; } - const domain = shapes.value.flatMap((shape) => + const predomain = shapes.value.flatMap((shape) => shape.discrete.concat(shape.continuous) ); + const domain = + xAxis === "dateTime" + ? predomain.map((p) => { + return { dateTime: p.x, y: p.y }; + }) + : predomain; + + const data = + xAxis === "dateTime" + ? shapes.value.map((val) => { + return { + ...val, + continuous: val.continuous.map((p) => { + return { dateTime: p.x, y: p.y }; + }), + discrete: val.discrete.map((p) => { + return { dateTime: p.x, y: p.y }; + }), + }; + }) + : shapes.value; + return (
{logX && shapes.value.some(hasMassBelowZero) ? ( @@ -184,26 +120,13 @@ export const DistributionChart: React.FC = (props) => { Cannot graph distribution with negative values on logarithmic scale. ) : ( - <> - -
- -
- + )}
{showSummary && plot.distributions.length === 1 && ( From e88d93ac9e999baba201ceb5951cd9ba9d142c2f Mon Sep 17 00:00:00 2001 From: Conor Barnes Date: Mon, 29 Aug 2022 15:28:31 -0300 Subject: [PATCH 10/55] more stringent logic over visibility of rule-line and announcer --- .../components/src/lib/distributionSpecBuilder.ts | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/packages/components/src/lib/distributionSpecBuilder.ts b/packages/components/src/lib/distributionSpecBuilder.ts index cbab3039..0bd10c69 100644 --- a/packages/components/src/lib/distributionSpecBuilder.ts +++ b/packages/components/src/lib/distributionSpecBuilder.ts @@ -105,7 +105,9 @@ export function buildVegaSpec( { name: "position_scaled", value: 0, - update: "position ? invert('xscale', position[0]) : null", + update: "position ? position[0] < 0 ? null : position[0] > width ? null : invert('xscale', position[0]) : null", + // "position ? position[0] < 0 ? 0 : position[0] > width ? 0 : 1 : 0", + }, ], scales: [ @@ -303,6 +305,7 @@ export function buildVegaSpec( }, { type: "text", + name: "announcer", interactive: false, encode: { enter: { @@ -338,7 +341,11 @@ export function buildVegaSpec( "position ? position[0] < 0 ? null : position[0] > width ? null : position[0]: null", }, - opacity: { signal: "position ? 1 : 0" }, + opacity: { + signal: + "position ? position[0] < 0 ? 0 : position[0] > width ? 0 : 1 : 0", + }, + // opacity: { signal: "position ? 1 : 0" }, }, }, }, From 7c00897833cc50d65991706426f459f491d361f9 Mon Sep 17 00:00:00 2001 From: Conor Barnes Date: Mon, 29 Aug 2022 16:00:51 -0300 Subject: [PATCH 11/55] don't let rule-line intercept hover events --- .../src/lib/distributionSpecBuilder.ts | 29 +------------------ 1 file changed, 1 insertion(+), 28 deletions(-) diff --git a/packages/components/src/lib/distributionSpecBuilder.ts b/packages/components/src/lib/distributionSpecBuilder.ts index 0bd10c69..983866ea 100644 --- a/packages/components/src/lib/distributionSpecBuilder.ts +++ b/packages/components/src/lib/distributionSpecBuilder.ts @@ -138,35 +138,7 @@ export function buildVegaSpec( }, ], marks: [ - { - name: "sample_distributions", - type: "group", - from: { - facet: { - name: "distribution_facet", - data: "domain", - groupby: ["name"], - }, - }, - marks: [ - { - name: "samples", - type: "rect", - from: { data: "distribution_facet" }, - encode: { - enter: { - x: { scale: "xscale", field: "x" }, - width: { value: 0.5 }, - y: { value: 25, offset: { signal: "height" } }, - height: { value: 5 }, - fill: { value: "steelblue" }, - fillOpacity: { value: 0.8 }, - }, - }, - }, - ], - }, { name: "all_distributions", type: "group", @@ -323,6 +295,7 @@ export function buildVegaSpec( }, { type: "rule", + interactive: false, encode: { enter: { x: { value: 0 }, From 0292c66c805bd05782979190a2194b555d508c63 Mon Sep 17 00:00:00 2001 From: Conor Barnes Date: Mon, 29 Aug 2022 17:27:13 -0300 Subject: [PATCH 12/55] combined distribution chart component --- .../src/components/DistributionChart.tsx | 5 +- .../src/lib/dateDistributionSpecBuilder.ts | 384 ------------------ .../src/lib/distributionSpecBuilder.ts | 88 +++- 3 files changed, 72 insertions(+), 405 deletions(-) delete mode 100644 packages/components/src/lib/dateDistributionSpecBuilder.ts diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index 783de071..caf01e6d 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -15,7 +15,6 @@ import { buildVegaSpec, DistributionChartSpecOptions, } from "../lib/distributionSpecBuilder"; -import { buildDateVegaSpec } from "../lib/dateDistributionSpecBuilder"; import { NumberShower } from "./NumberShower"; import { Plot, parsePlot } from "../lib/plotParser"; import { flattenResult } from "../lib/utility"; @@ -31,6 +30,7 @@ export type DistributionChartProps = { plot: Plot; width?: number; height: number; + sample: boolean; xAxis?: "number" | "dateTime"; } & DistributionPlottingSettings; @@ -77,8 +77,7 @@ export const DistributionChart: React.FC = (props) => { ); } - const spec = - xAxis === "dateTime" ? buildDateVegaSpec(props) : buildVegaSpec(props); + const spec = buildVegaSpec(props); let widthProp = width ? width : size.width; if (widthProp < 20) { diff --git a/packages/components/src/lib/dateDistributionSpecBuilder.ts b/packages/components/src/lib/dateDistributionSpecBuilder.ts deleted file mode 100644 index 5e64a18b..00000000 --- a/packages/components/src/lib/dateDistributionSpecBuilder.ts +++ /dev/null @@ -1,384 +0,0 @@ -import { VisualizationSpec } from "react-vega"; -import type { LogScale, LinearScale, PowScale, TimeScale } from "vega"; - -export type DistributionChartSpecOptions = { - /** Set the x scale to be logarithmic by deault */ - logX: boolean; - /** Set the y scale to be exponential by deault */ - expY: boolean; - /** The minimum x coordinate shown on the chart */ - minX?: number; - /** The maximum x coordinate shown on the chart */ - maxX?: number; - /** The title of the chart */ - title?: string; - /** The formatting of the ticks */ - format?: string; -}; - -export const timeXScale: TimeScale = { - name: "xscale", - clamp: true, - type: "time", - range: "width", - nice: false, - domain: { data: "domain", field: "dateTime" }, -}; - -export const linearYScale: LinearScale = { - name: "yscale", - type: "linear", - range: "height", - zero: true, - domain: { data: "domain", field: "y" }, -}; - -export const logXScale: LogScale = { - name: "xscale", - type: "log", - range: "width", - zero: false, - base: 10, - nice: false, - clamp: true, - domain: { data: "domain", field: "x" }, -}; - -export const expYScale: PowScale = { - name: "yscale", - type: "pow", - exponent: 0.1, - range: "height", - zero: true, - nice: false, - domain: { data: "domain", field: "y" }, -}; - -export const defaultTickFormat = "%b %d, %Y %H:%M"; - -export function buildDateVegaSpec( - specOptions: DistributionChartSpecOptions -): VisualizationSpec { - const { - format = defaultTickFormat, - title, - minX, - maxX, - logX, - expY, - } = specOptions; - - let xScale = timeXScale; - if (minX !== undefined && Number.isFinite(minX)) { - xScale = { ...xScale, domainMin: minX }; - } - - if (maxX !== undefined && Number.isFinite(maxX)) { - xScale = { ...xScale, domainMax: maxX }; - } - - const spec: VisualizationSpec = { - $schema: "https://vega.github.io/schema/vega/v5.json", - description: "Squiggle plot chart", - width: 500, - height: 100, - padding: 5, - data: [{ name: "data" }, { name: "domain" }], - signals: [ - { - name: "hover", - value: null, - on: [ - { events: "mouseover", update: "datum" }, - { events: "mouseout", update: "null" }, - ], - }, - { - name: "position", - value: "[0, 0]", - on: [ - { events: "mousemove", update: "xy() " }, - { events: "mouseout", update: "null" }, - ], - }, - { - name: "position_scaled", - value: null, - update: "isArray(position) ? invert('xscale', position[0]) : ''", - }, - ], - scales: [ - xScale, - expY ? expYScale : linearYScale, - { - name: "color", - type: "ordinal", - domain: { - data: "data", - field: "name", - }, - range: { scheme: "blues" }, - }, - ], - axes: [ - { - orient: "bottom", - scale: "xscale", - labelColor: "#727d93", - tickColor: "#fff", - tickOpacity: 0.0, - domainColor: "#fff", - domainOpacity: 0.0, - format: format, - tickCount: 3, - labelOverlap: "greedy", - }, - ], - marks: [ - { - name: "sample_distributions", - type: "group", - from: { - facet: { - name: "distribution_facet", - data: "domain", - groupby: ["name"], - }, - }, - marks: [ - { - name: "samples", - type: "rect", - from: { data: "distribution_facet" }, - encode: { - enter: { - x: { scale: "xscale", field: "dateTime" }, - width: { value: 0.5 }, - - y: { value: 25, offset: { signal: "height" } }, - height: { value: 5 }, - fill: { value: "steelblue" }, - fillOpacity: { value: 0.8 }, - }, - }, - }, - ], - }, - { - name: "all_distributions", - type: "group", - from: { - facet: { - name: "distribution_facet", - data: "data", - groupby: ["name"], - }, - }, - marks: [ - { - name: "continuous_distribution", - type: "group", - from: { - facet: { - name: "continuous_facet", - data: "distribution_facet", - field: "continuous", - }, - }, - encode: { - update: {}, - }, - marks: [ - { - name: "continuous_area", - type: "area", - from: { - data: "continuous_facet", - }, - encode: { - update: { - // interpolate: { value: "linear" }, - x: { - scale: "xscale", - field: "dateTime", - }, - y: { - scale: "yscale", - field: "y", - }, - fill: { - scale: "color", - field: { parent: "name" }, - }, - y2: { - scale: "yscale", - value: 0, - }, - fillOpacity: { - value: 1, - }, - }, - }, - }, - ], - }, - { - name: "discrete_distribution", - type: "group", - from: { - facet: { - name: "discrete_facet", - data: "distribution_facet", - field: "discrete", - }, - }, - marks: [ - { - type: "rect", - from: { - data: "discrete_facet", - }, - encode: { - enter: { - width: { - value: 1, - }, - }, - update: { - x: { - scale: "xscale", - field: "dateTime", - }, - y: { - scale: "yscale", - field: "y", - }, - y2: { - scale: "yscale", - value: 0, - }, - fill: { - scale: "color", - field: { parent: "name" }, - }, - }, - }, - }, - { - type: "symbol", - from: { - data: "discrete_facet", - }, - encode: { - enter: { - shape: { - value: "circle", - }, - size: [{ value: 100 }], - tooltip: { - signal: - "{ probability: datum.y, value: datetime(datum.dateTime) }", - }, - }, - update: { - x: { - scale: "xscale", - field: "dateTime", - offset: 0.5, // if this is not included, the circles are slightly left of center. - }, - y: { - scale: "yscale", - field: "y", - }, - fill: { - scale: "color", - field: { parent: "name" }, - }, - }, - }, - }, - ], - }, - ], - }, - { - type: "text", - interactive: false, - encode: { - enter: { - text: { - signal: "", - }, - x: { signal: "width", offset: 1 }, - fill: { value: "black" }, - fontSize: { value: 20 }, - align: { value: "right" }, - }, - update: { - text: { - signal: - "position_scaled ? utcyear(position_scaled) + '-' + utcmonth(position_scaled) + '-' + utcdate(position_scaled) + 'T' + utchours(position_scaled)+':' +utcminutes(position_scaled) : ''", - }, - }, - }, - }, - { - type: "rule", - encode: { - enter: { - x: { value: 0 }, - y: { scale: "yscale", value: 0 }, - - y2: { - signal: "height", - offset: 2, - }, - strokeDash: { value: [5, 5] }, - }, - - update: { - x: { - signal: - "position ? position[0] < 0 ? null : position[0] > width ? null : position[0]: null", - }, - - opacity: { signal: "position ? 1 : 0" }, - }, - }, - }, - ], - legends: [ - { - fill: "color", - orient: "top", - labelFontSize: 12, - encode: { - symbols: { - update: { - fill: [ - { test: "length(domain('color')) == 1", value: "transparent" }, - { scale: "color", field: "value" }, - ], - }, - }, - labels: { - interactive: true, - update: { - fill: [ - { test: "length(domain('color')) == 1", value: "transparent" }, - { value: "black" }, - ], - }, - }, - }, - }, - ], - ...(title && { - title: { - text: title, - }, - }), - }; - - return spec; -} diff --git a/packages/components/src/lib/distributionSpecBuilder.ts b/packages/components/src/lib/distributionSpecBuilder.ts index 983866ea..98a06a08 100644 --- a/packages/components/src/lib/distributionSpecBuilder.ts +++ b/packages/components/src/lib/distributionSpecBuilder.ts @@ -1,5 +1,5 @@ import { VisualizationSpec } from "react-vega"; -import type { LogScale, LinearScale, PowScale } from "vega"; +import type { LogScale, LinearScale, PowScale, TimeScale } from "vega"; export type DistributionChartSpecOptions = { /** Set the x scale to be logarithmic by deault */ @@ -14,6 +14,12 @@ export type DistributionChartSpecOptions = { title?: string; /** The formatting of the ticks */ format?: string; + + /** Whether or not to show the band of sample data at the bottom */ + sample?: boolean; + + /** Whether the x-axis should be dates or numbers */ + xAxis?: "number" | "dateTime"; }; export const linearXScale: LinearScale = { @@ -26,14 +32,6 @@ export const linearXScale: LinearScale = { domain: { data: "domain", field: "x" }, }; -export const linearYScale: LinearScale = { - name: "yscale", - type: "linear", - range: "height", - zero: true, - domain: { data: "domain", field: "y" }, -}; - export const logXScale: LogScale = { name: "xscale", type: "log", @@ -45,6 +43,23 @@ export const logXScale: LogScale = { domain: { data: "domain", field: "x" }, }; +export const timeXScale: TimeScale = { + name: "xscale", + clamp: true, + type: "time", + range: "width", + nice: false, + domain: { data: "domain", field: "dateTime" }, +}; + +export const linearYScale: LinearScale = { + name: "yscale", + type: "linear", + range: "height", + zero: true, + domain: { data: "domain", field: "y" }, +}; + export const expYScale: PowScale = { name: "yscale", type: "pow", @@ -56,6 +71,7 @@ export const expYScale: PowScale = { }; export const defaultTickFormat = ".9~s"; +export const timeTickFormat = "%b %d, %Y %H:%M"; export function buildVegaSpec( specOptions: DistributionChartSpecOptions @@ -67,9 +83,14 @@ export function buildVegaSpec( maxX, logX, expY, + sample = false, + xAxis = "number", } = specOptions; - let xScale = logX ? logXScale : linearXScale; + const dateTime = xAxis === "dateTime"; + + let xScale = dateTime ? timeXScale : logX ? logXScale : linearXScale; + if (minX !== undefined && Number.isFinite(minX)) { xScale = { ...xScale, domainMin: minX }; } @@ -105,9 +126,7 @@ export function buildVegaSpec( { name: "position_scaled", value: 0, - update: "position ? position[0] < 0 ? null : position[0] > width ? null : invert('xscale', position[0]) : null", - // "position ? position[0] < 0 ? 0 : position[0] > width ? 0 : 1 : 0", - + update: "position ? invert('xscale', position[0]) : null", }, ], scales: [ @@ -138,7 +157,6 @@ export function buildVegaSpec( }, ], marks: [ - { name: "all_distributions", type: "group", @@ -175,7 +193,7 @@ export function buildVegaSpec( interpolate: { value: "linear" }, x: { scale: "xscale", - field: "x", + field: dateTime ? "dateTime" : "x", }, y: { scale: "yscale", @@ -222,7 +240,7 @@ export function buildVegaSpec( update: { x: { scale: "xscale", - field: "x", + field: dateTime ? "dateTime" : "x", }, y: { scale: "yscale", @@ -251,13 +269,15 @@ export function buildVegaSpec( }, size: [{ value: 100 }], tooltip: { - signal: "{ probability: datum.y, value: datum.x }", + signal: dateTime + ? "{ probability: datum.y, value: datetime(datum.dateTime) }" + : "{ probability: datum.y, value: datum.x }", }, }, update: { x: { scale: "xscale", - field: "x", + field: dateTime ? "dateTime" : "x", offset: 0.5, // if this is not included, the circles are slightly left of center. }, y: { @@ -356,5 +376,37 @@ export function buildVegaSpec( }), }; + // include the band at the bottom if specified in the React component + if (sample) { + spec.marks?.push({ + name: "sample_distributions", + type: "group", + from: { + facet: { + name: "distribution_facet", + data: "domain", + groupby: ["name"], + }, + }, + marks: [ + { + name: "samples", + type: "rect", + from: { data: "distribution_facet" }, + encode: { + enter: { + x: { scale: "xscale", field: dateTime ? "dateTime" : "x" }, + width: { value: 0.5 }, + + y: { value: 25, offset: { signal: "height" } }, + height: { value: 5 }, + fill: { value: "steelblue" }, + fillOpacity: { value: 0.8 }, + }, + }, + }, + ], + }); + } return spec; } From 496bd0e53904fa9de228b950fb9cbb27730c61ca Mon Sep 17 00:00:00 2001 From: Conor Barnes Date: Mon, 29 Aug 2022 18:01:07 -0300 Subject: [PATCH 13/55] storybook for date distribution, grab missing things necessary for date distribution in spec --- .../src/components/DistributionChart.tsx | 1 + .../src/components/SquiggleChart.tsx | 4 ++++ .../src/lib/distributionSpecBuilder.ts | 20 ++++++++++++++----- .../src/stories/SquiggleChart.stories.mdx | 15 ++++++++++++++ 4 files changed, 35 insertions(+), 5 deletions(-) diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index caf01e6d..b570f4e6 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -57,6 +57,7 @@ export const DistributionChart: React.FC = (props) => { actions = false, xAxis = "number", } = props; + console.log({ plot }); const [sized] = useSize((size) => { const shapes = flattenResult( plot.distributions.map((x) => diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index 00688512..5baae229 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -51,6 +51,8 @@ export interface SquiggleChartProps { minX?: number; /** Specify the upper bound of the x scale */ maxX?: number; + /** Whether the x-axis should be dates or numbers */ + xAxis?: "number" | "dateTime"; /** Whether to show vega actions to the user, so they can copy the chart spec */ distributionChartActions?: boolean; enableLocalSettings?: boolean; @@ -79,6 +81,7 @@ export const SquiggleChart: React.FC = React.memo( maxX, color, title, + xAxis = "number", distributionChartActions, enableLocalSettings = false, }) => { @@ -100,6 +103,7 @@ export const SquiggleChart: React.FC = React.memo( maxX, color, title, + xAxis, actions: distributionChartActions, }; diff --git a/packages/components/src/lib/distributionSpecBuilder.ts b/packages/components/src/lib/distributionSpecBuilder.ts index 98a06a08..9f3cf02a 100644 --- a/packages/components/src/lib/distributionSpecBuilder.ts +++ b/packages/components/src/lib/distributionSpecBuilder.ts @@ -77,7 +77,6 @@ export function buildVegaSpec( specOptions: DistributionChartSpecOptions ): VisualizationSpec { const { - format = defaultTickFormat, title, minX, maxX, @@ -89,6 +88,13 @@ export function buildVegaSpec( const dateTime = xAxis === "dateTime"; + // some fallbacks + const format = specOptions?.format + ? specOptions.format + : dateTime + ? timeTickFormat + : defaultTickFormat; + let xScale = dateTime ? timeXScale : logX ? logXScale : linearXScale; if (minX !== undefined && Number.isFinite(minX)) { @@ -125,8 +131,10 @@ export function buildVegaSpec( }, { name: "position_scaled", - value: 0, - update: "position ? invert('xscale', position[0]) : null", + value: null, + update: "isArray(position) ? invert('xscale', position[0]) : ''", + // value: 0, + // update: "position ? invert('xscale', position[0]) : null", }, ], scales: [ @@ -152,7 +160,7 @@ export function buildVegaSpec( domainColor: "#fff", domainOpacity: 0.0, format: format, - tickCount: 10, + tickCount: dateTime ? 3 : 10, labelOverlap: "greedy", }, ], @@ -308,7 +316,9 @@ export function buildVegaSpec( }, update: { text: { - signal: "position_scaled ? format(position_scaled, ',.4r') : ''", + signal: dateTime + ? "position_scaled ? utcyear(position_scaled) + '-' + utcmonth(position_scaled) + '-' + utcdate(position_scaled) + 'T' + utchours(position_scaled)+':' +utcminutes(position_scaled) : ''" + : "position_scaled ? format(position_scaled, ',.4r') : ''", }, }, }, diff --git a/packages/components/src/stories/SquiggleChart.stories.mdx b/packages/components/src/stories/SquiggleChart.stories.mdx index 3c272982..3dc74761 100644 --- a/packages/components/src/stories/SquiggleChart.stories.mdx +++ b/packages/components/src/stories/SquiggleChart.stories.mdx @@ -79,6 +79,21 @@ could be continuous, discrete or mixed. +### Date Distribution + + + + {Template.bind({})} + + + ## Mixed distributions From 87c6ff1c3d39261633ea6120dce93bafaf4532ba Mon Sep 17 00:00:00 2001 From: Conor Barnes Date: Mon, 29 Aug 2022 20:32:32 -0300 Subject: [PATCH 14/55] width substitute --- packages/components/src/lib/distributionSpecBuilder.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/packages/components/src/lib/distributionSpecBuilder.ts b/packages/components/src/lib/distributionSpecBuilder.ts index 9f3cf02a..3476abeb 100644 --- a/packages/components/src/lib/distributionSpecBuilder.ts +++ b/packages/components/src/lib/distributionSpecBuilder.ts @@ -72,6 +72,7 @@ export const expYScale: PowScale = { export const defaultTickFormat = ".9~s"; export const timeTickFormat = "%b %d, %Y %H:%M"; +const width = 500; export function buildVegaSpec( specOptions: DistributionChartSpecOptions @@ -108,7 +109,7 @@ export function buildVegaSpec( const spec: VisualizationSpec = { $schema: "https://vega.github.io/schema/vega/v5.json", description: "Squiggle plot chart", - width: 500, + width: width, height: 100, padding: 5, data: [{ name: "data" }, { name: "domain" }], @@ -133,8 +134,6 @@ export function buildVegaSpec( name: "position_scaled", value: null, update: "isArray(position) ? invert('xscale', position[0]) : ''", - // value: 0, - // update: "position ? invert('xscale', position[0]) : null", }, ], scales: [ @@ -309,7 +308,7 @@ export function buildVegaSpec( interactive: false, encode: { enter: { - x: { signal: "width", offset: 1 }, + x: { signal: String(width), offset: 1 }, // vega would prefer its internal ` "width" ` variable, but that breaks the squiggle playground. Just setting it to the same var as used elsewhere in the spec achieves the same result. fill: { value: "black" }, fontSize: { value: 20 }, align: { value: "right" }, From a1db813b8b7cbd610745d41aa524af12b448bb3f Mon Sep 17 00:00:00 2001 From: Conor Barnes Date: Mon, 29 Aug 2022 21:11:48 -0300 Subject: [PATCH 15/55] pr comment tweaks --- packages/components/src/components/DistributionChart.tsx | 7 ++----- packages/components/src/components/SquiggleChart.tsx | 2 +- packages/components/src/lib/distributionSpecBuilder.ts | 2 -- packages/components/src/stories/SquiggleChart.stories.mdx | 1 + 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index b570f4e6..1cedc372 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -30,7 +30,7 @@ export type DistributionChartProps = { plot: Plot; width?: number; height: number; - sample: boolean; + sample?: boolean; xAxis?: "number" | "dateTime"; } & DistributionPlottingSettings; @@ -57,7 +57,6 @@ export const DistributionChart: React.FC = (props) => { actions = false, xAxis = "number", } = props; - console.log({ plot }); const [sized] = useSize((size) => { const shapes = flattenResult( plot.distributions.map((x) => @@ -93,9 +92,7 @@ export const DistributionChart: React.FC = (props) => { const domain = xAxis === "dateTime" - ? predomain.map((p) => { - return { dateTime: p.x, y: p.y }; - }) + ? predomain.map((p) => ({ dateTime: p.x, y: p.y })) : predomain; const data = diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index 5baae229..7bc2e737 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -51,7 +51,7 @@ export interface SquiggleChartProps { minX?: number; /** Specify the upper bound of the x scale */ maxX?: number; - /** Whether the x-axis should be dates or numbers */ + // /** Whether the x-axis should be dates or numbers */ xAxis?: "number" | "dateTime"; /** Whether to show vega actions to the user, so they can copy the chart spec */ distributionChartActions?: boolean; diff --git a/packages/components/src/lib/distributionSpecBuilder.ts b/packages/components/src/lib/distributionSpecBuilder.ts index 3476abeb..b1f49f23 100644 --- a/packages/components/src/lib/distributionSpecBuilder.ts +++ b/packages/components/src/lib/distributionSpecBuilder.ts @@ -14,10 +14,8 @@ export type DistributionChartSpecOptions = { title?: string; /** The formatting of the ticks */ format?: string; - /** Whether or not to show the band of sample data at the bottom */ sample?: boolean; - /** Whether the x-axis should be dates or numbers */ xAxis?: "number" | "dateTime"; }; diff --git a/packages/components/src/stories/SquiggleChart.stories.mdx b/packages/components/src/stories/SquiggleChart.stories.mdx index 3dc74761..2a4aa48d 100644 --- a/packages/components/src/stories/SquiggleChart.stories.mdx +++ b/packages/components/src/stories/SquiggleChart.stories.mdx @@ -88,6 +88,7 @@ could be continuous, discrete or mixed. code: "mx(10^12, 10^12 + 10^11, 10^12 + 2 * 10^11)", width, xAxis: "dateTime", + width, }} > {Template.bind({})} From 07b7b26d605d18164910371cf77a2d0066a8d754 Mon Sep 17 00:00:00 2001 From: Conor Barnes Date: Tue, 30 Aug 2022 09:14:25 -0300 Subject: [PATCH 16/55] include sample band on sampleset story --- packages/components/src/components/DistributionChart.tsx | 2 ++ packages/components/src/components/SquiggleChart.tsx | 8 ++++++-- packages/components/src/lib/distributionSpecBuilder.ts | 1 + packages/components/src/stories/SquiggleChart.stories.mdx | 3 ++- 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index 1cedc372..1a055ea9 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -110,6 +110,8 @@ export const DistributionChart: React.FC = (props) => { }) : shapes.value; + console.log({ data }); + return (
{logX && shapes.value.some(hasMassBelowZero) ? ( diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index 7bc2e737..2d05c1be 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -51,7 +51,9 @@ export interface SquiggleChartProps { minX?: number; /** Specify the upper bound of the x scale */ maxX?: number; - // /** Whether the x-axis should be dates or numbers */ + // /** Whether to include the sample band below the chart */ + sample?: boolean; + /** Whether the x-axis should be dates or numbers */ xAxis?: "number" | "dateTime"; /** Whether to show vega actions to the user, so they can copy the chart spec */ distributionChartActions?: boolean; @@ -81,6 +83,7 @@ export const SquiggleChart: React.FC = React.memo( maxX, color, title, + sample = false, xAxis = "number", distributionChartActions, enableLocalSettings = false, @@ -93,7 +96,7 @@ export const SquiggleChart: React.FC = React.memo( onChange, executionId, }); - + console.log({ result }); const distributionPlotSettings = { showSummary, logX, @@ -104,6 +107,7 @@ export const SquiggleChart: React.FC = React.memo( color, title, xAxis, + sample, actions: distributionChartActions, }; diff --git a/packages/components/src/lib/distributionSpecBuilder.ts b/packages/components/src/lib/distributionSpecBuilder.ts index b1f49f23..07253c4c 100644 --- a/packages/components/src/lib/distributionSpecBuilder.ts +++ b/packages/components/src/lib/distributionSpecBuilder.ts @@ -218,6 +218,7 @@ export function buildVegaSpec( }, }, }, + ], }, { diff --git a/packages/components/src/stories/SquiggleChart.stories.mdx b/packages/components/src/stories/SquiggleChart.stories.mdx index 2a4aa48d..72f708d7 100644 --- a/packages/components/src/stories/SquiggleChart.stories.mdx +++ b/packages/components/src/stories/SquiggleChart.stories.mdx @@ -59,6 +59,7 @@ could be continuous, discrete or mixed. args={{ code: "SampleSet.fromDist(normal(5,2))", width, + sample: true, }} > {Template.bind({})} @@ -85,7 +86,7 @@ could be continuous, discrete or mixed. Date: Wed, 31 Aug 2022 11:19:11 -0300 Subject: [PATCH 17/55] more elegantly handle samples, properly use sample data in SampleSets for bands --- .../src/components/DistributionChart.tsx | 13 +++- .../src/components/SquiggleChart.tsx | 6 +- .../src/lib/distributionSpecBuilder.ts | 65 +++++++++---------- .../src/stories/SquiggleChart.stories.mdx | 1 - 4 files changed, 42 insertions(+), 43 deletions(-) diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index 1a055ea9..a6f2608c 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -19,6 +19,7 @@ import { NumberShower } from "./NumberShower"; import { Plot, parsePlot } from "../lib/plotParser"; import { flattenResult } from "../lib/utility"; import { hasMassBelowZero } from "../lib/distributionUtils"; +import { point } from "@quri/squiggle-lang/src/js/distribution"; export type DistributionPlottingSettings = { /** Whether to show a summary of means, stdev, percentiles etc */ @@ -65,6 +66,7 @@ export const DistributionChart: React.FC = (props) => { // color: x.color, // not supported yet continuous: shape.continuous, discrete: shape.discrete, + samples: [] as point[], })) ) ); @@ -77,6 +79,12 @@ export const DistributionChart: React.FC = (props) => { ); } + // if this is a sample set, include the samples + const t = plot?.distributions[0]?.distribution?.t; + if (t.tag === "SampleSet") { + shapes.value[0].samples = t.value.map((v) => ({ x: v, y: 0 })); + } + const spec = buildVegaSpec(props); let widthProp = width ? width : size.width; @@ -106,12 +114,13 @@ export const DistributionChart: React.FC = (props) => { discrete: val.discrete.map((p) => { return { dateTime: p.x, y: p.y }; }), + samples: val.samples.map((p) => { + return { dateTime: p, y: 0 }; + }), }; }) : shapes.value; - console.log({ data }); - return (
{logX && shapes.value.some(hasMassBelowZero) ? ( diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index 2d05c1be..7b651e8f 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -51,8 +51,6 @@ export interface SquiggleChartProps { minX?: number; /** Specify the upper bound of the x scale */ maxX?: number; - // /** Whether to include the sample band below the chart */ - sample?: boolean; /** Whether the x-axis should be dates or numbers */ xAxis?: "number" | "dateTime"; /** Whether to show vega actions to the user, so they can copy the chart spec */ @@ -83,7 +81,6 @@ export const SquiggleChart: React.FC = React.memo( maxX, color, title, - sample = false, xAxis = "number", distributionChartActions, enableLocalSettings = false, @@ -96,7 +93,7 @@ export const SquiggleChart: React.FC = React.memo( onChange, executionId, }); - console.log({ result }); + const distributionPlotSettings = { showSummary, logX, @@ -107,7 +104,6 @@ export const SquiggleChart: React.FC = React.memo( color, title, xAxis, - sample, actions: distributionChartActions, }; diff --git a/packages/components/src/lib/distributionSpecBuilder.ts b/packages/components/src/lib/distributionSpecBuilder.ts index 07253c4c..b4e79609 100644 --- a/packages/components/src/lib/distributionSpecBuilder.ts +++ b/packages/components/src/lib/distributionSpecBuilder.ts @@ -81,7 +81,6 @@ export function buildVegaSpec( maxX, logX, expY, - sample = false, xAxis = "number", } = specOptions; @@ -110,7 +109,7 @@ export function buildVegaSpec( width: width, height: 100, padding: 5, - data: [{ name: "data" }, { name: "domain" }], + data: [{ name: "data" }, { name: "domain" }, { name: "samples" }], signals: [ { name: "hover", @@ -218,7 +217,6 @@ export function buildVegaSpec( }, }, }, - ], }, { @@ -299,6 +297,35 @@ export function buildVegaSpec( }, ], }, + { + name: "sample_distributions", + type: "group", + from: { + facet: { + name: "sample_facet", + data: "distribution_facet", + field: "samples", + }, + }, + marks: [ + { + name: "samples", + type: "rect", + from: { data: "sample_facet" }, + encode: { + enter: { + x: { scale: "xscale", field: dateTime ? "dateTime" : "x" }, + width: { value: 0.1 }, + + y: { value: 25, offset: { signal: "height" } }, + height: { value: 5 }, + fill: { value: "steelblue" }, + fillOpacity: { value: 1 }, + }, + }, + }, + ], + }, ], }, { @@ -384,37 +411,5 @@ export function buildVegaSpec( }), }; - // include the band at the bottom if specified in the React component - if (sample) { - spec.marks?.push({ - name: "sample_distributions", - type: "group", - from: { - facet: { - name: "distribution_facet", - data: "domain", - groupby: ["name"], - }, - }, - marks: [ - { - name: "samples", - type: "rect", - from: { data: "distribution_facet" }, - encode: { - enter: { - x: { scale: "xscale", field: dateTime ? "dateTime" : "x" }, - width: { value: 0.5 }, - - y: { value: 25, offset: { signal: "height" } }, - height: { value: 5 }, - fill: { value: "steelblue" }, - fillOpacity: { value: 0.8 }, - }, - }, - }, - ], - }); - } return spec; } diff --git a/packages/components/src/stories/SquiggleChart.stories.mdx b/packages/components/src/stories/SquiggleChart.stories.mdx index 72f708d7..887146f0 100644 --- a/packages/components/src/stories/SquiggleChart.stories.mdx +++ b/packages/components/src/stories/SquiggleChart.stories.mdx @@ -59,7 +59,6 @@ could be continuous, discrete or mixed. args={{ code: "SampleSet.fromDist(normal(5,2))", width, - sample: true, }} > {Template.bind({})} From 2087a30b6bbd5c09693baafc09b5ebf3d139c236 Mon Sep 17 00:00:00 2001 From: Conor Barnes Date: Wed, 31 Aug 2022 12:15:43 -0300 Subject: [PATCH 18/55] use in multiple plots --- .../src/components/DistributionChart.tsx | 16 ++++++++++++---- .../src/lib/distributionSpecBuilder.ts | 14 +++++--------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index a6f2608c..7b05d65f 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -80,11 +80,19 @@ export const DistributionChart: React.FC = (props) => { } // if this is a sample set, include the samples - const t = plot?.distributions[0]?.distribution?.t; - if (t.tag === "SampleSet") { - shapes.value[0].samples = t.value.map((v) => ({ x: v, y: 0 })); + const sampleSets = plot?.distributions.filter( + (dist) => dist.distribution.t.tag === "SampleSet" + ); + if (sampleSets.length) { + for (const set of sampleSets) { + if (set.distribution.t.tag === "SampleSet") { // this must be duplicated to please typescript, more elegant solution probably exists + shapes.value[0].samples.push( + ...set.distribution.t.value.map((v) => ({ x: v, y: 0 })) + ); + } + } } - + const spec = buildVegaSpec(props); let widthProp = width ? width : size.width; diff --git a/packages/components/src/lib/distributionSpecBuilder.ts b/packages/components/src/lib/distributionSpecBuilder.ts index b4e79609..06b23919 100644 --- a/packages/components/src/lib/distributionSpecBuilder.ts +++ b/packages/components/src/lib/distributionSpecBuilder.ts @@ -75,14 +75,7 @@ const width = 500; export function buildVegaSpec( specOptions: DistributionChartSpecOptions ): VisualizationSpec { - const { - title, - minX, - maxX, - logX, - expY, - xAxis = "number", - } = specOptions; + const { title, minX, maxX, logX, expY, xAxis = "number" } = specOptions; const dateTime = xAxis === "dateTime"; @@ -319,7 +312,10 @@ export function buildVegaSpec( y: { value: 25, offset: { signal: "height" } }, height: { value: 5 }, - fill: { value: "steelblue" }, + fill: { + scale: "color", + field: { parent: "name" }, + }, fillOpacity: { value: 1 }, }, }, From 3ea747fae4ba82dc4a225e15afc88b14f779f807 Mon Sep 17 00:00:00 2001 From: Conor Barnes Date: Tue, 6 Sep 2022 14:27:01 -0300 Subject: [PATCH 19/55] simplify code by not mapping x property to dateTime property --- .../src/components/DistributionChart.tsx | 30 +++---------------- .../src/lib/distributionSpecBuilder.ts | 17 ++++++----- 2 files changed, 13 insertions(+), 34 deletions(-) diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index 7b05d65f..0eabd0f6 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -85,7 +85,8 @@ export const DistributionChart: React.FC = (props) => { ); if (sampleSets.length) { for (const set of sampleSets) { - if (set.distribution.t.tag === "SampleSet") { // this must be duplicated to please typescript, more elegant solution probably exists + if (set.distribution.t.tag === "SampleSet") { + // this must be duplicated to please typescript, more elegant solution probably exists shapes.value[0].samples.push( ...set.distribution.t.value.map((v) => ({ x: v, y: 0 })) ); @@ -102,33 +103,10 @@ export const DistributionChart: React.FC = (props) => { ); widthProp = 20; } - const predomain = shapes.value.flatMap((shape) => + const domain = shapes.value.flatMap((shape) => shape.discrete.concat(shape.continuous) ); - const domain = - xAxis === "dateTime" - ? predomain.map((p) => ({ dateTime: p.x, y: p.y })) - : predomain; - - const data = - xAxis === "dateTime" - ? shapes.value.map((val) => { - return { - ...val, - continuous: val.continuous.map((p) => { - return { dateTime: p.x, y: p.y }; - }), - discrete: val.discrete.map((p) => { - return { dateTime: p.x, y: p.y }; - }), - samples: val.samples.map((p) => { - return { dateTime: p, y: 0 }; - }), - }; - }) - : shapes.value; - return (
{logX && shapes.value.some(hasMassBelowZero) ? ( @@ -138,7 +116,7 @@ export const DistributionChart: React.FC = (props) => { ) : ( width ? 0 : 1 : 0", }, - // opacity: { signal: "position ? 1 : 0" }, }, }, }, From 6c87a9e712ae8a294abef5896dd775ee9c5f250a Mon Sep 17 00:00:00 2001 From: Conor Barnes Date: Tue, 6 Sep 2022 14:30:52 -0300 Subject: [PATCH 20/55] rename to xAxisType --- .../src/components/DistributionChart.tsx | 4 ++-- .../src/components/SquiggleChart.tsx | 6 +++--- .../src/lib/distributionSpecBuilder.ts | 21 ++++++++++++------- .../src/stories/SquiggleChart.stories.mdx | 2 +- 4 files changed, 20 insertions(+), 13 deletions(-) diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index 0eabd0f6..fb0ff95c 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -32,7 +32,7 @@ export type DistributionChartProps = { width?: number; height: number; sample?: boolean; - xAxis?: "number" | "dateTime"; + xAxisType?: "number" | "dateTime"; } & DistributionPlottingSettings; export function defaultPlot(distribution: Distribution): Plot { @@ -56,7 +56,7 @@ export const DistributionChart: React.FC = (props) => { width, logX, actions = false, - xAxis = "number", + xAxisType = "number", } = props; const [sized] = useSize((size) => { const shapes = flattenResult( diff --git a/packages/components/src/components/SquiggleChart.tsx b/packages/components/src/components/SquiggleChart.tsx index 7b651e8f..e68ba427 100644 --- a/packages/components/src/components/SquiggleChart.tsx +++ b/packages/components/src/components/SquiggleChart.tsx @@ -52,7 +52,7 @@ export interface SquiggleChartProps { /** Specify the upper bound of the x scale */ maxX?: number; /** Whether the x-axis should be dates or numbers */ - xAxis?: "number" | "dateTime"; + xAxisType?: "number" | "dateTime"; /** Whether to show vega actions to the user, so they can copy the chart spec */ distributionChartActions?: boolean; enableLocalSettings?: boolean; @@ -81,7 +81,7 @@ export const SquiggleChart: React.FC = React.memo( maxX, color, title, - xAxis = "number", + xAxisType = "number", distributionChartActions, enableLocalSettings = false, }) => { @@ -103,7 +103,7 @@ export const SquiggleChart: React.FC = React.memo( maxX, color, title, - xAxis, + xAxisType, actions: distributionChartActions, }; diff --git a/packages/components/src/lib/distributionSpecBuilder.ts b/packages/components/src/lib/distributionSpecBuilder.ts index 170eb44c..261545b5 100644 --- a/packages/components/src/lib/distributionSpecBuilder.ts +++ b/packages/components/src/lib/distributionSpecBuilder.ts @@ -17,10 +17,10 @@ export type DistributionChartSpecOptions = { /** Whether or not to show the band of sample data at the bottom */ sample?: boolean; /** Whether the x-axis should be dates or numbers */ - xAxis?: "number" | "dateTime"; + xAxisType?: "number" | "dateTime"; }; -/** X Scales */ +/** X Scales */ export const linearXScale: LinearScale = { name: "xscale", clamp: true, @@ -51,7 +51,7 @@ export const timeXScale: TimeScale = { domain: { data: "domain", field: "x" }, }; -/** Y Scales */ +/** Y Scales */ export const linearYScale: LinearScale = { name: "yscale", type: "linear", @@ -77,9 +77,16 @@ const width = 500; export function buildVegaSpec( specOptions: DistributionChartSpecOptions ): VisualizationSpec { - const { title, minX, maxX, logX, expY, xAxis = "number" } = specOptions; + const { + title, + minX, + maxX, + logX, + expY, + xAxisType = "number", + } = specOptions; - const dateTime = xAxis === "dateTime"; + const dateTime = xAxisType === "dateTime"; // some fallbacks const format = specOptions?.format @@ -270,13 +277,13 @@ export function buildVegaSpec( tooltip: { signal: dateTime ? "{ probability: datum.y, value: datetime(datum.x) }" - : "{ probability: datum.y, value: datum.x }", + : "{ probability: datum.y, value: datum.x }", }, }, update: { x: { scale: "xscale", - field: "x", + field: "x", offset: 0.5, // if this is not included, the circles are slightly left of center. }, y: { diff --git a/packages/components/src/stories/SquiggleChart.stories.mdx b/packages/components/src/stories/SquiggleChart.stories.mdx index 887146f0..45fec12e 100644 --- a/packages/components/src/stories/SquiggleChart.stories.mdx +++ b/packages/components/src/stories/SquiggleChart.stories.mdx @@ -87,7 +87,7 @@ could be continuous, discrete or mixed. args={{ code: "mx(1661819770311, 1661829770311, 1661839770311)", width, - xAxis: "dateTime", + xAxisType: "dateTime", width, }} > From e0cd95fe5ca0ea9c758cf535b6e218c2e6168592 Mon Sep 17 00:00:00 2001 From: Conor Barnes Date: Tue, 6 Sep 2022 14:52:57 -0300 Subject: [PATCH 21/55] remove unnecessary mapping of sample array to array of objects --- .../components/src/components/DistributionChart.tsx | 10 +++++----- packages/components/src/lib/distributionSpecBuilder.ts | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index fb0ff95c..d423b197 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -66,7 +66,8 @@ export const DistributionChart: React.FC = (props) => { // color: x.color, // not supported yet continuous: shape.continuous, discrete: shape.discrete, - samples: [] as point[], + samples: [] as number[], + // samples: [] as point[], })) ) ); @@ -86,14 +87,13 @@ export const DistributionChart: React.FC = (props) => { if (sampleSets.length) { for (const set of sampleSets) { if (set.distribution.t.tag === "SampleSet") { - // this must be duplicated to please typescript, more elegant solution probably exists - shapes.value[0].samples.push( - ...set.distribution.t.value.map((v) => ({ x: v, y: 0 })) - ); + // this conditional must be duplicated to please typescript, more elegant solution probably exists + shapes.value[0].samples.push(...set.distribution.t.value); } } } + console.log(shapes.value); const spec = buildVegaSpec(props); let widthProp = width ? width : size.width; diff --git a/packages/components/src/lib/distributionSpecBuilder.ts b/packages/components/src/lib/distributionSpecBuilder.ts index 261545b5..2880aa4b 100644 --- a/packages/components/src/lib/distributionSpecBuilder.ts +++ b/packages/components/src/lib/distributionSpecBuilder.ts @@ -316,7 +316,7 @@ export function buildVegaSpec( from: { data: "sample_facet" }, encode: { enter: { - x: { scale: "xscale", field: "x" }, + x: { scale: "xscale", field: "data"}, width: { value: 0.1 }, y: { value: 25, offset: { signal: "height" } }, From 0c614a3fcfef9290da78ce76d4dfb47386d8d73f Mon Sep 17 00:00:00 2001 From: Conor Barnes Date: Wed, 7 Sep 2022 09:18:01 -0300 Subject: [PATCH 22/55] samples in own shape --- .../src/components/DistributionChart.tsx | 9 +-- .../src/components/SquiggleChart.tsx | 2 +- .../src/lib/distributionSpecBuilder.ts | 58 +++++-------------- 3 files changed, 22 insertions(+), 47 deletions(-) diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index 90cb4f1e..d1773993 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -32,7 +32,6 @@ export type DistributionChartProps = { environment: environment; width?: number; height: number; - sample?: boolean; xAxisType?: "number" | "dateTime"; } & DistributionPlottingSettings; @@ -64,7 +63,7 @@ export const DistributionChart: React.FC = (props) => { name: x.name, // color: x.color, // not supported yet ...pointSet.asShape(), - samples: [] as number[], + // samples: [] as number[], })) ) ); @@ -78,6 +77,7 @@ export const DistributionChart: React.FC = (props) => { } // if this is a sample set, include the samples + const samples: number[] = []; const sampleSets = plot?.distributions.filter( (dist) => dist.distribution.tag === SqDistributionTag.SampleSet ); @@ -85,7 +85,8 @@ export const DistributionChart: React.FC = (props) => { for (const { distribution } of sampleSets) { if (distribution.tag === SqDistributionTag.SampleSet) { // this conditional must be duplicated to please typescript, more elegant solution probably exists - shapes.value[0].samples.push(...distribution.value()); + samples.push(...distribution.value()); + // shapes.value[0].samples.push(...distribution.value()); } } } @@ -112,7 +113,7 @@ export const DistributionChart: React.FC = (props) => { ) : ( = React.memo( onChange, executionId, }); - + const distributionPlotSettings = { showSummary, logX, diff --git a/packages/components/src/lib/distributionSpecBuilder.ts b/packages/components/src/lib/distributionSpecBuilder.ts index 2880aa4b..d48078d3 100644 --- a/packages/components/src/lib/distributionSpecBuilder.ts +++ b/packages/components/src/lib/distributionSpecBuilder.ts @@ -14,8 +14,6 @@ export type DistributionChartSpecOptions = { title?: string; /** The formatting of the ticks */ format?: string; - /** Whether or not to show the band of sample data at the bottom */ - sample?: boolean; /** Whether the x-axis should be dates or numbers */ xAxisType?: "number" | "dateTime"; }; @@ -77,14 +75,7 @@ const width = 500; export function buildVegaSpec( specOptions: DistributionChartSpecOptions ): VisualizationSpec { - const { - title, - minX, - maxX, - logX, - expY, - xAxisType = "number", - } = specOptions; + const { title, minX, maxX, logX, expY, xAxisType = "number" } = specOptions; const dateTime = xAxisType === "dateTime"; @@ -299,40 +290,23 @@ export function buildVegaSpec( }, ], }, - { - name: "sample_distributions", - type: "group", - from: { - facet: { - name: "sample_facet", - data: "distribution_facet", - field: "samples", - }, - }, - marks: [ - { - name: "samples", - type: "rect", - from: { data: "sample_facet" }, - encode: { - enter: { - x: { scale: "xscale", field: "data"}, - width: { value: 0.1 }, - - y: { value: 25, offset: { signal: "height" } }, - height: { value: 5 }, - fill: { - scale: "color", - field: { parent: "name" }, - }, - fillOpacity: { value: 1 }, - }, - }, - }, - ], - }, ], }, + + { + name: "sampleset", + type: "rect", + from: { data: "samples" }, + encode: { + enter: { + x: { scale: "xscale", field: "data" }, + width: { value: 0.1 }, + + y: { value: 25, offset: { signal: "height" } }, + height: { value: 5 }, + }, + }, + }, { type: "text", name: "announcer", From 5b0d7a898fe5e35236c6384a4cece7074eda728e Mon Sep 17 00:00:00 2001 From: Conor Barnes Date: Wed, 7 Sep 2022 11:01:18 -0300 Subject: [PATCH 23/55] remove dead comments and simplify sample inclusion --- .../src/components/DistributionChart.tsx | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/packages/components/src/components/DistributionChart.tsx b/packages/components/src/components/DistributionChart.tsx index d1773993..61ee3c5b 100644 --- a/packages/components/src/components/DistributionChart.tsx +++ b/packages/components/src/components/DistributionChart.tsx @@ -63,7 +63,6 @@ export const DistributionChart: React.FC = (props) => { name: x.name, // color: x.color, // not supported yet ...pointSet.asShape(), - // samples: [] as number[], })) ) ); @@ -78,16 +77,9 @@ export const DistributionChart: React.FC = (props) => { // if this is a sample set, include the samples const samples: number[] = []; - const sampleSets = plot?.distributions.filter( - (dist) => dist.distribution.tag === SqDistributionTag.SampleSet - ); - if (sampleSets.length) { - for (const { distribution } of sampleSets) { - if (distribution.tag === SqDistributionTag.SampleSet) { - // this conditional must be duplicated to please typescript, more elegant solution probably exists - samples.push(...distribution.value()); - // shapes.value[0].samples.push(...distribution.value()); - } + for (const { distribution } of plot?.distributions) { + if (distribution.tag === SqDistributionTag.SampleSet) { + samples.push(...distribution.value()); } } From c0ccdbc1e9d98a89eb09f0d6b67d64d799a999f6 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Wed, 7 Sep 2022 22:45:19 +0400 Subject: [PATCH 24/55] experimental: replace result with exceptions in reducer --- .../Reducer/Reducer_TestMacroHelpers.res | 16 ++-- ...educer_Type_TypeChecker_arguments_test.res | 2 +- .../Reducer_Type_TypeChecker_test.res | 2 +- .../FunctionRegistry/Library/FR_Danger.res | 16 ++-- .../FunctionRegistry/Library/FR_List.res | 80 ++++++++---------- .../FunctionRegistry/Library/FR_Pointset.res | 2 +- .../FunctionRegistry/Library/FR_Sampleset.res | 2 +- .../Reducer_Dispatch_BuiltIn.res | 15 ++-- .../Reducer_Dispatch_BuiltInMacros.res | 81 ++++++++----------- .../rescript/Reducer/Reducer_ErrorValue.res | 2 + .../Reducer_Expression/Reducer_Expression.res | 61 ++++++-------- .../Reducer_ExpressionWithContext.res | 2 +- .../Reducer_Expression_BindingsReplacer.res | 28 +++---- .../Reducer_Expression_Lambda.res | 38 +++++---- .../Reducer_Expression_Macro.res | 21 +---- .../Reducer_Type/Reducer_Type_Compile.res | 10 +-- .../ReducerProject_ProjectItem.res | 28 ++++--- .../ReducerProject_ReducerFn_T.res | 2 +- 18 files changed, 178 insertions(+), 230 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res index 752cc9c7..363d33c7 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res @@ -17,17 +17,22 @@ let testMacro_ = ( expectedCode: string, ) => { let bindings = Bindings.fromArray(bindArray) - tester(expr->T.toString, () => - expr - ->Macro.expandMacroCall( + tester(expr->T.toString, () => { + let result = switch expr + ->Reducer_Dispatch_BuiltInMacros.dispatchMacroCall( bindings, ProjectAccessorsT.identityAccessors, Expression.reduceExpressionInProject, - ) + ) { + | v => Ok(v) + | exception Reducer_ErrorValue.ErrorException(e) => Error(e) + } + + result ->ExpressionWithContext.toStringResult ->expect ->toEqual(expectedCode) - ) + }) } let testMacroEval_ = ( @@ -44,6 +49,7 @@ let testMacroEval_ = ( ProjectAccessorsT.identityAccessors, Expression.reduceExpressionInProject, ) + ->Ok ->InternalExpressionValue.toStringResult ->expect ->toEqual(expectedValue) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res index 29fa8249..957024cb 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res @@ -16,7 +16,7 @@ let checkArgumentsSourceCode = (aTypeSourceCode: string, sourceCode: string): re > => { let reducerFn = Expression.reduceExpressionInProject let rResult = - Expression.BackCompatible.parse(sourceCode)->Belt.Result.flatMap(expr => + Expression.BackCompatible.parse(sourceCode)->Belt.Result.map(expr => reducerFn(expr, Bindings.emptyBindings, ProjectAccessorsT.identityAccessors) ) rResult->Belt.Result.flatMap(result => diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res index fccff738..d5726d5d 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res @@ -19,7 +19,7 @@ let isTypeOfSourceCode = (aTypeSourceCode: string, sourceCode: string): result< > => { let reducerFn = Expression.reduceExpressionInProject let rResult = - Expression.BackCompatible.parse(sourceCode)->Belt.Result.flatMap(expr => + Expression.BackCompatible.parse(sourceCode)->Belt.Result.map(expr => reducerFn(expr, Bindings.emptyBindings, ProjectAccessorsT.identityAccessors) ) rResult->Belt.Result.flatMap(result => TypeChecker.isTypeOf(aTypeSourceCode, result, reducerFn)) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Danger.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Danger.res index 95f9ba44..df3a91de 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Danger.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Danger.res @@ -74,12 +74,11 @@ module Integration = { reducer, ) let result = switch resultAsInternalExpression { - | Ok(IEvNumber(x)) => Ok(x) - | Error(_) => + | IEvNumber(x) => Ok(x) + | _ => Error( "Error 1 in Danger.integrate. It's possible that your function doesn't return a number, try definining auxiliaryFunction(x) = mean(yourFunction(x)) and integrate auxiliaryFunction instead", ) - | _ => Error("Error 2 in Danger.integrate") } result } @@ -143,7 +142,7 @@ module Integration = { } | Error(b) => Error( - "Integration error 3 in Danger.integrate. It's possible that your function doesn't return a number, try definining auxiliaryFunction(x) = mean(yourFunction(x)) and integrate auxiliaryFunction instead." ++ + "Integration error 2 in Danger.integrate. It's possible that your function doesn't return a number, try definining auxiliaryFunction(x) = mean(yourFunction(x)) and integrate auxiliaryFunction instead." ++ "Original error: " ++ b, ) @@ -310,15 +309,10 @@ module DiminishingReturns = { reducer, ) switch resultAsInternalExpression { - | Ok(IEvNumber(x)) => Ok(x) - | Error(_) => - Error( + | IEvNumber(x) => Ok(x) + | _ => Error( "Error 1 in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions. It's possible that your function doesn't return a number, try definining auxiliaryFunction(x) = mean(yourFunction(x)) and integrate auxiliaryFunction instead", ) - | _ => - Error( - "Error 2 in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions", - ) } } diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res index 63b7b3f4..733c2f86 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res @@ -32,19 +32,17 @@ module Internals = { accessors: ProjectAccessorsT.t, eLambdaValue, reducer: ProjectReducerFnT.t, - ): result => { - let rMappedList = array->E.A.reduceReverse(Ok(list{}), (rAcc, elem) => - rAcc->E.R.bind(_, acc => { - let rNewElem = Reducer_Expression_Lambda.doLambdaCall( - eLambdaValue, - list{elem}, - (accessors: ProjectAccessorsT.t), - (reducer: ProjectReducerFnT.t), - ) - rNewElem->E.R2.fmap(newElem => list{newElem, ...acc}) - }) - ) - rMappedList->E.R2.fmap(mappedList => mappedList->Belt.List.toArray->Wrappers.evArray) + ): ReducerInterface_InternalExpressionValue.t => { + let mappedList = array->E.A.reduceReverse(list{}, (acc, elem) => { + let newElem = Reducer_Expression_Lambda.doLambdaCall( + eLambdaValue, + list{elem}, + (accessors: ProjectAccessorsT.t), + (reducer: ProjectReducerFnT.t), + ) + list{newElem, ...acc} + }) + mappedList->Belt.List.toArray->Wrappers.evArray } let reduce = ( @@ -54,10 +52,8 @@ module Internals = { accessors: ProjectAccessorsT.t, reducer: ProjectReducerFnT.t, ) => { - aValueArray->E.A.reduce(Ok(initialValue), (rAcc, elem) => - rAcc->E.R.bind(_, acc => - Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, accessors, reducer) - ) + aValueArray->E.A.reduce(initialValue, (acc, elem) => + Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, accessors, reducer) ) } @@ -68,10 +64,8 @@ module Internals = { accessors: ProjectAccessorsT.t, reducer: ProjectReducerFnT.t, ) => { - aValueArray->Belt.Array.reduceReverse(Ok(initialValue), (rAcc, elem) => - rAcc->Belt.Result.flatMap(acc => - Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, accessors, reducer) - ) + aValueArray->Belt.Array.reduceReverse(initialValue, (acc, elem) => + Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, accessors, reducer) ) } @@ -81,25 +75,19 @@ module Internals = { accessors: ProjectAccessorsT.t, reducer: ProjectReducerFnT.t, ) => { - let rMappedList = aValueArray->Belt.Array.reduceReverse(Ok(list{}), (rAcc, elem) => - rAcc->E.R.bind(_, acc => { - let rNewElem = Reducer_Expression_Lambda.doLambdaCall( - aLambdaValue, - list{elem}, - accessors, - reducer, - ) - rNewElem->E.R2.fmap(newElem => { - switch newElem { - | IEvBool(true) => list{elem, ...acc} - | _ => acc - } - }) - }) - ) - let result = - rMappedList->E.R2.fmap(mappedList => mappedList->Belt.List.toArray->Wrappers.evArray) - result + let mappedList = aValueArray->Belt.Array.reduceReverse(list{}, (acc, elem) => { + let newElem = Reducer_Expression_Lambda.doLambdaCall( + aLambdaValue, + list{elem}, + accessors, + reducer, + ) + switch newElem { + | IEvBool(true) => list{elem, ...acc} + | _ => acc + } + }) + mappedList->Belt.List.toArray->Wrappers.evArray } } @@ -216,7 +204,7 @@ let library = [ ~run=(inputs, _, accessors: ProjectAccessorsT.t, reducer) => switch inputs { | [IEvArray(array), IEvLambda(lambda)] => - Internals.map(array, accessors, lambda, reducer)->E.R2.errMap(_ => "Error!") + Ok(Internals.map(array, accessors, lambda, reducer)) | _ => Error(impossibleError) }, (), @@ -236,9 +224,7 @@ let library = [ ~run=(inputs, _, accessors: ProjectAccessorsT.t, reducer) => switch inputs { | [IEvArray(array), initialValue, IEvLambda(lambda)] => - Internals.reduce(array, initialValue, lambda, accessors, reducer)->E.R2.errMap(_ => - "Error!" - ) + Ok(Internals.reduce(array, initialValue, lambda, accessors, reducer)) | _ => Error(impossibleError) }, (), @@ -258,13 +244,13 @@ let library = [ ~run=(inputs, _, accessors: ProjectAccessorsT.t, reducer: ProjectReducerFnT.t) => switch inputs { | [IEvArray(array), initialValue, IEvLambda(lambda)] => - Internals.reduceReverse( + Ok(Internals.reduceReverse( array, initialValue, lambda, accessors, reducer, - )->E.R2.errMap(_ => "Error!") + )) | _ => Error(impossibleError) }, (), @@ -284,7 +270,7 @@ let library = [ ~run=(inputs, _, accessors: ProjectAccessorsT.t, reducer: ProjectReducerFnT.t) => switch inputs { | [IEvArray(array), IEvLambda(lambda)] => - Internals.filter(array, lambda, accessors, reducer)->E.R2.errMap(_ => "Error!") + Ok(Internals.filter(array, lambda, accessors, reducer)) | _ => Error(impossibleError) }, (), diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res index 0d950ce5..ccc9a4a4 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res @@ -37,7 +37,7 @@ module Internal = { let doLambdaCall = (aLambdaValue, list, environment, reducer) => switch Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list, environment, reducer) { - | Ok(IEvNumber(f)) => Ok(f) + | IEvNumber(f) => Ok(f) | _ => Error(Operation.SampleMapNeedsNtoNFunction) } diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res index c3f56458..7d724a0f 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res @@ -16,7 +16,7 @@ module Internal = { reducer: ProjectReducerFnT.t, ) => switch Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list, accessors, reducer) { - | Ok(IEvNumber(f)) => Ok(f) + | IEvNumber(f) => Ok(f) | _ => Error(Operation.SampleMapNeedsNtoNFunction) } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index bec4a0da..4e0b60e7 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res @@ -13,6 +13,7 @@ module TypeBuilder = Reducer_Type_TypeBuilder open ReducerInterface_InternalExpressionValue open Reducer_ErrorValue + /* MathJs provides default implementations for built-ins This is where all the expected built-ins like + = * / sin cos log ln etc are handled @@ -111,7 +112,7 @@ let callInternal = ( module SampleMap = { let doLambdaCall = (aLambdaValue, list) => switch Lambda.doLambdaCall(aLambdaValue, list, accessors, reducer) { - | Ok(IEvNumber(f)) => Ok(f) + | IEvNumber(f) => Ok(f) | _ => Error(Operation.SampleMapNeedsNtoNFunction) } @@ -201,13 +202,17 @@ let dispatch = ( call: functionCall, accessors: ProjectAccessorsT.t, reducer: ProjectReducerFnT.t, -): result => +): internalExpressionValue => try { let (fn, args) = call // There is a bug that prevents string match in patterns // So we have to recreate a copy of the string - ExternalLibrary.dispatch((Js.String.make(fn), args), accessors, reducer, callInternal) + switch ExternalLibrary.dispatch((Js.String.make(fn), args), accessors, reducer, callInternal) { + | Ok(v) => v + | Error(e) => raise(ErrorException(e)) + } } catch { - | Js.Exn.Error(obj) => REJavaScriptExn(Js.Exn.message(obj), Js.Exn.name(obj))->Error - | _ => RETodo("unhandled rescript exception")->Error + | ErrorException(e) => raise(ErrorException(e)) + | Js.Exn.Error(obj) => raise(ErrorException(REJavaScriptExn(Js.Exn.message(obj), Js.Exn.name(obj)))) + | _ => raise(ErrorException(RETodo("unhandled rescript exception"))) } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index 978ca399..25f70fd8 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -12,11 +12,10 @@ module ExpressionWithContext = Reducer_ExpressionWithContext module InternalExpressionValue = ReducerInterface_InternalExpressionValue module ProjectAccessorsT = ReducerProject_ProjectAccessors_T module ProjectReducerFnT = ReducerProject_ReducerFn_T -module Result = Belt.Result open Reducer_Expression_ExpressionBuilder -type errorValue = ErrorValue.errorValue +exception ErrorException = ErrorValue.ErrorException type expression = ExpressionT.expression type expressionWithContext = ExpressionWithContext.expressionWithContext @@ -25,21 +24,18 @@ let dispatchMacroCall = ( bindings: ExpressionT.bindings, accessors: ProjectAccessorsT.t, reduceExpression: ProjectReducerFnT.t, -): result => { +): expressionWithContext => { let useExpressionToSetBindings = (bindingExpr: expression, accessors, statement, newCode) => { - let rExternalBindingsValue = reduceExpression(bindingExpr, bindings, accessors) + let nameSpaceValue = reduceExpression(bindingExpr, bindings, accessors) - rExternalBindingsValue->Result.flatMap(nameSpaceValue => { - let newBindings = Bindings.fromExpressionValue(nameSpaceValue) + let newBindings = Bindings.fromExpressionValue(nameSpaceValue) - let rNewStatement = BindingsReplacer.replaceSymbols(newBindings, statement) - rNewStatement->Result.map(boundStatement => - ExpressionWithContext.withContext( - newCode(newBindings->eModule, boundStatement), - newBindings, - ) - ) - }) + let boundStatement = BindingsReplacer.replaceSymbols(newBindings, statement) + + ExpressionWithContext.withContext( + newCode(newBindings->eModule, boundStatement), + newBindings, + ) } let correspondingSetBindingsFn = (fnName: string): string => @@ -52,7 +48,7 @@ let dispatchMacroCall = ( } let doBindStatement = (bindingExpr: expression, statement: expression, accessors) => { - let defaultStatement = ErrorValue.REAssignmentExpected->Error + let defaultStatement = ErrorValue.REAssignmentExpected->ErrorException switch statement { | ExpressionT.EList(list{ExpressionT.EValue(IEvCall(callName)), symbolExpr, statement}) => { let setBindingsFn = correspondingSetBindingsFn(callName) @@ -62,17 +58,14 @@ let dispatchMacroCall = ( boundStatement, ) => eFunction(setBindingsFn, list{newBindingsExpr, symbolExpr, boundStatement})) } else { - defaultStatement + raise(defaultStatement) } } - | _ => defaultStatement + | _ => raise(defaultStatement) } } - let doBindExpression = (bindingExpr: expression, statement: expression, accessors): result< - expressionWithContext, - errorValue, - > => { + let doBindExpression = (bindingExpr: expression, statement: expression, accessors): expressionWithContext => { let defaultStatement = () => useExpressionToSetBindings(bindingExpr, accessors, statement, ( _newBindingsExpr, @@ -100,10 +93,7 @@ let dispatchMacroCall = ( } } - let doBlock = (exprs: list, _bindings: ExpressionT.bindings, _accessors): result< - expressionWithContext, - errorValue, - > => { + let doBlock = (exprs: list, _bindings: ExpressionT.bindings, _accessors): expressionWithContext => { let exprsArray = Belt.List.toArray(exprs) let maxIndex = Js.Array2.length(exprsArray) - 1 let newStatement = exprsArray->Js.Array2.reducei((acc, statement, index) => @@ -119,14 +109,14 @@ let dispatchMacroCall = ( eBindStatement(acc, statement) } , eSymbol("undefined block")) - ExpressionWithContext.noContext(newStatement)->Ok + ExpressionWithContext.noContext(newStatement) } let doLambdaDefinition = ( bindings: ExpressionT.bindings, parameters: array, lambdaDefinition: ExpressionT.expression, - ) => ExpressionWithContext.noContext(eLambda(parameters, bindings, lambdaDefinition))->Ok + ) => ExpressionWithContext.noContext(eLambda(parameters, bindings, lambdaDefinition)) let doTernary = ( condition: expression, @@ -134,28 +124,25 @@ let dispatchMacroCall = ( ifFalse: expression, bindings: ExpressionT.bindings, accessors, - ): result => { + ): expressionWithContext => { let blockCondition = ExpressionBuilder.eBlock(list{condition}) - let rCondition = reduceExpression(blockCondition, bindings, accessors) - rCondition->Result.flatMap(conditionValue => - switch conditionValue { - | InternalExpressionValue.IEvBool(false) => { - let ifFalseBlock = eBlock(list{ifFalse}) - ExpressionWithContext.withContext(ifFalseBlock, bindings)->Ok - } - | InternalExpressionValue.IEvBool(true) => { - let ifTrueBlock = eBlock(list{ifTrue}) - ExpressionWithContext.withContext(ifTrueBlock, bindings)->Ok - } - | _ => REExpectedType("Boolean", "")->Error + let conditionValue = reduceExpression(blockCondition, bindings, accessors) + + switch conditionValue { + | InternalExpressionValue.IEvBool(false) => { + let ifFalseBlock = eBlock(list{ifFalse}) + ExpressionWithContext.withContext(ifFalseBlock, bindings) } - ) + | InternalExpressionValue.IEvBool(true) => { + let ifTrueBlock = eBlock(list{ifTrue}) + ExpressionWithContext.withContext(ifTrueBlock, bindings) + } + | _ => raise(ErrorException(REExpectedType("Boolean", ""))) + } } - let expandExpressionList = (aList, bindings: ExpressionT.bindings, accessors): result< - expressionWithContext, - errorValue, - > => + let expandExpressionList = (aList, bindings: ExpressionT.bindings, accessors): expressionWithContext + => switch aList { | list{ ExpressionT.EValue(IEvCall("$$_bindStatement_$$")), @@ -185,11 +172,11 @@ let dispatchMacroCall = ( doLambdaDefinition(bindings, parameters, lambdaDefinition) | list{ExpressionT.EValue(IEvCall("$$_ternary_$$")), condition, ifTrue, ifFalse} => doTernary(condition, ifTrue, ifFalse, bindings, accessors) - | _ => ExpressionWithContext.noContext(ExpressionT.EList(aList))->Ok + | _ => ExpressionWithContext.noContext(ExpressionT.EList(aList)) } switch macroExpression { | EList(aList) => expandExpressionList(aList, bindings, accessors) - | _ => ExpressionWithContext.noContext(macroExpression)->Ok + | _ => ExpressionWithContext.noContext(macroExpression) } } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res index 46da2216..e6404b18 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res @@ -26,6 +26,8 @@ type errorValue = type t = errorValue +exception ErrorException(errorValue) + let errorToString = err => switch err { | REArityError(_oFnName, arity, usedArity) => diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res index f2b05036..4950ffaa 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res @@ -14,6 +14,8 @@ module T = Reducer_Expression_T type errorValue = Reducer_ErrorValue.errorValue type t = T.t +exception ErrorException = Reducer_ErrorValue.ErrorException + /* Recursively evaluate/reduce the expression (Lisp AST/Lambda calculus) */ @@ -21,10 +23,10 @@ let rec reduceExpressionInProject = ( expression: t, continuation: T.bindings, accessors: ProjectAccessorsT.t, -): result => { +): InternalExpressionValue.t => { // Js.log(`reduce: ${T.toString(expression)} bindings: ${bindings->Bindings.toString}`) switch expression { - | T.EValue(value) => value->Ok + | T.EValue(value) => value | T.EList(list) => switch list { | list{EValue(IEvCall(fName)), ..._args} => @@ -41,20 +43,13 @@ and reduceExpressionList = ( expressions: list, continuation: T.bindings, accessors: ProjectAccessorsT.t, -): result => { - let racc: result< - list, - 'e, - > = expressions->Belt.List.reduceReverse(Ok(list{}), (racc, each: t) => - racc->Result.flatMap(acc => { - each - ->reduceExpressionInProject(continuation, accessors) - ->Result.map(newNode => { - acc->Belt.List.add(newNode) - }) - }) +): InternalExpressionValue.t => { + let acc: list = expressions->Belt.List.reduceReverse(list{}, (acc, each: t) => + acc->Belt.List.add( + each->reduceExpressionInProject(continuation, accessors) + ) ) - racc->Result.flatMap(acc => acc->reduceValueList(accessors)) + acc->reduceValueList(accessors) } /* @@ -63,48 +58,39 @@ and reduceExpressionList = ( and reduceValueList = ( valueList: list, accessors: ProjectAccessorsT.t, -): result => +): InternalExpressionValue.t => switch valueList { | list{IEvCall(fName), ...args} => { - let rCheckedArgs = switch fName { - | "$_setBindings_$" | "$_setTypeOfBindings_$" | "$_setTypeAliasBindings_$" => args->Ok + let checkedArgs = switch fName { + | "$_setBindings_$" | "$_setTypeOfBindings_$" | "$_setTypeAliasBindings_$" => args | _ => args->Lambda.checkIfReduced } - rCheckedArgs->Result.flatMap(checkedArgs => - (fName, checkedArgs->Belt.List.toArray)->BuiltIn.dispatch( - accessors, - reduceExpressionInProject, - ) + (fName, checkedArgs->Belt.List.toArray)->BuiltIn.dispatch( + accessors, + reduceExpressionInProject, ) } | list{IEvLambda(_)} => // TODO: remove on solving issue#558 valueList ->Lambda.checkIfReduced - ->Result.flatMap(reducedValueList => - reducedValueList->Belt.List.toArray->InternalExpressionValue.IEvArray->Ok - ) + ->Belt.List.toArray->InternalExpressionValue.IEvArray | list{IEvLambda(lambdaCall), ...args} => args ->Lambda.checkIfReduced - ->Result.flatMap(checkedArgs => - Lambda.doLambdaCall(lambdaCall, checkedArgs, accessors, reduceExpressionInProject) - ) - + ->Lambda.doLambdaCall(lambdaCall, _, accessors, reduceExpressionInProject) | _ => valueList ->Lambda.checkIfReduced - ->Result.flatMap(reducedValueList => - reducedValueList->Belt.List.toArray->InternalExpressionValue.IEvArray->Ok - ) + ->Belt.List.toArray->InternalExpressionValue.IEvArray } let reduceReturningBindings = ( expression: t, continuation: T.bindings, accessors: ProjectAccessorsT.t, -): (result, T.bindings) => { +): (InternalExpressionValue.t, T.bindings) => { let states = accessors.states let result = reduceExpressionInProject(expression, continuation, accessors) (result, states.continuation) @@ -118,7 +104,12 @@ module BackCompatible = { let evaluate = (expression: t): result => { let accessors = ProjectAccessorsT.identityAccessors - expression->reduceExpressionInProject(accessors.stdLib, accessors) + try { + expression->reduceExpressionInProject(accessors.stdLib, accessors)->Ok + } catch { + | ErrorException(e) => Error(e) + | _ => raise(ErrorException(RETodo("internal exception"))) + } } let evaluateString = (peggyCode: string): result => diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_ExpressionWithContext.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_ExpressionWithContext.res index 808a2dcd..23b7e2c8 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_ExpressionWithContext.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_ExpressionWithContext.res @@ -23,7 +23,7 @@ let callReducer = ( bindings: bindings, accessors: ProjectAccessorsT.t, reducer: ProjectReducerFnT.t, -): result => { +): internalExpressionValue => { switch expressionWithContext { | ExpressionNoContext(expr) => // Js.log(`callReducer: bindings ${Bindings.toString(bindings)} expr ${ExpressionT.toString(expr)}`) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_BindingsReplacer.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_BindingsReplacer.res index 6e38f833..09bd8ae8 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_BindingsReplacer.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_BindingsReplacer.res @@ -1,7 +1,6 @@ module ErrorValue = Reducer_ErrorValue module ExpressionT = Reducer_Expression_T module InternalExpressionValue = ReducerInterface_InternalExpressionValue -module Result = Belt.Result module Bindings = Reducer_Bindings type errorValue = Reducer_ErrorValue.errorValue @@ -10,19 +9,16 @@ type internalExpressionValue = InternalExpressionValue.t let isMacroName = (fName: string): bool => fName->Js.String2.startsWith("$$") -let rec replaceSymbols = (bindings: ExpressionT.bindings, expression: expression): result< - expression, - errorValue, -> => +let rec replaceSymbols = (bindings: ExpressionT.bindings, expression: expression): expression => switch expression { | ExpressionT.EValue(value) => - replaceSymbolOnValue(bindings, value)->Result.map(evValue => evValue->ExpressionT.EValue) + replaceSymbolOnValue(bindings, value)->ExpressionT.EValue | ExpressionT.EList(list) => switch list { | list{EValue(IEvCall(fName)), ..._args} => switch isMacroName(fName) { // A macro reduces itself so we dont dive in it - | true => expression->Ok + | true => expression | false => replaceSymbolsOnExpressionList(bindings, list) } | _ => replaceSymbolsOnExpressionList(bindings, list) @@ -30,23 +26,19 @@ let rec replaceSymbols = (bindings: ExpressionT.bindings, expression: expression } and replaceSymbolsOnExpressionList = (bindings, list) => { - let racc = list->Belt.List.reduceReverse(Ok(list{}), (racc, each: expression) => - racc->Result.flatMap(acc => { - replaceSymbols(bindings, each)->Result.flatMap(newNode => { - acc->Belt.List.add(newNode)->Ok - }) - }) + let racc = list->Belt.List.reduceReverse(list{}, (acc, each: expression) => + replaceSymbols(bindings, each)->Belt.List.add(acc, _) ) - racc->Result.map(acc => acc->ExpressionT.EList) + ExpressionT.EList(racc) } and replaceSymbolOnValue = (bindings, evValue: internalExpressionValue) => switch evValue { - | IEvSymbol(symbol) => Bindings.getWithDefault(bindings, symbol, evValue)->Ok + | IEvSymbol(symbol) => Bindings.getWithDefault(bindings, symbol, evValue) | IEvCall(symbol) => Bindings.getWithDefault(bindings, symbol, evValue)->checkIfCallable - | _ => evValue->Ok + | _ => evValue } and checkIfCallable = (evValue: internalExpressionValue) => switch evValue { - | IEvCall(_) | IEvLambda(_) => evValue->Ok - | _ => ErrorValue.RENotAFunction(InternalExpressionValue.toString(evValue))->Error + | IEvCall(_) | IEvLambda(_) => evValue + | _ => raise(ErrorValue.ErrorException(ErrorValue.RENotAFunction(InternalExpressionValue.toString(evValue)))) } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Lambda.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Lambda.res index 5ab7761d..8864c4d8 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Lambda.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Lambda.res @@ -23,26 +23,24 @@ let checkArity = ( let argsLength = Belt.List.length(args) let parametersLength = Js.Array2.length(lambdaValue.parameters) if argsLength !== parametersLength { - ErrorValue.REArityError(None, parametersLength, argsLength)->Error + raise(ErrorValue.ErrorException(ErrorValue.REArityError(None, parametersLength, argsLength))) } else { - args->Ok + args } } let exprOrFFI = castInternalCodeToExpression(lambdaValue.body) switch exprOrFFI { | NotFFI(_) => reallyCheck - | FFI(_) => args->Ok + | FFI(_) => args } } let checkIfReduced = (args: list) => - args->Belt.List.reduceReverse(Ok(list{}), (rAcc, arg) => - rAcc->Result.flatMap(acc => + args->Belt.List.reduceReverse(list{}, (acc, arg) => switch arg { - | IEvSymbol(symbol) => ErrorValue.RESymbolNotFound(symbol)->Error - | _ => list{arg, ...acc}->Ok + | IEvSymbol(symbol) => raise(ErrorValue.ErrorException(ErrorValue.RESymbolNotFound(symbol))) + | _ => list{arg, ...acc} } - ) ) let caseNotFFI = ( @@ -63,7 +61,10 @@ let caseNotFFI = ( } let caseFFI = (ffiFn: ExpressionT.ffiFn, args, accessors: ProjectAccessorsT.t) => { - ffiFn(args->Belt.List.toArray, accessors.environment) + switch ffiFn(args->Belt.List.toArray, accessors.environment) { + | Ok(value) => value + | Error(value) => raise(ErrorValue.ErrorException(value)) + } } let applyParametersToLambda = ( @@ -71,16 +72,13 @@ let applyParametersToLambda = ( args, accessors: ProjectAccessorsT.t, reducer: ProjectReducerFnT.t, -): result => { - checkArity(lambdaValue, args)->Result.flatMap(args => - checkIfReduced(args)->Result.flatMap(args => { - let exprOrFFI = castInternalCodeToExpression(lambdaValue.body) - switch exprOrFFI { - | NotFFI(expr) => caseNotFFI(lambdaValue, expr, args, accessors, reducer) - | FFI(ffiFn) => caseFFI(ffiFn, args, accessors) - } - }) - ) +): internalExpressionValue => { + let args = checkArity(lambdaValue, args)->checkIfReduced + let exprOrFFI = castInternalCodeToExpression(lambdaValue.body) + switch exprOrFFI { + | NotFFI(expr) => caseNotFFI(lambdaValue, expr, args, accessors, reducer) + | FFI(ffiFn) => caseFFI(ffiFn, args, accessors) + } } let doLambdaCall = ( @@ -95,7 +93,7 @@ let foreignFunctionInterface = ( argArray: array, accessors: ProjectAccessorsT.t, reducer: ProjectReducerFnT.t, -): result => { +): internalExpressionValue => { let args = argArray->Belt.List.fromArray applyParametersToLambda(lambdaValue, args, accessors, reducer) } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res index 003d3170..7426be18 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res @@ -10,32 +10,17 @@ type expression = ExpressionT.expression type internalExpressionValue = InternalExpressionValue.t type expressionWithContext = ExpressionWithContext.expressionWithContext -let expandMacroCall = ( - macroExpression: expression, - bindings: ExpressionT.bindings, - accessors: ProjectAccessorsT.t, - reduceExpression: ProjectReducerFnT.t, -): result => - Reducer_Dispatch_BuiltInMacros.dispatchMacroCall( - macroExpression, - bindings, - accessors, - reduceExpression, - ) - let doMacroCall = ( macroExpression: expression, bindings: ExpressionT.bindings, accessors: ProjectAccessorsT.t, reduceExpression: ProjectReducerFnT.t, -): result => - expandMacroCall( +): internalExpressionValue => + Reducer_Dispatch_BuiltInMacros.dispatchMacroCall( macroExpression, bindings, (accessors: ProjectAccessorsT.t), (reduceExpression: ProjectReducerFnT.t), - )->Result.flatMap(expressionWithContext => - ExpressionWithContext.callReducer(expressionWithContext, bindings, accessors, reduceExpression) - ) + )->ExpressionWithContext.callReducer(bindings, accessors, reduceExpression) let isMacroName = (fName: string): bool => fName->Js.String2.startsWith("$$") diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Compile.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Compile.res index 79153801..73696831 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Compile.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Compile.res @@ -18,13 +18,9 @@ let ievFromTypeExpression = ( let result = reducerFn(expr, Bindings.emptyBindings, accessors) let nameSpace = accessors.states.continuation - switch result { - | Ok(_) => - switch Bindings.getType(nameSpace, sIndex) { - | Some(value) => value->Ok - | None => raise(Reducer_Exception.ImpossibleException("Reducer_Type_Compile-none")) - } - | err => err + switch Bindings.getType(nameSpace, sIndex) { + | Some(value) => value->Ok + | None => raise(Reducer_Exception.ImpossibleException("Reducer_Type_Compile-none")) } }) } diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res index 8eb915de..07210232 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res @@ -183,16 +183,16 @@ let buildExpression = (this: t): t => { } } -let wrappedReducer = ( - rExpression: T.expressionArgumentType, - aContinuation: T.continuation, - accessors: ProjectAccessorsT.t, -): T.resultArgumentType => { - Belt.Result.flatMap( - rExpression, - Reducer_Expression.reduceExpressionInProject(_, aContinuation, accessors), - ) -} +// let wrappedReducer = ( +// rExpression: T.expressionArgumentType, +// aContinuation: T.continuation, +// accessors: ProjectAccessorsT.t, +// ): T.resultArgumentType => { +// Belt.Result.flatMap( +// rExpression, +// Reducer_Expression.reduceExpressionInProject(_, aContinuation, accessors), +// ) +// } let doBuildResult = ( this: t, @@ -204,7 +204,13 @@ let doBuildResult = ( ->Belt.Option.map( Belt.Result.flatMap( _, - Reducer_Expression.reduceExpressionInProject(_, aContinuation, accessors), + expression => + try { + Reducer_Expression.reduceExpressionInProject(expression, aContinuation, accessors)->Ok + } catch { + | Reducer_ErrorValue.ErrorException(e) => e->Error + | _ => RETodo("unhandled rescript exception")->Error + } ), ) diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ReducerFn_T.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ReducerFn_T.res index 0b401fcb..2b948a02 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ReducerFn_T.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ReducerFn_T.res @@ -6,4 +6,4 @@ type t = ( ExpressionT.t, ExpressionT.bindings, ProjectAccessorsT.t, -) => result +) => InternalExpressionValue.t From 06ec2caae03f0c79ef8b4f99539d09660f3a4665 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Wed, 7 Sep 2022 22:50:24 +0400 Subject: [PATCH 25/55] remove unused code --- .../ReducerProject/ReducerProject_ProjectItem.res | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res index 07210232..573d82c1 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res @@ -183,17 +183,6 @@ let buildExpression = (this: t): t => { } } -// let wrappedReducer = ( -// rExpression: T.expressionArgumentType, -// aContinuation: T.continuation, -// accessors: ProjectAccessorsT.t, -// ): T.resultArgumentType => { -// Belt.Result.flatMap( -// rExpression, -// Reducer_Expression.reduceExpressionInProject(_, aContinuation, accessors), -// ) -// } - let doBuildResult = ( this: t, aContinuation: T.continuation, From ecc82ba8f7cab30bc2a4231d097190d328a09c29 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Wed, 7 Sep 2022 23:04:07 +0400 Subject: [PATCH 26/55] reformat for lint --- .../Reducer/Reducer_TestMacroHelpers.res | 12 +- .../FunctionRegistry/Library/FR_Danger.res | 10 +- .../FunctionRegistry/Library/FR_List.res | 14 +- .../Reducer_Dispatch_BuiltIn.res | 4 +- .../Reducer_Dispatch_BuiltInMacros.res | 24 +- .../Reducer_Expression/Reducer_Expression.res | 16 +- .../Reducer_Expression_BindingsReplacer.res | 17 +- .../Reducer_Expression_Lambda.res | 12 +- .../ReducerProject_IncludeParser.js | 298 ++++++++++++------ .../ReducerProject_ProjectItem.res | 4 +- .../ReducerProject_ReducerFn_T.res | 6 +- 11 files changed, 265 insertions(+), 152 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res index 363d33c7..a1a3399e 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res @@ -18,20 +18,16 @@ let testMacro_ = ( ) => { let bindings = Bindings.fromArray(bindArray) tester(expr->T.toString, () => { - let result = switch expr - ->Reducer_Dispatch_BuiltInMacros.dispatchMacroCall( + let result = switch expr->Reducer_Dispatch_BuiltInMacros.dispatchMacroCall( bindings, ProjectAccessorsT.identityAccessors, Expression.reduceExpressionInProject, ) { - | v => Ok(v) - | exception Reducer_ErrorValue.ErrorException(e) => Error(e) + | v => Ok(v) + | exception Reducer_ErrorValue.ErrorException(e) => Error(e) } - result - ->ExpressionWithContext.toStringResult - ->expect - ->toEqual(expectedCode) + result->ExpressionWithContext.toStringResult->expect->toEqual(expectedCode) }) } diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Danger.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Danger.res index df3a91de..2fcfcdaf 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Danger.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Danger.res @@ -261,13 +261,13 @@ module DiminishingReturns = { This is currently being done with a reducer, that keeps track of: - Value of marginal spending for each function - How much has been assigned to each function. - */ + */ /* Two possible algorithms (n=funds/increment, m=num lambdas) 1. O(n): Iterate through value on next n dollars. At each step, only compute the new marginal return of the function which is spent. (This is what we are doing.) 2. O(n*(m-1)): Iterate through all possible spending combinations. The advantage of this option is that it wouldn't assume that the returns of marginal spending are diminishing. - */ + */ let optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions = ( lambdas, funds, @@ -275,7 +275,6 @@ module DiminishingReturns = { environment, reducer, ) => { - switch ( E.A.length(lambdas) > 1, funds > 0.0, @@ -310,7 +309,8 @@ module DiminishingReturns = { ) switch resultAsInternalExpression { | IEvNumber(x) => Ok(x) - | _ => Error( + | _ => + Error( "Error 1 in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions. It's possible that your function doesn't return a number, try definining auxiliaryFunction(x) = mean(yourFunction(x)) and integrate auxiliaryFunction instead", ) } @@ -452,5 +452,5 @@ let library = [ // will only depend on num points and the complexity of the function // Diminishing marginal return functions - DiminishingReturns.Lib.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions + DiminishingReturns.Lib.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions, ] diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res index 733c2f86..1def1e36 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res @@ -41,7 +41,7 @@ module Internals = { (reducer: ProjectReducerFnT.t), ) list{newElem, ...acc} - }) + }) mappedList->Belt.List.toArray->Wrappers.evArray } @@ -83,8 +83,8 @@ module Internals = { reducer, ) switch newElem { - | IEvBool(true) => list{elem, ...acc} - | _ => acc + | IEvBool(true) => list{elem, ...acc} + | _ => acc } }) mappedList->Belt.List.toArray->Wrappers.evArray @@ -244,13 +244,7 @@ let library = [ ~run=(inputs, _, accessors: ProjectAccessorsT.t, reducer: ProjectReducerFnT.t) => switch inputs { | [IEvArray(array), initialValue, IEvLambda(lambda)] => - Ok(Internals.reduceReverse( - array, - initialValue, - lambda, - accessors, - reducer, - )) + Ok(Internals.reduceReverse(array, initialValue, lambda, accessors, reducer)) | _ => Error(impossibleError) }, (), diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index 4e0b60e7..b7fed530 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res @@ -13,7 +13,6 @@ module TypeBuilder = Reducer_Type_TypeBuilder open ReducerInterface_InternalExpressionValue open Reducer_ErrorValue - /* MathJs provides default implementations for built-ins This is where all the expected built-ins like + = * / sin cos log ln etc are handled @@ -213,6 +212,7 @@ let dispatch = ( } } catch { | ErrorException(e) => raise(ErrorException(e)) - | Js.Exn.Error(obj) => raise(ErrorException(REJavaScriptExn(Js.Exn.message(obj), Js.Exn.name(obj)))) + | Js.Exn.Error(obj) => + raise(ErrorException(REJavaScriptExn(Js.Exn.message(obj), Js.Exn.name(obj)))) | _ => raise(ErrorException(RETodo("unhandled rescript exception"))) } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index 25f70fd8..67ed732c 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -32,10 +32,7 @@ let dispatchMacroCall = ( let boundStatement = BindingsReplacer.replaceSymbols(newBindings, statement) - ExpressionWithContext.withContext( - newCode(newBindings->eModule, boundStatement), - newBindings, - ) + ExpressionWithContext.withContext(newCode(newBindings->eModule, boundStatement), newBindings) } let correspondingSetBindingsFn = (fnName: string): string => @@ -65,7 +62,11 @@ let dispatchMacroCall = ( } } - let doBindExpression = (bindingExpr: expression, statement: expression, accessors): expressionWithContext => { + let doBindExpression = ( + bindingExpr: expression, + statement: expression, + accessors, + ): expressionWithContext => { let defaultStatement = () => useExpressionToSetBindings(bindingExpr, accessors, statement, ( _newBindingsExpr, @@ -93,7 +94,11 @@ let dispatchMacroCall = ( } } - let doBlock = (exprs: list, _bindings: ExpressionT.bindings, _accessors): expressionWithContext => { + let doBlock = ( + exprs: list, + _bindings: ExpressionT.bindings, + _accessors, + ): expressionWithContext => { let exprsArray = Belt.List.toArray(exprs) let maxIndex = Js.Array2.length(exprsArray) - 1 let newStatement = exprsArray->Js.Array2.reducei((acc, statement, index) => @@ -141,8 +146,11 @@ let dispatchMacroCall = ( } } - let expandExpressionList = (aList, bindings: ExpressionT.bindings, accessors): expressionWithContext - => + let expandExpressionList = ( + aList, + bindings: ExpressionT.bindings, + accessors, + ): expressionWithContext => switch aList { | list{ ExpressionT.EValue(IEvCall("$$_bindStatement_$$")), diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res index 4950ffaa..4b957e33 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res @@ -44,11 +44,10 @@ and reduceExpressionList = ( continuation: T.bindings, accessors: ProjectAccessorsT.t, ): InternalExpressionValue.t => { - let acc: list = expressions->Belt.List.reduceReverse(list{}, (acc, each: t) => - acc->Belt.List.add( - each->reduceExpressionInProject(continuation, accessors) + let acc: list = + expressions->Belt.List.reduceReverse(list{}, (acc, each: t) => + acc->Belt.List.add(each->reduceExpressionInProject(continuation, accessors)) ) - ) acc->reduceValueList(accessors) } @@ -73,17 +72,12 @@ and reduceValueList = ( } | list{IEvLambda(_)} => // TODO: remove on solving issue#558 - valueList - ->Lambda.checkIfReduced - ->Belt.List.toArray->InternalExpressionValue.IEvArray + valueList->Lambda.checkIfReduced->Belt.List.toArray->InternalExpressionValue.IEvArray | list{IEvLambda(lambdaCall), ...args} => args ->Lambda.checkIfReduced ->Lambda.doLambdaCall(lambdaCall, _, accessors, reduceExpressionInProject) - | _ => - valueList - ->Lambda.checkIfReduced - ->Belt.List.toArray->InternalExpressionValue.IEvArray + | _ => valueList->Lambda.checkIfReduced->Belt.List.toArray->InternalExpressionValue.IEvArray } let reduceReturningBindings = ( diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_BindingsReplacer.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_BindingsReplacer.res index 09bd8ae8..8a729405 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_BindingsReplacer.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_BindingsReplacer.res @@ -11,8 +11,7 @@ let isMacroName = (fName: string): bool => fName->Js.String2.startsWith("$$") let rec replaceSymbols = (bindings: ExpressionT.bindings, expression: expression): expression => switch expression { - | ExpressionT.EValue(value) => - replaceSymbolOnValue(bindings, value)->ExpressionT.EValue + | ExpressionT.EValue(value) => replaceSymbolOnValue(bindings, value)->ExpressionT.EValue | ExpressionT.EList(list) => switch list { | list{EValue(IEvCall(fName)), ..._args} => @@ -26,9 +25,10 @@ let rec replaceSymbols = (bindings: ExpressionT.bindings, expression: expression } and replaceSymbolsOnExpressionList = (bindings, list) => { - let racc = list->Belt.List.reduceReverse(list{}, (acc, each: expression) => - replaceSymbols(bindings, each)->Belt.List.add(acc, _) - ) + let racc = + list->Belt.List.reduceReverse(list{}, (acc, each: expression) => + replaceSymbols(bindings, each)->Belt.List.add(acc, _) + ) ExpressionT.EList(racc) } and replaceSymbolOnValue = (bindings, evValue: internalExpressionValue) => @@ -40,5 +40,10 @@ and replaceSymbolOnValue = (bindings, evValue: internalExpressionValue) => and checkIfCallable = (evValue: internalExpressionValue) => switch evValue { | IEvCall(_) | IEvLambda(_) => evValue - | _ => raise(ErrorValue.ErrorException(ErrorValue.RENotAFunction(InternalExpressionValue.toString(evValue)))) + | _ => + raise( + ErrorValue.ErrorException( + ErrorValue.RENotAFunction(InternalExpressionValue.toString(evValue)), + ), + ) } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Lambda.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Lambda.res index 8864c4d8..c4ef011e 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Lambda.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Lambda.res @@ -37,10 +37,10 @@ let checkArity = ( let checkIfReduced = (args: list) => args->Belt.List.reduceReverse(list{}, (acc, arg) => - switch arg { - | IEvSymbol(symbol) => raise(ErrorValue.ErrorException(ErrorValue.RESymbolNotFound(symbol))) - | _ => list{arg, ...acc} - } + switch arg { + | IEvSymbol(symbol) => raise(ErrorValue.ErrorException(ErrorValue.RESymbolNotFound(symbol))) + | _ => list{arg, ...acc} + } ) let caseNotFFI = ( @@ -62,8 +62,8 @@ let caseNotFFI = ( let caseFFI = (ffiFn: ExpressionT.ffiFn, args, accessors: ProjectAccessorsT.t) => { switch ffiFn(args->Belt.List.toArray, accessors.environment) { - | Ok(value) => value - | Error(value) => raise(ErrorValue.ErrorException(value)) + | Ok(value) => value + | Error(value) => raise(ErrorValue.ErrorException(value)) } } diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js index 7f9c0418..06e710d6 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js @@ -5,7 +5,9 @@ "use strict"; function peg$subclass(child, parent) { - function C() { this.constructor = child; } + function C() { + this.constructor = child; + } C.prototype = parent.prototype; child.prototype = new C(); } @@ -27,13 +29,15 @@ peg$subclass(peg$SyntaxError, Error); function peg$padEnd(str, targetLength, padString) { padString = padString || " "; - if (str.length > targetLength) { return str; } + if (str.length > targetLength) { + return str; + } targetLength -= str.length; padString += padString.repeat(targetLength); return str + padString.slice(0, targetLength); } -peg$SyntaxError.prototype.format = function(sources) { +peg$SyntaxError.prototype.format = function (sources) { var str = "Error: " + this.message; if (this.location) { var src = null; @@ -48,15 +52,24 @@ peg$SyntaxError.prototype.format = function(sources) { var loc = this.location.source + ":" + s.line + ":" + s.column; if (src) { var e = this.location.end; - var filler = peg$padEnd("", s.line.toString().length, ' '); + var filler = peg$padEnd("", s.line.toString().length, " "); var line = src[s.line - 1]; var last = s.line === e.line ? e.column : line.length + 1; - var hatLen = (last - s.column) || 1; - str += "\n --> " + loc + "\n" - + filler + " |\n" - + s.line + " | " + line + "\n" - + filler + " | " + peg$padEnd("", s.column - 1, ' ') - + peg$padEnd("", hatLen, "^"); + var hatLen = last - s.column || 1; + str += + "\n --> " + + loc + + "\n" + + filler + + " |\n" + + s.line + + " | " + + line + + "\n" + + filler + + " | " + + peg$padEnd("", s.column - 1, " ") + + peg$padEnd("", hatLen, "^"); } else { str += "\n at " + loc; } @@ -64,33 +77,35 @@ peg$SyntaxError.prototype.format = function(sources) { return str; }; -peg$SyntaxError.buildMessage = function(expected, found) { +peg$SyntaxError.buildMessage = function (expected, found) { var DESCRIBE_EXPECTATION_FNS = { - literal: function(expectation) { - return "\"" + literalEscape(expectation.text) + "\""; + literal: function (expectation) { + return '"' + literalEscape(expectation.text) + '"'; }, - class: function(expectation) { - var escapedParts = expectation.parts.map(function(part) { + class: function (expectation) { + var escapedParts = expectation.parts.map(function (part) { return Array.isArray(part) ? classEscape(part[0]) + "-" + classEscape(part[1]) : classEscape(part); }); - return "[" + (expectation.inverted ? "^" : "") + escapedParts.join("") + "]"; + return ( + "[" + (expectation.inverted ? "^" : "") + escapedParts.join("") + "]" + ); }, - any: function() { + any: function () { return "any character"; }, - end: function() { + end: function () { return "end of input"; }, - other: function(expectation) { + other: function (expectation) { return expectation.description; - } + }, }; function hex(ch) { @@ -100,13 +115,17 @@ peg$SyntaxError.buildMessage = function(expected, found) { function literalEscape(s) { return s .replace(/\\/g, "\\\\") - .replace(/"/g, "\\\"") + .replace(/"/g, '\\"') .replace(/\0/g, "\\0") .replace(/\t/g, "\\t") .replace(/\n/g, "\\n") .replace(/\r/g, "\\r") - .replace(/[\x00-\x0F]/g, function(ch) { return "\\x0" + hex(ch); }) - .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return "\\x" + hex(ch); }); + .replace(/[\x00-\x0F]/g, function (ch) { + return "\\x0" + hex(ch); + }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function (ch) { + return "\\x" + hex(ch); + }); } function classEscape(s) { @@ -114,13 +133,17 @@ peg$SyntaxError.buildMessage = function(expected, found) { .replace(/\\/g, "\\\\") .replace(/\]/g, "\\]") .replace(/\^/g, "\\^") - .replace(/-/g, "\\-") + .replace(/-/g, "\\-") .replace(/\0/g, "\\0") .replace(/\t/g, "\\t") .replace(/\n/g, "\\n") .replace(/\r/g, "\\r") - .replace(/[\x00-\x0F]/g, function(ch) { return "\\x0" + hex(ch); }) - .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return "\\x" + hex(ch); }); + .replace(/[\x00-\x0F]/g, function (ch) { + return "\\x0" + hex(ch); + }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function (ch) { + return "\\x" + hex(ch); + }); } function describeExpectation(expectation) { @@ -151,17 +174,25 @@ peg$SyntaxError.buildMessage = function(expected, found) { return descriptions[0] + " or " + descriptions[1]; default: - return descriptions.slice(0, -1).join(", ") - + ", or " - + descriptions[descriptions.length - 1]; + return ( + descriptions.slice(0, -1).join(", ") + + ", or " + + descriptions[descriptions.length - 1] + ); } } function describeFound(found) { - return found ? "\"" + literalEscape(found) + "\"" : "end of input"; + return found ? '"' + literalEscape(found) + '"' : "end of input"; } - return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; + return ( + "Expected " + + describeExpected(expected) + + " but " + + describeFound(found) + + " found." + ); }; function peg$parse(input, options) { @@ -177,7 +208,7 @@ function peg$parse(input, options) { var peg$c1 = "#include"; var peg$c2 = "as"; var peg$c3 = "'"; - var peg$c4 = "\""; + var peg$c4 = '"'; var peg$c5 = "//"; var peg$c6 = "/*"; var peg$c7 = "*/"; @@ -197,8 +228,8 @@ function peg$parse(input, options) { var peg$e3 = peg$otherExpectation("string"); var peg$e4 = peg$literalExpectation("'", false); var peg$e5 = peg$classExpectation(["'"], true, false); - var peg$e6 = peg$literalExpectation("\"", false); - var peg$e7 = peg$classExpectation(["\""], true, false); + var peg$e6 = peg$literalExpectation('"', false); + var peg$e7 = peg$classExpectation(['"'], true, false); var peg$e8 = peg$otherExpectation("comment"); var peg$e9 = peg$literalExpectation("//", false); var peg$e10 = peg$literalExpectation("/*", false); @@ -212,16 +243,36 @@ function peg$parse(input, options) { var peg$e18 = peg$classExpectation(["\r", "\n"], true, false); var peg$e19 = peg$otherExpectation("identifier"); var peg$e20 = peg$classExpectation(["_", ["a", "z"]], false, false); - var peg$e21 = peg$classExpectation(["_", ["a", "z"], ["0", "9"]], false, true); + var peg$e21 = peg$classExpectation( + ["_", ["a", "z"], ["0", "9"]], + false, + true + ); - var peg$f0 = function(head, tail) {return [head, ...tail].filter( e => e != '');}; - var peg$f1 = function() {return [];}; - var peg$f2 = function(file, variable) {return [!variable ? '' : variable, file]}; - var peg$f3 = function(characters) {return characters.join('');}; - var peg$f4 = function(characters) {return characters.join('');}; - var peg$f5 = function() { return '';}; - var peg$f6 = function() { return '';}; - var peg$f7 = function() {return text();}; + var peg$f0 = function (head, tail) { + return [head, ...tail].filter((e) => e != ""); + }; + var peg$f1 = function () { + return []; + }; + var peg$f2 = function (file, variable) { + return [!variable ? "" : variable, file]; + }; + var peg$f3 = function (characters) { + return characters.join(""); + }; + var peg$f4 = function (characters) { + return characters.join(""); + }; + var peg$f5 = function () { + return ""; + }; + var peg$f6 = function () { + return ""; + }; + var peg$f7 = function () { + return text(); + }; var peg$currPos = 0; var peg$savedPos = 0; var peg$posDetailsCache = [{ line: 1, column: 1 }]; @@ -235,7 +286,9 @@ function peg$parse(input, options) { if ("startRule" in options) { if (!(options.startRule in peg$startRuleFunctions)) { - throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); + throw new Error( + "Can't start parsing from rule \"" + options.startRule + '".' + ); } peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; @@ -253,7 +306,7 @@ function peg$parse(input, options) { return { source: peg$source, start: peg$savedPos, - end: peg$currPos + end: peg$currPos, }; } @@ -262,9 +315,10 @@ function peg$parse(input, options) { } function expected(description, location) { - location = location !== undefined - ? location - : peg$computeLocation(peg$savedPos, peg$currPos); + location = + location !== undefined + ? location + : peg$computeLocation(peg$savedPos, peg$currPos); throw peg$buildStructuredError( [peg$otherExpectation(description)], @@ -274,9 +328,10 @@ function peg$parse(input, options) { } function error(message, location) { - location = location !== undefined - ? location - : peg$computeLocation(peg$savedPos, peg$currPos); + location = + location !== undefined + ? location + : peg$computeLocation(peg$savedPos, peg$currPos); throw peg$buildSimpleError(message, location); } @@ -286,7 +341,12 @@ function peg$parse(input, options) { } function peg$classExpectation(parts, inverted, ignoreCase) { - return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase }; + return { + type: "class", + parts: parts, + inverted: inverted, + ignoreCase: ignoreCase, + }; } function peg$anyExpectation() { @@ -316,7 +376,7 @@ function peg$parse(input, options) { details = peg$posDetailsCache[p]; details = { line: details.line, - column: details.column + column: details.column, }; while (p < pos) { @@ -345,18 +405,20 @@ function peg$parse(input, options) { start: { offset: startPos, line: startPosDetails.line, - column: startPosDetails.column + column: startPosDetails.column, }, end: { offset: endPos, line: endPosDetails.line, - column: endPosDetails.column - } + column: endPosDetails.column, + }, }; } function peg$fail(expected) { - if (peg$currPos < peg$maxFailPos) { return; } + if (peg$currPos < peg$maxFailPos) { + return; + } if (peg$currPos > peg$maxFailPos) { peg$maxFailPos = peg$currPos; @@ -516,7 +578,9 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e0); } + if (peg$silentFails === 0) { + peg$fail(peg$e0); + } } peg$silentFails--; if (s2 === peg$FAILED) { @@ -586,7 +650,9 @@ function peg$parse(input, options) { peg$currPos += 8; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e1); } + if (peg$silentFails === 0) { + peg$fail(peg$e1); + } } if (s2 !== peg$FAILED) { s3 = []; @@ -619,7 +685,9 @@ function peg$parse(input, options) { peg$currPos += 2; } else { s7 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e2); } + if (peg$silentFails === 0) { + peg$fail(peg$e2); + } } if (s7 !== peg$FAILED) { s8 = []; @@ -716,7 +784,9 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } + if (peg$silentFails === 0) { + peg$fail(peg$e4); + } } if (s2 !== peg$FAILED) { s3 = []; @@ -725,7 +795,9 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e5); } + if (peg$silentFails === 0) { + peg$fail(peg$e5); + } } while (s4 !== peg$FAILED) { s3.push(s4); @@ -734,7 +806,9 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e5); } + if (peg$silentFails === 0) { + peg$fail(peg$e5); + } } } if (input.charCodeAt(peg$currPos) === 39) { @@ -742,7 +816,9 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } + if (peg$silentFails === 0) { + peg$fail(peg$e4); + } } if (s4 !== peg$FAILED) { s1 = s3; @@ -767,7 +843,9 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e6); } + if (peg$silentFails === 0) { + peg$fail(peg$e6); + } } if (s2 !== peg$FAILED) { s3 = []; @@ -776,7 +854,9 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e7); } + if (peg$silentFails === 0) { + peg$fail(peg$e7); + } } while (s4 !== peg$FAILED) { s3.push(s4); @@ -785,7 +865,9 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e7); } + if (peg$silentFails === 0) { + peg$fail(peg$e7); + } } } if (input.charCodeAt(peg$currPos) === 34) { @@ -793,7 +875,9 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e6); } + if (peg$silentFails === 0) { + peg$fail(peg$e6); + } } if (s4 !== peg$FAILED) { s1 = s3; @@ -814,7 +898,9 @@ function peg$parse(input, options) { peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } + if (peg$silentFails === 0) { + peg$fail(peg$e3); + } } peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; @@ -877,7 +963,9 @@ function peg$parse(input, options) { peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e9); } + if (peg$silentFails === 0) { + peg$fail(peg$e9); + } } if (s1 !== peg$FAILED) { s2 = []; @@ -910,7 +998,9 @@ function peg$parse(input, options) { peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e8); } + if (peg$silentFails === 0) { + peg$fail(peg$e8); + } } peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; @@ -937,7 +1027,9 @@ function peg$parse(input, options) { peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } + if (peg$silentFails === 0) { + peg$fail(peg$e10); + } } if (s1 !== peg$FAILED) { s2 = []; @@ -946,7 +1038,9 @@ function peg$parse(input, options) { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } + if (peg$silentFails === 0) { + peg$fail(peg$e11); + } } while (s3 !== peg$FAILED) { s2.push(s3); @@ -955,7 +1049,9 @@ function peg$parse(input, options) { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } + if (peg$silentFails === 0) { + peg$fail(peg$e11); + } } } if (input.substr(peg$currPos, 2) === peg$c7) { @@ -963,7 +1059,9 @@ function peg$parse(input, options) { peg$currPos += 2; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e12); } + if (peg$silentFails === 0) { + peg$fail(peg$e12); + } } if (s3 !== peg$FAILED) { peg$savedPos = s0; @@ -979,7 +1077,9 @@ function peg$parse(input, options) { peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e8); } + if (peg$silentFails === 0) { + peg$fail(peg$e8); + } } peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; @@ -1005,12 +1105,16 @@ function peg$parse(input, options) { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e14); } + if (peg$silentFails === 0) { + peg$fail(peg$e14); + } } peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e13); } + if (peg$silentFails === 0) { + peg$fail(peg$e13); + } } peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; @@ -1036,12 +1140,16 @@ function peg$parse(input, options) { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e16); } + if (peg$silentFails === 0) { + peg$fail(peg$e16); + } } peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e15); } + if (peg$silentFails === 0) { + peg$fail(peg$e15); + } } peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; @@ -1067,12 +1175,16 @@ function peg$parse(input, options) { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e18); } + if (peg$silentFails === 0) { + peg$fail(peg$e18); + } } peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e17); } + if (peg$silentFails === 0) { + peg$fail(peg$e17); + } } peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; @@ -1101,7 +1213,9 @@ function peg$parse(input, options) { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e20); } + if (peg$silentFails === 0) { + peg$fail(peg$e20); + } } if (s3 !== peg$FAILED) { while (s3 !== peg$FAILED) { @@ -1111,7 +1225,9 @@ function peg$parse(input, options) { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e20); } + if (peg$silentFails === 0) { + peg$fail(peg$e20); + } } } } else { @@ -1124,7 +1240,9 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e21); } + if (peg$silentFails === 0) { + peg$fail(peg$e21); + } } while (s4 !== peg$FAILED) { s3.push(s4); @@ -1133,7 +1251,9 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e21); } + if (peg$silentFails === 0) { + peg$fail(peg$e21); + } } } s2 = [s2, s3]; @@ -1150,7 +1270,9 @@ function peg$parse(input, options) { peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e19); } + if (peg$silentFails === 0) { + peg$fail(peg$e19); + } } peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; @@ -1179,5 +1301,5 @@ function peg$parse(input, options) { module.exports = { SyntaxError: peg$SyntaxError, - parse: peg$parse + parse: peg$parse, }; diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res index 573d82c1..8517dd95 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res @@ -191,9 +191,7 @@ let doBuildResult = ( this ->getExpression ->Belt.Option.map( - Belt.Result.flatMap( - _, - expression => + Belt.Result.flatMap(_, expression => try { Reducer_Expression.reduceExpressionInProject(expression, aContinuation, accessors)->Ok } catch { diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ReducerFn_T.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ReducerFn_T.res index 2b948a02..2dc926be 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ReducerFn_T.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ReducerFn_T.res @@ -2,8 +2,4 @@ module ExpressionT = Reducer_Expression_T module InternalExpressionValue = ReducerInterface_InternalExpressionValue module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -type t = ( - ExpressionT.t, - ExpressionT.bindings, - ProjectAccessorsT.t, -) => InternalExpressionValue.t +type t = (ExpressionT.t, ExpressionT.bindings, ProjectAccessorsT.t) => InternalExpressionValue.t From d3788fb4115fa51fa85b0466841062f1a6ff8d94 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Thu, 8 Sep 2022 16:27:32 +0400 Subject: [PATCH 27/55] remove generated ReducerProject_IncludeParser.js from repo --- packages/squiggle-lang/.gitignore | 1 + .../ReducerProject_IncludeParser.js | 1305 ----------------- 2 files changed, 1 insertion(+), 1305 deletions(-) delete mode 100644 packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js diff --git a/packages/squiggle-lang/.gitignore b/packages/squiggle-lang/.gitignore index 034f263d..d407752c 100644 --- a/packages/squiggle-lang/.gitignore +++ b/packages/squiggle-lang/.gitignore @@ -23,3 +23,4 @@ coverage .nyc_output/ src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.js src/rescript/Reducer/Reducer_Peggy/helpers.js +src/rescript/ReducerProject/ReducerProject_IncludeParser.js diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js deleted file mode 100644 index 06e710d6..00000000 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js +++ /dev/null @@ -1,1305 +0,0 @@ -// Generated by Peggy 2.0.1. -// -// https://peggyjs.org/ - -"use strict"; - -function peg$subclass(child, parent) { - function C() { - this.constructor = child; - } - C.prototype = parent.prototype; - child.prototype = new C(); -} - -function peg$SyntaxError(message, expected, found, location) { - var self = Error.call(this, message); - // istanbul ignore next Check is a necessary evil to support older environments - if (Object.setPrototypeOf) { - Object.setPrototypeOf(self, peg$SyntaxError.prototype); - } - self.expected = expected; - self.found = found; - self.location = location; - self.name = "SyntaxError"; - return self; -} - -peg$subclass(peg$SyntaxError, Error); - -function peg$padEnd(str, targetLength, padString) { - padString = padString || " "; - if (str.length > targetLength) { - return str; - } - targetLength -= str.length; - padString += padString.repeat(targetLength); - return str + padString.slice(0, targetLength); -} - -peg$SyntaxError.prototype.format = function (sources) { - var str = "Error: " + this.message; - if (this.location) { - var src = null; - var k; - for (k = 0; k < sources.length; k++) { - if (sources[k].source === this.location.source) { - src = sources[k].text.split(/\r\n|\n|\r/g); - break; - } - } - var s = this.location.start; - var loc = this.location.source + ":" + s.line + ":" + s.column; - if (src) { - var e = this.location.end; - var filler = peg$padEnd("", s.line.toString().length, " "); - var line = src[s.line - 1]; - var last = s.line === e.line ? e.column : line.length + 1; - var hatLen = last - s.column || 1; - str += - "\n --> " + - loc + - "\n" + - filler + - " |\n" + - s.line + - " | " + - line + - "\n" + - filler + - " | " + - peg$padEnd("", s.column - 1, " ") + - peg$padEnd("", hatLen, "^"); - } else { - str += "\n at " + loc; - } - } - return str; -}; - -peg$SyntaxError.buildMessage = function (expected, found) { - var DESCRIBE_EXPECTATION_FNS = { - literal: function (expectation) { - return '"' + literalEscape(expectation.text) + '"'; - }, - - class: function (expectation) { - var escapedParts = expectation.parts.map(function (part) { - return Array.isArray(part) - ? classEscape(part[0]) + "-" + classEscape(part[1]) - : classEscape(part); - }); - - return ( - "[" + (expectation.inverted ? "^" : "") + escapedParts.join("") + "]" - ); - }, - - any: function () { - return "any character"; - }, - - end: function () { - return "end of input"; - }, - - other: function (expectation) { - return expectation.description; - }, - }; - - function hex(ch) { - return ch.charCodeAt(0).toString(16).toUpperCase(); - } - - function literalEscape(s) { - return s - .replace(/\\/g, "\\\\") - .replace(/"/g, '\\"') - .replace(/\0/g, "\\0") - .replace(/\t/g, "\\t") - .replace(/\n/g, "\\n") - .replace(/\r/g, "\\r") - .replace(/[\x00-\x0F]/g, function (ch) { - return "\\x0" + hex(ch); - }) - .replace(/[\x10-\x1F\x7F-\x9F]/g, function (ch) { - return "\\x" + hex(ch); - }); - } - - function classEscape(s) { - return s - .replace(/\\/g, "\\\\") - .replace(/\]/g, "\\]") - .replace(/\^/g, "\\^") - .replace(/-/g, "\\-") - .replace(/\0/g, "\\0") - .replace(/\t/g, "\\t") - .replace(/\n/g, "\\n") - .replace(/\r/g, "\\r") - .replace(/[\x00-\x0F]/g, function (ch) { - return "\\x0" + hex(ch); - }) - .replace(/[\x10-\x1F\x7F-\x9F]/g, function (ch) { - return "\\x" + hex(ch); - }); - } - - function describeExpectation(expectation) { - return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation); - } - - function describeExpected(expected) { - var descriptions = expected.map(describeExpectation); - var i, j; - - descriptions.sort(); - - if (descriptions.length > 0) { - for (i = 1, j = 1; i < descriptions.length; i++) { - if (descriptions[i - 1] !== descriptions[i]) { - descriptions[j] = descriptions[i]; - j++; - } - } - descriptions.length = j; - } - - switch (descriptions.length) { - case 1: - return descriptions[0]; - - case 2: - return descriptions[0] + " or " + descriptions[1]; - - default: - return ( - descriptions.slice(0, -1).join(", ") + - ", or " + - descriptions[descriptions.length - 1] - ); - } - } - - function describeFound(found) { - return found ? '"' + literalEscape(found) + '"' : "end of input"; - } - - return ( - "Expected " + - describeExpected(expected) + - " but " + - describeFound(found) + - " found." - ); -}; - -function peg$parse(input, options) { - options = options !== undefined ? options : {}; - - var peg$FAILED = {}; - var peg$source = options.grammarSource; - - var peg$startRuleFunctions = { start: peg$parsestart }; - var peg$startRuleFunction = peg$parsestart; - - var peg$c0 = "#"; - var peg$c1 = "#include"; - var peg$c2 = "as"; - var peg$c3 = "'"; - var peg$c4 = '"'; - var peg$c5 = "//"; - var peg$c6 = "/*"; - var peg$c7 = "*/"; - - var peg$r0 = /^[^']/; - var peg$r1 = /^[^"]/; - var peg$r2 = /^[^*]/; - var peg$r3 = /^[ \t]/; - var peg$r4 = /^[\n\r]/; - var peg$r5 = /^[^\r\n]/; - var peg$r6 = /^[_a-z]/; - var peg$r7 = /^[_a-z0-9]/i; - - var peg$e0 = peg$literalExpectation("#", false); - var peg$e1 = peg$literalExpectation("#include", false); - var peg$e2 = peg$literalExpectation("as", false); - var peg$e3 = peg$otherExpectation("string"); - var peg$e4 = peg$literalExpectation("'", false); - var peg$e5 = peg$classExpectation(["'"], true, false); - var peg$e6 = peg$literalExpectation('"', false); - var peg$e7 = peg$classExpectation(['"'], true, false); - var peg$e8 = peg$otherExpectation("comment"); - var peg$e9 = peg$literalExpectation("//", false); - var peg$e10 = peg$literalExpectation("/*", false); - var peg$e11 = peg$classExpectation(["*"], true, false); - var peg$e12 = peg$literalExpectation("*/", false); - var peg$e13 = peg$otherExpectation("white space"); - var peg$e14 = peg$classExpectation([" ", "\t"], false, false); - var peg$e15 = peg$otherExpectation("newline"); - var peg$e16 = peg$classExpectation(["\n", "\r"], false, false); - var peg$e17 = peg$otherExpectation("code"); - var peg$e18 = peg$classExpectation(["\r", "\n"], true, false); - var peg$e19 = peg$otherExpectation("identifier"); - var peg$e20 = peg$classExpectation(["_", ["a", "z"]], false, false); - var peg$e21 = peg$classExpectation( - ["_", ["a", "z"], ["0", "9"]], - false, - true - ); - - var peg$f0 = function (head, tail) { - return [head, ...tail].filter((e) => e != ""); - }; - var peg$f1 = function () { - return []; - }; - var peg$f2 = function (file, variable) { - return [!variable ? "" : variable, file]; - }; - var peg$f3 = function (characters) { - return characters.join(""); - }; - var peg$f4 = function (characters) { - return characters.join(""); - }; - var peg$f5 = function () { - return ""; - }; - var peg$f6 = function () { - return ""; - }; - var peg$f7 = function () { - return text(); - }; - var peg$currPos = 0; - var peg$savedPos = 0; - var peg$posDetailsCache = [{ line: 1, column: 1 }]; - var peg$maxFailPos = 0; - var peg$maxFailExpected = []; - var peg$silentFails = 0; - - var peg$resultsCache = {}; - - var peg$result; - - if ("startRule" in options) { - if (!(options.startRule in peg$startRuleFunctions)) { - throw new Error( - "Can't start parsing from rule \"" + options.startRule + '".' - ); - } - - peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; - } - - function text() { - return input.substring(peg$savedPos, peg$currPos); - } - - function offset() { - return peg$savedPos; - } - - function range() { - return { - source: peg$source, - start: peg$savedPos, - end: peg$currPos, - }; - } - - function location() { - return peg$computeLocation(peg$savedPos, peg$currPos); - } - - function expected(description, location) { - location = - location !== undefined - ? location - : peg$computeLocation(peg$savedPos, peg$currPos); - - throw peg$buildStructuredError( - [peg$otherExpectation(description)], - input.substring(peg$savedPos, peg$currPos), - location - ); - } - - function error(message, location) { - location = - location !== undefined - ? location - : peg$computeLocation(peg$savedPos, peg$currPos); - - throw peg$buildSimpleError(message, location); - } - - function peg$literalExpectation(text, ignoreCase) { - return { type: "literal", text: text, ignoreCase: ignoreCase }; - } - - function peg$classExpectation(parts, inverted, ignoreCase) { - return { - type: "class", - parts: parts, - inverted: inverted, - ignoreCase: ignoreCase, - }; - } - - function peg$anyExpectation() { - return { type: "any" }; - } - - function peg$endExpectation() { - return { type: "end" }; - } - - function peg$otherExpectation(description) { - return { type: "other", description: description }; - } - - function peg$computePosDetails(pos) { - var details = peg$posDetailsCache[pos]; - var p; - - if (details) { - return details; - } else { - p = pos - 1; - while (!peg$posDetailsCache[p]) { - p--; - } - - details = peg$posDetailsCache[p]; - details = { - line: details.line, - column: details.column, - }; - - while (p < pos) { - if (input.charCodeAt(p) === 10) { - details.line++; - details.column = 1; - } else { - details.column++; - } - - p++; - } - - peg$posDetailsCache[pos] = details; - - return details; - } - } - - function peg$computeLocation(startPos, endPos) { - var startPosDetails = peg$computePosDetails(startPos); - var endPosDetails = peg$computePosDetails(endPos); - - return { - source: peg$source, - start: { - offset: startPos, - line: startPosDetails.line, - column: startPosDetails.column, - }, - end: { - offset: endPos, - line: endPosDetails.line, - column: endPosDetails.column, - }, - }; - } - - function peg$fail(expected) { - if (peg$currPos < peg$maxFailPos) { - return; - } - - if (peg$currPos > peg$maxFailPos) { - peg$maxFailPos = peg$currPos; - peg$maxFailExpected = []; - } - - peg$maxFailExpected.push(expected); - } - - function peg$buildSimpleError(message, location) { - return new peg$SyntaxError(message, null, null, location); - } - - function peg$buildStructuredError(expected, found, location) { - return new peg$SyntaxError( - peg$SyntaxError.buildMessage(expected, found), - expected, - found, - location - ); - } - - function peg$parsestart() { - var s0, s1, s2, s3, s4; - - var key = peg$currPos * 12 + 0; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = []; - s2 = peg$parsenewLine(); - if (s2 === peg$FAILED) { - s2 = peg$parse_(); - if (s2 === peg$FAILED) { - s2 = peg$parsecomment(); - if (s2 === peg$FAILED) { - s2 = peg$parsedelimitedComment(); - } - } - } - while (s2 !== peg$FAILED) { - s1.push(s2); - s2 = peg$parsenewLine(); - if (s2 === peg$FAILED) { - s2 = peg$parse_(); - if (s2 === peg$FAILED) { - s2 = peg$parsecomment(); - if (s2 === peg$FAILED) { - s2 = peg$parsedelimitedComment(); - } - } - } - } - s2 = peg$parseincludes(); - if (s2 !== peg$FAILED) { - s3 = []; - s4 = peg$parsenewLine(); - while (s4 !== peg$FAILED) { - s3.push(s4); - s4 = peg$parsenewLine(); - } - s4 = peg$parseignore(); - s0 = s2; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseincludes() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 12 + 1; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parsedependencyStatement(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = []; - s5 = peg$parsenewLine(); - if (s5 !== peg$FAILED) { - while (s5 !== peg$FAILED) { - s4.push(s5); - s5 = peg$parsenewLine(); - } - } else { - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - s5 = peg$parsedependencyStatement(); - if (s5 !== peg$FAILED) { - s3 = s5; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = []; - s5 = peg$parsenewLine(); - if (s5 !== peg$FAILED) { - while (s5 !== peg$FAILED) { - s4.push(s5); - s5 = peg$parsenewLine(); - } - } else { - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - s5 = peg$parsedependencyStatement(); - if (s5 !== peg$FAILED) { - s3 = s5; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f0(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$currPos; - peg$silentFails++; - if (input.charCodeAt(peg$currPos) === 35) { - s2 = peg$c0; - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e0); - } - } - peg$silentFails--; - if (s2 === peg$FAILED) { - s1 = undefined; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f1(); - } - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsedependencyStatement() { - var s0; - - var key = peg$currPos * 12 + 2; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseincludeStatement(); - if (s0 === peg$FAILED) { - s0 = peg$parsecomment(); - if (s0 === peg$FAILED) { - s0 = peg$parsedelimitedComment(); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseincludeStatement() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; - - var key = peg$currPos * 12 + 3; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = []; - s2 = peg$parse_(); - while (s2 !== peg$FAILED) { - s1.push(s2); - s2 = peg$parse_(); - } - if (input.substr(peg$currPos, 8) === peg$c1) { - s2 = peg$c1; - peg$currPos += 8; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e1); - } - } - if (s2 !== peg$FAILED) { - s3 = []; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - while (s4 !== peg$FAILED) { - s3.push(s4); - s4 = peg$parse_(); - } - } else { - s3 = peg$FAILED; - } - if (s3 !== peg$FAILED) { - s4 = peg$parsestring(); - if (s4 !== peg$FAILED) { - s5 = peg$currPos; - s6 = []; - s7 = peg$parse_(); - if (s7 !== peg$FAILED) { - while (s7 !== peg$FAILED) { - s6.push(s7); - s7 = peg$parse_(); - } - } else { - s6 = peg$FAILED; - } - if (s6 !== peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c2) { - s7 = peg$c2; - peg$currPos += 2; - } else { - s7 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e2); - } - } - if (s7 !== peg$FAILED) { - s8 = []; - s9 = peg$parse_(); - if (s9 !== peg$FAILED) { - while (s9 !== peg$FAILED) { - s8.push(s9); - s9 = peg$parse_(); - } - } else { - s8 = peg$FAILED; - } - if (s8 !== peg$FAILED) { - s9 = peg$parseidentifier(); - if (s9 !== peg$FAILED) { - s5 = s9; - } else { - peg$currPos = s5; - s5 = peg$FAILED; - } - } else { - peg$currPos = s5; - s5 = peg$FAILED; - } - } else { - peg$currPos = s5; - s5 = peg$FAILED; - } - } else { - peg$currPos = s5; - s5 = peg$FAILED; - } - if (s5 === peg$FAILED) { - s5 = null; - } - s6 = []; - s7 = peg$parse_(); - while (s7 !== peg$FAILED) { - s6.push(s7); - s7 = peg$parse_(); - } - s7 = peg$currPos; - peg$silentFails++; - s8 = peg$parsenewLine(); - peg$silentFails--; - if (s8 !== peg$FAILED) { - peg$currPos = s7; - s7 = undefined; - } else { - s7 = peg$FAILED; - } - if (s7 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f2(s4, s5); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsestring() { - var s0, s1, s2, s3, s4; - - var key = peg$currPos * 12 + 4; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - peg$silentFails++; - s0 = peg$currPos; - s1 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 39) { - s2 = peg$c3; - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e4); - } - } - if (s2 !== peg$FAILED) { - s3 = []; - if (peg$r0.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e5); - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$r0.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e5); - } - } - } - if (input.charCodeAt(peg$currPos) === 39) { - s4 = peg$c3; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e4); - } - } - if (s4 !== peg$FAILED) { - s1 = s3; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f3(s1); - } - s0 = s1; - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 34) { - s2 = peg$c4; - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e6); - } - } - if (s2 !== peg$FAILED) { - s3 = []; - if (peg$r1.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e7); - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$r1.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e7); - } - } - } - if (input.charCodeAt(peg$currPos) === 34) { - s4 = peg$c4; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e6); - } - } - if (s4 !== peg$FAILED) { - s1 = s3; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f4(s1); - } - s0 = s1; - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e3); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseignore() { - var s0, s1; - - var key = peg$currPos * 12 + 5; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = []; - s1 = peg$parseany(); - if (s1 === peg$FAILED) { - s1 = peg$parsenewLine(); - if (s1 === peg$FAILED) { - s1 = peg$parse_(); - } - } - while (s1 !== peg$FAILED) { - s0.push(s1); - s1 = peg$parseany(); - if (s1 === peg$FAILED) { - s1 = peg$parsenewLine(); - if (s1 === peg$FAILED) { - s1 = peg$parse_(); - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsecomment() { - var s0, s1, s2, s3, s4; - - var key = peg$currPos * 12 + 6; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - peg$silentFails++; - s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c5) { - s1 = peg$c5; - peg$currPos += 2; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e9); - } - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$parseany(); - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$parseany(); - } - s3 = peg$currPos; - peg$silentFails++; - s4 = peg$parsenewLine(); - peg$silentFails--; - if (s4 !== peg$FAILED) { - peg$currPos = s3; - s3 = undefined; - } else { - s3 = peg$FAILED; - } - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f5(); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e8); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsedelimitedComment() { - var s0, s1, s2, s3; - - var key = peg$currPos * 12 + 7; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - peg$silentFails++; - s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c6) { - s1 = peg$c6; - peg$currPos += 2; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e10); - } - } - if (s1 !== peg$FAILED) { - s2 = []; - if (peg$r2.test(input.charAt(peg$currPos))) { - s3 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e11); - } - } - while (s3 !== peg$FAILED) { - s2.push(s3); - if (peg$r2.test(input.charAt(peg$currPos))) { - s3 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e11); - } - } - } - if (input.substr(peg$currPos, 2) === peg$c7) { - s3 = peg$c7; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e12); - } - } - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f6(); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e8); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parse_() { - var s0, s1; - - var key = peg$currPos * 12 + 8; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - peg$silentFails++; - if (peg$r3.test(input.charAt(peg$currPos))) { - s0 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s0 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e14); - } - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e13); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsenewLine() { - var s0, s1; - - var key = peg$currPos * 12 + 9; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - peg$silentFails++; - if (peg$r4.test(input.charAt(peg$currPos))) { - s0 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s0 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e16); - } - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e15); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseany() { - var s0, s1; - - var key = peg$currPos * 12 + 10; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - peg$silentFails++; - if (peg$r5.test(input.charAt(peg$currPos))) { - s0 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s0 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e18); - } - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e17); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseidentifier() { - var s0, s1, s2, s3, s4; - - var key = peg$currPos * 12 + 11; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - peg$silentFails++; - s0 = peg$currPos; - s1 = peg$currPos; - s2 = []; - if (peg$r6.test(input.charAt(peg$currPos))) { - s3 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e20); - } - } - if (s3 !== peg$FAILED) { - while (s3 !== peg$FAILED) { - s2.push(s3); - if (peg$r6.test(input.charAt(peg$currPos))) { - s3 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e20); - } - } - } - } else { - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - s3 = []; - if (peg$r7.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e21); - } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$r7.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e21); - } - } - } - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f7(); - } - s0 = s1; - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e19); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - peg$result = peg$startRuleFunction(); - - if (peg$result !== peg$FAILED && peg$currPos === input.length) { - return peg$result; - } else { - if (peg$result !== peg$FAILED && peg$currPos < input.length) { - peg$fail(peg$endExpectation()); - } - - throw peg$buildStructuredError( - peg$maxFailExpected, - peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, - peg$maxFailPos < input.length - ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) - : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) - ); - } -} - -module.exports = { - SyntaxError: peg$SyntaxError, - parse: peg$parse, -}; From 2736fb9a1791e3049926a977706c01b589d3b403 Mon Sep 17 00:00:00 2001 From: Conor Barnes Date: Thu, 8 Sep 2022 16:31:02 -0300 Subject: [PATCH 28/55] delete conflicting file --- .../ReducerProject_IncludeParser.js | 1183 ----------------- 1 file changed, 1183 deletions(-) delete mode 100644 packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js deleted file mode 100644 index 7f9c0418..00000000 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js +++ /dev/null @@ -1,1183 +0,0 @@ -// Generated by Peggy 2.0.1. -// -// https://peggyjs.org/ - -"use strict"; - -function peg$subclass(child, parent) { - function C() { this.constructor = child; } - C.prototype = parent.prototype; - child.prototype = new C(); -} - -function peg$SyntaxError(message, expected, found, location) { - var self = Error.call(this, message); - // istanbul ignore next Check is a necessary evil to support older environments - if (Object.setPrototypeOf) { - Object.setPrototypeOf(self, peg$SyntaxError.prototype); - } - self.expected = expected; - self.found = found; - self.location = location; - self.name = "SyntaxError"; - return self; -} - -peg$subclass(peg$SyntaxError, Error); - -function peg$padEnd(str, targetLength, padString) { - padString = padString || " "; - if (str.length > targetLength) { return str; } - targetLength -= str.length; - padString += padString.repeat(targetLength); - return str + padString.slice(0, targetLength); -} - -peg$SyntaxError.prototype.format = function(sources) { - var str = "Error: " + this.message; - if (this.location) { - var src = null; - var k; - for (k = 0; k < sources.length; k++) { - if (sources[k].source === this.location.source) { - src = sources[k].text.split(/\r\n|\n|\r/g); - break; - } - } - var s = this.location.start; - var loc = this.location.source + ":" + s.line + ":" + s.column; - if (src) { - var e = this.location.end; - var filler = peg$padEnd("", s.line.toString().length, ' '); - var line = src[s.line - 1]; - var last = s.line === e.line ? e.column : line.length + 1; - var hatLen = (last - s.column) || 1; - str += "\n --> " + loc + "\n" - + filler + " |\n" - + s.line + " | " + line + "\n" - + filler + " | " + peg$padEnd("", s.column - 1, ' ') - + peg$padEnd("", hatLen, "^"); - } else { - str += "\n at " + loc; - } - } - return str; -}; - -peg$SyntaxError.buildMessage = function(expected, found) { - var DESCRIBE_EXPECTATION_FNS = { - literal: function(expectation) { - return "\"" + literalEscape(expectation.text) + "\""; - }, - - class: function(expectation) { - var escapedParts = expectation.parts.map(function(part) { - return Array.isArray(part) - ? classEscape(part[0]) + "-" + classEscape(part[1]) - : classEscape(part); - }); - - return "[" + (expectation.inverted ? "^" : "") + escapedParts.join("") + "]"; - }, - - any: function() { - return "any character"; - }, - - end: function() { - return "end of input"; - }, - - other: function(expectation) { - return expectation.description; - } - }; - - function hex(ch) { - return ch.charCodeAt(0).toString(16).toUpperCase(); - } - - function literalEscape(s) { - return s - .replace(/\\/g, "\\\\") - .replace(/"/g, "\\\"") - .replace(/\0/g, "\\0") - .replace(/\t/g, "\\t") - .replace(/\n/g, "\\n") - .replace(/\r/g, "\\r") - .replace(/[\x00-\x0F]/g, function(ch) { return "\\x0" + hex(ch); }) - .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return "\\x" + hex(ch); }); - } - - function classEscape(s) { - return s - .replace(/\\/g, "\\\\") - .replace(/\]/g, "\\]") - .replace(/\^/g, "\\^") - .replace(/-/g, "\\-") - .replace(/\0/g, "\\0") - .replace(/\t/g, "\\t") - .replace(/\n/g, "\\n") - .replace(/\r/g, "\\r") - .replace(/[\x00-\x0F]/g, function(ch) { return "\\x0" + hex(ch); }) - .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return "\\x" + hex(ch); }); - } - - function describeExpectation(expectation) { - return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation); - } - - function describeExpected(expected) { - var descriptions = expected.map(describeExpectation); - var i, j; - - descriptions.sort(); - - if (descriptions.length > 0) { - for (i = 1, j = 1; i < descriptions.length; i++) { - if (descriptions[i - 1] !== descriptions[i]) { - descriptions[j] = descriptions[i]; - j++; - } - } - descriptions.length = j; - } - - switch (descriptions.length) { - case 1: - return descriptions[0]; - - case 2: - return descriptions[0] + " or " + descriptions[1]; - - default: - return descriptions.slice(0, -1).join(", ") - + ", or " - + descriptions[descriptions.length - 1]; - } - } - - function describeFound(found) { - return found ? "\"" + literalEscape(found) + "\"" : "end of input"; - } - - return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; -}; - -function peg$parse(input, options) { - options = options !== undefined ? options : {}; - - var peg$FAILED = {}; - var peg$source = options.grammarSource; - - var peg$startRuleFunctions = { start: peg$parsestart }; - var peg$startRuleFunction = peg$parsestart; - - var peg$c0 = "#"; - var peg$c1 = "#include"; - var peg$c2 = "as"; - var peg$c3 = "'"; - var peg$c4 = "\""; - var peg$c5 = "//"; - var peg$c6 = "/*"; - var peg$c7 = "*/"; - - var peg$r0 = /^[^']/; - var peg$r1 = /^[^"]/; - var peg$r2 = /^[^*]/; - var peg$r3 = /^[ \t]/; - var peg$r4 = /^[\n\r]/; - var peg$r5 = /^[^\r\n]/; - var peg$r6 = /^[_a-z]/; - var peg$r7 = /^[_a-z0-9]/i; - - var peg$e0 = peg$literalExpectation("#", false); - var peg$e1 = peg$literalExpectation("#include", false); - var peg$e2 = peg$literalExpectation("as", false); - var peg$e3 = peg$otherExpectation("string"); - var peg$e4 = peg$literalExpectation("'", false); - var peg$e5 = peg$classExpectation(["'"], true, false); - var peg$e6 = peg$literalExpectation("\"", false); - var peg$e7 = peg$classExpectation(["\""], true, false); - var peg$e8 = peg$otherExpectation("comment"); - var peg$e9 = peg$literalExpectation("//", false); - var peg$e10 = peg$literalExpectation("/*", false); - var peg$e11 = peg$classExpectation(["*"], true, false); - var peg$e12 = peg$literalExpectation("*/", false); - var peg$e13 = peg$otherExpectation("white space"); - var peg$e14 = peg$classExpectation([" ", "\t"], false, false); - var peg$e15 = peg$otherExpectation("newline"); - var peg$e16 = peg$classExpectation(["\n", "\r"], false, false); - var peg$e17 = peg$otherExpectation("code"); - var peg$e18 = peg$classExpectation(["\r", "\n"], true, false); - var peg$e19 = peg$otherExpectation("identifier"); - var peg$e20 = peg$classExpectation(["_", ["a", "z"]], false, false); - var peg$e21 = peg$classExpectation(["_", ["a", "z"], ["0", "9"]], false, true); - - var peg$f0 = function(head, tail) {return [head, ...tail].filter( e => e != '');}; - var peg$f1 = function() {return [];}; - var peg$f2 = function(file, variable) {return [!variable ? '' : variable, file]}; - var peg$f3 = function(characters) {return characters.join('');}; - var peg$f4 = function(characters) {return characters.join('');}; - var peg$f5 = function() { return '';}; - var peg$f6 = function() { return '';}; - var peg$f7 = function() {return text();}; - var peg$currPos = 0; - var peg$savedPos = 0; - var peg$posDetailsCache = [{ line: 1, column: 1 }]; - var peg$maxFailPos = 0; - var peg$maxFailExpected = []; - var peg$silentFails = 0; - - var peg$resultsCache = {}; - - var peg$result; - - if ("startRule" in options) { - if (!(options.startRule in peg$startRuleFunctions)) { - throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); - } - - peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; - } - - function text() { - return input.substring(peg$savedPos, peg$currPos); - } - - function offset() { - return peg$savedPos; - } - - function range() { - return { - source: peg$source, - start: peg$savedPos, - end: peg$currPos - }; - } - - function location() { - return peg$computeLocation(peg$savedPos, peg$currPos); - } - - function expected(description, location) { - location = location !== undefined - ? location - : peg$computeLocation(peg$savedPos, peg$currPos); - - throw peg$buildStructuredError( - [peg$otherExpectation(description)], - input.substring(peg$savedPos, peg$currPos), - location - ); - } - - function error(message, location) { - location = location !== undefined - ? location - : peg$computeLocation(peg$savedPos, peg$currPos); - - throw peg$buildSimpleError(message, location); - } - - function peg$literalExpectation(text, ignoreCase) { - return { type: "literal", text: text, ignoreCase: ignoreCase }; - } - - function peg$classExpectation(parts, inverted, ignoreCase) { - return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase }; - } - - function peg$anyExpectation() { - return { type: "any" }; - } - - function peg$endExpectation() { - return { type: "end" }; - } - - function peg$otherExpectation(description) { - return { type: "other", description: description }; - } - - function peg$computePosDetails(pos) { - var details = peg$posDetailsCache[pos]; - var p; - - if (details) { - return details; - } else { - p = pos - 1; - while (!peg$posDetailsCache[p]) { - p--; - } - - details = peg$posDetailsCache[p]; - details = { - line: details.line, - column: details.column - }; - - while (p < pos) { - if (input.charCodeAt(p) === 10) { - details.line++; - details.column = 1; - } else { - details.column++; - } - - p++; - } - - peg$posDetailsCache[pos] = details; - - return details; - } - } - - function peg$computeLocation(startPos, endPos) { - var startPosDetails = peg$computePosDetails(startPos); - var endPosDetails = peg$computePosDetails(endPos); - - return { - source: peg$source, - start: { - offset: startPos, - line: startPosDetails.line, - column: startPosDetails.column - }, - end: { - offset: endPos, - line: endPosDetails.line, - column: endPosDetails.column - } - }; - } - - function peg$fail(expected) { - if (peg$currPos < peg$maxFailPos) { return; } - - if (peg$currPos > peg$maxFailPos) { - peg$maxFailPos = peg$currPos; - peg$maxFailExpected = []; - } - - peg$maxFailExpected.push(expected); - } - - function peg$buildSimpleError(message, location) { - return new peg$SyntaxError(message, null, null, location); - } - - function peg$buildStructuredError(expected, found, location) { - return new peg$SyntaxError( - peg$SyntaxError.buildMessage(expected, found), - expected, - found, - location - ); - } - - function peg$parsestart() { - var s0, s1, s2, s3, s4; - - var key = peg$currPos * 12 + 0; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = []; - s2 = peg$parsenewLine(); - if (s2 === peg$FAILED) { - s2 = peg$parse_(); - if (s2 === peg$FAILED) { - s2 = peg$parsecomment(); - if (s2 === peg$FAILED) { - s2 = peg$parsedelimitedComment(); - } - } - } - while (s2 !== peg$FAILED) { - s1.push(s2); - s2 = peg$parsenewLine(); - if (s2 === peg$FAILED) { - s2 = peg$parse_(); - if (s2 === peg$FAILED) { - s2 = peg$parsecomment(); - if (s2 === peg$FAILED) { - s2 = peg$parsedelimitedComment(); - } - } - } - } - s2 = peg$parseincludes(); - if (s2 !== peg$FAILED) { - s3 = []; - s4 = peg$parsenewLine(); - while (s4 !== peg$FAILED) { - s3.push(s4); - s4 = peg$parsenewLine(); - } - s4 = peg$parseignore(); - s0 = s2; - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseincludes() { - var s0, s1, s2, s3, s4, s5; - - var key = peg$currPos * 12 + 1; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = peg$parsedependencyStatement(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$currPos; - s4 = []; - s5 = peg$parsenewLine(); - if (s5 !== peg$FAILED) { - while (s5 !== peg$FAILED) { - s4.push(s5); - s5 = peg$parsenewLine(); - } - } else { - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - s5 = peg$parsedependencyStatement(); - if (s5 !== peg$FAILED) { - s3 = s5; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$currPos; - s4 = []; - s5 = peg$parsenewLine(); - if (s5 !== peg$FAILED) { - while (s5 !== peg$FAILED) { - s4.push(s5); - s5 = peg$parsenewLine(); - } - } else { - s4 = peg$FAILED; - } - if (s4 !== peg$FAILED) { - s5 = peg$parsedependencyStatement(); - if (s5 !== peg$FAILED) { - s3 = s5; - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } else { - peg$currPos = s3; - s3 = peg$FAILED; - } - } - peg$savedPos = s0; - s0 = peg$f0(s1, s2); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$currPos; - peg$silentFails++; - if (input.charCodeAt(peg$currPos) === 35) { - s2 = peg$c0; - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e0); } - } - peg$silentFails--; - if (s2 === peg$FAILED) { - s1 = undefined; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f1(); - } - s0 = s1; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsedependencyStatement() { - var s0; - - var key = peg$currPos * 12 + 2; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$parseincludeStatement(); - if (s0 === peg$FAILED) { - s0 = peg$parsecomment(); - if (s0 === peg$FAILED) { - s0 = peg$parsedelimitedComment(); - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseincludeStatement() { - var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; - - var key = peg$currPos * 12 + 3; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = peg$currPos; - s1 = []; - s2 = peg$parse_(); - while (s2 !== peg$FAILED) { - s1.push(s2); - s2 = peg$parse_(); - } - if (input.substr(peg$currPos, 8) === peg$c1) { - s2 = peg$c1; - peg$currPos += 8; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e1); } - } - if (s2 !== peg$FAILED) { - s3 = []; - s4 = peg$parse_(); - if (s4 !== peg$FAILED) { - while (s4 !== peg$FAILED) { - s3.push(s4); - s4 = peg$parse_(); - } - } else { - s3 = peg$FAILED; - } - if (s3 !== peg$FAILED) { - s4 = peg$parsestring(); - if (s4 !== peg$FAILED) { - s5 = peg$currPos; - s6 = []; - s7 = peg$parse_(); - if (s7 !== peg$FAILED) { - while (s7 !== peg$FAILED) { - s6.push(s7); - s7 = peg$parse_(); - } - } else { - s6 = peg$FAILED; - } - if (s6 !== peg$FAILED) { - if (input.substr(peg$currPos, 2) === peg$c2) { - s7 = peg$c2; - peg$currPos += 2; - } else { - s7 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e2); } - } - if (s7 !== peg$FAILED) { - s8 = []; - s9 = peg$parse_(); - if (s9 !== peg$FAILED) { - while (s9 !== peg$FAILED) { - s8.push(s9); - s9 = peg$parse_(); - } - } else { - s8 = peg$FAILED; - } - if (s8 !== peg$FAILED) { - s9 = peg$parseidentifier(); - if (s9 !== peg$FAILED) { - s5 = s9; - } else { - peg$currPos = s5; - s5 = peg$FAILED; - } - } else { - peg$currPos = s5; - s5 = peg$FAILED; - } - } else { - peg$currPos = s5; - s5 = peg$FAILED; - } - } else { - peg$currPos = s5; - s5 = peg$FAILED; - } - if (s5 === peg$FAILED) { - s5 = null; - } - s6 = []; - s7 = peg$parse_(); - while (s7 !== peg$FAILED) { - s6.push(s7); - s7 = peg$parse_(); - } - s7 = peg$currPos; - peg$silentFails++; - s8 = peg$parsenewLine(); - peg$silentFails--; - if (s8 !== peg$FAILED) { - peg$currPos = s7; - s7 = undefined; - } else { - s7 = peg$FAILED; - } - if (s7 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f2(s4, s5); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsestring() { - var s0, s1, s2, s3, s4; - - var key = peg$currPos * 12 + 4; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - peg$silentFails++; - s0 = peg$currPos; - s1 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 39) { - s2 = peg$c3; - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s2 !== peg$FAILED) { - s3 = []; - if (peg$r0.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e5); } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$r0.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e5); } - } - } - if (input.charCodeAt(peg$currPos) === 39) { - s4 = peg$c3; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e4); } - } - if (s4 !== peg$FAILED) { - s1 = s3; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f3(s1); - } - s0 = s1; - if (s0 === peg$FAILED) { - s0 = peg$currPos; - s1 = peg$currPos; - if (input.charCodeAt(peg$currPos) === 34) { - s2 = peg$c4; - peg$currPos++; - } else { - s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e6); } - } - if (s2 !== peg$FAILED) { - s3 = []; - if (peg$r1.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e7); } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$r1.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e7); } - } - } - if (input.charCodeAt(peg$currPos) === 34) { - s4 = peg$c4; - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e6); } - } - if (s4 !== peg$FAILED) { - s1 = s3; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f4(s1); - } - s0 = s1; - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseignore() { - var s0, s1; - - var key = peg$currPos * 12 + 5; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - s0 = []; - s1 = peg$parseany(); - if (s1 === peg$FAILED) { - s1 = peg$parsenewLine(); - if (s1 === peg$FAILED) { - s1 = peg$parse_(); - } - } - while (s1 !== peg$FAILED) { - s0.push(s1); - s1 = peg$parseany(); - if (s1 === peg$FAILED) { - s1 = peg$parsenewLine(); - if (s1 === peg$FAILED) { - s1 = peg$parse_(); - } - } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsecomment() { - var s0, s1, s2, s3, s4; - - var key = peg$currPos * 12 + 6; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - peg$silentFails++; - s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c5) { - s1 = peg$c5; - peg$currPos += 2; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e9); } - } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$parseany(); - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$parseany(); - } - s3 = peg$currPos; - peg$silentFails++; - s4 = peg$parsenewLine(); - peg$silentFails--; - if (s4 !== peg$FAILED) { - peg$currPos = s3; - s3 = undefined; - } else { - s3 = peg$FAILED; - } - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f5(); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e8); } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsedelimitedComment() { - var s0, s1, s2, s3; - - var key = peg$currPos * 12 + 7; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - peg$silentFails++; - s0 = peg$currPos; - if (input.substr(peg$currPos, 2) === peg$c6) { - s1 = peg$c6; - peg$currPos += 2; - } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } - } - if (s1 !== peg$FAILED) { - s2 = []; - if (peg$r2.test(input.charAt(peg$currPos))) { - s3 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - while (s3 !== peg$FAILED) { - s2.push(s3); - if (peg$r2.test(input.charAt(peg$currPos))) { - s3 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } - } - } - if (input.substr(peg$currPos, 2) === peg$c7) { - s3 = peg$c7; - peg$currPos += 2; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e12); } - } - if (s3 !== peg$FAILED) { - peg$savedPos = s0; - s0 = peg$f6(); - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - } else { - peg$currPos = s0; - s0 = peg$FAILED; - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e8); } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parse_() { - var s0, s1; - - var key = peg$currPos * 12 + 8; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - peg$silentFails++; - if (peg$r3.test(input.charAt(peg$currPos))) { - s0 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e14); } - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e13); } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parsenewLine() { - var s0, s1; - - var key = peg$currPos * 12 + 9; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - peg$silentFails++; - if (peg$r4.test(input.charAt(peg$currPos))) { - s0 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e16); } - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e15); } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseany() { - var s0, s1; - - var key = peg$currPos * 12 + 10; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - peg$silentFails++; - if (peg$r5.test(input.charAt(peg$currPos))) { - s0 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e18); } - } - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e17); } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - function peg$parseidentifier() { - var s0, s1, s2, s3, s4; - - var key = peg$currPos * 12 + 11; - var cached = peg$resultsCache[key]; - - if (cached) { - peg$currPos = cached.nextPos; - - return cached.result; - } - - peg$silentFails++; - s0 = peg$currPos; - s1 = peg$currPos; - s2 = []; - if (peg$r6.test(input.charAt(peg$currPos))) { - s3 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e20); } - } - if (s3 !== peg$FAILED) { - while (s3 !== peg$FAILED) { - s2.push(s3); - if (peg$r6.test(input.charAt(peg$currPos))) { - s3 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e20); } - } - } - } else { - s2 = peg$FAILED; - } - if (s2 !== peg$FAILED) { - s3 = []; - if (peg$r7.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e21); } - } - while (s4 !== peg$FAILED) { - s3.push(s4); - if (peg$r7.test(input.charAt(peg$currPos))) { - s4 = input.charAt(peg$currPos); - peg$currPos++; - } else { - s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e21); } - } - } - s2 = [s2, s3]; - s1 = s2; - } else { - peg$currPos = s1; - s1 = peg$FAILED; - } - if (s1 !== peg$FAILED) { - peg$savedPos = s0; - s1 = peg$f7(); - } - s0 = s1; - peg$silentFails--; - if (s0 === peg$FAILED) { - s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e19); } - } - - peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; - - return s0; - } - - peg$result = peg$startRuleFunction(); - - if (peg$result !== peg$FAILED && peg$currPos === input.length) { - return peg$result; - } else { - if (peg$result !== peg$FAILED && peg$currPos < input.length) { - peg$fail(peg$endExpectation()); - } - - throw peg$buildStructuredError( - peg$maxFailExpected, - peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, - peg$maxFailPos < input.length - ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) - : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) - ); - } -} - -module.exports = { - SyntaxError: peg$SyntaxError, - parse: peg$parse -}; From 1c98aaa3e20abf4fe284f4ea2263907ab4a3459c Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Thu, 8 Sep 2022 23:13:28 +0200 Subject: [PATCH 29/55] value vs result conversion functions --- .../Reducer/Reducer_TestMacroHelpers.res | 17 ++++++++--------- .../__tests__/Reducer/Reducer_test.res | 2 +- .../Reducer_Dispatch_BuiltIn.res | 16 ++++++++-------- .../Reducer_Dispatch_BuiltInMacros.res | 9 ++++----- .../src/rescript/Reducer/Reducer_ErrorValue.res | 17 +++++++++++++++++ .../Reducer_Expression/Reducer_Expression.res | 3 +-- .../Reducer_ExpressionWithContext.res | 9 +++++++++ .../Reducer_Expression_BindingsReplacer.res | 6 +----- .../Reducer_Expression_Macro.res | 17 +++++++++++++++++ .../Reducer_Expression/Reducer_Expression_T.res | 6 ++++++ .../Reducer_Type/Reducer_Type_Compile.res | 2 +- ...ReducerInterface_InternalExpressionValue.res | 6 ++++++ .../ReducerProject_ProjectItem.res | 3 +-- 13 files changed, 80 insertions(+), 33 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res index a1a3399e..329f30bc 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res @@ -17,18 +17,17 @@ let testMacro_ = ( expectedCode: string, ) => { let bindings = Bindings.fromArray(bindArray) - tester(expr->T.toString, () => { - let result = switch expr->Reducer_Dispatch_BuiltInMacros.dispatchMacroCall( + tester(expr->T.toString, () => + expr + ->Macro.expandMacroCallRs( bindings, ProjectAccessorsT.identityAccessors, Expression.reduceExpressionInProject, - ) { - | v => Ok(v) - | exception Reducer_ErrorValue.ErrorException(e) => Error(e) - } - - result->ExpressionWithContext.toStringResult->expect->toEqual(expectedCode) - }) + ) + ->ExpressionWithContext.toStringResult + ->expect + ->toEqual(expectedCode) + ) } let testMacroEval_ = ( diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res index f70aa934..f6b9ad77 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res @@ -56,7 +56,7 @@ describe("test exceptions", () => { testDescriptionEvalToBe( "javascript exception", "javascriptraise('div by 0')", - "Error(JS Exception: Error: 'div by 0')", + "Error(Error: 'div by 0')", ) // testDescriptionEvalToBe( // "rescript exception", diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index b7fed530..985558e7 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res @@ -3,6 +3,7 @@ module BindingsReplacer = Reducer_Expression_BindingsReplacer module Continuation = ReducerInterface_Value_Continuation module ExpressionT = Reducer_Expression_T module ExternalLibrary = ReducerInterface.ExternalLibrary +module InternalExpressionValue = ReducerInterface_InternalExpressionValue module Lambda = Reducer_Expression_Lambda module MathJs = Reducer_MathJs module ProjectAccessorsT = ReducerProject_ProjectAccessors_T @@ -206,13 +207,12 @@ let dispatch = ( let (fn, args) = call // There is a bug that prevents string match in patterns // So we have to recreate a copy of the string - switch ExternalLibrary.dispatch((Js.String.make(fn), args), accessors, reducer, callInternal) { - | Ok(v) => v - | Error(e) => raise(ErrorException(e)) - } + ExternalLibrary.dispatch( + (Js.String.make(fn), args), + accessors, + reducer, + callInternal, + )->InternalExpressionValue.resultToValue } catch { - | ErrorException(e) => raise(ErrorException(e)) - | Js.Exn.Error(obj) => - raise(ErrorException(REJavaScriptExn(Js.Exn.message(obj), Js.Exn.name(obj)))) - | _ => raise(ErrorException(RETodo("unhandled rescript exception"))) + | exn => Reducer_ErrorValue.fromException(exn)->Reducer_ErrorValue.toException } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index 67ed732c..73b7bbd1 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -15,7 +15,6 @@ module ProjectReducerFnT = ReducerProject_ReducerFn_T open Reducer_Expression_ExpressionBuilder -exception ErrorException = ErrorValue.ErrorException type expression = ExpressionT.expression type expressionWithContext = ExpressionWithContext.expressionWithContext @@ -45,7 +44,7 @@ let dispatchMacroCall = ( } let doBindStatement = (bindingExpr: expression, statement: expression, accessors) => { - let defaultStatement = ErrorValue.REAssignmentExpected->ErrorException + let defaultStatement = ErrorValue.REAssignmentExpected switch statement { | ExpressionT.EList(list{ExpressionT.EValue(IEvCall(callName)), symbolExpr, statement}) => { let setBindingsFn = correspondingSetBindingsFn(callName) @@ -55,10 +54,10 @@ let dispatchMacroCall = ( boundStatement, ) => eFunction(setBindingsFn, list{newBindingsExpr, symbolExpr, boundStatement})) } else { - raise(defaultStatement) + defaultStatement->Reducer_ErrorValue.toException } } - | _ => raise(defaultStatement) + | _ => defaultStatement->Reducer_ErrorValue.toException } } @@ -142,7 +141,7 @@ let dispatchMacroCall = ( let ifTrueBlock = eBlock(list{ifTrue}) ExpressionWithContext.withContext(ifTrueBlock, bindings) } - | _ => raise(ErrorException(REExpectedType("Boolean", ""))) + | _ => REExpectedType("Boolean", "")->Reducer_ErrorValue.toException } } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res index e6404b18..b6baeaf5 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res @@ -64,3 +64,20 @@ let errorToString = err => | RENeedToRun => "Need to run" | REOther(msg) => `Error: ${msg}` } + +let fromException = exn => + switch exn { + | ErrorException(e) => e + | Js.Exn.Error(e) => + switch Js.Exn.message(e) { + | Some(message) => REOther(message) + | None => + switch Js.Exn.name(e) { + | Some(name) => REOther(name) + | None => REOther("Unknown error") + } + } + | _e => REOther("Unknown error") + } + +let toException = (errorValue: t) => raise(ErrorException(errorValue)) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res index 4b957e33..ea810c88 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res @@ -101,8 +101,7 @@ module BackCompatible = { try { expression->reduceExpressionInProject(accessors.stdLib, accessors)->Ok } catch { - | ErrorException(e) => Error(e) - | _ => raise(ErrorException(RETodo("internal exception"))) + | exn => Reducer_ErrorValue.fromException(exn)->Error } } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_ExpressionWithContext.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_ExpressionWithContext.res index 23b7e2c8..539585b4 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_ExpressionWithContext.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_ExpressionWithContext.res @@ -18,6 +18,8 @@ type expressionWithContext = | ExpressionWithContext(expression, context) | ExpressionNoContext(expression) +type t = expressionWithContext + let callReducer = ( expressionWithContext: expressionWithContext, bindings: bindings, @@ -51,3 +53,10 @@ let toStringResult = rExpressionWithContext => | Ok(expressionWithContext) => `Ok(${toString(expressionWithContext)})` | Error(errorValue) => ErrorValue.errorToString(errorValue) } + +let resultToValue = (rExpressionWithContext: result): t => { + switch rExpressionWithContext { + | Ok(expressionWithContext) => expressionWithContext + | Error(errorValue) => ErrorValue.toException(errorValue) + } +} diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_BindingsReplacer.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_BindingsReplacer.res index 8a729405..f1bf0135 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_BindingsReplacer.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_BindingsReplacer.res @@ -41,9 +41,5 @@ and checkIfCallable = (evValue: internalExpressionValue) => switch evValue { | IEvCall(_) | IEvLambda(_) => evValue | _ => - raise( - ErrorValue.ErrorException( - ErrorValue.RENotAFunction(InternalExpressionValue.toString(evValue)), - ), - ) + ErrorValue.RENotAFunction(InternalExpressionValue.toString(evValue))->ErrorValue.toException } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res index 7426be18..11a7cb0b 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res @@ -10,6 +10,23 @@ type expression = ExpressionT.expression type internalExpressionValue = InternalExpressionValue.t type expressionWithContext = ExpressionWithContext.expressionWithContext +let expandMacroCallRs = ( + macroExpression: expression, + bindings: ExpressionT.bindings, + accessors: ProjectAccessorsT.t, + reduceExpression: ProjectReducerFnT.t, +): result => + try { + Reducer_Dispatch_BuiltInMacros.dispatchMacroCall( + macroExpression, + bindings, + accessors, + reduceExpression, + )->Ok + } catch { + | exn => Reducer_ErrorValue.fromException(exn)->Error + } + let doMacroCall = ( macroExpression: expression, bindings: ExpressionT.bindings, diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_T.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_T.res index 61f723df..be2755fe 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_T.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_T.res @@ -82,3 +82,9 @@ type optionFfiFnReturningResult = ( type expressionOrFFI = | NotFFI(expression) | FFI(ffiFn) + +let resultToValue = (rExpression: result): t => + switch rExpression { + | Ok(expression) => expression + | Error(errorValue) => Reducer_ErrorValue.toException(errorValue) + } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Compile.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Compile.res index 73696831..b2e0be9b 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Compile.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Compile.res @@ -15,7 +15,7 @@ let ievFromTypeExpression = ( let sourceCode = `type ${sIndex}=${typeExpressionSourceCode}` Reducer_Expression.BackCompatible.parse(sourceCode)->Belt.Result.flatMap(expr => { let accessors = ProjectAccessorsT.identityAccessors - let result = reducerFn(expr, Bindings.emptyBindings, accessors) + let _result = reducerFn(expr, Bindings.emptyBindings, accessors) let nameSpace = accessors.states.continuation switch Bindings.getType(nameSpace, sIndex) { diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res index 34eb6f40..5531cbdf 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res @@ -244,3 +244,9 @@ let nameSpaceGet = (nameSpace: nameSpace, key: string): option => { let NameSpace(container) = nameSpace container->Belt.Map.String.get(key) } + +let resultToValue = (rExpression: result): t => + switch rExpression { + | Ok(expression) => expression + | Error(errorValue) => Reducer_ErrorValue.toException(errorValue) + } diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res index 8517dd95..7676ddef 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res @@ -195,8 +195,7 @@ let doBuildResult = ( try { Reducer_Expression.reduceExpressionInProject(expression, aContinuation, accessors)->Ok } catch { - | Reducer_ErrorValue.ErrorException(e) => e->Error - | _ => RETodo("unhandled rescript exception")->Error + | exn => Reducer_ErrorValue.fromException(exn)->Error } ), ) From 5d1730101612a8575fcba7c3151f1fac16faab1a Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 9 Sep 2022 01:14:42 +0200 Subject: [PATCH 30/55] remove raise --- .../Reducer/Reducer_Expression/Reducer_Expression.res | 2 -- .../Reducer_Expression/Reducer_Expression_Lambda.res | 6 +++--- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res index ea810c88..e3fdf168 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res @@ -14,8 +14,6 @@ module T = Reducer_Expression_T type errorValue = Reducer_ErrorValue.errorValue type t = T.t -exception ErrorException = Reducer_ErrorValue.ErrorException - /* Recursively evaluate/reduce the expression (Lisp AST/Lambda calculus) */ diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Lambda.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Lambda.res index c4ef011e..aa0745ae 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Lambda.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Lambda.res @@ -23,7 +23,7 @@ let checkArity = ( let argsLength = Belt.List.length(args) let parametersLength = Js.Array2.length(lambdaValue.parameters) if argsLength !== parametersLength { - raise(ErrorValue.ErrorException(ErrorValue.REArityError(None, parametersLength, argsLength))) + ErrorValue.REArityError(None, parametersLength, argsLength)->ErrorValue.toException } else { args } @@ -38,7 +38,7 @@ let checkArity = ( let checkIfReduced = (args: list) => args->Belt.List.reduceReverse(list{}, (acc, arg) => switch arg { - | IEvSymbol(symbol) => raise(ErrorValue.ErrorException(ErrorValue.RESymbolNotFound(symbol))) + | IEvSymbol(symbol) => ErrorValue.RESymbolNotFound(symbol)->ErrorValue.toException | _ => list{arg, ...acc} } ) @@ -63,7 +63,7 @@ let caseNotFFI = ( let caseFFI = (ffiFn: ExpressionT.ffiFn, args, accessors: ProjectAccessorsT.t) => { switch ffiFn(args->Belt.List.toArray, accessors.environment) { | Ok(value) => value - | Error(value) => raise(ErrorValue.ErrorException(value)) + | Error(value) => value->ErrorValue.toException } } From 3c0255cfb917bbb2eaea4980cccab876b7b272ac Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Fri, 9 Sep 2022 15:26:20 +0800 Subject: [PATCH 31/55] hotfix: lint docs --- packages/website/docs/Api/Danger.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/website/docs/Api/Danger.md b/packages/website/docs/Api/Danger.md index 61f64695..3b4baa0e 100644 --- a/packages/website/docs/Api/Danger.md +++ b/packages/website/docs/Api/Danger.md @@ -14,9 +14,9 @@ Danger.laplace: (number, number) => number Calculates the probability implied by [Laplace's rule of succession](https://en.wikipedia.org/wiki/Rule_of_succession) ```js -trials = 10 -successes = 1 -Danger.laplace(trials, successes) // (successes + 1) / (trials + 2) = 2 / 12 = 0.1666 +trials = 10; +successes = 1; +Danger.laplace(trials, successes); // (successes + 1) / (trials + 2) = 2 / 12 = 0.1666 ``` ### factorial @@ -49,7 +49,7 @@ Danger.binomial: (number, number, number) => number Danger.integrateFunctionBetweenWithNumIntegrationPoints: (number => number, number, number, number) => number ``` -`Danger.integrateFunctionBetweenWithNumIntegrationPoints(f, min, max, numIntegrationPoints)` integrates the function `f` between `min` and `max`, and computes `numIntegrationPoints` in between to do so. +`Danger.integrateFunctionBetweenWithNumIntegrationPoints(f, min, max, numIntegrationPoints)` integrates the function `f` between `min` and `max`, and computes `numIntegrationPoints` in between to do so. Note that the function `f` has to take in and return numbers. To integrate a function which returns distributios, use: @@ -67,7 +67,7 @@ Danger.integrateFunctionBetweenWithEpsilon: (number => number, number, number, n `Danger.integrateFunctionBetweenWithEpsilon(f, min, max, epsilon)` integrates the function `f` between `min` and `max`, and uses an interval of `epsilon` between integration points when doing so. This makes its runtime less predictable than `integrateFunctionBetweenWithNumIntegrationPoints`, because runtime will not only depend on `epsilon`, but also on `min` and `max`. -Same caveats as `integrateFunctionBetweenWithNumIntegrationPoints` apply. +Same caveats as `integrateFunctionBetweenWithNumIntegrationPoints` apply. ### optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions @@ -83,4 +83,4 @@ Example: Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions([{|x| 20-x}, {|y| 10}], 100, 0.01) ``` -Note also that the array ought to have more than one function in it. \ No newline at end of file +Note also that the array ought to have more than one function in it. From 4dc7619e5a28cfab394eec8463f1f87384700c78 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Fri, 9 Sep 2022 15:28:29 +0800 Subject: [PATCH 32/55] hotfix: manual versions in `.release-please-manifest.json` --- .release-please-manifest.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 1f1ac6f3..7a9992fa 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,7 +1,7 @@ { "packages/cli": "0.0.3", - "packages/components": "0.3.1", - "packages/squiggle-lang": "0.3.0", - "packages/vscode-ext": "0.3.1", - "packages/website": "0.3.0" + "packages/components": "0.4.1", + "packages/squiggle-lang": "0.4.1", + "packages/vscode-ext": "0.4.1", + "packages/website": "0.0.0" } From 4d1f76f80e0b11f5202d984c73ec2a2506cdceea Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Fri, 9 Sep 2022 14:39:42 +0400 Subject: [PATCH 33/55] slightly faster map implementation see this comment: https://github.com/quantified-uncertainty/squiggle/pull/1047#issuecomment-1241805927 --- .../src/rescript/FunctionRegistry/Library/FR_List.res | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res index 1def1e36..7be0f9f3 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res @@ -33,16 +33,14 @@ module Internals = { eLambdaValue, reducer: ProjectReducerFnT.t, ): ReducerInterface_InternalExpressionValue.t => { - let mappedList = array->E.A.reduceReverse(list{}, (acc, elem) => { - let newElem = Reducer_Expression_Lambda.doLambdaCall( + Belt.Array.map(array, elem => + Reducer_Expression_Lambda.doLambdaCall( eLambdaValue, list{elem}, (accessors: ProjectAccessorsT.t), (reducer: ProjectReducerFnT.t), ) - list{newElem, ...acc} - }) - mappedList->Belt.List.toArray->Wrappers.evArray + )->Wrappers.evArray } let reduce = ( From 1187c0330a71d28740c0dd8a4a5f40fb1a66ee3b Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Fri, 9 Sep 2022 17:04:32 +0400 Subject: [PATCH 34/55] faster filter --- .../rescript/FunctionRegistry/Library/FR_List.res | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res index 7be0f9f3..c174272b 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res @@ -73,19 +73,18 @@ module Internals = { accessors: ProjectAccessorsT.t, reducer: ProjectReducerFnT.t, ) => { - let mappedList = aValueArray->Belt.Array.reduceReverse(list{}, (acc, elem) => { - let newElem = Reducer_Expression_Lambda.doLambdaCall( + Js.Array2.filter(aValueArray, elem => { + let result = Reducer_Expression_Lambda.doLambdaCall( aLambdaValue, list{elem}, accessors, reducer, ) - switch newElem { - | IEvBool(true) => list{elem, ...acc} - | _ => acc + switch result { + | IEvBool(true) => true + | _ => false } - }) - mappedList->Belt.List.toArray->Wrappers.evArray + })->Wrappers.evArray } } From 5de73f171cae18f78013714d7e6cfb2553632710 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Sun, 11 Sep 2022 21:52:25 +0200 Subject: [PATCH 35/55] E modules OCaml style Huge E decomposed in to files --- .../src/rescript/Utility/E copy.resxxx | 916 +++++++++++++++++ .../squiggle-lang/src/rescript/Utility/E.res | 929 +----------------- .../src/rescript/Utility/E/E_A.res | 360 +++++++ .../src/rescript/Utility/E/E_A2.res | 5 + .../src/rescript/Utility/E/E_B.res | 11 + .../src/rescript/Utility/E/E_Dict.res | 10 + .../src/rescript/Utility/E/E_F.res | 20 + .../src/rescript/Utility/E/E_Float.res | 6 + .../rescript/Utility/E/E_FloatFloatMap.res | 24 + .../src/rescript/Utility/E/E_I.res | 4 + .../src/rescript/Utility/E/E_Int.res | 2 + .../src/rescript/Utility/E/E_J.res | 19 + .../src/rescript/Utility/E/E_JsArray.res | 6 + .../src/rescript/Utility/E/E_JsDate.res | 4 + .../src/rescript/Utility/E/E_L.res | 151 +++ .../src/rescript/Utility/E/E_O.res | 99 ++ .../src/rescript/Utility/E/E_O2.res | 7 + .../src/rescript/Utility/E/E_R.res | 94 ++ .../src/rescript/Utility/E/E_R2.res | 19 + .../src/rescript/Utility/E/E_S.res | 8 + .../src/rescript/Utility/E/E_Tuple2.res | 9 + .../src/rescript/Utility/E/E_Tuple3.res | 1 + .../src/rescript/Utility/E/E_U.res | 4 + 23 files changed, 1799 insertions(+), 909 deletions(-) create mode 100644 packages/squiggle-lang/src/rescript/Utility/E copy.resxxx create mode 100644 packages/squiggle-lang/src/rescript/Utility/E/E_A.res create mode 100644 packages/squiggle-lang/src/rescript/Utility/E/E_A2.res create mode 100644 packages/squiggle-lang/src/rescript/Utility/E/E_B.res create mode 100644 packages/squiggle-lang/src/rescript/Utility/E/E_Dict.res create mode 100644 packages/squiggle-lang/src/rescript/Utility/E/E_F.res create mode 100644 packages/squiggle-lang/src/rescript/Utility/E/E_Float.res create mode 100644 packages/squiggle-lang/src/rescript/Utility/E/E_FloatFloatMap.res create mode 100644 packages/squiggle-lang/src/rescript/Utility/E/E_I.res create mode 100644 packages/squiggle-lang/src/rescript/Utility/E/E_Int.res create mode 100644 packages/squiggle-lang/src/rescript/Utility/E/E_J.res create mode 100644 packages/squiggle-lang/src/rescript/Utility/E/E_JsArray.res create mode 100644 packages/squiggle-lang/src/rescript/Utility/E/E_JsDate.res create mode 100644 packages/squiggle-lang/src/rescript/Utility/E/E_L.res create mode 100644 packages/squiggle-lang/src/rescript/Utility/E/E_O.res create mode 100644 packages/squiggle-lang/src/rescript/Utility/E/E_O2.res create mode 100644 packages/squiggle-lang/src/rescript/Utility/E/E_R.res create mode 100644 packages/squiggle-lang/src/rescript/Utility/E/E_R2.res create mode 100644 packages/squiggle-lang/src/rescript/Utility/E/E_S.res create mode 100644 packages/squiggle-lang/src/rescript/Utility/E/E_Tuple2.res create mode 100644 packages/squiggle-lang/src/rescript/Utility/E/E_Tuple3.res create mode 100644 packages/squiggle-lang/src/rescript/Utility/E/E_U.res diff --git a/packages/squiggle-lang/src/rescript/Utility/E copy.resxxx b/packages/squiggle-lang/src/rescript/Utility/E copy.resxxx new file mode 100644 index 00000000..60da5737 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/E copy.resxxx @@ -0,0 +1,916 @@ +/* +Some functions from modules `L`, `O`, and `R` below were copied directly from +running `rescript convert -all` on Rationale https://github.com/jonlaing/rationale +*/ + +let equals = (a, b) => a === b + +module FloatFloatMap = { + module Id = Belt.Id.MakeComparable({ + type t = float + let cmp: (float, float) => int = Pervasives.compare + }) + + type t = Belt.MutableMap.t + + let fromArray = (ar: array<(float, float)>) => Belt.MutableMap.fromArray(ar, ~id=module(Id)) + let toArray = (t: t): array<(float, float)> => Belt.MutableMap.toArray(t) + let empty = () => Belt.MutableMap.make(~id=module(Id)) + let increment = (el, t: t) => + Belt.MutableMap.update(t, el, x => + switch x { + | Some(n) => Some(n +. 1.0) + | None => Some(1.0) + } + ) + + let get = (el, t: t) => Belt.MutableMap.get(t, el) + let fmap = (fn, t: t) => Belt.MutableMap.map(t, fn) + let partition = (fn, t: t) => { + let (match, noMatch) = Belt.Array.partition(toArray(t), fn) + (fromArray(match), fromArray(noMatch)) + } +} + +module Int = { + let max = (i1: int, i2: int) => i1 > i2 ? i1 : i2 + let random = (~min, ~max) => Js.Math.random_int(min, max) +} +/* Utils */ +module U = { + let isEqual = \"==" + let toA = a => [a] + let id = e => e +} + +module Tuple2 = { + let first = (v: ('a, 'b)) => { + let (a, _) = v + a + } + let second = (v: ('a, 'b)) => { + let (_, b) = v + b + } + let toFnCall = (fn, (a1, a2)) => fn(a1, a2) +} + +module Tuple3 = { + let toFnCall = (fn, (a1, a2, a3)) => fn(a1, a2, a3) +} + +module O = { + let dimap = (sFn, rFn, e) => + switch e { + | Some(r) => sFn(r) + | None => rFn() + } + () + let fmap = (f: 'a => 'b, x: option<'a>): option<'b> => { + switch x { + | None => None + | Some(x') => Some(f(x')) + } + } + let bind = (o, f) => + switch o { + | None => None + | Some(a) => f(a) + } + let default = (d, o) => + switch o { + | None => d + | Some(a) => a + } + let defaultFn = (d, o) => + switch o { + | None => d() + | Some(a) => a + } + let isSome = o => + switch o { + | Some(_) => true + | _ => false + } + let isNone = o => + switch o { + | None => true + | _ => false + } + let toExn = (err, o) => + switch o { + | None => raise(Failure(err)) + | Some(a) => a + } + + let some = a => Some(a) + let firstSome = (a, b) => + switch a { + | None => b + | _ => a + } + + let toExt = toExn + + let flatten = o => + switch o { + | None => None + | Some(x) => x + } + + let apply = (o, a) => + switch o { + | Some(f) => bind(a, b => some(f(b))) + | _ => None + } + let flatApply = (fn, b) => apply(fn, Some(b)) |> flatten + + let toBool = opt => + switch opt { + | Some(_) => true + | _ => false + } + + let ffmap = (fn, r) => + switch r { + | Some(sm) => fn(sm) + | _ => None + } + + let toString = opt => + switch opt { + | Some(s) => s + | _ => "" + } + + let toResult = (error, e) => + switch e { + | Some(r) => Belt.Result.Ok(r) + | None => Error(error) + } + + let compare = (compare, f1: option, f2: option) => + switch (f1, f2) { + | (Some(f1), Some(f2)) => Some(compare(f1, f2) ? f1 : f2) + | (Some(f1), None) => Some(f1) + | (None, Some(f2)) => Some(f2) + | (None, None) => None + } + + let min = compare(\"<") + let max = compare(\">") +} + +module O2 = { + let default = (a, b) => O.default(b, a) + let defaultFn = (a, b) => O.defaultFn(b, a) + let toExn = (a, b) => O.toExn(b, a) + let fmap = (a, b) => O.fmap(b, a) + let toResult = (a, b) => O.toResult(b, a) + let bind = (a, b) => O.bind(b, a) +} + +/* Functions */ +module F = { + let pipe = (f, g, x) => g(f(x)) + let compose = (f, g, x) => f(g(x)) + let flip = (f, a, b) => f(b, a) + let always = (x, _y) => x + + let apply = (a, e) => a |> e + + let flatten2Callbacks = (fn1, fn2, fnlast) => + fn1(response1 => fn2(response2 => fnlast(response1, response2))) + + let flatten3Callbacks = (fn1, fn2, fn3, fnlast) => + fn1(response1 => fn2(response2 => fn3(response3 => fnlast(response1, response2, response3)))) + + let flatten4Callbacks = (fn1, fn2, fn3, fn4, fnlast) => + fn1(response1 => + fn2(response2 => + fn3(response3 => fn4(response4 => fnlast(response1, response2, response3, response4))) + ) + ) +} + +module Bool = { + type t = bool + let toString = (t: t) => t ? "TRUE" : "FALSE" + let fromString = str => str == "TRUE" ? true : false + + module O = { + let toBool = opt => + switch opt { + | Some(true) => true + | _ => false + } + } +} + +module Float = { + let with2DigitsPrecision = Js.Float.toPrecisionWithPrecision(_, ~digits=2) + let with3DigitsPrecision = Js.Float.toPrecisionWithPrecision(_, ~digits=3) + let toFixed = Js.Float.toFixed + let toString = Js.Float.toString + let isFinite = Js.Float.isFinite + let toInt = Belt.Float.toInt +} + +module I = { + let increment = n => n + 1 + let decrement = n => n - 1 + let toString = Js.Int.toString + let toFloat = Js.Int.toFloat +} + +exception Assertion(string) + +/* R for Result */ +module R = { + open Belt.Result + let result = (okF, errF, r) => + switch r { + | Ok(a) => okF(a) + | Error(err) => errF(err) + } + let id = e => e |> result(U.id, U.id) + let isOk = Belt.Result.isOk + let getError = (r: result<'a, 'b>) => + switch r { + | Ok(_) => None + | Error(e) => Some(e) + } + let fmap = (f: 'a => 'b, r: result<'a, 'c>): result<'b, 'c> => { + switch r { + | Ok(r') => Ok(f(r')) + | Error(err) => Error(err) + } + } + let bind = (r, f) => + switch r { + | Ok(a) => f(a) + | Error(err) => Error(err) + } + let toExn = (msg: string, x: result<'a, 'b>): 'a => + switch x { + | Ok(r) => r + | Error(_) => raise(Assertion(msg)) + } + let toExnFnString = (errorToStringFn, o) => + switch o { + | Ok(r) => r + | Error(r) => raise(Assertion(errorToStringFn(r))) + } + let default = (default, res: Belt.Result.t<'a, 'b>) => + switch res { + | Ok(r) => r + | Error(_) => default + } + let merge = (a, b) => + switch (a, b) { + | (Error(e), _) => Error(e) + | (_, Error(e)) => Error(e) + | (Ok(a), Ok(b)) => Ok((a, b)) + } + let toOption = (e: Belt.Result.t<'a, 'b>) => + switch e { + | Ok(r) => Some(r) + | Error(_) => None + } + + let errorIfCondition = (errorCondition, errorMessage, r) => + errorCondition(r) ? Error(errorMessage) : Ok(r) + + let ap = (r, a) => + switch r { + | Ok(f) => Ok(f(a)) + | Error(err) => Error(err) + } + let ap' = (r, a) => + switch r { + | Ok(f) => fmap(f, a) + | Error(err) => Error(err) + } + + let liftM2: (('a, 'b) => 'c, result<'a, 'd>, result<'b, 'd>) => result<'c, 'd> = (op, xR, yR) => { + ap'(fmap(op, xR), yR) + } + + let liftJoin2: (('a, 'b) => result<'c, 'd>, result<'a, 'd>, result<'b, 'd>) => result<'c, 'd> = ( + op, + xR, + yR, + ) => { + bind(liftM2(op, xR, yR), x => x) + } + + let fmap2 = (f, r) => + switch r { + | Ok(r) => r->Ok + | Error(x) => x->f->Error + } + + //I'm not sure what to call this. + let unify = (a: result<'a, 'b>, c: 'b => 'a): 'a => + switch a { + | Ok(x) => x + | Error(x) => c(x) + } +} + +module R2 = { + let fmap = (a, b) => R.fmap(b, a) + let bind = (a, b) => R.bind(b, a) + + //Converts result type to change error type only + let errMap = (a: result<'a, 'b>, map: 'b => 'c): result<'a, 'c> => + switch a { + | Ok(r) => Ok(r) + | Error(e) => Error(map(e)) + } + + let fmap2 = (xR, f) => + switch xR { + | Ok(x) => x->Ok + | Error(x) => x->f->Error + } + + let toExn = (a, b) => R.toExn(b, a) +} + +let safe_fn_of_string = (fn, s: string): option<'a> => + try Some(fn(s)) catch { + | _ => None + } + +module S = { + let safe_float = float_of_string->safe_fn_of_string + let safe_int = int_of_string->safe_fn_of_string + let default = (defaultStr, str) => str == "" ? defaultStr : str +} + +module J = { + let toString = F.pipe(Js.Json.decodeString, O.default("")) + let fromString = Js.Json.string + let fromNumber = Js.Json.number + + module O = { + let fromString = (str: string) => + switch str { + | "" => None + | _ => Some(Js.Json.string(str)) + } + + let toString = (str: option<'a>) => + switch str { + | Some(str) => Some(str |> F.pipe(Js.Json.decodeString, O.default(""))) + | _ => None + } + } +} + +module JsDate = { + let fromString = Js.Date.fromString + let now = Js.Date.now + let make = Js.Date.make + let valueOf = Js.Date.valueOf +} + +/* List */ +module L = { + module Util = { + let eq = \"==" + } + let fmap = List.map + let get = Belt.List.get + let toArray = Array.of_list + let fmapi = List.mapi + let concat = List.concat + let concat' = (xs, ys) => List.append(ys, xs) + + let rec drop = (i, xs) => + switch (i, xs) { + | (_, list{}) => list{} + | (i, _) if i <= 0 => xs + | (i, list{_, ...b}) => drop(i - 1, b) + } + + let append = (a, xs) => List.append(xs, list{a}) + let take = { + let rec loop = (i, xs, acc) => + switch (i, xs) { + | (i, _) if i <= 0 => acc + | (_, list{}) => acc + | (i, list{a, ...b}) => loop(i - 1, b, append(a, acc)) + } + (i, xs) => loop(i, xs, list{}) + } + let takeLast = (i, xs) => List.rev(xs) |> take(i) |> List.rev + + let splitAt = (i, xs) => (take(i, xs), takeLast(List.length(xs) - i, xs)) + let remove = (i, n, xs) => { + let (a, b) = splitAt(i, xs) + \"@"(a, drop(n, b)) + } + + let find = List.find + let filter = List.filter + let for_all = List.for_all + let exists = List.exists + let sort = List.sort + let length = List.length + + let filter_opt = xs => { + let rec loop = (l, acc) => + switch l { + | list{} => acc + | list{hd, ...tl} => + switch hd { + | None => loop(tl, acc) + | Some(x) => loop(tl, list{x, ...acc}) + } + } + List.rev(loop(xs, list{})) + } + + let containsWith = f => List.exists(f) + + let uniqWithBy = (eq, f, xs) => + List.fold_left( + ((acc, tacc), v) => + containsWith(eq(f(v)), tacc) ? (acc, tacc) : (append(v, acc), append(f(v), tacc)), + (list{}, list{}), + xs, + ) |> fst + + let uniqBy = (f, xs) => uniqWithBy(Util.eq, f, xs) + let join = j => List.fold_left((acc, v) => String.length(acc) == 0 ? v : acc ++ (j ++ v), "") + + let head = xs => + switch List.hd(xs) { + | exception _ => None + | a => Some(a) + } + + let uniq = xs => uniqBy(x => x, xs) + let flatten = List.flatten + let last = xs => xs |> List.rev |> head + let append = List.append + let getBy = Belt.List.getBy + let dropLast = (i, xs) => take(List.length(xs) - i, xs) + let containsWith = f => List.exists(f) + let contains = x => containsWith(Util.eq(x)) + + let reject = pred => List.filter(x => !pred(x)) + let tail = xs => + switch List.tl(xs) { + | exception _ => None + | a => Some(a) + } + + let init = xs => { + O.fmap(List.rev, xs |> List.rev |> tail) + } + + let singleton = (x: 'a): list<'a> => list{x} + + let adjust = (f, i, xs) => { + let (a, b) = splitAt(i + 1, xs) + switch a { + | _ if i < 0 => xs + | _ if i >= List.length(xs) => xs + | list{} => b + | list{a} => list{f(a), ...b} + | a => + O.fmap( + concat'(b), + O.bind(init(a), x => + O.fmap(F.flip(append, x), O.fmap(fmap(f), O.fmap(singleton, last(a)))) + ), + ) |> O.default(xs) + } + } + + let without = (exclude, xs) => reject(x => contains(x, exclude), xs) + let update = (x, i, xs) => adjust(F.always(x), i, xs) + let iter = List.iter + + let findIndex = { + let rec loop = (pred, xs, i) => + switch xs { + | list{} => None + | list{a, ...b} => pred(a) ? Some(i) : loop(pred, b, i + 1) + } + (pred, xs) => loop(pred, xs, 0) + } + + let headSafe = Belt.List.head + let tailSafe = Belt.List.tail + let headExn = Belt.List.headExn + let tailExn = Belt.List.tailExn + let zip = Belt.List.zip + + let combinations2: list<'a> => list<('a, 'a)> = xs => { + let rec loop: ('a, list<'a>) => list<('a, 'a)> = (x', xs') => { + let n = length(xs') + if n == 0 { + list{} + } else { + let combs = fmap(y => (x', y), xs') + let hd = headExn(xs') + let tl = tailExn(xs') + concat(list{combs, loop(hd, tl)}) + } + } + switch (headSafe(xs), tailSafe(xs)) { + | (Some(x'), Some(xs')) => loop(x', xs') + | (_, _) => list{} + } + } +} + +/* A for Array */ +module A = { + let fmap = Array.map + let fmapi = Array.mapi + let to_list = Array.to_list + let of_list = Array.of_list + let length = Array.length + let append = Array.append + // let empty = [||]; + let unsafe_get = Array.unsafe_get + let get = Belt.Array.get + let getBy = Belt.Array.getBy + let getIndexBy = Belt.Array.getIndexBy + let last = a => get(a, length(a) - 1) + let first = get(_, 0) + let hasBy = (r, fn) => Belt.Array.getBy(r, fn) |> O.isSome + let fold_left = Array.fold_left + let fold_right = Array.fold_right + let concat = Belt.Array.concat + let concatMany = Belt.Array.concatMany + let keepMap = Belt.Array.keepMap + let slice = Belt.Array.slice + let init = Array.init + let reduce = Belt.Array.reduce + let reduceReverse = Belt.Array.reduceReverse + let reducei = Belt.Array.reduceWithIndex + let some = Belt.Array.some + let isEmpty = r => length(r) < 1 + let stableSortBy = Belt.SortArray.stableSortBy + let toNoneIfEmpty = r => isEmpty(r) ? None : Some(r) + let toRanges = (a: array<'a>) => + switch a |> Belt.Array.length { + | 0 + | 1 => + Belt.Result.Error("Must be at least 2 elements") + | n => + Belt.Array.makeBy(n - 1, r => r) + |> Belt.Array.map(_, index => ( + Belt.Array.getUnsafe(a, index), + Belt.Array.getUnsafe(a, index + 1), + )) + |> (x => Ok(x)) + } + + let getByFmap = (a, fn, boolCondition) => { + let i = ref(0) + let finalFunctionValue = ref(None) + let length = Belt.Array.length(a) + + while i.contents < length && finalFunctionValue.contents == None { + let itemWithFnApplied = Belt.Array.getUnsafe(a, i.contents) |> fn + if boolCondition(itemWithFnApplied) { + finalFunctionValue := Some(itemWithFnApplied) + } + i := i.contents + 1 + } + + finalFunctionValue.contents + } + + let tail = Belt.Array.sliceToEnd(_, 1) + + let zip = Belt.Array.zip + let unzip = Belt.Array.unzip + let zip3 = (a, b, c) => + Belt.Array.zip(a, b)->Belt.Array.zip(c)->Belt.Array.map((((v1, v2), v3)) => (v1, v2, v3)) + // This zips while taking the longest elements of each array. + let zipMaxLength = (array1, array2) => { + let maxLength = Int.max(length(array1), length(array2)) + let result = maxLength |> Belt.Array.makeUninitializedUnsafe + for i in 0 to maxLength - 1 { + Belt.Array.set(result, i, (get(array1, i), get(array2, i))) |> ignore + } + result + } + + let asList = (f: list<'a> => list<'a>, r: array<'a>) => r |> to_list |> f |> of_list + /* TODO: Is there a better way of doing this? */ + let uniq = r => asList(L.uniq, r) + + //intersperse([1,2,3], [10,11,12]) => [1,10,2,11,3,12] + let intersperse = (a: array<'a>, b: array<'a>) => { + let items: ref> = ref([]) + + Belt.Array.forEachWithIndex(a, (i, item) => + switch Belt.Array.get(b, i) { + | Some(r) => items := append(items.contents, [item, r]) + | None => items := append(items.contents, [item]) + } + ) + items.contents + } + + // This is like map, but + //accumulate((a,b) => a + b, [1,2,3]) => [1, 3, 5] + let accumulate = (fn: ('a, 'a) => 'a, items: array<'a>) => { + let length = items |> length + let empty = Belt.Array.make(length, items |> unsafe_get(_, 0)) + Belt.Array.forEachWithIndex(items, (index, element) => { + let item = switch index { + | 0 => element + | index => fn(element, unsafe_get(empty, index - 1)) + } + let _ = Belt.Array.set(empty, index, item) + }) + empty + } + + // @todo: Is -1 still the indicator that this is false (as is true with + // @todo: js findIndex)? Wasn't sure. + let findIndex = (e, i) => + Js.Array.findIndex(e, i) |> ( + r => + switch r { + | -1 => None + | r => Some(r) + } + ) + let filter = Js.Array.filter + let joinWith = Js.Array.joinWith + let transpose = (xs: array>): array> => { + let arr: array> = [] + for i in 0 to length(xs) - 1 { + for j in 0 to length(xs[i]) - 1 { + if Js.Array.length(arr) <= j { + ignore(Js.Array.push([xs[i][j]], arr)) + } else { + ignore(Js.Array.push(xs[i][j], arr[j])) + } + } + } + arr + } + + let all = (p: 'a => bool, xs: array<'a>): bool => length(filter(p, xs)) == length(xs) + let any = (p: 'a => bool, xs: array<'a>): bool => length(filter(p, xs)) > 0 + + module O = { + let concatSomes = (optionals: array>): array<'a> => + optionals + |> Js.Array.filter(O.isSome) + |> Js.Array.map(O.toExn("Warning: This should not have happened")) + let defaultEmpty = (o: option>): array<'a> => + switch o { + | Some(o) => o + | None => [] + } + // REturns `None` there are no non-`None` elements + let rec arrSomeToSomeArr = (optionals: array>): option> => { + let optionals' = optionals->Belt.List.fromArray + switch optionals' { + | list{} => []->Some + | list{x, ...xs} => + switch x { + | Some(_) => xs->Belt.List.toArray->arrSomeToSomeArr + | None => None + } + } + } + let firstSome = x => Belt.Array.getBy(x, O.isSome) + + let firstSomeFn = (r: array option<'a>>): option<'a> => + O.flatten(getByFmap(r, l => l(), O.isSome)) + + let firstSomeFnWithDefault = (r, default) => firstSomeFn(r)->O2.default(default) + + let openIfAllSome = (optionals: array>): option> => { + if all(O.isSome, optionals) { + Some(optionals |> fmap(O.toExn("Warning: This should not have happened"))) + } else { + None + } + } + } + + module R = { + let firstErrorOrOpen = (results: array>): Belt.Result.t< + array<'a>, + 'b, + > => { + let bringErrorUp = switch results |> Belt.Array.getBy(_, Belt.Result.isError) { + | Some(Belt.Result.Error(err)) => Belt.Result.Error(err) + | Some(Belt.Result.Ok(_)) => Belt.Result.Ok(results) + | None => Belt.Result.Ok(results) + } + let forceOpen = (r: array>): array<'a> => + r |> Belt.Array.map(_, r => Belt.Result.getExn(r)) + bringErrorUp |> Belt.Result.map(_, forceOpen) + } + let filterOk = (x: array>): array<'a> => fmap(R.toOption, x)->O.concatSomes + + let forM = (x: array<'a>, fn: 'a => result<'b, 'c>): result, 'c> => + firstErrorOrOpen(fmap(fn, x)) + + let foldM = (fn: ('c, 'a) => result<'b, 'e>, init: 'c, x: array<'a>): result<'c, 'e> => { + let acc = ref(init) + let final = ref(Ok()) + let break = ref(false) + let i = ref(0) + + while break.contents != true && i.contents < length(x) { + switch fn(acc.contents, x[i.contents]) { + | Ok(r) => acc := r + | Error(err) => { + final := Error(err) + break := true + } + } + i := i.contents + 1 + } + switch final.contents { + | Ok(_) => Ok(acc.contents) + | Error(err) => Error(err) + } + } + } + + module Floats = { + type t = array + let mean = Jstat.mean + let geomean = Jstat.geomean + let mode = Jstat.mode + let variance = Jstat.variance + let stdev = Jstat.stdev + let sum = Jstat.sum + let product = Jstat.product + let random = Js.Math.random_int + + let floatCompare: (float, float) => int = compare + let sort = t => { + let r = t + r |> Array.fast_sort(floatCompare) + r + } + + let getNonFinite = (t: t) => Belt.Array.getBy(t, r => !Js.Float.isFinite(r)) + let getBelowZero = (t: t) => Belt.Array.getBy(t, r => r < 0.0) + + let isSorted = (t: t): bool => + if Array.length(t) < 1 { + true + } else { + reduce(zip(t, tail(t)), true, (acc, (first, second)) => acc && first < second) + } + + //Passing true for the exclusive parameter excludes both endpoints of the range. + //https://jstat.github.io/all.html + let percentile = (a, b) => Jstat.percentile(a, b, false) + + // Gives an array with all the differences between values + // diff([1,5,3,7]) = [4,-2,4] + let diff = (t: t): array => + Belt.Array.zipBy(t, Belt.Array.sliceToEnd(t, 1), (left, right) => right -. left) + + let cumSum = (t: t): array => accumulate((a, b) => a +. b, t) + let cumProd = (t: t): array => accumulate((a, b) => a *. b, t) + + exception RangeError(string) + let range = (min: float, max: float, n: int): array => + switch n { + | 0 => [] + | 1 => [min] + | 2 => [min, max] + | _ if min == max => Belt.Array.make(n, min) + | _ if n < 0 => raise(RangeError("n must be greater than 0")) + | _ if min > max => raise(RangeError("Min value is less then max value")) + | _ => + let diff = (max -. min) /. Belt.Float.fromInt(n - 1) + Belt.Array.makeBy(n, i => min +. Belt.Float.fromInt(i) *. diff) + } + + let min = Js.Math.minMany_float + let max = Js.Math.maxMany_float + + module Sorted = { + let min = first + let max = last + let range = (~min=min, ~max=max, a) => + switch (min(a), max(a)) { + | (Some(min), Some(max)) => Some(max -. min) + | _ => None + } + + let binarySearchFirstElementGreaterIndex = (ar: array<'a>, el: 'a) => { + let el = Belt.SortArray.binarySearchBy(ar, el, floatCompare) + let el = el < 0 ? el * -1 - 1 : el + switch el { + | e if e >= length(ar) => #overMax + | e if e == 0 => #underMin + | e => #firstHigher(e) + } + } + + let concat = (t1: array<'a>, t2: array<'a>) => Belt.Array.concat(t1, t2)->sort + + let concatMany = (t1: array>) => Belt.Array.concatMany(t1)->sort + + let makeIncrementalUp = (a, b) => + Array.make(b - a + 1, a) |> Array.mapi((i, c) => c + i) |> Belt.Array.map(_, float_of_int) + + let makeIncrementalDown = (a, b) => + Array.make(a - b + 1, a) |> Array.mapi((i, c) => c - i) |> Belt.Array.map(_, float_of_int) + + /* + This function goes through a sorted array and divides it into two different clusters: + continuous samples and discrete samples. The discrete samples are stored in a mutable map. + Samples are thought to be discrete if they have any duplicates. + */ + let _splitContinuousAndDiscreteForDuplicates = (sortedArray: array) => { + let continuous: array = [] + let discrete = FloatFloatMap.empty() + Belt.Array.forEachWithIndex(sortedArray, (index, element) => { + let maxIndex = (sortedArray |> Array.length) - 1 + let possiblySimilarElements = switch index { + | 0 => [index + 1] + | n if n == maxIndex => [index - 1] + | _ => [index - 1, index + 1] + } |> Belt.Array.map(_, r => sortedArray[r]) + let hasSimilarElement = Belt.Array.some(possiblySimilarElements, r => r == element) + hasSimilarElement + ? FloatFloatMap.increment(element, discrete) + : { + let _ = Js.Array.push(element, continuous) + } + + () + }) + + (continuous, discrete) + } + + /* + This function works very similarly to splitContinuousAndDiscreteForDuplicates. The one major difference + is that you can specify a minDiscreteWeight. If the min discreet weight is 4, that would mean that + at least four elements needed from a specific value for that to be kept as discrete. This is important + because in some cases, we can expect that some common elements will be generated by regular operations. + The final continous array will be sorted. + */ + let splitContinuousAndDiscreteForMinWeight = ( + sortedArray: array, + ~minDiscreteWeight: int, + ) => { + let (continuous, discrete) = _splitContinuousAndDiscreteForDuplicates(sortedArray) + let keepFn = v => Belt.Float.toInt(v) >= minDiscreteWeight + let (discreteToKeep, discreteToIntegrate) = FloatFloatMap.partition( + ((_, v)) => keepFn(v), + discrete, + ) + let newContinousSamples = + discreteToIntegrate->FloatFloatMap.toArray + |> fmap(((k, v)) => Belt.Array.makeBy(Belt.Float.toInt(v), _ => k)) + |> Belt.Array.concatMany + let newContinuous = concat(continuous, newContinousSamples) + newContinuous |> Array.fast_sort(floatCompare) + (newContinuous, discreteToKeep) + } + } + } + module Sorted = Floats.Sorted +} + +module A2 = { + let fmap = (a, b) => A.fmap(b, a) + let fmapi = (a, b) => A.fmapi(b, a) + let joinWith = (a, b) => A.joinWith(b, a) + let filter = (a, b) => A.filter(b, a) +} + +module JsArray = { + let concatSomes = (optionals: Js.Array.t>): Js.Array.t<'a> => + optionals + |> Js.Array.filter(O.isSome) + |> Js.Array.map(O.toExn("Warning: This should not have happened")) + let filter = Js.Array.filter +} + +module Dict = { + type t<'a> = Js.Dict.t<'a> + let get = Js.Dict.get + let keys = Js.Dict.keys + let fromArray = Js.Dict.fromArray + let toArray = Js.Dict.entries + let concat = (a, b) => A.concat(toArray(a), toArray(b))->fromArray + let concatMany = ts => ts->A2.fmap(toArray)->A.concatMany->fromArray +} diff --git a/packages/squiggle-lang/src/rescript/Utility/E.res b/packages/squiggle-lang/src/rescript/Utility/E.res index 60da5737..fb0b553f 100644 --- a/packages/squiggle-lang/src/rescript/Utility/E.res +++ b/packages/squiggle-lang/src/rescript/Utility/E.res @@ -5,912 +5,23 @@ running `rescript convert -all` on Rationale https://github.com/jonlaing/rationa let equals = (a, b) => a === b -module FloatFloatMap = { - module Id = Belt.Id.MakeComparable({ - type t = float - let cmp: (float, float) => int = Pervasives.compare - }) - - type t = Belt.MutableMap.t - - let fromArray = (ar: array<(float, float)>) => Belt.MutableMap.fromArray(ar, ~id=module(Id)) - let toArray = (t: t): array<(float, float)> => Belt.MutableMap.toArray(t) - let empty = () => Belt.MutableMap.make(~id=module(Id)) - let increment = (el, t: t) => - Belt.MutableMap.update(t, el, x => - switch x { - | Some(n) => Some(n +. 1.0) - | None => Some(1.0) - } - ) - - let get = (el, t: t) => Belt.MutableMap.get(t, el) - let fmap = (fn, t: t) => Belt.MutableMap.map(t, fn) - let partition = (fn, t: t) => { - let (match, noMatch) = Belt.Array.partition(toArray(t), fn) - (fromArray(match), fromArray(noMatch)) - } -} - -module Int = { - let max = (i1: int, i2: int) => i1 > i2 ? i1 : i2 - let random = (~min, ~max) => Js.Math.random_int(min, max) -} -/* Utils */ -module U = { - let isEqual = \"==" - let toA = a => [a] - let id = e => e -} - -module Tuple2 = { - let first = (v: ('a, 'b)) => { - let (a, _) = v - a - } - let second = (v: ('a, 'b)) => { - let (_, b) = v - b - } - let toFnCall = (fn, (a1, a2)) => fn(a1, a2) -} - -module Tuple3 = { - let toFnCall = (fn, (a1, a2, a3)) => fn(a1, a2, a3) -} - -module O = { - let dimap = (sFn, rFn, e) => - switch e { - | Some(r) => sFn(r) - | None => rFn() - } - () - let fmap = (f: 'a => 'b, x: option<'a>): option<'b> => { - switch x { - | None => None - | Some(x') => Some(f(x')) - } - } - let bind = (o, f) => - switch o { - | None => None - | Some(a) => f(a) - } - let default = (d, o) => - switch o { - | None => d - | Some(a) => a - } - let defaultFn = (d, o) => - switch o { - | None => d() - | Some(a) => a - } - let isSome = o => - switch o { - | Some(_) => true - | _ => false - } - let isNone = o => - switch o { - | None => true - | _ => false - } - let toExn = (err, o) => - switch o { - | None => raise(Failure(err)) - | Some(a) => a - } - - let some = a => Some(a) - let firstSome = (a, b) => - switch a { - | None => b - | _ => a - } - - let toExt = toExn - - let flatten = o => - switch o { - | None => None - | Some(x) => x - } - - let apply = (o, a) => - switch o { - | Some(f) => bind(a, b => some(f(b))) - | _ => None - } - let flatApply = (fn, b) => apply(fn, Some(b)) |> flatten - - let toBool = opt => - switch opt { - | Some(_) => true - | _ => false - } - - let ffmap = (fn, r) => - switch r { - | Some(sm) => fn(sm) - | _ => None - } - - let toString = opt => - switch opt { - | Some(s) => s - | _ => "" - } - - let toResult = (error, e) => - switch e { - | Some(r) => Belt.Result.Ok(r) - | None => Error(error) - } - - let compare = (compare, f1: option, f2: option) => - switch (f1, f2) { - | (Some(f1), Some(f2)) => Some(compare(f1, f2) ? f1 : f2) - | (Some(f1), None) => Some(f1) - | (None, Some(f2)) => Some(f2) - | (None, None) => None - } - - let min = compare(\"<") - let max = compare(\">") -} - -module O2 = { - let default = (a, b) => O.default(b, a) - let defaultFn = (a, b) => O.defaultFn(b, a) - let toExn = (a, b) => O.toExn(b, a) - let fmap = (a, b) => O.fmap(b, a) - let toResult = (a, b) => O.toResult(b, a) - let bind = (a, b) => O.bind(b, a) -} - -/* Functions */ -module F = { - let pipe = (f, g, x) => g(f(x)) - let compose = (f, g, x) => f(g(x)) - let flip = (f, a, b) => f(b, a) - let always = (x, _y) => x - - let apply = (a, e) => a |> e - - let flatten2Callbacks = (fn1, fn2, fnlast) => - fn1(response1 => fn2(response2 => fnlast(response1, response2))) - - let flatten3Callbacks = (fn1, fn2, fn3, fnlast) => - fn1(response1 => fn2(response2 => fn3(response3 => fnlast(response1, response2, response3)))) - - let flatten4Callbacks = (fn1, fn2, fn3, fn4, fnlast) => - fn1(response1 => - fn2(response2 => - fn3(response3 => fn4(response4 => fnlast(response1, response2, response3, response4))) - ) - ) -} - -module Bool = { - type t = bool - let toString = (t: t) => t ? "TRUE" : "FALSE" - let fromString = str => str == "TRUE" ? true : false - - module O = { - let toBool = opt => - switch opt { - | Some(true) => true - | _ => false - } - } -} - -module Float = { - let with2DigitsPrecision = Js.Float.toPrecisionWithPrecision(_, ~digits=2) - let with3DigitsPrecision = Js.Float.toPrecisionWithPrecision(_, ~digits=3) - let toFixed = Js.Float.toFixed - let toString = Js.Float.toString - let isFinite = Js.Float.isFinite - let toInt = Belt.Float.toInt -} - -module I = { - let increment = n => n + 1 - let decrement = n => n - 1 - let toString = Js.Int.toString - let toFloat = Js.Int.toFloat -} - -exception Assertion(string) - -/* R for Result */ -module R = { - open Belt.Result - let result = (okF, errF, r) => - switch r { - | Ok(a) => okF(a) - | Error(err) => errF(err) - } - let id = e => e |> result(U.id, U.id) - let isOk = Belt.Result.isOk - let getError = (r: result<'a, 'b>) => - switch r { - | Ok(_) => None - | Error(e) => Some(e) - } - let fmap = (f: 'a => 'b, r: result<'a, 'c>): result<'b, 'c> => { - switch r { - | Ok(r') => Ok(f(r')) - | Error(err) => Error(err) - } - } - let bind = (r, f) => - switch r { - | Ok(a) => f(a) - | Error(err) => Error(err) - } - let toExn = (msg: string, x: result<'a, 'b>): 'a => - switch x { - | Ok(r) => r - | Error(_) => raise(Assertion(msg)) - } - let toExnFnString = (errorToStringFn, o) => - switch o { - | Ok(r) => r - | Error(r) => raise(Assertion(errorToStringFn(r))) - } - let default = (default, res: Belt.Result.t<'a, 'b>) => - switch res { - | Ok(r) => r - | Error(_) => default - } - let merge = (a, b) => - switch (a, b) { - | (Error(e), _) => Error(e) - | (_, Error(e)) => Error(e) - | (Ok(a), Ok(b)) => Ok((a, b)) - } - let toOption = (e: Belt.Result.t<'a, 'b>) => - switch e { - | Ok(r) => Some(r) - | Error(_) => None - } - - let errorIfCondition = (errorCondition, errorMessage, r) => - errorCondition(r) ? Error(errorMessage) : Ok(r) - - let ap = (r, a) => - switch r { - | Ok(f) => Ok(f(a)) - | Error(err) => Error(err) - } - let ap' = (r, a) => - switch r { - | Ok(f) => fmap(f, a) - | Error(err) => Error(err) - } - - let liftM2: (('a, 'b) => 'c, result<'a, 'd>, result<'b, 'd>) => result<'c, 'd> = (op, xR, yR) => { - ap'(fmap(op, xR), yR) - } - - let liftJoin2: (('a, 'b) => result<'c, 'd>, result<'a, 'd>, result<'b, 'd>) => result<'c, 'd> = ( - op, - xR, - yR, - ) => { - bind(liftM2(op, xR, yR), x => x) - } - - let fmap2 = (f, r) => - switch r { - | Ok(r) => r->Ok - | Error(x) => x->f->Error - } - - //I'm not sure what to call this. - let unify = (a: result<'a, 'b>, c: 'b => 'a): 'a => - switch a { - | Ok(x) => x - | Error(x) => c(x) - } -} - -module R2 = { - let fmap = (a, b) => R.fmap(b, a) - let bind = (a, b) => R.bind(b, a) - - //Converts result type to change error type only - let errMap = (a: result<'a, 'b>, map: 'b => 'c): result<'a, 'c> => - switch a { - | Ok(r) => Ok(r) - | Error(e) => Error(map(e)) - } - - let fmap2 = (xR, f) => - switch xR { - | Ok(x) => x->Ok - | Error(x) => x->f->Error - } - - let toExn = (a, b) => R.toExn(b, a) -} - -let safe_fn_of_string = (fn, s: string): option<'a> => - try Some(fn(s)) catch { - | _ => None - } - -module S = { - let safe_float = float_of_string->safe_fn_of_string - let safe_int = int_of_string->safe_fn_of_string - let default = (defaultStr, str) => str == "" ? defaultStr : str -} - -module J = { - let toString = F.pipe(Js.Json.decodeString, O.default("")) - let fromString = Js.Json.string - let fromNumber = Js.Json.number - - module O = { - let fromString = (str: string) => - switch str { - | "" => None - | _ => Some(Js.Json.string(str)) - } - - let toString = (str: option<'a>) => - switch str { - | Some(str) => Some(str |> F.pipe(Js.Json.decodeString, O.default(""))) - | _ => None - } - } -} - -module JsDate = { - let fromString = Js.Date.fromString - let now = Js.Date.now - let make = Js.Date.make - let valueOf = Js.Date.valueOf -} - -/* List */ -module L = { - module Util = { - let eq = \"==" - } - let fmap = List.map - let get = Belt.List.get - let toArray = Array.of_list - let fmapi = List.mapi - let concat = List.concat - let concat' = (xs, ys) => List.append(ys, xs) - - let rec drop = (i, xs) => - switch (i, xs) { - | (_, list{}) => list{} - | (i, _) if i <= 0 => xs - | (i, list{_, ...b}) => drop(i - 1, b) - } - - let append = (a, xs) => List.append(xs, list{a}) - let take = { - let rec loop = (i, xs, acc) => - switch (i, xs) { - | (i, _) if i <= 0 => acc - | (_, list{}) => acc - | (i, list{a, ...b}) => loop(i - 1, b, append(a, acc)) - } - (i, xs) => loop(i, xs, list{}) - } - let takeLast = (i, xs) => List.rev(xs) |> take(i) |> List.rev - - let splitAt = (i, xs) => (take(i, xs), takeLast(List.length(xs) - i, xs)) - let remove = (i, n, xs) => { - let (a, b) = splitAt(i, xs) - \"@"(a, drop(n, b)) - } - - let find = List.find - let filter = List.filter - let for_all = List.for_all - let exists = List.exists - let sort = List.sort - let length = List.length - - let filter_opt = xs => { - let rec loop = (l, acc) => - switch l { - | list{} => acc - | list{hd, ...tl} => - switch hd { - | None => loop(tl, acc) - | Some(x) => loop(tl, list{x, ...acc}) - } - } - List.rev(loop(xs, list{})) - } - - let containsWith = f => List.exists(f) - - let uniqWithBy = (eq, f, xs) => - List.fold_left( - ((acc, tacc), v) => - containsWith(eq(f(v)), tacc) ? (acc, tacc) : (append(v, acc), append(f(v), tacc)), - (list{}, list{}), - xs, - ) |> fst - - let uniqBy = (f, xs) => uniqWithBy(Util.eq, f, xs) - let join = j => List.fold_left((acc, v) => String.length(acc) == 0 ? v : acc ++ (j ++ v), "") - - let head = xs => - switch List.hd(xs) { - | exception _ => None - | a => Some(a) - } - - let uniq = xs => uniqBy(x => x, xs) - let flatten = List.flatten - let last = xs => xs |> List.rev |> head - let append = List.append - let getBy = Belt.List.getBy - let dropLast = (i, xs) => take(List.length(xs) - i, xs) - let containsWith = f => List.exists(f) - let contains = x => containsWith(Util.eq(x)) - - let reject = pred => List.filter(x => !pred(x)) - let tail = xs => - switch List.tl(xs) { - | exception _ => None - | a => Some(a) - } - - let init = xs => { - O.fmap(List.rev, xs |> List.rev |> tail) - } - - let singleton = (x: 'a): list<'a> => list{x} - - let adjust = (f, i, xs) => { - let (a, b) = splitAt(i + 1, xs) - switch a { - | _ if i < 0 => xs - | _ if i >= List.length(xs) => xs - | list{} => b - | list{a} => list{f(a), ...b} - | a => - O.fmap( - concat'(b), - O.bind(init(a), x => - O.fmap(F.flip(append, x), O.fmap(fmap(f), O.fmap(singleton, last(a)))) - ), - ) |> O.default(xs) - } - } - - let without = (exclude, xs) => reject(x => contains(x, exclude), xs) - let update = (x, i, xs) => adjust(F.always(x), i, xs) - let iter = List.iter - - let findIndex = { - let rec loop = (pred, xs, i) => - switch xs { - | list{} => None - | list{a, ...b} => pred(a) ? Some(i) : loop(pred, b, i + 1) - } - (pred, xs) => loop(pred, xs, 0) - } - - let headSafe = Belt.List.head - let tailSafe = Belt.List.tail - let headExn = Belt.List.headExn - let tailExn = Belt.List.tailExn - let zip = Belt.List.zip - - let combinations2: list<'a> => list<('a, 'a)> = xs => { - let rec loop: ('a, list<'a>) => list<('a, 'a)> = (x', xs') => { - let n = length(xs') - if n == 0 { - list{} - } else { - let combs = fmap(y => (x', y), xs') - let hd = headExn(xs') - let tl = tailExn(xs') - concat(list{combs, loop(hd, tl)}) - } - } - switch (headSafe(xs), tailSafe(xs)) { - | (Some(x'), Some(xs')) => loop(x', xs') - | (_, _) => list{} - } - } -} - -/* A for Array */ -module A = { - let fmap = Array.map - let fmapi = Array.mapi - let to_list = Array.to_list - let of_list = Array.of_list - let length = Array.length - let append = Array.append - // let empty = [||]; - let unsafe_get = Array.unsafe_get - let get = Belt.Array.get - let getBy = Belt.Array.getBy - let getIndexBy = Belt.Array.getIndexBy - let last = a => get(a, length(a) - 1) - let first = get(_, 0) - let hasBy = (r, fn) => Belt.Array.getBy(r, fn) |> O.isSome - let fold_left = Array.fold_left - let fold_right = Array.fold_right - let concat = Belt.Array.concat - let concatMany = Belt.Array.concatMany - let keepMap = Belt.Array.keepMap - let slice = Belt.Array.slice - let init = Array.init - let reduce = Belt.Array.reduce - let reduceReverse = Belt.Array.reduceReverse - let reducei = Belt.Array.reduceWithIndex - let some = Belt.Array.some - let isEmpty = r => length(r) < 1 - let stableSortBy = Belt.SortArray.stableSortBy - let toNoneIfEmpty = r => isEmpty(r) ? None : Some(r) - let toRanges = (a: array<'a>) => - switch a |> Belt.Array.length { - | 0 - | 1 => - Belt.Result.Error("Must be at least 2 elements") - | n => - Belt.Array.makeBy(n - 1, r => r) - |> Belt.Array.map(_, index => ( - Belt.Array.getUnsafe(a, index), - Belt.Array.getUnsafe(a, index + 1), - )) - |> (x => Ok(x)) - } - - let getByFmap = (a, fn, boolCondition) => { - let i = ref(0) - let finalFunctionValue = ref(None) - let length = Belt.Array.length(a) - - while i.contents < length && finalFunctionValue.contents == None { - let itemWithFnApplied = Belt.Array.getUnsafe(a, i.contents) |> fn - if boolCondition(itemWithFnApplied) { - finalFunctionValue := Some(itemWithFnApplied) - } - i := i.contents + 1 - } - - finalFunctionValue.contents - } - - let tail = Belt.Array.sliceToEnd(_, 1) - - let zip = Belt.Array.zip - let unzip = Belt.Array.unzip - let zip3 = (a, b, c) => - Belt.Array.zip(a, b)->Belt.Array.zip(c)->Belt.Array.map((((v1, v2), v3)) => (v1, v2, v3)) - // This zips while taking the longest elements of each array. - let zipMaxLength = (array1, array2) => { - let maxLength = Int.max(length(array1), length(array2)) - let result = maxLength |> Belt.Array.makeUninitializedUnsafe - for i in 0 to maxLength - 1 { - Belt.Array.set(result, i, (get(array1, i), get(array2, i))) |> ignore - } - result - } - - let asList = (f: list<'a> => list<'a>, r: array<'a>) => r |> to_list |> f |> of_list - /* TODO: Is there a better way of doing this? */ - let uniq = r => asList(L.uniq, r) - - //intersperse([1,2,3], [10,11,12]) => [1,10,2,11,3,12] - let intersperse = (a: array<'a>, b: array<'a>) => { - let items: ref> = ref([]) - - Belt.Array.forEachWithIndex(a, (i, item) => - switch Belt.Array.get(b, i) { - | Some(r) => items := append(items.contents, [item, r]) - | None => items := append(items.contents, [item]) - } - ) - items.contents - } - - // This is like map, but - //accumulate((a,b) => a + b, [1,2,3]) => [1, 3, 5] - let accumulate = (fn: ('a, 'a) => 'a, items: array<'a>) => { - let length = items |> length - let empty = Belt.Array.make(length, items |> unsafe_get(_, 0)) - Belt.Array.forEachWithIndex(items, (index, element) => { - let item = switch index { - | 0 => element - | index => fn(element, unsafe_get(empty, index - 1)) - } - let _ = Belt.Array.set(empty, index, item) - }) - empty - } - - // @todo: Is -1 still the indicator that this is false (as is true with - // @todo: js findIndex)? Wasn't sure. - let findIndex = (e, i) => - Js.Array.findIndex(e, i) |> ( - r => - switch r { - | -1 => None - | r => Some(r) - } - ) - let filter = Js.Array.filter - let joinWith = Js.Array.joinWith - let transpose = (xs: array>): array> => { - let arr: array> = [] - for i in 0 to length(xs) - 1 { - for j in 0 to length(xs[i]) - 1 { - if Js.Array.length(arr) <= j { - ignore(Js.Array.push([xs[i][j]], arr)) - } else { - ignore(Js.Array.push(xs[i][j], arr[j])) - } - } - } - arr - } - - let all = (p: 'a => bool, xs: array<'a>): bool => length(filter(p, xs)) == length(xs) - let any = (p: 'a => bool, xs: array<'a>): bool => length(filter(p, xs)) > 0 - - module O = { - let concatSomes = (optionals: array>): array<'a> => - optionals - |> Js.Array.filter(O.isSome) - |> Js.Array.map(O.toExn("Warning: This should not have happened")) - let defaultEmpty = (o: option>): array<'a> => - switch o { - | Some(o) => o - | None => [] - } - // REturns `None` there are no non-`None` elements - let rec arrSomeToSomeArr = (optionals: array>): option> => { - let optionals' = optionals->Belt.List.fromArray - switch optionals' { - | list{} => []->Some - | list{x, ...xs} => - switch x { - | Some(_) => xs->Belt.List.toArray->arrSomeToSomeArr - | None => None - } - } - } - let firstSome = x => Belt.Array.getBy(x, O.isSome) - - let firstSomeFn = (r: array option<'a>>): option<'a> => - O.flatten(getByFmap(r, l => l(), O.isSome)) - - let firstSomeFnWithDefault = (r, default) => firstSomeFn(r)->O2.default(default) - - let openIfAllSome = (optionals: array>): option> => { - if all(O.isSome, optionals) { - Some(optionals |> fmap(O.toExn("Warning: This should not have happened"))) - } else { - None - } - } - } - - module R = { - let firstErrorOrOpen = (results: array>): Belt.Result.t< - array<'a>, - 'b, - > => { - let bringErrorUp = switch results |> Belt.Array.getBy(_, Belt.Result.isError) { - | Some(Belt.Result.Error(err)) => Belt.Result.Error(err) - | Some(Belt.Result.Ok(_)) => Belt.Result.Ok(results) - | None => Belt.Result.Ok(results) - } - let forceOpen = (r: array>): array<'a> => - r |> Belt.Array.map(_, r => Belt.Result.getExn(r)) - bringErrorUp |> Belt.Result.map(_, forceOpen) - } - let filterOk = (x: array>): array<'a> => fmap(R.toOption, x)->O.concatSomes - - let forM = (x: array<'a>, fn: 'a => result<'b, 'c>): result, 'c> => - firstErrorOrOpen(fmap(fn, x)) - - let foldM = (fn: ('c, 'a) => result<'b, 'e>, init: 'c, x: array<'a>): result<'c, 'e> => { - let acc = ref(init) - let final = ref(Ok()) - let break = ref(false) - let i = ref(0) - - while break.contents != true && i.contents < length(x) { - switch fn(acc.contents, x[i.contents]) { - | Ok(r) => acc := r - | Error(err) => { - final := Error(err) - break := true - } - } - i := i.contents + 1 - } - switch final.contents { - | Ok(_) => Ok(acc.contents) - | Error(err) => Error(err) - } - } - } - - module Floats = { - type t = array - let mean = Jstat.mean - let geomean = Jstat.geomean - let mode = Jstat.mode - let variance = Jstat.variance - let stdev = Jstat.stdev - let sum = Jstat.sum - let product = Jstat.product - let random = Js.Math.random_int - - let floatCompare: (float, float) => int = compare - let sort = t => { - let r = t - r |> Array.fast_sort(floatCompare) - r - } - - let getNonFinite = (t: t) => Belt.Array.getBy(t, r => !Js.Float.isFinite(r)) - let getBelowZero = (t: t) => Belt.Array.getBy(t, r => r < 0.0) - - let isSorted = (t: t): bool => - if Array.length(t) < 1 { - true - } else { - reduce(zip(t, tail(t)), true, (acc, (first, second)) => acc && first < second) - } - - //Passing true for the exclusive parameter excludes both endpoints of the range. - //https://jstat.github.io/all.html - let percentile = (a, b) => Jstat.percentile(a, b, false) - - // Gives an array with all the differences between values - // diff([1,5,3,7]) = [4,-2,4] - let diff = (t: t): array => - Belt.Array.zipBy(t, Belt.Array.sliceToEnd(t, 1), (left, right) => right -. left) - - let cumSum = (t: t): array => accumulate((a, b) => a +. b, t) - let cumProd = (t: t): array => accumulate((a, b) => a *. b, t) - - exception RangeError(string) - let range = (min: float, max: float, n: int): array => - switch n { - | 0 => [] - | 1 => [min] - | 2 => [min, max] - | _ if min == max => Belt.Array.make(n, min) - | _ if n < 0 => raise(RangeError("n must be greater than 0")) - | _ if min > max => raise(RangeError("Min value is less then max value")) - | _ => - let diff = (max -. min) /. Belt.Float.fromInt(n - 1) - Belt.Array.makeBy(n, i => min +. Belt.Float.fromInt(i) *. diff) - } - - let min = Js.Math.minMany_float - let max = Js.Math.maxMany_float - - module Sorted = { - let min = first - let max = last - let range = (~min=min, ~max=max, a) => - switch (min(a), max(a)) { - | (Some(min), Some(max)) => Some(max -. min) - | _ => None - } - - let binarySearchFirstElementGreaterIndex = (ar: array<'a>, el: 'a) => { - let el = Belt.SortArray.binarySearchBy(ar, el, floatCompare) - let el = el < 0 ? el * -1 - 1 : el - switch el { - | e if e >= length(ar) => #overMax - | e if e == 0 => #underMin - | e => #firstHigher(e) - } - } - - let concat = (t1: array<'a>, t2: array<'a>) => Belt.Array.concat(t1, t2)->sort - - let concatMany = (t1: array>) => Belt.Array.concatMany(t1)->sort - - let makeIncrementalUp = (a, b) => - Array.make(b - a + 1, a) |> Array.mapi((i, c) => c + i) |> Belt.Array.map(_, float_of_int) - - let makeIncrementalDown = (a, b) => - Array.make(a - b + 1, a) |> Array.mapi((i, c) => c - i) |> Belt.Array.map(_, float_of_int) - - /* - This function goes through a sorted array and divides it into two different clusters: - continuous samples and discrete samples. The discrete samples are stored in a mutable map. - Samples are thought to be discrete if they have any duplicates. - */ - let _splitContinuousAndDiscreteForDuplicates = (sortedArray: array) => { - let continuous: array = [] - let discrete = FloatFloatMap.empty() - Belt.Array.forEachWithIndex(sortedArray, (index, element) => { - let maxIndex = (sortedArray |> Array.length) - 1 - let possiblySimilarElements = switch index { - | 0 => [index + 1] - | n if n == maxIndex => [index - 1] - | _ => [index - 1, index + 1] - } |> Belt.Array.map(_, r => sortedArray[r]) - let hasSimilarElement = Belt.Array.some(possiblySimilarElements, r => r == element) - hasSimilarElement - ? FloatFloatMap.increment(element, discrete) - : { - let _ = Js.Array.push(element, continuous) - } - - () - }) - - (continuous, discrete) - } - - /* - This function works very similarly to splitContinuousAndDiscreteForDuplicates. The one major difference - is that you can specify a minDiscreteWeight. If the min discreet weight is 4, that would mean that - at least four elements needed from a specific value for that to be kept as discrete. This is important - because in some cases, we can expect that some common elements will be generated by regular operations. - The final continous array will be sorted. - */ - let splitContinuousAndDiscreteForMinWeight = ( - sortedArray: array, - ~minDiscreteWeight: int, - ) => { - let (continuous, discrete) = _splitContinuousAndDiscreteForDuplicates(sortedArray) - let keepFn = v => Belt.Float.toInt(v) >= minDiscreteWeight - let (discreteToKeep, discreteToIntegrate) = FloatFloatMap.partition( - ((_, v)) => keepFn(v), - discrete, - ) - let newContinousSamples = - discreteToIntegrate->FloatFloatMap.toArray - |> fmap(((k, v)) => Belt.Array.makeBy(Belt.Float.toInt(v), _ => k)) - |> Belt.Array.concatMany - let newContinuous = concat(continuous, newContinousSamples) - newContinuous |> Array.fast_sort(floatCompare) - (newContinuous, discreteToKeep) - } - } - } - module Sorted = Floats.Sorted -} - -module A2 = { - let fmap = (a, b) => A.fmap(b, a) - let fmapi = (a, b) => A.fmapi(b, a) - let joinWith = (a, b) => A.joinWith(b, a) - let filter = (a, b) => A.filter(b, a) -} - -module JsArray = { - let concatSomes = (optionals: Js.Array.t>): Js.Array.t<'a> => - optionals - |> Js.Array.filter(O.isSome) - |> Js.Array.map(O.toExn("Warning: This should not have happened")) - let filter = Js.Array.filter -} - -module Dict = { - type t<'a> = Js.Dict.t<'a> - let get = Js.Dict.get - let keys = Js.Dict.keys - let fromArray = Js.Dict.fromArray - let toArray = Js.Dict.entries - let concat = (a, b) => A.concat(toArray(a), toArray(b))->fromArray - let concatMany = ts => ts->A2.fmap(toArray)->A.concatMany->fromArray -} +module A = E_A +module A2 = E_A2 +module B = E_B +module Dict = E_Dict +module F = E_F +module Float = E_Float +module FloatFloatMap = E_FloatFloatMap +module I = E_I +module Int = E_Int +module J = E_J +module JsDate = E_JsDate +module L = E_L +module O = E_O +module O2 = E_O2 +module R = E_R +module R2 = E_R2 +module S = E_S +module Tuple2 = E_Tuple2 +module Tuple3 = E_Tuple3 +module U = E_U diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_A.res b/packages/squiggle-lang/src/rescript/Utility/E/E_A.res new file mode 100644 index 00000000..032d2305 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_A.res @@ -0,0 +1,360 @@ +/* A for Array */ +// module O = E_O +module Int = E_Int +module L = E_L +module FloatFloatMap = E_FloatFloatMap + +let fmap = Array.map +let fmapi = Array.mapi +let to_list = Array.to_list +let of_list = Array.of_list +let length = Array.length +let append = Array.append +// let empty = [||]; +let unsafe_get = Array.unsafe_get +let get = Belt.Array.get +let getBy = Belt.Array.getBy +let getIndexBy = Belt.Array.getIndexBy +let last = a => get(a, length(a) - 1) +let first = get(_, 0) +let hasBy = (r, fn) => Belt.Array.getBy(r, fn) |> E_O.isSome +let fold_left = Array.fold_left +let fold_right = Array.fold_right +let concat = Belt.Array.concat +let concatMany = Belt.Array.concatMany +let keepMap = Belt.Array.keepMap +let slice = Belt.Array.slice +let init = Array.init +let reduce = Belt.Array.reduce +let reduceReverse = Belt.Array.reduceReverse +let reducei = Belt.Array.reduceWithIndex +let some = Belt.Array.some +let isEmpty = r => length(r) < 1 +let stableSortBy = Belt.SortArray.stableSortBy +let toNoneIfEmpty = r => isEmpty(r) ? None : Some(r) +let toRanges = (a: array<'a>) => + switch a |> Belt.Array.length { + | 0 + | 1 => + Belt.Result.Error("Must be at least 2 elements") + | n => + Belt.Array.makeBy(n - 1, r => r) + |> Belt.Array.map(_, index => ( + Belt.Array.getUnsafe(a, index), + Belt.Array.getUnsafe(a, index + 1), + )) + |> (x => Ok(x)) + } + +let getByFmap = (a, fn, boolCondition) => { + let i = ref(0) + let finalFunctionValue = ref(None) + let length = Belt.Array.length(a) + + while i.contents < length && finalFunctionValue.contents == None { + let itemWithFnApplied = Belt.Array.getUnsafe(a, i.contents) |> fn + if boolCondition(itemWithFnApplied) { + finalFunctionValue := Some(itemWithFnApplied) + } + i := i.contents + 1 + } + + finalFunctionValue.contents +} + +let tail = Belt.Array.sliceToEnd(_, 1) + +let zip = Belt.Array.zip +let unzip = Belt.Array.unzip +let zip3 = (a, b, c) => + Belt.Array.zip(a, b)->Belt.Array.zip(c)->Belt.Array.map((((v1, v2), v3)) => (v1, v2, v3)) +// This zips while taking the longest elements of each array. +let zipMaxLength = (array1, array2) => { + let maxLength = Int.max(length(array1), length(array2)) + let result = maxLength |> Belt.Array.makeUninitializedUnsafe + for i in 0 to maxLength - 1 { + Belt.Array.set(result, i, (get(array1, i), get(array2, i))) |> ignore + } + result +} + +let asList = (f: list<'a> => list<'a>, r: array<'a>) => r |> to_list |> f |> of_list +/* TODO: Is there a better way of doing this? */ +let uniq = r => asList(L.uniq, r) + +//intersperse([1,2,3], [10,11,12]) => [1,10,2,11,3,12] +let intersperse = (a: array<'a>, b: array<'a>) => { + let items: ref> = ref([]) + + Belt.Array.forEachWithIndex(a, (i, item) => + switch Belt.Array.get(b, i) { + | Some(r) => items := append(items.contents, [item, r]) + | None => items := append(items.contents, [item]) + } + ) + items.contents +} + +// This is like map, but +//accumulate((a,b) => a + b, [1,2,3]) => [1, 3, 5] +let accumulate = (fn: ('a, 'a) => 'a, items: array<'a>) => { + let length = items |> length + let empty = Belt.Array.make(length, items |> unsafe_get(_, 0)) + Belt.Array.forEachWithIndex(items, (index, element) => { + let item = switch index { + | 0 => element + | index => fn(element, unsafe_get(empty, index - 1)) + } + let _ = Belt.Array.set(empty, index, item) + }) + empty +} + +// @todo: Is -1 still the indicator that this is false (as is true with +// @todo: js findIndex)? Wasn't sure. +let findIndex = (e, i) => + Js.Array.findIndex(e, i) |> ( + r => + switch r { + | -1 => None + | r => Some(r) + } + ) +let filter = Js.Array.filter +let joinWith = Js.Array.joinWith +let transpose = (xs: array>): array> => { + let arr: array> = [] + for i in 0 to length(xs) - 1 { + for j in 0 to length(xs[i]) - 1 { + if Js.Array.length(arr) <= j { + ignore(Js.Array.push([xs[i][j]], arr)) + } else { + ignore(Js.Array.push(xs[i][j], arr[j])) + } + } + } + arr +} + +let all = (p: 'a => bool, xs: array<'a>): bool => length(filter(p, xs)) == length(xs) +let any = (p: 'a => bool, xs: array<'a>): bool => length(filter(p, xs)) > 0 + +module O = { + let concatSomes = (optionals: array>): array<'a> => + optionals + |> Js.Array.filter(E_O.isSome) + |> Js.Array.map(E_O.toExn("Warning: This should not have happened")) + let defaultEmpty = (o: option>): array<'a> => + switch o { + | Some(o) => o + | None => [] + } + // REturns `None` there are no non-`None` elements + let rec arrSomeToSomeArr = (optionals: array>): option> => { + let optionals' = optionals->Belt.List.fromArray + switch optionals' { + | list{} => []->Some + | list{x, ...xs} => + switch x { + | Some(_) => xs->Belt.List.toArray->arrSomeToSomeArr + | None => None + } + } + } + let firstSome = x => Belt.Array.getBy(x, E_O.isSome) + + let firstSomeFn = (r: array option<'a>>): option<'a> => + E_O.flatten(getByFmap(r, l => l(), E_O.isSome)) + + let firstSomeFnWithDefault = (r, default) => firstSomeFn(r)->E_O2.default(default) + + let openIfAllSome = (optionals: array>): option> => { + if all(E_O.isSome, optionals) { + Some(optionals |> fmap(E_O.toExn("Warning: This should not have happened"))) + } else { + None + } + } +} + +module R = { + let firstErrorOrOpen = (results: array>): Belt.Result.t, 'b> => { + let bringErrorUp = switch results |> Belt.Array.getBy(_, Belt.Result.isError) { + | Some(Belt.Result.Error(err)) => Belt.Result.Error(err) + | Some(Belt.Result.Ok(_)) => Belt.Result.Ok(results) + | None => Belt.Result.Ok(results) + } + let forceOpen = (r: array>): array<'a> => + r |> Belt.Array.map(_, r => Belt.Result.getExn(r)) + bringErrorUp |> Belt.Result.map(_, forceOpen) + } + let filterOk = (x: array>): array<'a> => fmap(E_R.toOption, x)->O.concatSomes + + let forM = (x: array<'a>, fn: 'a => result<'b, 'c>): result, 'c> => + firstErrorOrOpen(fmap(fn, x)) + + let foldM = (fn: ('c, 'a) => result<'b, 'e>, init: 'c, x: array<'a>): result<'c, 'e> => { + let acc = ref(init) + let final = ref(Ok()) + let break = ref(false) + let i = ref(0) + + while break.contents != true && i.contents < length(x) { + switch fn(acc.contents, x[i.contents]) { + | Ok(r) => acc := r + | Error(err) => { + final := Error(err) + break := true + } + } + i := i.contents + 1 + } + switch final.contents { + | Ok(_) => Ok(acc.contents) + | Error(err) => Error(err) + } + } +} + +module Floats = { + type t = array + let mean = Jstat.mean + let geomean = Jstat.geomean + let mode = Jstat.mode + let variance = Jstat.variance + let stdev = Jstat.stdev + let sum = Jstat.sum + let product = Jstat.product + let random = Js.Math.random_int + + let floatCompare: (float, float) => int = compare + let sort = t => { + let r = t + r |> Array.fast_sort(floatCompare) + r + } + + let getNonFinite = (t: t) => Belt.Array.getBy(t, r => !Js.Float.isFinite(r)) + let getBelowZero = (t: t) => Belt.Array.getBy(t, r => r < 0.0) + + let isSorted = (t: t): bool => + if Array.length(t) < 1 { + true + } else { + reduce(zip(t, tail(t)), true, (acc, (first, second)) => acc && first < second) + } + + //Passing true for the exclusive parameter excludes both endpoints of the range. + //https://jstat.github.io/all.html + let percentile = (a, b) => Jstat.percentile(a, b, false) + + // Gives an array with all the differences between values + // diff([1,5,3,7]) = [4,-2,4] + let diff = (t: t): array => + Belt.Array.zipBy(t, Belt.Array.sliceToEnd(t, 1), (left, right) => right -. left) + + let cumSum = (t: t): array => accumulate((a, b) => a +. b, t) + let cumProd = (t: t): array => accumulate((a, b) => a *. b, t) + + exception RangeError(string) + let range = (min: float, max: float, n: int): array => + switch n { + | 0 => [] + | 1 => [min] + | 2 => [min, max] + | _ if min == max => Belt.Array.make(n, min) + | _ if n < 0 => raise(RangeError("n must be greater than 0")) + | _ if min > max => raise(RangeError("Min value is less then max value")) + | _ => + let diff = (max -. min) /. Belt.Float.fromInt(n - 1) + Belt.Array.makeBy(n, i => min +. Belt.Float.fromInt(i) *. diff) + } + + let min = Js.Math.minMany_float + let max = Js.Math.maxMany_float + + module Sorted = { + let min = first + let max = last + let range = (~min=min, ~max=max, a) => + switch (min(a), max(a)) { + | (Some(min), Some(max)) => Some(max -. min) + | _ => None + } + + let binarySearchFirstElementGreaterIndex = (ar: array<'a>, el: 'a) => { + let el = Belt.SortArray.binarySearchBy(ar, el, floatCompare) + let el = el < 0 ? el * -1 - 1 : el + switch el { + | e if e >= length(ar) => #overMax + | e if e == 0 => #underMin + | e => #firstHigher(e) + } + } + + let concat = (t1: array<'a>, t2: array<'a>) => Belt.Array.concat(t1, t2)->sort + + let concatMany = (t1: array>) => Belt.Array.concatMany(t1)->sort + + let makeIncrementalUp = (a, b) => + Array.make(b - a + 1, a) |> Array.mapi((i, c) => c + i) |> Belt.Array.map(_, float_of_int) + + let makeIncrementalDown = (a, b) => + Array.make(a - b + 1, a) |> Array.mapi((i, c) => c - i) |> Belt.Array.map(_, float_of_int) + + /* + This function goes through a sorted array and divides it into two different clusters: + continuous samples and discrete samples. The discrete samples are stored in a mutable map. + Samples are thought to be discrete if they have any duplicates. + */ + let _splitContinuousAndDiscreteForDuplicates = (sortedArray: array) => { + let continuous: array = [] + let discrete = FloatFloatMap.empty() + Belt.Array.forEachWithIndex(sortedArray, (index, element) => { + let maxIndex = (sortedArray |> Array.length) - 1 + let possiblySimilarElements = switch index { + | 0 => [index + 1] + | n if n == maxIndex => [index - 1] + | _ => [index - 1, index + 1] + } |> Belt.Array.map(_, r => sortedArray[r]) + let hasSimilarElement = Belt.Array.some(possiblySimilarElements, r => r == element) + hasSimilarElement + ? FloatFloatMap.increment(element, discrete) + : { + let _ = Js.Array.push(element, continuous) + } + + () + }) + + (continuous, discrete) + } + + /* + This function works very similarly to splitContinuousAndDiscreteForDuplicates. The one major difference + is that you can specify a minDiscreteWeight. If the min discreet weight is 4, that would mean that + at least four elements needed from a specific value for that to be kept as discrete. This is important + because in some cases, we can expect that some common elements will be generated by regular operations. + The final continous array will be sorted. + */ + let splitContinuousAndDiscreteForMinWeight = ( + sortedArray: array, + ~minDiscreteWeight: int, + ) => { + let (continuous, discrete) = _splitContinuousAndDiscreteForDuplicates(sortedArray) + let keepFn = v => Belt.Float.toInt(v) >= minDiscreteWeight + let (discreteToKeep, discreteToIntegrate) = FloatFloatMap.partition( + ((_, v)) => keepFn(v), + discrete, + ) + let newContinousSamples = + discreteToIntegrate->FloatFloatMap.toArray + |> fmap(((k, v)) => Belt.Array.makeBy(Belt.Float.toInt(v), _ => k)) + |> Belt.Array.concatMany + let newContinuous = concat(continuous, newContinousSamples) + newContinuous |> Array.fast_sort(floatCompare) + (newContinuous, discreteToKeep) + } + } +} +module Sorted = Floats.Sorted diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_A2.res b/packages/squiggle-lang/src/rescript/Utility/E/E_A2.res new file mode 100644 index 00000000..b21a3fa9 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_A2.res @@ -0,0 +1,5 @@ +module A = E_A +let fmap = (a, b) => A.fmap(b, a) +let fmapi = (a, b) => A.fmapi(b, a) +let joinWith = (a, b) => A.joinWith(b, a) +let filter = (a, b) => A.filter(b, a) diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_B.res b/packages/squiggle-lang/src/rescript/Utility/E/E_B.res new file mode 100644 index 00000000..f74e64bf --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_B.res @@ -0,0 +1,11 @@ +type t = bool +let toString = (t: t) => t ? "TRUE" : "FALSE" +let fromString = str => str == "TRUE" ? true : false + +module O = { + let toBool = opt => + switch opt { + | Some(true) => true + | _ => false + } +} diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_Dict.res b/packages/squiggle-lang/src/rescript/Utility/E/E_Dict.res new file mode 100644 index 00000000..d5f18cf2 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_Dict.res @@ -0,0 +1,10 @@ +module A = E_A +module A2 = E_A2 + +type t<'a> = Js.Dict.t<'a> +let get = Js.Dict.get +let keys = Js.Dict.keys +let fromArray = Js.Dict.fromArray +let toArray = Js.Dict.entries +let concat = (a, b) => A.concat(toArray(a), toArray(b))->fromArray +let concatMany = ts => ts->A2.fmap(toArray)->A.concatMany->fromArray diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_F.res b/packages/squiggle-lang/src/rescript/Utility/E/E_F.res new file mode 100644 index 00000000..6b283d49 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_F.res @@ -0,0 +1,20 @@ +/* Functions */ +let pipe = (f, g, x) => g(f(x)) +let compose = (f, g, x) => f(g(x)) +let flip = (f, a, b) => f(b, a) +let always = (x, _y) => x + +let apply = (a, e) => a |> e + +let flatten2Callbacks = (fn1, fn2, fnlast) => + fn1(response1 => fn2(response2 => fnlast(response1, response2))) + +let flatten3Callbacks = (fn1, fn2, fn3, fnlast) => + fn1(response1 => fn2(response2 => fn3(response3 => fnlast(response1, response2, response3)))) + +let flatten4Callbacks = (fn1, fn2, fn3, fn4, fnlast) => + fn1(response1 => + fn2(response2 => + fn3(response3 => fn4(response4 => fnlast(response1, response2, response3, response4))) + ) + ) diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_Float.res b/packages/squiggle-lang/src/rescript/Utility/E/E_Float.res new file mode 100644 index 00000000..8cacedfd --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_Float.res @@ -0,0 +1,6 @@ +let with2DigitsPrecision = Js.Float.toPrecisionWithPrecision(_, ~digits=2) +let with3DigitsPrecision = Js.Float.toPrecisionWithPrecision(_, ~digits=3) +let toFixed = Js.Float.toFixed +let toString = Js.Float.toString +let isFinite = Js.Float.isFinite +let toInt = Belt.Float.toInt diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_FloatFloatMap.res b/packages/squiggle-lang/src/rescript/Utility/E/E_FloatFloatMap.res new file mode 100644 index 00000000..aa89aac7 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_FloatFloatMap.res @@ -0,0 +1,24 @@ +module Id = Belt.Id.MakeComparable({ + type t = float + let cmp: (float, float) => int = Pervasives.compare +}) + +type t = Belt.MutableMap.t + +let fromArray = (ar: array<(float, float)>) => Belt.MutableMap.fromArray(ar, ~id=module(Id)) +let toArray = (t: t): array<(float, float)> => Belt.MutableMap.toArray(t) +let empty = () => Belt.MutableMap.make(~id=module(Id)) +let increment = (el, t: t) => + Belt.MutableMap.update(t, el, x => + switch x { + | Some(n) => Some(n +. 1.0) + | None => Some(1.0) + } + ) + +let get = (el, t: t) => Belt.MutableMap.get(t, el) +let fmap = (fn, t: t) => Belt.MutableMap.map(t, fn) +let partition = (fn, t: t) => { + let (match, noMatch) = Belt.Array.partition(toArray(t), fn) + (fromArray(match), fromArray(noMatch)) +} diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_I.res b/packages/squiggle-lang/src/rescript/Utility/E/E_I.res new file mode 100644 index 00000000..24660b01 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_I.res @@ -0,0 +1,4 @@ +let increment = n => n + 1 +let decrement = n => n - 1 +let toString = Js.Int.toString +let toFloat = Js.Int.toFloat diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_Int.res b/packages/squiggle-lang/src/rescript/Utility/E/E_Int.res new file mode 100644 index 00000000..9ca540dd --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_Int.res @@ -0,0 +1,2 @@ +let max = (i1: int, i2: int) => i1 > i2 ? i1 : i2 +let random = (~min, ~max) => Js.Math.random_int(min, max) diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_J.res b/packages/squiggle-lang/src/rescript/Utility/E/E_J.res new file mode 100644 index 00000000..1444c606 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_J.res @@ -0,0 +1,19 @@ +module F = E_F + +let toString = F.pipe(Js.Json.decodeString, E_O.default("")) +let fromString = Js.Json.string +let fromNumber = Js.Json.number + +module O = { + let fromString = (str: string) => + switch str { + | "" => None + | _ => Some(Js.Json.string(str)) + } + + let toString = (str: option<'a>) => + switch str { + | Some(str) => Some(str |> F.pipe(Js.Json.decodeString, E_O.default(""))) + | _ => None + } +} diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_JsArray.res b/packages/squiggle-lang/src/rescript/Utility/E/E_JsArray.res new file mode 100644 index 00000000..2551ec8c --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_JsArray.res @@ -0,0 +1,6 @@ +module O = E_O +let concatSomes = (optionals: Js.Array.t>): Js.Array.t<'a> => + optionals + |> Js.Array.filter(O.isSome) + |> Js.Array.map(O.toExn("Warning: This should not have happened")) +let filter = Js.Array.filter diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_JsDate.res b/packages/squiggle-lang/src/rescript/Utility/E/E_JsDate.res new file mode 100644 index 00000000..45c49582 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_JsDate.res @@ -0,0 +1,4 @@ +let fromString = Js.Date.fromString +let now = Js.Date.now +let make = Js.Date.make +let valueOf = Js.Date.valueOf diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_L.res b/packages/squiggle-lang/src/rescript/Utility/E/E_L.res new file mode 100644 index 00000000..f674fc93 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_L.res @@ -0,0 +1,151 @@ +/* List */ +module F = E_F +module O = E_O + +module Util = { + let eq = \"==" +} +let fmap = List.map +let get = Belt.List.get +let toArray = Array.of_list +let fmapi = List.mapi +let concat = List.concat +let concat' = (xs, ys) => List.append(ys, xs) + +let rec drop = (i, xs) => + switch (i, xs) { + | (_, list{}) => list{} + | (i, _) if i <= 0 => xs + | (i, list{_, ...b}) => drop(i - 1, b) + } + +let append = (a, xs) => List.append(xs, list{a}) +let take = { + let rec loop = (i, xs, acc) => + switch (i, xs) { + | (i, _) if i <= 0 => acc + | (_, list{}) => acc + | (i, list{a, ...b}) => loop(i - 1, b, append(a, acc)) + } + (i, xs) => loop(i, xs, list{}) +} +let takeLast = (i, xs) => List.rev(xs) |> take(i) |> List.rev + +let splitAt = (i, xs) => (take(i, xs), takeLast(List.length(xs) - i, xs)) +let remove = (i, n, xs) => { + let (a, b) = splitAt(i, xs) + \"@"(a, drop(n, b)) +} + +let find = List.find +let filter = List.filter +let for_all = List.for_all +let exists = List.exists +let sort = List.sort +let length = List.length + +let filter_opt = xs => { + let rec loop = (l, acc) => + switch l { + | list{} => acc + | list{hd, ...tl} => + switch hd { + | None => loop(tl, acc) + | Some(x) => loop(tl, list{x, ...acc}) + } + } + List.rev(loop(xs, list{})) +} + +let containsWith = f => List.exists(f) + +let uniqWithBy = (eq, f, xs) => + List.fold_left( + ((acc, tacc), v) => + containsWith(eq(f(v)), tacc) ? (acc, tacc) : (append(v, acc), append(f(v), tacc)), + (list{}, list{}), + xs, + ) |> fst + +let uniqBy = (f, xs) => uniqWithBy(Util.eq, f, xs) +let join = j => List.fold_left((acc, v) => String.length(acc) == 0 ? v : acc ++ (j ++ v), "") + +let head = xs => + switch List.hd(xs) { + | exception _ => None + | a => Some(a) + } + +let uniq = xs => uniqBy(x => x, xs) +let flatten = List.flatten +let last = xs => xs |> List.rev |> head +let append = List.append +let getBy = Belt.List.getBy +let dropLast = (i, xs) => take(List.length(xs) - i, xs) +let containsWith = f => List.exists(f) +let contains = x => containsWith(Util.eq(x)) + +let reject = pred => List.filter(x => !pred(x)) +let tail = xs => + switch List.tl(xs) { + | exception _ => None + | a => Some(a) + } + +let init = xs => { + O.fmap(List.rev, xs |> List.rev |> tail) +} + +let singleton = (x: 'a): list<'a> => list{x} + +let adjust = (f, i, xs) => { + let (a, b) = splitAt(i + 1, xs) + switch a { + | _ if i < 0 => xs + | _ if i >= List.length(xs) => xs + | list{} => b + | list{a} => list{f(a), ...b} + | a => + O.fmap( + concat'(b), + O.bind(init(a), x => O.fmap(F.flip(append, x), O.fmap(fmap(f), O.fmap(singleton, last(a))))), + ) |> O.default(xs) + } +} + +let without = (exclude, xs) => reject(x => contains(x, exclude), xs) +let update = (x, i, xs) => adjust(F.always(x), i, xs) +let iter = List.iter + +let findIndex = { + let rec loop = (pred, xs, i) => + switch xs { + | list{} => None + | list{a, ...b} => pred(a) ? Some(i) : loop(pred, b, i + 1) + } + (pred, xs) => loop(pred, xs, 0) +} + +let headSafe = Belt.List.head +let tailSafe = Belt.List.tail +let headExn = Belt.List.headExn +let tailExn = Belt.List.tailExn +let zip = Belt.List.zip + +let combinations2: list<'a> => list<('a, 'a)> = xs => { + let rec loop: ('a, list<'a>) => list<('a, 'a)> = (x', xs') => { + let n = length(xs') + if n == 0 { + list{} + } else { + let combs = fmap(y => (x', y), xs') + let hd = headExn(xs') + let tl = tailExn(xs') + concat(list{combs, loop(hd, tl)}) + } + } + switch (headSafe(xs), tailSafe(xs)) { + | (Some(x'), Some(xs')) => loop(x', xs') + | (_, _) => list{} + } +} diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_O.res b/packages/squiggle-lang/src/rescript/Utility/E/E_O.res new file mode 100644 index 00000000..02ce6e34 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_O.res @@ -0,0 +1,99 @@ +let dimap = (sFn, rFn, e) => + switch e { + | Some(r) => sFn(r) + | None => rFn() + } +() +let fmap = (f: 'a => 'b, x: option<'a>): option<'b> => { + switch x { + | None => None + | Some(x') => Some(f(x')) + } +} +let bind = (o, f) => + switch o { + | None => None + | Some(a) => f(a) + } +let default = (d, o) => + switch o { + | None => d + | Some(a) => a + } +let defaultFn = (d, o) => + switch o { + | None => d() + | Some(a) => a + } +let isSome = o => + switch o { + | Some(_) => true + | _ => false + } +let isNone = o => + switch o { + | None => true + | _ => false + } +let toExn = (err, o) => + switch o { + | None => raise(Failure(err)) + | Some(a) => a + } + +let some = a => Some(a) +let firstSome = (a, b) => + switch a { + | None => b + | _ => a + } + +let toExt = toExn + +let flatten = o => + switch o { + | None => None + | Some(x) => x + } + +let apply = (o, a) => + switch o { + | Some(f) => bind(a, b => some(f(b))) + | _ => None + } +let flatApply = (fn, b) => apply(fn, Some(b)) |> flatten + +let toBool = opt => + switch opt { + | Some(_) => true + | _ => false + } + +let ffmap = (fn, r) => + switch r { + | Some(sm) => fn(sm) + | _ => None + } + +let toString = opt => + switch opt { + | Some(s) => s + | _ => "" + } + +let toResult = (error, e) => + switch e { + | Some(r) => Belt.Result.Ok(r) + | None => Error(error) + } + +let compare = (compare, f1: option, f2: option) => + switch (f1, f2) { + | (Some(f1), Some(f2)) => Some(compare(f1, f2) ? f1 : f2) + | (Some(f1), None) => Some(f1) + | (None, Some(f2)) => Some(f2) + | (None, None) => None + } + +let min = compare(\"<") +let max = compare(\">") diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_O2.res b/packages/squiggle-lang/src/rescript/Utility/E/E_O2.res new file mode 100644 index 00000000..7f8a635e --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_O2.res @@ -0,0 +1,7 @@ +module O = E_O +let default = (a, b) => O.default(b, a) +let defaultFn = (a, b) => O.defaultFn(b, a) +let toExn = (a, b) => O.toExn(b, a) +let fmap = (a, b) => O.fmap(b, a) +let toResult = (a, b) => O.toResult(b, a) +let bind = (a, b) => O.bind(b, a) diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_R.res b/packages/squiggle-lang/src/rescript/Utility/E/E_R.res new file mode 100644 index 00000000..c60b26ae --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_R.res @@ -0,0 +1,94 @@ +/* R for Result */ + +exception Assertion(string) +module U = E_U + +open Belt.Result +let result = (okF, errF, r) => + switch r { + | Ok(a) => okF(a) + | Error(err) => errF(err) + } +let id = e => e |> result(U.id, U.id) +let isOk = Belt.Result.isOk +let getError = (r: result<'a, 'b>) => + switch r { + | Ok(_) => None + | Error(e) => Some(e) + } +let fmap = (f: 'a => 'b, r: result<'a, 'c>): result<'b, 'c> => { + switch r { + | Ok(r') => Ok(f(r')) + | Error(err) => Error(err) + } +} +let bind = (r, f) => + switch r { + | Ok(a) => f(a) + | Error(err) => Error(err) + } +let toExn = (msg: string, x: result<'a, 'b>): 'a => + switch x { + | Ok(r) => r + | Error(_) => raise(Assertion(msg)) + } +let toExnFnString = (errorToStringFn, o) => + switch o { + | Ok(r) => r + | Error(r) => raise(Assertion(errorToStringFn(r))) + } +let default = (default, res: Belt.Result.t<'a, 'b>) => + switch res { + | Ok(r) => r + | Error(_) => default + } +let merge = (a, b) => + switch (a, b) { + | (Error(e), _) => Error(e) + | (_, Error(e)) => Error(e) + | (Ok(a), Ok(b)) => Ok((a, b)) + } +let toOption = (e: Belt.Result.t<'a, 'b>) => + switch e { + | Ok(r) => Some(r) + | Error(_) => None + } + +let errorIfCondition = (errorCondition, errorMessage, r) => + errorCondition(r) ? Error(errorMessage) : Ok(r) + +let ap = (r, a) => + switch r { + | Ok(f) => Ok(f(a)) + | Error(err) => Error(err) + } +let ap' = (r, a) => + switch r { + | Ok(f) => fmap(f, a) + | Error(err) => Error(err) + } + +let liftM2: (('a, 'b) => 'c, result<'a, 'd>, result<'b, 'd>) => result<'c, 'd> = (op, xR, yR) => { + ap'(fmap(op, xR), yR) +} + +let liftJoin2: (('a, 'b) => result<'c, 'd>, result<'a, 'd>, result<'b, 'd>) => result<'c, 'd> = ( + op, + xR, + yR, +) => { + bind(liftM2(op, xR, yR), x => x) +} + +let fmap2 = (f, r) => + switch r { + | Ok(r) => r->Ok + | Error(x) => x->f->Error + } + +//I'm not sure what to call this. +let unify = (a: result<'a, 'b>, c: 'b => 'a): 'a => + switch a { + | Ok(x) => x + | Error(x) => c(x) + } diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_R2.res b/packages/squiggle-lang/src/rescript/Utility/E/E_R2.res new file mode 100644 index 00000000..733a4fbc --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_R2.res @@ -0,0 +1,19 @@ +module R = E_R + +let fmap = (a, b) => R.fmap(b, a) +let bind = (a, b) => R.bind(b, a) + +//Converts result type to change error type only +let errMap = (a: result<'a, 'b>, map: 'b => 'c): result<'a, 'c> => + switch a { + | Ok(r) => Ok(r) + | Error(e) => Error(map(e)) + } + +let fmap2 = (xR, f) => + switch xR { + | Ok(x) => x->Ok + | Error(x) => x->f->Error + } + +let toExn = (a, b) => R.toExn(b, a) diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_S.res b/packages/squiggle-lang/src/rescript/Utility/E/E_S.res new file mode 100644 index 00000000..12bcf129 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_S.res @@ -0,0 +1,8 @@ +let safe_fn_of_string = (fn, s: string): option<'a> => + try Some(fn(s)) catch { + | _ => None + } + +let safe_float = float_of_string->safe_fn_of_string +let safe_int = int_of_string->safe_fn_of_string +let default = (defaultStr, str) => str == "" ? defaultStr : str diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_Tuple2.res b/packages/squiggle-lang/src/rescript/Utility/E/E_Tuple2.res new file mode 100644 index 00000000..ec8f883d --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_Tuple2.res @@ -0,0 +1,9 @@ +let first = (v: ('a, 'b)) => { + let (a, _) = v + a +} +let second = (v: ('a, 'b)) => { + let (_, b) = v + b +} +let toFnCall = (fn, (a1, a2)) => fn(a1, a2) diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_Tuple3.res b/packages/squiggle-lang/src/rescript/Utility/E/E_Tuple3.res new file mode 100644 index 00000000..2f422da2 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_Tuple3.res @@ -0,0 +1 @@ +let toFnCall = (fn, (a1, a2, a3)) => fn(a1, a2, a3) diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_U.res b/packages/squiggle-lang/src/rescript/Utility/E/E_U.res new file mode 100644 index 00000000..016c0e17 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_U.res @@ -0,0 +1,4 @@ +/* Utils */ +let isEqual = \"==" +let toA = a => [a] +let id = e => e From f7f3e449d1a0f7f6ffb3ce67342d97e44ebefc0f Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sun, 11 Sep 2022 13:47:58 -0700 Subject: [PATCH 36/55] Delete E copy.resxxx --- .../src/rescript/Utility/E copy.resxxx | 916 ------------------ 1 file changed, 916 deletions(-) delete mode 100644 packages/squiggle-lang/src/rescript/Utility/E copy.resxxx diff --git a/packages/squiggle-lang/src/rescript/Utility/E copy.resxxx b/packages/squiggle-lang/src/rescript/Utility/E copy.resxxx deleted file mode 100644 index 60da5737..00000000 --- a/packages/squiggle-lang/src/rescript/Utility/E copy.resxxx +++ /dev/null @@ -1,916 +0,0 @@ -/* -Some functions from modules `L`, `O`, and `R` below were copied directly from -running `rescript convert -all` on Rationale https://github.com/jonlaing/rationale -*/ - -let equals = (a, b) => a === b - -module FloatFloatMap = { - module Id = Belt.Id.MakeComparable({ - type t = float - let cmp: (float, float) => int = Pervasives.compare - }) - - type t = Belt.MutableMap.t - - let fromArray = (ar: array<(float, float)>) => Belt.MutableMap.fromArray(ar, ~id=module(Id)) - let toArray = (t: t): array<(float, float)> => Belt.MutableMap.toArray(t) - let empty = () => Belt.MutableMap.make(~id=module(Id)) - let increment = (el, t: t) => - Belt.MutableMap.update(t, el, x => - switch x { - | Some(n) => Some(n +. 1.0) - | None => Some(1.0) - } - ) - - let get = (el, t: t) => Belt.MutableMap.get(t, el) - let fmap = (fn, t: t) => Belt.MutableMap.map(t, fn) - let partition = (fn, t: t) => { - let (match, noMatch) = Belt.Array.partition(toArray(t), fn) - (fromArray(match), fromArray(noMatch)) - } -} - -module Int = { - let max = (i1: int, i2: int) => i1 > i2 ? i1 : i2 - let random = (~min, ~max) => Js.Math.random_int(min, max) -} -/* Utils */ -module U = { - let isEqual = \"==" - let toA = a => [a] - let id = e => e -} - -module Tuple2 = { - let first = (v: ('a, 'b)) => { - let (a, _) = v - a - } - let second = (v: ('a, 'b)) => { - let (_, b) = v - b - } - let toFnCall = (fn, (a1, a2)) => fn(a1, a2) -} - -module Tuple3 = { - let toFnCall = (fn, (a1, a2, a3)) => fn(a1, a2, a3) -} - -module O = { - let dimap = (sFn, rFn, e) => - switch e { - | Some(r) => sFn(r) - | None => rFn() - } - () - let fmap = (f: 'a => 'b, x: option<'a>): option<'b> => { - switch x { - | None => None - | Some(x') => Some(f(x')) - } - } - let bind = (o, f) => - switch o { - | None => None - | Some(a) => f(a) - } - let default = (d, o) => - switch o { - | None => d - | Some(a) => a - } - let defaultFn = (d, o) => - switch o { - | None => d() - | Some(a) => a - } - let isSome = o => - switch o { - | Some(_) => true - | _ => false - } - let isNone = o => - switch o { - | None => true - | _ => false - } - let toExn = (err, o) => - switch o { - | None => raise(Failure(err)) - | Some(a) => a - } - - let some = a => Some(a) - let firstSome = (a, b) => - switch a { - | None => b - | _ => a - } - - let toExt = toExn - - let flatten = o => - switch o { - | None => None - | Some(x) => x - } - - let apply = (o, a) => - switch o { - | Some(f) => bind(a, b => some(f(b))) - | _ => None - } - let flatApply = (fn, b) => apply(fn, Some(b)) |> flatten - - let toBool = opt => - switch opt { - | Some(_) => true - | _ => false - } - - let ffmap = (fn, r) => - switch r { - | Some(sm) => fn(sm) - | _ => None - } - - let toString = opt => - switch opt { - | Some(s) => s - | _ => "" - } - - let toResult = (error, e) => - switch e { - | Some(r) => Belt.Result.Ok(r) - | None => Error(error) - } - - let compare = (compare, f1: option, f2: option) => - switch (f1, f2) { - | (Some(f1), Some(f2)) => Some(compare(f1, f2) ? f1 : f2) - | (Some(f1), None) => Some(f1) - | (None, Some(f2)) => Some(f2) - | (None, None) => None - } - - let min = compare(\"<") - let max = compare(\">") -} - -module O2 = { - let default = (a, b) => O.default(b, a) - let defaultFn = (a, b) => O.defaultFn(b, a) - let toExn = (a, b) => O.toExn(b, a) - let fmap = (a, b) => O.fmap(b, a) - let toResult = (a, b) => O.toResult(b, a) - let bind = (a, b) => O.bind(b, a) -} - -/* Functions */ -module F = { - let pipe = (f, g, x) => g(f(x)) - let compose = (f, g, x) => f(g(x)) - let flip = (f, a, b) => f(b, a) - let always = (x, _y) => x - - let apply = (a, e) => a |> e - - let flatten2Callbacks = (fn1, fn2, fnlast) => - fn1(response1 => fn2(response2 => fnlast(response1, response2))) - - let flatten3Callbacks = (fn1, fn2, fn3, fnlast) => - fn1(response1 => fn2(response2 => fn3(response3 => fnlast(response1, response2, response3)))) - - let flatten4Callbacks = (fn1, fn2, fn3, fn4, fnlast) => - fn1(response1 => - fn2(response2 => - fn3(response3 => fn4(response4 => fnlast(response1, response2, response3, response4))) - ) - ) -} - -module Bool = { - type t = bool - let toString = (t: t) => t ? "TRUE" : "FALSE" - let fromString = str => str == "TRUE" ? true : false - - module O = { - let toBool = opt => - switch opt { - | Some(true) => true - | _ => false - } - } -} - -module Float = { - let with2DigitsPrecision = Js.Float.toPrecisionWithPrecision(_, ~digits=2) - let with3DigitsPrecision = Js.Float.toPrecisionWithPrecision(_, ~digits=3) - let toFixed = Js.Float.toFixed - let toString = Js.Float.toString - let isFinite = Js.Float.isFinite - let toInt = Belt.Float.toInt -} - -module I = { - let increment = n => n + 1 - let decrement = n => n - 1 - let toString = Js.Int.toString - let toFloat = Js.Int.toFloat -} - -exception Assertion(string) - -/* R for Result */ -module R = { - open Belt.Result - let result = (okF, errF, r) => - switch r { - | Ok(a) => okF(a) - | Error(err) => errF(err) - } - let id = e => e |> result(U.id, U.id) - let isOk = Belt.Result.isOk - let getError = (r: result<'a, 'b>) => - switch r { - | Ok(_) => None - | Error(e) => Some(e) - } - let fmap = (f: 'a => 'b, r: result<'a, 'c>): result<'b, 'c> => { - switch r { - | Ok(r') => Ok(f(r')) - | Error(err) => Error(err) - } - } - let bind = (r, f) => - switch r { - | Ok(a) => f(a) - | Error(err) => Error(err) - } - let toExn = (msg: string, x: result<'a, 'b>): 'a => - switch x { - | Ok(r) => r - | Error(_) => raise(Assertion(msg)) - } - let toExnFnString = (errorToStringFn, o) => - switch o { - | Ok(r) => r - | Error(r) => raise(Assertion(errorToStringFn(r))) - } - let default = (default, res: Belt.Result.t<'a, 'b>) => - switch res { - | Ok(r) => r - | Error(_) => default - } - let merge = (a, b) => - switch (a, b) { - | (Error(e), _) => Error(e) - | (_, Error(e)) => Error(e) - | (Ok(a), Ok(b)) => Ok((a, b)) - } - let toOption = (e: Belt.Result.t<'a, 'b>) => - switch e { - | Ok(r) => Some(r) - | Error(_) => None - } - - let errorIfCondition = (errorCondition, errorMessage, r) => - errorCondition(r) ? Error(errorMessage) : Ok(r) - - let ap = (r, a) => - switch r { - | Ok(f) => Ok(f(a)) - | Error(err) => Error(err) - } - let ap' = (r, a) => - switch r { - | Ok(f) => fmap(f, a) - | Error(err) => Error(err) - } - - let liftM2: (('a, 'b) => 'c, result<'a, 'd>, result<'b, 'd>) => result<'c, 'd> = (op, xR, yR) => { - ap'(fmap(op, xR), yR) - } - - let liftJoin2: (('a, 'b) => result<'c, 'd>, result<'a, 'd>, result<'b, 'd>) => result<'c, 'd> = ( - op, - xR, - yR, - ) => { - bind(liftM2(op, xR, yR), x => x) - } - - let fmap2 = (f, r) => - switch r { - | Ok(r) => r->Ok - | Error(x) => x->f->Error - } - - //I'm not sure what to call this. - let unify = (a: result<'a, 'b>, c: 'b => 'a): 'a => - switch a { - | Ok(x) => x - | Error(x) => c(x) - } -} - -module R2 = { - let fmap = (a, b) => R.fmap(b, a) - let bind = (a, b) => R.bind(b, a) - - //Converts result type to change error type only - let errMap = (a: result<'a, 'b>, map: 'b => 'c): result<'a, 'c> => - switch a { - | Ok(r) => Ok(r) - | Error(e) => Error(map(e)) - } - - let fmap2 = (xR, f) => - switch xR { - | Ok(x) => x->Ok - | Error(x) => x->f->Error - } - - let toExn = (a, b) => R.toExn(b, a) -} - -let safe_fn_of_string = (fn, s: string): option<'a> => - try Some(fn(s)) catch { - | _ => None - } - -module S = { - let safe_float = float_of_string->safe_fn_of_string - let safe_int = int_of_string->safe_fn_of_string - let default = (defaultStr, str) => str == "" ? defaultStr : str -} - -module J = { - let toString = F.pipe(Js.Json.decodeString, O.default("")) - let fromString = Js.Json.string - let fromNumber = Js.Json.number - - module O = { - let fromString = (str: string) => - switch str { - | "" => None - | _ => Some(Js.Json.string(str)) - } - - let toString = (str: option<'a>) => - switch str { - | Some(str) => Some(str |> F.pipe(Js.Json.decodeString, O.default(""))) - | _ => None - } - } -} - -module JsDate = { - let fromString = Js.Date.fromString - let now = Js.Date.now - let make = Js.Date.make - let valueOf = Js.Date.valueOf -} - -/* List */ -module L = { - module Util = { - let eq = \"==" - } - let fmap = List.map - let get = Belt.List.get - let toArray = Array.of_list - let fmapi = List.mapi - let concat = List.concat - let concat' = (xs, ys) => List.append(ys, xs) - - let rec drop = (i, xs) => - switch (i, xs) { - | (_, list{}) => list{} - | (i, _) if i <= 0 => xs - | (i, list{_, ...b}) => drop(i - 1, b) - } - - let append = (a, xs) => List.append(xs, list{a}) - let take = { - let rec loop = (i, xs, acc) => - switch (i, xs) { - | (i, _) if i <= 0 => acc - | (_, list{}) => acc - | (i, list{a, ...b}) => loop(i - 1, b, append(a, acc)) - } - (i, xs) => loop(i, xs, list{}) - } - let takeLast = (i, xs) => List.rev(xs) |> take(i) |> List.rev - - let splitAt = (i, xs) => (take(i, xs), takeLast(List.length(xs) - i, xs)) - let remove = (i, n, xs) => { - let (a, b) = splitAt(i, xs) - \"@"(a, drop(n, b)) - } - - let find = List.find - let filter = List.filter - let for_all = List.for_all - let exists = List.exists - let sort = List.sort - let length = List.length - - let filter_opt = xs => { - let rec loop = (l, acc) => - switch l { - | list{} => acc - | list{hd, ...tl} => - switch hd { - | None => loop(tl, acc) - | Some(x) => loop(tl, list{x, ...acc}) - } - } - List.rev(loop(xs, list{})) - } - - let containsWith = f => List.exists(f) - - let uniqWithBy = (eq, f, xs) => - List.fold_left( - ((acc, tacc), v) => - containsWith(eq(f(v)), tacc) ? (acc, tacc) : (append(v, acc), append(f(v), tacc)), - (list{}, list{}), - xs, - ) |> fst - - let uniqBy = (f, xs) => uniqWithBy(Util.eq, f, xs) - let join = j => List.fold_left((acc, v) => String.length(acc) == 0 ? v : acc ++ (j ++ v), "") - - let head = xs => - switch List.hd(xs) { - | exception _ => None - | a => Some(a) - } - - let uniq = xs => uniqBy(x => x, xs) - let flatten = List.flatten - let last = xs => xs |> List.rev |> head - let append = List.append - let getBy = Belt.List.getBy - let dropLast = (i, xs) => take(List.length(xs) - i, xs) - let containsWith = f => List.exists(f) - let contains = x => containsWith(Util.eq(x)) - - let reject = pred => List.filter(x => !pred(x)) - let tail = xs => - switch List.tl(xs) { - | exception _ => None - | a => Some(a) - } - - let init = xs => { - O.fmap(List.rev, xs |> List.rev |> tail) - } - - let singleton = (x: 'a): list<'a> => list{x} - - let adjust = (f, i, xs) => { - let (a, b) = splitAt(i + 1, xs) - switch a { - | _ if i < 0 => xs - | _ if i >= List.length(xs) => xs - | list{} => b - | list{a} => list{f(a), ...b} - | a => - O.fmap( - concat'(b), - O.bind(init(a), x => - O.fmap(F.flip(append, x), O.fmap(fmap(f), O.fmap(singleton, last(a)))) - ), - ) |> O.default(xs) - } - } - - let without = (exclude, xs) => reject(x => contains(x, exclude), xs) - let update = (x, i, xs) => adjust(F.always(x), i, xs) - let iter = List.iter - - let findIndex = { - let rec loop = (pred, xs, i) => - switch xs { - | list{} => None - | list{a, ...b} => pred(a) ? Some(i) : loop(pred, b, i + 1) - } - (pred, xs) => loop(pred, xs, 0) - } - - let headSafe = Belt.List.head - let tailSafe = Belt.List.tail - let headExn = Belt.List.headExn - let tailExn = Belt.List.tailExn - let zip = Belt.List.zip - - let combinations2: list<'a> => list<('a, 'a)> = xs => { - let rec loop: ('a, list<'a>) => list<('a, 'a)> = (x', xs') => { - let n = length(xs') - if n == 0 { - list{} - } else { - let combs = fmap(y => (x', y), xs') - let hd = headExn(xs') - let tl = tailExn(xs') - concat(list{combs, loop(hd, tl)}) - } - } - switch (headSafe(xs), tailSafe(xs)) { - | (Some(x'), Some(xs')) => loop(x', xs') - | (_, _) => list{} - } - } -} - -/* A for Array */ -module A = { - let fmap = Array.map - let fmapi = Array.mapi - let to_list = Array.to_list - let of_list = Array.of_list - let length = Array.length - let append = Array.append - // let empty = [||]; - let unsafe_get = Array.unsafe_get - let get = Belt.Array.get - let getBy = Belt.Array.getBy - let getIndexBy = Belt.Array.getIndexBy - let last = a => get(a, length(a) - 1) - let first = get(_, 0) - let hasBy = (r, fn) => Belt.Array.getBy(r, fn) |> O.isSome - let fold_left = Array.fold_left - let fold_right = Array.fold_right - let concat = Belt.Array.concat - let concatMany = Belt.Array.concatMany - let keepMap = Belt.Array.keepMap - let slice = Belt.Array.slice - let init = Array.init - let reduce = Belt.Array.reduce - let reduceReverse = Belt.Array.reduceReverse - let reducei = Belt.Array.reduceWithIndex - let some = Belt.Array.some - let isEmpty = r => length(r) < 1 - let stableSortBy = Belt.SortArray.stableSortBy - let toNoneIfEmpty = r => isEmpty(r) ? None : Some(r) - let toRanges = (a: array<'a>) => - switch a |> Belt.Array.length { - | 0 - | 1 => - Belt.Result.Error("Must be at least 2 elements") - | n => - Belt.Array.makeBy(n - 1, r => r) - |> Belt.Array.map(_, index => ( - Belt.Array.getUnsafe(a, index), - Belt.Array.getUnsafe(a, index + 1), - )) - |> (x => Ok(x)) - } - - let getByFmap = (a, fn, boolCondition) => { - let i = ref(0) - let finalFunctionValue = ref(None) - let length = Belt.Array.length(a) - - while i.contents < length && finalFunctionValue.contents == None { - let itemWithFnApplied = Belt.Array.getUnsafe(a, i.contents) |> fn - if boolCondition(itemWithFnApplied) { - finalFunctionValue := Some(itemWithFnApplied) - } - i := i.contents + 1 - } - - finalFunctionValue.contents - } - - let tail = Belt.Array.sliceToEnd(_, 1) - - let zip = Belt.Array.zip - let unzip = Belt.Array.unzip - let zip3 = (a, b, c) => - Belt.Array.zip(a, b)->Belt.Array.zip(c)->Belt.Array.map((((v1, v2), v3)) => (v1, v2, v3)) - // This zips while taking the longest elements of each array. - let zipMaxLength = (array1, array2) => { - let maxLength = Int.max(length(array1), length(array2)) - let result = maxLength |> Belt.Array.makeUninitializedUnsafe - for i in 0 to maxLength - 1 { - Belt.Array.set(result, i, (get(array1, i), get(array2, i))) |> ignore - } - result - } - - let asList = (f: list<'a> => list<'a>, r: array<'a>) => r |> to_list |> f |> of_list - /* TODO: Is there a better way of doing this? */ - let uniq = r => asList(L.uniq, r) - - //intersperse([1,2,3], [10,11,12]) => [1,10,2,11,3,12] - let intersperse = (a: array<'a>, b: array<'a>) => { - let items: ref> = ref([]) - - Belt.Array.forEachWithIndex(a, (i, item) => - switch Belt.Array.get(b, i) { - | Some(r) => items := append(items.contents, [item, r]) - | None => items := append(items.contents, [item]) - } - ) - items.contents - } - - // This is like map, but - //accumulate((a,b) => a + b, [1,2,3]) => [1, 3, 5] - let accumulate = (fn: ('a, 'a) => 'a, items: array<'a>) => { - let length = items |> length - let empty = Belt.Array.make(length, items |> unsafe_get(_, 0)) - Belt.Array.forEachWithIndex(items, (index, element) => { - let item = switch index { - | 0 => element - | index => fn(element, unsafe_get(empty, index - 1)) - } - let _ = Belt.Array.set(empty, index, item) - }) - empty - } - - // @todo: Is -1 still the indicator that this is false (as is true with - // @todo: js findIndex)? Wasn't sure. - let findIndex = (e, i) => - Js.Array.findIndex(e, i) |> ( - r => - switch r { - | -1 => None - | r => Some(r) - } - ) - let filter = Js.Array.filter - let joinWith = Js.Array.joinWith - let transpose = (xs: array>): array> => { - let arr: array> = [] - for i in 0 to length(xs) - 1 { - for j in 0 to length(xs[i]) - 1 { - if Js.Array.length(arr) <= j { - ignore(Js.Array.push([xs[i][j]], arr)) - } else { - ignore(Js.Array.push(xs[i][j], arr[j])) - } - } - } - arr - } - - let all = (p: 'a => bool, xs: array<'a>): bool => length(filter(p, xs)) == length(xs) - let any = (p: 'a => bool, xs: array<'a>): bool => length(filter(p, xs)) > 0 - - module O = { - let concatSomes = (optionals: array>): array<'a> => - optionals - |> Js.Array.filter(O.isSome) - |> Js.Array.map(O.toExn("Warning: This should not have happened")) - let defaultEmpty = (o: option>): array<'a> => - switch o { - | Some(o) => o - | None => [] - } - // REturns `None` there are no non-`None` elements - let rec arrSomeToSomeArr = (optionals: array>): option> => { - let optionals' = optionals->Belt.List.fromArray - switch optionals' { - | list{} => []->Some - | list{x, ...xs} => - switch x { - | Some(_) => xs->Belt.List.toArray->arrSomeToSomeArr - | None => None - } - } - } - let firstSome = x => Belt.Array.getBy(x, O.isSome) - - let firstSomeFn = (r: array option<'a>>): option<'a> => - O.flatten(getByFmap(r, l => l(), O.isSome)) - - let firstSomeFnWithDefault = (r, default) => firstSomeFn(r)->O2.default(default) - - let openIfAllSome = (optionals: array>): option> => { - if all(O.isSome, optionals) { - Some(optionals |> fmap(O.toExn("Warning: This should not have happened"))) - } else { - None - } - } - } - - module R = { - let firstErrorOrOpen = (results: array>): Belt.Result.t< - array<'a>, - 'b, - > => { - let bringErrorUp = switch results |> Belt.Array.getBy(_, Belt.Result.isError) { - | Some(Belt.Result.Error(err)) => Belt.Result.Error(err) - | Some(Belt.Result.Ok(_)) => Belt.Result.Ok(results) - | None => Belt.Result.Ok(results) - } - let forceOpen = (r: array>): array<'a> => - r |> Belt.Array.map(_, r => Belt.Result.getExn(r)) - bringErrorUp |> Belt.Result.map(_, forceOpen) - } - let filterOk = (x: array>): array<'a> => fmap(R.toOption, x)->O.concatSomes - - let forM = (x: array<'a>, fn: 'a => result<'b, 'c>): result, 'c> => - firstErrorOrOpen(fmap(fn, x)) - - let foldM = (fn: ('c, 'a) => result<'b, 'e>, init: 'c, x: array<'a>): result<'c, 'e> => { - let acc = ref(init) - let final = ref(Ok()) - let break = ref(false) - let i = ref(0) - - while break.contents != true && i.contents < length(x) { - switch fn(acc.contents, x[i.contents]) { - | Ok(r) => acc := r - | Error(err) => { - final := Error(err) - break := true - } - } - i := i.contents + 1 - } - switch final.contents { - | Ok(_) => Ok(acc.contents) - | Error(err) => Error(err) - } - } - } - - module Floats = { - type t = array - let mean = Jstat.mean - let geomean = Jstat.geomean - let mode = Jstat.mode - let variance = Jstat.variance - let stdev = Jstat.stdev - let sum = Jstat.sum - let product = Jstat.product - let random = Js.Math.random_int - - let floatCompare: (float, float) => int = compare - let sort = t => { - let r = t - r |> Array.fast_sort(floatCompare) - r - } - - let getNonFinite = (t: t) => Belt.Array.getBy(t, r => !Js.Float.isFinite(r)) - let getBelowZero = (t: t) => Belt.Array.getBy(t, r => r < 0.0) - - let isSorted = (t: t): bool => - if Array.length(t) < 1 { - true - } else { - reduce(zip(t, tail(t)), true, (acc, (first, second)) => acc && first < second) - } - - //Passing true for the exclusive parameter excludes both endpoints of the range. - //https://jstat.github.io/all.html - let percentile = (a, b) => Jstat.percentile(a, b, false) - - // Gives an array with all the differences between values - // diff([1,5,3,7]) = [4,-2,4] - let diff = (t: t): array => - Belt.Array.zipBy(t, Belt.Array.sliceToEnd(t, 1), (left, right) => right -. left) - - let cumSum = (t: t): array => accumulate((a, b) => a +. b, t) - let cumProd = (t: t): array => accumulate((a, b) => a *. b, t) - - exception RangeError(string) - let range = (min: float, max: float, n: int): array => - switch n { - | 0 => [] - | 1 => [min] - | 2 => [min, max] - | _ if min == max => Belt.Array.make(n, min) - | _ if n < 0 => raise(RangeError("n must be greater than 0")) - | _ if min > max => raise(RangeError("Min value is less then max value")) - | _ => - let diff = (max -. min) /. Belt.Float.fromInt(n - 1) - Belt.Array.makeBy(n, i => min +. Belt.Float.fromInt(i) *. diff) - } - - let min = Js.Math.minMany_float - let max = Js.Math.maxMany_float - - module Sorted = { - let min = first - let max = last - let range = (~min=min, ~max=max, a) => - switch (min(a), max(a)) { - | (Some(min), Some(max)) => Some(max -. min) - | _ => None - } - - let binarySearchFirstElementGreaterIndex = (ar: array<'a>, el: 'a) => { - let el = Belt.SortArray.binarySearchBy(ar, el, floatCompare) - let el = el < 0 ? el * -1 - 1 : el - switch el { - | e if e >= length(ar) => #overMax - | e if e == 0 => #underMin - | e => #firstHigher(e) - } - } - - let concat = (t1: array<'a>, t2: array<'a>) => Belt.Array.concat(t1, t2)->sort - - let concatMany = (t1: array>) => Belt.Array.concatMany(t1)->sort - - let makeIncrementalUp = (a, b) => - Array.make(b - a + 1, a) |> Array.mapi((i, c) => c + i) |> Belt.Array.map(_, float_of_int) - - let makeIncrementalDown = (a, b) => - Array.make(a - b + 1, a) |> Array.mapi((i, c) => c - i) |> Belt.Array.map(_, float_of_int) - - /* - This function goes through a sorted array and divides it into two different clusters: - continuous samples and discrete samples. The discrete samples are stored in a mutable map. - Samples are thought to be discrete if they have any duplicates. - */ - let _splitContinuousAndDiscreteForDuplicates = (sortedArray: array) => { - let continuous: array = [] - let discrete = FloatFloatMap.empty() - Belt.Array.forEachWithIndex(sortedArray, (index, element) => { - let maxIndex = (sortedArray |> Array.length) - 1 - let possiblySimilarElements = switch index { - | 0 => [index + 1] - | n if n == maxIndex => [index - 1] - | _ => [index - 1, index + 1] - } |> Belt.Array.map(_, r => sortedArray[r]) - let hasSimilarElement = Belt.Array.some(possiblySimilarElements, r => r == element) - hasSimilarElement - ? FloatFloatMap.increment(element, discrete) - : { - let _ = Js.Array.push(element, continuous) - } - - () - }) - - (continuous, discrete) - } - - /* - This function works very similarly to splitContinuousAndDiscreteForDuplicates. The one major difference - is that you can specify a minDiscreteWeight. If the min discreet weight is 4, that would mean that - at least four elements needed from a specific value for that to be kept as discrete. This is important - because in some cases, we can expect that some common elements will be generated by regular operations. - The final continous array will be sorted. - */ - let splitContinuousAndDiscreteForMinWeight = ( - sortedArray: array, - ~minDiscreteWeight: int, - ) => { - let (continuous, discrete) = _splitContinuousAndDiscreteForDuplicates(sortedArray) - let keepFn = v => Belt.Float.toInt(v) >= minDiscreteWeight - let (discreteToKeep, discreteToIntegrate) = FloatFloatMap.partition( - ((_, v)) => keepFn(v), - discrete, - ) - let newContinousSamples = - discreteToIntegrate->FloatFloatMap.toArray - |> fmap(((k, v)) => Belt.Array.makeBy(Belt.Float.toInt(v), _ => k)) - |> Belt.Array.concatMany - let newContinuous = concat(continuous, newContinousSamples) - newContinuous |> Array.fast_sort(floatCompare) - (newContinuous, discreteToKeep) - } - } - } - module Sorted = Floats.Sorted -} - -module A2 = { - let fmap = (a, b) => A.fmap(b, a) - let fmapi = (a, b) => A.fmapi(b, a) - let joinWith = (a, b) => A.joinWith(b, a) - let filter = (a, b) => A.filter(b, a) -} - -module JsArray = { - let concatSomes = (optionals: Js.Array.t>): Js.Array.t<'a> => - optionals - |> Js.Array.filter(O.isSome) - |> Js.Array.map(O.toExn("Warning: This should not have happened")) - let filter = Js.Array.filter -} - -module Dict = { - type t<'a> = Js.Dict.t<'a> - let get = Js.Dict.get - let keys = Js.Dict.keys - let fromArray = Js.Dict.fromArray - let toArray = Js.Dict.entries - let concat = (a, b) => A.concat(toArray(a), toArray(b))->fromArray - let concatMany = ts => ts->A2.fmap(toArray)->A.concatMany->fromArray -} From 8b4ea5079ac7892044a95e5ee176dc1f4abc99ef Mon Sep 17 00:00:00 2001 From: Ozzie Gooen Date: Sun, 11 Sep 2022 19:28:26 -0700 Subject: [PATCH 37/55] Added @berekuk as codeowner. --- .github/CODEOWNERS | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 728a8c1c..13175cfc 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -9,22 +9,22 @@ # This also holds true for GitHub teams. # Rescript -*.res @OAGr -*.resi @OAGr +*.res @berekuk @OAGr +*.resi @berekuk @OAGr # Typescript -*.tsx @Hazelfire @OAGr -*.ts @Hazelfire @OAGr +*.tsx @Hazelfire @berekuk @OAGr +*.ts @Hazelfire @berekuk @OAGr # Javascript -*.js @Hazelfire @OAGr +*.js @Hazelfire @berekuk @OAGr # Any opsy files -.github/** @quinn-dougherty @OAGr -*.json @quinn-dougherty @Hazelfire @OAGr -*.y*ml @quinn-dougherty @OAGr -*.config.js @Hazelfire @OAGr -netlify.toml @quinn-dougherty @OAGr @Hazelfire +.github/** @quinn-doughert @berekuky @OAGr +*.json @quinn-dougherty @Hazelfire @berekuk @OAGr +*.y*ml @quinn-dougherty @berekuk @OAGr +*.config.js @Hazelfire @berekuk @OAGr +netlify.toml @quinn-dougherty @OAGr @berekuk @Hazelfire # Documentation *.md @quinn-dougherty @OAGr @Hazelfire From b49e8c43f0705834e11dd1a0ef9245e60bc17b07 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Mon, 12 Sep 2022 11:53:29 +0800 Subject: [PATCH 38/55] added another file to un.gitignore --- nix/squiggle-lang.nix | 1 + 1 file changed, 1 insertion(+) diff --git a/nix/squiggle-lang.nix b/nix/squiggle-lang.nix index 4d855d7f..724533cf 100644 --- a/nix/squiggle-lang.nix +++ b/nix/squiggle-lang.nix @@ -75,6 +75,7 @@ rec { # custom gitignore so that the flake keeps build artefacts mv .gitignore GITIGNORE sed -i /Reducer_Peggy_GeneratedParser.js/d GITIGNORE + sed -i /ReducerProject_IncludeParser.js/d GITIGNORE sed -i /\*.bs.js/d GITIGNORE sed -i /\*.gen.ts/d GITIGNORE sed -i /\*.gen.tsx/d GITIGNORE From 7beff3f83481dc19132fc14580c61802b3748713 Mon Sep 17 00:00:00 2001 From: Quinn Dougherty Date: Mon, 12 Sep 2022 13:50:21 +0800 Subject: [PATCH 39/55] uncommented out most of the jobs --- .github/workflows/ci.yml | 250 +++++++++++++++++++-------------------- 1 file changed, 125 insertions(+), 125 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a2d0ef16..184ac544 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,26 +49,26 @@ jobs: with: paths: '["packages/cli/**"]' - # lang-lint: - # name: Language lint - # runs-on: ubuntu-latest - # needs: pre_check - # if: ${{ needs.pre_check.outputs.should_skip_lang != 'true' }} - # defaults: - # run: - # shell: bash - # working-directory: packages/squiggle-lang - # steps: - # - uses: actions/checkout@v3 - # - name: Install Dependencies - # run: cd ../../ && yarn - # - name: Check rescript lint - # run: yarn lint:rescript - # - name: Check javascript, typescript, and markdown lint - # uses: creyD/prettier_action@v4.2 - # with: - # dry: true - # prettier_options: --check packages/squiggle-lang + lang-lint: + name: Language lint + runs-on: ubuntu-latest + needs: pre_check + if: ${{ needs.pre_check.outputs.should_skip_lang != 'true' }} + defaults: + run: + shell: bash + working-directory: packages/squiggle-lang + steps: + - uses: actions/checkout@v3 + - name: Install Dependencies + run: cd ../../ && yarn + - name: Check rescript lint + run: yarn lint:rescript + - name: Check javascript, typescript, and markdown lint + uses: creyD/prettier_action@v4.2 + with: + dry: true + prettier_options: --check packages/squiggle-lang lang-build-test-bundle: name: Language build, test, and bundle @@ -98,96 +98,96 @@ jobs: - name: Upload typescript coverage report run: yarn coverage:ts:ci - # components-lint: - # name: Components lint - # runs-on: ubuntu-latest - # needs: pre_check - # if: ${{ needs.pre_check.outputs.should_skip_components != 'true' }} - # defaults: - # run: - # shell: bash - # working-directory: packages/components - # steps: - # - uses: actions/checkout@v3 - # - name: Check javascript, typescript, and markdown lint - # uses: creyD/prettier_action@v4.2 - # with: - # dry: true - # prettier_options: --check packages/components --ignore-path packages/components/.prettierignore - # - # components-bundle-build: - # name: Components bundle and build - # runs-on: ubuntu-latest - # needs: pre_check - # if: ${{ (needs.pre_check.outputs.should_skip_components != 'true') || (needs.pre_check.outputs.should_skip_lang != 'true') }} - # defaults: - # run: - # shell: bash - # working-directory: packages/components - # steps: - # - uses: actions/checkout@v3 - # - name: Install dependencies from monorepo level - # run: cd ../../ && yarn - # - name: Build rescript codebase in squiggle-lang - # run: cd ../squiggle-lang && yarn build - # - name: Run webpack - # run: yarn bundle - # - name: Build storybook - # run: yarn build + components-lint: + name: Components lint + runs-on: ubuntu-latest + needs: pre_check + if: ${{ needs.pre_check.outputs.should_skip_components != 'true' }} + defaults: + run: + shell: bash + working-directory: packages/components + steps: + - uses: actions/checkout@v3 + - name: Check javascript, typescript, and markdown lint + uses: creyD/prettier_action@v4.2 + with: + dry: true + prettier_options: --check packages/components --ignore-path packages/components/.prettierignore - # website-lint: - # name: Website lint - # runs-on: ubuntu-latest - # needs: pre_check - # if: ${{ needs.pre_check.outputs.should_skip_website != 'true' }} - # defaults: - # run: - # shell: bash - # working-directory: packages/website - # steps: - # - uses: actions/checkout@v3 - # - name: Check javascript, typescript, and markdown lint - # uses: creyD/prettier_action@v4.2 - # with: - # dry: true - # prettier_options: --check packages/website - # - # website-build: - # name: Website build - # runs-on: ubuntu-latest - # needs: pre_check - # if: ${{ (needs.pre_check.outputs.should_skip_website != 'true') || (needs.pre_check.outputs.should_skip_lang != 'true') || (needs.pre_check.outputs.should_skip_components != 'true') }} - # defaults: - # run: - # shell: bash - # working-directory: packages/website - # steps: - # - uses: actions/checkout@v3 - # - name: Install dependencies from monorepo level - # run: cd ../../ && yarn - # - name: Build rescript in squiggle-lang - # run: cd ../squiggle-lang && yarn build - # - name: Build components - # run: cd ../components && yarn build - # - name: Build website assets - # run: yarn build - # - # vscode-ext-lint: - # name: VS Code extension lint - # runs-on: ubuntu-latest - # needs: pre_check - # if: ${{ needs.pre_check.outputs.should_skip_vscodeext != 'true' }} - # defaults: - # run: - # shell: bash - # working-directory: packages/vscode-ext - # steps: - # - uses: actions/checkout@v3 - # - name: Check javascript, typescript, and markdown lint - # uses: creyD/prettier_action@v4.2 - # with: - # dry: true - # prettier_options: --check packages/vscode-ext + components-bundle-build: + name: Components bundle and build + runs-on: ubuntu-latest + needs: pre_check + if: ${{ (needs.pre_check.outputs.should_skip_components != 'true') || (needs.pre_check.outputs.should_skip_lang != 'true') }} + defaults: + run: + shell: bash + working-directory: packages/components + steps: + - uses: actions/checkout@v3 + - name: Install dependencies from monorepo level + run: cd ../../ && yarn + - name: Build rescript codebase in squiggle-lang + run: cd ../squiggle-lang && yarn build + - name: Run webpack + run: yarn bundle + - name: Build storybook + run: yarn build + + website-lint: + name: Website lint + runs-on: ubuntu-latest + needs: pre_check + if: ${{ needs.pre_check.outputs.should_skip_website != 'true' }} + defaults: + run: + shell: bash + working-directory: packages/website + steps: + - uses: actions/checkout@v3 + - name: Check javascript, typescript, and markdown lint + uses: creyD/prettier_action@v4.2 + with: + dry: true + prettier_options: --check packages/website + + website-build: + name: Website build + runs-on: ubuntu-latest + needs: pre_check + if: ${{ (needs.pre_check.outputs.should_skip_website != 'true') || (needs.pre_check.outputs.should_skip_lang != 'true') || (needs.pre_check.outputs.should_skip_components != 'true') }} + defaults: + run: + shell: bash + working-directory: packages/website + steps: + - uses: actions/checkout@v3 + - name: Install dependencies from monorepo level + run: cd ../../ && yarn + - name: Build rescript in squiggle-lang + run: cd ../squiggle-lang && yarn build + - name: Build components + run: cd ../components && yarn build + - name: Build website assets + run: yarn build + + vscode-ext-lint: + name: VS Code extension lint + runs-on: ubuntu-latest + needs: pre_check + if: ${{ needs.pre_check.outputs.should_skip_vscodeext != 'true' }} + defaults: + run: + shell: bash + working-directory: packages/vscode-ext + steps: + - uses: actions/checkout@v3 + - name: Check javascript, typescript, and markdown lint + uses: creyD/prettier_action@v4.2 + with: + dry: true + prettier_options: --check packages/vscode-ext vscode-ext-build: name: VS Code extension build @@ -204,19 +204,19 @@ jobs: run: cd ../../ && yarn - name: Build run: yarn compile -# cli-lint: -# name: CLI lint -# runs-on: ubuntu-latest -# needs: pre_check -# if: ${{ needs.pre_check.outputs.should_skip_cli != 'true' }} -# defaults: -# run: -# shell: bash -# working-directory: packages/cli -# steps: -# - uses: actions/checkout@v3 -# - name: Check javascript, typescript, and markdown lint -# uses: creyD/prettier_action@v4.2 -# with: -# dry: true -# prettier_options: --check packages/cli + cli-lint: + name: CLI lint + runs-on: ubuntu-latest + needs: pre_check + if: ${{ needs.pre_check.outputs.should_skip_cli != 'true' }} + defaults: + run: + shell: bash + working-directory: packages/cli + steps: + - uses: actions/checkout@v3 + - name: Check javascript, typescript, and markdown lint + uses: creyD/prettier_action@v4.2 + with: + dry: true + prettier_options: --check packages/cli From e5717009445b41d82ad526c42f494ec6698924de Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Sep 2022 07:14:42 +0000 Subject: [PATCH 40/55] :arrow_up: Bump postcss-import from 14.1.0 to 15.0.0 Bumps [postcss-import](https://github.com/postcss/postcss-import) from 14.1.0 to 15.0.0. - [Release notes](https://github.com/postcss/postcss-import/releases) - [Changelog](https://github.com/postcss/postcss-import/blob/master/CHANGELOG.md) - [Commits](https://github.com/postcss/postcss-import/compare/14.1.0...15.0.0) --- updated-dependencies: - dependency-name: postcss-import dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- packages/components/package.json | 2 +- yarn.lock | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index 9e027f37..40522095 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -46,7 +46,7 @@ "cross-env": "^7.0.3", "mini-css-extract-plugin": "^2.6.1", "postcss-cli": "^10.0.0", - "postcss-import": "^14.1.0", + "postcss-import": "^15.0.0", "postcss-loader": "^7.0.1", "postcss-nesting": "^10.1.10", "react": "^18.1.0", diff --git a/yarn.lock b/yarn.lock index 4635c0e5..944332d4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4805,9 +4805,9 @@ "@types/react" "*" "@types/react@*", "@types/react@^18.0.1", "@types/react@^18.0.18": - version "18.0.18" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.18.tgz#9f16f33d57bc5d9dca848d12c3572110ff9429ac" - integrity sha512-6hI08umYs6NaiHFEEGioXnxJ+oEhY3eRz8VCUaudZmGdtvPviCJB8mgaMxaDWAdPSYd4eFavrPk2QIolwbLYrg== + version "18.0.19" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.19.tgz#269a5f35b9a73c69dfb0c7189017013ab02acbaa" + integrity sha512-BDc3Q+4Q3zsn7k9xZrKfjWyJsSlEDMs38gD1qp2eDazLCdcPqAT+vq1ND+Z8AGel/UiwzNUk8ptpywgNQcJ1MQ== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -13980,6 +13980,15 @@ postcss-import@^14.1.0: read-cache "^1.0.0" resolve "^1.1.7" +postcss-import@^15.0.0: + version "15.0.0" + resolved "https://registry.yarnpkg.com/postcss-import/-/postcss-import-15.0.0.tgz#0b66c25fdd9c0d19576e63c803cf39e4bad08822" + integrity sha512-Y20shPQ07RitgBGv2zvkEAu9bqvrD77C9axhj/aA1BQj4czape2MdClCExvB27EwYEJdGgKZBpKanb0t1rK2Kg== + dependencies: + postcss-value-parser "^4.0.0" + read-cache "^1.0.0" + resolve "^1.1.7" + postcss-initial@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/postcss-initial/-/postcss-initial-4.0.1.tgz#529f735f72c5724a0fb30527df6fb7ac54d7de42" From 28310168cbe655c05a5abacf3b7e694e436e1f8c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Sep 2022 14:31:47 +0000 Subject: [PATCH 41/55] :arrow_up: Bump react-hook-form from 7.34.2 to 7.35.0 Bumps [react-hook-form](https://github.com/react-hook-form/react-hook-form) from 7.34.2 to 7.35.0. - [Release notes](https://github.com/react-hook-form/react-hook-form/releases) - [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md) - [Commits](https://github.com/react-hook-form/react-hook-form/compare/v7.34.2...v7.35.0) --- updated-dependencies: - dependency-name: react-hook-form dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- packages/components/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index 40522095..a48c999f 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -15,7 +15,7 @@ "lodash": "^4.17.21", "react": "^18.1.0", "react-ace": "^10.1.0", - "react-hook-form": "^7.34.2", + "react-hook-form": "^7.35.0", "react-use": "^17.4.0", "react-vega": "^7.6.0", "vega": "^5.22.1", diff --git a/yarn.lock b/yarn.lock index 944332d4..cece7280 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14968,10 +14968,10 @@ react-helmet-async@*, react-helmet-async@^1.3.0: react-fast-compare "^3.2.0" shallowequal "^1.1.0" -react-hook-form@^7.34.2: - version "7.34.2" - resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.34.2.tgz#9ac6d1a309a7c4aaa369d1269357a70e9e9bf4de" - integrity sha512-1lYWbEqr0GW7HHUjMScXMidGvV0BE2RJV3ap2BL7G0EJirkqpccTaawbsvBO8GZaB3JjCeFBEbnEWI1P8ZoLRQ== +react-hook-form@^7.35.0: + version "7.35.0" + resolved "https://registry.yarnpkg.com/react-hook-form/-/react-hook-form-7.35.0.tgz#b133de48fc84b1e62f9277ba79dfbacd9bb13dd3" + integrity sha512-9CYdOed+Itbiu5VMVxW0PK9mBR3f0gDGJcZEyUSm0eJbDymQ913TRs2gHcQZZmfTC+rtxyDFRuelMxx/+xwMcw== react-inspector@^5.1.0: version "5.1.1" From 565bcf83314e5a0eef82e575a4f585a8e062b66f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Sep 2022 14:32:19 +0000 Subject: [PATCH 42/55] :arrow_up: Bump mathjs from 11.1.0 to 11.2.0 Bumps [mathjs](https://github.com/josdejong/mathjs) from 11.1.0 to 11.2.0. - [Release notes](https://github.com/josdejong/mathjs/releases) - [Changelog](https://github.com/josdejong/mathjs/blob/develop/HISTORY.md) - [Commits](https://github.com/josdejong/mathjs/compare/v11.1.0...v11.2.0) --- updated-dependencies: - dependency-name: mathjs dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- packages/squiggle-lang/package.json | 2 +- yarn.lock | 19 ++++++------------- 2 files changed, 7 insertions(+), 14 deletions(-) diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index 15f126d3..8b651d0f 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -45,7 +45,7 @@ "@stdlib/stats": "^0.0.13", "jstat": "^1.9.5", "lodash": "^4.17.21", - "mathjs": "^11.1.0", + "mathjs": "^11.2.0", "pdfast": "^0.2.0" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index 944332d4..57e1fb5a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1490,14 +1490,7 @@ core-js-pure "^3.20.2" regenerator-runtime "^0.13.4" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.9", "@babel/runtime@^7.5.0", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.18.9.tgz#b4fcfce55db3d2e5e080d2490f608a3b9f407f4a" - integrity sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw== - dependencies: - regenerator-runtime "^0.13.4" - -"@babel/runtime@^7.10.3", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.18.6": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.12.5", "@babel/runtime@^7.15.4", "@babel/runtime@^7.16.3", "@babel/runtime@^7.17.8", "@babel/runtime@^7.18.6", "@babel/runtime@^7.18.9", "@babel/runtime@^7.19.0", "@babel/runtime@^7.5.0", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": version "7.19.0" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.19.0.tgz#22b11c037b094d27a8a2504ea4dcff00f50e2259" integrity sha512-eR8Lo9hnDS7tqkO7NsV+mKvCmv5boaXFSZ70DnfhcgiEne8hv9oCEd36Klw74EtizEqLsy4YnW8UWwpBVolHZA== @@ -12353,12 +12346,12 @@ markdown-it@^8.3.1: mdurl "^1.0.1" uc.micro "^1.0.5" -mathjs@^11.0.1, mathjs@^11.1.0: - version "11.1.0" - resolved "https://registry.yarnpkg.com/mathjs/-/mathjs-11.1.0.tgz#501fc1b8d66155442ce7762bf04469168d38587c" - integrity sha512-cbsEruLNoIlj5h5vOF+DUQVe4EsA/WNomSQDMnX2WafX9TLneBSCRMx2okgGnSLzLoMGWQ211KVzY55bEnQa8Q== +mathjs@^11.0.1, mathjs@^11.2.0: + version "11.2.0" + resolved "https://registry.yarnpkg.com/mathjs/-/mathjs-11.2.0.tgz#06ade7425287bf69c3210158853996a55861e07e" + integrity sha512-4x1LUP1tkNWWvaZiPO+rF9rKE5q4o541FF4m8ZIk1PlmSyHDGRAKutjA67rICK4DXWEY1gpumPOvaq3xuQHT6Q== dependencies: - "@babel/runtime" "^7.18.9" + "@babel/runtime" "^7.19.0" complex.js "^2.1.1" decimal.js "^10.4.0" escape-latex "^1.2.0" From 20654c4f082a8acc202022c782dd29a3507cc86b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Sep 2022 14:32:53 +0000 Subject: [PATCH 43/55] :arrow_up: Bump fast-check from 3.1.2 to 3.1.3 Bumps [fast-check](https://github.com/dubzzz/fast-check/tree/HEAD/packages/fast-check) from 3.1.2 to 3.1.3. - [Release notes](https://github.com/dubzzz/fast-check/releases) - [Changelog](https://github.com/dubzzz/fast-check/blob/main/packages/fast-check/CHANGELOG.md) - [Commits](https://github.com/dubzzz/fast-check/commits/v3.1.3/packages/fast-check) --- updated-dependencies: - dependency-name: fast-check dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- packages/squiggle-lang/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index 15f126d3..cfd60c93 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -56,7 +56,7 @@ "bisect_ppx": "^2.7.1", "chalk": "^5.0.1", "codecov": "^3.8.3", - "fast-check": "^3.1.2", + "fast-check": "^3.1.3", "gentype": "^4.5.0", "jest": "^27.5.1", "moduleserve": "^0.9.1", diff --git a/yarn.lock b/yarn.lock index 944332d4..7fcaf9b7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9158,10 +9158,10 @@ fast-check@^2.17.0: dependencies: pure-rand "^5.0.1" -fast-check@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/fast-check/-/fast-check-3.1.2.tgz#1b09c3d856d425e06be9d39e9e23d1f6fa4a6d0e" - integrity sha512-OZRPFXhZHpIhtG46XtAMzVW1jtuR7Clw13wOcfw1v//tNnPCvVuLLlT1bEqywCQXNXR4qGT3tk7z0MUMSTit3Q== +fast-check@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-check/-/fast-check-3.1.3.tgz#134e5852e3c56b65e47a48b1a5022bee14c10ba3" + integrity sha512-IFY7xJrOUktiC1ZnaJdrinaRpFgDZtURRPwzAiOhL8eyt2NbBTHNF1CO7vZUla1BoUeJVI7gLnTQA+Lko0T2dQ== dependencies: pure-rand "^5.0.1" From 901ee9f2fd6b9c8268c6078744c95cefd0c830ce Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Sep 2022 14:34:46 +0000 Subject: [PATCH 44/55] :arrow_up: Bump webpack-dev-server from 4.10.1 to 4.11.0 Bumps [webpack-dev-server](https://github.com/webpack/webpack-dev-server) from 4.10.1 to 4.11.0. - [Release notes](https://github.com/webpack/webpack-dev-server/releases) - [Changelog](https://github.com/webpack/webpack-dev-server/blob/master/CHANGELOG.md) - [Commits](https://github.com/webpack/webpack-dev-server/compare/v4.10.1...v4.11.0) --- updated-dependencies: - dependency-name: webpack-dev-server dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- packages/components/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index 40522095..6b445420 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -59,7 +59,7 @@ "web-vitals": "^3.0.1", "webpack": "^5.74.0", "webpack-cli": "^4.10.0", - "webpack-dev-server": "^4.10.0" + "webpack-dev-server": "^4.11.0" }, "peerDependencies": { "react": "^16.8.0 || ^17 || ^18", diff --git a/yarn.lock b/yarn.lock index 944332d4..a249bf24 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18514,10 +18514,10 @@ webpack-dev-middleware@^5.3.1: range-parser "^1.2.1" schema-utils "^4.0.0" -webpack-dev-server@^4.10.0, webpack-dev-server@^4.6.0, webpack-dev-server@^4.9.3: - version "4.10.1" - resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.10.1.tgz#124ac9ac261e75303d74d95ab6712b4aec3e12ed" - integrity sha512-FIzMq3jbBarz3ld9l7rbM7m6Rj1lOsgq/DyLGMX/fPEB1UBUPtf5iL/4eNfhx8YYJTRlzfv107UfWSWcBK5Odw== +webpack-dev-server@^4.11.0, webpack-dev-server@^4.6.0, webpack-dev-server@^4.9.3: + version "4.11.0" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-4.11.0.tgz#290ee594765cd8260adfe83b2d18115ea04484e7" + integrity sha512-L5S4Q2zT57SK7tazgzjMiSMBdsw+rGYIX27MgPgx7LDhWO0lViPrHKoLS7jo5In06PWYAhlYu3PbyoC6yAThbw== dependencies: "@types/bonjour" "^3.5.9" "@types/connect-history-api-fallback" "^1.3.5" From 159f8721d835d3d673307e48b58eadfbdcb997b1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Sep 2022 14:35:58 +0000 Subject: [PATCH 45/55] :arrow_up: Bump @headlessui/react from 1.6.6 to 1.7.0 Bumps [@headlessui/react](https://github.com/tailwindlabs/headlessui/tree/HEAD/packages/@headlessui-react) from 1.6.6 to 1.7.0. - [Release notes](https://github.com/tailwindlabs/headlessui/releases) - [Changelog](https://github.com/tailwindlabs/headlessui/blob/main/packages/@headlessui-react/CHANGELOG.md) - [Commits](https://github.com/tailwindlabs/headlessui/commits/@headlessui/react@v1.7.0/packages/@headlessui-react) --- updated-dependencies: - dependency-name: "@headlessui/react" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- packages/components/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index 40522095..00445e5e 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -5,7 +5,7 @@ "dependencies": { "@floating-ui/react-dom": "^1.0.0", "@floating-ui/react-dom-interactions": "^0.9.3", - "@headlessui/react": "^1.6.6", + "@headlessui/react": "^1.7.0", "@heroicons/react": "^1.0.6", "@hookform/resolvers": "^2.9.7", "@quri/squiggle-lang": "^0.4.1", diff --git a/yarn.lock b/yarn.lock index 944332d4..04795955 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2200,10 +2200,10 @@ dependencies: "@hapi/hoek" "^9.0.0" -"@headlessui/react@^1.6.6": - version "1.6.6" - resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.6.6.tgz#3073c066b85535c9d28783da0a4d9288b5354d0c" - integrity sha512-MFJtmj9Xh/hhBMhLccGbBoSk+sk61BlP6sJe4uQcVMtXZhCgGqd2GyIQzzmsdPdTEWGSF434CBi8mnhR6um46Q== +"@headlessui/react@^1.7.0": + version "1.7.0" + resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.7.0.tgz#7e36e6bbc25a24b02011527ae157a000dda88b85" + integrity sha512-/nDsijOXRwXVLpUBEiYuWguIBSIN3ZbKyah+KPUiD8bdIKtX1U/k+qLYUEr7NCQnSF2e4w1dr8me42ECuG3cvw== "@heroicons/react@^1.0.6": version "1.0.6" From ae130bbef4c657a61cdb62092a57f61fb6b42cea Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Sep 2022 14:37:48 +0000 Subject: [PATCH 46/55] :arrow_up: Bump @hookform/resolvers from 2.9.7 to 2.9.8 Bumps [@hookform/resolvers](https://github.com/react-hook-form/resolvers) from 2.9.7 to 2.9.8. - [Release notes](https://github.com/react-hook-form/resolvers/releases) - [Commits](https://github.com/react-hook-form/resolvers/compare/v2.9.7...v2.9.8) --- updated-dependencies: - dependency-name: "@hookform/resolvers" dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- packages/components/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index 40522095..1e2e2054 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -7,7 +7,7 @@ "@floating-ui/react-dom-interactions": "^0.9.3", "@headlessui/react": "^1.6.6", "@heroicons/react": "^1.0.6", - "@hookform/resolvers": "^2.9.7", + "@hookform/resolvers": "^2.9.8", "@quri/squiggle-lang": "^0.4.1", "@react-hook/size": "^2.1.2", "clsx": "^1.2.1", diff --git a/yarn.lock b/yarn.lock index 944332d4..70e5783c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2210,10 +2210,10 @@ resolved "https://registry.yarnpkg.com/@heroicons/react/-/react-1.0.6.tgz#35dd26987228b39ef2316db3b1245c42eb19e324" integrity sha512-JJCXydOFWMDpCP4q13iEplA503MQO3xLoZiKum+955ZCtHINWnx26CUxVxxFQu/uLb4LW3ge15ZpzIkXKkJ8oQ== -"@hookform/resolvers@^2.9.7": - version "2.9.7" - resolved "https://registry.yarnpkg.com/@hookform/resolvers/-/resolvers-2.9.7.tgz#8b257ae67234ce0270e6b044c1a61fb98ec02b4b" - integrity sha512-BloehX3MOLwuFEwT4yZnmolPjVmqyn8VsSuodLfazbCIqxBHsQ4qUZsi+bvNNCduRli1AGWFrkDLGD5QoNzsoA== +"@hookform/resolvers@^2.9.8": + version "2.9.8" + resolved "https://registry.yarnpkg.com/@hookform/resolvers/-/resolvers-2.9.8.tgz#9af51d15602f3c6e3249714712d8275564e65b72" + integrity sha512-iVVjH0USq+1TqDdGkWe2M1x7Wn5OFPgVRo7CbWFsXTqqXqCaZtZcnzJu+UhljCWbthFWxWGXKLGYUDPZ04oVvQ== "@humanwhocodes/config-array@^0.10.4": version "0.10.4" From f41447c2634ef2c039e445a6718169c29aa17b85 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Sep 2022 14:38:30 +0000 Subject: [PATCH 47/55] :arrow_up: Bump @types/lodash from 4.14.184 to 4.14.185 Bumps [@types/lodash](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/lodash) from 4.14.184 to 4.14.185. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/lodash) --- updated-dependencies: - dependency-name: "@types/lodash" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- packages/components/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index 40522095..4ed6f4bd 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -38,7 +38,7 @@ "@testing-library/react": "^13.4.0", "@testing-library/user-event": "^14.4.3", "@types/jest": "^27.5.0", - "@types/lodash": "^4.14.184", + "@types/lodash": "^4.14.185", "@types/node": "^18.7.15", "@types/react": "^18.0.18", "@types/styled-components": "^5.1.26", diff --git a/yarn.lock b/yarn.lock index 944332d4..052e86c8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4676,10 +4676,10 @@ resolved "https://registry.yarnpkg.com/@types/katex/-/katex-0.11.1.tgz#34de04477dcf79e2ef6c8d23b41a3d81f9ebeaf5" integrity sha512-DUlIj2nk0YnJdlWgsFuVKcX27MLW0KbKmGVoUHmFr+74FYYNUDAaj9ZqTADvsbE8rfxuVmSFc7KczYn5Y09ozg== -"@types/lodash@^4.14.167", "@types/lodash@^4.14.175", "@types/lodash@^4.14.184": - version "4.14.184" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.184.tgz#23f96cd2a21a28e106dc24d825d4aa966de7a9fe" - integrity sha512-RoZphVtHbxPZizt4IcILciSWiC6dcn+eZ8oX9IWEYfDMcocdd42f7NPI6fQj+6zI8y4E0L7gu2pcZKLGTRaV9Q== +"@types/lodash@^4.14.167", "@types/lodash@^4.14.175", "@types/lodash@^4.14.185": + version "4.14.185" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.185.tgz#c9843f5a40703a8f5edfd53358a58ae729816908" + integrity sha512-evMDG1bC4rgQg4ku9tKpuMh5iBNEwNa3tf9zRHdP1qlv+1WUg44xat4IxCE14gIpZRGUUWAx2VhItCZc25NfMA== "@types/mdast@^3.0.0": version "3.0.10" From 60eba96172729a24724421049c849a8db716d990 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Sep 2022 14:39:54 +0000 Subject: [PATCH 48/55] :arrow_up: Bump typescript from 4.8.2 to 4.8.3 Bumps [typescript](https://github.com/Microsoft/TypeScript) from 4.8.2 to 4.8.3. - [Release notes](https://github.com/Microsoft/TypeScript/releases) - [Commits](https://github.com/Microsoft/TypeScript/compare/v4.8.2...v4.8.3) --- updated-dependencies: - dependency-name: typescript dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- packages/components/package.json | 2 +- packages/squiggle-lang/package.json | 2 +- packages/vscode-ext/package.json | 2 +- yarn.lock | 8 ++++---- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index 40522095..f422ad85 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -55,7 +55,7 @@ "tailwindcss": "^3.1.8", "ts-loader": "^9.3.0", "tsconfig-paths-webpack-plugin": "^4.0.0", - "typescript": "^4.8.2", + "typescript": "^4.8.3", "web-vitals": "^3.0.1", "webpack": "^5.74.0", "webpack-cli": "^4.10.0", diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index 15f126d3..7bcecde4 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -69,7 +69,7 @@ "ts-jest": "^27.1.4", "ts-loader": "^9.3.0", "ts-node": "^10.9.1", - "typescript": "^4.8.2", + "typescript": "^4.8.3", "webpack": "^5.74.0", "webpack-cli": "^4.10.0" }, diff --git a/packages/vscode-ext/package.json b/packages/vscode-ext/package.json index c3489450..45376860 100644 --- a/packages/vscode-ext/package.json +++ b/packages/vscode-ext/package.json @@ -131,7 +131,7 @@ "@types/vscode": "^1.70.0", "glob": "^8.0.3", "js-yaml": "^4.1.0", - "typescript": "^4.8.2", + "typescript": "^4.8.3", "vsce-yarn-patch": "^1.66.2" }, "dependencies": { diff --git a/yarn.lock b/yarn.lock index 944332d4..7400ce47 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17442,10 +17442,10 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== -typescript@^4.8.2: - version "4.8.2" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.2.tgz#e3b33d5ccfb5914e4eeab6699cf208adee3fd790" - integrity sha512-C0I1UsrrDHo2fYI5oaCGbSejwX4ch+9Y5jTQELvovfmFkK3HHSZJB8MSJcWLmCUBzQBchCrZ9rMRV6GuNrvGtw== +typescript@^4.8.3: + version "4.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.3.tgz#d59344522c4bc464a65a730ac695007fdb66dd88" + integrity sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig== ua-parser-js@^0.7.30: version "0.7.31" From b892a97e09ab2155f559e51814b156fec88b515d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Sep 2022 15:59:40 +0000 Subject: [PATCH 49/55] :arrow_up: Bump @types/node from 18.7.15 to 18.7.16 Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 18.7.15 to 18.7.16. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node) --- updated-dependencies: - dependency-name: "@types/node" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- packages/components/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index 342d73b4..18f511d4 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -39,7 +39,7 @@ "@testing-library/user-event": "^14.4.3", "@types/jest": "^27.5.0", "@types/lodash": "^4.14.185", - "@types/node": "^18.7.15", + "@types/node": "^18.7.16", "@types/react": "^18.0.18", "@types/styled-components": "^5.1.26", "@types/webpack": "^5.28.0", diff --git a/yarn.lock b/yarn.lock index 5f22f3e8..92f9b9b0 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4699,10 +4699,10 @@ "@types/node" "*" form-data "^3.0.0" -"@types/node@*", "@types/node@18.x", "@types/node@^18.7.15": - version "18.7.15" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.15.tgz#20ae1ec80c57ee844b469f968a1cd511d4088b29" - integrity sha512-XnjpaI8Bgc3eBag2Aw4t2Uj/49lLBSStHWfqKvIuXD7FIrZyMLWp8KuAFHAqxMZYTF9l08N1ctUn9YNybZJVmQ== +"@types/node@*", "@types/node@18.x", "@types/node@^18.7.16": + version "18.7.16" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.7.16.tgz#0eb3cce1e37c79619943d2fd903919fc30850601" + integrity sha512-EQHhixfu+mkqHMZl1R2Ovuvn47PUw18azMJOTwSZr9/fhzHNGXAJ0ma0dayRVchprpCj0Kc1K1xKoWaATWF1qg== "@types/node@^14.0.10 || ^16.0.0", "@types/node@^14.14.20 || ^16.0.0": version "16.11.56" From e72ac8a44f17ba150904a05a3bc87e4573842e9f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 12 Sep 2022 16:02:32 +0000 Subject: [PATCH 50/55] :arrow_up: Bump framer-motion from 7.2.1 to 7.3.2 Bumps [framer-motion](https://github.com/framer/motion) from 7.2.1 to 7.3.2. - [Release notes](https://github.com/framer/motion/releases) - [Changelog](https://github.com/framer/motion/blob/main/CHANGELOG.md) - [Commits](https://github.com/framer/motion/compare/v7.2.1...v7.3.2) --- updated-dependencies: - dependency-name: framer-motion dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- packages/components/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index 342d73b4..2f16fc46 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -11,7 +11,7 @@ "@quri/squiggle-lang": "^0.4.1", "@react-hook/size": "^2.1.2", "clsx": "^1.2.1", - "framer-motion": "^7.2.1", + "framer-motion": "^7.3.2", "lodash": "^4.17.21", "react": "^18.1.0", "react-ace": "^10.1.0", diff --git a/yarn.lock b/yarn.lock index 5f22f3e8..054731cd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9522,10 +9522,10 @@ fragment-cache@^0.2.1: dependencies: map-cache "^0.2.2" -framer-motion@^7.2.1: - version "7.2.1" - resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-7.2.1.tgz#0db5992ece791cb58357787ef9c29dd76281720d" - integrity sha512-bt2ZqqGpPsW6UojYUa5poWQJu3sDr4Dp3IZsdVBYdKUJ8p+9PxOk1fYRAT8lTGGmaC5HFoKrbDXQeKWGAKZz9g== +framer-motion@^7.3.2: + version "7.3.2" + resolved "https://registry.yarnpkg.com/framer-motion/-/framer-motion-7.3.2.tgz#9768092cd98cf0ebaf70864f1248f2e703305a15" + integrity sha512-BTG0BqJSwxoFBWpwaaxS/954DGZFsluF+dUv9Hfq53VNkwUt5g+wYTEM66oTUhiH/+6R/y0Rq+BmkUBcmzbyMQ== dependencies: "@motionone/dom" "10.13.1" framesync "6.1.2" From be934af68415da5ac45145ae95df0a466d54c4fd Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Tue, 13 Sep 2022 01:07:32 +0300 Subject: [PATCH 51/55] =?UTF-8?q?Revert=20"=E2=AC=86=EF=B8=8F=20Bump=20@he?= =?UTF-8?q?adlessui/react=20from=201.6.6=20to=201.7.0"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/components/package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index 342d73b4..74faad7a 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -5,7 +5,7 @@ "dependencies": { "@floating-ui/react-dom": "^1.0.0", "@floating-ui/react-dom-interactions": "^0.9.3", - "@headlessui/react": "^1.7.0", + "@headlessui/react": "^1.6.6", "@heroicons/react": "^1.0.6", "@hookform/resolvers": "^2.9.8", "@quri/squiggle-lang": "^0.4.1", diff --git a/yarn.lock b/yarn.lock index 5f22f3e8..b704068c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2193,10 +2193,10 @@ dependencies: "@hapi/hoek" "^9.0.0" -"@headlessui/react@^1.7.0": - version "1.7.0" - resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.7.0.tgz#7e36e6bbc25a24b02011527ae157a000dda88b85" - integrity sha512-/nDsijOXRwXVLpUBEiYuWguIBSIN3ZbKyah+KPUiD8bdIKtX1U/k+qLYUEr7NCQnSF2e4w1dr8me42ECuG3cvw== +"@headlessui/react@^1.6.6": + version "1.6.6" + resolved "https://registry.yarnpkg.com/@headlessui/react/-/react-1.6.6.tgz#3073c066b85535c9d28783da0a4d9288b5354d0c" + integrity sha512-MFJtmj9Xh/hhBMhLccGbBoSk+sk61BlP6sJe4uQcVMtXZhCgGqd2GyIQzzmsdPdTEWGSF434CBi8mnhR6um46Q== "@heroicons/react@^1.0.6": version "1.0.6" From 1b714f06335c4f67ad30486a4cb5c324c882e286 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Tue, 13 Sep 2022 03:55:59 +0400 Subject: [PATCH 52/55] fix sampleset -> pointset sorting sideeffects --- .../Distributions/SampleSetDist/SampleSetDist_ToPointSet.res | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res index ec2bf0d0..2836ca78 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res @@ -62,6 +62,7 @@ let toPointSetDist = ( ~samplingInputs: SamplingInputs.samplingInputs, (), ): Internals.Types.outputs => { + let samples = Js.Array2.copy(samples) Array.fast_sort(compare, samples) let minDiscreteToKeep = MagicNumbers.ToPointSet.minDiscreteToKeep(samples) let (continuousPart, discretePart) = E.A.Floats.Sorted.splitContinuousAndDiscreteForMinWeight( From 7b77dd09cf50fc97e855f5fc20fb481277013392 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Thu, 15 Sep 2022 00:07:16 +0400 Subject: [PATCH 53/55] v0.4.2 --- packages/squiggle-lang/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index 80c542f5..341270d2 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -1,6 +1,6 @@ { "name": "@quri/squiggle-lang", - "version": "0.4.1", + "version": "0.4.2", "homepage": "https://squiggle-language.com", "license": "MIT", "scripts": { From 8d268ec4335a6735f6ca6573371f18904efca95a Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Thu, 15 Sep 2022 00:11:39 +0400 Subject: [PATCH 54/55] v0.4.2 --- packages/components/package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index 22dfdcc5..91f49939 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@quri/squiggle-components", - "version": "0.4.1", + "version": "0.4.2", "license": "MIT", "dependencies": { "@floating-ui/react-dom": "^1.0.0", @@ -8,7 +8,7 @@ "@headlessui/react": "^1.6.6", "@heroicons/react": "^1.0.6", "@hookform/resolvers": "^2.9.8", - "@quri/squiggle-lang": "^0.4.1", + "@quri/squiggle-lang": "^0.4.2", "@react-hook/size": "^2.1.2", "clsx": "^1.2.1", "framer-motion": "^7.3.2", From a6b24cb9e57c0c342a3cfd4794f2219bb6b3614c Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Thu, 15 Sep 2022 00:24:46 +0400 Subject: [PATCH 55/55] vscode ext 0.4.2 --- packages/vscode-ext/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/vscode-ext/package.json b/packages/vscode-ext/package.json index 45376860..210b4a23 100644 --- a/packages/vscode-ext/package.json +++ b/packages/vscode-ext/package.json @@ -3,7 +3,7 @@ "displayName": "Squiggle", "description": "Squiggle language support", "license": "MIT", - "version": "0.4.1", + "version": "0.4.2", "publisher": "QURI", "repository": { "type": "git",