From 757d458ecfb9408e65fb8add56094ea3093aaf15 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Mon, 12 Sep 2022 13:33:20 +0400 Subject: [PATCH] more FR --- .../rescript/ForTS/ForTS_ReducerProject.res | 21 +- .../FunctionRegistry_Core.res | 33 +- .../FunctionRegistry_Helpers.res | 43 +- .../FunctionRegistry_Library.res | 7 + .../FunctionRegistry/Library/FR_Builtin.res | 82 ++-- .../FunctionRegistry/Library/FR_Danger.res | 59 +-- .../FunctionRegistry/Library/FR_Dict.res | 5 +- .../FunctionRegistry/Library/FR_Dist.res | 14 +- .../FunctionRegistry/Library/FR_Fn.res | 8 +- .../Library/FR_GenericDist.res | 412 ++++++++++++++++++ .../FunctionRegistry/Library/FR_List.res | 32 +- .../FunctionRegistry/Library/FR_Number.res | 6 +- .../FunctionRegistry/Library/FR_Pointset.res | 21 +- .../FunctionRegistry/Library/FR_Sampleset.res | 25 +- .../FunctionRegistry/Library/FR_Scoring.res | 6 +- .../FunctionRegistry/Library/FR_Units.res | 35 ++ .../Reducer_Bindings/Reducer_Bindings.res | 29 +- .../src/rescript/Reducer/Reducer_Context.res | 10 +- .../Reducer_Dispatch_BuiltIn.res | 30 +- .../Reducer_Dispatch_ChainPiece.res | 1 + .../Reducer_Dispatch/Reducer_Dispatch_T.res | 1 + .../Reducer_Expression/Reducer_Expression.res | 78 ++-- .../Reducer_Expression_ExpressionBuilder.res | 37 +- .../Reducer_Expression_Lambda.res | 20 +- .../Reducer_Expression_T.res | 16 +- .../Reducer_Peggy/Reducer_Peggy_Parse.res | 17 +- .../Reducer_Peggy_ToExpression.res | 19 +- .../src/rescript/Reducer/Reducer_T.res | 8 +- .../Reducer_Type/Reducer_Type_Compile.res | 1 + .../Reducer/Reducer_Type/Reducer_Type_T.res | 1 + .../Reducer_Type/Reducer_Type_TypeBuilder.res | 1 + .../Reducer_Type/Reducer_Type_TypeChecker.res | 1 + .../ReducerInterface_Date.res | 7 +- .../ReducerInterface_Duration.res | 5 +- .../ReducerInterface_ExternalLibrary.res | 2 +- .../ReducerInterface_GenericDistribution.res | 310 ------------- .../ReducerInterface_GenericDistribution.resi | 4 - ...ducerInterface_InternalExpressionValue.res | 9 +- .../ReducerInterface_Number.res | 45 -- .../ReducerInterface_StdLib.res | 117 ++--- .../ReducerProject/ReducerProject.res | 20 +- .../ReducerProject_IncludeParser.js | 298 +++++++++---- .../ReducerProject_ProjectAccessors_T.res | 1 + .../ReducerProject_ProjectItem.res | 52 +-- .../ReducerProject_Topology.res | 20 +- .../SquiggleLibrary/SquiggleLibrary_Math.res | 4 +- .../SquiggleLibrary_Versions.res | 4 +- .../src/rescript/Utility/Mathjs.res | 1 + 48 files changed, 1067 insertions(+), 911 deletions(-) create mode 100644 packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_GenericDist.res create mode 100644 packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Units.res delete mode 100644 packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res delete mode 100644 packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi delete mode 100644 packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Number.res diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res index 512138d5..68a143bd 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res @@ -41,8 +41,7 @@ let createProject = (): reducerProject => Private.createProject() Answer all the source ids of all the sources in the project. */ @genType -let getSourceIds = (project: reducerProject): array => - project->Private.getSourceIds +let getSourceIds = (project: reducerProject): array => project->Private.getSourceIds /* Sets the source for a given source Id. @@ -71,15 +70,13 @@ Cleans the compilation artifacts for a given source ID. The results stay untouch Normally, you would never need the compilation artifacts again as the results with the same sources would never change. However, they are needed in case of any debugging reruns */ @genType -let clean = (project: reducerProject, sourceId: string): unit => - project->Private.clean(sourceId) +let clean = (project: reducerProject, sourceId: string): unit => project->Private.clean(sourceId) /* Cleans all the compilation artifacts in all of the project */ @genType -let cleanAll = (project: reducerProject): unit => - project->Private.cleanAll +let cleanAll = (project: reducerProject): unit => project->Private.cleanAll /* Cleans results. Compilation stays untouched to be able to re-run the source. @@ -93,8 +90,7 @@ let cleanResults = (project: reducerProject, sourceId: string): unit => Cleans all results. Compilations remains untouched to rerun the source. */ @genType -let cleanAllResults = (project: reducerProject): unit => - project->Private.cleanAllResults +let cleanAllResults = (project: reducerProject): unit => project->Private.cleanAllResults /* To set the includes one first has to call "parseIncludes". The parsed includes or the parser error is returned. @@ -144,8 +140,7 @@ let getDependents = (project: reducerProject, sourceId: string): array = Get the run order for the sources in the project. */ @genType -let getRunOrder = (project: reducerProject): array => - project->Private.getRunOrder +let getRunOrder = (project: reducerProject): array => project->Private.getRunOrder /* Get the run order to get the results of this specific source @@ -177,15 +172,13 @@ let rawParse = (project: reducerProject, sourceId: string): unit => Runs a specific source code if it is not done already. The code is parsed if it is not already done. It runs the dependencies if it is not already done. */ @genType -let run = (project: reducerProject, sourceId: string): unit => - project->Private.run(sourceId) +let run = (project: reducerProject, sourceId: string): unit => project->Private.run(sourceId) /* Runs all of the sources in a project. Their results and bindings will be available */ @genType -let runAll = (project: reducerProject): unit => - project->Private.runAll +let runAll = (project: reducerProject): unit => project->Private.runAll /* Get the bindings after running this source fil. The bindings are local to the source diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res index 145c9a60..28f55f1c 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res @@ -1,5 +1,6 @@ type internalExpressionValue = Reducer_T.value type internalExpressionValueType = ReducerInterface_InternalExpressionValue.internalExpressionValueType +type errorValue = Reducer_ErrorValue.errorValue /* Function Registry "Type". A type, without any other information. @@ -48,7 +49,7 @@ type fnDefinition = { array, Reducer_T.environment, Reducer_T.reducerFn, - ) => result, + ) => result, } type function = { @@ -206,7 +207,7 @@ module FnDefinition = { let argValues = FRType.matchWithExpressionValueArray(t.inputs, args) switch argValues { | Some(values) => t.run(args, values, env, reducer) - | None => Error("Incorrect Types") + | None => REOther("Incorrect Types")->Error } } @@ -267,17 +268,20 @@ module Registry = { let _buildFnNameDict = (r: array): fnNameDict => { // Sorry for the imperative style of this. But it's much easier/less buggy than the previous version. let res: fnNameDict = Js.Dict.empty() - r->Js.Array2.forEach(fn => + r->Js.Array2.forEach(fn => fn.definitions->Js.Array2.forEach(def => { - let nameWithNamespace = `${fn.nameSpace}.${def.name}` - let nameWithoutNamespace = def.name - let names = fn.requiresNamespace ? [nameWithNamespace] : [nameWithNamespace, nameWithoutNamespace] + let names = + [ + fn.nameSpace == "" ? [] : [`${fn.nameSpace}.${def.name}`], + fn.requiresNamespace ? [] : [def.name], + ]->E.A.concatMany + names->Js.Array2.forEach(name => { switch res->Js.Dict.get(name) { - | Some(fns) => { + | Some(fns) => { let _ = fns->Js.Array2.push(def) } - | None => res->Js.Dict.set(name, [def]) + | None => res->Js.Dict.set(name, [def]) } }) }) @@ -296,9 +300,9 @@ module Registry = { args: array, env: Reducer_T.environment, reducer: Reducer_T.reducerFn, - ): result => { + ): result => { switch Js.Dict.get(registry.fnNameDict, fnName) { - | Some(definitions) => { + | Some(definitions) => { let showNameMatchDefinitions = () => { let defsString = definitions @@ -310,13 +314,12 @@ module Registry = { let match = definitions->Js.Array2.find(def => def->FnDefinition.isMatch(args)) switch match { - | Some(def) => def->FnDefinition.run(args, env, reducer)->E.R2.errMap(e => Reducer_ErrorValue.REOther(e)) - | None => { - Reducer_ErrorValue.REOther(showNameMatchDefinitions())->Error - } + | Some(def) => + def->FnDefinition.run(args, env, reducer) + | None => REOther(showNameMatchDefinitions())->Error } } - | None => Reducer_ErrorValue.RESymbolNotFound(fnName)->Error + | None => RESymbolNotFound(fnName)->Error } } } diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res index 872251cf..6a3931af 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res @@ -1,6 +1,8 @@ open FunctionRegistry_Core -let impossibleError = "Wrong inputs / Logically impossible" +let impossibleErrorString = "Wrong inputs / Logically impossible" +let impossibleError: errorValue = impossibleErrorString->REOther +let wrapError = e => Reducer_ErrorValue.REOther(e) module Wrappers = { let symbolic = r => DistributionTypes.Symbolic(r) @@ -15,7 +17,7 @@ module Wrappers = { let evArrayOfEvNumber = xs => xs->Belt.Array.map(evNumber)->evArray } -let getOrError = (a, g) => E.A.get(a, g) |> E.O.toResult(impossibleError) +let getOrError = (a, g) => E.A.get(a, g) |> E.O.toResult(impossibleErrorString) module Prepare = { type t = frValue @@ -27,19 +29,19 @@ module Prepare = { let twoArgs = (inputs: ts): result => switch inputs { | [FRValueRecord([(_, n1), (_, n2)])] => Ok([n1, n2]) - | _ => Error(impossibleError) + | _ => Error(impossibleErrorString) } let threeArgs = (inputs: ts): result => switch inputs { | [FRValueRecord([(_, n1), (_, n2), (_, n3)])] => Ok([n1, n2, n3]) - | _ => Error(impossibleError) + | _ => Error(impossibleErrorString) } let toArgs = (inputs: ts): result => switch inputs { | [FRValueRecord(args)] => args->E.A2.fmap(((_, b)) => b)->Ok - | _ => Error(impossibleError) + | _ => Error(impossibleErrorString) } } @@ -47,13 +49,13 @@ module Prepare = { let openA = (inputs: t): result => switch inputs { | FRValueArray(n) => Ok(n) - | _ => Error(impossibleError) + | _ => Error(impossibleErrorString) } let arrayOfArrays = (inputs: t): result, err> => switch inputs { | FRValueArray(n) => n->E.A2.fmap(openA)->E.A.R.firstErrorOrOpen - | _ => Error(impossibleError) + | _ => Error(impossibleErrorString) } } } @@ -62,7 +64,7 @@ module Prepare = { let twoDistOrNumber = (values: ts): result<(frValueDistOrNumber, frValueDistOrNumber), err> => { switch values { | [FRValueDistOrNumber(a1), FRValueDistOrNumber(a2)] => Ok(a1, a2) - | _ => Error(impossibleError) + | _ => Error(impossibleErrorString) } } @@ -72,28 +74,28 @@ module Prepare = { > => { switch values { | [FRValueDist(a1), FRValueDist(a2)] => Ok(a1, a2) - | _ => Error(impossibleError) + | _ => Error(impossibleErrorString) } } let twoNumbers = (values: ts): result<(float, float), err> => { switch values { | [FRValueNumber(a1), FRValueNumber(a2)] => Ok(a1, a2) - | _ => Error(impossibleError) + | _ => Error(impossibleErrorString) } } let threeNumbers = (values: ts): result<(float, float, float), err> => { switch values { | [FRValueNumber(a1), FRValueNumber(a2), FRValueNumber(a3)] => Ok(a1, a2, a3) - | _ => Error(impossibleError) + | _ => Error(impossibleErrorString) } } let oneDistOrNumber = (values: ts): result => { switch values { | [FRValueDistOrNumber(a1)] => Ok(a1) - | _ => Error(impossibleError) + | _ => Error(impossibleErrorString) } } @@ -124,14 +126,14 @@ module Prepare = { let oneNumber = (values: t): result => { switch values { | FRValueNumber(a1) => Ok(a1) - | _ => Error(impossibleError) + | _ => Error(impossibleErrorString) } } let oneDict = (values: t): result, err> => { switch values { | FRValueDict(a1) => Ok(a1) - | _ => Error(impossibleError) + | _ => Error(impossibleErrorString) } } @@ -229,6 +231,7 @@ module DefineFn = { ->E.R.bind(Prepare.oneNumber) ->E.R2.fmap(fn) ->E.R2.fmap(Wrappers.evNumber) + ->E.R2.errMap(e => Reducer_ErrorValue.REOther(e)) }, (), ) @@ -237,7 +240,11 @@ module DefineFn = { ~name, ~inputs=[FRTypeNumber, FRTypeNumber], ~run=(_, inputs, _, _) => { - inputs->Prepare.ToValueTuple.twoNumbers->E.R2.fmap(fn)->E.R2.fmap(Wrappers.evNumber) + inputs + ->Prepare.ToValueTuple.twoNumbers + ->E.R2.fmap(fn) + ->E.R2.fmap(Wrappers.evNumber) + ->E.R2.errMap(e => Reducer_ErrorValue.REOther(e)) }, (), ) @@ -246,7 +253,11 @@ module DefineFn = { ~name, ~inputs=[FRTypeNumber, FRTypeNumber, FRTypeNumber], ~run=(_, inputs, _, _) => { - inputs->Prepare.ToValueTuple.threeNumbers->E.R2.fmap(fn)->E.R2.fmap(Wrappers.evNumber) + inputs + ->Prepare.ToValueTuple.threeNumbers + ->E.R2.fmap(fn) + ->E.R2.fmap(Wrappers.evNumber) + ->E.R2.errMap(e => Reducer_ErrorValue.REOther(e)) }, (), ) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res index 0d54dee3..ce14c6da 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res @@ -9,7 +9,14 @@ let fnList = Belt.Array.concatMany([ FR_Number.library, FR_Pointset.library, FR_Scoring.library, + FR_GenericDist.library, + FR_Units.library, ]) let registry = FunctionRegistry_Core.Registry.make(fnList) let call = FunctionRegistry_Core.Registry.call(registry) + +let nonRegistryLambdas: array<(string, Reducer_T.lambdaValue)> = [ + ("mx", FR_GenericDist.mxLambda), + ("mixture", FR_GenericDist.mxLambda), +] diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res index da064f94..067d8e17 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res @@ -1,73 +1,47 @@ open FunctionRegistry_Core open FunctionRegistry_Helpers -let nameSpace = "Builtin" +let nameSpace = "" // no namespaced versions type simpleDefinition = { inputs: array, - fn: (array) => result, + fn: array => result, } let makeFnMany = (name: string, definitions: array) => Function.make( - ~name=name, + ~name, ~nameSpace, ~requiresNamespace=false, - ~definitions=definitions->Js.Array2.map( - ({ inputs, fn }) => FnDefinition.make( - ~name=name, - ~inputs=inputs, - ~run=(inputs, _, _, _) => fn(inputs), - () - ) + ~definitions=definitions->Js.Array2.map(({inputs, fn}) => + FnDefinition.make(~name, ~inputs, ~run=(inputs, _, _, _) => fn(inputs), ()) ), (), ) -let makeFn = (name: string, inputs: array, fn: (array) => result) => - makeFnMany(name, [{ inputs, fn }]) +let makeFn = ( + name: string, + inputs: array, + fn: array => result, +) => makeFnMany(name, [{ inputs, fn }]) + +let makeBinaryFn = (name: string, fn: (float, float) => float) => { + makeFn( + name, + [FRTypeNumber, FRTypeNumber], + inputs => { + switch inputs { + | [IEvNumber(x), IEvNumber(y)] => fn(x, y)->IEvNumber->Ok + | _ => Error(impossibleError) + } + } + ) +} let library = [ -// TODO - other MathJS - Function.make( - ~name="add", - ~nameSpace, - ~requiresNamespace=false, - ~definitions=[ - FnDefinition.make( - ~name="add", - ~inputs=[FRTypeNumber, FRTypeNumber], - ~run=(inputs, _, _, _) => { - switch inputs { - | [IEvNumber(x), IEvNumber(y)] => IEvNumber(x+.y)->Ok - | _ => Error(impossibleError) - } - }, - () - ), - FnDefinition.make( - ~name="add", - ~inputs=[FRTypeNumber, FRTypeNumber], - ~run=(inputs, _, _, _) => { - switch inputs { - | [IEvNumber(x), IEvNumber(y)] => IEvNumber(x+.y)->Ok - | _ => Error(impossibleError) - } - }, - () - ), - FnDefinition.make( - ~name="add", - ~inputs=[FRTypeNumber, FRTypeNumber], - ~run=(inputs, _, _, _) => { - switch inputs { - | [IEvNumber(x), IEvNumber(y)] => IEvNumber(x+.y)->Ok - | _ => Error(impossibleError) - } - }, - () - ), - ], - (), - ), + // TODO - other MathJS + makeBinaryFn("add", (x, y) => x +. y), + makeBinaryFn("subtract", (x, y) => x -. y), + makeBinaryFn("multiply", (x, y) => x *. y), + makeBinaryFn("divide", (x, y) => x /. y), ] 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 2f50c73a..c3d25799 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Danger.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Danger.res @@ -71,13 +71,14 @@ module Integration = { aLambda, [pointAsInternalExpression], environment, - reducer + reducer, ) let result = switch resultAsInternalExpression { | Reducer_T.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 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" + ->Reducer_ErrorValue.REOther ) } result @@ -141,11 +142,11 @@ module Integration = { resultWithOuterPoints } | Error(b) => - Error( + ( "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, - ) + b->Reducer_ErrorValue.errorToString + )->Reducer_ErrorValue.REOther->Error } result } @@ -168,7 +169,7 @@ module Integration = { ~run=(inputs, _, env, reducer) => { let result = switch inputs { | [_, _, _, IEvNumber(0.0)] => - Error("Integration error 4 in Danger.integrate: Increment can't be 0.") + "Integration error 4 in Danger.integrate: Increment can't be 0."->Reducer_ErrorValue.REOther->Error | [ IEvLambda(aLambda), IEvNumber(min), @@ -185,7 +186,7 @@ module Integration = { ) | _ => Error( - "Integration error 5 in Danger.integrate. Remember that inputs are (function, number (min), number (max), number(increment))", + Reducer_ErrorValue.REOther("Integration error 5 in Danger.integrate. Remember that inputs are (function, number (min), number (max), number(increment))") ) } result @@ -208,7 +209,9 @@ module Integration = { ~run=(inputs, _, env, reducer) => { let result = switch inputs { | [_, _, _, IEvNumber(0.0)] => - Error("Integration error in Danger.integrate: Increment can't be 0.") + "Integration error in Danger.integrate: Increment can't be 0." + ->Reducer_ErrorValue.REOther + ->Error | [IEvLambda(aLambda), IEvNumber(min), IEvNumber(max), IEvNumber(epsilon)] => Helpers.integrateFunctionBetweenWithNumIntegrationPoints( aLambda, @@ -218,12 +221,13 @@ module Integration = { env, reducer, )->E.R2.errMap(b => - "Integration error 7 in Danger.integrate. Something went wrong along the way: " ++ b + ("Integration error 7 in Danger.integrate. Something went wrong along the way: " ++ b->Reducer_ErrorValue.errorToString) + ->Reducer_ErrorValue.REOther ) | _ => - Error( - "Integration error 8 in Danger.integrate. Remember that inputs are (function, number (min), number (max), number(increment))", - ) + "Integration error 8 in Danger.integrate. Remember that inputs are (function, number (min), number (max), number(increment))" + ->Reducer_ErrorValue.REOther + ->Error } result }, @@ -239,7 +243,7 @@ module DiminishingReturns = { module Helpers = { type diminishingReturnsAccumulatorInner = { optimalAllocations: array, - currentMarginalReturns: result, string>, + currentMarginalReturns: result, errorValue>, } let findBiggestElementIndex = xs => E.A.reducei(xs, 0, (acc, newElement, index) => { @@ -248,7 +252,7 @@ module DiminishingReturns = { | false => acc } }) - type diminishingReturnsAccumulator = result + type diminishingReturnsAccumulator = result // TODO: This is so complicated, it probably should be its own file. It might also make sense to have it work in Rescript directly, taking in a function rather than a reducer; then something else can wrap that function in the reducer/lambdas/environment. /* The key idea for this function is that @@ -273,7 +277,7 @@ module DiminishingReturns = { funds, approximateIncrement, environment, - reducer + reducer, ) => { switch ( E.A.length(lambdas) > 1, @@ -283,19 +287,23 @@ module DiminishingReturns = { ) { | (false, _, _, _) => Error( - "Error in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions, number of functions should be greater than 1.", + "Error in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions, number of functions should be greater than 1." + ->Reducer_ErrorValue.REOther ) | (_, false, _, _) => Error( - "Error in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions, funds should be greater than 0.", + "Error in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions, funds should be greater than 0." + ->Reducer_ErrorValue.REOther ) | (_, _, false, _) => Error( - "Error in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions, approximateIncrement should be greater than 0.", + "Error in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions, approximateIncrement should be greater than 0." + ->Reducer_ErrorValue.REOther ) | (_, _, _, false) => Error( - "Error in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions, approximateIncrement should be smaller than funds amount.", + "Error in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions, approximateIncrement should be smaller than funds amount." + ->Reducer_ErrorValue.REOther ) | (true, true, true, true) => { let applyFunctionAtPoint = (lambda, point: float) => { @@ -305,13 +313,14 @@ module DiminishingReturns = { lambda, [pointAsInternalExpression], environment, - reducer + reducer, ) switch resultAsInternalExpression { | Reducer_T.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 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" + ->Reducer_ErrorValue.REOther ) } } @@ -403,9 +412,9 @@ module DiminishingReturns = { switch innerLambda { | Reducer_T.IEvLambda(lambda) => Ok(lambda) | _ => - Error( - "Error in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions. A member of the array wasn't a function", - ) + "Error in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions. A member of the array wasn't a function" + ->Reducer_ErrorValue.REOther + ->Error } }, innerlambdas) let wrappedLambdas = E.A.R.firstErrorOrOpen(individuallyWrappedLambdas) @@ -424,7 +433,7 @@ module DiminishingReturns = { } result } - | _ => Error("Error in Danger.diminishingMarginalReturnsForTwoFunctions") + | _ => "Error in Danger.diminishingMarginalReturnsForTwoFunctions"->Reducer_ErrorValue.REOther->Error }, (), ), diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res index df37f69c..f1cd86f3 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res @@ -17,7 +17,7 @@ module Internals = { ->E.A2.fmap(((key, value)) => Wrappers.evArray([IEvString(key), value])) ->Wrappers.evArray - let fromList = (items: array): result => + let fromList = (items: array): result => items ->E.A2.fmap(item => { switch (item: internalExpressionValue) { @@ -80,7 +80,8 @@ let library = [ ->E.R2.fmap(E.Dict.concatMany) ->E.R2.fmap(Js.Dict.map((. r) => FunctionRegistry_Core.FRType.matchReverse(r))) ->E.R2.fmap(r => r->Js.Dict.entries->Belt.Map.String.fromArray) - ->E.R2.fmap(Wrappers.evRecord), + ->E.R2.fmap(Wrappers.evRecord) + ->E.R2.errMap(e => e->Reducer_ErrorValue.REOther), (), ), ], diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dist.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dist.res index e1ddb61d..8482f3f8 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dist.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dist.res @@ -16,13 +16,14 @@ module DistributionCreation = { r ->E.R.bind(Process.DistOrNumberToDist.twoValuesUsingSymbolicDist(~fn, ~values=_, ~env)) ->E.R2.fmap(Wrappers.evDistribution) + ->E.R2.errMap(e => Reducer_ErrorValue.REOther(e)) let make = (name, fn) => { FnDefinition.make( ~name, ~inputs=[FRTypeDistOrNumber, FRTypeDistOrNumber], ~run=(_, inputs, env, _) => - inputs->Prepare.ToValueTuple.twoDistOrNumber->process(~fn, ~env=env), + inputs->Prepare.ToValueTuple.twoDistOrNumber->process(~fn, ~env), (), ) } @@ -32,9 +33,7 @@ module DistributionCreation = { ~name, ~inputs=[FRTypeRecord([("p5", FRTypeDistOrNumber), ("p95", FRTypeDistOrNumber)])], ~run=(_, inputs, env, _) => - inputs - ->Prepare.ToValueTuple.Record.twoDistOrNumber - ->process(~fn, ~env=env), + inputs->Prepare.ToValueTuple.Record.twoDistOrNumber->process(~fn, ~env), (), ) } @@ -44,9 +43,7 @@ module DistributionCreation = { ~name, ~inputs=[FRTypeRecord([("mean", FRTypeDistOrNumber), ("stdev", FRTypeDistOrNumber)])], ~run=(_, inputs, env, _) => - inputs - ->Prepare.ToValueTuple.Record.twoDistOrNumber - ->process(~fn, ~env=env), + inputs->Prepare.ToValueTuple.Record.twoDistOrNumber->process(~fn, ~env), (), ) } @@ -57,13 +54,14 @@ module DistributionCreation = { r ->E.R.bind(Process.DistOrNumberToDist.oneValueUsingSymbolicDist(~fn, ~value=_, ~env)) ->E.R2.fmap(Wrappers.evDistribution) + ->E.R2.errMap(e => Reducer_ErrorValue.REOther(e)) let make = (name, fn) => FnDefinition.make( ~name, ~inputs=[FRTypeDistOrNumber], ~run=(_, inputs, env, _) => - inputs->Prepare.ToValueTuple.oneDistOrNumber->process(~fn, ~env=env), + inputs->Prepare.ToValueTuple.oneDistOrNumber->process(~fn, ~env), (), ) } diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Fn.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Fn.res index 86d9462e..44d8882b 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Fn.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Fn.res @@ -18,12 +18,10 @@ module Declaration = { inputs ->E.A2.fmap(getMinMax) ->E.A.R.firstErrorOrOpen - ->E.R2.fmap(args => Reducer_T.IEvDeclaration( - Declaration.make(lambda, args), - )) + ->E.R2.fmap(args => Reducer_T.IEvDeclaration(Declaration.make(lambda, args))) } | Error(r) => Error(r) - | Ok(_) => Error(FunctionRegistry_Helpers.impossibleError) + | Ok(_) => Error(impossibleErrorString) } } } @@ -52,7 +50,7 @@ let library = [ ~name="declare", ~inputs=[Declaration.frType], ~run=(_, inputs, _, _) => { - inputs->getOrError(0)->E.R.bind(Declaration.fromExpressionValue) + inputs->getOrError(0)->E.R.bind(Declaration.fromExpressionValue)->E.R2.errMap(wrapError) }, (), ), diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_GenericDist.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_GenericDist.res new file mode 100644 index 00000000..5d5b4d98 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_GenericDist.res @@ -0,0 +1,412 @@ +open FunctionRegistry_Core + +module Old = { + module Helpers = { + let arithmeticMap = r => + switch r { + | "add" => #Add + | "dotAdd" => #Add + | "subtract" => #Subtract + | "dotSubtract" => #Subtract + | "divide" => #Divide + | "log" => #Logarithm + | "dotDivide" => #Divide + | "pow" => #Power + | "dotPow" => #Power + | "multiply" => #Multiply + | "dotMultiply" => #Multiply + | _ => #Multiply + } + + let catchAndConvertTwoArgsToDists = (args: array): option<( + DistributionTypes.genericDist, + DistributionTypes.genericDist, + )> => + switch args { + | [IEvDistribution(a), IEvDistribution(b)] => Some((a, b)) + | [IEvNumber(a), IEvDistribution(b)] => Some((GenericDist.fromFloat(a), b)) + | [IEvDistribution(a), IEvNumber(b)] => Some((a, GenericDist.fromFloat(b))) + | _ => None + } + + let toFloatFn = ( + fnCall: DistributionTypes.DistributionOperation.toFloat, + dist: DistributionTypes.genericDist, + ~env: GenericDist.env, + ) => { + FromDist(#ToFloat(fnCall), dist)->DistributionOperation.run(~env)->Some + } + + let toStringFn = ( + fnCall: DistributionTypes.DistributionOperation.toString, + dist: DistributionTypes.genericDist, + ~env: GenericDist.env, + ) => { + FromDist(#ToString(fnCall), dist)->DistributionOperation.run(~env)->Some + } + + let toBoolFn = ( + fnCall: DistributionTypes.DistributionOperation.toBool, + dist: DistributionTypes.genericDist, + ~env: GenericDist.env, + ) => { + FromDist(#ToBool(fnCall), dist)->DistributionOperation.run(~env)->Some + } + + let toDistFn = ( + fnCall: DistributionTypes.DistributionOperation.toDist, + dist, + ~env: GenericDist.env, + ) => { + FromDist(#ToDist(fnCall), dist)->DistributionOperation.run(~env)->Some + } + + let twoDiststoDistFn = (direction, arithmetic, dist1, dist2, ~env: GenericDist.env) => { + FromDist( + #ToDistCombination(direction, arithmeticMap(arithmetic), #Dist(dist2)), + dist1, + )->DistributionOperation.run(~env) + } + + let parseNumber = (args: internalExpressionValue): Belt.Result.t => + switch args { + | IEvNumber(x) => Ok(x) + | _ => Error("Not a number") + } + + let parseNumberArray = (ags: array): Belt.Result.t< + array, + string, + > => E.A.fmap(parseNumber, ags) |> E.A.R.firstErrorOrOpen + + let parseDist = (args: internalExpressionValue): Belt.Result.t< + DistributionTypes.genericDist, + string, + > => + switch args { + | IEvDistribution(x) => Ok(x) + | IEvNumber(x) => Ok(GenericDist.fromFloat(x)) + | _ => Error("Not a distribution") + } + + let parseDistributionArray = (ags: array): Belt.Result.t< + array, + string, + > => E.A.fmap(parseDist, ags) |> E.A.R.firstErrorOrOpen + + let mixtureWithGivenWeights = ( + distributions: array, + weights: array, + ~env: GenericDist.env, + ): DistributionOperation.outputType => + E.A.length(distributions) == E.A.length(weights) + ? Mixture(Belt.Array.zip(distributions, weights))->DistributionOperation.run(~env) + : GenDistError( + ArgumentError("Error, mixture call has different number of distributions and weights"), + ) + + let mixtureWithDefaultWeights = ( + distributions: array, + ~env: GenericDist.env, + ): DistributionOperation.outputType => { + let length = E.A.length(distributions) + let weights = Belt.Array.make(length, 1.0 /. Belt.Int.toFloat(length)) + mixtureWithGivenWeights(distributions, weights, ~env) + } + + let mixture = ( + args: array, + ~env: GenericDist.env, + ): DistributionOperation.outputType => { + let error = (err: string): DistributionOperation.outputType => + err->DistributionTypes.ArgumentError->GenDistError + switch args { + | [IEvArray(distributions)] => + switch parseDistributionArray(distributions) { + | Ok(distrs) => mixtureWithDefaultWeights(distrs, ~env) + | Error(err) => error(err) + } + | [IEvArray(distributions), IEvArray(weights)] => + switch (parseDistributionArray(distributions), parseNumberArray(weights)) { + | (Ok(distrs), Ok(wghts)) => mixtureWithGivenWeights(distrs, wghts, ~env) + | (Error(err), Ok(_)) => error(err) + | (Ok(_), Error(err)) => error(err) + | (Error(err1), Error(err2)) => error(`${err1}|${err2}`) + } + | _ => + switch E.A.last(args) { + | Some(IEvArray(b)) => { + let weights = parseNumberArray(b) + let distributions = parseDistributionArray( + Belt.Array.slice(args, ~offset=0, ~len=E.A.length(args) - 1), + ) + switch E.R.merge(distributions, weights) { + | Ok(d, w) => mixtureWithGivenWeights(d, w, ~env) + | Error(err) => error(err) + } + } + | Some(IEvNumber(_)) + | Some(IEvDistribution(_)) => + switch parseDistributionArray(args) { + | Ok(distributions) => mixtureWithDefaultWeights(distributions, ~env) + | Error(err) => error(err) + } + | _ => error("Last argument of mx must be array or distribution") + } + } + } + } + + module SymbolicConstructors = { + let threeFloat = name => + switch name { + | "triangular" => Ok(SymbolicDist.Triangular.make) + | _ => Error("Unreachable state") + } + + let symbolicResultToOutput = ( + symbolicResult: result, + ): option => + switch symbolicResult { + | Ok(r) => Some(Dist(Symbolic(r))) + | Error(r) => Some(GenDistError(OtherError(r))) + } + } + + let dispatchToGenericOutput = ( + call: ReducerInterface_InternalExpressionValue.functionCall, + env: GenericDist.env, + ): option => { + let (fnName, args) = call + switch (fnName, args) { + | ("triangular" as fnName, [IEvNumber(f1), IEvNumber(f2), IEvNumber(f3)]) => + SymbolicConstructors.threeFloat(fnName) + ->E.R.bind(r => r(f1, f2, f3)) + ->SymbolicConstructors.symbolicResultToOutput + | ("sample", [IEvDistribution(dist)]) => Helpers.toFloatFn(#Sample, dist, ~env) + | ("sampleN", [IEvDistribution(dist), IEvNumber(n)]) => + Some(FloatArray(GenericDist.sampleN(dist, Belt.Int.fromFloat(n)))) + | (("mean" | "stdev" | "variance" | "min" | "max" | "mode") as op, [IEvDistribution(dist)]) => { + let fn = switch op { + | "mean" => #Mean + | "stdev" => #Stdev + | "variance" => #Variance + | "min" => #Min + | "max" => #Max + | "mode" => #Mode + | _ => #Mean + } + Helpers.toFloatFn(fn, dist, ~env) + } + | ("integralSum", [IEvDistribution(dist)]) => Helpers.toFloatFn(#IntegralSum, dist, ~env) + | ("toString", [IEvDistribution(dist)]) => Helpers.toStringFn(ToString, dist, ~env) + | ("sparkline", [IEvDistribution(dist)]) => + Helpers.toStringFn(ToSparkline(MagicNumbers.Environment.sparklineLength), dist, ~env) + | ("sparkline", [IEvDistribution(dist), IEvNumber(n)]) => + Helpers.toStringFn(ToSparkline(Belt.Float.toInt(n)), dist, ~env) + | ("exp", [IEvDistribution(a)]) => + // https://mathjs.org/docs/reference/functions/exp.html + Helpers.twoDiststoDistFn( + Algebraic(AsDefault), + "pow", + GenericDist.fromFloat(MagicNumbers.Math.e), + a, + ~env, + )->Some + | ("normalize", [IEvDistribution(dist)]) => Helpers.toDistFn(Normalize, dist, ~env) + | ("isNormalized", [IEvDistribution(dist)]) => Helpers.toBoolFn(IsNormalized, dist, ~env) + | ("toPointSet", [IEvDistribution(dist)]) => Helpers.toDistFn(ToPointSet, dist, ~env) + | ("scaleLog", [IEvDistribution(dist)]) => + Helpers.toDistFn(Scale(#Logarithm, MagicNumbers.Math.e), dist, ~env) + | ("scaleLog10", [IEvDistribution(dist)]) => + Helpers.toDistFn(Scale(#Logarithm, 10.0), dist, ~env) + | ("scaleLog", [IEvDistribution(dist), IEvNumber(float)]) => + Helpers.toDistFn(Scale(#Logarithm, float), dist, ~env) + | ("scaleLogWithThreshold", [IEvDistribution(dist), IEvNumber(base), IEvNumber(eps)]) => + Helpers.toDistFn(Scale(#LogarithmWithThreshold(eps), base), dist, ~env) + | ("scaleMultiply", [IEvDistribution(dist), IEvNumber(float)]) => + Helpers.toDistFn(Scale(#Multiply, float), dist, ~env) + | ("scalePow", [IEvDistribution(dist), IEvNumber(float)]) => + Helpers.toDistFn(Scale(#Power, float), dist, ~env) + | ("scaleExp", [IEvDistribution(dist)]) => + Helpers.toDistFn(Scale(#Power, MagicNumbers.Math.e), dist, ~env) + | ("cdf", [IEvDistribution(dist), IEvNumber(float)]) => + Helpers.toFloatFn(#Cdf(float), dist, ~env) + | ("pdf", [IEvDistribution(dist), IEvNumber(float)]) => + Helpers.toFloatFn(#Pdf(float), dist, ~env) + | ("inv", [IEvDistribution(dist), IEvNumber(float)]) => + Helpers.toFloatFn(#Inv(float), dist, ~env) + | ("quantile", [IEvDistribution(dist), IEvNumber(float)]) => + Helpers.toFloatFn(#Inv(float), dist, ~env) + | ("inspect", [IEvDistribution(dist)]) => Helpers.toDistFn(Inspect, dist, ~env) + | ("truncateLeft", [IEvDistribution(dist), IEvNumber(float)]) => + Helpers.toDistFn(Truncate(Some(float), None), dist, ~env) + | ("truncateRight", [IEvDistribution(dist), IEvNumber(float)]) => + Helpers.toDistFn(Truncate(None, Some(float)), dist, ~env) + | ("truncate", [IEvDistribution(dist), IEvNumber(float1), IEvNumber(float2)]) => + Helpers.toDistFn(Truncate(Some(float1), Some(float2)), dist, ~env) + | ("mx" | "mixture", args) => Helpers.mixture(args, ~env)->Some + | ("log", [IEvDistribution(a)]) => + Helpers.twoDiststoDistFn( + Algebraic(AsDefault), + "log", + a, + GenericDist.fromFloat(MagicNumbers.Math.e), + ~env, + )->Some + | ("log10", [IEvDistribution(a)]) => + Helpers.twoDiststoDistFn( + Algebraic(AsDefault), + "log", + a, + GenericDist.fromFloat(10.0), + ~env, + )->Some + | ("unaryMinus", [IEvDistribution(a)]) => + Helpers.twoDiststoDistFn( + Algebraic(AsDefault), + "multiply", + a, + GenericDist.fromFloat(-1.0), + ~env, + )->Some + | ( + ("add" | "multiply" | "subtract" | "divide" | "pow" | "log") as arithmetic, + [_, _] as args, + ) => + Helpers.catchAndConvertTwoArgsToDists(args)->E.O2.fmap(((fst, snd)) => + Helpers.twoDiststoDistFn(Algebraic(AsDefault), arithmetic, fst, snd, ~env) + ) + | ( + ("dotAdd" + | "dotMultiply" + | "dotSubtract" + | "dotDivide" + | "dotPow") as arithmetic, + [_, _] as args, + ) => + Helpers.catchAndConvertTwoArgsToDists(args)->E.O2.fmap(((fst, snd)) => + Helpers.twoDiststoDistFn(Pointwise, arithmetic, fst, snd, ~env) + ) + | ("dotExp", [IEvDistribution(a)]) => + Helpers.twoDiststoDistFn( + Pointwise, + "dotPow", + GenericDist.fromFloat(MagicNumbers.Math.e), + a, + ~env, + )->Some + | _ => None + } + } + + let genericOutputToReducerValue = (o: DistributionOperation.outputType): result< + internalExpressionValue, + Reducer_ErrorValue.errorValue, + > => + switch o { + | Dist(d) => Ok(Reducer_T.IEvDistribution(d)) + | Float(d) => Ok(IEvNumber(d)) + | String(d) => Ok(IEvString(d)) + | Bool(d) => Ok(IEvBool(d)) + | FloatArray(d) => Ok(IEvArray(d |> E.A.fmap(r => Reducer_T.IEvNumber(r)))) + // // FIXME - can't propagate error objects through FunctionRegistry + // | GenDistError(err) => Error(REDistributionError(err)) + | GenDistError(err) => Error(REDistributionError(err)) + } + + let dispatch = (call: ReducerInterface_InternalExpressionValue.functionCall, environment) => + switch dispatchToGenericOutput(call, environment) { + | Some(o) => genericOutputToReducerValue(o) + | None => Reducer_ErrorValue.REOther("Internal error in FR_GenericDist implementation") + ->Reducer_ErrorValue.ErrorException + ->raise + } +} + +let makeProxyFn = (name: string, inputs: array) => { + Function.make( + ~name, + ~nameSpace="", + ~requiresNamespace=false, + ~definitions=[ + FnDefinition.make( + ~name, + ~inputs, + ~run=(inputs, _, env, _) => Old.dispatch((name, inputs), env), + (), + ), + ], + (), + ) +} + +let makeOperationFns = (): array => { + let ops = ["add", "multiply", "subtract", "divide", "pow", "log", "dotAdd", "dotMultiply", "dotSubtract", "dotDivide", "dotPow"] + let twoArgTypes = [ + // can't use numeric+numeric, since number+number should be delegated to builtin arithmetics + [FRTypeDist, FRTypeNumber], + [FRTypeNumber, FRTypeDist], + [FRTypeDist, FRTypeDist], + ] + + ops->E.A2.fmap( + op => twoArgTypes->E.A2.fmap( + types => makeProxyFn(op, types) + ) + )->E.A.concatMany +} + +// TODO - duplicates the switch above, should rewrite with standard FR APIs +let library = E.A.concatMany([ + [ + makeProxyFn("triangular", [FRTypeNumber, FRTypeNumber, FRTypeNumber]), + makeProxyFn("sample", [FRTypeDist]), + makeProxyFn("sampleN", [FRTypeDist, FRTypeNumber]), + makeProxyFn("mean", [FRTypeDist]), + makeProxyFn("stdev", [FRTypeDist]), + makeProxyFn("variance", [FRTypeDist]), + makeProxyFn("min", [FRTypeDist]), + makeProxyFn("max", [FRTypeDist]), + makeProxyFn("mode", [FRTypeDist]), + makeProxyFn("integralSum", [FRTypeDist]), + // // FIXME: doesn't work with Js.Dict in FunctionRegistry_Core + // makeProxyFn("toString", [FRTypeDist]), + makeProxyFn("sparkline", [FRTypeDist]), + makeProxyFn("sparkline", [FRTypeDist, FRTypeNumber]), + makeProxyFn("exp", [FRTypeDist]), + makeProxyFn("normalize", [FRTypeDist]), + makeProxyFn("isNormalized", [FRTypeDist]), + makeProxyFn("toPointSet", [FRTypeDist]), + makeProxyFn("scaleLog", [FRTypeDist]), + makeProxyFn("scaleLog10", [FRTypeDist]), + makeProxyFn("scaleLog", [FRTypeDist, FRTypeNumber]), + makeProxyFn("scaleLogWithThreshold", [FRTypeDist, FRTypeNumber, FRTypeNumber]), + makeProxyFn("scaleMultiply", [FRTypeDist, FRTypeNumber]), + makeProxyFn("scalePow", [FRTypeDist, FRTypeNumber]), + makeProxyFn("scaleExp", [FRTypeDist]), + makeProxyFn("cdf", [FRTypeDist, FRTypeNumber]), + makeProxyFn("pdf", [FRTypeDist, FRTypeNumber]), + makeProxyFn("inv", [FRTypeDist, FRTypeNumber]), + makeProxyFn("quantile", [FRTypeDist, FRTypeNumber]), + makeProxyFn("inspect", [FRTypeDist]), + makeProxyFn("truncateLeft", [FRTypeDist, FRTypeNumber]), + makeProxyFn("truncateRight", [FRTypeDist, FRTypeNumber]), + makeProxyFn("truncate", [FRTypeDist, FRTypeNumber, FRTypeNumber]), + // // FIXME - impossible to implement with FR!!! + // | ("mx" | "mixture", args) => Helpers.mixture(args, ~env)->Some + makeProxyFn("log", [FRTypeDist]), + makeProxyFn("log10", [FRTypeDist]), + makeProxyFn("unaryMinus", [FRTypeDist]), + makeProxyFn("dotExp", [FRTypeDist]), + ], + makeOperationFns() +]) + +// FIXME - impossible to implement with FR due to arbitrary parameters length; +let mxLambda = Reducer_Expression_Lambda.makeFFILambda((inputs, env, _) => { + switch Old.dispatch(("mx", inputs), env) { + | Ok(value) => value + | Error(e) => e->Reducer_ErrorValue.ErrorException->raise + } +}) 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 1e9c2dfb..8bb472d8 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res @@ -28,15 +28,10 @@ module Internals = { array: array, eLambdaValue, env: Reducer_T.environment, - reducer: Reducer_T.reducerFn + reducer: Reducer_T.reducerFn, ): internalExpressionValue => { let mappedList = array->E.A.reduceReverse(list{}, (acc, elem) => { - let newElem = Reducer_Expression_Lambda.doLambdaCall( - eLambdaValue, - [elem], - env, - reducer - ) + let newElem = Reducer_Expression_Lambda.doLambdaCall(eLambdaValue, [elem], env, reducer) list{newElem, ...acc} }) mappedList->Belt.List.toArray->Wrappers.evArray @@ -47,7 +42,7 @@ module Internals = { initialValue, aLambdaValue, env: Reducer_T.environment, - reducer: Reducer_T.reducerFn + reducer: Reducer_T.reducerFn, ) => { aValueArray->E.A.reduce(initialValue, (acc, elem) => Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, [acc, elem], env, reducer) @@ -59,7 +54,7 @@ module Internals = { initialValue, aLambdaValue, env: Reducer_T.environment, - reducer: Reducer_T.reducerFn + reducer: Reducer_T.reducerFn, ) => { aValueArray->Belt.Array.reduceReverse(initialValue, (acc, elem) => Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, [acc, elem], env, reducer) @@ -70,15 +65,10 @@ module Internals = { aValueArray, aLambdaValue, env: Reducer_T.environment, - reducer: Reducer_T.reducerFn + reducer: Reducer_T.reducerFn, ) => { let mappedList = aValueArray->Belt.Array.reduceReverse(list{}, (acc, elem) => { - let newElem = Reducer_Expression_Lambda.doLambdaCall( - aLambdaValue, - [elem], - env, - reducer - ) + let newElem = Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, [elem], env, reducer) switch newElem { | IEvBool(true) => list{elem, ...acc} | _ => acc @@ -124,7 +114,8 @@ let library = [ ~run=(_, inputs, _, _) => inputs ->Prepare.ToValueTuple.twoNumbers - ->E.R2.fmap(((low, high)) => Internals.upTo(low, high)), + ->E.R2.fmap(((low, high)) => Internals.upTo(low, high)) + ->E.R2.errMap(wrapError), (), ), ], @@ -141,7 +132,7 @@ let library = [ ~inputs=[FRTypeArray(FRTypeAny)], ~run=(inputs, _, _, _) => switch inputs { - | [IEvArray(array)] => Internals.first(array) + | [IEvArray(array)] => Internals.first(array)->E.R2.errMap(wrapError) | _ => Error(impossibleError) }, (), @@ -160,7 +151,7 @@ let library = [ ~inputs=[FRTypeArray(FRTypeAny)], ~run=(inputs, _, _, _) => switch inputs { - | [IEvArray(array)] => Internals.last(array) + | [IEvArray(array)] => Internals.last(array)->E.R2.errMap(wrapError) | _ => Error(impossibleError) }, (), @@ -200,8 +191,7 @@ let library = [ ~inputs=[FRTypeArray(FRTypeAny), FRTypeLambda], ~run=(inputs, _, env, reducer) => switch inputs { - | [IEvArray(array), IEvLambda(lambda)] => - Ok(Internals.map(array, lambda, env, reducer)) + | [IEvArray(array), IEvLambda(lambda)] => Ok(Internals.map(array, lambda, env, reducer)) | _ => Error(impossibleError) }, (), diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Number.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Number.res index 6305855d..90707891 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Number.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Number.res @@ -12,7 +12,8 @@ module ArrayNumberDist = { ~run=(_, inputs, _, _) => Prepare.ToTypedArray.numbers(inputs) ->E.R.bind(r => E.A.length(r) === 0 ? Error("List is empty") : Ok(r)) - ->E.R.bind(fn), + ->E.R.bind(fn) + ->E.R2.errMap(wrapError), (), ) } @@ -23,7 +24,8 @@ module ArrayNumberDist = { ~run=(_, inputs, _, _) => Prepare.ToTypedArray.numbers(inputs) ->E.R.bind(r => E.A.length(r) === 0 ? Error("List is empty") : Ok(r)) - ->E.R.bind(fn), + ->E.R.bind(fn) + ->E.R2.errMap(wrapError), (), ) } 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 e8cf6539..324843d7 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res @@ -17,19 +17,14 @@ let inputsTodist = (inputs: array, makeDist) => { let expressionValue = xyCoords ->E.R.bind(r => r->XYShape.T.makeFromZipped->E.R2.errMap(XYShape.Error.toString)) - ->E.R2.fmap(r => Reducer_T.IEvDistribution( - PointSet(makeDist(r)), - )) + ->E.R2.fmap(r => Reducer_T.IEvDistribution(PointSet(makeDist(r)))) expressionValue } module Internal = { type t = PointSetDist.t - let toType = (r): result< - Reducer_T.value, - Reducer_ErrorValue.errorValue, - > => + let toType = (r): result => switch r { | Ok(r) => Ok(Wrappers.evDistribution(PointSet(r))) | Error(err) => Error(REOperationError(err)) @@ -69,7 +64,7 @@ let library = [ ) ->E.R2.fmap(Wrappers.pointSet) ->E.R2.fmap(Wrappers.evDistribution) - ->E.R2.errMap(_ => "") + ->E.R2.errMap(e => Reducer_ErrorValue.REDistributionError(e)) | _ => Error(impossibleError) }, (), @@ -90,7 +85,7 @@ let library = [ ~run=(inputs, _, env, reducer) => switch inputs { | [IEvDistribution(PointSet(dist)), IEvLambda(lambda)] => - Internal.mapY(dist, lambda, env, reducer)->E.R2.errMap(Reducer_ErrorValue.errorToString) + Internal.mapY(dist, lambda, env, reducer) | _ => Error(impossibleError) }, (), @@ -115,7 +110,9 @@ let library = [ FnDefinition.make( ~name="makeContinuous", ~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))], - ~run=(_, inputs, _, _) => inputsTodist(inputs, r => Continuous(Continuous.make(r))), + ~run=(_, inputs, _, _) => + inputsTodist(inputs, r => Continuous(Continuous.make(r))) + ->E.R2.errMap(wrapError), (), ), ], @@ -138,7 +135,9 @@ let library = [ FnDefinition.make( ~name="makeDiscrete", ~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))], - ~run=(_, inputs, _, _) => inputsTodist(inputs, r => Discrete(Discrete.make(r))), + ~run=(_, inputs, _, _) => + inputsTodist(inputs, r => Discrete(Discrete.make(r))) + ->E.R2.errMap(wrapError), (), ), ], 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 6a98b4b7..b27b423e 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res @@ -18,10 +18,7 @@ module Internal = { | _ => Error(Operation.SampleMapNeedsNtoNFunction) } - let toType = (r): result< - Reducer_T.value, - Reducer_ErrorValue.errorValue, - > => + let toType = (r): result => switch r { | Ok(r) => Ok(Wrappers.evDistribution(SampleSet(r))) | Error(r) => Error(REDistributionError(SampleSetError(r))) @@ -100,7 +97,7 @@ let libaryBase = [ GenericDist.toSampleSetDist(dist, environment.sampleCount) ->E.R2.fmap(Wrappers.sampleSet) ->E.R2.fmap(Wrappers.evDistribution) - ->E.R2.errMap(DistributionTypes.Error.toString) + ->E.R2.errMap(e => Reducer_ErrorValue.REDistributionError(e)) | _ => Error(impossibleError) }, (), @@ -123,7 +120,9 @@ let libaryBase = [ Prepare.ToTypedArray.numbers(inputs) |> E.R2.bind(r => SampleSetDist.make(r)->E.R2.errMap(_ => "AM I HERE? WHYERE AMI??") ) - sampleSet->E.R2.fmap(Wrappers.sampleSet)->E.R2.fmap(Wrappers.evDistribution) + sampleSet->E.R2.fmap(Wrappers.sampleSet) + ->E.R2.fmap(Wrappers.evDistribution) + ->E.R2.errMap(wrapError) }, (), ), @@ -166,7 +165,7 @@ let libaryBase = [ | [IEvLambda(lambda)] => switch Internal.fromFn(lambda, environment, reducer) { | Ok(r) => Ok(r->Wrappers.sampleSet->Wrappers.evDistribution) - | Error(e) => Error(Operation.Error.toString(e)) + | Error(e) => e->Reducer_ErrorValue.REOperationError->Error } | _ => Error(impossibleError) }, @@ -188,7 +187,7 @@ let libaryBase = [ ~run=(inputs, _, environment, reducer) => switch inputs { | [IEvDistribution(SampleSet(dist)), IEvLambda(lambda)] => - Internal.map1(dist, lambda, environment, reducer)->E.R2.errMap(_ => "") + Internal.map1(dist, lambda, environment, reducer) | _ => Error(impossibleError) }, (), @@ -215,7 +214,7 @@ let libaryBase = [ IEvDistribution(SampleSet(dist2)), IEvLambda(lambda), ] => - Internal.map2(dist1, dist2, lambda, environment, reducer)->E.R2.errMap(_ => "") + Internal.map2(dist1, dist2, lambda, environment, reducer) | _ => Error(impossibleError) } }, @@ -244,7 +243,7 @@ let libaryBase = [ IEvDistribution(SampleSet(dist3)), IEvLambda(lambda), ] => - Internal.map3(dist1, dist2, dist3, lambda, environment, reducer)->E.R2.errMap(_ => "") + Internal.map3(dist1, dist2, dist3, lambda, environment, reducer) | _ => Error(impossibleError) }, (), @@ -267,9 +266,7 @@ let libaryBase = [ ~run=(inputs, _, environment, reducer) => switch inputs { | [IEvArray(dists), IEvLambda(lambda)] => - Internal.mapN(dists, lambda, environment, reducer)->E.R2.errMap(_e => { - "AHHH doesn't work" - }) + Internal.mapN(dists, lambda, environment, reducer) | _ => Error(impossibleError) }, (), @@ -294,7 +291,7 @@ module Comparison = { let wrapper = r => r ->E.R2.fmap(r => r->Wrappers.sampleSet->Wrappers.evDistribution) - ->E.R2.errMap(SampleSetDist.Error.toString) + ->E.R2.errMap(e => e->DistributionTypes.Error.sampleErrorToDistErr->Reducer_ErrorValue.REDistributionError) let mkBig = (name, withDist, withFloat) => Function.make( diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Scoring.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Scoring.res index dc1008a8..0f9b5811 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Scoring.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Scoring.res @@ -6,7 +6,7 @@ let requiresNamespace = true let runScoring = (estimate, answer, prior, env) => { GenericDist.Score.logScore(~estimate, ~answer, ~prior, ~env) ->E.R2.fmap(FunctionRegistry_Helpers.Wrappers.evNumber) - ->E.R2.errMap(DistributionTypes.Error.toString) + ->E.R2.errMap(e => Reducer_ErrorValue.REDistributionError(e)) } let library = [ @@ -40,7 +40,7 @@ let library = [ FRValueDist(prior), ]) => runScoring(estimate, Score_Scalar(d), Some(prior), environment) - | Error(e) => Error(e) + | Error(e) => Error(e->FunctionRegistry_Helpers.wrapError) | _ => Error(FunctionRegistry_Helpers.impossibleError) } }, @@ -55,7 +55,7 @@ let library = [ runScoring(estimate, Score_Dist(d), None, environment) | Ok([FRValueDist(estimate), FRValueDistOrNumber(FRValueNumber(d))]) => runScoring(estimate, Score_Scalar(d), None, environment) - | Error(e) => Error(e) + | Error(e) => Error(e->FunctionRegistry_Helpers.wrapError) | _ => Error(FunctionRegistry_Helpers.impossibleError) } }, diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Units.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Units.res new file mode 100644 index 00000000..90ea56bc --- /dev/null +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Units.res @@ -0,0 +1,35 @@ +open FunctionRegistry_Core + +let makeUnitFn = (name: string, multiplier: float) => { + Function.make( + ~name="fromUnit_" ++ name, + ~nameSpace="", + ~requiresNamespace=false, + ~definitions=[ + FnDefinition.make( + ~name="fromUnit_" ++ name, + ~inputs=[FRTypeNumber], + ~run=(inputs, _, _, _) => { + switch inputs { + | [IEvNumber(f)] => IEvNumber(f *. multiplier)->Ok + | _ => FunctionRegistry_Helpers.impossibleError->Error + } + }, + (), + ), + ], + (), + ) +} + + +let library = [ + makeUnitFn("n", 1E-9), + makeUnitFn("m", 1E-3), + makeUnitFn("k", 1E3), + makeUnitFn("M", 1E6), + makeUnitFn("B", 1E9), + makeUnitFn("G", 1E9), + makeUnitFn("T", 1E12), + makeUnitFn("P", 1E15), +] diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings/Reducer_Bindings.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings/Reducer_Bindings.res index 0e9e51f3..d58a7abd 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings/Reducer_Bindings.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings/Reducer_Bindings.res @@ -11,10 +11,11 @@ let rec get = (nameSpace: t, id: string) => { let T.NameSpace(container, parent) = nameSpace switch container->Belt.MutableMap.String.get(id) { - | Some(v) => Some(v) - | None => switch parent { - | Some(p) => get(p, id) - | None => None + | Some(v) => Some(v) + | None => + switch parent { + | Some(p) => get(p, id) + | None => None } } } @@ -35,16 +36,12 @@ let set = (nameSpace: t, id: string, value): t => { nameSpace } -let extend = (nameSpace: t) => T.NameSpace( - makeEmptyMap(), - nameSpace->Some -) +let extend = (nameSpace: t) => T.NameSpace(makeEmptyMap(), nameSpace->Some) let toKeyValuePairs = (T.NameSpace(container, _): t): array<(string, internalExpressionValue)> => { container->Belt.MutableMap.String.toArray } - let makeEmptyBindings = (): t => T.NameSpace(makeEmptyMap(), None) let toExpressionValue = (nameSpace: t): internalExpressionValue => T.IEvBindings(nameSpace) @@ -64,7 +61,7 @@ let mergeFrom = (T.NameSpace(container, _): t, T.NameSpace(newContainer, parent) } container }), - parent + parent, ) } @@ -80,6 +77,8 @@ let removeResult = (nameSpace: t): t => { nameSpace } +let locals = (T.NameSpace(container, _): t) => T.NameSpace(container, None) + // let typeAliasesKey = "_typeAliases_" // let typeReferencesKey = "_typeReferences_" @@ -131,16 +130,6 @@ let removeResult = (nameSpace: t): t => { // ) // } -// external castExpressionToInternalCode: ExpressionT.expressionOrFFI => internalCode = "%identity" - -// let eLambdaFFIValue = (ffiFn: ExpressionT.ffiFn) => { -// IEvLambda({ -// parameters: [], -// context: emptyModule, -// body: FFI(ffiFn)->castExpressionToInternalCode, -// }) -// } - // let functionNotFoundError = (call: functionCall) => // REFunctionNotFound(call->functionCallToCallSignature->functionCallSignatureToString)->Error diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res index 213d1d80..9fed751c 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res @@ -3,12 +3,12 @@ type t = Reducer_T.context let createContext = (stdLib: Reducer_T.nameSpace, environment: Reducer_T.environment): t => { { bindings: stdLib->Reducer_Bindings.extend, - environment, + environment: environment, } } let createDefaultContext = (): t => - createContext( - ReducerInterface_StdLib.internalStdLib, - ReducerInterface_InternalExpressionValue.defaultEnvironment - ) + createContext( + ReducerInterface_StdLib.internalStdLib, + ReducerInterface_InternalExpressionValue.defaultEnvironment, + ) 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 72c8aa79..09e19d3a 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 @@ -33,17 +33,17 @@ let callInternal = ( | call => call->IEV.toStringFunctionCall->MathJs.Eval.eval } - let constructRecord = arrayOfPairs => { - Belt.Array.map(arrayOfPairs, pairValue => - switch pairValue { - | Reducer_T.IEvArray([IEvString(key), valueValue]) => (key, valueValue) - | _ => ("wrong key type", pairValue->IEV.toStringWithType->IEvString) - } - ) - ->Belt.Map.String.fromArray - ->Reducer_T.IEvRecord - ->Ok - } + // let constructRecord = arrayOfPairs => { + // Belt.Array.map(arrayOfPairs, pairValue => + // switch pairValue { + // | Reducer_T.IEvArray([IEvString(key), valueValue]) => (key, valueValue) + // | _ => ("wrong key type", pairValue->IEV.toStringWithType->IEvString) + // } + // ) + // ->Belt.Map.String.fromArray + // ->Reducer_T.IEvRecord + // ->Ok + // } // let arrayAtIndex = (aValueArray: array, fIndex: float) => // switch Belt.Array.get(aValueArray, Belt.Int.fromFloat(fIndex)) { @@ -111,7 +111,7 @@ let callInternal = ( | ("$_atIndex_$", [IEvBindings(dict), IEvString(sIndex)]) => moduleAtIndex(dict, sIndex) // | ("$_atIndex_$", [IEvRecord(dict), IEvString(sIndex)]) => recordAtIndex(dict, sIndex) // | ("$_constructArray_$", args) => IEvArray(args)->Ok - | ("$_constructRecord_$", [IEvArray(arrayOfPairs)]) => constructRecord(arrayOfPairs) + // | ("$_constructRecord_$", [IEvArray(arrayOfPairs)]) => constructRecord(arrayOfPairs) // | ("$_exportBindings_$", [IEvBindings(nameSpace)]) => doExportBindings(nameSpace) // | ("$_exportBindings_$", [evValue]) => doIdentity(evValue) // | ("$_setBindings_$", [IEvBindings(nameSpace), IEvSymbol(symbol), value]) => @@ -154,7 +154,9 @@ let callInternal = ( | (_, [IEvString(_), IEvString(_)]) => callMathJs(call) | call => - Error(REFunctionNotFound(call->IEV.functionCallToCallSignature->IEV.functionCallSignatureToString)) // Report full type signature as error + Error( + REFunctionNotFound(call->IEV.functionCallToCallSignature->IEV.functionCallSignatureToString), + ) // Report full type signature as error } } /* @@ -163,7 +165,7 @@ let callInternal = ( let dispatch = ( call: IEV.functionCall, env: Reducer_T.environment, - reducer: Reducer_T.reducerFn + reducer: Reducer_T.reducerFn, ): Reducer_T.value => try { let (fn, args) = call diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_ChainPiece.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_ChainPiece.res index 68339bed..ebeb7f43 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_ChainPiece.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_ChainPiece.res @@ -21,3 +21,4 @@ // } // dispatchChainPiece // } + diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_T.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_T.res index 0966c699..a60a92b5 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_T.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_T.res @@ -19,3 +19,4 @@ // array, // ProjectAccessorsT.t, // ) => result + 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 ecf6c29a..3dada5c4 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 @@ -10,78 +10,70 @@ exception ErrorException = Reducer_ErrorValue.ErrorException /* Recursively evaluate the expression */ -let rec evaluate: T.reducerFn = ( - expression, - context -) => { +let rec evaluate: T.reducerFn = (expression, context) => { // Js.log(`reduce: ${expression->Reducer_Expression_T.toString}`) switch expression { - | T.EBlock(statements) => { + | T.EBlock(statements) => { let innerContext = {...context, bindings: context.bindings->Bindings.extend} - statements->Js.Array2.reduce( - (_, statement) => statement->evaluate(innerContext), - T.IEvVoid - ) + statements->Js.Array2.reduce((_, statement) => statement->evaluate(innerContext), T.IEvVoid) } - | T.EProgram(statements) => { + | T.EProgram(statements) => { // Js.log(`bindings: ${context.bindings->Reducer_Bindings.toString}`) - let res = statements->Js.Array2.reduce( - (_, statement) => statement->evaluate(context), - T.IEvVoid - ) + let res = + statements->Js.Array2.reduce((_, statement) => statement->evaluate(context), T.IEvVoid) + // Js.log(`bindings after: ${context.bindings->Reducer_Bindings.toString}`) res } - | T.EArray(elements) => - elements->Js.Array2.map(element => evaluate(element, context))->T.IEvArray + | T.EArray(elements) => elements->Js.Array2.map(element => evaluate(element, context))->T.IEvArray - | T.ERecord(pairs) => - pairs->Js.Array2.map(((eKey, eValue)) => { - let key = eKey->evaluate(context) - let keyString = switch key { - | IEvString(s) => s - | _ => REOther("Record keys must be strings")->ErrorException->raise - } - let value = eValue->evaluate(context) - (keyString, value) - })->Belt.Map.String.fromArray->IEvRecord + | T.ERecord(pairs) => + pairs + ->Js.Array2.map(((eKey, eValue)) => { + let key = eKey->evaluate(context) + let keyString = switch key { + | IEvString(s) => s + | _ => REOther("Record keys must be strings")->ErrorException->raise + } + let value = eValue->evaluate(context) + (keyString, value) + }) + ->Belt.Map.String.fromArray + ->IEvRecord - | T.EAssign(left, right) => { + | T.EAssign(left, right) => { let result = right->evaluate(context) let _ = context.bindings->Bindings.set(left, result) T.IEvVoid } - | T.ESymbol(name) => - switch context.bindings->Bindings.get(name) { - | Some(v) => v - | None => Reducer_ErrorValue.RESymbolNotFound(name)->ErrorException->raise - } + | T.ESymbol(name) => + switch context.bindings->Bindings.get(name) { + | Some(v) => v + | None => Reducer_ErrorValue.RESymbolNotFound(name)->ErrorException->raise + } - | T.EValue(value) => - value + | T.EValue(value) => value - | T.ETernary(predicate, trueCase, falseCase) => { + | T.ETernary(predicate, trueCase, falseCase) => { let predicateResult = predicate->evaluate(context) switch predicateResult { - | T.IEvBool(value) => - (value ? trueCase : falseCase)->evaluate(context) + | T.IEvBool(value) => (value ? trueCase : falseCase)->evaluate(context) | _ => REExpectedType("Boolean", "")->ErrorException->raise } } - | T.ELambda(parameters, body) => - Lambda.makeLambda(parameters, context.bindings, body)->T.IEvLambda + | T.ELambda(parameters, body) => + Lambda.makeLambda(parameters, context.bindings, body)->T.IEvLambda - | T.ECall(fn, args) => { + | T.ECall(fn, args) => { let lambda = fn->evaluate(context) let argValues = Js.Array2.map(args, arg => arg->evaluate(context)) switch lambda { - | T.IEvLambda(lambda) => - Lambda.doLambdaCall(lambda, argValues, context.environment, evaluate) - | _ => REExpectedType("Lambda", "")->ErrorException->raise + | T.IEvLambda(lambda) => Lambda.doLambdaCall(lambda, argValues, context.environment, evaluate) + | _ => REExpectedType("Lambda", "")->ErrorException->raise } } } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res index b11baa6e..08e51890 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_ExpressionBuilder.res @@ -1,4 +1,3 @@ -module BBindingsReplacer = Reducer_Expression_BindingsReplacer module BErrorValue = Reducer_ErrorValue module T = Reducer_T @@ -14,13 +13,9 @@ let eBindings = (anArray: array<(string, T.value)>) => let eBool = aBool => aBool->T.IEvBool->T.EValue -let eCall = (fn: expression, args: array): expression => - T.ECall(fn, args) +let eCall = (fn: expression, args: array): expression => T.ECall(fn, args) -let eLambda = ( - parameters: array, - expr: expression, -) => T.ELambda(parameters, expr) +let eLambda = (parameters: array, expr: expression) => T.ELambda(parameters, expr) let eNumber = aNumber => aNumber->T.IEvNumber->T.EValue @@ -28,26 +23,26 @@ let eRecord = (aMap: array<(T.expression, T.expression)>) => aMap->T.ERecord let eString = aString => aString->T.IEvString->T.EValue -let eSymbol = (name: string): expression => - T.ESymbol(name) +let eSymbol = (name: string): expression => T.ESymbol(name) -let eBlock = (exprs: array): expression => - T.EBlock(exprs) +let eBlock = (exprs: array): expression => T.EBlock(exprs) -let eProgram = (exprs: array): expression => - T.EProgram(exprs) +let eProgram = (exprs: array): expression => T.EProgram(exprs) -let eModule = (nameSpace: T.nameSpace): expression => - nameSpace->T.IEvBindings->T.EValue +let eModule = (nameSpace: T.nameSpace): expression => nameSpace->T.IEvBindings->T.EValue -let eLetStatement = (symbol: string, valueExpression: expression): expression => - T.EAssign(symbol, valueExpression) +let eLetStatement = (symbol: string, valueExpression: expression): expression => T.EAssign( + symbol, + valueExpression, +) -let eTernary = (predicate: expression, trueCase: expression, falseCase: expression): expression => - T.ETernary(predicate, trueCase, falseCase) +let eTernary = ( + predicate: expression, + trueCase: expression, + falseCase: expression, +): expression => T.ETernary(predicate, trueCase, falseCase) -let eIdentifier = (name: string): expression => - name->T.ESymbol +let eIdentifier = (name: string): expression => name->T.ESymbol // let eTypeIdentifier = (name: string): expression => // name->T.IEvTypeIdentifier->T.EValue 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 e9460f69..5f52fe12 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 @@ -7,7 +7,7 @@ let doLambdaCall = ( lambdaValue: Reducer_T.lambdaValue, args, environment: Reducer_T.environment, - reducer: Reducer_T.reducerFn + reducer: Reducer_T.reducerFn, ): Reducer_T.value => { lambdaValue.body(args, environment, reducer) } @@ -25,7 +25,7 @@ let makeLambda = ( let lambda = ( arguments: array, environment: Reducer_T.environment, - reducer: Reducer_T.reducerFn + reducer: Reducer_T.reducerFn, ) => { let argsLength = arguments->Js.Array2.length let parametersLength = parameters->Js.Array2.length @@ -34,23 +34,21 @@ let makeLambda = ( } let localBindings = bindings->Reducer_Bindings.extend - parameters->Js.Array2.forEachi( - (parameter, index) => { - let _ = localBindings->Reducer_Bindings.set(parameter, arguments[index]) - } - ) + parameters->Js.Array2.forEachi((parameter, index) => { + let _ = localBindings->Reducer_Bindings.set(parameter, arguments[index]) + }) - reducer(body, { bindings: localBindings, environment }) + reducer(body, {bindings: localBindings, environment: environment}) } { // context: bindings, body: lambda, - parameters, + parameters: parameters, } } let makeFFILambda = (body: Reducer_T.lambdaBody): Reducer_T.lambdaValue => { - body, - parameters: ["..."] + body: body, + parameters: ["..."], } 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 e1f3f501..76c85d68 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 @@ -27,15 +27,13 @@ let commaJoin = values => values->Reducer_Extra_Array.intersperse(", ")->Js.Stri */ let rec toString = (expression: expression) => switch expression { - | EBlock(statements) => - `{${Js.Array2.map(statements, aValue => toString(aValue))->commaJoin}}` - | EProgram(statements) => - `<${Js.Array2.map(statements, aValue => toString(aValue))->commaJoin}>` - | EArray(aList) => - `[${Js.Array2.map(aList, aValue => toString(aValue))->commaJoin}]` + | EBlock(statements) => `{${Js.Array2.map(statements, aValue => toString(aValue))->commaJoin}}` + | EProgram(statements) => `<${Js.Array2.map(statements, aValue => toString(aValue))->commaJoin}>` + | EArray(aList) => `[${Js.Array2.map(aList, aValue => toString(aValue))->commaJoin}]` | ERecord(map) => "TODO" | ESymbol(name) => name - | ETernary(predicate, trueCase, falseCase) => `${predicate->toString} ? (${trueCase->toString}) : (${falseCase->toString})` + | ETernary(predicate, trueCase, falseCase) => + `${predicate->toString} ? (${trueCase->toString}) : (${falseCase->toString})` | EAssign(name, value) => `${name} = ${value->toString}` | ECall(fn, args) => `(${fn->toString})(${args->Js.Array2.map(toString)->commaJoin})` | ELambda(parameters, body) => `{|${parameters->commaJoin}| ${body->toString}}` @@ -77,7 +75,3 @@ type optionFfiFnReturningResult = ( array, environment, ) => option> - -type expressionOrFFI = - | NotFFI(expression) - | FFI(ffiFn) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_Parse.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_Parse.res index ed8d8f18..9c59c504 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_Parse.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_Parse.res @@ -109,14 +109,17 @@ let rec pgToString = (peggyNode: peggyNode): string => { switch peggyNode { | PgNodeBlock(node) - | PgNodeProgram(node) - => "{" ++ node["statements"]->nodesToStringUsingSeparator("; ") ++ "}" - | PgNodeArray(node) - => "[" ++ node["elements"]->nodesToStringUsingSeparator("; ") ++ "]" - | PgNodeRecord(node) - => "{" ++ node["elements"]->Js.Array2.map(element => PgNodeKeyValue(element))->pgNodesToStringUsingSeparator(", ") ++ "}" + | PgNodeProgram(node) => + "{" ++ node["statements"]->nodesToStringUsingSeparator("; ") ++ "}" + | PgNodeArray(node) => "[" ++ node["elements"]->nodesToStringUsingSeparator("; ") ++ "]" + | PgNodeRecord(node) => + "{" ++ + node["elements"] + ->Js.Array2.map(element => PgNodeKeyValue(element)) + ->pgNodesToStringUsingSeparator(", ") ++ "}" | PgNodeBoolean(node) => node["value"]->Js.String.make - | PgNodeCall(node) => "(" ++ node["fn"]->toString ++ " " ++ node["args"]->nodesToStringUsingSeparator(" ") ++ ")" + | PgNodeCall(node) => + "(" ++ node["fn"]->toString ++ " " ++ node["args"]->nodesToStringUsingSeparator(" ") ++ ")" | PgNodeFloat(node) => node["value"]->Js.String.make | PgNodeIdentifier(node) => `:${node["value"]}` | PgNodeInteger(node) => node["value"]->Js.String.make diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression.res index cf8ad010..ef8ed75b 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression.res @@ -13,29 +13,30 @@ let rec fromNode = (node: Parse.node): expression => { let caseLambda = (nodeLambda: Parse.nodeLambda): expression => { let args = - nodeLambda["args"] - ->Js.Array2.map((argNode: Parse.nodeIdentifier) => argNode["value"]) + nodeLambda["args"]->Js.Array2.map((argNode: Parse.nodeIdentifier) => argNode["value"]) let body = nodeLambda["body"]->fromNode ExpressionBuilder.eLambda(args, body) - } let caseRecord = (nodeRecord): expression => { nodeRecord["elements"] - ->Js.Array2.map( - keyValueNode => (keyValueNode["key"]->fromNode, keyValueNode["value"]->fromNode) - ) + ->Js.Array2.map(keyValueNode => ( + keyValueNode["key"]->fromNode, + keyValueNode["value"]->fromNode, + )) ->ExpressionBuilder.eRecord } switch Parse.castNodeType(node) { | PgNodeBlock(nodeBlock) => caseBlock(nodeBlock) | PgNodeProgram(nodeProgram) => caseProgram(nodeProgram) - | PgNodeArray(nodeArray) => ExpressionBuilder.eArray(nodeArray["elements"]->Js.Array2.map(fromNode)) + | PgNodeArray(nodeArray) => + ExpressionBuilder.eArray(nodeArray["elements"]->Js.Array2.map(fromNode)) | PgNodeRecord(nodeRecord) => caseRecord(nodeRecord) | PgNodeBoolean(nodeBoolean) => ExpressionBuilder.eBool(nodeBoolean["value"]) - | PgNodeCall(nodeCall) => ExpressionBuilder.eCall(fromNode(nodeCall["fn"]), nodeCall["args"]->Js.Array2.map(fromNode)) + | PgNodeCall(nodeCall) => + ExpressionBuilder.eCall(fromNode(nodeCall["fn"]), nodeCall["args"]->Js.Array2.map(fromNode)) | PgNodeFloat(nodeFloat) => ExpressionBuilder.eNumber(nodeFloat["value"]) | PgNodeIdentifier(nodeIdentifier) => ExpressionBuilder.eSymbol(nodeIdentifier["value"]) | PgNodeInteger(nodeInteger) => ExpressionBuilder.eNumber(Belt.Int.toFloat(nodeInteger["value"])) @@ -54,7 +55,7 @@ let rec fromNode = (node: Parse.node): expression => { ExpressionBuilder.eTernary( fromNode(nodeTernary["condition"]), fromNode(nodeTernary["trueExpression"]), - fromNode(nodeTernary["falseExpression"]) + fromNode(nodeTernary["falseExpression"]), ) // | PgNodeTypeIdentifier(nodeTypeIdentifier) => // ExpressionBuilder.eTypeIdentifier(nodeTypeIdentifier["value"]) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res index a207f69c..b4eb4d43 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res @@ -25,10 +25,10 @@ type rec value = and lambdaBody = (array, environment, reducerFn) => value @genType.opaque and lambdaValue = { - parameters: array, - // context: nameSpace, - body: (array, environment, reducerFn) => value, - } + parameters: array, + // context: nameSpace, + body: (array, environment, reducerFn) => value, +} @genType.opaque and lambdaDeclaration = Declaration.declaration and expression = | EBlock(array) 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 bc191ffe..8f66be8f 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 @@ -39,3 +39,4 @@ // | Ok(value) => value // | _ => `Cannot compile ${typeExpressionSourceCode}`->Reducer_Exception.ImpossibleException->raise // } + diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_T.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_T.res index 40b74e56..e7bab837 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_T.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_T.res @@ -117,3 +117,4 @@ // | IEvRecord(record) => record->Belt.Map.String.map(fromIEvValue) // | _ => raise(Reducer_Exception.ImpossibleException("Reducer_Type_T-ievRecord")) // } + diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_TypeBuilder.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_TypeBuilder.res index 8ecc2f82..0acfae19 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_TypeBuilder.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_TypeBuilder.res @@ -78,3 +78,4 @@ // ]) // newRecord->IEvType->Ok // } + diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_TypeChecker.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_TypeChecker.res index 3c0b4bc9..af712587 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_TypeChecker.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_TypeChecker.res @@ -179,3 +179,4 @@ // | Error(error) => Error(error) // Directly propagating - err => err - causes type mismatch // } // } + diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Date.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Date.res index 8252b47a..bde1459f 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Date.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Date.res @@ -1,8 +1,9 @@ module T = Reducer_T -let dispatch = (call: ReducerInterface_InternalExpressionValue.functionCall, _: GenericDist.env): option< - result, -> => { +let dispatch = ( + call: ReducerInterface_InternalExpressionValue.functionCall, + _: GenericDist.env, +): option> => { switch call { | ("toString", [IEvDate(t)]) => T.IEvString(DateTime.Date.toString(t))->Ok->Some | ("makeDateFromYear", [IEvNumber(year)]) => diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Duration.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Duration.res index 846f6417..889df52a 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Duration.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Duration.res @@ -3,7 +3,7 @@ module T = Reducer_T type internalExpressionValue = IEV.t let dispatch = (call: IEV.functionCall, _: T.environment): option< - result + result, > => { switch call { | ("toString", [IEvTimeDuration(t)]) => T.IEvString(DateTime.Duration.toString(t))->Ok->Some @@ -14,8 +14,7 @@ let dispatch = (call: IEV.functionCall, _: T.environment): option< | ("fromUnit_hours", [IEvNumber(f)]) => T.IEvTimeDuration(DateTime.Duration.fromHours(f))->Ok->Some | ("days", [IEvNumber(f)]) => T.IEvTimeDuration(DateTime.Duration.fromDays(f))->Ok->Some - | ("fromUnit_days", [IEvNumber(f)]) => - T.IEvTimeDuration(DateTime.Duration.fromDays(f))->Ok->Some + | ("fromUnit_days", [IEvNumber(f)]) => T.IEvTimeDuration(DateTime.Duration.fromDays(f))->Ok->Some | ("years", [IEvNumber(f)]) => T.IEvTimeDuration(DateTime.Duration.fromYears(f))->Ok->Some | ("fromUnit_years", [IEvNumber(f)]) => T.IEvTimeDuration(DateTime.Duration.fromYears(f))->Ok->Some diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res index 0c9703d7..cb296904 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res @@ -10,7 +10,7 @@ let dispatch = ( chain, ): result => { E.A.O.firstSomeFn([ - () => ReducerInterface_GenericDistribution.dispatch(call, environment), + // () => ReducerInterface_GenericDistribution.dispatch(call, environment), () => ReducerInterface_Date.dispatch(call, environment), () => ReducerInterface_Duration.dispatch(call, environment), () => ReducerInterface_Number.dispatch(call, environment), diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res deleted file mode 100644 index 43234fe7..00000000 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ /dev/null @@ -1,310 +0,0 @@ -module IEV = ReducerInterface_InternalExpressionValue -type internalExpressionValue = IEV.t - -module Helpers = { - let arithmeticMap = r => - switch r { - | "add" => #Add - | "dotAdd" => #Add - | "subtract" => #Subtract - | "dotSubtract" => #Subtract - | "divide" => #Divide - | "log" => #Logarithm - | "dotDivide" => #Divide - | "pow" => #Power - | "dotPow" => #Power - | "multiply" => #Multiply - | "dotMultiply" => #Multiply - | _ => #Multiply - } - - let catchAndConvertTwoArgsToDists = (args: array): option<( - DistributionTypes.genericDist, - DistributionTypes.genericDist, - )> => - switch args { - | [IEvDistribution(a), IEvDistribution(b)] => Some((a, b)) - | [IEvNumber(a), IEvDistribution(b)] => Some((GenericDist.fromFloat(a), b)) - | [IEvDistribution(a), IEvNumber(b)] => Some((a, GenericDist.fromFloat(b))) - | _ => None - } - - let toFloatFn = ( - fnCall: DistributionTypes.DistributionOperation.toFloat, - dist: DistributionTypes.genericDist, - ~env: GenericDist.env, - ) => { - FromDist(#ToFloat(fnCall), dist)->DistributionOperation.run(~env)->Some - } - - let toStringFn = ( - fnCall: DistributionTypes.DistributionOperation.toString, - dist: DistributionTypes.genericDist, - ~env: GenericDist.env, - ) => { - FromDist(#ToString(fnCall), dist)->DistributionOperation.run(~env)->Some - } - - let toBoolFn = ( - fnCall: DistributionTypes.DistributionOperation.toBool, - dist: DistributionTypes.genericDist, - ~env: GenericDist.env, - ) => { - FromDist(#ToBool(fnCall), dist)->DistributionOperation.run(~env)->Some - } - - let toDistFn = ( - fnCall: DistributionTypes.DistributionOperation.toDist, - dist, - ~env: GenericDist.env, - ) => { - FromDist(#ToDist(fnCall), dist)->DistributionOperation.run(~env)->Some - } - - let twoDiststoDistFn = (direction, arithmetic, dist1, dist2, ~env: GenericDist.env) => { - FromDist( - #ToDistCombination(direction, arithmeticMap(arithmetic), #Dist(dist2)), - dist1, - )->DistributionOperation.run(~env) - } - - let parseNumber = (args: internalExpressionValue): Belt.Result.t => - switch args { - | IEvNumber(x) => Ok(x) - | _ => Error("Not a number") - } - - let parseNumberArray = (ags: array): Belt.Result.t< - array, - string, - > => E.A.fmap(parseNumber, ags) |> E.A.R.firstErrorOrOpen - - let parseDist = (args: internalExpressionValue): Belt.Result.t< - DistributionTypes.genericDist, - string, - > => - switch args { - | IEvDistribution(x) => Ok(x) - | IEvNumber(x) => Ok(GenericDist.fromFloat(x)) - | _ => Error("Not a distribution") - } - - let parseDistributionArray = (ags: array): Belt.Result.t< - array, - string, - > => E.A.fmap(parseDist, ags) |> E.A.R.firstErrorOrOpen - - let mixtureWithGivenWeights = ( - distributions: array, - weights: array, - ~env: GenericDist.env, - ): DistributionOperation.outputType => - E.A.length(distributions) == E.A.length(weights) - ? Mixture(Belt.Array.zip(distributions, weights))->DistributionOperation.run(~env) - : GenDistError( - ArgumentError("Error, mixture call has different number of distributions and weights"), - ) - - let mixtureWithDefaultWeights = ( - distributions: array, - ~env: GenericDist.env, - ): DistributionOperation.outputType => { - let length = E.A.length(distributions) - let weights = Belt.Array.make(length, 1.0 /. Belt.Int.toFloat(length)) - mixtureWithGivenWeights(distributions, weights, ~env) - } - - let mixture = ( - args: array, - ~env: GenericDist.env, - ): DistributionOperation.outputType => { - let error = (err: string): DistributionOperation.outputType => - err->DistributionTypes.ArgumentError->GenDistError - switch args { - | [IEvArray(distributions)] => - switch parseDistributionArray(distributions) { - | Ok(distrs) => mixtureWithDefaultWeights(distrs, ~env) - | Error(err) => error(err) - } - | [IEvArray(distributions), IEvArray(weights)] => - switch (parseDistributionArray(distributions), parseNumberArray(weights)) { - | (Ok(distrs), Ok(wghts)) => mixtureWithGivenWeights(distrs, wghts, ~env) - | (Error(err), Ok(_)) => error(err) - | (Ok(_), Error(err)) => error(err) - | (Error(err1), Error(err2)) => error(`${err1}|${err2}`) - } - | _ => - switch E.A.last(args) { - | Some(IEvArray(b)) => { - let weights = parseNumberArray(b) - let distributions = parseDistributionArray( - Belt.Array.slice(args, ~offset=0, ~len=E.A.length(args) - 1), - ) - switch E.R.merge(distributions, weights) { - | Ok(d, w) => mixtureWithGivenWeights(d, w, ~env) - | Error(err) => error(err) - } - } - | Some(IEvNumber(_)) - | Some(IEvDistribution(_)) => - switch parseDistributionArray(args) { - | Ok(distributions) => mixtureWithDefaultWeights(distributions, ~env) - | Error(err) => error(err) - } - | _ => error("Last argument of mx must be array or distribution") - } - } - } -} - -module SymbolicConstructors = { - let threeFloat = name => - switch name { - | "triangular" => Ok(SymbolicDist.Triangular.make) - | _ => Error("Unreachable state") - } - - let symbolicResultToOutput = ( - symbolicResult: result, - ): option => - switch symbolicResult { - | Ok(r) => Some(Dist(Symbolic(r))) - | Error(r) => Some(GenDistError(OtherError(r))) - } -} - -let dispatchToGenericOutput = (call: IEV.functionCall, env: GenericDist.env): option< - DistributionOperation.outputType, -> => { - let (fnName, args) = call - switch (fnName, args) { - | ("triangular" as fnName, [IEvNumber(f1), IEvNumber(f2), IEvNumber(f3)]) => - SymbolicConstructors.threeFloat(fnName) - ->E.R.bind(r => r(f1, f2, f3)) - ->SymbolicConstructors.symbolicResultToOutput - | ("sample", [IEvDistribution(dist)]) => Helpers.toFloatFn(#Sample, dist, ~env) - | ("sampleN", [IEvDistribution(dist), IEvNumber(n)]) => - Some(FloatArray(GenericDist.sampleN(dist, Belt.Int.fromFloat(n)))) - | (("mean" | "stdev" | "variance" | "min" | "max" | "mode") as op, [IEvDistribution(dist)]) => { - let fn = switch op { - | "mean" => #Mean - | "stdev" => #Stdev - | "variance" => #Variance - | "min" => #Min - | "max" => #Max - | "mode" => #Mode - | _ => #Mean - } - Helpers.toFloatFn(fn, dist, ~env) - } - | ("integralSum", [IEvDistribution(dist)]) => Helpers.toFloatFn(#IntegralSum, dist, ~env) - | ("toString", [IEvDistribution(dist)]) => Helpers.toStringFn(ToString, dist, ~env) - | ("sparkline", [IEvDistribution(dist)]) => - Helpers.toStringFn(ToSparkline(MagicNumbers.Environment.sparklineLength), dist, ~env) - | ("sparkline", [IEvDistribution(dist), IEvNumber(n)]) => - Helpers.toStringFn(ToSparkline(Belt.Float.toInt(n)), dist, ~env) - | ("exp", [IEvDistribution(a)]) => - // https://mathjs.org/docs/reference/functions/exp.html - Helpers.twoDiststoDistFn( - Algebraic(AsDefault), - "pow", - GenericDist.fromFloat(MagicNumbers.Math.e), - a, - ~env, - )->Some - | ("normalize", [IEvDistribution(dist)]) => Helpers.toDistFn(Normalize, dist, ~env) - | ("isNormalized", [IEvDistribution(dist)]) => Helpers.toBoolFn(IsNormalized, dist, ~env) - | ("toPointSet", [IEvDistribution(dist)]) => Helpers.toDistFn(ToPointSet, dist, ~env) - | ("scaleLog", [IEvDistribution(dist)]) => - Helpers.toDistFn(Scale(#Logarithm, MagicNumbers.Math.e), dist, ~env) - | ("scaleLog10", [IEvDistribution(dist)]) => Helpers.toDistFn(Scale(#Logarithm, 10.0), dist, ~env) - | ("scaleLog", [IEvDistribution(dist), IEvNumber(float)]) => - Helpers.toDistFn(Scale(#Logarithm, float), dist, ~env) - | ("scaleLogWithThreshold", [IEvDistribution(dist), IEvNumber(base), IEvNumber(eps)]) => - Helpers.toDistFn(Scale(#LogarithmWithThreshold(eps), base), dist, ~env) - | ("scaleMultiply", [IEvDistribution(dist), IEvNumber(float)]) => - Helpers.toDistFn(Scale(#Multiply, float), dist, ~env) - | ("scalePow", [IEvDistribution(dist), IEvNumber(float)]) => - Helpers.toDistFn(Scale(#Power, float), dist, ~env) - | ("scaleExp", [IEvDistribution(dist)]) => - Helpers.toDistFn(Scale(#Power, MagicNumbers.Math.e), dist, ~env) - | ("cdf", [IEvDistribution(dist), IEvNumber(float)]) => Helpers.toFloatFn(#Cdf(float), dist, ~env) - | ("pdf", [IEvDistribution(dist), IEvNumber(float)]) => Helpers.toFloatFn(#Pdf(float), dist, ~env) - | ("inv", [IEvDistribution(dist), IEvNumber(float)]) => Helpers.toFloatFn(#Inv(float), dist, ~env) - | ("quantile", [IEvDistribution(dist), IEvNumber(float)]) => - Helpers.toFloatFn(#Inv(float), dist, ~env) - | ("inspect", [IEvDistribution(dist)]) => Helpers.toDistFn(Inspect, dist, ~env) - | ("truncateLeft", [IEvDistribution(dist), IEvNumber(float)]) => - Helpers.toDistFn(Truncate(Some(float), None), dist, ~env) - | ("truncateRight", [IEvDistribution(dist), IEvNumber(float)]) => - Helpers.toDistFn(Truncate(None, Some(float)), dist, ~env) - | ("truncate", [IEvDistribution(dist), IEvNumber(float1), IEvNumber(float2)]) => - Helpers.toDistFn(Truncate(Some(float1), Some(float2)), dist, ~env) - | ("mx" | "mixture", args) => Helpers.mixture(args, ~env)->Some - | ("log", [IEvDistribution(a)]) => - Helpers.twoDiststoDistFn( - Algebraic(AsDefault), - "log", - a, - GenericDist.fromFloat(MagicNumbers.Math.e), - ~env, - )->Some - | ("log10", [IEvDistribution(a)]) => - Helpers.twoDiststoDistFn( - Algebraic(AsDefault), - "log", - a, - GenericDist.fromFloat(10.0), - ~env, - )->Some - | ("unaryMinus", [IEvDistribution(a)]) => - Helpers.twoDiststoDistFn( - Algebraic(AsDefault), - "multiply", - a, - GenericDist.fromFloat(-1.0), - ~env, - )->Some - | (("add" | "multiply" | "subtract" | "divide" | "pow" | "log") as arithmetic, [_, _] as args) => - Helpers.catchAndConvertTwoArgsToDists(args)->E.O2.fmap(((fst, snd)) => - Helpers.twoDiststoDistFn(Algebraic(AsDefault), arithmetic, fst, snd, ~env) - ) - | ( - ("dotAdd" - | "dotMultiply" - | "dotSubtract" - | "dotDivide" - | "dotPow") as arithmetic, - [_, _] as args, - ) => - Helpers.catchAndConvertTwoArgsToDists(args)->E.O2.fmap(((fst, snd)) => - Helpers.twoDiststoDistFn(Pointwise, arithmetic, fst, snd, ~env) - ) - | ("dotExp", [IEvDistribution(a)]) => - Helpers.twoDiststoDistFn( - Pointwise, - "dotPow", - GenericDist.fromFloat(MagicNumbers.Math.e), - a, - ~env, - )->Some - | _ => None - } -} - -let genericOutputToReducerValue = (o: DistributionOperation.outputType): result< - internalExpressionValue, - Reducer_ErrorValue.errorValue, -> => - switch o { - | Dist(d) => Ok(Reducer_T.IEvDistribution(d)) - | Float(d) => Ok(IEvNumber(d)) - | String(d) => Ok(IEvString(d)) - | Bool(d) => Ok(IEvBool(d)) - | FloatArray(d) => - Ok(IEvArray(d |> E.A.fmap(r => Reducer_T.IEvNumber(r)))) - | GenDistError(err) => Error(REDistributionError(err)) - } - -let dispatch = (call: IEV.functionCall, environment) => - dispatchToGenericOutput(call, environment)->E.O2.fmap(genericOutputToReducerValue) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi deleted file mode 100644 index 4cf8a17d..00000000 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi +++ /dev/null @@ -1,4 +0,0 @@ -let dispatch: ( - ReducerInterface_InternalExpressionValue.functionCall, - ReducerInterface_InternalExpressionValue.environment, -) => option> diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res index 9eacb8df..15ef7f57 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res @@ -50,7 +50,8 @@ and toStringDeclaration = d => Declaration.toString(d, r => toString(IEvLambda(r and toStringDistribution = dist => GenericDist.toString(dist) and toStringLambda = (lambdaValue: T.lambdaValue) => `lambda(${Js.Array2.toString(lambdaValue.parameters)}=>internal code)` -and toStringFunction = (lambdaValue: T.lambdaValue) => `function(${Js.Array2.toString(lambdaValue.parameters)})` +and toStringFunction = (lambdaValue: T.lambdaValue) => + `function(${Js.Array2.toString(lambdaValue.parameters)})` and toStringNumber = aNumber => Js.String.make(aNumber) and toStringRecord = aMap => aMap->toStringMap and toStringString = aString => `'${aString}'` @@ -75,10 +76,10 @@ and toStringNameSpace = nameSpace => { ->Belt.MutableMap.String.toArray ->Js.Array2.map(((eachKey, eachValue)) => `${eachKey}: ${toString(eachValue)}`) ->Js.Array2.toString - + switch parent { - | Some(p) => `{${pairs}} / ${toStringNameSpace(p)}` - | None => `{${pairs}}` + | Some(p) => `{${pairs}} / ${toStringNameSpace(p)}` + | None => `{${pairs}}` } } diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Number.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Number.res deleted file mode 100644 index bdef0c6d..00000000 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Number.res +++ /dev/null @@ -1,45 +0,0 @@ -module IEV = ReducerInterface_InternalExpressionValue -type internalExpressionValue = IEV.t - -module ScientificUnit = { - let nameToMultiplier = str => - switch str { - | "n" => Some(1E-9) - | "m" => Some(1E-3) - | "k" => Some(1E3) - | "M" => Some(1E6) - | "B" => Some(1E9) - | "G" => Some(1E9) - | "T" => Some(1E12) - | "P" => Some(1E15) - | _ => None - } - - let getMultiplier = (r: string) => { - let match = Js.String2.match_(r, %re(`/fromUnit_([_a-zA-Z]*)/`)) - switch match { - | Some([_, unit]) => nameToMultiplier(unit) - | _ => None - } - } -} - -let dispatch = (call: IEV.functionCall, _: GenericDist.env): option< - result, -> => { - switch call { - | ( - ("fromUnit_n" - | "fromUnit_m" - | "fromUnit_k" - | "fromUnit_M" - | "fromUnit_B" - | "fromUnit_G" - | "fromUnit_T" - | "fromUnit_P") as op, - [IEvNumber(f)], - ) => - op->ScientificUnit.getMultiplier->E.O2.fmap(multiplier => Reducer_T.IEvNumber(f *. multiplier)->Ok) - | _ => None - } -} diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res index 21f40d72..d9bc517a 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res @@ -1,76 +1,77 @@ exception ErrorException = Reducer_ErrorValue.ErrorException let internalStdLib: Reducer_Bindings.t = { - let res = Reducer_Bindings.makeEmptyBindings() - ->SquiggleLibrary_Math.makeBindings - ->SquiggleLibrary_Versions.makeBindings + let res = + Reducer_Bindings.makeEmptyBindings() + ->SquiggleLibrary_Math.makeBindings + ->SquiggleLibrary_Versions.makeBindings - let _ = res->Reducer_Bindings.set("multiply", Reducer_Expression_Lambda.makeFFILambda( - (arguments, _, _) => { - switch arguments { - | [IEvNumber(x), IEvNumber(y)] => IEvNumber(x *. y) - | _ => raise(Not_found) - } - } - )->Reducer_T.IEvLambda) - - let _ = res->Reducer_Bindings.set("$_atIndex_$", Reducer_Expression_Lambda.makeFFILambda( - (inputs, _, _) => { + let _ = res->Reducer_Bindings.set( + "$_atIndex_$", + Reducer_Expression_Lambda.makeFFILambda((inputs, _, _) => { switch inputs { - | [IEvArray(aValueArray), IEvNumber(fIndex)] => { - switch Belt.Array.get(aValueArray, Belt.Int.fromFloat(fIndex)) { + | [IEvArray(aValueArray), IEvNumber(fIndex)] => switch Belt.Array.get( + aValueArray, + Belt.Int.fromFloat(fIndex), + ) { | Some(value) => value - | None => REArrayIndexNotFound("Array index not found", Belt.Int.fromFloat(fIndex))->ErrorException->raise + | None => + REArrayIndexNotFound("Array index not found", Belt.Int.fromFloat(fIndex)) + ->ErrorException + ->raise } - } - | [IEvRecord(dict), IEvString(sIndex)] => { - switch Belt.Map.String.get(dict, sIndex) { + | [IEvRecord(dict), IEvString(sIndex)] => switch Belt.Map.String.get(dict, sIndex) { | Some(value) => value | None => RERecordPropertyNotFound("Record index not found", sIndex)->ErrorException->raise } - } | _ => REOther("Trying to access key on wrong value")->ErrorException->raise } - } - )->Reducer_T.IEvLambda) + })->Reducer_T.IEvLambda, + ) - // TODO: - // () => ReducerInterface_GenericDistribution.dispatch(call, environment), - // () => ReducerInterface_Date.dispatch(call, environment), - // () => ReducerInterface_Duration.dispatch(call, environment), - // () => ReducerInterface_Number.dispatch(call, environment), - - // Reducer_Dispatch_BuiltIn: - - // [x] | ("$_atIndex_$", [IEvArray(aValueArray), IEvNumber(fIndex)]) => arrayAtIndex(aValueArray, fIndex) - // [ ] | ("$_atIndex_$", [IEvBindings(dict), IEvString(sIndex)]) => moduleAtIndex(dict, sIndex) - // [x] | ("$_atIndex_$", [IEvRecord(dict), IEvString(sIndex)]) => recordAtIndex(dict, sIndex) - // [ ] | ("$_constructArray_$", args) => IEvArray(args)->Ok - // [ ] | ("$_constructRecord_$", [IEvArray(arrayOfPairs)]) => constructRecord(arrayOfPairs) - // [ ] | ("concat", [IEvArray(aValueArray), IEvArray(bValueArray)]) => doAddArray(aValueArray, bValueArray) - // [ ] | ("concat", [IEvString(aValueString), IEvString(bValueString)]) => doAddString(aValueString, bValueString) - // [ ] | ("inspect", [value, IEvString(label)]) => inspectLabel(value, label) - // [ ] | ("inspect", [value]) => inspect(value) - // [ ] | (_, [IEvBool(_)]) - // [ ] | (_, [IEvNumber(_)]) - // [ ] | (_, [IEvString(_)]) - // [ ] | (_, [IEvBool(_), IEvBool(_)]) - // [ ] | (_, [IEvNumber(_), IEvNumber(_)]) - // [ ] | (_, [IEvString(_), IEvString(_)]) => callMathJs(call) - - - FunctionRegistry_Library.registry.fnNameDict->Js.Dict.keys->Js.Array2.forEach( - (name) => { - let _ = res->Reducer_Bindings.set(name, Reducer_Expression_Lambda.makeFFILambda( - (arguments, environment, reducer) => { - switch FunctionRegistry_Library.call(name, arguments, environment, reducer) { - | Ok(value) => value - | Error(error) => error->Reducer_ErrorValue.ErrorException->raise - } - } - )->Reducer_T.IEvLambda) + FunctionRegistry_Library.nonRegistryLambdas->Js.Array2.forEach( + ((name, lambda)) => { + let _ = res->Reducer_Bindings.set(name, lambda->Reducer_T.IEvLambda) } ) + // TODO: + // () => ReducerInterface_GenericDistribution.dispatch(call, environment), + // () => ReducerInterface_Date.dispatch(call, environment), + // () => ReducerInterface_Duration.dispatch(call, environment), + // () => ReducerInterface_Number.dispatch(call, environment), + + // Reducer_Dispatch_BuiltIn: + + // [x] | ("$_atIndex_$", [IEvArray(aValueArray), IEvNumber(fIndex)]) => arrayAtIndex(aValueArray, fIndex) + // [ ] | ("$_atIndex_$", [IEvBindings(dict), IEvString(sIndex)]) => moduleAtIndex(dict, sIndex) + // [x] | ("$_atIndex_$", [IEvRecord(dict), IEvString(sIndex)]) => recordAtIndex(dict, sIndex) + // [x] | ("$_constructArray_$", args) => IEvArray(args)->Ok + // [x] | ("$_constructRecord_$", [IEvArray(arrayOfPairs)]) => constructRecord(arrayOfPairs) + // [ ] | ("concat", [IEvArray(aValueArray), IEvArray(bValueArray)]) => doAddArray(aValueArray, bValueArray) + // [ ] | ("concat", [IEvString(aValueString), IEvString(bValueString)]) => doAddString(aValueString, bValueString) + // [ ] | ("inspect", [value, IEvString(label)]) => inspectLabel(value, label) + // [ ] | ("inspect", [value]) => inspect(value) + // [ ] | (_, [IEvBool(_)]) + // [ ] | (_, [IEvNumber(_)]) + // [ ] | (_, [IEvString(_)]) + // [ ] | (_, [IEvBool(_), IEvBool(_)]) + // [ ] | (_, [IEvNumber(_), IEvNumber(_)]) + // [ ] | (_, [IEvString(_), IEvString(_)]) => callMathJs(call) + + FunctionRegistry_Library.registry.fnNameDict + ->Js.Dict.keys + ->Js.Array2.forEach(name => { + let _ = res->Reducer_Bindings.set( + name, + Reducer_Expression_Lambda.makeFFILambda((arguments, environment, reducer) => { + switch FunctionRegistry_Library.call(name, arguments, environment, reducer) { + | Ok(value) => value + | Error(error) => error->Reducer_ErrorValue.ErrorException->raise + } + })->Reducer_T.IEvLambda, + ) + }) + res } diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res index 5e7632b0..fe7718d6 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res @@ -85,10 +85,7 @@ let getIncludes = (project: t, sourceId: string): ProjectItem.T.includesType => let getPastChain = (project: t, sourceId: string): array => project->getItem(sourceId)->ProjectItem.getPastChain -let getIncludesAsVariables = ( - project: t, - sourceId: string, -): ProjectItem.T.importAsVariablesType => +let getIncludesAsVariables = (project: t, sourceId: string): ProjectItem.T.importAsVariablesType => project->getItem(sourceId)->ProjectItem.getIncludesAsVariables let getDirectIncludes = (project: t, sourceId: string): array => @@ -156,12 +153,10 @@ let setEnvironment = (project: t, value: InternalExpressionValue.environment): u } let getBindings = (project: t, sourceId: string): ProjectItem.T.bindingsArgumentType => { - project->getContinuation(sourceId) // TODO - locals method for cleaning parent? + project->getContinuation(sourceId)->Reducer_Bindings.locals } -let getContinuationsBefore = (project: t, sourceId: string): array< - ProjectItem.T.continuation, -> => { +let getContinuationsBefore = (project: t, sourceId: string): array => { let pastNameSpaces = project->getPastChain(sourceId)->Js.Array2.map(getBindings(project, _)) let theLength = pastNameSpaces->Js.Array2.length if theLength == 0 { @@ -177,7 +172,8 @@ let getContinuationsBefore = (project: t, sourceId: string): array< let linkDependencies = (project: t, sourceId: string): ProjectItem.T.continuation => { let continuationsBefore = project->getContinuationsBefore(sourceId) - let nameSpace = Reducer_Bindings.makeEmptyBindings()->Reducer_Bindings.chainTo(continuationsBefore) + let nameSpace = + Reducer_Bindings.makeEmptyBindings()->Reducer_Bindings.chainTo(continuationsBefore) let includesAsVariables = project->getIncludesAsVariables(sourceId) Belt.Array.reduce(includesAsVariables, nameSpace, (currentNameSpace, (variable, includeFile)) => Bindings.set( @@ -242,9 +238,7 @@ let evaluate = (sourceCode: string) => { runAll(project) ( - getResultOption(project, "main")->Belt.Option.getWithDefault( - Reducer_T.IEvVoid->Ok, - ), - project->getBindings("main") + getResultOption(project, "main")->Belt.Option.getWithDefault(Reducer_T.IEvVoid->Ok), + project->getBindings("main"), ) } 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_ProjectAccessors_T.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectAccessors_T.res index ea6c0f1b..51fd41e3 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectAccessors_T.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectAccessors_T.res @@ -28,3 +28,4 @@ // environment: environment, // } // } + diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res index b4a5a184..e870bcfb 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res @@ -81,8 +81,10 @@ let setRawParse = (r: t, rawParse: T.rawParseArgumentType): t => let setExpression = (r: t, expression: T.expressionArgumentType): t => {...r, expression: Some(expression)}->touchExpression -let setContinuation = (r: t, continuation: T.continuationArgumentType): t => - {...r, continuation: continuation} +let setContinuation = (r: t, continuation: T.continuationArgumentType): t => { + ...r, + continuation: continuation, +} let setResult = (r: t, result: T.resultArgumentType): t => { ...r, @@ -115,10 +117,10 @@ let setIncludes = (this: t, includes: T.includesType): t => { includes: includes, } -let setImportAsVariables = ( - this: t, - includeAsVariables: T.importAsVariablesType, -): t => {...this, includeAsVariables: includeAsVariables} +let setImportAsVariables = (this: t, includeAsVariables: T.importAsVariablesType): t => { + ...this, + includeAsVariables: includeAsVariables, +} let setDirectImports = (this: t, directIncludes: array): t => { ...this, @@ -161,38 +163,26 @@ let buildExpression = (this: t): t => { switch this->getExpression { | Some(_) => this // cached | None => - this - ->doBuildExpression - ->Belt.Option.map(setExpression(this, _)) - ->E.O2.defaultFn(() => this) + this->doBuildExpression->Belt.Option.map(setExpression(this, _))->E.O2.defaultFn(() => this) } } -let failRun = ( - this: t, - e: Reducer_ErrorValue.errorValue -): t => this->setResult(e->Error)->setContinuation(Reducer_Bindings.makeEmptyBindings()) +let failRun = (this: t, e: Reducer_ErrorValue.errorValue): t => + this->setResult(e->Error)->setContinuation(Reducer_Bindings.makeEmptyBindings()) -let doRun = ( - this: t, - context: Reducer_T.context -): t => +let doRun = (this: t, context: Reducer_T.context): t => switch this->getExpression { - | Some(expressionResult) => { - switch expressionResult { - | Ok(expression) => { - try { - let result = Reducer_Expression.evaluate(expression, context) - this->setResult(result->Ok)->setContinuation(context.bindings) - } catch { - | Reducer_ErrorValue.ErrorException(e) => this->failRun(e) - | _ => this->failRun(RETodo("unhandled rescript exception")) - } - } - | Error(e) => this->failRun(e) + | Some(expressionResult) => switch expressionResult { + | Ok(expression) => try { + let result = Reducer_Expression.evaluate(expression, context) + this->setResult(result->Ok)->setContinuation(context.bindings) + } catch { + | Reducer_ErrorValue.ErrorException(e) => this->failRun(e) + | _ => this->failRun(RETodo("unhandled rescript exception")) } + | Error(e) => this->failRun(e) } - | None => this->failRun(RETodo("attempt to run without expression")) + | None => this->failRun(RETodo("attempt to run without expression")) } let run = (this: t, context: Reducer_T.context): t => { diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_Topology.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_Topology.res index 0cb807dc..682dd0d6 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_Topology.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_Topology.res @@ -31,16 +31,16 @@ let rec topologicalSortUtil = ( } let getTopologicalSort = (this: t): array => { - let (_visited, stack) = this->getSourceIds->Belt.Array.reduce((Belt.Map.String.empty, list{}), ( - (currVisited, currStack), - currId, - ) => - if !Belt.Map.String.getWithDefault(currVisited, currId, false) { - topologicalSortUtil(this, currId, (currVisited, currStack)) - } else { - (currVisited, currStack) - } - ) + let (_visited, stack) = + this + ->getSourceIds + ->Belt.Array.reduce((Belt.Map.String.empty, list{}), ((currVisited, currStack), currId) => + if !Belt.Map.String.getWithDefault(currVisited, currId, false) { + topologicalSortUtil(this, currId, (currVisited, currStack)) + } else { + (currVisited, currStack) + } + ) Belt.List.reverse(stack)->Belt.List.toArray } diff --git a/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Math.res b/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Math.res index 7d79b613..2a433c5a 100644 --- a/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Math.res +++ b/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Math.res @@ -14,9 +14,7 @@ let availableNumbers: array<(string, float)> = [ ] let mathBindings: Bindings.t = - availableNumbers - ->E.A2.fmap(((name, v)) => (name, Reducer_T.IEvNumber(v))) - ->Bindings.fromArray + availableNumbers->E.A2.fmap(((name, v)) => (name, Reducer_T.IEvNumber(v)))->Bindings.fromArray let makeBindings = (previousBindings: Bindings.t): Bindings.t => previousBindings->Bindings.mergeFrom(mathBindings) diff --git a/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Versions.res b/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Versions.res index 028e4b3f..30b64b81 100644 --- a/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Versions.res +++ b/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Versions.res @@ -1,9 +1,7 @@ module Bindings = Reducer_Bindings let bindings: Reducer_T.nameSpace = - [ - ("System.version", Reducer_T.IEvString("0.4.0-dev")), - ]->Bindings.fromArray + [("System.version", Reducer_T.IEvString("0.4.0-dev"))]->Bindings.fromArray let makeBindings = (previousBindings: Reducer_T.nameSpace): Reducer_T.nameSpace => previousBindings->Bindings.mergeFrom(bindings) diff --git a/packages/squiggle-lang/src/rescript/Utility/Mathjs.res b/packages/squiggle-lang/src/rescript/Utility/Mathjs.res index 4a792af4..ccf43100 100644 --- a/packages/squiggle-lang/src/rescript/Utility/Mathjs.res +++ b/packages/squiggle-lang/src/rescript/Utility/Mathjs.res @@ -7,3 +7,4 @@ // | exception _ => Error("MathJS Parse Error") // | j => Ok(j) // } +