From fe56e817103c54a9d9ad5c9a1af7a9978c87e234 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Sat, 10 Sep 2022 21:01:04 +0400 Subject: [PATCH 01/46] WIP --- packages/squiggle-lang/bench-bio.js | 30 ++ packages/squiggle-lang/bench.js | 27 ++ .../ForTS_SquiggleValue_Module.res | 2 +- .../Reducer_Bindings/Reducer_Bindings.res | 84 ++--- .../Reducer_Dispatch_BuiltIn.res | 71 +++-- .../Reducer_Dispatch_BuiltInMacros.res | 4 +- .../Reducer_Expression/Reducer_Expression.res | 52 +-- .../Reducer_Expression_ExpressionBuilder.res | 71 ++--- .../Reducer_Expression_T.res | 37 ++- .../Reducer_Peggy_GeneratedParser.peggy | 14 +- .../Reducer_Peggy/Reducer_Peggy_Parse.res | 15 +- .../Reducer_Peggy_ToExpression.res | 20 +- .../rescript/Reducer/Reducer_Peggy/helpers.ts | 50 +-- ...ducerInterface_InternalExpressionValue.res | 22 +- .../ReducerProject_IncludeParser.js | 298 ++++++------------ 15 files changed, 345 insertions(+), 452 deletions(-) create mode 100755 packages/squiggle-lang/bench-bio.js create mode 100755 packages/squiggle-lang/bench.js diff --git a/packages/squiggle-lang/bench-bio.js b/packages/squiggle-lang/bench-bio.js new file mode 100755 index 00000000..2bc78095 --- /dev/null +++ b/packages/squiggle-lang/bench-bio.js @@ -0,0 +1,30 @@ +#!/usr/bin/env node +const s = require("./dist/src/js"); +const fs = require("fs"); + +const measure = (cb, times = 1) => { + const t1 = new Date(); + + for (let i = 1; i <= times; i++) { + cb(); + } + const t2 = new Date(); + return (t2 - t1) / 1000; +}; + +const maxP = 0; + +const bioSrc = fs.readFileSync( + "/Users/berekuk/Downloads/Bio.squiggle", + "utf-8" +); + +for (let p = 0; p <= maxP; p++) { + const size = Math.pow(10, p); + const prj = s.SqProject.create(); + prj.setSource("main", bioSrc); + const t = measure(() => { + prj.run("main"); + }); + console.log(`1e${p}`, "\t", t); +} diff --git a/packages/squiggle-lang/bench.js b/packages/squiggle-lang/bench.js new file mode 100755 index 00000000..effccdfa --- /dev/null +++ b/packages/squiggle-lang/bench.js @@ -0,0 +1,27 @@ +#!/usr/bin/env node +const s = require("./dist/src/js"); + +const measure = (cb, times = 1) => { + const t1 = new Date(); + + for (let i = 1; i <= times; i++) { + cb(); + } + const t2 = new Date(); + return (t2 - t1) / 1000; +}; + +const maxP = 7; + +for (let p = 0; p <= maxP; p++) { + const size = Math.pow(10, p); + const prj = s.SqProject.create(); + prj.setSource("list", `l = List.upTo(1,${size})`); + prj.run("list"); + prj.setSource("map", "l |> map({|x| x})"); + prj.setContinues("map", ["list"]); + const t = measure(() => { + prj.run("map"); + }); + console.log(`1e${p}`, "\t", t); +} diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Module.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Module.res index e76acbc8..2b164aee 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Module.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Module.res @@ -13,4 +13,4 @@ let toString = (v: squiggleValue_Module): string => let toSquiggleValue = (v: squiggleValue_Module): squiggleValue => IEvBindings(v) @genType -let get = ReducerInterface_InternalExpressionValue.nameSpaceGet +let get = Reducer_Bindings.get 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 68bc6c3a..c9cffcfd 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 @@ -13,23 +13,23 @@ type t = ReducerInterface_InternalExpressionValue.nameSpace let typeAliasesKey = "_typeAliases_" let typeReferencesKey = "_typeReferences_" -let getType = (NameSpace(container): t, id: string) => { - Belt.Map.String.get(container, typeAliasesKey)->Belt.Option.flatMap(aliases => - switch aliases { - | IEvRecord(r) => Belt.Map.String.get(r, id) - | _ => None - } - ) -} +// let getType = (NameSpace(container): t, id: string) => { +// Belt.Map.String.get(container, typeAliasesKey)->Belt.Option.flatMap(aliases => +// switch aliases { +// | IEvRecord(r) => Belt.Map.String.get(r, id) +// | _ => None +// } +// ) +// } -let getTypeOf = (NameSpace(container): t, id: string) => { - Belt.Map.String.get(container, typeReferencesKey)->Belt.Option.flatMap(defs => - switch defs { - | IEvRecord(r) => Belt.Map.String.get(r, id) - | _ => None - } - ) -} +// let getTypeOf = (NameSpace(container): t, id: string) => { +// Belt.Map.String.get(container, typeReferencesKey)->Belt.Option.flatMap(defs => +// switch defs { +// | IEvRecord(r) => Belt.Map.String.get(r, id) +// | _ => None +// } +// ) +// } let getWithDefault = (NameSpace(container): t, id: string, default) => switch Belt.Map.String.get(container, id) { @@ -37,29 +37,40 @@ let getWithDefault = (NameSpace(container): t, id: string, default) => | None => default } -let get = (NameSpace(container): t, id: string) => Belt.Map.String.get(container, id) +let get = (nameSpace: t, id: string) => { + let NameSpace(container, parent) = nameSpace + + switch container->Belt.MutableMap.String.get(key) { + | Some(v) => Some(v) + | None => switch parent { + | Some(p) => nameSpaceGet(p, key) + | None => None + } + } +} + let emptyMap: map = Belt.Map.String.empty -let setTypeAlias = (NameSpace(container): t, id: string, value): t => { - let rValue = Belt.Map.String.getWithDefault(container, typeAliasesKey, IEvRecord(emptyMap)) - let r = switch rValue { - | IEvRecord(r) => r - | _ => emptyMap - } - let r2 = Belt.Map.String.set(r, id, value)->IEvRecord - NameSpace(Belt.Map.String.set(container, typeAliasesKey, r2)) -} +// let setTypeAlias = (NameSpace(container): t, id: string, value): t => { +// let rValue = Belt.Map.String.getWithDefault(container, typeAliasesKey, IEvRecord(emptyMap)) +// let r = switch rValue { +// | IEvRecord(r) => r +// | _ => emptyMap +// } +// let r2 = Belt.Map.String.set(r, id, value)->IEvRecord +// NameSpace(Belt.Map.String.set(container, typeAliasesKey, r2)) +// } -let setTypeOf = (NameSpace(container): t, id: string, value): t => { - let rValue = Belt.Map.String.getWithDefault(container, typeReferencesKey, IEvRecord(emptyMap)) - let r = switch rValue { - | IEvRecord(r) => r - | _ => emptyMap - } - let r2 = Belt.Map.String.set(r, id, value)->IEvRecord - NameSpace(Belt.Map.String.set(container, typeReferencesKey, r2)) -} +// let setTypeOf = (NameSpace(container): t, id: string, value): t => { +// let rValue = Belt.Map.String.getWithDefault(container, typeReferencesKey, IEvRecord(emptyMap)) +// let r = switch rValue { +// | IEvRecord(r) => r +// | _ => emptyMap +// } +// let r2 = Belt.Map.String.set(r, id, value)->IEvRecord +// NameSpace(Belt.Map.String.set(container, typeReferencesKey, r2)) +// } let set = (NameSpace(container): t, id: string, value): t => NameSpace( Belt.Map.String.set(container, id, value), @@ -69,9 +80,6 @@ let emptyModule: t = NameSpace(emptyMap) let emptyBindings = emptyModule let emptyNameSpace = emptyModule -// let fromTypeScriptBindings = ReducerInterface_InternalExpressionValue.nameSpaceFromTypeScriptBindings -// let toTypeScriptBindings = ReducerInterface_InternalExpressionValue.nameSpaceToTypeScriptBindings - let toExpressionValue = (nameSpace: t): internalExpressionValue => IEvBindings(nameSpace) let fromExpressionValue = (aValue: internalExpressionValue): t => switch aValue { diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index b7fed530..74804d4b 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 @@ -89,14 +89,14 @@ let callInternal = ( Bindings.set(bindings, symbol, value)->IEvBindings->Ok } - let doSetTypeAliasBindings = ( - bindings: nameSpace, - symbol: string, - value: internalExpressionValue, - ) => Bindings.setTypeAlias(bindings, symbol, value)->IEvBindings->Ok + // let doSetTypeAliasBindings = ( + // bindings: nameSpace, + // symbol: string, + // value: internalExpressionValue, + // ) => Bindings.setTypeAlias(bindings, symbol, value)->IEvBindings->Ok - let doSetTypeOfBindings = (bindings: nameSpace, symbol: string, value: internalExpressionValue) => - Bindings.setTypeOf(bindings, symbol, value)->IEvBindings->Ok + // let doSetTypeOfBindings = (bindings: nameSpace, symbol: string, value: internalExpressionValue) => + // Bindings.setTypeOf(bindings, symbol, value)->IEvBindings->Ok let doExportBindings = (bindings: nameSpace) => bindings->Bindings.toExpressionValue->Ok @@ -153,30 +153,30 @@ let callInternal = ( | ("$_exportBindings_$", [evValue]) => doIdentity(evValue) | ("$_setBindings_$", [IEvBindings(nameSpace), IEvSymbol(symbol), value]) => doSetBindings(nameSpace, symbol, value) - | ("$_setTypeAliasBindings_$", [IEvBindings(nameSpace), IEvTypeIdentifier(symbol), value]) => - doSetTypeAliasBindings(nameSpace, symbol, value) - | ("$_setTypeOfBindings_$", [IEvBindings(nameSpace), IEvSymbol(symbol), value]) => - doSetTypeOfBindings(nameSpace, symbol, value) + // | ("$_setTypeAliasBindings_$", [IEvBindings(nameSpace), IEvTypeIdentifier(symbol), value]) => + // doSetTypeAliasBindings(nameSpace, symbol, value) + // | ("$_setTypeOfBindings_$", [IEvBindings(nameSpace), IEvSymbol(symbol), value]) => + // doSetTypeOfBindings(nameSpace, symbol, value) | ("$_dumpBindings_$", [IEvBindings(nameSpace), _, evValue]) => doDumpBindings(nameSpace, evValue) - | ("$_typeModifier_memberOf_$", [IEvTypeIdentifier(typeIdentifier), IEvArray(arr)]) => - TypeBuilder.typeModifier_memberOf(IEvTypeIdentifier(typeIdentifier), IEvArray(arr)) - | ("$_typeModifier_memberOf_$", [IEvType(typeRecord), IEvArray(arr)]) => - TypeBuilder.typeModifier_memberOf_update(typeRecord, IEvArray(arr)) - | ("$_typeModifier_min_$", [IEvTypeIdentifier(typeIdentifier), value]) => - TypeBuilder.typeModifier_min(IEvTypeIdentifier(typeIdentifier), value) - | ("$_typeModifier_min_$", [IEvType(typeRecord), value]) => - TypeBuilder.typeModifier_min_update(typeRecord, value) - | ("$_typeModifier_max_$", [IEvTypeIdentifier(typeIdentifier), value]) => - TypeBuilder.typeModifier_max(IEvTypeIdentifier(typeIdentifier), value) - | ("$_typeModifier_max_$", [IEvType(typeRecord), value]) => - TypeBuilder.typeModifier_max_update(typeRecord, value) - | ("$_typeModifier_opaque_$", [IEvType(typeRecord)]) => - TypeBuilder.typeModifier_opaque_update(typeRecord) - | ("$_typeOr_$", [IEvArray(arr)]) => TypeBuilder.typeOr(IEvArray(arr)) - | ("$_typeFunction_$", [IEvArray(arr)]) => TypeBuilder.typeFunction(arr) - | ("$_typeTuple_$", [IEvArray(elems)]) => TypeBuilder.typeTuple(elems) - | ("$_typeArray_$", [elem]) => TypeBuilder.typeArray(elem) - | ("$_typeRecord_$", [IEvRecord(propertyMap)]) => TypeBuilder.typeRecord(propertyMap) + // | ("$_typeModifier_memberOf_$", [IEvTypeIdentifier(typeIdentifier), IEvArray(arr)]) => + // TypeBuilder.typeModifier_memberOf(IEvTypeIdentifier(typeIdentifier), IEvArray(arr)) + // | ("$_typeModifier_memberOf_$", [IEvType(typeRecord), IEvArray(arr)]) => + // TypeBuilder.typeModifier_memberOf_update(typeRecord, IEvArray(arr)) + // | ("$_typeModifier_min_$", [IEvTypeIdentifier(typeIdentifier), value]) => + // TypeBuilder.typeModifier_min(IEvTypeIdentifier(typeIdentifier), value) + // | ("$_typeModifier_min_$", [IEvType(typeRecord), value]) => + // TypeBuilder.typeModifier_min_update(typeRecord, value) + // | ("$_typeModifier_max_$", [IEvTypeIdentifier(typeIdentifier), value]) => + // TypeBuilder.typeModifier_max(IEvTypeIdentifier(typeIdentifier), value) + // | ("$_typeModifier_max_$", [IEvType(typeRecord), value]) => + // TypeBuilder.typeModifier_max_update(typeRecord, value) + // | ("$_typeModifier_opaque_$", [IEvType(typeRecord)]) => + // TypeBuilder.typeModifier_opaque_update(typeRecord) + // | ("$_typeOr_$", [IEvArray(arr)]) => TypeBuilder.typeOr(IEvArray(arr)) + // | ("$_typeFunction_$", [IEvArray(arr)]) => TypeBuilder.typeFunction(arr) + // | ("$_typeTuple_$", [IEvArray(elems)]) => TypeBuilder.typeTuple(elems) + // | ("$_typeArray_$", [elem]) => TypeBuilder.typeArray(elem) + // | ("$_typeRecord_$", [IEvRecord(propertyMap)]) => TypeBuilder.typeRecord(propertyMap) | ("concat", [IEvArray(aValueArray), IEvArray(bValueArray)]) => doAddArray(aValueArray, bValueArray) | ("concat", [IEvString(aValueString), IEvString(bValueString)]) => @@ -204,12 +204,19 @@ let dispatch = ( ): internalExpressionValue => try { let (fn, args) = call - // There is a bug that prevents string match in patterns - // So we have to recreate a copy of the string + if fn->Js.String2.startsWith("$") { + switch callInternal((fn, args), accessors, reducer) { + | Ok(v) => v + | Error(e) => raise(ErrorException(e)) + } + } else { + // There is a bug that prevents string match in patterns + // So we have to recreate a copy of the string switch ExternalLibrary.dispatch((Js.String.make(fn), args), accessors, reducer, callInternal) { | Ok(v) => v | Error(e) => raise(ErrorException(e)) } + } } catch { | ErrorException(e) => raise(ErrorException(e)) | Js.Exn.Error(obj) => diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index 67ed732c..69916c4c 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -47,13 +47,13 @@ let dispatchMacroCall = ( let doBindStatement = (bindingExpr: expression, statement: expression, accessors) => { let defaultStatement = ErrorValue.REAssignmentExpected->ErrorException switch statement { - | ExpressionT.EList(list{ExpressionT.EValue(IEvCall(callName)), symbolExpr, statement}) => { + | ExpressionT.EList(list{ExpressionT.EValue(IEvCall(callName)), ExpressionT.EValue(IEvSymbol(symbolExpr)), statement}) => { let setBindingsFn = correspondingSetBindingsFn(callName) if setBindingsFn !== "" { useExpressionToSetBindings(bindingExpr, accessors, statement, ( newBindingsExpr, boundStatement, - ) => eFunction(setBindingsFn, list{newBindingsExpr, symbolExpr, boundStatement})) + ) => eFunction(setBindingsFn, list{newBindingsExpr, symbolExpr->IEvSymbol->ExpressionT.EValue, boundStatement})) } else { raise(defaultStatement) } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res index 4b957e33..c2d46576 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 @@ -19,37 +19,43 @@ exception ErrorException = Reducer_ErrorValue.ErrorException /* Recursively evaluate/reduce the expression (Lisp AST/Lambda calculus) */ -let rec reduceExpressionInProject = ( +let rec evaluate = ( expression: t, - continuation: T.bindings, + bindings: T.bindings, accessors: ProjectAccessorsT.t, ): InternalExpressionValue.t => { // Js.log(`reduce: ${T.toString(expression)} bindings: ${bindings->Bindings.toString}`) + // Js.log(`reduce: ${T.toString(expression)}`) switch expression { - | T.EValue(value) => value - | T.EList(list) => - switch list { - | list{EValue(IEvCall(fName)), ..._args} => - switch Macro.isMacroName(fName) { - // A macro expands then reduces itself - | true => Macro.doMacroCall(expression, continuation, accessors, reduceExpressionInProject) - | false => reduceExpressionList(list, continuation, accessors) + | T.Eblock(statements) => { + statements->Js.Array2.reduce(statement => evaluate(statement, bindings, accessors)) + } + | T.ESymbol(name) => bindings->nameSpaceGet(name) + | T.EValue(value) => value + | T.ETernary(predicate, trueCase, falseCase) => { + let predicateResult = evaluate(predicate, bindings, accessors) + switch predicateResult { + | InternalExpressionValue.IEvBool(false) => + evaluate(false, bindings, accessors) + | InternalExpressionValue.IEvBool(true) => + evaluate(trueCase, bindings, accessors) + | _ => REExpectedType("Boolean", "")->ErrorException->raise } - | _ => reduceExpressionList(list, continuation, accessors) + } + | T.ELambda(parameteres, expr) => { + BInternalExpressionValue.IEvLambda({ + parameters: parameters, + context: context, + body: NotFFI(expr)->BBindings.castExpressionToInternalCode, + })->T.EValue + } + | T.ECall(fn, args) => { + let func = evaluate(fn, bindings, accessors) + "TODO" + // Lambda.doLambdaCall(), etc. } } } -and reduceExpressionList = ( - expressions: list, - continuation: T.bindings, - accessors: ProjectAccessorsT.t, -): InternalExpressionValue.t => { - let acc: list = - expressions->Belt.List.reduceReverse(list{}, (acc, each: t) => - acc->Belt.List.add(each->reduceExpressionInProject(continuation, accessors)) - ) - acc->reduceValueList(accessors) -} /* After reducing each level of expression(Lisp AST), we have a value list to evaluate @@ -80,6 +86,8 @@ and reduceValueList = ( | _ => valueList->Lambda.checkIfReduced->Belt.List.toArray->InternalExpressionValue.IEvArray } +let reduceExpressionInProject = evaluate + let reduceReturningBindings = ( expression: t, continuation: T.bindings, 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 9cc25725..fa757ca8 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,86 +1,63 @@ module BBindingsReplacer = Reducer_Expression_BindingsReplacer module BErrorValue = Reducer_ErrorValue -module BExpressionT = Reducer_Expression_T +module T = Reducer_Expression_T module BInternalExpressionValue = ReducerInterface_InternalExpressionValue module BBindings = Reducer_Bindings type errorValue = BErrorValue.errorValue -type expression = BExpressionT.expression -type expressionOrFFI = BExpressionT.expressionOrFFI -type ffiFn = BExpressionT.ffiFn +type expression = T.expression +type expressionOrFFI = T.expressionOrFFI +type ffiFn = T.ffiFn type internalCode = ReducerInterface_InternalExpressionValue.internalCode -let eArray = anArray => anArray->BInternalExpressionValue.IEvArray->BExpressionT.EValue +let eArray = anArray => anArray->BInternalExpressionValue.IEvArray->T.EValue -let eArrayString = anArray => anArray->BInternalExpressionValue.IEvArrayString->BExpressionT.EValue +let eArrayString = anArray => anArray->BInternalExpressionValue.IEvArrayString->T.EValue let eBindings = (anArray: array<(string, BInternalExpressionValue.t)>) => - anArray->BBindings.fromArray->BBindings.toExpressionValue->BExpressionT.EValue + anArray->BBindings.fromArray->BBindings.toExpressionValue->T.EValue -let eBool = aBool => aBool->BInternalExpressionValue.IEvBool->BExpressionT.EValue +let eBool = aBool => aBool->BInternalExpressionValue.IEvBool->T.EValue let eCall = (name: string): expression => - name->BInternalExpressionValue.IEvCall->BExpressionT.EValue + name->BInternalExpressionValue.IEvCall->T.EValue let eFunction = (fName: string, lispArgs: list): expression => { let fn = fName->eCall - list{fn, ...lispArgs}->BExpressionT.EList + list{fn, ...lispArgs}->T.EList } let eLambda = ( parameters: array, - context: BInternalExpressionValue.nameSpace, expr: expression, ) => { - BInternalExpressionValue.IEvLambda({ - parameters: parameters, - context: context, - body: NotFFI(expr)->BBindings.castExpressionToInternalCode, - })->BExpressionT.EValue -} + T.ELambda(parameters, expr) -let eLambdaFFI = (ffiFn: ffiFn) => { - ffiFn->BBindings.eLambdaFFIValue->BExpressionT.EValue -} +let eNumber = aNumber => aNumber->BInternalExpressionValue.IEvNumber->T.EValue -let eNumber = aNumber => aNumber->BInternalExpressionValue.IEvNumber->BExpressionT.EValue +let eRecord = aMap => aMap->BInternalExpressionValue.IEvRecord->T.EValue -let eRecord = aMap => aMap->BInternalExpressionValue.IEvRecord->BExpressionT.EValue - -let eString = aString => aString->BInternalExpressionValue.IEvString->BExpressionT.EValue +let eString = aString => aString->BInternalExpressionValue.IEvString->T.EValue let eSymbol = (name: string): expression => - name->BInternalExpressionValue.IEvSymbol->BExpressionT.EValue + T.ESymbol(name) -let eList = (list: list): expression => list->BExpressionT.EList - -let eBlock = (exprs: list): expression => eFunction("$$_block_$$", exprs) +let eBlock = (exprs: array): expression => + T.EBlock(exprs) let eModule = (nameSpace: BInternalExpressionValue.nameSpace): expression => - nameSpace->BInternalExpressionValue.IEvBindings->BExpressionT.EValue + nameSpace->BInternalExpressionValue.IEvBindings->T.EValue let eLetStatement = (symbol: string, valueExpression: expression): expression => - eFunction("$_let_$", list{eSymbol(symbol), valueExpression}) + T.EAssign(symbol, valueExpression) -let eBindStatement = (bindingExpr: expression, letStatement: expression): expression => - eFunction("$$_bindStatement_$$", list{bindingExpr, letStatement}) - -let eBindStatementDefault = (letStatement: expression): expression => - eFunction("$$_bindStatement_$$", list{letStatement}) - -let eBindExpression = (bindingExpr: expression, expression: expression): expression => - eFunction("$$_bindExpression_$$", list{bindingExpr, expression}) - -let eBindExpressionDefault = (expression: expression): expression => - eFunction("$$_bindExpression_$$", list{expression}) - -let eTernary = (truth: expression, trueCase: expression, falseCase: expression): expression => - eFunction("$$_ternary_$$", list{truth, trueCase, falseCase}) +let eTernary = (predicate: expression, trueCase: expression, falseCase: expression): expression => + T.ETernary(predicate, trueCase, falseCase) let eIdentifier = (name: string): expression => - name->BInternalExpressionValue.IEvSymbol->BExpressionT.EValue + name->BInternalExpressionValue.IEvSymbol->T.EValue let eTypeIdentifier = (name: string): expression => - name->BInternalExpressionValue.IEvTypeIdentifier->BExpressionT.EValue + name->BInternalExpressionValue.IEvTypeIdentifier->T.EValue -let eVoid: expression = BInternalExpressionValue.IEvVoid->BExpressionT.EValue +let eVoid: expression = BInternalExpressionValue.IEvVoid->T.EValue diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_T.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_T.res index 61f723df..bc98082d 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 @@ -13,8 +13,13 @@ type internalExpressionValue = InternalExpressionValue.t type environment = ReducerInterface_InternalExpressionValue.environment type rec expression = - | EList(list) // A list to map-reduce - | EValue(internalExpressionValue) // Irreducible built-in value. Reducer should not know the internals. External libraries are responsible + | EBlock(array) + | ESymbol(string) + | ETernary(expression, expression, expression) + | EAssign(string, expression) + | ECall(expression, array) + | ELambda(array, expression) + | EValue(internalExpressionValue) and bindings = InternalExpressionValue.nameSpace type t = expression @@ -28,20 +33,20 @@ type reducerFn = ( /* Converts the expression to String */ -let rec toString = expression => - switch expression { - | EList(list{EValue(IEvCall("$$_block_$$")), ...statements}) => - `{${Belt.List.map(statements, aValue => toString(aValue)) - ->Extra.List.intersperse("; ") - ->Belt.List.toArray - ->Js.String.concatMany("")}}` - | EList(aList) => - `(${Belt.List.map(aList, aValue => toString(aValue)) - ->Extra.List.intersperse(" ") - ->Belt.List.toArray - ->Js.String.concatMany("")})` - | EValue(aValue) => InternalExpressionValue.toString(aValue) - } +let rec toString = expression => "TODO" + // switch expression { + // | EList(list{EValue(IEvCall("$$_block_$$")), ...statements}) => + // `{${Belt.List.map(statements, aValue => toString(aValue)) + // ->Extra.List.intersperse("; ") + // ->Belt.List.toArray + // ->Js.String.concatMany("")}}` + // | EList(aList) => + // `(${Belt.List.map(aList, aValue => toString(aValue)) + // ->Extra.List.intersperse(" ") + // ->Belt.List.toArray + // ->Js.String.concatMany("")})` + // | EValue(aValue) => InternalExpressionValue.toString(aValue) + // } let toStringResult = codeResult => switch codeResult { diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy index 646dae5a..deaddd57 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy @@ -168,7 +168,7 @@ chainFunctionCall unary = unaryOperator:unaryOperator _nl right:(unary/postOperator) - { return h.apply(h.unaryToFunction[unaryOperator], right)} + { return h.makeFunctionCall(h.unaryToFunction[unaryOperator], [right])} / postOperator unaryOperator "unary operator" @@ -247,7 +247,7 @@ number = number:(float / integer) unit:unitIdentifier? if (unit === null) { return number } else - { return h.apply('fromUnit_'+unit.value, number) + { return h.makeFunctionCall('fromUnit_'+unit.value, [number]) } } @@ -357,10 +357,10 @@ typePostModifierExpression = head:typeOr tail:(_ '$' _nl @typeModifier)* } typeOr = head:typeFunction tail:(_ '|' _nl @typeFunction)* - { return tail.length === 0 ? head : h.apply('$_typeOr_$', h.constructArray([head, ...tail])); } + { return tail.length === 0 ? head : h.makeFunctionCall('$_typeOr_$', [h.constructArray([head, ...tail])]); } typeFunction = head:typeModifierExpression tail:(_ '=>' _nl @typeModifierExpression)* - { return tail.length === 0 ? head : h.apply( '$_typeFunction_$', h.constructArray([head, ...tail])); } + { return tail.length === 0 ? head : h.makeFunctionCall( '$_typeFunction_$', [h.constructArray([head, ...tail])]); } typeModifierExpression = head:basicType tail:(_ '<-' _nl @typeModifier)* { @@ -378,17 +378,17 @@ typeModifierExpression = head:basicType tail:(_ '<-' _nl @typeModifier)* basicType = typeConstructor / typeArray / typeTuple / typeRecord / typeInParanthesis / typeIdentifier typeArray = '[' _nl elem:typeExpression _nl ']' - {return h.apply('$_typeArray_$', elem)} + {return h.makeFunctionCall('$_typeArray_$', [elem])} typeTuple = '[' _nl elems:array_typeTupleArguments _nl ']' - { return h.apply('$_typeTuple_$', h.constructArray(elems))} + { return h.makeFunctionCall('$_typeTuple_$', [h.constructArray(elems)])} array_typeTupleArguments = head:typeExpression tail:(_ ',' _nl @typeExpression)* { return [head, ...tail]; } typeRecord = '{' _nl elems:array_typeRecordArguments _nl '}' - { return h.apply('$_typeRecord_$', h.constructRecord(elems)); } + { return h.makeFunctionCall('$_typeRecord_$', [h.constructRecord(elems)]); } array_typeRecordArguments = head:typeKeyValuePair tail:(_ ',' _nl @typeKeyValuePair)* 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 8ecff48c..61c4e0af 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 @@ -21,8 +21,7 @@ let parse = (expr: string): result => type nodeBlock = {...node, "statements": array} type nodeBoolean = {...node, "value": bool} -type nodeCallIdentifier = {...node, "value": string} -type nodeExpression = {...node, "nodes": array} +type nodeCall = {...node, "fn": node, "args": array} type nodeFloat = {...node, "value": float} type nodeIdentifier = {...node, "value": string} type nodeInteger = {...node, "value": int} @@ -38,9 +37,8 @@ type nodeVoid = node type peggyNode = | PgNodeBlock(nodeBlock) | PgNodeBoolean(nodeBoolean) - | PgNodeCallIdentifier(nodeCallIdentifier) - | PgNodeExpression(nodeExpression) | PgNodeFloat(nodeFloat) + | PgNodeCall(nodeCall) | PgNodeIdentifier(nodeIdentifier) | PgNodeInteger(nodeInteger) | PgNodeKeyValue(nodeKeyValue) @@ -54,8 +52,7 @@ type peggyNode = external castNodeBlock: node => nodeBlock = "%identity" external castNodeBoolean: node => nodeBoolean = "%identity" -external castNodeCallIdentifier: node => nodeCallIdentifier = "%identity" -external castNodeExpression: node => nodeExpression = "%identity" +external castNodeCall: node => nodeCall = "%identity" external castNodeFloat: node => nodeFloat = "%identity" external castNodeIdentifier: node => nodeIdentifier = "%identity" external castNodeInteger: node => nodeInteger = "%identity" @@ -73,8 +70,7 @@ let castNodeType = (node: node) => switch node["type"] { | "Block" => node->castNodeBlock->PgNodeBlock | "Boolean" => node->castNodeBoolean->PgNodeBoolean - | "CallIdentifier" => node->castNodeCallIdentifier->PgNodeCallIdentifier - | "Expression" => node->castNodeExpression->PgNodeExpression + | "Call" => node->castNodeCall->PgNodeCall | "Float" => node->castNodeFloat->PgNodeFloat | "Identifier" => node->castNodeIdentifier->PgNodeIdentifier | "Integer" => node->castNodeInteger->PgNodeInteger @@ -99,8 +95,7 @@ let rec pgToString = (peggyNode: peggyNode): string => { switch peggyNode { | PgNodeBlock(node) => "{" ++ node["statements"]->nodesToStringUsingSeparator("; ") ++ "}" | PgNodeBoolean(node) => node["value"]->Js.String.make - | PgNodeCallIdentifier(node) => `::${Js.String.make(node["value"])}` // This is an identifier also but for function names - | PgNodeExpression(node) => "(" ++ node["nodes"]->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 73247a8e..a14dca34 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 @@ -6,23 +6,22 @@ type expression = ExpressionT.expression let rec fromNode = (node: Parse.node): expression => { let caseBlock = nodeBlock => - ExpressionBuilder.eBlock(nodeBlock["statements"]->Js.Array2.map(fromNode)->Belt.List.fromArray) + ExpressionBuilder.eBlock(nodeBlock["statements"]->Js.Array2.map(fromNode)) let caseLambda = (nodeLambda: Parse.nodeLambda): expression => { let args = nodeLambda["args"] ->Js.Array2.map((argNode: Parse.nodeIdentifier) => argNode["value"]) - ->ExpressionBuilder.eArrayString let body = nodeLambda["body"]->caseBlock - ExpressionBuilder.eFunction("$$_lambda_$$", list{args, body}) + + ExpressionBuilder.eLambda(args, body) } switch Parse.castNodeType(node) { | PgNodeBlock(nodeBlock) => caseBlock(nodeBlock) | PgNodeBoolean(nodeBoolean) => ExpressionBuilder.eBool(nodeBoolean["value"]) - | PgNodeCallIdentifier(nodeCallIdentifier) => ExpressionBuilder.eCall(nodeCallIdentifier["value"]) | PgNodeExpression(nodeExpression) => - ExpressionT.EList(nodeExpression["nodes"]->Js.Array2.map(fromNode)->Belt.List.fromArray) + ExpressionT.EList(nodeExpression["nodes"]->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"])) @@ -38,13 +37,10 @@ let rec fromNode = (node: Parse.node): expression => { ExpressionBuilder.eIdentifier(nodeModuleIdentifier["value"]) | PgNodeString(nodeString) => ExpressionBuilder.eString(nodeString["value"]) | PgNodeTernary(nodeTernary) => - ExpressionBuilder.eFunction( - "$$_ternary_$$", - list{ - fromNode(nodeTernary["condition"]), - fromNode(nodeTernary["trueExpression"]), - fromNode(nodeTernary["falseExpression"]), - }, + ExpressionBuilder.eTernary( + fromNode(nodeTernary["condition"]), + fromNode(nodeTernary["trueExpression"]), + fromNode(nodeTernary["falseExpression"]) ) | PgNodeTypeIdentifier(nodeTypeIdentifier) => ExpressionBuilder.eTypeIdentifier(nodeTypeIdentifier["value"]) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts index 394796f5..330f23e9 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts @@ -40,9 +40,10 @@ type NodeBlock = { statements: AnyPeggyNode[]; }; -type NodeExpression = { - type: "Expression"; - nodes: AnyPeggyNode[]; +type NodeCall = { + type: "Call"; + fn: AnyPeggyNode; + args: AnyPeggyNode[]; }; type NodeFloat = { @@ -58,12 +59,6 @@ type NodeInteger = { type NodeIdentifier = { type: "Identifier"; value: string; - location: LocationRange; -}; - -type NodeCallIdentifier = { - type: "CallIdentifier"; - value: string; }; type NodeLetStatement = { @@ -104,11 +99,10 @@ type NodeBoolean = { export type AnyPeggyNode = | NodeBlock - | NodeExpression + | NodeCall | NodeFloat | NodeInteger | NodeIdentifier - | NodeCallIdentifier | NodeLetStatement | NodeLambda | NodeTernary @@ -117,30 +111,14 @@ export type AnyPeggyNode = | NodeBoolean; export function makeFunctionCall(fn: string, args: AnyPeggyNode[]) { - if (fn === "$$_applyAll_$$") { - // Any list of values is applied from left to right anyway. - // Like in Haskell and Lisp. - // So we remove the redundant $$_applyAll_$$. - if (args[0].type === "Identifier") { - args[0] = { - ...args[0], - type: "CallIdentifier", - }; - } - return nodeExpression(args); - } else { - return nodeExpression([nodeCallIndentifier(fn), ...args]); - } + return nodeCall(nodeIdentifier(fn), args); } -export function apply(fn: string, arg: AnyPeggyNode) { - return makeFunctionCall(fn, [arg]); -} export function constructArray(elems: AnyPeggyNode[]) { return makeFunctionCall("$_constructArray_$", elems); } export function constructRecord(elems: AnyPeggyNode[]) { - return apply("$_constructRecord_$", nodeExpression(elems)); + return makeFunctionCall("$_constructRecord_$", elems); } export function nodeBlock(statements: AnyPeggyNode[]): NodeBlock { @@ -149,20 +127,14 @@ export function nodeBlock(statements: AnyPeggyNode[]): NodeBlock { export function nodeBoolean(value: boolean): NodeBoolean { return { type: "Boolean", value }; } -export function nodeCallIndentifier(value: string): NodeCallIdentifier { - return { type: "CallIdentifier", value }; -} -export function nodeExpression(args: AnyPeggyNode[]): NodeExpression { - return { type: "Expression", nodes: args }; +export function nodeCall(fn: AnyPeggyNode, args: AnyPeggyNode[]): NodeCall { + return { type: "Call", fn, args }; } export function nodeFloat(value: number): NodeFloat { return { type: "Float", value }; } -export function nodeIdentifier( - value: string, - location: LocationRange -): NodeIdentifier { - return { type: "Identifier", value, location }; +export function nodeIdentifier(value: string): NodeIdentifier { + return { type: "Identifier", value }; } export function nodeInteger(value: number): NodeInteger { return { type: "Integer", value }; diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res index 34eb6f40..4144c016 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res @@ -26,7 +26,7 @@ type rec t = | IEvVoid @genType.opaque and squiggleArray = array @genType.opaque and map = Belt.Map.String.t -@genType.opaque and nameSpace = NameSpace(Belt.Map.String.t) +@genType.opaque and nameSpace = NameSpace(Belt.MutableMap.String.t, option) @genType.opaque and lambdaValue = { parameters: array, @@ -94,7 +94,8 @@ and toStringMap = aMap => { `{${pairs}}` } and toStringNameSpace = nameSpace => { - let NameSpace(container) = nameSpace + let NameSpace(container, parent) = nameSpace + FIXME_CALL_PARENTS container->toStringMap } @@ -228,19 +229,8 @@ let arrayToValueArray = (arr: array): array => arr let recordToKeyValuePairs = (record: map): array<(string, t)> => record->Belt.Map.String.toArray -// let nameSpaceToTypeScriptBindings = ( -// nameSpace: nameSpace, -// ) => { -// let NameSpace(container) = nameSpace -// Belt.Map.String.map(container, e => e->Belt.Map.String.toArray->Js.Dict.fromArray) -// } - let nameSpaceToKeyValuePairs = (nameSpace: nameSpace): array<(string, t)> => { - let NameSpace(container) = nameSpace - container->Belt.Map.String.toArray -} - -let nameSpaceGet = (nameSpace: nameSpace, key: string): option => { - let NameSpace(container) = nameSpace - container->Belt.Map.String.get(key) + let NameSpace(container, parent) = nameSpace + FIXME_CALL_PARENTS + container->Belt.MutableMap.String.toArray } diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js index 06e710d6..7f9c0418 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js @@ -5,9 +5,7 @@ "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(); } @@ -29,15 +27,13 @@ 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; @@ -52,24 +48,15 @@ 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; } @@ -77,35 +64,33 @@ 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) { @@ -115,17 +100,13 @@ 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) { @@ -133,17 +114,13 @@ 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) { @@ -174,25 +151,17 @@ 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) { @@ -208,7 +177,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 = "*/"; @@ -228,8 +197,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); @@ -243,36 +212,16 @@ 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 }]; @@ -286,9 +235,7 @@ 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]; @@ -306,7 +253,7 @@ function peg$parse(input, options) { return { source: peg$source, start: peg$savedPos, - end: peg$currPos, + end: peg$currPos }; } @@ -315,10 +262,9 @@ 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)], @@ -328,10 +274,9 @@ 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); } @@ -341,12 +286,7 @@ 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() { @@ -376,7 +316,7 @@ function peg$parse(input, options) { details = peg$posDetailsCache[p]; details = { line: details.line, - column: details.column, + column: details.column }; while (p < pos) { @@ -405,20 +345,18 @@ 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; @@ -578,9 +516,7 @@ 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) { @@ -650,9 +586,7 @@ 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 = []; @@ -685,9 +619,7 @@ 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 = []; @@ -784,9 +716,7 @@ 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 = []; @@ -795,9 +725,7 @@ 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); @@ -806,9 +734,7 @@ 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) { @@ -816,9 +742,7 @@ 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; @@ -843,9 +767,7 @@ 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 = []; @@ -854,9 +776,7 @@ 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); @@ -865,9 +785,7 @@ 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) { @@ -875,9 +793,7 @@ 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; @@ -898,9 +814,7 @@ 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 }; @@ -963,9 +877,7 @@ 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 = []; @@ -998,9 +910,7 @@ 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 }; @@ -1027,9 +937,7 @@ 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 = []; @@ -1038,9 +946,7 @@ 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); @@ -1049,9 +955,7 @@ 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) { @@ -1059,9 +963,7 @@ 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; @@ -1077,9 +979,7 @@ 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 }; @@ -1105,16 +1005,12 @@ 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 }; @@ -1140,16 +1036,12 @@ 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 }; @@ -1175,16 +1067,12 @@ 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 }; @@ -1213,9 +1101,7 @@ 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) { @@ -1225,9 +1111,7 @@ 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 { @@ -1240,9 +1124,7 @@ 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); @@ -1251,9 +1133,7 @@ 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]; @@ -1270,9 +1150,7 @@ 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 }; @@ -1301,5 +1179,5 @@ function peg$parse(input, options) { module.exports = { SyntaxError: peg$SyntaxError, - parse: peg$parse, + parse: peg$parse }; From 7a29be38454d3fcbaa6acea8152fb17598eeab29 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Sun, 11 Sep 2022 19:22:07 +0400 Subject: [PATCH 02/46] WIP (basic functionality, stdlib not converted yet) --- .../Reducer_Bindings_test.res | 12 +- .../Reducer_Dispatch_BuiltInMacros_test.res | 278 +++++------ .../__tests__/Reducer/Reducer_Helpers.res | 18 +- .../__tests__/Reducer/Reducer_TestHelpers.res | 2 +- .../Reducer/Reducer_TestMacroHelpers.res | 165 ++++--- .../Reducer_Type_Compile_test.res | 88 ++-- ...educer_Type_TypeChecker_arguments_test.res | 72 +-- .../Reducer_Type_TypeChecker_test.res | 132 ++--- .../Reducer_Type_switch_replacement_test.res | 223 +++++---- .../ReducerProject_includes_test.res | 220 ++++----- .../ReducerProject/ReducerProject_test.res | 12 +- .../ReducerProject_tutorial_1_test.res | 2 +- packages/squiggle-lang/src/js/SqValue.ts | 32 +- packages/squiggle-lang/src/js/index.ts | 2 +- .../rescript/ForTS/ForTS_ReducerProject.res | 52 +- .../ForTS_SquiggleValue.res | 46 +- .../ForTS_SquiggleValue_Declaration.res | 2 +- .../ForTS_SquiggleValue_Lambda.res | 2 +- .../ForTS_SquiggleValue_Module.res | 4 +- .../ForTS_SquiggleValue_tag.ts | 4 +- .../FunctionRegistry_Core.res | 28 +- .../FunctionRegistry_Helpers.res | 10 +- .../FunctionRegistry/Library/FR_Danger.res | 18 +- .../FunctionRegistry/Library/FR_Dict.res | 2 +- .../FunctionRegistry/Library/FR_Dist.res | 16 +- .../FunctionRegistry/Library/FR_Fn.res | 2 +- .../FunctionRegistry/Library/FR_List.res | 53 +- .../FunctionRegistry/Library/FR_Pointset.res | 18 +- .../FunctionRegistry/Library/FR_Sampleset.res | 58 ++- .../FunctionRegistry/Library/FR_Scoring.res | 16 +- .../Reducer_Bindings/Reducer_Bindings.res | 275 +++++------ .../src/rescript/Reducer/Reducer_Context.res | 14 + .../Reducer_Dispatch/Reducer_Dispatch.res | 2 - .../Reducer_Dispatch_BuiltIn.res | 127 ++--- .../Reducer_Dispatch_BuiltInMacros.res | 347 +++++++------ .../Reducer_Dispatch_ChainPiece.res | 42 +- .../Reducer_Dispatch/Reducer_Dispatch_T.res | 37 +- .../Reducer_Expression/Reducer_Expression.res | 145 +++--- .../Reducer_ExpressionWithContext.res | 91 ++-- .../Reducer_Expression_BindingsReplacer.res | 90 ++-- .../Reducer_Expression_ExpressionBuilder.res | 52 +- .../Reducer_Expression_Lambda.res | 136 ++--- .../Reducer_Expression_Macro.res | 46 +- .../Reducer_Expression_T.res | 54 +- .../Reducer_Peggy_GeneratedParser.peggy | 154 +++--- .../Reducer_Peggy/Reducer_Peggy_Parse.res | 18 +- .../Reducer_Peggy_ToExpression.res | 15 +- .../rescript/Reducer/Reducer_Peggy/helpers.ts | 15 +- .../src/rescript/Reducer/Reducer_T.res | 53 ++ .../Reducer_Type/Reducer_Type_Compile.res | 75 ++- .../Reducer/Reducer_Type/Reducer_Type_T.res | 220 ++++----- .../Reducer_Type/Reducer_Type_TypeBuilder.res | 136 ++--- .../Reducer_Type/Reducer_Type_TypeChecker.res | 339 +++++++------ .../ReducerInterface_Date.res | 21 +- .../ReducerInterface_Duration.res | 41 +- .../ReducerInterface_ExternalLibrary.res | 23 +- .../ReducerInterface_GenericDistribution.res | 4 +- ...ducerInterface_InternalExpressionValue.res | 92 ++-- .../ReducerInterface_Number.res | 2 +- .../ReducerInterface_StdLib.res | 8 +- .../ReducerInterface_Value_Continuation.res | 10 +- .../ReducerProject/ReducerProject.res | 464 +++++++++--------- .../ReducerProject_ProjectAccessors_T.res | 60 +-- .../ReducerProject_ProjectItem.res | 194 ++++---- .../ReducerProject_ProjectItem_T.res | 32 +- .../ReducerProject_ReducerFn_T.res | 5 - .../ReducerProject/ReducerProject_T.res | 40 +- .../ReducerProject_Topology.res | 10 +- .../SquiggleLibrary/SquiggleLibrary_Math.res | 2 +- .../SquiggleLibrary_Versions.res | 6 +- 70 files changed, 2472 insertions(+), 2614 deletions(-) create mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res delete mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch.res create mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res delete mode 100644 packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ReducerFn_T.res diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Bindings/Reducer_Bindings_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Bindings/Reducer_Bindings_test.res index 9079acfa..8b9f2064 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Bindings/Reducer_Bindings_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Bindings/Reducer_Bindings_test.res @@ -7,21 +7,21 @@ open Expect open Expect.Operators describe("Name Space", () => { - let value = InternalExpressionValue.IEvNumber(1967.0) - let nameSpace = Bindings.emptyNameSpace->Bindings.set("value", value) + let value = Reducer_T.IEvNumber(1967.0) + let nameSpace = Bindings.makeEmptyBindings()->Bindings.set("value", value) test("get", () => { expect(Bindings.get(nameSpace, "value")) == Some(value) }) test("chain and get", () => { - let mainNameSpace = Bindings.emptyNameSpace->Bindings.chainTo([nameSpace]) + let mainNameSpace = Bindings.makeEmptyBindings()->Bindings.chainTo([nameSpace]) expect(Bindings.get(mainNameSpace, "value")) == Some(value) }) test("chain and set", () => { - let mainNameSpace0 = Bindings.emptyNameSpace->Bindings.chainTo([nameSpace]) + let mainNameSpace0 = Bindings.makeEmptyBindings()->Bindings.chainTo([nameSpace]) let mainNameSpace = - mainNameSpace0->Bindings.set("value", InternalExpressionValue.IEvNumber(1968.0)) - expect(Bindings.get(mainNameSpace, "value")) == Some(InternalExpressionValue.IEvNumber(1968.0)) + mainNameSpace0->Bindings.set("value", Reducer_T.IEvNumber(1968.0)) + expect(Bindings.get(mainNameSpace, "value")) == Some(Reducer_T.IEvNumber(1968.0)) }) }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros_test.res index 84659ed7..7e667acd 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros_test.res @@ -1,146 +1,146 @@ -open Jest -// open Expect +// open Jest +// // open Expect -open Reducer_Expression_ExpressionBuilder -open Reducer_TestMacroHelpers -module ExpressionT = Reducer_Expression_T +// open Reducer_Expression_ExpressionBuilder +// open Reducer_TestMacroHelpers +// module ExpressionT = Reducer_Expression_T -let exampleExpression = eNumber(1.) -let exampleExpressionY = eSymbol("y") -let exampleStatementY = eLetStatement("y", eNumber(1.)) -let exampleStatementX = eLetStatement("y", eSymbol("x")) -let exampleStatementZ = eLetStatement("z", eSymbol("y")) +// let exampleExpression = eNumber(1.) +// let exampleExpressionY = eSymbol("y") +// let exampleStatementY = eLetStatement("y", eNumber(1.)) +// let exampleStatementX = eLetStatement("y", eSymbol("x")) +// let exampleStatementZ = eLetStatement("z", eSymbol("y")) -// If it is not a macro then it is not expanded -testMacro([], exampleExpression, "Ok(1)") +// // If it is not a macro then it is not expanded +// testMacro([], exampleExpression, "Ok(1)") -describe("bindStatement", () => { - // A statement is bound by the bindings created by the previous statement - testMacro( - [], - eBindStatement(eBindings([]), exampleStatementY), - "Ok((:$_setBindings_$ @{} :y 1) context: @{})", - ) - // Then it answers the bindings for the next statement when reduced - testMacroEval([], eBindStatement(eBindings([]), exampleStatementY), "Ok(@{y: 1})") - // Now let's feed a binding to see what happens - testMacro( - [], - eBindStatement(eBindings([("x", IEvNumber(2.))]), exampleStatementX), - "Ok((:$_setBindings_$ @{x: 2} :y 2) context: @{x: 2})", - ) - // An expression does not return a binding, thus error - testMacro([], eBindStatement(eBindings([]), exampleExpression), "Assignment expected") - // When bindings from previous statement are missing the context is injected. This must be the first statement of a block - testMacro( - [("z", IEvNumber(99.))], - eBindStatementDefault(exampleStatementY), - "Ok((:$_setBindings_$ @{z: 99} :y 1) context: @{z: 99})", - ) -}) +// describe("bindStatement", () => { +// // A statement is bound by the bindings created by the previous statement +// testMacro( +// [], +// eBindStatement(eBindings([]), exampleStatementY), +// "Ok((:$_setBindings_$ @{} :y 1) context: @{})", +// ) +// // Then it answers the bindings for the next statement when reduced +// testMacroEval([], eBindStatement(eBindings([]), exampleStatementY), "Ok(@{y: 1})") +// // Now let's feed a binding to see what happens +// testMacro( +// [], +// eBindStatement(eBindings([("x", IEvNumber(2.))]), exampleStatementX), +// "Ok((:$_setBindings_$ @{x: 2} :y 2) context: @{x: 2})", +// ) +// // An expression does not return a binding, thus error +// testMacro([], eBindStatement(eBindings([]), exampleExpression), "Assignment expected") +// // When bindings from previous statement are missing the context is injected. This must be the first statement of a block +// testMacro( +// [("z", IEvNumber(99.))], +// eBindStatementDefault(exampleStatementY), +// "Ok((:$_setBindings_$ @{z: 99} :y 1) context: @{z: 99})", +// ) +// }) -describe("bindExpression", () => { - // x is simply bound in the expression - testMacro( - [], - eBindExpression(eBindings([("x", IEvNumber(2.))]), eSymbol("x")), - "Ok(2 context: @{x: 2})", - ) - // When an let statement is the end expression then bindings are returned - testMacro( - [], - eBindExpression(eBindings([("x", IEvNumber(2.))]), exampleStatementY), - "Ok((:$_exportBindings_$ (:$_setBindings_$ @{x: 2} :y 1)) context: @{x: 2})", - ) - // Now let's reduce that expression - testMacroEval( - [], - eBindExpression(eBindings([("x", IEvNumber(2.))]), exampleStatementY), - "Ok(@{x: 2,y: 1})", - ) - // When bindings are missing the context is injected. This must be the first and last statement of a block - testMacroEval( - [("z", IEvNumber(99.))], - eBindExpressionDefault(exampleStatementY), - "Ok(@{y: 1,z: 99})", - ) -}) +// describe("bindExpression", () => { +// // x is simply bound in the expression +// testMacro( +// [], +// eBindExpression(eBindings([("x", IEvNumber(2.))]), eSymbol("x")), +// "Ok(2 context: @{x: 2})", +// ) +// // When an let statement is the end expression then bindings are returned +// testMacro( +// [], +// eBindExpression(eBindings([("x", IEvNumber(2.))]), exampleStatementY), +// "Ok((:$_exportBindings_$ (:$_setBindings_$ @{x: 2} :y 1)) context: @{x: 2})", +// ) +// // Now let's reduce that expression +// testMacroEval( +// [], +// eBindExpression(eBindings([("x", IEvNumber(2.))]), exampleStatementY), +// "Ok(@{x: 2,y: 1})", +// ) +// // When bindings are missing the context is injected. This must be the first and last statement of a block +// testMacroEval( +// [("z", IEvNumber(99.))], +// eBindExpressionDefault(exampleStatementY), +// "Ok(@{y: 1,z: 99})", +// ) +// }) -describe("block", () => { - // Block with a single expression - testMacro([], eBlock(list{exampleExpression}), "Ok((:$$_bindExpression_$$ 1))") - testMacroEval([], eBlock(list{exampleExpression}), "Ok(1)") - // Block with a single statement - testMacro([], eBlock(list{exampleStatementY}), "Ok((:$$_bindExpression_$$ (:$_let_$ :y 1)))") - testMacroEval([], eBlock(list{exampleStatementY}), "Ok(@{y: 1})") - // Block with a statement and an expression - testMacro( - [], - eBlock(list{exampleStatementY, exampleExpressionY}), - "Ok((:$$_bindExpression_$$ (:$$_bindStatement_$$ (:$_let_$ :y 1)) :y))", - ) - testMacroEval([], eBlock(list{exampleStatementY, exampleExpressionY}), "Ok(1)") - // Block with a statement and another statement - testMacro( - [], - eBlock(list{exampleStatementY, exampleStatementZ}), - "Ok((:$$_bindExpression_$$ (:$$_bindStatement_$$ (:$_let_$ :y 1)) (:$_let_$ :z :y)))", - ) - testMacroEval([], eBlock(list{exampleStatementY, exampleStatementZ}), "Ok(@{y: 1,z: 1})") - // Block inside a block - testMacro([], eBlock(list{eBlock(list{exampleExpression})}), "Ok((:$$_bindExpression_$$ {1}))") - testMacroEval([], eBlock(list{eBlock(list{exampleExpression})}), "Ok(1)") - // Block assigned to a variable - testMacro( - [], - eBlock(list{eLetStatement("z", eBlock(list{eBlock(list{exampleExpressionY})}))}), - "Ok((:$$_bindExpression_$$ (:$_let_$ :z {{:y}})))", - ) - testMacroEval( - [], - eBlock(list{eLetStatement("z", eBlock(list{eBlock(list{exampleExpressionY})}))}), - "Ok(@{z: :y})", - ) - // Empty block - testMacro([], eBlock(list{}), "Ok(:undefined block)") //TODO: should be an error - // :$$_block_$$ (:$$_block_$$ (:$_let_$ :y (:add :x 1)) :y)" - testMacro( - [], - eBlock(list{ - eBlock(list{ - eLetStatement("y", eFunction("add", list{eSymbol("x"), eNumber(1.)})), - eSymbol("y"), - }), - }), - "Ok((:$$_bindExpression_$$ {(:$_let_$ :y (:add :x 1)); :y}))", - ) - testMacroEval( - [("x", IEvNumber(1.))], - eBlock(list{ - eBlock(list{ - eLetStatement("y", eFunction("add", list{eSymbol("x"), eNumber(1.)})), - eSymbol("y"), - }), - }), - "Ok(2)", - ) -}) +// describe("block", () => { +// // Block with a single expression +// testMacro([], eBlock(list{exampleExpression}), "Ok((:$$_bindExpression_$$ 1))") +// testMacroEval([], eBlock(list{exampleExpression}), "Ok(1)") +// // Block with a single statement +// testMacro([], eBlock(list{exampleStatementY}), "Ok((:$$_bindExpression_$$ (:$_let_$ :y 1)))") +// testMacroEval([], eBlock(list{exampleStatementY}), "Ok(@{y: 1})") +// // Block with a statement and an expression +// testMacro( +// [], +// eBlock(list{exampleStatementY, exampleExpressionY}), +// "Ok((:$$_bindExpression_$$ (:$$_bindStatement_$$ (:$_let_$ :y 1)) :y))", +// ) +// testMacroEval([], eBlock(list{exampleStatementY, exampleExpressionY}), "Ok(1)") +// // Block with a statement and another statement +// testMacro( +// [], +// eBlock(list{exampleStatementY, exampleStatementZ}), +// "Ok((:$$_bindExpression_$$ (:$$_bindStatement_$$ (:$_let_$ :y 1)) (:$_let_$ :z :y)))", +// ) +// testMacroEval([], eBlock(list{exampleStatementY, exampleStatementZ}), "Ok(@{y: 1,z: 1})") +// // Block inside a block +// testMacro([], eBlock(list{eBlock(list{exampleExpression})}), "Ok((:$$_bindExpression_$$ {1}))") +// testMacroEval([], eBlock(list{eBlock(list{exampleExpression})}), "Ok(1)") +// // Block assigned to a variable +// testMacro( +// [], +// eBlock(list{eLetStatement("z", eBlock(list{eBlock(list{exampleExpressionY})}))}), +// "Ok((:$$_bindExpression_$$ (:$_let_$ :z {{:y}})))", +// ) +// testMacroEval( +// [], +// eBlock(list{eLetStatement("z", eBlock(list{eBlock(list{exampleExpressionY})}))}), +// "Ok(@{z: :y})", +// ) +// // Empty block +// testMacro([], eBlock(list{}), "Ok(:undefined block)") //TODO: should be an error +// // :$$_block_$$ (:$$_block_$$ (:$_let_$ :y (:add :x 1)) :y)" +// testMacro( +// [], +// eBlock(list{ +// eBlock(list{ +// eLetStatement("y", eFunction("add", list{eSymbol("x"), eNumber(1.)})), +// eSymbol("y"), +// }), +// }), +// "Ok((:$$_bindExpression_$$ {(:$_let_$ :y (:add :x 1)); :y}))", +// ) +// testMacroEval( +// [("x", IEvNumber(1.))], +// eBlock(list{ +// eBlock(list{ +// eLetStatement("y", eFunction("add", list{eSymbol("x"), eNumber(1.)})), +// eSymbol("y"), +// }), +// }), +// "Ok(2)", +// ) +// }) -describe("lambda", () => { - // assign a lambda to a variable - let lambdaExpression = eFunction("$$_lambda_$$", list{eArrayString(["y"]), exampleExpressionY}) - testMacro([], lambdaExpression, "Ok(lambda(y=>internal code))") - // call a lambda - let callLambdaExpression = list{lambdaExpression, eNumber(1.)}->ExpressionT.EList - testMacro([], callLambdaExpression, "Ok(((:$$_lambda_$$ [y] :y) 1))") - testMacroEval([], callLambdaExpression, "Ok(1)") - // Parameters shadow the outer scope - testMacroEval([("y", IEvNumber(666.))], callLambdaExpression, "Ok(1)") - // When not shadowed by the parameters, the outer scope variables are available - let lambdaExpression = eFunction( - "$$_lambda_$$", - list{eArrayString(["z"]), eFunction("add", list{eSymbol("y"), eSymbol("z")})}, - ) - let callLambdaExpression = eList(list{lambdaExpression, eNumber(1.)}) - testMacroEval([("y", IEvNumber(666.))], callLambdaExpression, "Ok(667)") -}) +// describe("lambda", () => { +// // assign a lambda to a variable +// let lambdaExpression = eFunction("$$_lambda_$$", list{eArrayString(["y"]), exampleExpressionY}) +// testMacro([], lambdaExpression, "Ok(lambda(y=>internal code))") +// // call a lambda +// let callLambdaExpression = list{lambdaExpression, eNumber(1.)}->ExpressionT.EList +// testMacro([], callLambdaExpression, "Ok(((:$$_lambda_$$ [y] :y) 1))") +// testMacroEval([], callLambdaExpression, "Ok(1)") +// // Parameters shadow the outer scope +// testMacroEval([("y", IEvNumber(666.))], callLambdaExpression, "Ok(1)") +// // When not shadowed by the parameters, the outer scope variables are available +// let lambdaExpression = eFunction( +// "$$_lambda_$$", +// list{eArrayString(["z"]), eFunction("add", list{eSymbol("y"), eSymbol("z")})}, +// ) +// let callLambdaExpression = eList(list{lambdaExpression, eNumber(1.)}) +// testMacroEval([("y", IEvNumber(666.))], callLambdaExpression, "Ok(667)") +// }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Helpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Helpers.res index e915bfc1..706e4c8e 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Helpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Helpers.res @@ -1,17 +1,17 @@ // Reducer_Helpers module ErrorValue = Reducer_ErrorValue module InternalExpressionValue = ReducerInterface.InternalExpressionValue -module Bindings = Reducer_Bindings let removeDefaultsInternal = (iev: InternalExpressionValue.t) => { - switch iev { - | InternalExpressionValue.IEvBindings(nameSpace) => - Bindings.removeOther( - nameSpace, - ReducerInterface.StdLib.internalStdLib, - )->InternalExpressionValue.IEvBindings - | value => value - } + Not_found->raise + // switch iev { + // | Reducer_T.IEvBindings(nameSpace) => + // Reducer_Bindings.removeOther( + // nameSpace, + // ReducerInterface.StdLib.internalStdLib, + // )->Reducer_T.IEvBindings + // | value => value + // } } let rRemoveDefaultsInternal = r => Belt.Result.map(r, removeDefaultsInternal) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res index 34a21573..e9057671 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res @@ -9,7 +9,7 @@ open Expect let unwrapRecord = rValue => rValue->Belt.Result.flatMap(value => switch value { - | InternalExpressionValue.IEvRecord(aRecord) => Ok(aRecord) + | Reducer_T.IEvRecord(aRecord) => Ok(aRecord) | _ => ErrorValue.RETodo("TODO: Internal bindings must be returned")->Error } ) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res index a1a3399e..b5920cf1 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res @@ -1,90 +1,89 @@ -open Jest -open Expect +// open Jest +// open Expect -module Bindings = Reducer_Bindings -module BindingsReplacer = Reducer_Expression_BindingsReplacer -module Expression = Reducer_Expression -module ExpressionWithContext = Reducer_ExpressionWithContext -module InternalExpressionValue = ReducerInterface.InternalExpressionValue -module Macro = Reducer_Expression_Macro -module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -module T = Reducer_Expression_T +// module BindingsReplacer = Reducer_Expression_BindingsReplacer +// module Expression = Reducer_Expression +// module ExpressionWithContext = Reducer_ExpressionWithContext +// module InternalExpressionValue = ReducerInterface.InternalExpressionValue +// module Macro = Reducer_Expression_Macro +// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T +// module T = Reducer_Expression_T -let testMacro_ = ( - tester, - bindArray: array<(string, InternalExpressionValue.t)>, - expr: T.expression, - expectedCode: string, -) => { - let bindings = Bindings.fromArray(bindArray) - tester(expr->T.toString, () => { - let result = switch expr->Reducer_Dispatch_BuiltInMacros.dispatchMacroCall( - bindings, - ProjectAccessorsT.identityAccessors, - Expression.reduceExpressionInProject, - ) { - | v => Ok(v) - | exception Reducer_ErrorValue.ErrorException(e) => Error(e) - } +// let testMacro_ = ( +// tester, +// bindArray: array<(string, InternalExpressionValue.t)>, +// expr: T.expression, +// expectedCode: string, +// ) => { +// let bindings = Reducer_Bindings.fromArray(bindArray) +// tester(expr->T.toString, () => { +// let result = switch expr->Reducer_Dispatch_BuiltInMacros.dispatchMacroCall( +// bindings, +// ProjectAccessorsT.identityAccessors, +// Expression.reduceExpressionInProject, +// ) { +// | v => Ok(v) +// | exception Reducer_ErrorValue.ErrorException(e) => Error(e) +// } - result->ExpressionWithContext.toStringResult->expect->toEqual(expectedCode) - }) -} +// result->ExpressionWithContext.toStringResult->expect->toEqual(expectedCode) +// }) +// } -let testMacroEval_ = ( - tester, - bindArray: array<(string, InternalExpressionValue.t)>, - expr: T.expression, - expectedValue: string, -) => { - let bindings = Bindings.fromArray(bindArray) - tester(expr->T.toString, () => - expr - ->Macro.doMacroCall( - bindings, - ProjectAccessorsT.identityAccessors, - Expression.reduceExpressionInProject, - ) - ->Ok - ->InternalExpressionValue.toStringResult - ->expect - ->toEqual(expectedValue) - ) -} +// let testMacroEval_ = ( +// tester, +// bindArray: array<(string, InternalExpressionValue.t)>, +// expr: T.expression, +// expectedValue: string, +// ) => { +// let bindings = Reducer_Bindings.fromArray(bindArray) +// tester(expr->T.toString, () => +// expr +// ->Macro.doMacroCall( +// bindings, +// ProjectAccessorsT.identityAccessors, +// Expression.reduceExpressionInProject, +// ) +// ->Ok +// ->InternalExpressionValue.toStringResult +// ->expect +// ->toEqual(expectedValue) +// ) +// } -let testMacro = ( - bindArray: array<(string, InternalExpressionValue.t)>, - expr: T.expression, - expectedExpr: string, -) => testMacro_(test, bindArray, expr, expectedExpr) -let testMacroEval = ( - bindArray: array<(string, InternalExpressionValue.t)>, - expr: T.expression, - expectedValue: string, -) => testMacroEval_(test, bindArray, expr, expectedValue) +// let testMacro = ( +// bindArray: array<(string, InternalExpressionValue.t)>, +// expr: T.expression, +// expectedExpr: string, +// ) => testMacro_(test, bindArray, expr, expectedExpr) +// let testMacroEval = ( +// bindArray: array<(string, InternalExpressionValue.t)>, +// expr: T.expression, +// expectedValue: string, +// ) => testMacroEval_(test, bindArray, expr, expectedValue) -module MySkip = { - let testMacro = ( - bindArray: array<(string, InternalExpressionValue.t)>, - expr: T.expression, - expectedExpr: string, - ) => testMacro_(Skip.test, bindArray, expr, expectedExpr) - let testMacroEval = ( - bindArray: array<(string, InternalExpressionValue.t)>, - expr: T.expression, - expectedValue: string, - ) => testMacroEval_(Skip.test, bindArray, expr, expectedValue) -} +// module MySkip = { +// let testMacro = ( +// bindArray: array<(string, InternalExpressionValue.t)>, +// expr: T.expression, +// expectedExpr: string, +// ) => testMacro_(Skip.test, bindArray, expr, expectedExpr) +// let testMacroEval = ( +// bindArray: array<(string, InternalExpressionValue.t)>, +// expr: T.expression, +// expectedValue: string, +// ) => testMacroEval_(Skip.test, bindArray, expr, expectedValue) +// } -module MyOnly = { - let testMacro = ( - bindArray: array<(string, InternalExpressionValue.t)>, - expr: T.expression, - expectedExpr: string, - ) => testMacro_(Only.test, bindArray, expr, expectedExpr) - let testMacroEval = ( - bindArray: array<(string, InternalExpressionValue.t)>, - expr: T.expression, - expectedValue: string, - ) => testMacroEval_(Only.test, bindArray, expr, expectedValue) -} +// module MyOnly = { +// let testMacro = ( +// bindArray: array<(string, InternalExpressionValue.t)>, +// expr: T.expression, +// expectedExpr: string, +// ) => testMacro_(Only.test, bindArray, expr, expectedExpr) +// let testMacroEval = ( +// bindArray: array<(string, InternalExpressionValue.t)>, +// expr: T.expression, +// expectedValue: string, +// ) => testMacroEval_(Only.test, bindArray, expr, expectedValue) +// } diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_Compile_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_Compile_test.res index 55ed36bd..7d3ab86b 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_Compile_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_Compile_test.res @@ -1,52 +1,52 @@ -module Expression = Reducer_Expression -module InternalExpressionValue = ReducerInterface_InternalExpressionValue -module Bindings = Reducer_Bindings -module T = Reducer_Type_T -module TypeCompile = Reducer_Type_Compile +// module Expression = Reducer_Expression +// module InternalExpressionValue = ReducerInterface_InternalExpressionValue +// module Bindings = Reducer_Bindings +// module T = Reducer_Type_T +// module TypeCompile = Reducer_Type_Compile -open Jest -open Expect +// open Jest +// open Expect -let myIevEval = (aTypeSourceCode: string) => - TypeCompile.ievFromTypeExpression(aTypeSourceCode, Expression.reduceExpressionInProject) -let myIevEvalToString = (aTypeSourceCode: string) => - myIevEval(aTypeSourceCode)->InternalExpressionValue.toStringResult +// let myIevEval = (aTypeSourceCode: string) => +// TypeCompile.ievFromTypeExpression(aTypeSourceCode, Expression.reduceExpressionInProject) +// let myIevEvalToString = (aTypeSourceCode: string) => +// myIevEval(aTypeSourceCode)->InternalExpressionValue.toStringResult -let myIevExpectEqual = (aTypeSourceCode, answer) => - expect(myIevEvalToString(aTypeSourceCode))->toEqual(answer) +// let myIevExpectEqual = (aTypeSourceCode, answer) => +// expect(myIevEvalToString(aTypeSourceCode))->toEqual(answer) -let myIevTest = (test, aTypeSourceCode, answer) => - test(aTypeSourceCode, () => myIevExpectEqual(aTypeSourceCode, answer)) +// let myIevTest = (test, aTypeSourceCode, answer) => +// test(aTypeSourceCode, () => myIevExpectEqual(aTypeSourceCode, answer)) -let myTypeEval = (aTypeSourceCode: string) => - TypeCompile.fromTypeExpression(aTypeSourceCode, Expression.reduceExpressionInProject) -let myTypeEvalToString = (aTypeSourceCode: string) => myTypeEval(aTypeSourceCode)->T.toStringResult +// let myTypeEval = (aTypeSourceCode: string) => +// TypeCompile.fromTypeExpression(aTypeSourceCode, Expression.reduceExpressionInProject) +// let myTypeEvalToString = (aTypeSourceCode: string) => myTypeEval(aTypeSourceCode)->T.toStringResult -let myTypeExpectEqual = (aTypeSourceCode, answer) => - expect(myTypeEvalToString(aTypeSourceCode))->toEqual(answer) +// let myTypeExpectEqual = (aTypeSourceCode, answer) => +// expect(myTypeEvalToString(aTypeSourceCode))->toEqual(answer) -let myTypeTest = (test, aTypeSourceCode, answer) => - test(aTypeSourceCode, () => myTypeExpectEqual(aTypeSourceCode, answer)) +// let myTypeTest = (test, aTypeSourceCode, answer) => +// test(aTypeSourceCode, () => myTypeExpectEqual(aTypeSourceCode, answer)) -// | ItTypeIdentifier(string) -myTypeTest(test, "number", "number") -myTypeTest(test, "(number)", "number") -// | ItModifiedType({modifiedType: iType}) -myIevTest(test, "number<-min(0)", "Ok({min: 0,typeIdentifier: #number,typeTag: 'typeIdentifier'})") -myTypeTest(test, "number<-min(0)", "number<-min(0)") -// | ItTypeOr({typeOr: array}) -myTypeTest(test, "number | string", "(number | string)") -// | ItTypeFunction({inputs: array, output: iType}) -myTypeTest(test, "number => number => number", "(number => number => number)") -// | ItTypeArray({element: iType}) -myIevTest(test, "[number]", "Ok({element: #number,typeTag: 'typeArray'})") -myTypeTest(test, "[number]", "[number]") -// | ItTypeTuple({elements: array}) -myTypeTest(test, "[number, string]", "[number, string]") -// | ItTypeRecord({properties: Belt.Map.String.t}) -myIevTest( - test, - "{age: number, name: string}", - "Ok({properties: {age: #number,name: #string},typeTag: 'typeRecord'})", -) -myTypeTest(test, "{age: number, name: string}", "{age: number, name: string}") +// // | ItTypeIdentifier(string) +// myTypeTest(test, "number", "number") +// myTypeTest(test, "(number)", "number") +// // | ItModifiedType({modifiedType: iType}) +// myIevTest(test, "number<-min(0)", "Ok({min: 0,typeIdentifier: #number,typeTag: 'typeIdentifier'})") +// myTypeTest(test, "number<-min(0)", "number<-min(0)") +// // | ItTypeOr({typeOr: array}) +// myTypeTest(test, "number | string", "(number | string)") +// // | ItTypeFunction({inputs: array, output: iType}) +// myTypeTest(test, "number => number => number", "(number => number => number)") +// // | ItTypeArray({element: iType}) +// myIevTest(test, "[number]", "Ok({element: #number,typeTag: 'typeArray'})") +// myTypeTest(test, "[number]", "[number]") +// // | ItTypeTuple({elements: array}) +// myTypeTest(test, "[number, string]", "[number, string]") +// // | ItTypeRecord({properties: Belt.Map.String.t}) +// myIevTest( +// test, +// "{age: number, name: string}", +// "Ok({properties: {age: #number,name: #string},typeTag: 'typeRecord'})", +// ) +// myTypeTest(test, "{age: number, name: string}", "{age: number, name: string}") diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res index 957024cb..be20c5fd 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res @@ -1,42 +1,42 @@ -module Bindings = Reducer_Bindings -module ErrorValue = Reducer_ErrorValue -module Expression = Reducer_Expression -module ExpressionT = Reducer_Expression_T -module InternalExpressionValue = ReducerInterface_InternalExpressionValue -module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -module T = Reducer_Type_T -module TypeChecker = Reducer_Type_TypeChecker +// module Bindings = Reducer_Bindings +// module ErrorValue = Reducer_ErrorValue +// module Expression = Reducer_Expression +// module ExpressionT = Reducer_Expression_T +// module InternalExpressionValue = ReducerInterface_InternalExpressionValue +// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T +// module T = Reducer_Type_T +// module TypeChecker = Reducer_Type_TypeChecker -open Jest -open Expect +// open Jest +// open Expect -let checkArgumentsSourceCode = (aTypeSourceCode: string, sourceCode: string): result< - 'v, - ErrorValue.t, -> => { - let reducerFn = Expression.reduceExpressionInProject - let rResult = - Expression.BackCompatible.parse(sourceCode)->Belt.Result.map(expr => - reducerFn(expr, Bindings.emptyBindings, ProjectAccessorsT.identityAccessors) - ) - rResult->Belt.Result.flatMap(result => - switch result { - | IEvArray(args) => TypeChecker.checkArguments(aTypeSourceCode, args, reducerFn) - | _ => Js.Exn.raiseError("Arguments has to be an array") - } - ) -} +// let checkArgumentsSourceCode = (aTypeSourceCode: string, sourceCode: string): result< +// 'v, +// ErrorValue.t, +// > => { +// let reducerFn = Expression.reduceExpressionInProject +// let rResult = +// Expression.BackCompatible.parse(sourceCode)->Belt.Result.map(expr => +// reducerFn(expr, Bindings.emptyBindings, ProjectAccessorsT.identityAccessors) +// ) +// rResult->Belt.Result.flatMap(result => +// switch result { +// | IEvArray(args) => TypeChecker.checkArguments(aTypeSourceCode, args, reducerFn) +// | _ => Js.Exn.raiseError("Arguments has to be an array") +// } +// ) +// } -let myCheckArguments = (aTypeSourceCode: string, sourceCode: string): string => - switch checkArgumentsSourceCode(aTypeSourceCode, sourceCode) { - | Ok(_) => "Ok" - | Error(error) => ErrorValue.errorToString(error) - } +// let myCheckArguments = (aTypeSourceCode: string, sourceCode: string): string => +// switch checkArgumentsSourceCode(aTypeSourceCode, sourceCode) { +// | Ok(_) => "Ok" +// | Error(error) => ErrorValue.errorToString(error) +// } -let myCheckArgumentsExpectEqual = (aTypeSourceCode, sourceCode, answer) => - expect(myCheckArguments(aTypeSourceCode, sourceCode))->toEqual(answer) +// let myCheckArgumentsExpectEqual = (aTypeSourceCode, sourceCode, answer) => +// expect(myCheckArguments(aTypeSourceCode, sourceCode))->toEqual(answer) -let myCheckArgumentsTest = (test, aTypeSourceCode, sourceCode, answer) => - test(aTypeSourceCode, () => myCheckArgumentsExpectEqual(aTypeSourceCode, sourceCode, answer)) +// let myCheckArgumentsTest = (test, aTypeSourceCode, sourceCode, answer) => +// test(aTypeSourceCode, () => myCheckArgumentsExpectEqual(aTypeSourceCode, sourceCode, answer)) -myCheckArgumentsTest(test, "number=>number=>number", "[1,2]", "Ok") +// myCheckArgumentsTest(test, "number=>number=>number", "[1,2]", "Ok") diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res index d5726d5d..f935c7b0 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res @@ -1,73 +1,73 @@ -module Expression = Reducer_Expression -module ExpressionT = Reducer_Expression_T -module ErrorValue = Reducer_ErrorValue -module InternalExpressionValue = ReducerInterface_InternalExpressionValue -module Bindings = Reducer_Bindings -module T = Reducer_Type_T -module TypeChecker = Reducer_Type_TypeChecker -module ProjectAccessorsT = ReducerProject_ProjectAccessors_T +// module Expression = Reducer_Expression +// module ExpressionT = Reducer_Expression_T +// module ErrorValue = Reducer_ErrorValue +// module InternalExpressionValue = ReducerInterface_InternalExpressionValue +// module Bindings = Reducer_Bindings +// module T = Reducer_Type_T +// module TypeChecker = Reducer_Type_TypeChecker +// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -open Jest -open Expect +// open Jest +// open Expect -// In development, you are expected to use TypeChecker.isTypeOf(aTypeSourceCode, result, reducerFn). -// isTypeOfSourceCode is written to use strings instead of expression values. +// // In development, you are expected to use TypeChecker.isTypeOf(aTypeSourceCode, result, reducerFn). +// // isTypeOfSourceCode is written to use strings instead of expression values. -let isTypeOfSourceCode = (aTypeSourceCode: string, sourceCode: string): result< - 'v, - ErrorValue.t, -> => { - let reducerFn = Expression.reduceExpressionInProject - let rResult = - Expression.BackCompatible.parse(sourceCode)->Belt.Result.map(expr => - reducerFn(expr, Bindings.emptyBindings, ProjectAccessorsT.identityAccessors) - ) - rResult->Belt.Result.flatMap(result => TypeChecker.isTypeOf(aTypeSourceCode, result, reducerFn)) -} +// let isTypeOfSourceCode = (aTypeSourceCode: string, sourceCode: string): result< +// 'v, +// ErrorValue.t, +// > => { +// let reducerFn = Expression.reduceExpressionInProject +// let rResult = +// Expression.BackCompatible.parse(sourceCode)->Belt.Result.map(expr => +// reducerFn(expr, Bindings.emptyBindings, ProjectAccessorsT.identityAccessors) +// ) +// rResult->Belt.Result.flatMap(result => TypeChecker.isTypeOf(aTypeSourceCode, result, reducerFn)) +// } -let myTypeCheck = (aTypeSourceCode: string, sourceCode: string): string => - switch isTypeOfSourceCode(aTypeSourceCode, sourceCode) { - | Ok(_) => "Ok" - | Error(error) => ErrorValue.errorToString(error) - } +// let myTypeCheck = (aTypeSourceCode: string, sourceCode: string): string => +// switch isTypeOfSourceCode(aTypeSourceCode, sourceCode) { +// | Ok(_) => "Ok" +// | Error(error) => ErrorValue.errorToString(error) +// } -let myTypeCheckExpectEqual = (aTypeSourceCode, sourceCode, answer) => - expect(myTypeCheck(aTypeSourceCode, sourceCode))->toEqual(answer) +// let myTypeCheckExpectEqual = (aTypeSourceCode, sourceCode, answer) => +// expect(myTypeCheck(aTypeSourceCode, sourceCode))->toEqual(answer) -let myTypeCheckTest = (test, aTypeSourceCode, sourceCode, answer) => - test(aTypeSourceCode, () => myTypeCheckExpectEqual(aTypeSourceCode, sourceCode, answer)) +// let myTypeCheckTest = (test, aTypeSourceCode, sourceCode, answer) => +// test(aTypeSourceCode, () => myTypeCheckExpectEqual(aTypeSourceCode, sourceCode, answer)) -myTypeCheckTest(test, "number", "1", "Ok") -myTypeCheckTest(test, "number", "'2'", "Expected type: number but got: '2'") -myTypeCheckTest(test, "string", "3", "Expected type: string but got: 3") -myTypeCheckTest(test, "string", "'a'", "Ok") -myTypeCheckTest(test, "[number]", "[1,2,3]", "Ok") -myTypeCheckTest(test, "[number]", "['a','a','a']", "Expected type: number but got: 'a'") -myTypeCheckTest(test, "[number]", "[1,'a',3]", "Expected type: number but got: 'a'") -myTypeCheckTest(test, "[number, string]", "[1,'a']", "Ok") -myTypeCheckTest(test, "[number, string]", "[1, 2]", "Expected type: string but got: 2") -myTypeCheckTest( - test, - "[number, string, string]", - "[1,'a']", - "Expected type: [number, string, string] but got: [1,'a']", -) -myTypeCheckTest( - test, - "[number, string]", - "[1,'a', 3]", - "Expected type: [number, string] but got: [1,'a',3]", -) -myTypeCheckTest(test, "{age: number, name: string}", "{age: 1, name: 'a'}", "Ok") -myTypeCheckTest( - test, - "{age: number, name: string}", - "{age: 1, name: 'a', job: 'IT'}", - "Expected type: {age: number, name: string} but got: {age: 1,job: 'IT',name: 'a'}", -) -myTypeCheckTest(test, "number | string", "1", "Ok") -myTypeCheckTest(test, "date | string", "1", "Expected type: (date | string) but got: 1") -myTypeCheckTest(test, "number<-min(10)", "10", "Ok") -myTypeCheckTest(test, "number<-min(10)", "0", "Expected type: number<-min(10) but got: 0") -myTypeCheckTest(test, "any", "0", "Ok") -myTypeCheckTest(test, "any", "'a'", "Ok") +// myTypeCheckTest(test, "number", "1", "Ok") +// myTypeCheckTest(test, "number", "'2'", "Expected type: number but got: '2'") +// myTypeCheckTest(test, "string", "3", "Expected type: string but got: 3") +// myTypeCheckTest(test, "string", "'a'", "Ok") +// myTypeCheckTest(test, "[number]", "[1,2,3]", "Ok") +// myTypeCheckTest(test, "[number]", "['a','a','a']", "Expected type: number but got: 'a'") +// myTypeCheckTest(test, "[number]", "[1,'a',3]", "Expected type: number but got: 'a'") +// myTypeCheckTest(test, "[number, string]", "[1,'a']", "Ok") +// myTypeCheckTest(test, "[number, string]", "[1, 2]", "Expected type: string but got: 2") +// myTypeCheckTest( +// test, +// "[number, string, string]", +// "[1,'a']", +// "Expected type: [number, string, string] but got: [1,'a']", +// ) +// myTypeCheckTest( +// test, +// "[number, string]", +// "[1,'a', 3]", +// "Expected type: [number, string] but got: [1,'a',3]", +// ) +// myTypeCheckTest(test, "{age: number, name: string}", "{age: 1, name: 'a'}", "Ok") +// myTypeCheckTest( +// test, +// "{age: number, name: string}", +// "{age: 1, name: 'a', job: 'IT'}", +// "Expected type: {age: number, name: string} but got: {age: 1,job: 'IT',name: 'a'}", +// ) +// myTypeCheckTest(test, "number | string", "1", "Ok") +// myTypeCheckTest(test, "date | string", "1", "Expected type: (date | string) but got: 1") +// myTypeCheckTest(test, "number<-min(10)", "10", "Ok") +// myTypeCheckTest(test, "number<-min(10)", "0", "Expected type: number<-min(10) but got: 0") +// myTypeCheckTest(test, "any", "0", "Ok") +// myTypeCheckTest(test, "any", "'a'", "Ok") diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_switch_replacement_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_switch_replacement_test.res index 9dbe08c5..27fe6fce 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_switch_replacement_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_switch_replacement_test.res @@ -1,127 +1,126 @@ -open Jest -open Expect +// open Jest +// open Expect -module DispatchT = Reducer_Dispatch_T -module Expression = Reducer_Expression -module ExpressionT = Reducer_Expression_T -module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -module ProjectReducerFnT = ReducerProject_ReducerFn_T -module TypeChecker = Reducer_Type_TypeChecker -module TypeCompile = Reducer_Type_Compile +// module DispatchT = Reducer_Dispatch_T +// module Expression = Reducer_Expression +// module ExpressionT = Reducer_Expression_T +// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T +// module TypeChecker = Reducer_Type_TypeChecker +// module TypeCompile = Reducer_Type_Compile -open ReducerInterface_InternalExpressionValue +// open ReducerInterface_InternalExpressionValue -type errorValue = Reducer_ErrorValue.errorValue +// type errorValue = Reducer_ErrorValue.errorValue -// Let's build a function to replace switch statements -// In dispatchChainPiece, we execute an return the result of execution if there is a type match. -// Otherwise we return None so that the call chain can continue. -// So we want to build a function like -// dispatchChainPiece = (call: functionCall, accessors): option> -// Use accessors.environment to get the environment finally. +// // Let's build a function to replace switch statements +// // In dispatchChainPiece, we execute an return the result of execution if there is a type match. +// // Otherwise we return None so that the call chain can continue. +// // So we want to build a function like +// // dispatchChainPiece = (call: functionCall, accessors): option> +// // Use accessors.environment to get the environment finally. -// Now lets make the dispatchChainPiece itself. -// Note that I am not passing the reducer to the dispatchChainPiece as an argument because it is in the context anyway. -// Keep in mind that reducerFn is necessary for map/reduce so dispatchChainPiece should have a reducerFn in context. +// // Now lets make the dispatchChainPiece itself. +// // Note that I am not passing the reducer to the dispatchChainPiece as an argument because it is in the context anyway. +// // Keep in mind that reducerFn is necessary for map/reduce so dispatchChainPiece should have a reducerFn in context. -let makeMyDispatchChainPiece = (reducer: ProjectReducerFnT.t): DispatchT.dispatchChainPiece => { - // Let's have a pure implementations - module Implementation = { - let stringConcat = (a: string, b: string): string => Js.String2.concat(a, b) - let arrayConcat = ( - a: Js.Array2.t, - b: Js.Array2.t, - ): Js.Array2.t => Js.Array2.concat(a, b) - let plot = _r => "yey, plotted" - } +// let makeMyDispatchChainPiece = (reducer: Reducer_T.reducerFn): DispatchT.dispatchChainPiece => { +// // Let's have a pure implementations +// module Implementation = { +// let stringConcat = (a: string, b: string): string => Js.String2.concat(a, b) +// let arrayConcat = ( +// a: Js.Array2.t, +// b: Js.Array2.t, +// ): Js.Array2.t => Js.Array2.concat(a, b) +// let plot = _r => "yey, plotted" +// } - let extractStringString = args => - switch args { - | [IEvString(a), IEvString(b)] => (a, b) - | _ => raise(Reducer_Exception.ImpossibleException("extractStringString developer error")) - } +// let extractStringString = args => +// switch args { +// | [IEvString(a), IEvString(b)] => (a, b) +// | _ => raise(Reducer_Exception.ImpossibleException("extractStringString developer error")) +// } - let extractArrayArray = args => - switch args { - | [IEvArray(a), IEvArray(b)] => (a, b) - | _ => raise(Reducer_Exception.ImpossibleException("extractArrayArray developer error")) - } +// let extractArrayArray = args => +// switch args { +// | [IEvArray(a), IEvArray(b)] => (a, b) +// | _ => raise(Reducer_Exception.ImpossibleException("extractArrayArray developer error")) +// } - // Let's bridge the pure implementation to expression values - module Bridge = { - let stringConcat: DispatchT.genericIEvFunction = (args, _accessors: ProjectAccessorsT.t) => { - let (a, b) = extractStringString(args) - Implementation.stringConcat(a, b)->IEvString->Ok - } - let arrayConcat: DispatchT.genericIEvFunction = (args, _accessors: ProjectAccessorsT.t) => { - let (a, b) = extractArrayArray(args) - Implementation.arrayConcat(a, b)->IEvArray->Ok - } - let plot: DispatchT.genericIEvFunction = (args, _accessors: ProjectAccessorsT.t) => { - switch args { - // Just assume that we are doing the business of extracting and converting the deep record - | [IEvRecord(_)] => Implementation.plot({"title": "This is a plot"})->IEvString->Ok - | _ => raise(Reducer_Exception.ImpossibleException("plot developer error")) - } - } - } +// // Let's bridge the pure implementation to expression values +// module Bridge = { +// let stringConcat: DispatchT.genericIEvFunction = (args, _accessors: ProjectAccessorsT.t) => { +// let (a, b) = extractStringString(args) +// Implementation.stringConcat(a, b)->IEvString->Ok +// } +// let arrayConcat: DispatchT.genericIEvFunction = (args, _accessors: ProjectAccessorsT.t) => { +// let (a, b) = extractArrayArray(args) +// Implementation.arrayConcat(a, b)->IEvArray->Ok +// } +// let plot: DispatchT.genericIEvFunction = (args, _accessors: ProjectAccessorsT.t) => { +// switch args { +// // Just assume that we are doing the business of extracting and converting the deep record +// | [IEvRecord(_)] => Implementation.plot({"title": "This is a plot"})->IEvString->Ok +// | _ => raise(Reducer_Exception.ImpossibleException("plot developer error")) +// } +// } +// } - // concat functions are to illustrate polymoprhism. And the plot function is to illustrate complex types - let jumpTable = [ - ( - "concat", - TypeCompile.fromTypeExpressionExn("string=>string=>string", reducer), - Bridge.stringConcat, - ), - ( - "concat", - TypeCompile.fromTypeExpressionExn("[any]=>[any]=>[any]", reducer), - Bridge.arrayConcat, - ), - ( - "plot", - TypeCompile.fromTypeExpressionExn( - // Nested complex types are available - // records {property: type} - // arrays [type] - // tuples [type, type] - // <- type contracts are available naturally and they become part of dispatching - // Here we are not enumerating the possibilities because type checking has a dedicated test - "{title: string, line: {width: number, color: string}}=>string", - reducer, - ), - Bridge.plot, - ), - ] +// // concat functions are to illustrate polymoprhism. And the plot function is to illustrate complex types +// let jumpTable = [ +// ( +// "concat", +// TypeCompile.fromTypeExpressionExn("string=>string=>string", reducer), +// Bridge.stringConcat, +// ), +// ( +// "concat", +// TypeCompile.fromTypeExpressionExn("[any]=>[any]=>[any]", reducer), +// Bridge.arrayConcat, +// ), +// ( +// "plot", +// TypeCompile.fromTypeExpressionExn( +// // Nested complex types are available +// // records {property: type} +// // arrays [type] +// // tuples [type, type] +// // <- type contracts are available naturally and they become part of dispatching +// // Here we are not enumerating the possibilities because type checking has a dedicated test +// "{title: string, line: {width: number, color: string}}=>string", +// reducer, +// ), +// Bridge.plot, +// ), +// ] - //Here we are creating a dispatchChainPiece function that will do the actual dispatch from the jumpTable - Reducer_Dispatch_ChainPiece.makeFromTypes(jumpTable) -} +// //Here we are creating a dispatchChainPiece function that will do the actual dispatch from the jumpTable +// Reducer_Dispatch_ChainPiece.makeFromTypes(jumpTable) +// } -// And finally, let's write a library dispatch for our external library -// Exactly the same as the one used in real life -let _dispatch = ( - call: functionCall, - accessors: ProjectAccessorsT.t, - reducer: ProjectReducerFnT.t, - chain, -): result => { - let dispatchChainPiece = makeMyDispatchChainPiece(reducer) - dispatchChainPiece(call, accessors)->E.O2.defaultFn(() => chain(call, accessors, reducer)) -} +// // And finally, let's write a library dispatch for our external library +// // Exactly the same as the one used in real life +// let _dispatch = ( +// call: functionCall, +// accessors: ProjectAccessorsT.t, +// reducer: Reducer_T.reducerFn, +// chain, +// ): result => { +// let dispatchChainPiece = makeMyDispatchChainPiece(reducer) +// dispatchChainPiece(call, accessors)->E.O2.defaultFn(() => chain(call, accessors, reducer)) +// } -// What is important about this implementation? -// A) Exactly the same function jump table can be used to create type guarded lambda functions -// Guarded lambda functions will be the basis of the next version of Squiggle -// B) Complicated recursive record types are not a problem. +// // What is important about this implementation? +// // A) Exactly the same function jump table can be used to create type guarded lambda functions +// // Guarded lambda functions will be the basis of the next version of Squiggle +// // B) Complicated recursive record types are not a problem. -describe("Type Dispatch", () => { - let reducerFn = Expression.reduceExpressionInProject - let dispatchChainPiece = makeMyDispatchChainPiece(reducerFn) - test("stringConcat", () => { - let call: functionCall = ("concat", [IEvString("hello"), IEvString("world")]) +// describe("Type Dispatch", () => { +// let reducerFn = Expression.reduceExpressionInProject +// let dispatchChainPiece = makeMyDispatchChainPiece(reducerFn) +// test("stringConcat", () => { +// let call: functionCall = ("concat", [IEvString("hello"), IEvString("world")]) - let result = dispatchChainPiece(call, ProjectAccessorsT.identityAccessors) - expect(result)->toEqual(Some(Ok(IEvString("helloworld")))) - }) -}) +// let result = dispatchChainPiece(call, ProjectAccessorsT.identityAccessors) +// expect(result)->toEqual(Some(Ok(IEvString("helloworld")))) +// }) +// }) diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res index d2dbafb3..471ac55b 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res @@ -1,121 +1,121 @@ -@@warning("-44") -module InternalExpressionValue = ReducerInterface_InternalExpressionValue -module Project = ForTS_ReducerProject -module Bindings = Reducer_Bindings +// @@warning("-44") +// module InternalExpressionValue = ReducerInterface_InternalExpressionValue +// module Project = ForTS_ReducerProject +// module Bindings = Reducer_Bindings -open Jest -open Expect -open Expect.Operators +// open Jest +// open Expect +// open Expect.Operators -describe("Parse includes", () => { - let project = Project.createProject() - Project.setSource( - project, - "main", - ` -#include 'common' -x=1`, - ) - Project.parseIncludes(project, "main") - test("dependencies", () => { - expect(Project.getDependencies(project, "main")) == ["common"] - }) - test("dependents", () => { - expect(Project.getDependents(project, "main")) == [] - }) - test("getIncludes", () => { - let mainIncludes = Project.getIncludes(project, "main") - switch mainIncludes { - | Ok(includes) => expect(includes) == ["common"] - | Error(error) => fail(error->Reducer_ErrorValue.errorToString) - } - }) - let internalProject = project->Project.T.Private.castToInternalProject - test("past chain", () => { - expect(Project.Private.getPastChain(internalProject, "main")) == ["common"] - }) - test("import as variables", () => { - expect(Project.Private.getIncludesAsVariables(internalProject, "main")) == [] - }) -}) +// describe("Parse includes", () => { +// let project = Project.createProject() +// Project.setSource( +// project, +// "main", +// ` +// #include 'common' +// x=1`, +// ) +// Project.parseIncludes(project, "main") +// test("dependencies", () => { +// expect(Project.getDependencies(project, "main")) == ["common"] +// }) +// test("dependents", () => { +// expect(Project.getDependents(project, "main")) == [] +// }) +// test("getIncludes", () => { +// let mainIncludes = Project.getIncludes(project, "main") +// switch mainIncludes { +// | Ok(includes) => expect(includes) == ["common"] +// | Error(error) => fail(error->Reducer_ErrorValue.errorToString) +// } +// }) +// let internalProject = project->Project.T.Private.castToInternalProject +// test("past chain", () => { +// expect(Project.Private.getPastChain(internalProject, "main")) == ["common"] +// }) +// test("import as variables", () => { +// expect(Project.Private.getIncludesAsVariables(internalProject, "main")) == [] +// }) +// }) -describe("Parse includes", () => { - let project = Project.createProject() - Project.setSource( - project, - "main", - ` -#include 'common' -#include 'myModule' as myVariable -x=1`, - ) - Project.parseIncludes(project, "main") +// describe("Parse includes", () => { +// let project = Project.createProject() +// Project.setSource( +// project, +// "main", +// ` +// #include 'common' +// #include 'myModule' as myVariable +// x=1`, +// ) +// Project.parseIncludes(project, "main") - test("dependencies", () => { - expect(Project.getDependencies(project, "main")) == ["common", "myModule"] - }) +// test("dependencies", () => { +// expect(Project.getDependencies(project, "main")) == ["common", "myModule"] +// }) - test("dependents", () => { - expect(Project.getDependents(project, "main")) == [] - }) +// test("dependents", () => { +// expect(Project.getDependents(project, "main")) == [] +// }) - test("getIncludes", () => { - let mainIncludes = Project.getIncludes(project, "main") - switch mainIncludes { - | Ok(includes) => expect(includes) == ["common", "myModule"] - | Error(error) => fail(error->Reducer_ErrorValue.errorToString) - } - }) +// test("getIncludes", () => { +// let mainIncludes = Project.getIncludes(project, "main") +// switch mainIncludes { +// | Ok(includes) => expect(includes) == ["common", "myModule"] +// | Error(error) => fail(error->Reducer_ErrorValue.errorToString) +// } +// }) - let internalProject = project->Project.T.Private.castToInternalProject +// let internalProject = project->Project.T.Private.castToInternalProject - test("direct past chain", () => { - expect(Project.Private.getPastChain(internalProject, "main")) == ["common"] - }) +// test("direct past chain", () => { +// expect(Project.Private.getPastChain(internalProject, "main")) == ["common"] +// }) - test("direct includes", () => { - expect(Project.Private.getDirectIncludes(internalProject, "main")) == ["common"] - }) +// test("direct includes", () => { +// expect(Project.Private.getDirectIncludes(internalProject, "main")) == ["common"] +// }) - test("include as variables", () => { - expect(Project.Private.getIncludesAsVariables(internalProject, "main")) == [ - ("myVariable", "myModule"), - ] - }) -}) +// test("include as variables", () => { +// expect(Project.Private.getIncludesAsVariables(internalProject, "main")) == [ +// ("myVariable", "myModule"), +// ] +// }) +// }) -describe("Parse multiple direct includes", () => { - let project = Project.createProject() - Project.setSource( - project, - "main", - ` -#include 'common' -#include 'common2' -#include 'myModule' as myVariable -x=1`, - ) - Project.parseIncludes(project, "main") - test("dependencies", () => { - expect(Project.getDependencies(project, "main")) == ["common", "common2", "myModule"] - }) - test("dependents", () => { - expect(Project.getDependents(project, "main")) == [] - }) - test("getIncludes", () => { - let mainIncludes = Project.getIncludes(project, "main") - switch mainIncludes { - | Ok(includes) => expect(includes) == ["common", "common2", "myModule"] - | Error(error) => fail(error->Reducer_ErrorValue.errorToString) - } - }) - let internalProject = project->Project.T.Private.castToInternalProject - test("direct past chain", () => { - expect(Project.getPastChain(project, "main")) == ["common", "common2"] - }) - test("include as variables", () => { - expect(Project.Private.getIncludesAsVariables(internalProject, "main")) == [ - ("myVariable", "myModule"), - ] - }) -}) +// describe("Parse multiple direct includes", () => { +// let project = Project.createProject() +// Project.setSource( +// project, +// "main", +// ` +// #include 'common' +// #include 'common2' +// #include 'myModule' as myVariable +// x=1`, +// ) +// Project.parseIncludes(project, "main") +// test("dependencies", () => { +// expect(Project.getDependencies(project, "main")) == ["common", "common2", "myModule"] +// }) +// test("dependents", () => { +// expect(Project.getDependents(project, "main")) == [] +// }) +// test("getIncludes", () => { +// let mainIncludes = Project.getIncludes(project, "main") +// switch mainIncludes { +// | Ok(includes) => expect(includes) == ["common", "common2", "myModule"] +// | Error(error) => fail(error->Reducer_ErrorValue.errorToString) +// } +// }) +// let internalProject = project->Project.T.Private.castToInternalProject +// test("direct past chain", () => { +// expect(Project.getPastChain(project, "main")) == ["common", "common2"] +// }) +// test("include as variables", () => { +// expect(Project.Private.getIncludesAsVariables(internalProject, "main")) == [ +// ("myVariable", "myModule"), +// ] +// }) +// }) diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res index 1dd215b9..1bfe8c36 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res @@ -23,10 +23,9 @@ let runFetchFlatBindings = (project, sourceId) => { test("setting continuation", () => { let project = Project.createProject() - let privateProject = project->Project.T.Private.castToInternalProject - let sampleBindings = Bindings.emptyBindings->Bindings.set("test", IEvVoid) - Project.Private.setContinuation(privateProject, "main", sampleBindings) - let answer = Project.Private.getContinuation(privateProject, "main") + let sampleBindings = Bindings.makeEmptyBindings()->Bindings.set("test", IEvVoid) + ReducerProject.setContinuation(project, "main", sampleBindings) + let answer = ReducerProject.getContinuation(project, "main") expect(answer)->toBe(sampleBindings) }) @@ -59,7 +58,6 @@ describe("project1", () => { Project.setSource(project, "first", "x=1") Project.setSource(project, "main", "x") Project.setContinues(project, "main", ["first"]) - let internalProject = project->Project.T.Private.castToInternalProject test("runOrder", () => { expect(Project.getRunOrder(project)) == ["first", "main"] @@ -78,10 +76,10 @@ describe("project1", () => { }) test("past chain first", () => { - expect(Project.Private.getPastChain(internalProject, "first")) == [] + expect(ReducerProject.getPastChain(project, "first")) == [] }) test("past chain main", () => { - expect(Project.Private.getPastChain(internalProject, "main")) == ["first"] + expect(ReducerProject.getPastChain(project, "main")) == ["first"] }) test("test result", () => { diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_test.res index 92a4932f..59579c80 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_test.res @@ -65,7 +65,7 @@ Case "Running a single source". /* Now you have external bindings and external result. */ ( result->InternalExpressionValue.toStringResult, - bindings->InternalExpressionValue.IEvBindings->InternalExpressionValue.toString, + bindings->Reducer_T.IEvBindings->InternalExpressionValue.toString, )->expect == ("Ok(3)", "@{}") }) diff --git a/packages/squiggle-lang/src/js/SqValue.ts b/packages/squiggle-lang/src/js/SqValue.ts index abb49ae8..fbde4f80 100644 --- a/packages/squiggle-lang/src/js/SqValue.ts +++ b/packages/squiggle-lang/src/js/SqValue.ts @@ -62,13 +62,13 @@ export class SqBoolValue extends SqAbstractValue { } } -export class SqCallValue extends SqAbstractValue { - tag = Tag.Call as const; +// export class SqCallValue extends SqAbstractValue { +// tag = Tag.Call as const; - get value() { - return this.valueMethod(RSValue.getCall); - } -} +// get value() { +// return this.valueMethod(RSValue.getCall); +// } +// } export class SqDateValue extends SqAbstractValue { tag = Tag.Date as const; @@ -134,13 +134,13 @@ export class SqStringValue extends SqAbstractValue { } } -export class SqSymbolValue extends SqAbstractValue { - tag = Tag.Symbol as const; +// export class SqSymbolValue extends SqAbstractValue { +// tag = Tag.Symbol as const; - get value(): string { - return this.valueMethod(RSValue.getSymbol); - } -} +// get value(): string { +// return this.valueMethod(RSValue.getSymbol); +// } +// } export class SqTimeDurationValue extends SqAbstractValue { tag = Tag.TimeDuration as const; @@ -178,7 +178,7 @@ const tagToClass = { [Tag.Array]: SqArrayValue, [Tag.ArrayString]: SqArrayStringValue, [Tag.Bool]: SqBoolValue, - [Tag.Call]: SqCallValue, + // [Tag.Call]: SqCallValue, [Tag.Date]: SqDateValue, [Tag.Declaration]: SqDeclarationValue, [Tag.Distribution]: SqDistributionValue, @@ -187,7 +187,7 @@ const tagToClass = { [Tag.Number]: SqNumberValue, [Tag.Record]: SqRecordValue, [Tag.String]: SqStringValue, - [Tag.Symbol]: SqSymbolValue, + // [Tag.Symbol]: SqSymbolValue, [Tag.TimeDuration]: SqTimeDurationValue, [Tag.Type]: SqTypeValue, [Tag.TypeIdentifier]: SqTypeIdentifierValue, @@ -200,7 +200,7 @@ export type SqValue = | SqArrayValue | SqArrayStringValue | SqBoolValue - | SqCallValue + // | SqCallValue | SqDateValue | SqDeclarationValue | SqDistributionValue @@ -209,7 +209,7 @@ export type SqValue = | SqNumberValue | SqRecordValue | SqStringValue - | SqSymbolValue + // | SqSymbolValue | SqTimeDurationValue | SqTypeValue | SqTypeIdentifierValue diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index bb443fac..aac26bd5 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -1,4 +1,4 @@ -import { environment } from "../rescript/ForTS/ForTS_ReducerProject.gen"; +import { environment } from "../rescript/ForTS/ForTS__Types.gen"; import { SqProject } from "./SqProject"; import { SqValue, SqValueTag } from "./SqValue"; export { SqValueLocation } from "./SqValueLocation"; diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res index 18838899..512138d5 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res @@ -1,4 +1,4 @@ -@genType type reducerProject = ReducerProject_T.t //re-export +@genType type reducerProject = ReducerProject_T.project //re-export type reducerErrorValue = ForTS_Reducer_ErrorValue.reducerErrorValue //use @@ -8,7 +8,7 @@ type squiggleValue_Module = ForTS_SquiggleValue_Module.squiggleValue_Module //us type environment = ForTS_Distribution_Environment.environment //use module T = ReducerProject_T -module Private = ReducerProject.Private +module Private = ReducerProject /* PUBLIC FUNCTIONS @@ -35,35 +35,35 @@ A project has a public field tag with a constant value "reducerProject" project = {tag: "reducerProject"} */ @genType -let createProject = (): reducerProject => Private.createProject()->T.Private.castFromInternalProject +let createProject = (): reducerProject => Private.createProject() /* Answer all the source ids of all the sources in the project. */ @genType let getSourceIds = (project: reducerProject): array => - project->T.Private.castToInternalProject->Private.getSourceIds + project->Private.getSourceIds /* Sets the source for a given source Id. */ @genType let setSource = (project: reducerProject, sourceId: string, value: string): unit => - project->T.Private.castToInternalProject->Private.setSource(sourceId, value) + project->Private.setSource(sourceId, value) /* Gets the source for a given source id. */ @genType let getSource = (project: reducerProject, sourceId: string): option => - project->T.Private.castToInternalProject->Private.getSource(sourceId) + project->Private.getSource(sourceId) /* Touches the source for a given source id. This and dependent, sources are set to be re-evaluated. */ @genType let touchSource = (project: reducerProject, sourceId: string): unit => - project->T.Private.castToInternalProject->Private.touchSource(sourceId) + project->Private.touchSource(sourceId) /* Cleans the compilation artifacts for a given source ID. The results stay untouched, so compilation won't be run again. @@ -72,14 +72,14 @@ Normally, you would never need the compilation artifacts again as the results wi */ @genType let clean = (project: reducerProject, sourceId: string): unit => - project->T.Private.castToInternalProject->Private.clean(sourceId) + project->Private.clean(sourceId) /* Cleans all the compilation artifacts in all of the project */ @genType let cleanAll = (project: reducerProject): unit => - project->T.Private.castToInternalProject->Private.cleanAll + project->Private.cleanAll /* Cleans results. Compilation stays untouched to be able to re-run the source. @@ -87,14 +87,14 @@ You would not do this if you were not trying to debug the source code. */ @genType let cleanResults = (project: reducerProject, sourceId: string): unit => - project->T.Private.castToInternalProject->Private.cleanResults(sourceId) + project->Private.cleanResults(sourceId) /* Cleans all results. Compilations remains untouched to rerun the source. */ @genType let cleanAllResults = (project: reducerProject): unit => - project->T.Private.castToInternalProject->Private.cleanAllResults + project->Private.cleanAllResults /* To set the includes one first has to call "parseIncludes". The parsed includes or the parser error is returned. @@ -103,19 +103,19 @@ To set the includes one first has to call "parseIncludes". The parsed includes o let getIncludes = (project: reducerProject, sourceId: string): result< array, reducerErrorValue, -> => project->T.Private.castToInternalProject->Private.getIncludes(sourceId) +> => project->Private.getIncludes(sourceId) /* Other sources contributing to the global namespace of this source. */ @genType let getPastChain = (project: reducerProject, sourceId: string): array => - project->T.Private.castToInternalProject->Private.getPastChain(sourceId) + project->Private.getPastChain(sourceId) /* Answers the source codes after which this source code is continuing */ @genType let getContinues = (project: reducerProject, sourceId: string): array => - project->T.Private.castToInternalProject->Private.getContinues(sourceId) + project->Private.getContinues(sourceId) /* "continues" acts like hidden includes in the source. @@ -124,35 +124,35 @@ let getContinues = (project: reducerProject, sourceId: string): array => */ @genType let setContinues = (project: reducerProject, sourceId: string, continues: array): unit => - project->T.Private.castToInternalProject->Private.setContinues(sourceId, continues) + project->Private.setContinues(sourceId, continues) /* This source depends on the array of sources returned. */ @genType let getDependencies = (project: reducerProject, sourceId: string): array => - project->T.Private.castToInternalProject->Private.getDependencies(sourceId) + project->Private.getDependencies(sourceId) /* The sources returned are dependent on this */ @genType let getDependents = (project: reducerProject, sourceId: string): array => - project->T.Private.castToInternalProject->Private.getDependents(sourceId) + project->Private.getDependents(sourceId) /* Get the run order for the sources in the project. */ @genType let getRunOrder = (project: reducerProject): array => - project->T.Private.castToInternalProject->Private.getRunOrder + project->Private.getRunOrder /* Get the run order to get the results of this specific source */ @genType let getRunOrderFor = (project: reducerProject, sourceId: string) => - project->T.Private.castToInternalProject->Private.getRunOrderFor(sourceId) + project->Private.getRunOrderFor(sourceId) /* Parse includes so that you can load them before running. @@ -162,7 +162,7 @@ It is your responsibility to load the includes before running. @genType let parseIncludes = (project: reducerProject, sourceId: string): unit => - project->T.Private.castToInternalProject->Private.parseIncludes(sourceId) + project->Private.parseIncludes(sourceId) /* Parse the source code if it is not done already. @@ -171,28 +171,28 @@ You would need this function if you want to see the parse tree without running t */ @genType let rawParse = (project: reducerProject, sourceId: string): unit => - project->T.Private.castToInternalProject->Private.rawParse(sourceId) + project->Private.rawParse(sourceId) /* 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->T.Private.castToInternalProject->Private.run(sourceId) + 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->T.Private.castToInternalProject->Private.runAll + project->Private.runAll /* Get the bindings after running this source fil. The bindings are local to the source */ @genType let getBindings = (project: reducerProject, sourceId: string): squiggleValue_Module => - project->T.Private.castToInternalProject->Private.getBindings(sourceId) + project->Private.getBindings(sourceId) /* Get the result after running this source file or the project @@ -201,7 +201,7 @@ Get the result after running this source file or the project let getResult = (project: reducerProject, sourceId: string): result< squiggleValue, reducerErrorValue, -> => project->T.Private.castToInternalProject->Private.getResult(sourceId) +> => project->Private.getResult(sourceId) /* This is a convenience function to get the result of a single source without creating a project. @@ -216,7 +216,7 @@ let evaluate = (sourceCode: string): ( @genType let setEnvironment = (project: reducerProject, environment: environment): unit => - project->T.Private.castToInternalProject->Private.setEnvironment(environment) + project->Private.setEnvironment(environment) /* Foreign function interface is intentionally demolished. diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res index 692ed3e6..1dd3887d 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res @@ -1,10 +1,10 @@ -@genType type squiggleValue = ReducerInterface_InternalExpressionValue.t //re-export +@genType type squiggleValue = Reducer_T.value //re-export type reducerErrorValue = ForTS_Reducer_ErrorValue.reducerErrorValue //use -@genType type squiggleValue_Array = ReducerInterface_InternalExpressionValue.squiggleArray //re-export recursive type -@genType type squiggleValue_Module = ReducerInterface_InternalExpressionValue.nameSpace //re-export recursive type -@genType type squiggleValue_Record = ReducerInterface_InternalExpressionValue.map //re-export recursive type -@genType type squiggleValue_Type = ReducerInterface_InternalExpressionValue.map //re-export recursive type +@genType type squiggleValue_Array = Reducer_T.arrayValue //re-export recursive type +@genType type squiggleValue_Module = Reducer_T.nameSpace //re-export recursive type +@genType type squiggleValue_Record = Reducer_T.map //re-export recursive type +@genType type squiggleValue_Type = Reducer_T.map //re-export recursive type type squiggleValue_Declaration = ForTS_SquiggleValue_Declaration.squiggleValue_Declaration //use type squiggleValue_Distribution = ForTS_SquiggleValue_Distribution.squiggleValue_Distribution //use type squiggleValue_Lambda = ForTS_SquiggleValue_Lambda.squiggleValue_Lambda //use @@ -20,8 +20,8 @@ external svtArrayString_: string = "ArrayString" @module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtBool_: string = "Bool" -@module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -external svtCall_: string = "Call" +// @module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") +// external svtCall_: string = "Call" @module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtDate_: string = "Date" @@ -47,8 +47,8 @@ external svtRecord_: string = "Record" @module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtString_: string = "String" -@module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -external svtSymbol_: string = "Symbol" +// @module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") +// external svtSymbol_: string = "Symbol" @module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtTimeDuration_: string = "TimeDuration" @@ -73,7 +73,7 @@ let getTag = (variant: squiggleValue): squiggleValueTag => | IEvArray(_) => svtArray_->castEnum | IEvArrayString(_) => svtArrayString_->castEnum | IEvBool(_) => svtBool_->castEnum - | IEvCall(_) => svtCall_->castEnum //Impossible + // | IEvCall(_) => svtCall_->castEnum //Impossible | IEvDate(_) => svtDate_->castEnum | IEvDeclaration(_) => svtDeclaration_->castEnum | IEvDistribution(_) => svtDistribution_->castEnum @@ -82,7 +82,7 @@ let getTag = (variant: squiggleValue): squiggleValueTag => | IEvNumber(_) => svtNumber_->castEnum | IEvRecord(_) => svtRecord_->castEnum | IEvString(_) => svtString_->castEnum - | IEvSymbol(_) => svtSymbol_->castEnum + // | IEvSymbol(_) => svtSymbol_->castEnum | IEvTimeDuration(_) => svtTimeDuration_->castEnum | IEvType(_) => svtType_->castEnum | IEvTypeIdentifier(_) => svtTypeIdentifier_->castEnum @@ -121,12 +121,12 @@ let getBool = (variant: squiggleValue): option => | _ => None } -@genType -let getCall = (variant: squiggleValue): option => - switch variant { - | IEvCall(value) => value->Some - | _ => None - } +// @genType +// let getCall = (variant: squiggleValue): option => +// switch variant { +// | IEvCall(value) => value->Some +// | _ => None +// } @genType let getDate = (variant: squiggleValue): option => @@ -184,12 +184,12 @@ let getString = (variant: squiggleValue): option => | _ => None } -@genType -let getSymbol = (variant: squiggleValue): option => - switch variant { - | IEvSymbol(value) => value->Some - | _ => None - } +// @genType +// let getSymbol = (variant: squiggleValue): option => +// switch variant { +// | IEvSymbol(value) => value->Some +// | _ => None +// } @genType let getTimeDuration = (variant: squiggleValue): option => diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Declaration.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Declaration.res index 7fe342f8..d7da5e1e 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Declaration.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Declaration.res @@ -1,4 +1,4 @@ -@genType type squiggleValue_Declaration = ReducerInterface_InternalExpressionValue.lambdaDeclaration //re-export +@genType type squiggleValue_Declaration = Reducer_T.lambdaDeclaration //re-export @genType let toString = (v: squiggleValue_Declaration): string => diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Lambda.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Lambda.res index 9f176576..ef4c460f 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Lambda.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Lambda.res @@ -1,4 +1,4 @@ -@genType type squiggleValue_Lambda = ReducerInterface_InternalExpressionValue.lambdaValue //re-export +@genType type squiggleValue_Lambda = Reducer_T.lambdaValue //re-export @genType let toString = (v: squiggleValue_Lambda): string => diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Module.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Module.res index 2b164aee..12021fbf 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Module.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Module.res @@ -3,7 +3,7 @@ type squiggleValue = ForTS_SquiggleValue.squiggleValue //use @genType let getKeyValuePairs = (v: squiggleValue_Module): array<(string, squiggleValue)> => - ReducerInterface_InternalExpressionValue.nameSpaceToKeyValuePairs(v) + v->Reducer_Bindings.toKeyValuePairs @genType let toString = (v: squiggleValue_Module): string => @@ -13,4 +13,4 @@ let toString = (v: squiggleValue_Module): string => let toSquiggleValue = (v: squiggleValue_Module): squiggleValue => IEvBindings(v) @genType -let get = Reducer_Bindings.get +let get = (v: squiggleValue_Module, k: string): option => Reducer_Bindings.get(v, k) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_tag.ts b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_tag.ts index a54b38e0..45957e8d 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_tag.ts +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_tag.ts @@ -2,7 +2,7 @@ export enum squiggleValueTag { Array = "Array", ArrayString = "ArrayString", Bool = "Bool", - Call = "Call", + // Call = "Call", Date = "Date", Declaration = "Declaration", Distribution = "Distribution", @@ -11,7 +11,7 @@ export enum squiggleValueTag { Number = "Number", Record = "Record", String = "String", - Symbol = "Symbol", + // Symbol = "Symbol", TimeDuration = "TimeDuration", Type = "Type", TypeIdentifier = "TypeIdentifier", diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res index edce5ac2..e217cad9 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res @@ -1,6 +1,4 @@ -module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -module ProjectReducerFnT = ReducerProject_ReducerFn_T -type internalExpressionValue = ReducerInterface_InternalExpressionValue.t +type internalExpressionValue = Reducer_T.value type internalExpressionValueType = ReducerInterface_InternalExpressionValue.internalExpressionValueType /* @@ -32,7 +30,7 @@ type rec frValue = | FRValueArray(array) | FRValueDistOrNumber(frValueDistOrNumber) | FRValueRecord(frValueRecord) - | FRValueLambda(ReducerInterface_InternalExpressionValue.lambdaValue) + | FRValueLambda(Reducer_T.lambdaValue) | FRValueString(string) | FRValueVariant(string) | FRValueAny(frValue) @@ -48,8 +46,8 @@ type fnDefinition = { run: ( array, array, - ProjectAccessorsT.t, - ProjectReducerFnT.t, + Reducer_T.environment, + Reducer_T.reducerFn, ) => result, } @@ -384,12 +382,12 @@ module FnDefinition = { let run = ( t: t, args: array, - accessors: ProjectAccessorsT.t, - reducer: ProjectReducerFnT.t, + env: Reducer_T.environment, + reducer: Reducer_T.reducerFn, ) => { let argValues = FRType.matchWithExpressionValueArray(t.inputs, args) switch argValues { - | Some(values) => t.run(args, values, accessors, reducer) + | Some(values) => t.run(args, values, env, reducer) | None => Error("Incorrect Types") } } @@ -495,8 +493,8 @@ module Registry = { ~registry: registry, ~fnName: string, ~args: array, - ~accessors: ProjectAccessorsT.t, - ~reducer: ProjectReducerFnT.t, + ~env: Reducer_T.environment, + ~reducer: Reducer_T.reducerFn, ) => { let relevantFunctions = Js.Dict.get(registry.fnNameDict, fnName) |> E.O.default([]) let modified = {functions: relevantFunctions, fnNameDict: registry.fnNameDict} @@ -514,7 +512,7 @@ module Registry = { switch Matcher.Registry.findMatches(modified, fnName, args) { | Matcher.Match.FullMatch(match) => - match->matchToDef->E.O2.fmap(FnDefinition.run(_, args, accessors, reducer)) + match->matchToDef->E.O2.fmap(FnDefinition.run(_, args, env, reducer)) | SameNameDifferentArguments(m) => Some(Error(showNameMatchDefinitions(m))) | _ => None } @@ -523,10 +521,10 @@ module Registry = { let dispatch = ( registry, (fnName, args): ReducerInterface_InternalExpressionValue.functionCall, - accessors: ProjectAccessorsT.t, - reducer: ProjectReducerFnT.t, + env: Reducer_T.environment, + reducer: Reducer_T.reducerFn, ) => { - _matchAndRun(~registry, ~fnName, ~args, ~accessors, ~reducer)->E.O2.fmap( + _matchAndRun(~registry, ~fnName, ~args, ~env, ~reducer)->E.O2.fmap( E.R2.errMap(_, s => Reducer_ErrorValue.RETodo(s)), ) } diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res index 3fce1b54..872251cf 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res @@ -6,11 +6,11 @@ module Wrappers = { let symbolic = r => DistributionTypes.Symbolic(r) let pointSet = r => DistributionTypes.PointSet(r) let sampleSet = r => DistributionTypes.SampleSet(r) - let evDistribution = r => ReducerInterface_InternalExpressionValue.IEvDistribution(r) - let evNumber = r => ReducerInterface_InternalExpressionValue.IEvNumber(r) - let evArray = r => ReducerInterface_InternalExpressionValue.IEvArray(r) - let evRecord = r => ReducerInterface_InternalExpressionValue.IEvRecord(r) - let evString = r => ReducerInterface_InternalExpressionValue.IEvString(r) + let evDistribution = r => Reducer_T.IEvDistribution(r) + let evNumber = r => Reducer_T.IEvNumber(r) + let evArray = r => Reducer_T.IEvArray(r) + let evRecord = r => Reducer_T.IEvRecord(r) + let evString = r => Reducer_T.IEvString(r) let symbolicEvDistribution = r => r->DistributionTypes.Symbolic->evDistribution let evArrayOfEvNumber = xs => xs->Belt.Array.map(evNumber)->evArray } 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 2fcfcdaf..2f50c73a 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Danger.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Danger.res @@ -69,12 +69,12 @@ module Integration = { let pointAsInternalExpression = FunctionRegistry_Helpers.Wrappers.evNumber(point) let resultAsInternalExpression = Reducer_Expression_Lambda.doLambdaCall( aLambda, - list{pointAsInternalExpression}, + [pointAsInternalExpression], environment, - reducer, + reducer ) let result = switch resultAsInternalExpression { - | IEvNumber(x) => Ok(x) + | 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", @@ -132,7 +132,7 @@ module Integration = { | (Ok(yMin), Ok(yMax)) => { let result = (yMin +. yMax) *. weightForAnOuterPoint +. innerPointsSum *. weightForAnInnerPoint - let wrappedResult = result->ReducerInterface_InternalExpressionValue.IEvNumber->Ok + let wrappedResult = result->Reducer_T.IEvNumber->Ok wrappedResult } | (Error(b), _) => Error(b) @@ -273,7 +273,7 @@ module DiminishingReturns = { funds, approximateIncrement, environment, - reducer, + reducer ) => { switch ( E.A.length(lambdas) > 1, @@ -303,12 +303,12 @@ module DiminishingReturns = { let pointAsInternalExpression = FunctionRegistry_Helpers.Wrappers.evNumber(point) let resultAsInternalExpression = Reducer_Expression_Lambda.doLambdaCall( lambda, - list{pointAsInternalExpression}, + [pointAsInternalExpression], environment, - reducer, + reducer ) switch resultAsInternalExpression { - | IEvNumber(x) => Ok(x) + | 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", @@ -401,7 +401,7 @@ module DiminishingReturns = { | [IEvArray(innerlambdas), IEvNumber(funds), IEvNumber(approximateIncrement)] => { let individuallyWrappedLambdas = E.A.fmap(innerLambda => { switch innerLambda { - | ReducerInterface_InternalExpressionValue.IEvLambda(lambda) => Ok(lambda) + | Reducer_T.IEvLambda(lambda) => Ok(lambda) | _ => Error( "Error in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions. A member of the array wasn't a function", 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 0c85bbe1..df37f69c 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res @@ -4,7 +4,7 @@ open FunctionRegistry_Helpers let nameSpace = "Dict" module Internals = { - type t = ReducerInterface_InternalExpressionValue.map + type t = Reducer_T.map let keys = (a: t): internalExpressionValue => IEvArray( Belt.Map.String.keysToArray(a)->E.A2.fmap(Wrappers.evString), 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 23619187..e1ddb61d 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dist.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dist.res @@ -21,8 +21,8 @@ module DistributionCreation = { FnDefinition.make( ~name, ~inputs=[FRTypeDistOrNumber, FRTypeDistOrNumber], - ~run=(_, inputs, accessors, _) => - inputs->Prepare.ToValueTuple.twoDistOrNumber->process(~fn, ~env=accessors.environment), + ~run=(_, inputs, env, _) => + inputs->Prepare.ToValueTuple.twoDistOrNumber->process(~fn, ~env=env), (), ) } @@ -31,10 +31,10 @@ module DistributionCreation = { FnDefinition.make( ~name, ~inputs=[FRTypeRecord([("p5", FRTypeDistOrNumber), ("p95", FRTypeDistOrNumber)])], - ~run=(_, inputs, accessors, _) => + ~run=(_, inputs, env, _) => inputs ->Prepare.ToValueTuple.Record.twoDistOrNumber - ->process(~fn, ~env=accessors.environment), + ->process(~fn, ~env=env), (), ) } @@ -43,10 +43,10 @@ module DistributionCreation = { FnDefinition.make( ~name, ~inputs=[FRTypeRecord([("mean", FRTypeDistOrNumber), ("stdev", FRTypeDistOrNumber)])], - ~run=(_, inputs, accessors, _) => + ~run=(_, inputs, env, _) => inputs ->Prepare.ToValueTuple.Record.twoDistOrNumber - ->process(~fn, ~env=accessors.environment), + ->process(~fn, ~env=env), (), ) } @@ -62,8 +62,8 @@ module DistributionCreation = { FnDefinition.make( ~name, ~inputs=[FRTypeDistOrNumber], - ~run=(_, inputs, accessors, _) => - inputs->Prepare.ToValueTuple.oneDistOrNumber->process(~fn, ~env=accessors.environment), + ~run=(_, inputs, env, _) => + inputs->Prepare.ToValueTuple.oneDistOrNumber->process(~fn, ~env=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 ee2ef343..86d9462e 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Fn.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Fn.res @@ -18,7 +18,7 @@ module Declaration = { inputs ->E.A2.fmap(getMinMax) ->E.A.R.firstErrorOrOpen - ->E.R2.fmap(args => ReducerInterface_InternalExpressionValue.IEvDeclaration( + ->E.R2.fmap(args => Reducer_T.IEvDeclaration( Declaration.make(lambda, args), )) } diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res index 1def1e36..1e9c2dfb 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res @@ -1,6 +1,3 @@ -// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -// module ProjectReducerFnT = ReducerProject_ReducerFn_T - open FunctionRegistry_Core open FunctionRegistry_Helpers @@ -29,16 +26,16 @@ module Internals = { let map = ( array: array, - accessors: ProjectAccessorsT.t, eLambdaValue, - reducer: ProjectReducerFnT.t, - ): ReducerInterface_InternalExpressionValue.t => { + env: Reducer_T.environment, + reducer: Reducer_T.reducerFn + ): internalExpressionValue => { let mappedList = array->E.A.reduceReverse(list{}, (acc, elem) => { let newElem = Reducer_Expression_Lambda.doLambdaCall( eLambdaValue, - list{elem}, - (accessors: ProjectAccessorsT.t), - (reducer: ProjectReducerFnT.t), + [elem], + env, + reducer ) list{newElem, ...acc} }) @@ -49,11 +46,11 @@ module Internals = { aValueArray, initialValue, aLambdaValue, - accessors: ProjectAccessorsT.t, - reducer: ProjectReducerFnT.t, + env: Reducer_T.environment, + reducer: Reducer_T.reducerFn ) => { aValueArray->E.A.reduce(initialValue, (acc, elem) => - Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, accessors, reducer) + Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, [acc, elem], env, reducer) ) } @@ -61,26 +58,26 @@ module Internals = { aValueArray, initialValue, aLambdaValue, - accessors: ProjectAccessorsT.t, - reducer: ProjectReducerFnT.t, + env: Reducer_T.environment, + reducer: Reducer_T.reducerFn ) => { aValueArray->Belt.Array.reduceReverse(initialValue, (acc, elem) => - Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, accessors, reducer) + Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, [acc, elem], env, reducer) ) } let filter = ( aValueArray, aLambdaValue, - accessors: ProjectAccessorsT.t, - reducer: ProjectReducerFnT.t, + env: Reducer_T.environment, + reducer: Reducer_T.reducerFn ) => { let mappedList = aValueArray->Belt.Array.reduceReverse(list{}, (acc, elem) => { let newElem = Reducer_Expression_Lambda.doLambdaCall( aLambdaValue, - list{elem}, - accessors, - reducer, + [elem], + env, + reducer ) switch newElem { | IEvBool(true) => list{elem, ...acc} @@ -201,10 +198,10 @@ let library = [ FnDefinition.make( ~name="map", ~inputs=[FRTypeArray(FRTypeAny), FRTypeLambda], - ~run=(inputs, _, accessors: ProjectAccessorsT.t, reducer) => + ~run=(inputs, _, env, reducer) => switch inputs { | [IEvArray(array), IEvLambda(lambda)] => - Ok(Internals.map(array, accessors, lambda, reducer)) + Ok(Internals.map(array, lambda, env, reducer)) | _ => Error(impossibleError) }, (), @@ -221,10 +218,10 @@ let library = [ FnDefinition.make( ~name="reduce", ~inputs=[FRTypeArray(FRTypeAny), FRTypeAny, FRTypeLambda], - ~run=(inputs, _, accessors: ProjectAccessorsT.t, reducer) => + ~run=(inputs, _, env, reducer) => switch inputs { | [IEvArray(array), initialValue, IEvLambda(lambda)] => - Ok(Internals.reduce(array, initialValue, lambda, accessors, reducer)) + Ok(Internals.reduce(array, initialValue, lambda, env, reducer)) | _ => Error(impossibleError) }, (), @@ -241,10 +238,10 @@ let library = [ FnDefinition.make( ~name="reduceReverse", ~inputs=[FRTypeArray(FRTypeAny), FRTypeAny, FRTypeLambda], - ~run=(inputs, _, accessors: ProjectAccessorsT.t, reducer: ProjectReducerFnT.t) => + ~run=(inputs, _, env, reducer) => switch inputs { | [IEvArray(array), initialValue, IEvLambda(lambda)] => - Ok(Internals.reduceReverse(array, initialValue, lambda, accessors, reducer)) + Ok(Internals.reduceReverse(array, initialValue, lambda, env, reducer)) | _ => Error(impossibleError) }, (), @@ -261,10 +258,10 @@ let library = [ FnDefinition.make( ~name="filter", ~inputs=[FRTypeArray(FRTypeAny), FRTypeLambda], - ~run=(inputs, _, accessors: ProjectAccessorsT.t, reducer: ProjectReducerFnT.t) => + ~run=(inputs, _, env, reducer) => switch inputs { | [IEvArray(array), IEvLambda(lambda)] => - Ok(Internals.filter(array, lambda, accessors, reducer)) + Ok(Internals.filter(array, lambda, env, reducer)) | _ => Error(impossibleError) }, (), diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res index ccc9a4a4..e8cf6539 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res @@ -17,7 +17,7 @@ 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 => ReducerInterface_InternalExpressionValue.IEvDistribution( + ->E.R2.fmap(r => Reducer_T.IEvDistribution( PointSet(makeDist(r)), )) expressionValue @@ -27,7 +27,7 @@ module Internal = { type t = PointSetDist.t let toType = (r): result< - ReducerInterface_InternalExpressionValue.t, + Reducer_T.value, Reducer_ErrorValue.errorValue, > => switch r { @@ -35,14 +35,14 @@ module Internal = { | Error(err) => Error(REOperationError(err)) } - let doLambdaCall = (aLambdaValue, list, environment, reducer) => - switch Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list, environment, reducer) { - | IEvNumber(f) => Ok(f) + let doLambdaCall = (aLambdaValue, list, env, reducer) => + switch Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list, env, reducer) { + | Reducer_T.IEvNumber(f) => Ok(f) | _ => Error(Operation.SampleMapNeedsNtoNFunction) } let mapY = (pointSetDist: t, aLambdaValue, env, reducer) => { - let fn = r => doLambdaCall(aLambdaValue, list{IEvNumber(r)}, env, reducer) + let fn = r => doLambdaCall(aLambdaValue, [IEvNumber(r)], env, reducer) PointSetDist.T.mapYResult(~fn, pointSetDist)->toType } } @@ -58,13 +58,13 @@ let library = [ FnDefinition.make( ~name="fromDist", ~inputs=[FRTypeDist], - ~run=(_, inputs, accessors, _) => + ~run=(_, inputs, env, _) => switch inputs { | [FRValueDist(dist)] => GenericDist.toPointSet( dist, - ~xyPointLength=accessors.environment.xyPointLength, - ~sampleCount=accessors.environment.sampleCount, + ~xyPointLength=env.xyPointLength, + ~sampleCount=env.sampleCount, (), ) ->E.R2.fmap(Wrappers.pointSet) 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 7d724a0f..6a98b4b7 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res @@ -1,5 +1,3 @@ -// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -// module ProjectReducerFnT = ReducerProject_ReducerFn_T open FunctionRegistry_Core open FunctionRegistry_Helpers @@ -12,16 +10,16 @@ module Internal = { let doLambdaCall = ( aLambdaValue, list, - accessors: ProjectAccessorsT.t, - reducer: ProjectReducerFnT.t, + env: Reducer_T.environment, + reducer: Reducer_T.reducerFn, ) => - switch Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list, accessors, reducer) { + switch Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list, env, reducer) { | IEvNumber(f) => Ok(f) | _ => Error(Operation.SampleMapNeedsNtoNFunction) } let toType = (r): result< - ReducerInterface_InternalExpressionValue.t, + Reducer_T.value, Reducer_ErrorValue.errorValue, > => switch r { @@ -30,26 +28,26 @@ module Internal = { } //TODO: I don't know why this seems to need at least one input - let fromFn = (aLambdaValue, accessors: ProjectAccessorsT.t, reducer: ProjectReducerFnT.t) => { - let sampleCount = accessors.environment.sampleCount - let fn = r => doLambdaCall(aLambdaValue, list{IEvNumber(r)}, accessors, reducer) + let fromFn = (aLambdaValue, environment: Reducer_T.environment, reducer: Reducer_T.reducerFn) => { + let sampleCount = environment.sampleCount + let fn = r => doLambdaCall(aLambdaValue, [IEvNumber(r)], environment, reducer) Belt_Array.makeBy(sampleCount, r => fn(r->Js.Int.toFloat))->E.A.R.firstErrorOrOpen } - let map1 = (sampleSetDist: t, aLambdaValue, accessors: ProjectAccessorsT.t, reducer) => { - let fn = r => doLambdaCall(aLambdaValue, list{IEvNumber(r)}, accessors, reducer) + let map1 = (sampleSetDist: t, aLambdaValue, environment: Reducer_T.environment, reducer) => { + let fn = r => doLambdaCall(aLambdaValue, [IEvNumber(r)], environment, reducer) SampleSetDist.samplesMap(~fn, sampleSetDist)->toType } - let map2 = (t1: t, t2: t, aLambdaValue, accessors: ProjectAccessorsT.t, reducer) => { + let map2 = (t1: t, t2: t, aLambdaValue, environment: Reducer_T.environment, reducer) => { let fn = (a, b) => - doLambdaCall(aLambdaValue, list{IEvNumber(a), IEvNumber(b)}, accessors, reducer) + doLambdaCall(aLambdaValue, [IEvNumber(a), IEvNumber(b)], environment, reducer) SampleSetDist.map2(~fn, ~t1, ~t2)->toType } - let map3 = (t1: t, t2: t, t3: t, aLambdaValue, accessors: ProjectAccessorsT.t, reducer) => { + let map3 = (t1: t, t2: t, t3: t, aLambdaValue, environment: Reducer_T.environment, reducer) => { let fn = (a, b, c) => - doLambdaCall(aLambdaValue, list{IEvNumber(a), IEvNumber(b), IEvNumber(c)}, accessors, reducer) + doLambdaCall(aLambdaValue, [IEvNumber(a), IEvNumber(b), IEvNumber(c)], environment, reducer) SampleSetDist.map3(~fn, ~t1, ~t2, ~t3)->toType } @@ -67,7 +65,7 @@ module Internal = { let mapN = ( aValueArray: array, aLambdaValue, - accessors: ProjectAccessorsT.t, + environment: Reducer_T.environment, reducer, ) => { switch parseSampleSetArray(aValueArray) { @@ -75,8 +73,8 @@ module Internal = { let fn = a => doLambdaCall( aLambdaValue, - list{IEvArray(E.A.fmap(x => Wrappers.evNumber(x), a))}, - accessors, + [IEvArray(E.A.fmap(x => Wrappers.evNumber(x), a))], + environment, reducer, ) SampleSetDist.mapN(~fn, ~t1)->toType @@ -96,10 +94,10 @@ let libaryBase = [ FnDefinition.make( ~name="fromDist", ~inputs=[FRTypeDist], - ~run=(_, inputs, accessors: ProjectAccessorsT.t, _) => + ~run=(_, inputs, environment, _) => switch inputs { | [FRValueDist(dist)] => - GenericDist.toSampleSetDist(dist, accessors.environment.sampleCount) + GenericDist.toSampleSetDist(dist, environment.sampleCount) ->E.R2.fmap(Wrappers.sampleSet) ->E.R2.fmap(Wrappers.evDistribution) ->E.R2.errMap(DistributionTypes.Error.toString) @@ -163,10 +161,10 @@ let libaryBase = [ FnDefinition.make( ~name="fromFn", ~inputs=[FRTypeLambda], - ~run=(inputs, _, accessors: ProjectAccessorsT.t, reducer: ProjectReducerFnT.t) => + ~run=(inputs, _, environment, reducer) => switch inputs { | [IEvLambda(lambda)] => - switch Internal.fromFn(lambda, accessors, reducer) { + switch Internal.fromFn(lambda, environment, reducer) { | Ok(r) => Ok(r->Wrappers.sampleSet->Wrappers.evDistribution) | Error(e) => Error(Operation.Error.toString(e)) } @@ -187,10 +185,10 @@ let libaryBase = [ FnDefinition.make( ~name="map", ~inputs=[FRTypeDist, FRTypeLambda], - ~run=(inputs, _, accessors: ProjectAccessorsT.t, reducer) => + ~run=(inputs, _, environment, reducer) => switch inputs { | [IEvDistribution(SampleSet(dist)), IEvLambda(lambda)] => - Internal.map1(dist, lambda, accessors, reducer)->E.R2.errMap(_ => "") + Internal.map1(dist, lambda, environment, reducer)->E.R2.errMap(_ => "") | _ => Error(impossibleError) }, (), @@ -210,14 +208,14 @@ let libaryBase = [ FnDefinition.make( ~name="map2", ~inputs=[FRTypeDist, FRTypeDist, FRTypeLambda], - ~run=(inputs, _, accessors: ProjectAccessorsT.t, reducer) => { + ~run=(inputs, _, environment, reducer) => { switch inputs { | [ IEvDistribution(SampleSet(dist1)), IEvDistribution(SampleSet(dist2)), IEvLambda(lambda), ] => - Internal.map2(dist1, dist2, lambda, accessors, reducer)->E.R2.errMap(_ => "") + Internal.map2(dist1, dist2, lambda, environment, reducer)->E.R2.errMap(_ => "") | _ => Error(impossibleError) } }, @@ -238,7 +236,7 @@ let libaryBase = [ FnDefinition.make( ~name="map3", ~inputs=[FRTypeDist, FRTypeDist, FRTypeDist, FRTypeLambda], - ~run=(inputs, _, accessors: ProjectAccessorsT.t, reducer) => + ~run=(inputs, _, environment, reducer) => switch inputs { | [ IEvDistribution(SampleSet(dist1)), @@ -246,7 +244,7 @@ let libaryBase = [ IEvDistribution(SampleSet(dist3)), IEvLambda(lambda), ] => - Internal.map3(dist1, dist2, dist3, lambda, accessors, reducer)->E.R2.errMap(_ => "") + Internal.map3(dist1, dist2, dist3, lambda, environment, reducer)->E.R2.errMap(_ => "") | _ => Error(impossibleError) }, (), @@ -266,10 +264,10 @@ let libaryBase = [ FnDefinition.make( ~name="mapN", ~inputs=[FRTypeArray(FRTypeDist), FRTypeLambda], - ~run=(inputs, _, accessors: ProjectAccessorsT.t, reducer) => + ~run=(inputs, _, environment, reducer) => switch inputs { | [IEvArray(dists), IEvLambda(lambda)] => - Internal.mapN(dists, lambda, accessors, reducer)->E.R2.errMap(_e => { + Internal.mapN(dists, lambda, environment, reducer)->E.R2.errMap(_e => { "AHHH doesn't work" }) | _ => Error(impossibleError) 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 d45b1a81..dc1008a8 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Scoring.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Scoring.res @@ -30,16 +30,16 @@ let library = [ ("prior", FRTypeDist), ]), ], - ~run=(_, inputs, accessors, _) => { + ~run=(_, inputs, environment, _) => { switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.threeArgs(inputs) { | Ok([FRValueDist(estimate), FRValueDistOrNumber(FRValueDist(d)), FRValueDist(prior)]) => - runScoring(estimate, Score_Dist(d), Some(prior), accessors.environment) + runScoring(estimate, Score_Dist(d), Some(prior), environment) | Ok([ FRValueDist(estimate), FRValueDistOrNumber(FRValueNumber(d)), FRValueDist(prior), ]) => - runScoring(estimate, Score_Scalar(d), Some(prior), accessors.environment) + runScoring(estimate, Score_Scalar(d), Some(prior), environment) | Error(e) => Error(e) | _ => Error(FunctionRegistry_Helpers.impossibleError) } @@ -49,12 +49,12 @@ let library = [ FnDefinition.make( ~name="logScore", ~inputs=[FRTypeRecord([("estimate", FRTypeDist), ("answer", FRTypeDistOrNumber)])], - ~run=(_, inputs, accessors, _) => { + ~run=(_, inputs, environment, _) => { switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.twoArgs(inputs) { | Ok([FRValueDist(estimate), FRValueDistOrNumber(FRValueDist(d))]) => - runScoring(estimate, Score_Dist(d), None, accessors.environment) + runScoring(estimate, Score_Dist(d), None, environment) | Ok([FRValueDist(estimate), FRValueDistOrNumber(FRValueNumber(d))]) => - runScoring(estimate, Score_Scalar(d), None, accessors.environment) + runScoring(estimate, Score_Scalar(d), None, environment) | Error(e) => Error(e) | _ => Error(FunctionRegistry_Helpers.impossibleError) } @@ -74,10 +74,10 @@ let library = [ FnDefinition.make( ~name="klDivergence", ~inputs=[FRTypeDist, FRTypeDist], - ~run=(_, inputs, accessors, _) => { + ~run=(_, inputs, environment, _) => { switch inputs { | [FRValueDist(estimate), FRValueDist(d)] => - runScoring(estimate, Score_Dist(d), None, accessors.environment) + runScoring(estimate, Score_Dist(d), None, environment) | _ => Error(FunctionRegistry_Helpers.impossibleError) } }, 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 c9cffcfd..0e9e51f3 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 @@ -2,16 +2,86 @@ // Other module operations such as import export will be preprocessed jobs module ExpressionT = Reducer_Expression_T -module InternalExpressionValue = ReducerInterface_InternalExpressionValue -open Reducer_ErrorValue -open ReducerInterface_InternalExpressionValue +module T = Reducer_T -let expressionValueToString = toString +type t = Reducer_T.nameSpace +type internalExpressionValue = Reducer_T.value -type t = ReducerInterface_InternalExpressionValue.nameSpace +let rec get = (nameSpace: t, id: string) => { + let T.NameSpace(container, parent) = nameSpace -let typeAliasesKey = "_typeAliases_" -let typeReferencesKey = "_typeReferences_" + switch container->Belt.MutableMap.String.get(id) { + | Some(v) => Some(v) + | None => switch parent { + | Some(p) => get(p, id) + | None => None + } + } +} + +let getWithDefault = (nameSpace: t, id: string, default) => + switch get(nameSpace, id) { + | Some(v) => Some(v) + | None => default + } + +let toString = ReducerInterface_InternalExpressionValue.toStringNameSpace + +let makeEmptyMap = () => Belt.MutableMap.String.make() + +let set = (nameSpace: t, id: string, value): t => { + let T.NameSpace(container, _) = nameSpace + Belt.MutableMap.String.set(container, id, value) + nameSpace +} + +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) +let fromExpressionValue = (aValue: internalExpressionValue): t => + switch aValue { + | IEvBindings(nameSpace) => nameSpace + | _ => makeEmptyBindings() + } + +let fromArray = a => T.NameSpace(Belt.MutableMap.String.fromArray(a), None) + +let mergeFrom = (T.NameSpace(container, _): t, T.NameSpace(newContainer, parent): t): t => { + NameSpace( + newContainer->Belt.MutableMap.String.reduce(container, (container, key, value) => { + if key != "__result__" { + Belt.MutableMap.String.set(container, key, value) + } + container + }), + parent + ) +} + +let chainTo = (nameSpace: t, previousNameSpaces: array) => { + previousNameSpaces->Belt.Array.reduce(nameSpace, (topNameSpace, prevNameSpace) => + mergeFrom(prevNameSpace, topNameSpace) + ) +} + +let removeResult = (nameSpace: t): t => { + let T.NameSpace(container, _) = nameSpace + container->Belt.MutableMap.String.remove("__result__") + nameSpace +} + +// let typeAliasesKey = "_typeAliases_" +// let typeReferencesKey = "_typeReferences_" // let getType = (NameSpace(container): t, id: string) => { // Belt.Map.String.get(container, typeAliasesKey)->Belt.Option.flatMap(aliases => @@ -31,27 +101,6 @@ let typeReferencesKey = "_typeReferences_" // ) // } -let getWithDefault = (NameSpace(container): t, id: string, default) => - switch Belt.Map.String.get(container, id) { - | Some(v) => v - | None => default - } - -let get = (nameSpace: t, id: string) => { - let NameSpace(container, parent) = nameSpace - - switch container->Belt.MutableMap.String.get(key) { - | Some(v) => Some(v) - | None => switch parent { - | Some(p) => nameSpaceGet(p, key) - | None => None - } - } -} - - -let emptyMap: map = Belt.Map.String.empty - // let setTypeAlias = (NameSpace(container): t, id: string, value): t => { // let rValue = Belt.Map.String.getWithDefault(container, typeAliasesKey, IEvRecord(emptyMap)) // let r = switch rValue { @@ -72,126 +121,74 @@ let emptyMap: map = Belt.Map.String.empty // NameSpace(Belt.Map.String.set(container, typeReferencesKey, r2)) // } -let set = (NameSpace(container): t, id: string, value): t => NameSpace( - Belt.Map.String.set(container, id, value), -) +// let removeOther = (NameSpace(container): t, NameSpace(otherContainer): t): t => { +// let keys = Belt.Map.String.keysToArray(otherContainer) +// NameSpace( +// Belt.Map.String.keep(container, (key, _value) => { +// let removeThis = Js.Array2.includes(keys, key) +// !removeThis +// }), +// ) +// } -let emptyModule: t = NameSpace(emptyMap) -let emptyBindings = emptyModule -let emptyNameSpace = emptyModule +// external castExpressionToInternalCode: ExpressionT.expressionOrFFI => internalCode = "%identity" -let toExpressionValue = (nameSpace: t): internalExpressionValue => IEvBindings(nameSpace) -let fromExpressionValue = (aValue: internalExpressionValue): t => - switch aValue { - | IEvBindings(nameSpace) => nameSpace - | _ => emptyModule - } +// let eLambdaFFIValue = (ffiFn: ExpressionT.ffiFn) => { +// IEvLambda({ +// parameters: [], +// context: emptyModule, +// body: FFI(ffiFn)->castExpressionToInternalCode, +// }) +// } -let fromArray = a => NameSpace(Belt.Map.String.fromArray(a)) +// let functionNotFoundError = (call: functionCall) => +// REFunctionNotFound(call->functionCallToCallSignature->functionCallSignatureToString)->Error -let mergeFrom = (NameSpace(container): t, NameSpace(newContainer): t): t => { - NameSpace( - newContainer->Belt.Map.String.reduce(container, (container, key, value) => - Belt.Map.String.set(container, key, value) - ), - ) -} +// let functionNotFoundErrorFFIFn = (functionName: string): ExpressionT.ffiFn => { +// (args: array, _environment: environment): result< +// internalExpressionValue, +// errorValue, +// > => { +// let call = (functionName, args) +// functionNotFoundError(call) +// } +// } -let removeOther = (NameSpace(container): t, NameSpace(otherContainer): t): t => { - let keys = Belt.Map.String.keysToArray(otherContainer) - NameSpace( - Belt.Map.String.keep(container, (key, _value) => { - let removeThis = Js.Array2.includes(keys, key) - !removeThis - }), - ) -} +// let convertOptionToFfiFnReturningResult = ( +// myFunctionName: string, +// myFunction: ExpressionT.optionFfiFnReturningResult, +// ): ExpressionT.ffiFn => { +// (args: array, environment) => { +// myFunction(args, environment)->Belt.Option.getWithDefault( +// functionNotFoundErrorFFIFn(myFunctionName)(args, environment), +// ) +// } +// } -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 - -let functionNotFoundErrorFFIFn = (functionName: string): ExpressionT.ffiFn => { - (args: array, _environment: environment): result< - internalExpressionValue, - errorValue, - > => { - let call = (functionName, args) - functionNotFoundError(call) - } -} - -let convertOptionToFfiFnReturningResult = ( - myFunctionName: string, - myFunction: ExpressionT.optionFfiFnReturningResult, -): ExpressionT.ffiFn => { - (args: array, environment) => { - myFunction(args, environment)->Belt.Option.getWithDefault( - functionNotFoundErrorFFIFn(myFunctionName)(args, environment), - ) - } -} - -let convertOptionToFfiFn = ( - myFunctionName: string, - myFunction: ExpressionT.optionFfiFn, -): ExpressionT.ffiFn => { - (args: array, environment) => { - myFunction(args, environment) - ->Belt.Option.map(v => v->Ok) - ->Belt.Option.getWithDefault(functionNotFoundErrorFFIFn(myFunctionName)(args, environment)) - } -} +// let convertOptionToFfiFn = ( +// myFunctionName: string, +// myFunction: ExpressionT.optionFfiFn, +// ): ExpressionT.ffiFn => { +// (args: array, environment) => { +// myFunction(args, environment) +// ->Belt.Option.map(v => v->Ok) +// ->Belt.Option.getWithDefault(functionNotFoundErrorFFIFn(myFunctionName)(args, environment)) +// } +// } // -- Module definition -let define = (NameSpace(container): t, identifier: string, ev: internalExpressionValue): t => { - NameSpace(Belt.Map.String.set(container, identifier, ev)) -} +// let define = (NameSpace(container): t, identifier: string, ev: internalExpressionValue): t => { +// NameSpace(Belt.Map.String.set(container, identifier, ev)) +// } -let defineNumber = (nameSpace: t, identifier: string, value: float): t => - nameSpace->define(identifier, IEvNumber(value)) +// let defineNumber = (nameSpace: t, identifier: string, value: float): t => +// nameSpace->define(identifier, IEvNumber(value)) -let defineString = (nameSpace: t, identifier: string, value: string): t => - nameSpace->define(identifier, IEvString(value)) +// let defineString = (nameSpace: t, identifier: string, value: string): t => +// nameSpace->define(identifier, IEvString(value)) -let defineBool = (nameSpace: t, identifier: string, value: bool): t => - nameSpace->define(identifier, IEvBool(value)) +// let defineBool = (nameSpace: t, identifier: string, value: bool): t => +// nameSpace->define(identifier, IEvBool(value)) -let defineModule = (nameSpace: t, identifier: string, value: t): t => - nameSpace->define(identifier, toExpressionValue(value)) - -let defineFunction = (nameSpace: t, identifier: string, value: ExpressionT.optionFfiFn): t => { - nameSpace->define(identifier, convertOptionToFfiFn(identifier, value)->eLambdaFFIValue) -} - -let defineFunctionReturningResult = ( - nameSpace: t, - identifier: string, - value: ExpressionT.optionFfiFnReturningResult, -): t => { - nameSpace->define( - identifier, - convertOptionToFfiFnReturningResult(identifier, value)->eLambdaFFIValue, - ) -} - -let emptyStdLib: t = emptyModule->defineBool("_standardLibrary", true) - -let chainTo = (nameSpace: t, previousNameSpaces: array) => { - previousNameSpaces->Belt.Array.reduce(nameSpace, (topNameSpace, prevNameSpace) => - mergeFrom(prevNameSpace, topNameSpace) - ) -} - -let removeResult = (NameSpace(container): t): t => { - container->Belt.Map.String.remove("__result__")->NameSpace -} +// let defineModule = (nameSpace: t, identifier: string, value: t): t => +// nameSpace->define(identifier, toExpressionValue(value)) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res new file mode 100644 index 00000000..213d1d80 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res @@ -0,0 +1,14 @@ +type t = Reducer_T.context + +let createContext = (stdLib: Reducer_T.nameSpace, environment: Reducer_T.environment): t => { + { + bindings: stdLib->Reducer_Bindings.extend, + environment, + } +} + +let createDefaultContext = (): t => + createContext( + ReducerInterface_StdLib.internalStdLib, + ReducerInterface_InternalExpressionValue.defaultEnvironment + ) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch.res deleted file mode 100644 index 83d3eca2..00000000 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch.res +++ /dev/null @@ -1,2 +0,0 @@ -module Builtin = Reducer_Dispatch_BuiltIn -module BuiltinMacros = Reducer_Dispatch_BuiltInMacros 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 74804d4b..1ae512db 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 @@ -1,16 +1,14 @@ module Bindings = Reducer_Bindings -module BindingsReplacer = Reducer_Expression_BindingsReplacer module Continuation = ReducerInterface_Value_Continuation module ExpressionT = Reducer_Expression_T module ExternalLibrary = ReducerInterface.ExternalLibrary module Lambda = Reducer_Expression_Lambda module MathJs = Reducer_MathJs -module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -module ProjectReducerFnT = ReducerProject_ReducerFn_T module Result = Belt.Result module TypeBuilder = Reducer_Type_TypeBuilder -open ReducerInterface_InternalExpressionValue +module IEV = ReducerInterface_InternalExpressionValue + open Reducer_ErrorValue /* @@ -24,42 +22,42 @@ open Reducer_ErrorValue exception TestRescriptException let callInternal = ( - call: functionCall, - accessors: ProjectAccessorsT.t, - reducer: ProjectReducerFnT.t, + call: IEV.functionCall, + _: Reducer_T.environment, + _: Reducer_T.reducerFn, ): result<'b, errorValue> => { - let callMathJs = (call: functionCall): result<'b, errorValue> => + let callMathJs = (call: IEV.functionCall): result<'b, errorValue> => switch call { - | ("javascriptraise", [msg]) => Js.Exn.raiseError(toString(msg)) // For Tests + | ("javascriptraise", [msg]) => Js.Exn.raiseError(IEV.toString(msg)) // For Tests | ("rescriptraise", _) => raise(TestRescriptException) // For Tests - | call => call->toStringFunctionCall->MathJs.Eval.eval + | call => call->IEV.toStringFunctionCall->MathJs.Eval.eval } let constructRecord = arrayOfPairs => { Belt.Array.map(arrayOfPairs, pairValue => switch pairValue { - | IEvArray([IEvString(key), valueValue]) => (key, valueValue) - | _ => ("wrong key type", pairValue->toStringWithType->IEvString) + | Reducer_T.IEvArray([IEvString(key), valueValue]) => (key, valueValue) + | _ => ("wrong key type", pairValue->IEV.toStringWithType->IEvString) } ) ->Belt.Map.String.fromArray - ->IEvRecord + ->Reducer_T.IEvRecord ->Ok } - let arrayAtIndex = (aValueArray: array, fIndex: float) => + let arrayAtIndex = (aValueArray: array, fIndex: float) => switch Belt.Array.get(aValueArray, Belt.Int.fromFloat(fIndex)) { | Some(value) => value->Ok | None => REArrayIndexNotFound("Array index not found", Belt.Int.fromFloat(fIndex))->Error } - let moduleAtIndex = (nameSpace: nameSpace, sIndex) => + let moduleAtIndex = (nameSpace: Reducer_T.nameSpace, sIndex) => switch Bindings.get(nameSpace, sIndex) { | Some(value) => value->Ok | None => RERecordPropertyNotFound("Bindings property not found", sIndex)->Error } - let recordAtIndex = (dict: Belt.Map.String.t, sIndex) => + let recordAtIndex = (dict: Belt.Map.String.t, sIndex) => switch Belt.Map.String.get(dict, sIndex) { | Some(value) => value->Ok | None => RERecordPropertyNotFound("Record property not found", sIndex)->Error @@ -68,26 +66,26 @@ let callInternal = ( let doAddArray = (originalA, b) => { let a = originalA->Js.Array2.copy let _ = Js.Array2.pushMany(a, b) - a->IEvArray->Ok + a->Reducer_T.IEvArray->Ok } let doAddString = (a, b) => { let answer = Js.String2.concat(a, b) - answer->IEvString->Ok + answer->Reducer_T.IEvString->Ok } - let inspect = (value: internalExpressionValue) => { - Js.log(value->toString) + let inspect = (value: Reducer_T.value) => { + Js.log(value->IEV.toString) value->Ok } - let inspectLabel = (value: internalExpressionValue, label: string) => { - Js.log(`${label}: ${value->toString}`) + let inspectLabel = (value: Reducer_T.value, label: string) => { + Js.log(`${label}: ${value->IEV.toString}`) value->Ok } - let doSetBindings = (bindings: nameSpace, symbol: string, value: internalExpressionValue) => { - Bindings.set(bindings, symbol, value)->IEvBindings->Ok - } + // let doSetBindings = (bindings: Reducer_T.nameSpace, symbol: string, value: Reducer_T.value) => { + // Bindings.set(bindings, symbol, value)->IEvBindings->Ok + // } // let doSetTypeAliasBindings = ( // bindings: nameSpace, @@ -98,50 +96,15 @@ let callInternal = ( // let doSetTypeOfBindings = (bindings: nameSpace, symbol: string, value: internalExpressionValue) => // Bindings.setTypeOf(bindings, symbol, value)->IEvBindings->Ok - let doExportBindings = (bindings: nameSpace) => bindings->Bindings.toExpressionValue->Ok + // let doExportBindings = (bindings: nameSpace) => bindings->Bindings.toExpressionValue->Ok - let doIdentity = (value: internalExpressionValue) => value->Ok + // let doIdentity = (value: Reducer_T.value) => value->Ok - let doDumpBindings = (continuation: nameSpace, value: internalExpressionValue) => { - // let _ = Continuation.inspect(continuation, "doDumpBindings") - accessors.states.continuation = continuation->Bindings.set("__result__", value) - value->Ok - } - - module SampleMap = { - let doLambdaCall = (aLambdaValue, list) => - switch Lambda.doLambdaCall(aLambdaValue, list, accessors, reducer) { - | IEvNumber(f) => Ok(f) - | _ => Error(Operation.SampleMapNeedsNtoNFunction) - } - - let toType = r => - switch r { - | Ok(r) => Ok(IEvDistribution(SampleSet(r))) - | Error(r) => Error(REDistributionError(SampleSetError(r))) - } - - let parseSampleSetArray = (arr: array): option< - array, - > => { - let parseSampleSet = (value: internalExpressionValue): option => - switch value { - | IEvDistribution(SampleSet(dist)) => Some(dist) - | _ => None - } - E.A.O.openIfAllSome(E.A.fmap(parseSampleSet, arr)) - } - - let _mapN = (aValueArray: array, aLambdaValue) => { - switch parseSampleSetArray(aValueArray) { - | Some(t1) => - let fn = a => doLambdaCall(aLambdaValue, list{IEvArray(E.A.fmap(x => IEvNumber(x), a))}) - SampleSetDist.mapN(~fn, ~t1)->toType - | None => - Error(REFunctionNotFound(call->functionCallToCallSignature->functionCallSignatureToString)) - } - } - } + // let doDumpBindings = (continuation: Reducer_T.nameSpace, value: Reducer_T.value) => { + // // let _ = Continuation.inspect(continuation, "doDumpBindings") + // accessors.states.continuation = continuation->Bindings.set("__result__", value) + // value->Ok + // } switch call { | ("$_atIndex_$", [IEvArray(aValueArray), IEvNumber(fIndex)]) => arrayAtIndex(aValueArray, fIndex) @@ -149,15 +112,15 @@ let callInternal = ( | ("$_atIndex_$", [IEvRecord(dict), IEvString(sIndex)]) => recordAtIndex(dict, sIndex) | ("$_constructArray_$", args) => IEvArray(args)->Ok | ("$_constructRecord_$", [IEvArray(arrayOfPairs)]) => constructRecord(arrayOfPairs) - | ("$_exportBindings_$", [IEvBindings(nameSpace)]) => doExportBindings(nameSpace) - | ("$_exportBindings_$", [evValue]) => doIdentity(evValue) - | ("$_setBindings_$", [IEvBindings(nameSpace), IEvSymbol(symbol), value]) => - doSetBindings(nameSpace, symbol, value) + // | ("$_exportBindings_$", [IEvBindings(nameSpace)]) => doExportBindings(nameSpace) + // | ("$_exportBindings_$", [evValue]) => doIdentity(evValue) + // | ("$_setBindings_$", [IEvBindings(nameSpace), IEvSymbol(symbol), value]) => + // doSetBindings(nameSpace, symbol, value) // | ("$_setTypeAliasBindings_$", [IEvBindings(nameSpace), IEvTypeIdentifier(symbol), value]) => // doSetTypeAliasBindings(nameSpace, symbol, value) // | ("$_setTypeOfBindings_$", [IEvBindings(nameSpace), IEvSymbol(symbol), value]) => // doSetTypeOfBindings(nameSpace, symbol, value) - | ("$_dumpBindings_$", [IEvBindings(nameSpace), _, evValue]) => doDumpBindings(nameSpace, evValue) + // | ("$_dumpBindings_$", [IEvBindings(nameSpace), _, evValue]) => doDumpBindings(nameSpace, evValue) // | ("$_typeModifier_memberOf_$", [IEvTypeIdentifier(typeIdentifier), IEvArray(arr)]) => // TypeBuilder.typeModifier_memberOf(IEvTypeIdentifier(typeIdentifier), IEvArray(arr)) // | ("$_typeModifier_memberOf_$", [IEvType(typeRecord), IEvArray(arr)]) => @@ -191,31 +154,31 @@ let callInternal = ( | (_, [IEvString(_), IEvString(_)]) => callMathJs(call) | call => - Error(REFunctionNotFound(call->functionCallToCallSignature->functionCallSignatureToString)) // Report full type signature as error + Error(REFunctionNotFound(call->IEV.functionCallToCallSignature->IEV.functionCallSignatureToString)) // Report full type signature as error } } /* Reducer uses Result monad while reducing expressions */ let dispatch = ( - call: functionCall, - accessors: ProjectAccessorsT.t, - reducer: ProjectReducerFnT.t, -): internalExpressionValue => + call: IEV.functionCall, + env: Reducer_T.environment, + reducer: Reducer_T.reducerFn +): Reducer_T.value => try { let (fn, args) = call if fn->Js.String2.startsWith("$") { - switch callInternal((fn, args), accessors, reducer) { + switch callInternal((fn, args), env, reducer) { | Ok(v) => v | Error(e) => raise(ErrorException(e)) } } else { // There is a bug that prevents string match in patterns // So we have to recreate a copy of the string - switch ExternalLibrary.dispatch((Js.String.make(fn), args), accessors, reducer, callInternal) { - | Ok(v) => v - | Error(e) => raise(ErrorException(e)) - } + switch ExternalLibrary.dispatch((Js.String.make(fn), args), env, reducer, callInternal) { + | Ok(v) => v + | Error(e) => raise(ErrorException(e)) + } } } catch { | ErrorException(e) => raise(ErrorException(e)) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index 69916c4c..22b5f0d6 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -1,190 +1,189 @@ -/* - Macros are like functions but instead of taking values as parameters, - they take expressions as parameters and return a new expression. - Macros are used to define language building blocks. They are like Lisp macros. -*/ -module Bindings = Reducer_Bindings -module BindingsReplacer = Reducer_Expression_BindingsReplacer -module ErrorValue = Reducer_ErrorValue -module ExpressionBuilder = Reducer_Expression_ExpressionBuilder -module ExpressionT = Reducer_Expression_T -module ExpressionWithContext = Reducer_ExpressionWithContext -module InternalExpressionValue = ReducerInterface_InternalExpressionValue -module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -module ProjectReducerFnT = ReducerProject_ReducerFn_T +// /* +// Macros are like functions but instead of taking values as parameters, +// they take expressions as parameters and return a new expression. +// Macros are used to define language building blocks. They are like Lisp macros. +// */ +// module BindingsReplacer = Reducer_Expression_BindingsReplacer +// module ErrorValue = Reducer_ErrorValue +// module ExpressionBuilder = Reducer_Expression_ExpressionBuilder +// module ExpressionT = Reducer_Expression_T +// module ExpressionWithContext = Reducer_ExpressionWithContext +// module InternalExpressionValue = ReducerInterface_InternalExpressionValue +// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T +// module ProjectReducerFnT = ReducerProject_ReducerFn_T -open Reducer_Expression_ExpressionBuilder +// open Reducer_Expression_ExpressionBuilder -exception ErrorException = ErrorValue.ErrorException -type expression = ExpressionT.expression -type expressionWithContext = ExpressionWithContext.expressionWithContext +// exception ErrorException = ErrorValue.ErrorException +// type expression = ExpressionT.expression +// type expressionWithContext = ExpressionWithContext.expressionWithContext -let dispatchMacroCall = ( - macroExpression: expression, - bindings: ExpressionT.bindings, - accessors: ProjectAccessorsT.t, - reduceExpression: ProjectReducerFnT.t, -): expressionWithContext => { - let useExpressionToSetBindings = (bindingExpr: expression, accessors, statement, newCode) => { - let nameSpaceValue = reduceExpression(bindingExpr, bindings, accessors) +// let dispatchMacroCall = ( +// macroExpression: expression, +// bindings: ExpressionT.bindings, +// accessors: ProjectAccessorsT.t, +// reduceExpression: ProjectReducerFnT.t, +// ): expressionWithContext => { +// let useExpressionToSetBindings = (bindingExpr: expression, accessors, statement, newCode) => { +// let nameSpaceValue = reduceExpression(bindingExpr, bindings, accessors) - let newBindings = Bindings.fromExpressionValue(nameSpaceValue) +// let newBindings = Reducer_Bindings.fromExpressionValue(nameSpaceValue) - let boundStatement = BindingsReplacer.replaceSymbols(newBindings, statement) +// let boundStatement = BindingsReplacer.replaceSymbols(newBindings, statement) - ExpressionWithContext.withContext(newCode(newBindings->eModule, boundStatement), newBindings) - } +// ExpressionWithContext.withContext(newCode(newBindings->eModule, boundStatement), newBindings) +// } - let correspondingSetBindingsFn = (fnName: string): string => - switch fnName { - | "$_let_$" => "$_setBindings_$" - | "$_typeOf_$" => "$_setTypeOfBindings_$" - | "$_typeAlias_$" => "$_setTypeAliasBindings_$" - | "$_endOfOuterBlock_$" => "$_dumpBindings_$" - | _ => "" - } +// let correspondingSetBindingsFn = (fnName: string): string => +// switch fnName { +// | "$_let_$" => "$_setBindings_$" +// | "$_typeOf_$" => "$_setTypeOfBindings_$" +// | "$_typeAlias_$" => "$_setTypeAliasBindings_$" +// | "$_endOfOuterBlock_$" => "$_dumpBindings_$" +// | _ => "" +// } - let doBindStatement = (bindingExpr: expression, statement: expression, accessors) => { - let defaultStatement = ErrorValue.REAssignmentExpected->ErrorException - switch statement { - | ExpressionT.EList(list{ExpressionT.EValue(IEvCall(callName)), ExpressionT.EValue(IEvSymbol(symbolExpr)), statement}) => { - let setBindingsFn = correspondingSetBindingsFn(callName) - if setBindingsFn !== "" { - useExpressionToSetBindings(bindingExpr, accessors, statement, ( - newBindingsExpr, - boundStatement, - ) => eFunction(setBindingsFn, list{newBindingsExpr, symbolExpr->IEvSymbol->ExpressionT.EValue, boundStatement})) - } else { - raise(defaultStatement) - } - } - | _ => raise(defaultStatement) - } - } +// let doBindStatement = (bindingExpr: expression, statement: expression, accessors) => { +// let defaultStatement = ErrorValue.REAssignmentExpected->ErrorException +// switch statement { +// | ExpressionT.EList(list{ExpressionT.EValue(IEvCall(callName)), ExpressionT.EValue(IEvSymbol(symbolExpr)), statement}) => { +// let setBindingsFn = correspondingSetBindingsFn(callName) +// if setBindingsFn !== "" { +// useExpressionToSetBindings(bindingExpr, accessors, statement, ( +// newBindingsExpr, +// boundStatement, +// ) => eFunction(setBindingsFn, list{newBindingsExpr, symbolExpr->IEvSymbol->ExpressionT.EValue, boundStatement})) +// } else { +// raise(defaultStatement) +// } +// } +// | _ => raise(defaultStatement) +// } +// } - let doBindExpression = ( - bindingExpr: expression, - statement: expression, - accessors, - ): expressionWithContext => { - let defaultStatement = () => - useExpressionToSetBindings(bindingExpr, accessors, statement, ( - _newBindingsExpr, - boundStatement, - ) => boundStatement) +// let doBindExpression = ( +// bindingExpr: expression, +// statement: expression, +// accessors, +// ): expressionWithContext => { +// let defaultStatement = () => +// useExpressionToSetBindings(bindingExpr, accessors, statement, ( +// _newBindingsExpr, +// boundStatement, +// ) => boundStatement) - switch statement { - | ExpressionT.EList(list{ExpressionT.EValue(IEvCall(callName)), symbolExpr, statement}) => { - let setBindingsFn = correspondingSetBindingsFn(callName) - if setBindingsFn !== "" { - useExpressionToSetBindings(bindingExpr, accessors, statement, ( - newBindingsExpr, - boundStatement, - ) => - eFunction( - "$_exportBindings_$", - list{eFunction(setBindingsFn, list{newBindingsExpr, symbolExpr, boundStatement})}, // expression returning bindings - ) - ) - } else { - defaultStatement() - } - } - | _ => defaultStatement() - } - } +// switch statement { +// | ExpressionT.EList(list{ExpressionT.EValue(IEvCall(callName)), symbolExpr, statement}) => { +// let setBindingsFn = correspondingSetBindingsFn(callName) +// if setBindingsFn !== "" { +// useExpressionToSetBindings(bindingExpr, accessors, statement, ( +// newBindingsExpr, +// boundStatement, +// ) => +// eFunction( +// "$_exportBindings_$", +// list{eFunction(setBindingsFn, list{newBindingsExpr, symbolExpr, boundStatement})}, // expression returning bindings +// ) +// ) +// } else { +// defaultStatement() +// } +// } +// | _ => defaultStatement() +// } +// } - let doBlock = ( - exprs: list, - _bindings: ExpressionT.bindings, - _accessors, - ): expressionWithContext => { - let exprsArray = Belt.List.toArray(exprs) - let maxIndex = Js.Array2.length(exprsArray) - 1 - let newStatement = exprsArray->Js.Array2.reducei((acc, statement, index) => - if index == 0 { - if index == maxIndex { - eBindExpressionDefault(statement) - } else { - eBindStatementDefault(statement) - } - } else if index == maxIndex { - eBindExpression(acc, statement) - } else { - eBindStatement(acc, statement) - } - , eSymbol("undefined block")) - ExpressionWithContext.noContext(newStatement) - } +// let doBlock = ( +// exprs: list, +// _bindings: ExpressionT.bindings, +// _accessors, +// ): expressionWithContext => { +// let exprsArray = Belt.List.toArray(exprs) +// let maxIndex = Js.Array2.length(exprsArray) - 1 +// let newStatement = exprsArray->Js.Array2.reducei((acc, statement, index) => +// if index == 0 { +// if index == maxIndex { +// eBindExpressionDefault(statement) +// } else { +// eBindStatementDefault(statement) +// } +// } else if index == maxIndex { +// eBindExpression(acc, statement) +// } else { +// eBindStatement(acc, statement) +// } +// , eSymbol("undefined block")) +// ExpressionWithContext.noContext(newStatement) +// } - let doLambdaDefinition = ( - bindings: ExpressionT.bindings, - parameters: array, - lambdaDefinition: ExpressionT.expression, - ) => ExpressionWithContext.noContext(eLambda(parameters, bindings, lambdaDefinition)) +// let doLambdaDefinition = ( +// bindings: ExpressionT.bindings, +// parameters: array, +// lambdaDefinition: ExpressionT.expression, +// ) => ExpressionWithContext.noContext(eLambda(parameters, bindings, lambdaDefinition)) - let doTernary = ( - condition: expression, - ifTrue: expression, - ifFalse: expression, - bindings: ExpressionT.bindings, - accessors, - ): expressionWithContext => { - let blockCondition = ExpressionBuilder.eBlock(list{condition}) - let conditionValue = reduceExpression(blockCondition, bindings, accessors) +// let doTernary = ( +// condition: expression, +// ifTrue: expression, +// ifFalse: expression, +// bindings: ExpressionT.bindings, +// accessors, +// ): expressionWithContext => { +// let blockCondition = ExpressionBuilder.eBlock(list{condition}) +// let conditionValue = reduceExpression(blockCondition, bindings, accessors) - switch conditionValue { - | InternalExpressionValue.IEvBool(false) => { - let ifFalseBlock = eBlock(list{ifFalse}) - ExpressionWithContext.withContext(ifFalseBlock, bindings) - } - | InternalExpressionValue.IEvBool(true) => { - let ifTrueBlock = eBlock(list{ifTrue}) - ExpressionWithContext.withContext(ifTrueBlock, bindings) - } - | _ => raise(ErrorException(REExpectedType("Boolean", ""))) - } - } +// switch conditionValue { +// | InternalExpressionValue.IEvBool(false) => { +// let ifFalseBlock = eBlock(list{ifFalse}) +// ExpressionWithContext.withContext(ifFalseBlock, bindings) +// } +// | InternalExpressionValue.IEvBool(true) => { +// let ifTrueBlock = eBlock(list{ifTrue}) +// ExpressionWithContext.withContext(ifTrueBlock, bindings) +// } +// | _ => raise(ErrorException(REExpectedType("Boolean", ""))) +// } +// } - let expandExpressionList = ( - aList, - bindings: ExpressionT.bindings, - accessors, - ): expressionWithContext => - switch aList { - | list{ - ExpressionT.EValue(IEvCall("$$_bindStatement_$$")), - bindingExpr: ExpressionT.expression, - statement, - } => - doBindStatement(bindingExpr, statement, accessors) - | list{ExpressionT.EValue(IEvCall("$$_bindStatement_$$")), statement} => - // bindings of the context are used when there is no binding expression - doBindStatement(eModule(bindings), statement, accessors) - | list{ - ExpressionT.EValue(IEvCall("$$_bindExpression_$$")), - bindingExpr: ExpressionT.expression, - expression, - } => - doBindExpression(bindingExpr, expression, accessors) - | list{ExpressionT.EValue(IEvCall("$$_bindExpression_$$")), expression} => - // bindings of the context are used when there is no binding expression - doBindExpression(eModule(bindings), expression, accessors) - | list{ExpressionT.EValue(IEvCall("$$_block_$$")), ...exprs} => - doBlock(exprs, bindings, accessors) - | list{ - ExpressionT.EValue(IEvCall("$$_lambda_$$")), - ExpressionT.EValue(IEvArrayString(parameters)), - lambdaDefinition, - } => - doLambdaDefinition(bindings, parameters, lambdaDefinition) - | list{ExpressionT.EValue(IEvCall("$$_ternary_$$")), condition, ifTrue, ifFalse} => - doTernary(condition, ifTrue, ifFalse, bindings, accessors) - | _ => ExpressionWithContext.noContext(ExpressionT.EList(aList)) - } +// let expandExpressionList = ( +// aList, +// bindings: ExpressionT.bindings, +// accessors, +// ): expressionWithContext => +// switch aList { +// | list{ +// ExpressionT.EValue(IEvCall("$$_bindStatement_$$")), +// bindingExpr: ExpressionT.expression, +// statement, +// } => +// doBindStatement(bindingExpr, statement, accessors) +// | list{ExpressionT.EValue(IEvCall("$$_bindStatement_$$")), statement} => +// // bindings of the context are used when there is no binding expression +// doBindStatement(eModule(bindings), statement, accessors) +// | list{ +// ExpressionT.EValue(IEvCall("$$_bindExpression_$$")), +// bindingExpr: ExpressionT.expression, +// expression, +// } => +// doBindExpression(bindingExpr, expression, accessors) +// | list{ExpressionT.EValue(IEvCall("$$_bindExpression_$$")), expression} => +// // bindings of the context are used when there is no binding expression +// doBindExpression(eModule(bindings), expression, accessors) +// | list{ExpressionT.EValue(IEvCall("$$_block_$$")), ...exprs} => +// doBlock(exprs, bindings, accessors) +// | list{ +// ExpressionT.EValue(IEvCall("$$_lambda_$$")), +// ExpressionT.EValue(IEvArrayString(parameters)), +// lambdaDefinition, +// } => +// doLambdaDefinition(bindings, parameters, lambdaDefinition) +// | list{ExpressionT.EValue(IEvCall("$$_ternary_$$")), condition, ifTrue, ifFalse} => +// doTernary(condition, ifTrue, ifFalse, bindings, accessors) +// | _ => ExpressionWithContext.noContext(ExpressionT.EList(aList)) +// } - switch macroExpression { - | EList(aList) => expandExpressionList(aList, bindings, accessors) - | _ => ExpressionWithContext.noContext(macroExpression) - } -} +// switch macroExpression { +// | EList(aList) => expandExpressionList(aList, bindings, accessors) +// | _ => ExpressionWithContext.noContext(macroExpression) +// } +// } 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 310f4879..68339bed 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 @@ -1,23 +1,23 @@ -module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -module T = Reducer_Dispatch_T -module TypeChecker = Reducer_Type_TypeChecker -open ReducerInterface_InternalExpressionValue +// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T +// module T = Reducer_Dispatch_T +// module TypeChecker = Reducer_Type_TypeChecker +// open ReducerInterface_InternalExpressionValue -type errorValue = Reducer_ErrorValue.errorValue +// type errorValue = Reducer_ErrorValue.errorValue -let makeFromTypes = jumpTable => { - let dispatchChainPiece: T.dispatchChainPiece = ( - (fnName, fnArgs): functionCall, - accessors: ProjectAccessorsT.t, - ) => { - let jumpTableEntry = jumpTable->Js.Array2.find(elem => { - let (candidName, candidType, _) = elem - candidName == fnName && TypeChecker.checkITypeArgumentsBool(candidType, fnArgs) - }) - switch jumpTableEntry { - | Some((_, _, bridgeFn)) => bridgeFn(fnArgs, accessors)->Some - | _ => None - } - } - dispatchChainPiece -} +// let makeFromTypes = jumpTable => { +// let dispatchChainPiece: T.dispatchChainPiece = ( +// (fnName, fnArgs): functionCall, +// accessors: ProjectAccessorsT.t, +// ) => { +// let jumpTableEntry = jumpTable->Js.Array2.find(elem => { +// let (candidName, candidType, _) = elem +// candidName == fnName && TypeChecker.checkITypeArgumentsBool(candidType, fnArgs) +// }) +// switch jumpTableEntry { +// | Some((_, _, bridgeFn)) => bridgeFn(fnArgs, accessors)->Some +// | _ => None +// } +// } +// 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 68b8f789..0966c699 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 @@ -1,22 +1,21 @@ -module InternalExpressionValue = ReducerInterface_InternalExpressionValue -module ExpressionT = Reducer_Expression_T -module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -module ProjectReducerFnT = ReducerProject_ReducerFn_T +// module InternalExpressionValue = ReducerInterface_InternalExpressionValue +// module ExpressionT = Reducer_Expression_T +// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -// Each piece of the dispatch chain computes the result or returns None so that the chain can continue -type dispatchChainPiece = ( - InternalExpressionValue.functionCall, - ProjectAccessorsT.t, -) => option> +// // Each piece of the dispatch chain computes the result or returns None so that the chain can continue +// type dispatchChainPiece = ( +// InternalExpressionValue.functionCall, +// ProjectAccessorsT.t, +// ) => option> -type dispatchChainPieceWithReducer = ( - InternalExpressionValue.functionCall, - ProjectAccessorsT.t, - ProjectReducerFnT.t, -) => option> +// type dispatchChainPieceWithReducer = ( +// InternalExpressionValue.functionCall, +// ProjectAccessorsT.t, +// Reducer_T.reducerFn, +// ) => option> -// This is a switch statement case implementation: get the arguments and compute the result -type genericIEvFunction = ( - array, - ProjectAccessorsT.t, -) => result +// // This is a switch statement case implementation: get the arguments and compute the result +// type genericIEvFunction = ( +// 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 c2d46576..1bfd330d 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 @@ -1,119 +1,100 @@ module Bindings = Reducer_Bindings -module BindingsReplacer = Reducer_Expression_BindingsReplacer -module BuiltIn = Reducer_Dispatch_BuiltIn -module ExpressionBuilder = Reducer_Expression_ExpressionBuilder -module Extra = Reducer_Extra -module InternalExpressionValue = ReducerInterface_InternalExpressionValue module Lambda = Reducer_Expression_Lambda -module Macro = Reducer_Expression_Macro -module MathJs = Reducer_MathJs -module ProjectAccessorsT = ReducerProject_ProjectAccessors_T module Result = Belt.Result -module T = Reducer_Expression_T +module T = Reducer_T type errorValue = Reducer_ErrorValue.errorValue -type t = T.t exception ErrorException = Reducer_ErrorValue.ErrorException /* - Recursively evaluate/reduce the expression (Lisp AST/Lambda calculus) + Recursively evaluate the expression */ -let rec evaluate = ( - expression: t, - bindings: T.bindings, - accessors: ProjectAccessorsT.t, -): InternalExpressionValue.t => { - // Js.log(`reduce: ${T.toString(expression)} bindings: ${bindings->Bindings.toString}`) - // Js.log(`reduce: ${T.toString(expression)}`) +let rec evaluate: T.reducerFn = ( + expression, + context +) => { + Js.log(`reduce: ${expression->Reducer_Expression_T.toString}`) switch expression { - | T.Eblock(statements) => { - statements->Js.Array2.reduce(statement => evaluate(statement, bindings, accessors)) + | T.EBlock(statements) => { + let innerContext = {...context, bindings: context.bindings->Bindings.extend} + statements->Js.Array2.reduce( + (acc, statement) => statement->evaluate(innerContext), + T.IEvVoid + ) } - | T.ESymbol(name) => bindings->nameSpaceGet(name) - | T.EValue(value) => value + + | T.EProgram(statements) => { + Js.log(`bindings: ${context.bindings->Reducer_Bindings.toString}`) + let res = statements->Js.Array2.reduce( + (acc, 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.ERecord(map) => + RETodo("TODO")->ErrorException->raise + + | 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.EValue(value) => + value + | T.ETernary(predicate, trueCase, falseCase) => { - let predicateResult = evaluate(predicate, bindings, accessors) + let predicateResult = predicate->evaluate(context) switch predicateResult { - | InternalExpressionValue.IEvBool(false) => - evaluate(false, bindings, accessors) - | InternalExpressionValue.IEvBool(true) => - evaluate(trueCase, bindings, accessors) + | T.IEvBool(value) => + (value ? trueCase : falseCase)->evaluate(context) | _ => REExpectedType("Boolean", "")->ErrorException->raise } } - | T.ELambda(parameteres, expr) => { - BInternalExpressionValue.IEvLambda({ - parameters: parameters, - context: context, - body: NotFFI(expr)->BBindings.castExpressionToInternalCode, - })->T.EValue - } + + | T.ELambda(parameters, body) => + Lambda.makeLambda(parameters, context.bindings, body)->T.IEvLambda + | T.ECall(fn, args) => { - let func = evaluate(fn, bindings, accessors) - "TODO" - // Lambda.doLambdaCall(), etc. - } - } -} - -/* - After reducing each level of expression(Lisp AST), we have a value list to evaluate - */ -and reduceValueList = ( - valueList: list, - accessors: ProjectAccessorsT.t, -): InternalExpressionValue.t => - switch valueList { - | list{IEvCall(fName), ...args} => { - let checkedArgs = switch fName { - | "$_setBindings_$" | "$_setTypeOfBindings_$" | "$_setTypeAliasBindings_$" => args - | _ => args->Lambda.checkIfReduced + 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 } - - (fName, checkedArgs->Belt.List.toArray)->BuiltIn.dispatch( - accessors, - reduceExpressionInProject, - ) } - | list{IEvLambda(_)} => - // TODO: remove on solving issue#558 - valueList->Lambda.checkIfReduced->Belt.List.toArray->InternalExpressionValue.IEvArray - | list{IEvLambda(lambdaCall), ...args} => - args - ->Lambda.checkIfReduced - ->Lambda.doLambdaCall(lambdaCall, _, accessors, reduceExpressionInProject) - | _ => valueList->Lambda.checkIfReduced->Belt.List.toArray->InternalExpressionValue.IEvArray } - -let reduceExpressionInProject = evaluate - -let reduceReturningBindings = ( - expression: t, - continuation: T.bindings, - accessors: ProjectAccessorsT.t, -): (InternalExpressionValue.t, T.bindings) => { - let states = accessors.states - let result = reduceExpressionInProject(expression, continuation, accessors) - (result, states.continuation) } module BackCompatible = { // Those methods are used to support the existing tests // If they are used outside limited testing context, error location reporting will fail - let parse = (peggyCode: string): result => + let parse = (peggyCode: string): result => peggyCode->Reducer_Peggy_Parse.parse->Result.map(Reducer_Peggy_ToExpression.fromNode) - let evaluate = (expression: t): result => { - let accessors = ProjectAccessorsT.identityAccessors + let evaluate = (expression: Reducer_T.expression): result => { + let context = Reducer_Context.createDefaultContext() try { - expression->reduceExpressionInProject(accessors.stdLib, accessors)->Ok + expression->evaluate(context)->Ok } catch { | ErrorException(e) => Error(e) | _ => raise(ErrorException(RETodo("internal exception"))) } } - let evaluateString = (peggyCode: string): result => + let evaluateString = (peggyCode: string): result => parse(peggyCode)->Result.flatMap(evaluate) } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_ExpressionWithContext.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_ExpressionWithContext.res index 23b7e2c8..47bcf817 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_ExpressionWithContext.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_ExpressionWithContext.res @@ -1,53 +1,50 @@ -module Bindings = Reducer_Bindings -module BindingsReplacer = Reducer_Expression_BindingsReplacer -module ErrorValue = Reducer_ErrorValue -module ExpressionT = Reducer_Expression_T -module InternalExpressionValue = ReducerInterface_InternalExpressionValue -module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -module ProjectReducerFnT = ReducerProject_ReducerFn_T -module Result = Belt.Result +// module Bindings = Reducer_Bindings +// module ErrorValue = Reducer_ErrorValue +// module ExpressionT = Reducer_Expression_T +// module InternalExpressionValue = ReducerInterface_InternalExpressionValue +// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T +// module Result = Belt.Result -type bindings = ExpressionT.bindings -type context = bindings -type environment = InternalExpressionValue.environment -type errorValue = Reducer_ErrorValue.errorValue -type expression = ExpressionT.expression -type internalExpressionValue = InternalExpressionValue.t +// type bindings = Reducer_T.nameSpace +// type context = bindings +// type environment = InternalExpressionValue.environment +// type errorValue = Reducer_ErrorValue.errorValue +// type expression = ExpressionT.expression -type expressionWithContext = - | ExpressionWithContext(expression, context) - | ExpressionNoContext(expression) +// type expressionWithContext = +// | ExpressionWithContext(expression, context) +// | ExpressionNoContext(expression) -let callReducer = ( - expressionWithContext: expressionWithContext, - bindings: bindings, - accessors: ProjectAccessorsT.t, - reducer: ProjectReducerFnT.t, -): internalExpressionValue => { - switch expressionWithContext { - | ExpressionNoContext(expr) => - // Js.log(`callReducer: bindings ${Bindings.toString(bindings)} expr ${ExpressionT.toString(expr)}`) - reducer(expr, bindings, accessors) - | ExpressionWithContext(expr, context) => - // Js.log(`callReducer: context ${Bindings.toString(context)} expr ${ExpressionT.toString(expr)}`) - reducer(expr, context, accessors) - } -} +// let callReducer = ( +// expressionWithContext: expressionWithContext, +// bindings: bindings, +// accessors: ProjectAccessorsT.t, +// reducer: Reducer_T.reducerFn, +// ): Reducer_T.value => { +// switch expressionWithContext { +// | ExpressionNoContext(expr) => +// // Js.log(`callReducer: bindings ${Bindings.toString(bindings)} expr ${ExpressionT.toString(expr)}`) +// reducer(expr, bindings, accessors) +// | ExpressionWithContext(expr, context) => +// // Js.log(`callReducer: context ${Bindings.toString(context)} expr ${ExpressionT.toString(expr)}`) +// reducer(expr, context, accessors) +// } +// } -let withContext = (expression, context) => ExpressionWithContext(expression, context) -let noContext = expression => ExpressionNoContext(expression) +// let withContext = (expression, context) => ExpressionWithContext(expression, context) +// let noContext = expression => ExpressionNoContext(expression) -let toString = expressionWithContext => - switch expressionWithContext { - | ExpressionNoContext(expr) => ExpressionT.toString(expr) - | ExpressionWithContext(expr, context) => - `${ExpressionT.toString(expr)} context: ${context - ->Bindings.toExpressionValue - ->InternalExpressionValue.toString}` - } +// let toString = expressionWithContext => +// switch expressionWithContext { +// | ExpressionNoContext(expr) => ExpressionT.toString(expr) +// | ExpressionWithContext(expr, context) => +// `${ExpressionT.toString(expr)} context: ${context +// ->Bindings.toExpressionValue +// ->InternalExpressionValue.toString}` +// } -let toStringResult = rExpressionWithContext => - switch rExpressionWithContext { - | Ok(expressionWithContext) => `Ok(${toString(expressionWithContext)})` - | Error(errorValue) => ErrorValue.errorToString(errorValue) - } +// let toStringResult = rExpressionWithContext => +// switch rExpressionWithContext { +// | Ok(expressionWithContext) => `Ok(${toString(expressionWithContext)})` +// | Error(errorValue) => ErrorValue.errorToString(errorValue) +// } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_BindingsReplacer.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_BindingsReplacer.res index 8a729405..f818ee27 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_BindingsReplacer.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_BindingsReplacer.res @@ -1,49 +1,49 @@ -module ErrorValue = Reducer_ErrorValue -module ExpressionT = Reducer_Expression_T -module InternalExpressionValue = ReducerInterface_InternalExpressionValue -module Bindings = Reducer_Bindings +// module ErrorValue = Reducer_ErrorValue +// module ExpressionT = Reducer_Expression_T +// module InternalExpressionValue = ReducerInterface_InternalExpressionValue +// module Bindings = Reducer_Bindings -type errorValue = Reducer_ErrorValue.errorValue -type expression = ExpressionT.expression -type internalExpressionValue = InternalExpressionValue.t +// type errorValue = Reducer_ErrorValue.errorValue +// type expression = ExpressionT.expression +// type internalExpressionValue = InternalExpressionValue.t -let isMacroName = (fName: string): bool => fName->Js.String2.startsWith("$$") +// let isMacroName = (fName: string): bool => fName->Js.String2.startsWith("$$") -let rec replaceSymbols = (bindings: ExpressionT.bindings, expression: expression): expression => - switch expression { - | ExpressionT.EValue(value) => replaceSymbolOnValue(bindings, value)->ExpressionT.EValue - | ExpressionT.EList(list) => - switch list { - | list{EValue(IEvCall(fName)), ..._args} => - switch isMacroName(fName) { - // A macro reduces itself so we dont dive in it - | true => expression - | false => replaceSymbolsOnExpressionList(bindings, list) - } - | _ => replaceSymbolsOnExpressionList(bindings, list) - } - } +// let rec replaceSymbols = (bindings: ExpressionT.bindings, expression: expression): expression => +// switch expression { +// | ExpressionT.EValue(value) => replaceSymbolOnValue(bindings, value)->ExpressionT.EValue +// | ExpressionT.EList(list) => +// switch list { +// | list{EValue(IEvCall(fName)), ..._args} => +// switch isMacroName(fName) { +// // A macro reduces itself so we dont dive in it +// | true => expression +// | false => replaceSymbolsOnExpressionList(bindings, list) +// } +// | _ => replaceSymbolsOnExpressionList(bindings, list) +// } +// } -and replaceSymbolsOnExpressionList = (bindings, list) => { - let racc = - list->Belt.List.reduceReverse(list{}, (acc, each: expression) => - replaceSymbols(bindings, each)->Belt.List.add(acc, _) - ) - ExpressionT.EList(racc) -} -and replaceSymbolOnValue = (bindings, evValue: internalExpressionValue) => - switch evValue { - | IEvSymbol(symbol) => Bindings.getWithDefault(bindings, symbol, evValue) - | IEvCall(symbol) => Bindings.getWithDefault(bindings, symbol, evValue)->checkIfCallable - | _ => evValue - } -and checkIfCallable = (evValue: internalExpressionValue) => - switch evValue { - | IEvCall(_) | IEvLambda(_) => evValue - | _ => - raise( - ErrorValue.ErrorException( - ErrorValue.RENotAFunction(InternalExpressionValue.toString(evValue)), - ), - ) - } +// and replaceSymbolsOnExpressionList = (bindings, list) => { +// let racc = +// list->Belt.List.reduceReverse(list{}, (acc, each: expression) => +// replaceSymbols(bindings, each)->Belt.List.add(acc, _) +// ) +// ExpressionT.EList(racc) +// } +// and replaceSymbolOnValue = (bindings, evValue: internalExpressionValue) => +// switch evValue { +// | IEvSymbol(symbol) => Reducer_Bindings.getWithDefault(bindings, symbol, evValue) +// | IEvCall(symbol) => Reducer_Bindings.getWithDefault(bindings, symbol, evValue)->checkIfCallable +// | _ => evValue +// } +// and checkIfCallable = (evValue: internalExpressionValue) => +// switch evValue { +// | IEvCall(_) | IEvLambda(_) => evValue +// | _ => +// raise( +// ErrorValue.ErrorException( +// ErrorValue.RENotAFunction(InternalExpressionValue.toString(evValue)), +// ), +// ) +// } 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 fa757ca8..f45125c7 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,43 +1,32 @@ module BBindingsReplacer = Reducer_Expression_BindingsReplacer module BErrorValue = Reducer_ErrorValue -module T = Reducer_Expression_T -module BInternalExpressionValue = ReducerInterface_InternalExpressionValue -module BBindings = Reducer_Bindings +module T = Reducer_T type errorValue = BErrorValue.errorValue -type expression = T.expression -type expressionOrFFI = T.expressionOrFFI -type ffiFn = T.ffiFn -type internalCode = ReducerInterface_InternalExpressionValue.internalCode +type expression = Reducer_T.expression -let eArray = anArray => anArray->BInternalExpressionValue.IEvArray->T.EValue +let eArray = (anArray: array) => anArray->T.EArray -let eArrayString = anArray => anArray->BInternalExpressionValue.IEvArrayString->T.EValue +let eArrayString = anArray => anArray->T.IEvArrayString->T.EValue -let eBindings = (anArray: array<(string, BInternalExpressionValue.t)>) => - anArray->BBindings.fromArray->BBindings.toExpressionValue->T.EValue +let eBindings = (anArray: array<(string, T.value)>) => + anArray->Reducer_Bindings.fromArray->Reducer_Bindings.toExpressionValue->T.EValue -let eBool = aBool => aBool->BInternalExpressionValue.IEvBool->T.EValue +let eBool = aBool => aBool->T.IEvBool->T.EValue -let eCall = (name: string): expression => - name->BInternalExpressionValue.IEvCall->T.EValue - -let eFunction = (fName: string, lispArgs: list): expression => { - let fn = fName->eCall - list{fn, ...lispArgs}->T.EList -} +let eCall = (fn: expression, args: array): expression => + T.ECall(fn, args) let eLambda = ( parameters: array, expr: expression, -) => { - T.ELambda(parameters, expr) +) => T.ELambda(parameters, expr) -let eNumber = aNumber => aNumber->BInternalExpressionValue.IEvNumber->T.EValue +let eNumber = aNumber => aNumber->T.IEvNumber->T.EValue -let eRecord = aMap => aMap->BInternalExpressionValue.IEvRecord->T.EValue +let eRecord = aMap => aMap->T.IEvRecord->T.EValue -let eString = aString => aString->BInternalExpressionValue.IEvString->T.EValue +let eString = aString => aString->T.IEvString->T.EValue let eSymbol = (name: string): expression => T.ESymbol(name) @@ -45,8 +34,11 @@ let eSymbol = (name: string): expression => let eBlock = (exprs: array): expression => T.EBlock(exprs) -let eModule = (nameSpace: BInternalExpressionValue.nameSpace): expression => - nameSpace->BInternalExpressionValue.IEvBindings->T.EValue +let eProgram = (exprs: array): expression => + T.EProgram(exprs) + +let eModule = (nameSpace: T.nameSpace): expression => + nameSpace->T.IEvBindings->T.EValue let eLetStatement = (symbol: string, valueExpression: expression): expression => T.EAssign(symbol, valueExpression) @@ -55,9 +47,9 @@ let eTernary = (predicate: expression, trueCase: expression, falseCase: expressi T.ETernary(predicate, trueCase, falseCase) let eIdentifier = (name: string): expression => - name->BInternalExpressionValue.IEvSymbol->T.EValue + name->T.ESymbol -let eTypeIdentifier = (name: string): expression => - name->BInternalExpressionValue.IEvTypeIdentifier->T.EValue +// let eTypeIdentifier = (name: string): expression => +// name->T.IEvTypeIdentifier->T.EValue -let eVoid: expression = BInternalExpressionValue.IEvVoid->T.EValue +let eVoid: expression = T.IEvVoid->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 c4ef011e..8316998c 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 @@ -1,99 +1,53 @@ module Bindings = Reducer_Bindings -module BindingsReplacer = Reducer_Expression_BindingsReplacer module ErrorValue = Reducer_ErrorValue -module ExpressionBuilder = Reducer_Expression_ExpressionBuilder -module ExpressionT = Reducer_Expression_T -module ExpressionValue = ReducerInterface_InternalExpressionValue -module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -module ProjectReducerFnT = ReducerProject_ReducerFn_T -module Result = Belt.Result -type expression = ExpressionT.expression -type expressionOrFFI = ExpressionT.expressionOrFFI type internalExpressionValue = ReducerInterface_InternalExpressionValue.t -type internalCode = ReducerInterface_InternalExpressionValue.internalCode - -external castInternalCodeToExpression: internalCode => expressionOrFFI = "%identity" - -let checkArity = ( - lambdaValue: ExpressionValue.lambdaValue, - args: list, -) => { - let reallyCheck = { - let argsLength = Belt.List.length(args) - let parametersLength = Js.Array2.length(lambdaValue.parameters) - if argsLength !== parametersLength { - raise(ErrorValue.ErrorException(ErrorValue.REArityError(None, parametersLength, argsLength))) - } else { - args - } - } - let exprOrFFI = castInternalCodeToExpression(lambdaValue.body) - switch exprOrFFI { - | NotFFI(_) => reallyCheck - | FFI(_) => args - } -} - -let checkIfReduced = (args: list) => - args->Belt.List.reduceReverse(list{}, (acc, arg) => - switch arg { - | IEvSymbol(symbol) => raise(ErrorValue.ErrorException(ErrorValue.RESymbolNotFound(symbol))) - | _ => list{arg, ...acc} - } - ) - -let caseNotFFI = ( - lambdaValue: ExpressionValue.lambdaValue, - expr, - args, - accessors: ProjectAccessorsT.t, - reducer: ProjectReducerFnT.t, -) => { - let parameterList = lambdaValue.parameters->Belt.List.fromArray - let zippedParameterList = parameterList->Belt.List.zip(args) - let bindings = Belt.List.reduce(zippedParameterList, lambdaValue.context, ( - acc, - (variable, variableValue), - ) => acc->Bindings.set(variable, variableValue)) - let newExpression = ExpressionBuilder.eBlock(list{expr}) - reducer(newExpression, bindings, accessors) -} - -let caseFFI = (ffiFn: ExpressionT.ffiFn, args, accessors: ProjectAccessorsT.t) => { - switch ffiFn(args->Belt.List.toArray, accessors.environment) { - | Ok(value) => value - | Error(value) => raise(ErrorValue.ErrorException(value)) - } -} - -let applyParametersToLambda = ( - lambdaValue: ExpressionValue.lambdaValue, - args, - accessors: ProjectAccessorsT.t, - reducer: ProjectReducerFnT.t, -): internalExpressionValue => { - let args = checkArity(lambdaValue, args)->checkIfReduced - let exprOrFFI = castInternalCodeToExpression(lambdaValue.body) - switch exprOrFFI { - | NotFFI(expr) => caseNotFFI(lambdaValue, expr, args, accessors, reducer) - | FFI(ffiFn) => caseFFI(ffiFn, args, accessors) - } -} let doLambdaCall = ( - lambdaValue: ExpressionValue.lambdaValue, + lambdaValue: Reducer_T.lambdaValue, args, - accessors: ProjectAccessorsT.t, - reducer: ProjectReducerFnT.t, -) => applyParametersToLambda(lambdaValue, args, accessors, reducer) - -let foreignFunctionInterface = ( - lambdaValue: ExpressionValue.lambdaValue, - argArray: array, - accessors: ProjectAccessorsT.t, - reducer: ProjectReducerFnT.t, -): internalExpressionValue => { - let args = argArray->Belt.List.fromArray - applyParametersToLambda(lambdaValue, args, accessors, reducer) + environment: Reducer_T.environment, + reducer: Reducer_T.reducerFn +): Reducer_T.value => { + lambdaValue.body(args, environment, reducer) } + +let makeLambda = ( + parameters: array, + bindings: Reducer_T.nameSpace, + body: Reducer_T.expression, +): Reducer_T.lambdaValue => { + // TODO - clone bindings to avoid later redefinitions affecting lambdas? + + // Note: with this implementation, FFI lambdas (created by other methods than calling `makeLambda`) are allowed to violate the rules, pollute the bindings, etc. + // Not sure yet if that's a bug or a feature. + + let lambda = ( + arguments: array, + environment: Reducer_T.environment, + reducer: Reducer_T.reducerFn + ) => { + let argsLength = arguments->Js.Array2.length + let parametersLength = parameters->Js.Array2.length + if argsLength !== parametersLength { + ErrorValue.REArityError(None, parametersLength, argsLength)->ErrorValue.ErrorException->raise + } + + let localBindings = bindings->Reducer_Bindings.extend + parameters->Js.Array2.forEachi( + (parameter, index) => { + let _ = localBindings->Reducer_Bindings.set(parameter, arguments[index]) + } + ) + + reducer(body, { bindings: localBindings, environment }) + } + + LNoFFI({ + context: bindings, + body: lambda, + parameters, + }) +} + +let makeFFILambda = () => raise(Not_found) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res index 7426be18..442c4e98 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res @@ -1,26 +1,26 @@ -module ExpressionT = Reducer_Expression_T -module InternalExpressionValue = ReducerInterface_InternalExpressionValue -module ExpressionWithContext = Reducer_ExpressionWithContext -module Result = Belt.Result -module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -module ProjectReducerFnT = ReducerProject_ReducerFn_T +// module ExpressionT = Reducer_Expression_T +// module InternalExpressionValue = ReducerInterface_InternalExpressionValue +// module ExpressionWithContext = Reducer_ExpressionWithContext +// module Result = Belt.Result +// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T +// module ProjectReducerFnT = ReducerProject_ReducerFn_T -type environment = InternalExpressionValue.environment -type expression = ExpressionT.expression -type internalExpressionValue = InternalExpressionValue.t -type expressionWithContext = ExpressionWithContext.expressionWithContext +// type environment = InternalExpressionValue.environment +// type expression = ExpressionT.expression +// type internalExpressionValue = InternalExpressionValue.t +// type expressionWithContext = ExpressionWithContext.expressionWithContext -let doMacroCall = ( - macroExpression: expression, - bindings: ExpressionT.bindings, - accessors: ProjectAccessorsT.t, - reduceExpression: ProjectReducerFnT.t, -): internalExpressionValue => - Reducer_Dispatch_BuiltInMacros.dispatchMacroCall( - macroExpression, - bindings, - (accessors: ProjectAccessorsT.t), - (reduceExpression: ProjectReducerFnT.t), - )->ExpressionWithContext.callReducer(bindings, accessors, reduceExpression) +// let doMacroCall = ( +// macroExpression: expression, +// bindings: ExpressionT.bindings, +// accessors: ProjectAccessorsT.t, +// reduceExpression: ProjectReducerFnT.t, +// ): internalExpressionValue => +// Reducer_Dispatch_BuiltInMacros.dispatchMacroCall( +// macroExpression, +// bindings, +// (accessors: ProjectAccessorsT.t), +// (reduceExpression: ProjectReducerFnT.t), +// )->ExpressionWithContext.callReducer(bindings, accessors, reduceExpression) -let isMacroName = (fName: string): bool => fName->Js.String2.startsWith("$$") +// let isMacroName = (fName: string): bool => fName->Js.String2.startsWith("$$") 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 bc98082d..e1f3f501 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 @@ -9,44 +9,38 @@ module Extra = Reducer_Extra module InternalExpressionValue = ReducerInterface_InternalExpressionValue -type internalExpressionValue = InternalExpressionValue.t -type environment = ReducerInterface_InternalExpressionValue.environment +type internalExpressionValue = Reducer_T.value +type environment = Reducer_T.environment -type rec expression = - | EBlock(array) - | ESymbol(string) - | ETernary(expression, expression, expression) - | EAssign(string, expression) - | ECall(expression, array) - | ELambda(array, expression) - | EValue(internalExpressionValue) -and bindings = InternalExpressionValue.nameSpace +type expression = Reducer_T.expression type t = expression -type reducerFn = ( - expression, - bindings, - environment, -) => result +type context = Reducer_T.context + +type reducerFn = Reducer_T.reducerFn + +let commaJoin = values => values->Reducer_Extra_Array.intersperse(", ")->Js.String.concatMany("") /* Converts the expression to String */ -let rec toString = expression => "TODO" - // switch expression { - // | EList(list{EValue(IEvCall("$$_block_$$")), ...statements}) => - // `{${Belt.List.map(statements, aValue => toString(aValue)) - // ->Extra.List.intersperse("; ") - // ->Belt.List.toArray - // ->Js.String.concatMany("")}}` - // | EList(aList) => - // `(${Belt.List.map(aList, aValue => toString(aValue)) - // ->Extra.List.intersperse(" ") - // ->Belt.List.toArray - // ->Js.String.concatMany("")})` - // | EValue(aValue) => InternalExpressionValue.toString(aValue) - // } +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}]` + | ERecord(map) => "TODO" + | ESymbol(name) => name + | 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}}` + | EValue(aValue) => InternalExpressionValue.toString(aValue) + } let toStringResult = codeResult => switch codeResult { diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy index deaddd57..a8c61d59 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy @@ -9,25 +9,27 @@ start zeroOMoreArgumentsBlockOrExpression = innerBlockOrExpression / lambda -// { return h.makeFunctionCall('$_typeOf_$', [identifier, typeExpression])} -// {return [h.nodeVoid()];} outerBlock = statements:array_statements finalExpression: (statementSeparator @expression)? - { if (finalExpression != null) - { - var newFinalExpression = h.makeFunctionCall('$_endOfOuterBlock_$', [h.nodeVoid(), finalExpression]); - statements.push(newFinalExpression); - } - else - { - var newFinalStatement = h.makeFunctionCall('$_endOfOuterBlock_$', [h.nodeVoid(), h.nodeVoid()]); - statements.push(newFinalStatement); - } - return h.nodeBlock(statements) } - / finalExpression: expression - { - var newFinalExpression = h.makeFunctionCall('$_endOfOuterBlock_$', [h.nodeVoid(), finalExpression]); - return h.nodeBlock([newFinalExpression])} + { if (finalExpression) statements.push(finalExpression) + return h.nodeProgram(statements) } + // / '{' _nl finalExpression: expression _nl '}' + // { return h.nodeBlock([finalExpression]) } + // { if (finalExpression != null) + // { + // var newFinalExpression = h.makeFunctionCall('$_endOfOuterBlock_$', [h.nodeVoid(), finalExpression]); + // statements.push(newFinalExpression); + // } + // else + // { + // var newFinalStatement = h.makeFunctionCall('$_endOfOuterBlock_$', [h.nodeVoid(), h.nodeVoid()]); + // statements.push(newFinalStatement); + // } + // return h.nodeBlock(statements) } + // / finalExpression: expression + // { + // var newFinalExpression = h.makeFunctionCall('$_endOfOuterBlock_$', [h.nodeVoid(), finalExpression]); + // return h.nodeBlock([newFinalExpression])} innerBlockOrExpression = quotedInnerBlock @@ -36,7 +38,7 @@ innerBlockOrExpression quotedInnerBlock = '{' _nl statements:array_statements finalExpression: (statementSeparator @expression) _nl '}' - { statements.push(finalExpression) + { if (finalExpression) statements.push(finalExpression) return h.nodeBlock(statements) } / '{' _nl finalExpression: expression _nl '}' { return h.nodeBlock([finalExpression]) } @@ -50,7 +52,7 @@ array_statements statement = letStatement / defunStatement - / typeStatement + // / typeStatement / voidStatement voidStatement @@ -337,80 +339,80 @@ statementSeparator 'statement separator' newLine "newline" = [\n\r] -// Types +// // Types -noArguments = ('(' _nl ')' )? +// noArguments = ('(' _nl ')' )? -typeIdentifier 'type identifier' - = ([a-z]+[_a-z0-9]i*) {return h.nodeTypeIdentifier(text())} +// typeIdentifier 'type identifier' +// = ([a-z]+[_a-z0-9]i*) {return h.nodeTypeIdentifier(text())} -typeConstructorIdentifier 'type constructor identifier' - = ([A-Z]+[_a-z0-9]i*) {return h.nodeTypeIdentifier(text())} +// typeConstructorIdentifier 'type constructor identifier' +// = ([A-Z]+[_a-z0-9]i*) {return h.nodeTypeIdentifier(text())} -typeExpression = typePostModifierExpression +// typeExpression = typePostModifierExpression -typePostModifierExpression = head:typeOr tail:(_ '$' _nl @typeModifier)* - { - return tail.reduce((result, element) => { - return h.makeFunctionCall('$_typeModifier_'+element.modifier.value+'_$', [result, ...element.args]) - }, head) - } +// typePostModifierExpression = head:typeOr tail:(_ '$' _nl @typeModifier)* +// { +// return tail.reduce((result, element) => { +// return h.makeFunctionCall('$_typeModifier_'+element.modifier.value+'_$', [result, ...element.args]) +// }, head) +// } -typeOr = head:typeFunction tail:(_ '|' _nl @typeFunction)* - { return tail.length === 0 ? head : h.makeFunctionCall('$_typeOr_$', [h.constructArray([head, ...tail])]); } +// typeOr = head:typeFunction tail:(_ '|' _nl @typeFunction)* +// { return tail.length === 0 ? head : h.makeFunctionCall('$_typeOr_$', [h.constructArray([head, ...tail])]); } -typeFunction = head:typeModifierExpression tail:(_ '=>' _nl @typeModifierExpression)* - { return tail.length === 0 ? head : h.makeFunctionCall( '$_typeFunction_$', [h.constructArray([head, ...tail])]); } +// typeFunction = head:typeModifierExpression tail:(_ '=>' _nl @typeModifierExpression)* +// { return tail.length === 0 ? head : h.makeFunctionCall( '$_typeFunction_$', [h.constructArray([head, ...tail])]); } -typeModifierExpression = head:basicType tail:(_ '<-' _nl @typeModifier)* - { - return tail.reduce((result, element) => { - return h.makeFunctionCall('$_typeModifier_'+element.modifier.value+'_$', [result, ...element.args]) - }, head) - } +// typeModifierExpression = head:basicType tail:(_ '<-' _nl @typeModifier)* +// { +// return tail.reduce((result, element) => { +// return h.makeFunctionCall('$_typeModifier_'+element.modifier.value+'_$', [result, ...element.args]) +// }, head) +// } - typeModifier - = modifier:identifier _ '(' _nl args:array_elements _nl ')' - { return {modifier: modifier, args: args}; } - / modifier:identifier _ noArguments - { return {modifier: modifier, args: []}; } +// typeModifier +// = modifier:identifier _ '(' _nl args:array_elements _nl ')' +// { return {modifier: modifier, args: args}; } +// / modifier:identifier _ noArguments +// { return {modifier: modifier, args: []}; } -basicType = typeConstructor / typeArray / typeTuple / typeRecord / typeInParanthesis / typeIdentifier +// basicType = typeConstructor / typeArray / typeTuple / typeRecord / typeInParanthesis / typeIdentifier -typeArray = '[' _nl elem:typeExpression _nl ']' - {return h.makeFunctionCall('$_typeArray_$', [elem])} +// typeArray = '[' _nl elem:typeExpression _nl ']' +// {return h.makeFunctionCall('$_typeArray_$', [elem])} -typeTuple = '[' _nl elems:array_typeTupleArguments _nl ']' - { return h.makeFunctionCall('$_typeTuple_$', [h.constructArray(elems)])} +// typeTuple = '[' _nl elems:array_typeTupleArguments _nl ']' +// { return h.makeFunctionCall('$_typeTuple_$', [h.constructArray(elems)])} - array_typeTupleArguments - = head:typeExpression tail:(_ ',' _nl @typeExpression)* - { return [head, ...tail]; } +// array_typeTupleArguments +// = head:typeExpression tail:(_ ',' _nl @typeExpression)* +// { return [head, ...tail]; } -typeRecord = '{' _nl elems:array_typeRecordArguments _nl '}' - { return h.makeFunctionCall('$_typeRecord_$', [h.constructRecord(elems)]); } +// typeRecord = '{' _nl elems:array_typeRecordArguments _nl '}' +// { return h.makeFunctionCall('$_typeRecord_$', [h.constructRecord(elems)]); } - array_typeRecordArguments - = head:typeKeyValuePair tail:(_ ',' _nl @typeKeyValuePair)* - { return [head, ...tail]; } +// array_typeRecordArguments +// = head:typeKeyValuePair tail:(_ ',' _nl @typeKeyValuePair)* +// { return [head, ...tail]; } - typeKeyValuePair - = key:identifier _ ':' _nl value:typeExpression - { return h.nodeKeyValue(key, value)} +// typeKeyValuePair +// = key:identifier _ ':' _nl value:typeExpression +// { return h.nodeKeyValue(key, value)} -typeConstructor - = constructor:typeConstructorIdentifier _ '(' _nl args:array_types _nl ')' - { return h.makeFunctionCall('$_typeConstructor_$', [constructor, h.constructArray(args)]); } - / constructor:typeConstructorIdentifier _ noArguments - { return h.makeFunctionCall('$_typeConstructor_$', [constructor, h.constructArray([])]); } +// typeConstructor +// = constructor:typeConstructorIdentifier _ '(' _nl args:array_types _nl ')' +// { return h.makeFunctionCall('$_typeConstructor_$', [constructor, h.constructArray(args)]); } +// / constructor:typeConstructorIdentifier _ noArguments +// { return h.makeFunctionCall('$_typeConstructor_$', [constructor, h.constructArray([])]); } - array_types = head:typeExpression tail:(_ ',' _nl @typeExpression)* - { return [head, ...tail]; } +// array_types = head:typeExpression tail:(_ ',' _nl @typeExpression)* +// { return [head, ...tail]; } -typeStatement = typeAliasStatement / typeOfStatement -typeAliasStatement = 'type' __nl typeIdentifier:typeIdentifier _nl '=' _nl typeExpression:typeExpression - { return h.makeFunctionCall('$_typeAlias_$', [typeIdentifier, typeExpression])} -typeOfStatement = identifier:identifier _ ':' _nl typeExpression:typeExpression - { return h.makeFunctionCall('$_typeOf_$', [identifier, typeExpression])} +// typeStatement = typeAliasStatement / typeOfStatement +// typeAliasStatement = 'type' __nl typeIdentifier:typeIdentifier _nl '=' _nl typeExpression:typeExpression +// { return h.makeFunctionCall('$_typeAlias_$', [typeIdentifier, typeExpression])} +// typeOfStatement = identifier:identifier _ ':' _nl typeExpression:typeExpression +// { return h.makeFunctionCall('$_typeOf_$', [identifier, typeExpression])} -typeInParanthesis = '(' _nl typeExpression:typeExpression _nl ')' {return typeExpression} +// typeInParanthesis = '(' _nl typeExpression:typeExpression _nl ')' {return typeExpression} 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 61c4e0af..b5099c36 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 @@ -20,6 +20,7 @@ let parse = (expr: string): result => } type nodeBlock = {...node, "statements": array} +type nodeProgram = {...node, "statements": array} type nodeBoolean = {...node, "value": bool} type nodeCall = {...node, "fn": node, "args": array} type nodeFloat = {...node, "value": float} @@ -31,11 +32,12 @@ type nodeLetStatement = {...node, "variable": nodeIdentifier, "value": node} type nodeModuleIdentifier = {...node, "value": string} type nodeString = {...node, "value": string} type nodeTernary = {...node, "condition": node, "trueExpression": node, "falseExpression": node} -type nodeTypeIdentifier = {...node, "value": string} +// type nodeTypeIdentifier = {...node, "value": string} type nodeVoid = node type peggyNode = | PgNodeBlock(nodeBlock) + | PgNodeProgram(nodeBlock) | PgNodeBoolean(nodeBoolean) | PgNodeFloat(nodeFloat) | PgNodeCall(nodeCall) @@ -47,10 +49,11 @@ type peggyNode = | PgNodeModuleIdentifier(nodeModuleIdentifier) | PgNodeString(nodeString) | PgNodeTernary(nodeTernary) - | PgNodeTypeIdentifier(nodeTypeIdentifier) + // | PgNodeTypeIdentifier(nodeTypeIdentifier) | PgNodeVoid(nodeVoid) external castNodeBlock: node => nodeBlock = "%identity" +external castNodeProgram: node => nodeProgram = "%identity" external castNodeBoolean: node => nodeBoolean = "%identity" external castNodeCall: node => nodeCall = "%identity" external castNodeFloat: node => nodeFloat = "%identity" @@ -62,13 +65,14 @@ external castNodeLetStatement: node => nodeLetStatement = "%identity" external castNodeModuleIdentifier: node => nodeModuleIdentifier = "%identity" external castNodeString: node => nodeString = "%identity" external castNodeTernary: node => nodeTernary = "%identity" -external castNodeTypeIdentifier: node => nodeTypeIdentifier = "%identity" +// external castNodeTypeIdentifier: node => nodeTypeIdentifier = "%identity" external castNodeVoid: node => nodeVoid = "%identity" exception UnsupportedPeggyNodeType(string) // This should never happen; programming error let castNodeType = (node: node) => switch node["type"] { | "Block" => node->castNodeBlock->PgNodeBlock + | "Program" => node->castNodeBlock->PgNodeProgram | "Boolean" => node->castNodeBoolean->PgNodeBoolean | "Call" => node->castNodeCall->PgNodeCall | "Float" => node->castNodeFloat->PgNodeFloat @@ -80,7 +84,7 @@ let castNodeType = (node: node) => | "ModuleIdentifier" => node->castNodeModuleIdentifier->PgNodeModuleIdentifier | "String" => node->castNodeString->PgNodeString | "Ternary" => node->castNodeTernary->PgNodeTernary - | "TypeIdentifier" => node->castNodeTypeIdentifier->PgNodeTypeIdentifier + // | "TypeIdentifier" => node->castNodeTypeIdentifier->PgNodeTypeIdentifier | "Void" => node->castNodeVoid->PgNodeVoid | _ => raise(UnsupportedPeggyNodeType(node["type"])) } @@ -93,7 +97,9 @@ let rec pgToString = (peggyNode: peggyNode): string => { nodes->Js.Array2.map(toString)->Extra.Array.intersperse(separator)->Js.String.concatMany("") switch peggyNode { - | PgNodeBlock(node) => "{" ++ node["statements"]->nodesToStringUsingSeparator("; ") ++ "}" + | PgNodeBlock(node) + | PgNodeProgram(node) + => "{" ++ node["statements"]->nodesToStringUsingSeparator("; ") ++ "}" | PgNodeBoolean(node) => node["value"]->Js.String.make | PgNodeCall(node) => "(" ++ node["fn"]->toString ++ " " ++ node["args"]->nodesToStringUsingSeparator(" ") ++ ")" | PgNodeFloat(node) => node["value"]->Js.String.make @@ -113,7 +119,7 @@ let rec pgToString = (peggyNode: peggyNode): string => { toString(node["trueExpression"]) ++ " " ++ toString(node["falseExpression"]) ++ ")" - | PgNodeTypeIdentifier(node) => `#${node["value"]}` + // | PgNodeTypeIdentifier(node) => `#${node["value"]}` | PgNodeVoid(_node) => "()" } } 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 a14dca34..3b997440 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 @@ -2,12 +2,15 @@ module ExpressionBuilder = Reducer_Expression_ExpressionBuilder module ExpressionT = Reducer_Expression_T module Parse = Reducer_Peggy_Parse -type expression = ExpressionT.expression +type expression = Reducer_T.expression let rec fromNode = (node: Parse.node): expression => { let caseBlock = nodeBlock => ExpressionBuilder.eBlock(nodeBlock["statements"]->Js.Array2.map(fromNode)) + let caseProgram = nodeProgram => + ExpressionBuilder.eProgram(nodeProgram["statements"]->Js.Array2.map(fromNode)) + let caseLambda = (nodeLambda: Parse.nodeLambda): expression => { let args = nodeLambda["args"] @@ -19,14 +22,14 @@ let rec fromNode = (node: Parse.node): expression => { switch Parse.castNodeType(node) { | PgNodeBlock(nodeBlock) => caseBlock(nodeBlock) + | PgNodeProgram(nodeProgram) => caseProgram(nodeProgram) | PgNodeBoolean(nodeBoolean) => ExpressionBuilder.eBool(nodeBoolean["value"]) - | PgNodeExpression(nodeExpression) => - ExpressionT.EList(nodeExpression["nodes"]->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"])) | PgNodeKeyValue(nodeKeyValue) => - ExpressionT.EList(list{fromNode(nodeKeyValue["key"]), fromNode(nodeKeyValue["value"])}) + ExpressionBuilder.eArray([fromNode(nodeKeyValue["key"]), fromNode(nodeKeyValue["value"])]) | PgNodeLambda(nodeLambda) => caseLambda(nodeLambda) | PgNodeLetStatement(nodeLetStatement) => ExpressionBuilder.eLetStatement( @@ -42,8 +45,8 @@ let rec fromNode = (node: Parse.node): expression => { fromNode(nodeTernary["trueExpression"]), fromNode(nodeTernary["falseExpression"]) ) - | PgNodeTypeIdentifier(nodeTypeIdentifier) => - ExpressionBuilder.eTypeIdentifier(nodeTypeIdentifier["value"]) + // | PgNodeTypeIdentifier(nodeTypeIdentifier) => + // ExpressionBuilder.eTypeIdentifier(nodeTypeIdentifier["value"]) | PgNodeVoid(_) => ExpressionBuilder.eVoid } } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts index 330f23e9..ebf6dd2e 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts @@ -40,6 +40,11 @@ type NodeBlock = { statements: AnyPeggyNode[]; }; +type NodeProgram = { + type: "Program"; + statements: AnyPeggyNode[]; +}; + type NodeCall = { type: "Call"; fn: AnyPeggyNode; @@ -99,6 +104,7 @@ type NodeBoolean = { export type AnyPeggyNode = | NodeBlock + | NodeProgram | NodeCall | NodeFloat | NodeInteger @@ -111,7 +117,11 @@ export type AnyPeggyNode = | NodeBoolean; export function makeFunctionCall(fn: string, args: AnyPeggyNode[]) { - return nodeCall(nodeIdentifier(fn), args); + if (fn === "$$_applyAll_$$") { + return nodeCall(args[0], args.splice(1)); + } else { + return nodeCall(nodeIdentifier(fn), args); + } } export function constructArray(elems: AnyPeggyNode[]) { @@ -124,6 +134,9 @@ export function constructRecord(elems: AnyPeggyNode[]) { export function nodeBlock(statements: AnyPeggyNode[]): NodeBlock { return { type: "Block", statements }; } +export function nodeProgram(statements: AnyPeggyNode[]): NodeProgram { + return { type: "Program", statements }; +} export function nodeBoolean(value: boolean): NodeBoolean { return { type: "Boolean", value }; } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res new file mode 100644 index 00000000..19eedf39 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res @@ -0,0 +1,53 @@ +type environment = GenericDist.env + +@genType.opaque +type rec value = + | IEvArray(arrayValue) + | IEvArrayString(array) + | IEvBool(bool) + // | IEvCall(string) // External function call + | IEvDate(Js.Date.t) + | IEvDeclaration(lambdaDeclaration) + | IEvDistribution(DistributionTypes.genericDist) + | IEvLambda(lambdaValue) + | IEvBindings(nameSpace) + | IEvNumber(float) + | IEvRecord(map) + | IEvString(string) + // | IEvSymbol(string) + | IEvTimeDuration(float) + | IEvType(map) + | IEvTypeIdentifier(string) + | IEvVoid +@genType.opaque and arrayValue = array +@genType.opaque and map = Belt.Map.String.t +@genType.opaque and nameSpace = NameSpace(Belt.MutableMap.String.t, option) +@genType.opaque +and lambdaValue = + | LNoFFI({ + parameters: array, + context: nameSpace, + body: (array, environment, reducerFn) => value, + }) + | LFFI({ + body: (array, environment, reducerFn) => value, + }) +@genType.opaque and lambdaDeclaration = Declaration.declaration +and expression = + | EBlock(array) + | EProgram(array) // programs are similar to blocks, but don't create an inner scope. there can be only one program at the top level of the expression. + | EArray(array) + | ERecord(Belt.Map.String.t) + | ESymbol(string) + | ETernary(expression, expression, expression) + | EAssign(string, expression) + | ECall(expression, array) + | ELambda(array, expression) + | EValue(value) + +and context = { + bindings: nameSpace, + environment: environment, +} + +and reducerFn = (expression, context) => value diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Compile.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Compile.res index 73696831..bc191ffe 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 @@ -1,42 +1,41 @@ -module Bindings = Reducer_Bindings -module ErrorValue = Reducer_ErrorValue -module Expression = Reducer_Expression -module ExpressionT = Reducer_Expression_T -module InternalExpressionValue = ReducerInterface_InternalExpressionValue -module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -module ProjectReducerFnT = ReducerProject_ReducerFn_T -module T = Reducer_Type_T +// module Bindings = Reducer_Bindings +// module ErrorValue = Reducer_ErrorValue +// module Expression = Reducer_Expression +// module ExpressionT = Reducer_Expression_T +// module InternalExpressionValue = ReducerInterface_InternalExpressionValue +// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T +// module T = Reducer_Type_T -let ievFromTypeExpression = ( - typeExpressionSourceCode: string, - reducerFn: ProjectReducerFnT.t, -): result => { - let sIndex = "compiled" - let sourceCode = `type ${sIndex}=${typeExpressionSourceCode}` - Reducer_Expression.BackCompatible.parse(sourceCode)->Belt.Result.flatMap(expr => { - let accessors = ProjectAccessorsT.identityAccessors - let result = reducerFn(expr, Bindings.emptyBindings, accessors) - let nameSpace = accessors.states.continuation +// let ievFromTypeExpression = ( +// typeExpressionSourceCode: string, +// reducerFn: Reducer_T.reducerFn, +// ): result => { +// let sIndex = "compiled" +// let sourceCode = `type ${sIndex}=${typeExpressionSourceCode}` +// Reducer_Expression.BackCompatible.parse(sourceCode)->Belt.Result.flatMap(expr => { +// let accessors = ProjectAccessorsT.identityAccessors +// let result = reducerFn(expr, Bindings.emptyBindings, accessors) +// let nameSpace = accessors.states.continuation - switch Bindings.getType(nameSpace, sIndex) { - | Some(value) => value->Ok - | None => raise(Reducer_Exception.ImpossibleException("Reducer_Type_Compile-none")) - } - }) -} +// switch Bindings.getType(nameSpace, sIndex) { +// | Some(value) => value->Ok +// | None => raise(Reducer_Exception.ImpossibleException("Reducer_Type_Compile-none")) +// } +// }) +// } -let fromTypeExpression = (typeExpressionSourceCode: string, reducerFn: ProjectReducerFnT.t): result< - T.t, - ErrorValue.t, -> => { - ievFromTypeExpression(typeExpressionSourceCode, reducerFn)->Belt.Result.map(T.fromIEvValue) -} +// let fromTypeExpression = (typeExpressionSourceCode: string, reducerFn: Reducer_T.reducerFn): result< +// T.t, +// ErrorValue.t, +// > => { +// ievFromTypeExpression(typeExpressionSourceCode, reducerFn)->Belt.Result.map(T.fromIEvValue) +// } -let fromTypeExpressionExn = ( - typeExpressionSourceCode: string, - reducerFn: ProjectReducerFnT.t, -): T.t => - switch fromTypeExpression(typeExpressionSourceCode, reducerFn) { - | Ok(value) => value - | _ => `Cannot compile ${typeExpressionSourceCode}`->Reducer_Exception.ImpossibleException->raise - } +// let fromTypeExpressionExn = ( +// typeExpressionSourceCode: string, +// reducerFn: Reducer_T.reducerFn, +// ): T.t => +// switch fromTypeExpression(typeExpressionSourceCode, reducerFn) { +// | 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 511fe815..40b74e56 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 @@ -1,119 +1,119 @@ -module InternalExpressionValue = ReducerInterface_InternalExpressionValue -open InternalExpressionValue +// module InternalExpressionValue = ReducerInterface_InternalExpressionValue +// open InternalExpressionValue -type rec iType = - | ItTypeIdentifier(string) - | ItModifiedType({modifiedType: iType, contracts: Belt.Map.String.t}) - | ItTypeOr({typeOr: array}) - | ItTypeFunction({inputs: array, output: iType}) - | ItTypeArray({element: iType}) - | ItTypeTuple({elements: array}) - | ItTypeRecord({properties: Belt.Map.String.t}) +// type rec iType = +// | ItTypeIdentifier(string) +// | ItModifiedType({modifiedType: iType, contracts: Belt.Map.String.t}) +// | ItTypeOr({typeOr: array}) +// | ItTypeFunction({inputs: array, output: iType}) +// | ItTypeArray({element: iType}) +// | ItTypeTuple({elements: array}) +// | ItTypeRecord({properties: Belt.Map.String.t}) -type t = iType -type typeErrorValue = TypeMismatch(t, InternalExpressionValue.t) +// type t = iType +// type typeErrorValue = TypeMismatch(t, InternalExpressionValue.t) -let rec toString = (t: t): string => { - switch t { - | ItTypeIdentifier(s) => s - | ItModifiedType({modifiedType, contracts}) => - `${toString(modifiedType)}${contracts->Belt.Map.String.reduce("", (acc, k, v) => - Js.String2.concatMany(acc, ["<-", k, "(", InternalExpressionValue.toString(v), ")"]) - )}` - | ItTypeOr({typeOr}) => `(${Js.Array2.map(typeOr, toString)->Js.Array2.joinWith(" | ")})` - | ItTypeFunction({inputs, output}) => - `(${inputs->Js.Array2.map(toString)->Js.Array2.joinWith(" => ")} => ${toString(output)})` - | ItTypeArray({element}) => `[${toString(element)}]` - | ItTypeTuple({elements}) => `[${Js.Array2.map(elements, toString)->Js.Array2.joinWith(", ")}]` - | ItTypeRecord({properties}) => - `{${properties - ->Belt.Map.String.toArray - ->Js.Array2.map(((k, v)) => Js.String2.concatMany(k, [": ", toString(v)])) - ->Js.Array2.joinWith(", ")}}` - } -} +// let rec toString = (t: t): string => { +// switch t { +// | ItTypeIdentifier(s) => s +// | ItModifiedType({modifiedType, contracts}) => +// `${toString(modifiedType)}${contracts->Belt.Map.String.reduce("", (acc, k, v) => +// Js.String2.concatMany(acc, ["<-", k, "(", InternalExpressionValue.toString(v), ")"]) +// )}` +// | ItTypeOr({typeOr}) => `(${Js.Array2.map(typeOr, toString)->Js.Array2.joinWith(" | ")})` +// | ItTypeFunction({inputs, output}) => +// `(${inputs->Js.Array2.map(toString)->Js.Array2.joinWith(" => ")} => ${toString(output)})` +// | ItTypeArray({element}) => `[${toString(element)}]` +// | ItTypeTuple({elements}) => `[${Js.Array2.map(elements, toString)->Js.Array2.joinWith(", ")}]` +// | ItTypeRecord({properties}) => +// `{${properties +// ->Belt.Map.String.toArray +// ->Js.Array2.map(((k, v)) => Js.String2.concatMany(k, [": ", toString(v)])) +// ->Js.Array2.joinWith(", ")}}` +// } +// } -let toStringResult = (rt: result) => - switch rt { - | Ok(t) => toString(t) - | Error(e) => ErrorValue.errorToString(e) - } +// let toStringResult = (rt: result) => +// switch rt { +// | Ok(t) => toString(t) +// | Error(e) => ErrorValue.errorToString(e) +// } -let rec fromTypeMap = typeMap => { - let default = IEvString("") - let evTypeTag: InternalExpressionValue.t = Belt.Map.String.getWithDefault( - typeMap, - "typeTag", - default, - ) - let evTypeIdentifier: InternalExpressionValue.t = Belt.Map.String.getWithDefault( - typeMap, - "typeIdentifier", - default, - ) - let evTypeOr: InternalExpressionValue.t = Belt.Map.String.getWithDefault( - typeMap, - "typeOr", - default, - ) - let evInputs: InternalExpressionValue.t = Belt.Map.String.getWithDefault( - typeMap, - "inputs", - default, - ) - let evOutput: InternalExpressionValue.t = Belt.Map.String.getWithDefault( - typeMap, - "output", - default, - ) - let evElement: InternalExpressionValue.t = Belt.Map.String.getWithDefault( - typeMap, - "element", - default, - ) - let evElements: InternalExpressionValue.t = Belt.Map.String.getWithDefault( - typeMap, - "elements", - default, - ) - let evProperties: InternalExpressionValue.t = Belt.Map.String.getWithDefault( - typeMap, - "properties", - default, - ) +// let rec fromTypeMap = typeMap => { +// let default = IEvString("") +// let evTypeTag: InternalExpressionValue.t = Belt.Map.String.getWithDefault( +// typeMap, +// "typeTag", +// default, +// ) +// let evTypeIdentifier: InternalExpressionValue.t = Belt.Map.String.getWithDefault( +// typeMap, +// "typeIdentifier", +// default, +// ) +// let evTypeOr: InternalExpressionValue.t = Belt.Map.String.getWithDefault( +// typeMap, +// "typeOr", +// default, +// ) +// let evInputs: InternalExpressionValue.t = Belt.Map.String.getWithDefault( +// typeMap, +// "inputs", +// default, +// ) +// let evOutput: InternalExpressionValue.t = Belt.Map.String.getWithDefault( +// typeMap, +// "output", +// default, +// ) +// let evElement: InternalExpressionValue.t = Belt.Map.String.getWithDefault( +// typeMap, +// "element", +// default, +// ) +// let evElements: InternalExpressionValue.t = Belt.Map.String.getWithDefault( +// typeMap, +// "elements", +// default, +// ) +// let evProperties: InternalExpressionValue.t = Belt.Map.String.getWithDefault( +// typeMap, +// "properties", +// default, +// ) - let contracts = - typeMap->Belt.Map.String.keep((k, _v) => ["min", "max", "memberOf"]->Js.Array2.includes(k)) +// let contracts = +// typeMap->Belt.Map.String.keep((k, _v) => ["min", "max", "memberOf"]->Js.Array2.includes(k)) - let makeIt = switch evTypeTag { - | IEvString("typeIdentifier") => fromIEvValue(evTypeIdentifier) - | IEvString("typeOr") => ItTypeOr({typeOr: fromIEvArray(evTypeOr)}) - | IEvString("typeFunction") => - ItTypeFunction({inputs: fromIEvArray(evInputs), output: fromIEvValue(evOutput)}) - | IEvString("typeArray") => ItTypeArray({element: fromIEvValue(evElement)}) - | IEvString("typeTuple") => ItTypeTuple({elements: fromIEvArray(evElements)}) - | IEvString("typeRecord") => ItTypeRecord({properties: fromIEvRecord(evProperties)}) - | _ => raise(Reducer_Exception.ImpossibleException("Reducer_Type_T-evTypeTag")) - } +// let makeIt = switch evTypeTag { +// | IEvString("typeIdentifier") => fromIEvValue(evTypeIdentifier) +// | IEvString("typeOr") => ItTypeOr({typeOr: fromIEvArray(evTypeOr)}) +// | IEvString("typeFunction") => +// ItTypeFunction({inputs: fromIEvArray(evInputs), output: fromIEvValue(evOutput)}) +// | IEvString("typeArray") => ItTypeArray({element: fromIEvValue(evElement)}) +// | IEvString("typeTuple") => ItTypeTuple({elements: fromIEvArray(evElements)}) +// | IEvString("typeRecord") => ItTypeRecord({properties: fromIEvRecord(evProperties)}) +// | _ => raise(Reducer_Exception.ImpossibleException("Reducer_Type_T-evTypeTag")) +// } - Belt.Map.String.isEmpty(contracts) - ? makeIt - : ItModifiedType({modifiedType: makeIt, contracts: contracts}) -} +// Belt.Map.String.isEmpty(contracts) +// ? makeIt +// : ItModifiedType({modifiedType: makeIt, contracts: contracts}) +// } -and fromIEvValue = (ievValue: InternalExpressionValue.t): iType => - switch ievValue { - | IEvTypeIdentifier(typeIdentifier) => ItTypeIdentifier({typeIdentifier}) - | IEvType(typeMap) => fromTypeMap(typeMap) - | _ => raise(Reducer_Exception.ImpossibleException("Reducer_Type_T-ievValue")) - } -and fromIEvArray = (ievArray: InternalExpressionValue.t) => - switch ievArray { - | IEvArray(array) => array->Belt.Array.map(fromIEvValue) - | _ => raise(Reducer_Exception.ImpossibleException("Reducer_Type_T-ievArray")) - } -and fromIEvRecord = (ievRecord: InternalExpressionValue.t) => - switch ievRecord { - | IEvRecord(record) => record->Belt.Map.String.map(fromIEvValue) - | _ => raise(Reducer_Exception.ImpossibleException("Reducer_Type_T-ievRecord")) - } +// and fromIEvValue = (ievValue: InternalExpressionValue.t): iType => +// switch ievValue { +// | IEvTypeIdentifier(typeIdentifier) => ItTypeIdentifier({typeIdentifier}) +// | IEvType(typeMap) => fromTypeMap(typeMap) +// | _ => raise(Reducer_Exception.ImpossibleException("Reducer_Type_T-ievValue")) +// } +// and fromIEvArray = (ievArray: InternalExpressionValue.t) => +// switch ievArray { +// | IEvArray(array) => array->Belt.Array.map(fromIEvValue) +// | _ => raise(Reducer_Exception.ImpossibleException("Reducer_Type_T-ievArray")) +// } +// and fromIEvRecord = (ievRecord: InternalExpressionValue.t) => +// switch ievRecord { +// | 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 d3906a38..8ecc2f82 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 @@ -1,80 +1,80 @@ -open ReducerInterface_InternalExpressionValue +// open ReducerInterface_InternalExpressionValue -let typeModifier_memberOf = (aType, anArray) => { - let newRecord = Belt.Map.String.fromArray([ - ("typeTag", IEvString("typeIdentifier")), - ("typeIdentifier", aType), - ]) - newRecord->Belt.Map.String.set("memberOf", anArray)->IEvType->Ok -} +// let typeModifier_memberOf = (aType, anArray) => { +// let newRecord = Belt.Map.String.fromArray([ +// ("typeTag", IEvString("typeIdentifier")), +// ("typeIdentifier", aType), +// ]) +// newRecord->Belt.Map.String.set("memberOf", anArray)->IEvType->Ok +// } -let typeModifier_memberOf_update = (aRecord, anArray) => { - aRecord->Belt.Map.String.set("memberOf", anArray)->IEvType->Ok -} +// let typeModifier_memberOf_update = (aRecord, anArray) => { +// aRecord->Belt.Map.String.set("memberOf", anArray)->IEvType->Ok +// } -let typeModifier_min = (aType, value) => { - let newRecord = Belt.Map.String.fromArray([ - ("typeTag", IEvString("typeIdentifier")), - ("typeIdentifier", aType), - ]) - newRecord->Belt.Map.String.set("min", value)->IEvType->Ok -} +// let typeModifier_min = (aType, value) => { +// let newRecord = Belt.Map.String.fromArray([ +// ("typeTag", IEvString("typeIdentifier")), +// ("typeIdentifier", aType), +// ]) +// newRecord->Belt.Map.String.set("min", value)->IEvType->Ok +// } -let typeModifier_min_update = (aRecord, value) => { - aRecord->Belt.Map.String.set("min", value)->IEvType->Ok -} +// let typeModifier_min_update = (aRecord, value) => { +// aRecord->Belt.Map.String.set("min", value)->IEvType->Ok +// } -let typeModifier_max = (aType, value) => { - let newRecord = Belt.Map.String.fromArray([ - ("typeTag", IEvString("typeIdentifier")), - ("typeIdentifier", aType), - ]) - newRecord->Belt.Map.String.set("max", value)->IEvType->Ok -} +// let typeModifier_max = (aType, value) => { +// let newRecord = Belt.Map.String.fromArray([ +// ("typeTag", IEvString("typeIdentifier")), +// ("typeIdentifier", aType), +// ]) +// newRecord->Belt.Map.String.set("max", value)->IEvType->Ok +// } -let typeModifier_max_update = (aRecord, value) => - aRecord->Belt.Map.String.set("max", value)->IEvType->Ok +// let typeModifier_max_update = (aRecord, value) => +// aRecord->Belt.Map.String.set("max", value)->IEvType->Ok -let typeModifier_opaque_update = aRecord => - aRecord->Belt.Map.String.set("opaque", IEvBool(true))->IEvType->Ok +// let typeModifier_opaque_update = aRecord => +// aRecord->Belt.Map.String.set("opaque", IEvBool(true))->IEvType->Ok -let typeOr = evArray => { - let newRecord = Belt.Map.String.fromArray([("typeTag", IEvString("typeOr")), ("typeOr", evArray)]) - newRecord->IEvType->Ok -} +// let typeOr = evArray => { +// let newRecord = Belt.Map.String.fromArray([("typeTag", IEvString("typeOr")), ("typeOr", evArray)]) +// newRecord->IEvType->Ok +// } -let typeFunction = anArray => { - let output = Belt.Array.getUnsafe(anArray, Js.Array2.length(anArray) - 1) - let inputs = Js.Array2.slice(anArray, ~start=0, ~end_=-1) - let newRecord = Belt.Map.String.fromArray([ - ("typeTag", IEvString("typeFunction")), - ("inputs", IEvArray(inputs)), - ("output", output), - ]) - newRecord->IEvType->Ok -} +// let typeFunction = anArray => { +// let output = Belt.Array.getUnsafe(anArray, Js.Array2.length(anArray) - 1) +// let inputs = Js.Array2.slice(anArray, ~start=0, ~end_=-1) +// let newRecord = Belt.Map.String.fromArray([ +// ("typeTag", IEvString("typeFunction")), +// ("inputs", IEvArray(inputs)), +// ("output", output), +// ]) +// newRecord->IEvType->Ok +// } -let typeArray = element => { - let newRecord = Belt.Map.String.fromArray([ - ("typeTag", IEvString("typeArray")), - ("element", element), - ]) - newRecord->IEvType->Ok -} +// let typeArray = element => { +// let newRecord = Belt.Map.String.fromArray([ +// ("typeTag", IEvString("typeArray")), +// ("element", element), +// ]) +// newRecord->IEvType->Ok +// } -let typeTuple = anArray => { - let newRecord = Belt.Map.String.fromArray([ - ("typeTag", IEvString("typeTuple")), - ("elements", IEvArray(anArray)), - ]) - newRecord->IEvType->Ok -} +// let typeTuple = anArray => { +// let newRecord = Belt.Map.String.fromArray([ +// ("typeTag", IEvString("typeTuple")), +// ("elements", IEvArray(anArray)), +// ]) +// newRecord->IEvType->Ok +// } -let typeRecord = propertyMap => { - let newProperties = propertyMap->IEvRecord - let newRecord = Belt.Map.String.fromArray([ - ("typeTag", IEvString("typeRecord")), - ("properties", newProperties), - ]) - newRecord->IEvType->Ok -} +// let typeRecord = propertyMap => { +// let newProperties = propertyMap->IEvRecord +// let newRecord = Belt.Map.String.fromArray([ +// ("typeTag", IEvString("typeRecord")), +// ("properties", newProperties), +// ]) +// 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 c9152e3c..3c0b4bc9 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 @@ -1,182 +1,181 @@ -module ExpressionT = Reducer_Expression_T -module InternalExpressionValue = ReducerInterface_InternalExpressionValue -module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -module ProjectReducerFnT = ReducerProject_ReducerFn_T -module T = Reducer_Type_T -module TypeContracts = Reducer_Type_Contracts -open InternalExpressionValue +// module ExpressionT = Reducer_Expression_T +// module InternalExpressionValue = ReducerInterface_InternalExpressionValue +// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T +// module T = Reducer_Type_T +// module TypeContracts = Reducer_Type_Contracts +// open InternalExpressionValue -let rec isITypeOf = (anIType: T.iType, aValue): result => { - let caseTypeIdentifier = (anUpperTypeName, aValue) => { - let aTypeName = anUpperTypeName->Js.String2.toLowerCase - switch aTypeName { - | "any" => Ok(true) - | _ => { - let valueTypeName = aValue->valueToValueType->valueTypeToString->Js.String2.toLowerCase - switch aTypeName == valueTypeName { - | true => Ok(true) - | false => T.TypeMismatch(anIType, aValue)->Error - } - } - } - } +// let rec isITypeOf = (anIType: T.iType, aValue): result => { +// let caseTypeIdentifier = (anUpperTypeName, aValue) => { +// let aTypeName = anUpperTypeName->Js.String2.toLowerCase +// switch aTypeName { +// | "any" => Ok(true) +// | _ => { +// let valueTypeName = aValue->valueToValueType->valueTypeToString->Js.String2.toLowerCase +// switch aTypeName == valueTypeName { +// | true => Ok(true) +// | false => T.TypeMismatch(anIType, aValue)->Error +// } +// } +// } +// } - let caseRecord = (anIType, propertyMap: Belt.Map.String.t, evValue) => - switch evValue { - | IEvRecord(aRecord) => - if ( - Js.Array2.length(propertyMap->Belt.Map.String.keysToArray) == - Js.Array2.length(aRecord->Belt.Map.String.keysToArray) - ) { - Belt.Map.String.reduce(propertyMap, Ok(true), (acc, property, propertyType) => { - Belt.Result.flatMap(acc, _ => - switch Belt.Map.String.get(aRecord, property) { - | Some(propertyValue) => isITypeOf(propertyType, propertyValue) - | None => T.TypeMismatch(anIType, evValue)->Error - } - ) - }) - } else { - T.TypeMismatch(anIType, evValue)->Error - } +// let caseRecord = (anIType, propertyMap: Belt.Map.String.t, evValue) => +// switch evValue { +// | IEvRecord(aRecord) => +// if ( +// Js.Array2.length(propertyMap->Belt.Map.String.keysToArray) == +// Js.Array2.length(aRecord->Belt.Map.String.keysToArray) +// ) { +// Belt.Map.String.reduce(propertyMap, Ok(true), (acc, property, propertyType) => { +// Belt.Result.flatMap(acc, _ => +// switch Belt.Map.String.get(aRecord, property) { +// | Some(propertyValue) => isITypeOf(propertyType, propertyValue) +// | None => T.TypeMismatch(anIType, evValue)->Error +// } +// ) +// }) +// } else { +// T.TypeMismatch(anIType, evValue)->Error +// } - | _ => T.TypeMismatch(anIType, evValue)->Error - } +// | _ => T.TypeMismatch(anIType, evValue)->Error +// } - let caseArray = (anIType, elementType, evValue) => - switch evValue { - | IEvArray(anArray) => - Belt.Array.reduce(anArray, Ok(true), (acc, element) => - Belt.Result.flatMap(acc, _ => - switch isITypeOf(elementType, element) { - | Ok(_) => Ok(true) - | Error(error) => error->Error - } - ) - ) - | _ => T.TypeMismatch(anIType, evValue)->Error - } +// let caseArray = (anIType, elementType, evValue) => +// switch evValue { +// | IEvArray(anArray) => +// Belt.Array.reduce(anArray, Ok(true), (acc, element) => +// Belt.Result.flatMap(acc, _ => +// switch isITypeOf(elementType, element) { +// | Ok(_) => Ok(true) +// | Error(error) => error->Error +// } +// ) +// ) +// | _ => T.TypeMismatch(anIType, evValue)->Error +// } - let caseTuple = (anIType, elementTypes, evValue) => - switch evValue { - | IEvArray(anArray) => - if Js.Array2.length(elementTypes) == Js.Array2.length(anArray) { - let zipped = Belt.Array.zip(elementTypes, anArray) - Belt.Array.reduce(zipped, Ok(true), (acc, (elementType, element)) => - switch acc { - | Ok(_) => - switch isITypeOf(elementType, element) { - | Ok(_) => acc - | Error(error) => Error(error) - } - | _ => acc - } - ) - } else { - T.TypeMismatch(anIType, evValue)->Error - } - | _ => T.TypeMismatch(anIType, evValue)->Error - } +// let caseTuple = (anIType, elementTypes, evValue) => +// switch evValue { +// | IEvArray(anArray) => +// if Js.Array2.length(elementTypes) == Js.Array2.length(anArray) { +// let zipped = Belt.Array.zip(elementTypes, anArray) +// Belt.Array.reduce(zipped, Ok(true), (acc, (elementType, element)) => +// switch acc { +// | Ok(_) => +// switch isITypeOf(elementType, element) { +// | Ok(_) => acc +// | Error(error) => Error(error) +// } +// | _ => acc +// } +// ) +// } else { +// T.TypeMismatch(anIType, evValue)->Error +// } +// | _ => T.TypeMismatch(anIType, evValue)->Error +// } - let caseOr = (anIType, anITypeArray, evValue) => - switch Belt.Array.reduce(anITypeArray, Ok(false), (acc, anIType) => - Belt.Result.flatMap(acc, _ => - switch acc { - | Ok(false) => - switch isITypeOf(anIType, evValue) { - | Ok(_) => Ok(true) - | Error(_) => acc - } - | _ => acc - } - ) - ) { - | Ok(true) => Ok(true) - | Ok(false) => T.TypeMismatch(anIType, evValue)->Error - | Error(error) => Error(error) - } +// let caseOr = (anIType, anITypeArray, evValue) => +// switch Belt.Array.reduce(anITypeArray, Ok(false), (acc, anIType) => +// Belt.Result.flatMap(acc, _ => +// switch acc { +// | Ok(false) => +// switch isITypeOf(anIType, evValue) { +// | Ok(_) => Ok(true) +// | Error(_) => acc +// } +// | _ => acc +// } +// ) +// ) { +// | Ok(true) => Ok(true) +// | Ok(false) => T.TypeMismatch(anIType, evValue)->Error +// | Error(error) => Error(error) +// } - let caseModifiedType = ( - anIType: T.iType, - modifiedType: T.iType, - contracts: Belt.Map.String.t, - aValue: InternalExpressionValue.t, - ) => { - isITypeOf(modifiedType, aValue)->Belt.Result.flatMap(_result => { - if TypeContracts.checkModifiers(contracts, aValue) { - Ok(true) - } else { - T.TypeMismatch(anIType, aValue)->Error - } - }) - } +// let caseModifiedType = ( +// anIType: T.iType, +// modifiedType: T.iType, +// contracts: Belt.Map.String.t, +// aValue: InternalExpressionValue.t, +// ) => { +// isITypeOf(modifiedType, aValue)->Belt.Result.flatMap(_result => { +// if TypeContracts.checkModifiers(contracts, aValue) { +// Ok(true) +// } else { +// T.TypeMismatch(anIType, aValue)->Error +// } +// }) +// } - switch anIType { - | ItTypeIdentifier(name) => caseTypeIdentifier(name, aValue) - | ItModifiedType({modifiedType, contracts}) => - caseModifiedType(anIType, modifiedType, contracts, aValue) //{modifiedType: iType, contracts: Belt.Map.String.t} - | ItTypeOr({typeOr}) => caseOr(anIType, typeOr, aValue) - | ItTypeFunction(_) => - raise( - Reducer_Exception.ImpossibleException( - "Reducer_TypeChecker-functions are without a type at the moment", - ), - ) - | ItTypeArray({element}) => caseArray(anIType, element, aValue) - | ItTypeTuple({elements}) => caseTuple(anIType, elements, aValue) - | ItTypeRecord({properties}) => caseRecord(anIType, properties, aValue) - } -} +// switch anIType { +// | ItTypeIdentifier(name) => caseTypeIdentifier(name, aValue) +// | ItModifiedType({modifiedType, contracts}) => +// caseModifiedType(anIType, modifiedType, contracts, aValue) //{modifiedType: iType, contracts: Belt.Map.String.t} +// | ItTypeOr({typeOr}) => caseOr(anIType, typeOr, aValue) +// | ItTypeFunction(_) => +// raise( +// Reducer_Exception.ImpossibleException( +// "Reducer_TypeChecker-functions are without a type at the moment", +// ), +// ) +// | ItTypeArray({element}) => caseArray(anIType, element, aValue) +// | ItTypeTuple({elements}) => caseTuple(anIType, elements, aValue) +// | ItTypeRecord({properties}) => caseRecord(anIType, properties, aValue) +// } +// } -let isTypeOf = ( - typeExpressionSourceCode: string, - aValue: InternalExpressionValue.t, - reducerFn: ProjectReducerFnT.t, -): result => { - switch typeExpressionSourceCode->Reducer_Type_Compile.fromTypeExpression(reducerFn) { - | Ok(anIType) => - switch isITypeOf(anIType, aValue) { - | Ok(_) => Ok(aValue) - | Error(T.TypeMismatch(anIType, evValue)) => - Error( - ErrorValue.REExpectedType(anIType->T.toString, evValue->InternalExpressionValue.toString), - ) - } - | Error(error) => Error(error) // Directly propagating - err => err - causes type mismatch - } -} +// let isTypeOf = ( +// typeExpressionSourceCode: string, +// aValue: InternalExpressionValue.t, +// reducerFn: Reducer_T.reducerFn, +// ): result => { +// switch typeExpressionSourceCode->Reducer_Type_Compile.fromTypeExpression(reducerFn) { +// | Ok(anIType) => +// switch isITypeOf(anIType, aValue) { +// | Ok(_) => Ok(aValue) +// | Error(T.TypeMismatch(anIType, evValue)) => +// Error( +// ErrorValue.REExpectedType(anIType->T.toString, evValue->InternalExpressionValue.toString), +// ) +// } +// | Error(error) => Error(error) // Directly propagating - err => err - causes type mismatch +// } +// } -let checkITypeArguments = (anIType: T.iType, args: array): result< - bool, - T.typeErrorValue, -> => { - switch anIType { - | T.ItTypeFunction({inputs}) => isITypeOf(T.ItTypeTuple({elements: inputs}), args->IEvArray) - | _ => T.TypeMismatch(anIType, args->IEvArray)->Error - } -} +// let checkITypeArguments = (anIType: T.iType, args: array): result< +// bool, +// T.typeErrorValue, +// > => { +// switch anIType { +// | T.ItTypeFunction({inputs}) => isITypeOf(T.ItTypeTuple({elements: inputs}), args->IEvArray) +// | _ => T.TypeMismatch(anIType, args->IEvArray)->Error +// } +// } -let checkITypeArgumentsBool = (anIType: T.iType, args: array): bool => { - switch checkITypeArguments(anIType, args) { - | Ok(_) => true - | _ => false - } -} +// let checkITypeArgumentsBool = (anIType: T.iType, args: array): bool => { +// switch checkITypeArguments(anIType, args) { +// | Ok(_) => true +// | _ => false +// } +// } -let checkArguments = ( - typeExpressionSourceCode: string, - args: array, - reducerFn: ProjectReducerFnT.t, -): result => { - switch typeExpressionSourceCode->Reducer_Type_Compile.fromTypeExpression(reducerFn) { - | Ok(anIType) => - switch checkITypeArguments(anIType, args) { - | Ok(_) => Ok(args->IEvArray) - | Error(T.TypeMismatch(anIType, evValue)) => - Error( - ErrorValue.REExpectedType(anIType->T.toString, evValue->InternalExpressionValue.toString), - ) - } - | Error(error) => Error(error) // Directly propagating - err => err - causes type mismatch - } -} +// let checkArguments = ( +// typeExpressionSourceCode: string, +// args: array, +// reducerFn: ReducerT.reducerFn, +// ): result => { +// switch typeExpressionSourceCode->Reducer_Type_Compile.fromTypeExpression(reducerFn) { +// | Ok(anIType) => +// switch checkITypeArguments(anIType, args) { +// | Ok(_) => Ok(args->IEvArray) +// | Error(T.TypeMismatch(anIType, evValue)) => +// Error( +// ErrorValue.REExpectedType(anIType->T.toString, evValue->InternalExpressionValue.toString), +// ) +// } +// | 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 3396d0f3..8252b47a 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Date.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Date.res @@ -1,27 +1,26 @@ -module IEV = ReducerInterface_InternalExpressionValue -type internalExpressionValue = IEV.t +module T = Reducer_T -let dispatch = (call: IEV.functionCall, _: GenericDist.env): option< - result, +let dispatch = (call: ReducerInterface_InternalExpressionValue.functionCall, _: GenericDist.env): option< + result, > => { switch call { - | ("toString", [IEvDate(t)]) => IEV.IEvString(DateTime.Date.toString(t))->Ok->Some + | ("toString", [IEvDate(t)]) => T.IEvString(DateTime.Date.toString(t))->Ok->Some | ("makeDateFromYear", [IEvNumber(year)]) => switch DateTime.Date.makeFromYear(year) { - | Ok(t) => IEV.IEvDate(t)->Ok->Some + | Ok(t) => T.IEvDate(t)->Ok->Some | Error(e) => Reducer_ErrorValue.RETodo(e)->Error->Some } - | ("dateFromNumber", [IEvNumber(f)]) => IEV.IEvDate(DateTime.Date.fromFloat(f))->Ok->Some - | ("toNumber", [IEvDate(f)]) => IEV.IEvNumber(DateTime.Date.toFloat(f))->Ok->Some + | ("dateFromNumber", [IEvNumber(f)]) => T.IEvDate(DateTime.Date.fromFloat(f))->Ok->Some + | ("toNumber", [IEvDate(f)]) => T.IEvNumber(DateTime.Date.toFloat(f))->Ok->Some | ("subtract", [IEvDate(d1), IEvDate(d2)]) => switch DateTime.Date.subtract(d1, d2) { - | Ok(d) => IEV.IEvTimeDuration(d)->Ok + | Ok(d) => T.IEvTimeDuration(d)->Ok | Error(e) => Error(RETodo(e)) }->Some | ("subtract", [IEvDate(d1), IEvTimeDuration(d2)]) => - IEV.IEvDate(DateTime.Date.subtractDuration(d1, d2))->Ok->Some + T.IEvDate(DateTime.Date.subtractDuration(d1, d2))->Ok->Some | ("add", [IEvDate(d1), IEvTimeDuration(d2)]) => - IEV.IEvDate(DateTime.Date.addDuration(d1, d2))->Ok->Some + T.IEvDate(DateTime.Date.addDuration(d1, d2))->Ok->Some | _ => None } } diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Duration.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Duration.res index f9e06de4..846f6417 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Duration.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Duration.res @@ -1,36 +1,37 @@ module IEV = ReducerInterface_InternalExpressionValue +module T = Reducer_T type internalExpressionValue = IEV.t -let dispatch = (call: IEV.functionCall, _: GenericDist.env): option< - result, +let dispatch = (call: IEV.functionCall, _: T.environment): option< + result > => { switch call { - | ("toString", [IEvTimeDuration(t)]) => IEV.IEvString(DateTime.Duration.toString(t))->Ok->Some - | ("minutes", [IEvNumber(f)]) => IEV.IEvTimeDuration(DateTime.Duration.fromMinutes(f))->Ok->Some + | ("toString", [IEvTimeDuration(t)]) => T.IEvString(DateTime.Duration.toString(t))->Ok->Some + | ("minutes", [IEvNumber(f)]) => T.IEvTimeDuration(DateTime.Duration.fromMinutes(f))->Ok->Some | ("fromUnit_minutes", [IEvNumber(f)]) => - IEV.IEvTimeDuration(DateTime.Duration.fromMinutes(f))->Ok->Some - | ("hours", [IEvNumber(f)]) => IEV.IEvTimeDuration(DateTime.Duration.fromHours(f))->Ok->Some + T.IEvTimeDuration(DateTime.Duration.fromMinutes(f))->Ok->Some + | ("hours", [IEvNumber(f)]) => T.IEvTimeDuration(DateTime.Duration.fromHours(f))->Ok->Some | ("fromUnit_hours", [IEvNumber(f)]) => - IEV.IEvTimeDuration(DateTime.Duration.fromHours(f))->Ok->Some - | ("days", [IEvNumber(f)]) => IEV.IEvTimeDuration(DateTime.Duration.fromDays(f))->Ok->Some + T.IEvTimeDuration(DateTime.Duration.fromHours(f))->Ok->Some + | ("days", [IEvNumber(f)]) => T.IEvTimeDuration(DateTime.Duration.fromDays(f))->Ok->Some | ("fromUnit_days", [IEvNumber(f)]) => - IEV.IEvTimeDuration(DateTime.Duration.fromDays(f))->Ok->Some - | ("years", [IEvNumber(f)]) => IEV.IEvTimeDuration(DateTime.Duration.fromYears(f))->Ok->Some + T.IEvTimeDuration(DateTime.Duration.fromDays(f))->Ok->Some + | ("years", [IEvNumber(f)]) => T.IEvTimeDuration(DateTime.Duration.fromYears(f))->Ok->Some | ("fromUnit_years", [IEvNumber(f)]) => - IEV.IEvTimeDuration(DateTime.Duration.fromYears(f))->Ok->Some - | ("toHours", [IEvTimeDuration(f)]) => IEV.IEvNumber(DateTime.Duration.toHours(f))->Ok->Some - | ("toMinutes", [IEvTimeDuration(f)]) => IEV.IEvNumber(DateTime.Duration.toMinutes(f))->Ok->Some - | ("toDays", [IEvTimeDuration(f)]) => IEV.IEvNumber(DateTime.Duration.toDays(f))->Ok->Some - | ("toYears", [IEvTimeDuration(f)]) => IEV.IEvNumber(DateTime.Duration.toYears(f))->Ok->Some + T.IEvTimeDuration(DateTime.Duration.fromYears(f))->Ok->Some + | ("toHours", [IEvTimeDuration(f)]) => T.IEvNumber(DateTime.Duration.toHours(f))->Ok->Some + | ("toMinutes", [IEvTimeDuration(f)]) => T.IEvNumber(DateTime.Duration.toMinutes(f))->Ok->Some + | ("toDays", [IEvTimeDuration(f)]) => T.IEvNumber(DateTime.Duration.toDays(f))->Ok->Some + | ("toYears", [IEvTimeDuration(f)]) => T.IEvNumber(DateTime.Duration.toYears(f))->Ok->Some | ("add", [IEvTimeDuration(d1), IEvTimeDuration(d2)]) => - IEV.IEvTimeDuration(DateTime.Duration.add(d1, d2))->Ok->Some + T.IEvTimeDuration(DateTime.Duration.add(d1, d2))->Ok->Some | ("subtract", [IEvTimeDuration(d1), IEvTimeDuration(d2)]) => - IEV.IEvTimeDuration(DateTime.Duration.subtract(d1, d2))->Ok->Some + T.IEvTimeDuration(DateTime.Duration.subtract(d1, d2))->Ok->Some | ("multiply", [IEvTimeDuration(d1), IEvNumber(d2)]) => - IEV.IEvTimeDuration(DateTime.Duration.multiply(d1, d2))->Ok->Some + T.IEvTimeDuration(DateTime.Duration.multiply(d1, d2))->Ok->Some | ("divide", [IEvTimeDuration(d1), IEvNumber(d2)]) => - IEV.IEvTimeDuration(DateTime.Duration.divide(d1, d2))->Ok->Some - | ("divide", [IEvTimeDuration(d1), IEvTimeDuration(d2)]) => IEV.IEvNumber(d1 /. d2)->Ok->Some + T.IEvTimeDuration(DateTime.Duration.divide(d1, d2))->Ok->Some + | ("divide", [IEvTimeDuration(d1), IEvTimeDuration(d2)]) => T.IEvNumber(d1 /. d2)->Ok->Some | _ => None } } diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res index 89528a32..f60c4f95 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res @@ -1,24 +1,21 @@ module InternalExpressionValue = ReducerInterface_InternalExpressionValue -module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -module ProjectReducerFnT = ReducerProject_ReducerFn_T -type internalExpressionValue = InternalExpressionValue.t /* Map external calls of Reducer */ let dispatch = ( call: InternalExpressionValue.functionCall, - accessors: ProjectAccessorsT.t, - reducer: ProjectReducerFnT.t, + environment: Reducer_T.environment, + reducer: Reducer_T.reducerFn, chain, -): result => { +): result => { E.A.O.firstSomeFn([ - () => ReducerInterface_GenericDistribution.dispatch(call, accessors.environment), - () => ReducerInterface_Date.dispatch(call, accessors.environment), - () => ReducerInterface_Duration.dispatch(call, accessors.environment), - () => ReducerInterface_Number.dispatch(call, accessors.environment), - () => FunctionRegistry_Library.dispatch(call, accessors, reducer), - ])->E.O2.defaultFn(() => chain(call, accessors, reducer)) + () => ReducerInterface_GenericDistribution.dispatch(call, environment), + () => ReducerInterface_Date.dispatch(call, environment), + () => ReducerInterface_Duration.dispatch(call, environment), + () => ReducerInterface_Number.dispatch(call, environment), + () => FunctionRegistry_Library.dispatch(call, environment, reducer), + ])->E.O2.defaultFn(() => chain(call, environment, reducer)) } /* @@ -26,7 +23,7 @@ If your dispatch is too big you can divide it into smaller dispatches and pass t The final chain(call) invokes the builtin default functions of the interpreter. -Via chain(call), all MathJs operators and functions are available for string, number , boolean, array and record +Via chain(call), all MathJs operators and functions are available for string, number, boolean, array and record .e.g + - / * > >= < <= == /= not and or sin cos log ln concat, etc. // See https://mathjs.org/docs/expressions/syntax.html diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res index addd4388..43234fe7 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.res @@ -297,12 +297,12 @@ let genericOutputToReducerValue = (o: DistributionOperation.outputType): result< Reducer_ErrorValue.errorValue, > => switch o { - | Dist(d) => Ok(ReducerInterface_InternalExpressionValue.IEvDistribution(d)) + | 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 => ReducerInterface_InternalExpressionValue.IEvNumber(r)))) + Ok(IEvArray(d |> E.A.fmap(r => Reducer_T.IEvNumber(r)))) | GenDistError(err) => Error(REDistributionError(err)) } diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res index 4144c016..661b69e1 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res @@ -1,51 +1,26 @@ +// deprecated, use Reducer_T instead +// (value methods should be moved to Reducer_Value.res) + module ErrorValue = Reducer_ErrorValue module Extra_Array = Reducer_Extra_Array -type internalCode = Object type environment = GenericDist.env +module T = Reducer_T let defaultEnvironment: environment = DistributionOperation.defaultEnv -@genType.opaque -type rec t = - | IEvArray(array) // FIXME: Convert to MapInt - | IEvArrayString(array) - | IEvBool(bool) - | IEvCall(string) // External function call - | IEvDate(Js.Date.t) - | IEvDeclaration(lambdaDeclaration) - | IEvDistribution(DistributionTypes.genericDist) - | IEvLambda(lambdaValue) - | IEvBindings(nameSpace) - | IEvNumber(float) - | IEvRecord(map) - | IEvString(string) - | IEvSymbol(string) - | IEvTimeDuration(float) - | IEvType(map) - | IEvTypeIdentifier(string) - | IEvVoid -@genType.opaque and squiggleArray = array -@genType.opaque and map = Belt.Map.String.t -@genType.opaque and nameSpace = NameSpace(Belt.MutableMap.String.t, option) -@genType.opaque -and lambdaValue = { - parameters: array, - context: nameSpace, - body: internalCode, -} -@genType.opaque and lambdaDeclaration = Declaration.declaration +type t = Reducer_T.value type internalExpressionValue = t type functionCall = (string, array) -let rec toString = aValue => +let rec toString = (aValue: T.value) => switch aValue { | IEvArray(anArray) => toStringArray(anArray) | IEvArrayString(anArray) => toStringArrayString(anArray) | IEvBindings(m) => toStringBindings(m) | IEvBool(aBool) => toStringBool(aBool) - | IEvCall(fName) => toStringCall(fName) + // | IEvCall(fName) => toStringCall(fName) | IEvDate(date) => toStringDate(date) | IEvDeclaration(d) => toStringDeclaration(d) | IEvDistribution(dist) => toStringDistribution(dist) @@ -53,7 +28,7 @@ let rec toString = aValue => | IEvNumber(aNumber) => toStringNumber(aNumber) | IEvRecord(aMap) => aMap->toStringRecord | IEvString(aString) => toStringString(aString) - | IEvSymbol(aString) => toStringSymbol(aString) + // | IEvSymbol(aString) => toStringSymbol(aString) | IEvTimeDuration(t) => toStringTimeDuration(t) | IEvType(aMap) => toStringType(aMap) | IEvTypeIdentifier(id) => toStringTypeIdentifier(id) @@ -73,9 +48,12 @@ and toStringCall = fName => `:${fName}` and toStringDate = date => DateTime.Date.toString(date) and toStringDeclaration = d => Declaration.toString(d, r => toString(IEvLambda(r))) and toStringDistribution = dist => GenericDist.toString(dist) -and toStringLambda = lambdaValue => - `lambda(${Js.Array2.toString(lambdaValue.parameters)}=>internal code)` -and toStringFunction = lambdaValue => `function(${Js.Array2.toString(lambdaValue.parameters)})` +and toStringLambda = (lambdaValue: T.lambdaValue) => + switch lambdaValue { + | LNoFFI({ parameters }) => `lambda(${parameters->Js.Array2.toString}=>internal code)` // TODO - serialize code too? + | LFFI(_) => `standard function` // TODO - serialize name, etc? + } +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}'` @@ -94,17 +72,25 @@ and toStringMap = aMap => { `{${pairs}}` } and toStringNameSpace = nameSpace => { - let NameSpace(container, parent) = nameSpace - FIXME_CALL_PARENTS - container->toStringMap + let T.NameSpace(container, parent) = nameSpace + let pairs = + container + ->Belt.MutableMap.String.toArray + ->Js.Array2.map(((eachKey, eachValue)) => `${eachKey}: ${toString(eachValue)}`) + ->Js.Array2.toString + + switch parent { + | Some(p) => `{${pairs}} / ${toStringNameSpace(p)}` + | None => `{${pairs}}` + } } -let toStringWithType = aValue => +let toStringWithType = (aValue: T.value) => switch aValue { | IEvArray(_) => `Array::${toString(aValue)}` | IEvArrayString(_) => `ArrayString::${toString(aValue)}` | IEvBool(_) => `Bool::${toString(aValue)}` - | IEvCall(_) => `Call::${toString(aValue)}` + // | IEvCall(_) => `Call::${toString(aValue)}` | IEvDate(_) => `Date::${toString(aValue)}` | IEvDeclaration(_) => `Declaration::${toString(aValue)}` | IEvDistribution(_) => `Distribution::${toString(aValue)}` @@ -113,7 +99,7 @@ let toStringWithType = aValue => | IEvNumber(_) => `Number::${toString(aValue)}` | IEvRecord(_) => `Record::${toString(aValue)}` | IEvString(_) => `String::${toString(aValue)}` - | IEvSymbol(_) => `Symbol::${toString(aValue)}` + // | IEvSymbol(_) => `Symbol::${toString(aValue)}` | IEvTimeDuration(_) => `Date::${toString(aValue)}` | IEvType(_) => `Type::${toString(aValue)}` | IEvTypeIdentifier(_) => `TypeIdentifier::${toString(aValue)}` @@ -154,7 +140,7 @@ type internalExpressionValueType = | EvtArray | EvtArrayString | EvtBool - | EvtCall + // | EvtCall | EvtDate | EvtDeclaration | EvtDistribution @@ -163,7 +149,7 @@ type internalExpressionValueType = | EvtNumber | EvtRecord | EvtString - | EvtSymbol + // | EvtSymbol | EvtTimeDuration | EvtType | EvtTypeIdentifier @@ -173,12 +159,12 @@ type functionCallSignature = CallSignature(string, array +let valueToValueType = (value: T.value) => switch value { | IEvArray(_) => EvtArray | IEvArrayString(_) => EvtArrayString | IEvBool(_) => EvtBool - | IEvCall(_) => EvtCall + // | IEvCall(_) => EvtCall | IEvDate(_) => EvtDate | IEvDeclaration(_) => EvtDeclaration | IEvDistribution(_) => EvtDistribution @@ -187,7 +173,7 @@ let valueToValueType = value => | IEvNumber(_) => EvtNumber | IEvRecord(_) => EvtRecord | IEvString(_) => EvtString - | IEvSymbol(_) => EvtSymbol + // | IEvSymbol(_) => EvtSymbol | IEvTimeDuration(_) => EvtTimeDuration | IEvType(_) => EvtType | IEvTypeIdentifier(_) => EvtTypeIdentifier @@ -204,7 +190,7 @@ let valueTypeToString = (valueType: internalExpressionValueType): string => | EvtArray => `Array` | EvtArrayString => `ArrayString` | EvtBool => `Bool` - | EvtCall => `Call` + // | EvtCall => `Call` | EvtDate => `Date` | EvtDeclaration => `Declaration` | EvtDistribution => `Distribution` @@ -213,7 +199,7 @@ let valueTypeToString = (valueType: internalExpressionValueType): string => | EvtNumber => `Number` | EvtRecord => `Record` | EvtString => `String` - | EvtSymbol => `Symbol` + // | EvtSymbol => `Symbol` | EvtTimeDuration => `Duration` | EvtType => `Type` | EvtTypeIdentifier => `TypeIdentifier` @@ -227,10 +213,4 @@ let functionCallSignatureToString = (functionCallSignature: functionCallSignatur let arrayToValueArray = (arr: array): array => arr -let recordToKeyValuePairs = (record: map): array<(string, t)> => record->Belt.Map.String.toArray - -let nameSpaceToKeyValuePairs = (nameSpace: nameSpace): array<(string, t)> => { - let NameSpace(container, parent) = nameSpace - FIXME_CALL_PARENTS - container->Belt.MutableMap.String.toArray -} +let recordToKeyValuePairs = (record: T.map): array<(string, t)> => record->Belt.Map.String.toArray diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Number.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Number.res index f22df39b..bdef0c6d 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Number.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Number.res @@ -39,7 +39,7 @@ let dispatch = (call: IEV.functionCall, _: GenericDist.env): option< | "fromUnit_P") as op, [IEvNumber(f)], ) => - op->ScientificUnit.getMultiplier->E.O2.fmap(multiplier => IEV.IEvNumber(f *. multiplier)->Ok) + 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 a868eeb5..3a8c41cc 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res @@ -1,4 +1,4 @@ -module Bindings = Reducer_Bindings - -let internalStdLib: Bindings.t = - Bindings.emptyBindings->SquiggleLibrary_Math.makeBindings->SquiggleLibrary_Versions.makeBindings +let internalStdLib: Reducer_Bindings.t = + Reducer_Bindings.makeEmptyBindings() + ->SquiggleLibrary_Math.makeBindings + ->SquiggleLibrary_Versions.makeBindings diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Value/ReducerInterface_Value_Continuation.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Value/ReducerInterface_Value_Continuation.res index ac58532c..d22d75dd 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Value/ReducerInterface_Value_Continuation.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Value/ReducerInterface_Value_Continuation.res @@ -1,8 +1,8 @@ module InternalExpressionValue = ReducerInterface_InternalExpressionValue -type t = InternalExpressionValue.nameSpace +type t = Reducer_T.nameSpace -let toValue = nameSpace => InternalExpressionValue.IEvBindings(nameSpace) +let toValue = nameSpace => Reducer_T.IEvBindings(nameSpace) let toString = nameSpace => InternalExpressionValue.toString(toValue(nameSpace)) let toStringResult = rNameSpace => Belt.Result.map(rNameSpace, toValue(_))->InternalExpressionValue.toStringResult @@ -19,9 +19,3 @@ let inspectOption = (oNameSpace, label: string) => | Some(nameSpace) => inspect(nameSpace, label) | None => Js.log(`${label}: None`) } - -let minus = (NameSpace(thisContainer): t, NameSpace(thatContainer): t) => { - InternalExpressionValue.NameSpace( - Belt.Map.String.removeMany(thisContainer, Belt.Map.String.keysToArray(thatContainer)), - ) -} diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res index 948c14c3..bb314f80 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res @@ -4,263 +4,247 @@ module Bindings = Reducer_Bindings module Continuation = ReducerInterface_Value_Continuation module ErrorValue = Reducer_ErrorValue module InternalExpressionValue = ReducerInterface_InternalExpressionValue -module ProjectAccessorsT = ReducerProject_ProjectAccessors_T module ProjectItem = ReducerProject_ProjectItem module T = ReducerProject_T module Topology = ReducerProject_Topology type t = T.t -module Private = { - type internalProject = T.Private.t - type t = T.Private.t +let getItem = T.getItem +let getSourceIds = T.getSourceIds +let getDependents = Topology.getDependents +let getDependencies = Topology.getDependencies +let getRunOrder = Topology.getRunOrder +let getRunOrderFor = Topology.getRunOrderFor - let getSourceIds = T.Private.getSourceIds - let getItem = T.Private.getItem - let getDependents = Topology.getDependents - let getDependencies = Topology.getDependencies - let getRunOrder = Topology.getRunOrder - let getRunOrderFor = Topology.getRunOrderFor +let createProject = () => { + let project: t = { + items: Belt.MutableMap.String.make(), + stdLib: ReducerInterface_StdLib.internalStdLib, + environment: InternalExpressionValue.defaultEnvironment, + previousRunOrder: [], + } + project +} - let createProject = () => { - let project: t = { - "iAmProject": true, - "items": Belt.Map.String.empty, - "stdLib": ReducerInterface_StdLib.internalStdLib, - "environment": InternalExpressionValue.defaultEnvironment, - "previousRunOrder": [], - } - project +// will not be necessary when ProjectItem becomes mutable +let setItem = (project: t, sourceId: string, item: ProjectItem.t): unit => { + let _ = Belt.MutableMap.String.set(project.items, sourceId, item) +} + +let rec touchSource_ = (project: t, sourceId: string): unit => { + let item = project->getItem(sourceId) + let newItem = ProjectItem.touchSource(item) + project->setItem(sourceId, newItem) +} +and touchDependents = (project: t, sourceId: string): unit => { + let _ = getDependents(project, sourceId)->Belt.Array.forEach(_, touchSource_(project, _)) +} + +let touchSource = (project: t, sourceId: string): unit => { + touchSource_(project, sourceId) + touchDependents(project, sourceId) +} + +let handleNewTopology = (project: t): unit => { + let previousRunOrder = project.previousRunOrder + let currentRunOrder = Topology.getRunOrder(project) + let diff = Topology.runOrderDiff(currentRunOrder, previousRunOrder) + Belt.Array.forEach(diff, touchSource(project, _)) + project.previousRunOrder = currentRunOrder +} + +let getSource = (project: t, sourceId: string): option => + Belt.MutableMap.String.get(project.items, sourceId)->Belt.Option.map(ProjectItem.getSource) + +let setSource = (project: t, sourceId: string, value: string): unit => { + let newItem = project->getItem(sourceId)->ProjectItem.setSource(value) + project->setItem(sourceId, newItem) + touchDependents(project, sourceId) +} + +let clean = (project: t, sourceId: string): unit => { + let newItem = project->getItem(sourceId)->ProjectItem.clean + project->setItem(sourceId, newItem) +} + +let cleanAll = (project: t): unit => + project->getSourceIds->Belt.Array.forEach(sourceId => clean(project, sourceId)) + +let cleanResults = (project: t, sourceId: string): unit => { + let newItem = project->getItem(sourceId)->ProjectItem.cleanResults + project->setItem(sourceId, newItem) +} + +let cleanAllResults = (project: t): unit => + project->getSourceIds->Belt.Array.forEach(sourceId => project->cleanResults(sourceId)) + +let getIncludes = (project: t, sourceId: string): ProjectItem.T.includesType => + project->getItem(sourceId)->ProjectItem.getIncludes + +let getPastChain = (project: t, sourceId: string): array => + project->getItem(sourceId)->ProjectItem.getPastChain + +let getIncludesAsVariables = ( + project: t, + sourceId: string, +): ProjectItem.T.importAsVariablesType => + project->getItem(sourceId)->ProjectItem.getIncludesAsVariables + +let getDirectIncludes = (project: t, sourceId: string): array => + project->getItem(sourceId)->ProjectItem.getDirectIncludes + +let setContinues = (project: t, sourceId: string, continues: array): unit => { + let newItem = project->getItem(sourceId)->ProjectItem.setContinues(continues) + project->setItem(sourceId, newItem) + handleNewTopology(project) +} +let getContinues = (project: t, sourceId: string): array => + ProjectItem.getContinues(project->getItem(sourceId)) + +let removeContinues = (project: t, sourceId: string): unit => { + let newItem = project->getItem(sourceId)->ProjectItem.removeContinues + project->setItem(sourceId, newItem) + handleNewTopology(project) +} + +let getContinuation = (project: t, sourceId: string): ProjectItem.T.continuationArgumentType => + project->getItem(sourceId)->ProjectItem.getContinuation + +let setContinuation = ( + project: t, + sourceId: string, + continuation: ProjectItem.T.continuationArgumentType, +): unit => { + let newItem = project->getItem(sourceId)->ProjectItem.setContinuation(continuation) + project->setItem(sourceId, newItem) +} + +let getResultOption = (project: t, sourceId: string): ProjectItem.T.resultType => + project->getItem(sourceId)->ProjectItem.getResult + +let getResult = (project: t, sourceId: string): ProjectItem.T.resultArgumentType => + switch getResultOption(project, sourceId) { + | None => RENeedToRun->Error + | Some(result) => result } - let rec touchSource_ = (project: t, sourceId: string): unit => { - let item = project->getItem(sourceId) - let newItem = ProjectItem.touchSource(item) - Belt.Map.String.set(project["items"], sourceId, newItem)->T.Private.setFieldItems(project, _) - } - and touchDependents = (project: t, sourceId: string): unit => { - let _ = getDependents(project, sourceId)->Belt.Array.forEach(_, touchSource_(project, _)) +let setResult = (project: t, sourceId: string, value: ProjectItem.T.resultArgumentType): unit => { + let newItem = project->getItem(sourceId)->ProjectItem.setResult(value) + project->setItem(sourceId, newItem) +} + +let parseIncludes = (project: t, sourceId: string): unit => { + let newItem = project->getItem(sourceId)->ProjectItem.parseIncludes + project->setItem(sourceId, newItem) + handleNewTopology(project) +} + +let rawParse = (project: t, sourceId): unit => { + let newItem = project->getItem(sourceId)->ProjectItem.rawParse + project->setItem(sourceId, newItem) +} + +let getStdLib = (project: t): Reducer_Bindings.t => project.stdLib +let setStdLib = (project: t, value: Reducer_Bindings.t): unit => { + project.stdLib = value +} + +let getEnvironment = (project: t): InternalExpressionValue.environment => project.environment +let setEnvironment = (project: t, value: InternalExpressionValue.environment): unit => { + project.environment = value +} + +let getBindings = (project: t, sourceId: string): ProjectItem.T.bindingsArgumentType => { + project->getContinuation(sourceId) // TODO - locals method for cleaning parent? +} + +let getContinuationsBefore = (project: t, sourceId: string): array< + ProjectItem.T.continuation, +> => { + let pastNameSpaces = project->getPastChain(sourceId)->Js.Array2.map(getBindings(project, _)) + let theLength = pastNameSpaces->Js.Array2.length + if theLength == 0 { + // `getContinuationBefore ${sourceId}: stdLib`->Js.log + [project->getStdLib] + } else { + // `getContinuationBefore ${sourceId}: ${lastOne} = ${InternalExpressionValue.toStringBindings( + // project->getBindings(lastOne), + // )}`->Js.log + pastNameSpaces } +} - let touchSource = (project: t, sourceId: string): unit => { - touchSource_(project, sourceId) - touchDependents(project, sourceId) - } - - let handleNewTopology = (project: t): unit => { - let previousRunOrder = project["previousRunOrder"] - let currentRunOrder = Topology.getRunOrder(project) - let diff = Topology.runOrderDiff(currentRunOrder, previousRunOrder) - Belt.Array.forEach(diff, touchSource(project, _)) - T.Private.setFieldPreviousRunOrder(project, currentRunOrder) - } - - let getSource = (project: t, sourceId: string): option => - Belt.Map.String.get(project["items"], sourceId)->Belt.Option.map(ProjectItem.getSource) - - let setSource = (project: t, sourceId: string, value: string): unit => { - let newItem = project->getItem(sourceId)->ProjectItem.setSource(value) - Belt.Map.String.set(project["items"], sourceId, newItem)->T.Private.setFieldItems(project, _) - touchDependents(project, sourceId) - } - - let clean = (project: t, sourceId: string): unit => { - let newItem = project->getItem(sourceId)->ProjectItem.clean - Belt.Map.String.set(project["items"], sourceId, newItem)->T.Private.setFieldItems(project, _) - } - - let cleanAll = (project: t): unit => - getSourceIds(project)->Belt.Array.forEach(sourceId => clean(project, sourceId)) - - let cleanResults = (project: t, sourceId: string): unit => { - let newItem = project->getItem(sourceId)->ProjectItem.cleanResults - Belt.Map.String.set(project["items"], sourceId, newItem)->T.Private.setFieldItems(project, _) - } - - let cleanAllResults = (project: t): unit => - getSourceIds(project)->Belt.Array.forEach(sourceId => cleanResults(project, sourceId)) - - let getIncludes = (project: t, sourceId: string): ProjectItem.T.includesType => - project->getItem(sourceId)->ProjectItem.getIncludes - - // let getDirectIncludes = (project: t, sourceId: string): array => - // project->getItem(sourceId)->ProjectItem.getDirectIncludes - - let getPastChain = (project: t, sourceId: string): array => - project->getItem(sourceId)->ProjectItem.getPastChain - - let getIncludesAsVariables = ( - project: t, - sourceId: string, - ): ProjectItem.T.importAsVariablesType => - project->getItem(sourceId)->ProjectItem.getIncludesAsVariables - - let getDirectIncludes = (project: t, sourceId: string): array => - project->getItem(sourceId)->ProjectItem.getDirectIncludes - - let setContinues = (project: t, sourceId: string, continues: array): unit => { - let newItem = project->getItem(sourceId)->ProjectItem.setContinues(continues) - Belt.Map.String.set(project["items"], sourceId, newItem)->T.Private.setFieldItems(project, _) - handleNewTopology(project) - } - let getContinues = (project: t, sourceId: string): array => - ProjectItem.getContinues(project->getItem(sourceId)) - - let removeContinues = (project: t, sourceId: string): unit => { - let newItem = project->getItem(sourceId)->ProjectItem.removeContinues - Belt.Map.String.set(project["items"], sourceId, newItem)->T.Private.setFieldItems(project, _) - handleNewTopology(project) - } - - let getContinuation = (project: t, sourceId: string): ProjectItem.T.continuationArgumentType => - project->getItem(sourceId)->ProjectItem.getContinuation - - let setContinuation = ( - project: t, - sourceId: string, - continuation: ProjectItem.T.continuationArgumentType, - ): unit => { - let newItem = project->getItem(sourceId)->ProjectItem.setContinuation(continuation) - Belt.Map.String.set(project["items"], sourceId, newItem)->T.Private.setFieldItems(project, _) - } - - let getResultOption = (project: t, sourceId: string): ProjectItem.T.resultType => - project->getItem(sourceId)->ProjectItem.getResult - - let getResult = (project: t, sourceId: string): ProjectItem.T.resultArgumentType => - switch getResultOption(project, sourceId) { - | None => RENeedToRun->Error - | Some(result) => result - } - - let setResult = (project: t, sourceId: string, value: ProjectItem.T.resultArgumentType): unit => { - let newItem = project->getItem(sourceId)->ProjectItem.setResult(value) - Belt.Map.String.set(project["items"], sourceId, newItem)->T.Private.setFieldItems(project, _) - } - - let parseIncludes = (project: t, sourceId: string): unit => { - let newItem = project->getItem(sourceId)->ProjectItem.parseIncludes - Belt.Map.String.set(project["items"], sourceId, newItem)->T.Private.setFieldItems(project, _) - handleNewTopology(project) - } - - let rawParse = (project: t, sourceId): unit => { - let newItem = project->getItem(sourceId)->ProjectItem.rawParse - Belt.Map.String.set(project["items"], sourceId, newItem)->T.Private.setFieldItems(project, _) - } - - let getStdLib = (project: t): Reducer_Bindings.t => project["stdLib"] - let setStdLib = (project: t, value: Reducer_Bindings.t): unit => - T.Private.setFieldStdLib(project, value) - - let getEnvironment = (project: t): InternalExpressionValue.environment => project["environment"] - let setEnvironment = (project: t, value: InternalExpressionValue.environment): unit => - T.Private.setFieldEnvironment(project, value) - - let getBindings = (project: t, sourceId: string): ProjectItem.T.bindingsArgumentType => { - let those = project->getContinuation(sourceId) - let these = project->getStdLib - let ofUser = Continuation.minus(those, these) - ofUser - } - - let buildProjectAccessors = (project: t): ProjectAccessorsT.t => { - states: {continuation: Bindings.emptyBindings}, - stdLib: getStdLib(project), - environment: getEnvironment(project), - } - - let getContinuationsBefore = (project: t, sourceId: string): array< - ProjectItem.T.continuation, - > => { - let pastNameSpaces = project->getPastChain(sourceId)->Belt.Array.map(getBindings(project, _)) - let theLength = Belt.Array.length(pastNameSpaces) - if theLength == 0 { - // `getContinuationBefore ${sourceId}: stdLib`->Js.log - [project->getStdLib] - } else { - // `getContinuationBefore ${sourceId}: ${lastOne} = ${InternalExpressionValue.toStringBindings( - // project->getBindings(lastOne), - // )}`->Js.log - pastNameSpaces - } - } - - let linkDependencies = (project: t, sourceId: string): ProjectItem.T.continuation => { - module NameSpace = Reducer_Bindings - let continuationsBefore = project->getContinuationsBefore(sourceId) - let nameSpace = NameSpace.emptyNameSpace->NameSpace.chainTo(continuationsBefore) - let includesAsVariables = project->getIncludesAsVariables(sourceId) - Belt.Array.reduce(includesAsVariables, nameSpace, (currentNameSpace, (variable, includeFile)) => - Bindings.set( - currentNameSpace, - variable, - getBindings(project, includeFile)->InternalExpressionValue.IEvBindings, - ) +let linkDependencies = (project: t, sourceId: string): ProjectItem.T.continuation => { + let continuationsBefore = project->getContinuationsBefore(sourceId) + let nameSpace = Reducer_Bindings.makeEmptyBindings()->Reducer_Bindings.chainTo(continuationsBefore) + let includesAsVariables = project->getIncludesAsVariables(sourceId) + Belt.Array.reduce(includesAsVariables, nameSpace, (currentNameSpace, (variable, includeFile)) => + Bindings.set( + currentNameSpace, + variable, + getBindings(project, includeFile)->Reducer_T.IEvBindings, ) - } + ) +} - let doLinkAndRun = (project: t, sourceId: string): unit => { - let accessors = buildProjectAccessors(project) - let states = accessors.states - let continuation = linkDependencies(project, sourceId) - let newItem = project->getItem(sourceId)->ProjectItem.run(continuation, accessors) - Belt.Map.String.set(project["items"], sourceId, newItem)->T.Private.setFieldItems(project, _) - setContinuation(project, sourceId, states.continuation) - } +let doLinkAndRun = (project: t, sourceId: string): unit => { + let context = Reducer_Context.createContext(project->getStdLib, project->getEnvironment) + // FIXME: fill context with dependencies + // let continuation = linkDependencies(project, sourceId) + let newItem = project->getItem(sourceId)->ProjectItem.run(context) + Js.log("after run " ++ newItem.continuation->Reducer_Bindings.toString) + project->setItem(sourceId, newItem) +} - type runState = ProjectItem.T.resultArgumentType +type runState = ProjectItem.T.resultArgumentType - let tryRunWithResult = ( - project: t, - sourceId: string, - rPrevResult: ProjectItem.T.resultArgumentType, - ): ProjectItem.T.resultArgumentType => { - switch getResultOption(project, sourceId) { - | Some(result) => result // already ran - | None => - switch rPrevResult { - | Error(error) => { - setResult(project, sourceId, Error(error)) - Error(error) - } - | Ok(_prevResult) => { - doLinkAndRun(project, sourceId) - getResultOption(project, sourceId)->Belt.Option.getWithDefault(rPrevResult) - } +let tryRunWithResult = ( + project: t, + sourceId: string, + rPrevResult: ProjectItem.T.resultArgumentType, +): ProjectItem.T.resultArgumentType => { + switch getResultOption(project, sourceId) { + | Some(result) => result // already ran + | None => + switch rPrevResult { + | Error(error) => { + setResult(project, sourceId, Error(error)) + Error(error) + } + | Ok(_prevResult) => { + doLinkAndRun(project, sourceId) + getResultOption(project, sourceId)->Belt.Option.getWithDefault(rPrevResult) } } } - - let runAll = (project: t): unit => { - let runOrder = Topology.getRunOrder(project) - let initialState = Ok(InternalExpressionValue.IEvVoid) - let _finalState = Belt.Array.reduce(runOrder, initialState, (currState, currId) => - tryRunWithResult(project, currId, currState) - ) - } - - let run = (project: t, sourceId: string): unit => { - let runOrder = Topology.getRunOrderFor(project, sourceId) - let initialState = Ok(InternalExpressionValue.IEvVoid) - let _finalState = Belt.Array.reduce(runOrder, initialState, (currState, currId) => - tryRunWithResult(project, currId, currState) - ) - } - - let evaluate = (sourceCode: string) => { - let project = createProject() - setSource(project, "main", sourceCode) - runAll(project) - let those = project->getContinuation("main") - let these = project->getStdLib - let ofUser = Continuation.minus(those, these) - - ( - getResultOption(project, "main")->Belt.Option.getWithDefault( - InternalExpressionValue.IEvVoid->Ok, - ), - ofUser, - ) - } +} + +let runAll = (project: t): unit => { + let runOrder = Topology.getRunOrder(project) + let initialState = Ok(Reducer_T.IEvVoid) + let _finalState = Belt.Array.reduce(runOrder, initialState, (currState, currId) => + tryRunWithResult(project, currId, currState) + ) +} + +let run = (project: t, sourceId: string): unit => { + let runOrder = Topology.getRunOrderFor(project, sourceId) + let initialState = Ok(Reducer_T.IEvVoid) + let _finalState = Belt.Array.reduce(runOrder, initialState, (currState, currId) => + tryRunWithResult(project, currId, currState) + ) +} + +let evaluate = (sourceCode: string) => { + let project = createProject() + setSource(project, "main", sourceCode) + runAll(project) + + ( + getResultOption(project, "main")->Belt.Option.getWithDefault( + Reducer_T.IEvVoid->Ok, + ), + project->getBindings("main") + ) } 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 9cc06e8f..ea6c0f1b 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectAccessors_T.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectAccessors_T.res @@ -1,40 +1,30 @@ -module ProjectItemT = ReducerProject_ProjectItem_T -module Bindings = Reducer_Bindings -module ExpressionT = Reducer_Expression_T -module InternalExpressionValue = ReducerInterface_InternalExpressionValue +// module ProjectItemT = ReducerProject_ProjectItem_T +// module InternalExpressionValue = ReducerInterface_InternalExpressionValue -type states = {mutable continuation: ProjectItemT.continuationArgumentType} +// type states = {mutable continuation: ProjectItemT.continuationArgumentType} -type projectAccessors = { - stdLib: Reducer_Bindings.t, - environment: ExpressionT.environment, - states: states, -} +// type projectAccessors = { +// stdLib: Reducer_Bindings.t, +// environment: Reducer_T.environment, +// states: states, +// } -type t = projectAccessors +// type t = projectAccessors -let identityAccessors: t = { - // We need the states at the end of the runtime. - // Accessors can be modified but states will stay as the same pointer - states: { - continuation: Bindings.emptyBindings, - }, - stdLib: ReducerInterface_StdLib.internalStdLib, - environment: InternalExpressionValue.defaultEnvironment, -} +// let identityAccessors: t = { +// // We need the states at the end of the runtime. +// // Accessors can be modified but states will stay as the same pointer +// states: { +// continuation: Reducer_Bindings.emptyBindings, +// }, +// stdLib: ReducerInterface_StdLib.internalStdLib, +// environment: InternalExpressionValue.defaultEnvironment, +// } -let identityAccessorsWithEnvironment = (environment): t => { - states: { - continuation: Bindings.emptyBindings, - }, - stdLib: ReducerInterface_StdLib.internalStdLib, - environment: environment, -} - -// to support change of environment in runtime -let setEnvironment = (this: t, environment: ExpressionT.environment): t => { - { - ...this, - environment: environment, - } -} +// // to support change of environment in runtime +// let setEnvironment = (this: t, environment: Reducer_T.environment): t => { +// { +// ...this, +// 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 8517dd95..b4a5a184 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res @@ -1,69 +1,60 @@ -// TODO: Use actual types instead of aliases in public functions // TODO: Use topological sorting to prevent unnecessary runs -module Bindings = Reducer_Bindings -module Continuation = ReducerInterface_Value_Continuation -module ExpressionT = Reducer_Expression_T -module InternalExpressionValue = ReducerInterface_InternalExpressionValue -module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -module ReducerFnT = ReducerProject_ReducerFn_T module T = ReducerProject_ProjectItem_T type projectItem = T.projectItem type t = T.t -let emptyItem = T.ProjectItem({ +let emptyItem: projectItem = { source: "", rawParse: None, expression: None, - continuation: Bindings.emptyBindings, + continuation: Reducer_Bindings.makeEmptyBindings(), result: None, continues: [], includes: []->Ok, directIncludes: [], includeAsVariables: [], -}) +} // source -> rawParse -> includes -> expression -> continuation -> result -let getSource = (T.ProjectItem(r)): T.sourceType => r.source -let getRawParse = (T.ProjectItem(r)): T.rawParseType => r.rawParse -let getExpression = (T.ProjectItem(r)): T.expressionType => r.expression -let getContinuation = (T.ProjectItem(r)): T.continuationArgumentType => r.continuation -let getResult = (T.ProjectItem(r)): T.resultType => r.result +let getSource = (r: t): T.sourceType => r.source +let getRawParse = (r: t): T.rawParseType => r.rawParse +let getExpression = (r: t): T.expressionType => r.expression +let getContinuation = (r: t): T.continuationArgumentType => r.continuation +let getResult = (r: t): T.resultType => r.result -let getContinues = (T.ProjectItem(r)): T.continuesType => r.continues -let getIncludes = (T.ProjectItem(r)): T.includesType => r.includes -let getDirectIncludes = (T.ProjectItem(r)): array => r.directIncludes -let getIncludesAsVariables = (T.ProjectItem(r)): T.importAsVariablesType => r.includeAsVariables +let getContinues = (r: t): T.continuesType => r.continues +let getIncludes = (r: t): T.includesType => r.includes +let getDirectIncludes = (r: t): array => r.directIncludes +let getIncludesAsVariables = (r: t): T.importAsVariablesType => r.includeAsVariables let touchSource = (this: t): t => { - let T.ProjectItem(r) = emptyItem - T.ProjectItem({ + let r = emptyItem + { ...r, source: getSource(this), continues: getContinues(this), includes: getIncludes(this), includeAsVariables: getIncludesAsVariables(this), directIncludes: getDirectIncludes(this), - }) + } } let touchRawParse = (this: t): t => { - let T.ProjectItem(r) = emptyItem - T.ProjectItem({ - ...r, + { + ...emptyItem, source: getSource(this), continues: getContinues(this), includes: getIncludes(this), includeAsVariables: getIncludesAsVariables(this), directIncludes: getDirectIncludes(this), rawParse: getRawParse(this), - }) + } } let touchExpression = (this: t): t => { - let T.ProjectItem(r) = emptyItem - T.ProjectItem({ - ...r, + { + ...this, source: getSource(this), continues: getContinues(this), includes: getIncludes(this), @@ -71,46 +62,40 @@ let touchExpression = (this: t): t => { directIncludes: getDirectIncludes(this), rawParse: getRawParse(this), expression: getExpression(this), - }) + } } -let resetIncludes = (T.ProjectItem(r): t): t => { - T.ProjectItem({ - ...r, - includes: []->Ok, - includeAsVariables: [], - directIncludes: [], - }) +let resetIncludes = (r: t): t => { + ...r, + includes: []->Ok, + includeAsVariables: [], + directIncludes: [], } -let setSource = (T.ProjectItem(r): t, source: T.sourceArgumentType): t => - T.ProjectItem({...r, source: source})->resetIncludes->touchSource +let setSource = (r: t, source: T.sourceArgumentType): t => + {...r, source: source}->resetIncludes->touchSource -let setRawParse = (T.ProjectItem(r): t, rawParse: T.rawParseArgumentType): t => - T.ProjectItem({...r, rawParse: Some(rawParse)})->touchRawParse +let setRawParse = (r: t, rawParse: T.rawParseArgumentType): t => + {...r, rawParse: Some(rawParse)}->touchRawParse -let setExpression = (T.ProjectItem(r): t, expression: T.expressionArgumentType): t => - T.ProjectItem({...r, expression: Some(expression)})->touchExpression +let setExpression = (r: t, expression: T.expressionArgumentType): t => + {...r, expression: Some(expression)}->touchExpression -let setContinuation = (T.ProjectItem(r): t, continuation: T.continuationArgumentType): t => { - T.ProjectItem({...r, continuation: continuation}) -} +let setContinuation = (r: t, continuation: T.continuationArgumentType): t => + {...r, continuation: continuation} -let setResult = (T.ProjectItem(r): t, result: T.resultArgumentType): t => T.ProjectItem({ +let setResult = (r: t, result: T.resultArgumentType): t => { ...r, result: Some(result), -}) +} let cleanResults = touchExpression let clean = (this: t): t => { - let T.ProjectItem(r) = emptyItem - T.ProjectItem({ - ...r, - source: getSource(this), - continuation: getContinuation(this), - result: getResult(this), - }) + ...this, + source: getSource(this), + continuation: getContinuation(this), + result: getResult(this), } let getImmediateDependencies = (this: t): T.includesType => @@ -120,27 +105,27 @@ let getPastChain = (this: t): array => { Js.Array2.concat(getDirectIncludes(this), getContinues(this)) } -let setContinues = (T.ProjectItem(r): t, continues: array): t => - T.ProjectItem({...r, continues: continues})->touchSource -let removeContinues = (T.ProjectItem(r): t): t => T.ProjectItem({...r, continues: []})->touchSource +let setContinues = (this: t, continues: array): t => + {...this, continues: continues}->touchSource -let setIncludes = (T.ProjectItem(r): t, includes: T.includesType): t => T.ProjectItem({ - ...r, +let removeContinues = (this: t): t => {...this, continues: []}->touchSource + +let setIncludes = (this: t, includes: T.includesType): t => { + ...this, includes: includes, -}) +} let setImportAsVariables = ( - T.ProjectItem(r): t, + this: t, includeAsVariables: T.importAsVariablesType, -): t => T.ProjectItem({...r, includeAsVariables: includeAsVariables}) +): t => {...this, includeAsVariables: includeAsVariables} -let setDirectImports = (T.ProjectItem(r): t, directIncludes: array): t => T.ProjectItem({ - ...r, +let setDirectImports = (this: t, directIncludes: array): t => { + ...this, directIncludes: directIncludes, -}) +} let parseIncludes = (this: t): t => { - let T.ProjectItem(r) = this let rRawImportAsVariables = getSource(this)->ReducerProject_ParseIncludes.parseIncludes switch rRawImportAsVariables { | Error(e) => resetIncludes(this)->setIncludes(Error(e)) @@ -152,12 +137,12 @@ let parseIncludes = (this: t): t => { rawImportAsVariables ->Belt.Array.keep(((variable, _file)) => variable == "") ->Belt.Array.map(((_variable, file)) => file) - T.ProjectItem({ - ...r, + { + ...this, includes: includes, includeAsVariables: includeAsVariables, directIncludes: directIncludes, - }) + } } } } @@ -172,45 +157,48 @@ let doBuildExpression = (this: t): T.expressionType => ->Belt.Option.map(o => o->Belt.Result.map(r => r->Reducer_Peggy_ToExpression.fromNode)) let buildExpression = (this: t): t => { - let withRawParse: t = this->rawParse - switch withRawParse->getExpression { - | Some(_) => withRawParse + let this = this->rawParse + switch this->getExpression { + | Some(_) => this // cached | None => - withRawParse + this ->doBuildExpression - ->Belt.Option.map(setExpression(withRawParse, _)) - ->E.O2.defaultFn(() => withRawParse) + ->Belt.Option.map(setExpression(this, _)) + ->E.O2.defaultFn(() => this) } } -let doBuildResult = ( +let failRun = ( this: t, - aContinuation: T.continuation, - accessors: ProjectAccessorsT.t, -): T.resultType => - this - ->getExpression - ->Belt.Option.map( - Belt.Result.flatMap(_, expression => - try { - Reducer_Expression.reduceExpressionInProject(expression, aContinuation, accessors)->Ok - } catch { - | Reducer_ErrorValue.ErrorException(e) => e->Error - | _ => RETodo("unhandled rescript exception")->Error - } - ), - ) + e: Reducer_ErrorValue.errorValue +): t => this->setResult(e->Error)->setContinuation(Reducer_Bindings.makeEmptyBindings()) -let buildResult = (this: t, aContinuation: T.continuation, accessors: ProjectAccessorsT.t): t => { - let withExpression: t = this->buildExpression - switch withExpression->getResult { - | Some(_) => withExpression - | None => - withExpression - ->doBuildResult(aContinuation, accessors) - ->Belt.Option.map(setResult(withExpression, _)) - ->E.O2.defaultFn(() => withExpression) +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) + } + } + | None => this->failRun(RETodo("attempt to run without expression")) + } + +let run = (this: t, context: Reducer_T.context): t => { + let this = this->buildExpression + switch this->getResult { + | Some(_) => this + | None => this->doRun(context) } } - -let run = buildResult diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem_T.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem_T.res index caa80da4..e696534e 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem_T.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem_T.res @@ -1,6 +1,5 @@ module Parse = Reducer_Peggy_Parse module ExpressionT = Reducer_Expression_T -module InternalExpressionValue = ReducerInterface_InternalExpressionValue open Reducer_ErrorValue type sourceArgumentType = string @@ -9,13 +8,13 @@ type rawParseArgumentType = result type rawParseType = option type expressionArgumentType = result type expressionType = option -type continuation = InternalExpressionValue.nameSpace -type continuationArgumentType = InternalExpressionValue.nameSpace +type continuation = Reducer_T.nameSpace +type continuationArgumentType = Reducer_T.nameSpace type continuationType = option type continuationResultType = option> -type bindingsArgumentType = InternalExpressionValue.nameSpace +type bindingsArgumentType = Reducer_T.nameSpace type bindingsType = option -type resultArgumentType = result +type resultArgumentType = result type resultType = option type continuesArgumentType = array type continuesType = array @@ -23,17 +22,16 @@ type includesArgumentType = string type includesType = result, errorValue> type importAsVariablesType = array<(string, string)> -type projectItem = - | ProjectItem({ - source: sourceType, - rawParse: rawParseType, - expression: expressionType, - continuation: continuationArgumentType, - result: resultType, - continues: continuesType, - includes: includesType, //For loader - includeAsVariables: importAsVariablesType, //For linker - directIncludes: array, - }) //For linker +type projectItem = { + source: sourceType, + rawParse: rawParseType, + expression: expressionType, + continuation: continuationArgumentType, + result: resultType, + continues: continuesType, + includes: includesType, //For loader + includeAsVariables: importAsVariablesType, //For linker + directIncludes: array, +} type t = projectItem diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ReducerFn_T.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ReducerFn_T.res deleted file mode 100644 index 2dc926be..00000000 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ReducerFn_T.res +++ /dev/null @@ -1,5 +0,0 @@ -module ExpressionT = Reducer_Expression_T -module InternalExpressionValue = ReducerInterface_InternalExpressionValue -module ProjectAccessorsT = ReducerProject_ProjectAccessors_T - -type t = (ExpressionT.t, ExpressionT.bindings, ProjectAccessorsT.t) => InternalExpressionValue.t diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res index e1ec91f4..78a3e2a3 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res @@ -1,37 +1,17 @@ module ProjectItem = ReducerProject_ProjectItem module ExpressionT = Reducer_Expression_T -module ProjectAccessorsT = ReducerProject_ProjectAccessors_T @genType.opaque -type project = {"iAmProject": bool} -//re-export -@genType +type project = { + items: Belt.MutableMap.String.t, + mutable stdLib: Reducer_Bindings.t, + mutable environment: ExpressionT.environment, + mutable previousRunOrder: array, +} type t = project -module Private = { - type internalProject = { - "iAmProject": bool, - "items": Belt.Map.String.t, - "stdLib": Reducer_Bindings.t, - "environment": ExpressionT.environment, - "previousRunOrder": array, - } - type t = internalProject +// these functions are used in ReducerProject_Topology, so they are defined here to avoid circular dependencies +let getSourceIds = (project: t): array => Belt.MutableMap.String.keysToArray(project.items) - @set - external setFieldItems: (t, Belt.Map.String.t) => unit = "items" - @set - external setFieldStdLib: (t, Reducer_Bindings.t) => unit = "stdLib" - @set - external setFieldEnvironment: (t, ExpressionT.environment) => unit = "environment" - @set - external setFieldPreviousRunOrder: (t, array) => unit = "previousRunOrder" - - external castFromInternalProject: t => project = "%identity" - external castToInternalProject: project => t = "%identity" - - let getSourceIds = (this: t): array => Belt.Map.String.keysToArray(this["items"]) - - let getItem = (this: t, sourceId: string) => - Belt.Map.String.getWithDefault(this["items"], sourceId, ProjectItem.emptyItem) -} +let getItem = (project: t, sourceId: string) => + Belt.MutableMap.String.getWithDefault(project.items, sourceId, ProjectItem.emptyItem) diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_Topology.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_Topology.res index 20491678..0cb807dc 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_Topology.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_Topology.res @@ -1,12 +1,12 @@ module ProjectItem = ReducerProject_ProjectItem module T = ReducerProject_T -type t = T.Private.t +type t = T.t -let getSourceIds = T.Private.getSourceIds -let getItem = T.Private.getItem +let getSourceIds = T.getSourceIds +let getItem = T.getItem let getImmediateDependencies = (this: t, sourceId: string): ProjectItem.T.includesType => - getItem(this, sourceId)->ProjectItem.getImmediateDependencies + this->getItem(sourceId)->ProjectItem.getImmediateDependencies type topologicalSortState = (Belt.Map.String.t, list) let rec topologicalSortUtil = ( @@ -31,7 +31,7 @@ let rec topologicalSortUtil = ( } let getTopologicalSort = (this: t): array => { - let (_visited, stack) = getSourceIds(this)->Belt.Array.reduce((Belt.Map.String.empty, list{}), ( + let (_visited, stack) = this->getSourceIds->Belt.Array.reduce((Belt.Map.String.empty, list{}), ( (currVisited, currStack), currId, ) => diff --git a/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Math.res b/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Math.res index 14668a52..7d79b613 100644 --- a/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Math.res +++ b/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Math.res @@ -15,7 +15,7 @@ let availableNumbers: array<(string, float)> = [ let mathBindings: Bindings.t = availableNumbers - ->E.A2.fmap(((name, v)) => (name, ReducerInterface_InternalExpressionValue.IEvNumber(v))) + ->E.A2.fmap(((name, v)) => (name, Reducer_T.IEvNumber(v))) ->Bindings.fromArray let makeBindings = (previousBindings: Bindings.t): Bindings.t => diff --git a/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Versions.res b/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Versions.res index a54eab14..028e4b3f 100644 --- a/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Versions.res +++ b/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Versions.res @@ -1,9 +1,9 @@ module Bindings = Reducer_Bindings -let bindings: Bindings.t = +let bindings: Reducer_T.nameSpace = [ - ("System.version", ReducerInterface_InternalExpressionValue.IEvString("0.4.0-dev")), + ("System.version", Reducer_T.IEvString("0.4.0-dev")), ]->Bindings.fromArray -let makeBindings = (previousBindings: Bindings.t): Bindings.t => +let makeBindings = (previousBindings: Reducer_T.nameSpace): Reducer_T.nameSpace => previousBindings->Bindings.mergeFrom(bindings) From f2dccd4f1ea3a72d55afd7814e7100c6ace80562 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Sun, 11 Sep 2022 20:57:28 +0400 Subject: [PATCH 03/46] still WIP, FR works --- .../SquiggleViewer/ExpressionViewer.tsx | 34 +++++++++---------- .../Reducer_Expression/Reducer_Expression.res | 6 ++-- .../Reducer_Expression_Lambda.res | 11 +++--- .../Reducer_Peggy_GeneratedParser.peggy | 23 +++---------- .../src/rescript/Reducer/Reducer_T.res | 11 +++--- ...ducerInterface_InternalExpressionValue.res | 5 +-- .../ReducerInterface_StdLib.res | 34 +++++++++++++++++-- .../ReducerProject/ReducerProject.res | 2 +- .../src/rescript/Utility/Mathjs.res | 16 ++++----- 9 files changed, 77 insertions(+), 65 deletions(-) diff --git a/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx b/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx index 1aa106c8..1ef5e150 100644 --- a/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx +++ b/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx @@ -135,23 +135,23 @@ export const ExpressionViewer: React.FC = ({ value, width }) => { {() => value.value.toString()} ); - case SqValueTag.Symbol: - return ( - - {() => ( - <> - Undefined Symbol: - {value.value} - - )} - - ); - case SqValueTag.Call: - return ( - - {() => value.value} - - ); + // case SqValueTag.Symbol: + // return ( + // + // {() => ( + // <> + // Undefined Symbol: + // {value.value} + // + // )} + // + // ); + // case SqValueTag.Call: + // return ( + // + // {() => value.value} + // + // ); case SqValueTag.ArrayString: return ( 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 1bfd330d..62a1f200 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res @@ -14,7 +14,7 @@ let rec evaluate: T.reducerFn = ( expression, context ) => { - Js.log(`reduce: ${expression->Reducer_Expression_T.toString}`) + // Js.log(`reduce: ${expression->Reducer_Expression_T.toString}`) switch expression { | T.EBlock(statements) => { let innerContext = {...context, bindings: context.bindings->Bindings.extend} @@ -25,12 +25,12 @@ let rec evaluate: T.reducerFn = ( } | T.EProgram(statements) => { - Js.log(`bindings: ${context.bindings->Reducer_Bindings.toString}`) + // Js.log(`bindings: ${context.bindings->Reducer_Bindings.toString}`) let res = statements->Js.Array2.reduce( (acc, statement) => statement->evaluate(context), T.IEvVoid ) - Js.log(`bindings after: ${context.bindings->Reducer_Bindings.toString}`) + // Js.log(`bindings after: ${context.bindings->Reducer_Bindings.toString}`) res } 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 8316998c..e9460f69 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 @@ -43,11 +43,14 @@ let makeLambda = ( reducer(body, { bindings: localBindings, environment }) } - LNoFFI({ - context: bindings, + { + // context: bindings, body: lambda, parameters, - }) + } } -let makeFFILambda = () => raise(Not_found) +let makeFFILambda = (body: Reducer_T.lambdaBody): Reducer_T.lambdaValue => { + body, + parameters: ["..."] +} diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy index a8c61d59..4beba469 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy @@ -11,25 +11,10 @@ zeroOMoreArgumentsBlockOrExpression = innerBlockOrExpression / lambda outerBlock = statements:array_statements finalExpression: (statementSeparator @expression)? - { if (finalExpression) statements.push(finalExpression) - return h.nodeProgram(statements) } - // / '{' _nl finalExpression: expression _nl '}' - // { return h.nodeBlock([finalExpression]) } - // { if (finalExpression != null) - // { - // var newFinalExpression = h.makeFunctionCall('$_endOfOuterBlock_$', [h.nodeVoid(), finalExpression]); - // statements.push(newFinalExpression); - // } - // else - // { - // var newFinalStatement = h.makeFunctionCall('$_endOfOuterBlock_$', [h.nodeVoid(), h.nodeVoid()]); - // statements.push(newFinalStatement); - // } - // return h.nodeBlock(statements) } - // / finalExpression: expression - // { - // var newFinalExpression = h.makeFunctionCall('$_endOfOuterBlock_$', [h.nodeVoid(), finalExpression]); - // return h.nodeBlock([newFinalExpression])} + { if (finalExpression) statements.push(finalExpression) + return h.nodeProgram(statements) } + / finalExpression: expression + { return h.nodeProgram([finalExpression]) } innerBlockOrExpression = quotedInnerBlock diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res index 19eedf39..a70e0183 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res @@ -22,16 +22,13 @@ type rec value = @genType.opaque and arrayValue = array @genType.opaque and map = Belt.Map.String.t @genType.opaque and nameSpace = NameSpace(Belt.MutableMap.String.t, option) +and lambdaBody = (array, environment, reducerFn) => value @genType.opaque -and lambdaValue = - | LNoFFI({ +and lambdaValue = { parameters: array, - context: nameSpace, + // context: nameSpace, body: (array, environment, reducerFn) => value, - }) - | LFFI({ - body: (array, environment, reducerFn) => value, - }) + } @genType.opaque and lambdaDeclaration = Declaration.declaration and expression = | EBlock(array) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res index 661b69e1..9eacb8df 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res @@ -49,10 +49,7 @@ and toStringDate = date => DateTime.Date.toString(date) and toStringDeclaration = d => Declaration.toString(d, r => toString(IEvLambda(r))) and toStringDistribution = dist => GenericDist.toString(dist) and toStringLambda = (lambdaValue: T.lambdaValue) => - switch lambdaValue { - | LNoFFI({ parameters }) => `lambda(${parameters->Js.Array2.toString}=>internal code)` // TODO - serialize code too? - | LFFI(_) => `standard function` // TODO - serialize name, etc? - } + `lambda(${Js.Array2.toString(lambdaValue.parameters)}=>internal code)` and toStringFunction = (lambdaValue: T.lambdaValue) => `function(${Js.Array2.toString(lambdaValue.parameters)})` and toStringNumber = aNumber => Js.String.make(aNumber) and toStringRecord = aMap => aMap->toStringMap diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res index 3a8c41cc..81daff42 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res @@ -1,4 +1,34 @@ -let internalStdLib: Reducer_Bindings.t = - Reducer_Bindings.makeEmptyBindings() +let internalStdLib: Reducer_Bindings.t = { + 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) + + 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.dispatch((name, arguments), environment, reducer) { + | Some(result) => { + switch result { + | Ok(value) => value + | Error(error) => error->Reducer_ErrorValue.ErrorException->raise + } + } + | None => Reducer_ErrorValue.RESymbolNotFound("Not found in registry")->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 bb314f80..5e7632b0 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res @@ -193,7 +193,7 @@ let doLinkAndRun = (project: t, sourceId: string): unit => { // FIXME: fill context with dependencies // let continuation = linkDependencies(project, sourceId) let newItem = project->getItem(sourceId)->ProjectItem.run(context) - Js.log("after run " ++ newItem.continuation->Reducer_Bindings.toString) + // Js.log("after run " ++ newItem.continuation->Reducer_Bindings.toString) project->setItem(sourceId, newItem) } diff --git a/packages/squiggle-lang/src/rescript/Utility/Mathjs.res b/packages/squiggle-lang/src/rescript/Utility/Mathjs.res index 5e1be176..4a792af4 100644 --- a/packages/squiggle-lang/src/rescript/Utility/Mathjs.res +++ b/packages/squiggle-lang/src/rescript/Utility/Mathjs.res @@ -1,9 +1,9 @@ -@module("./MathjsWrapper.js") -external parseMathExt: string => Js.Json.t = "parseMath" +// @module("./MathjsWrapper.js") +// external parseMathExt: string => Js.Json.t = "parseMath" -let parseMath = (str: string): result => - switch parseMathExt(str) { - | exception Js.Exn.Error(err) => Error(Js.Exn.message(err) |> E.O.default("MathJS Parse Error")) - | exception _ => Error("MathJS Parse Error") - | j => Ok(j) - } +// let parseMath = (str: string): result => +// switch parseMathExt(str) { +// | exception Js.Exn.Error(err) => Error(Js.Exn.message(err) |> E.O.default("MathJS Parse Error")) +// | exception _ => Error("MathJS Parse Error") +// | j => Ok(j) +// } From fea89abff927aab1cc52a213f0036ca8cf0ab35c Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Sun, 11 Sep 2022 23:56:07 +0400 Subject: [PATCH 04/46] more WIP --- .../FunctionRegistry_Library.res | 1 + .../FunctionRegistry/Library/FR_Builtin.res | 51 +++++++++++++++++++ .../Reducer_Dispatch_BuiltIn.res | 44 +++++++--------- .../Reducer_Expression/Reducer_Expression.res | 16 ++++-- .../Reducer_Expression_ExpressionBuilder.res | 2 +- .../Reducer_Peggy/Reducer_Peggy_Parse.res | 17 ++++++- .../Reducer_Peggy_ToExpression.res | 11 ++++ .../rescript/Reducer/Reducer_Peggy/helpers.ts | 20 ++++++-- .../src/rescript/Reducer/Reducer_T.res | 2 +- .../ReducerInterface_StdLib.res | 47 +++++++++++++++++ 10 files changed, 175 insertions(+), 36 deletions(-) create mode 100644 packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res index 3714b0b7..d8c2c04b 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res @@ -1,4 +1,5 @@ let fnList = Belt.Array.concatMany([ + FR_Builtin.library, FR_Dict.library, FR_Dist.library, FR_Danger.library, diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res new file mode 100644 index 00000000..6bced75d --- /dev/null +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res @@ -0,0 +1,51 @@ +open FunctionRegistry_Core +open FunctionRegistry_Helpers + +let nameSpace = "Builtin" + +type simpleDefinition = { + inputs: array, + fn: (array) => result, +} + +let makeFnMany = (name: string, definitions: array) => + Function.make( + ~name=name, + ~nameSpace, + ~requiresNamespace=false, + ~definitions=definitions->Js.Array2.map( + ({ inputs, fn }) => FnDefinition.make( + ~name=name, + ~inputs=inputs, + ~run=(inputs, _, _, _) => fn(inputs), + () + ) + ), + (), + ) + +let makeFn = (name: string, inputs: array, fn: (array) => result) => + makeFnMany(name, [{ inputs, fn }]) + +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) + } + }, + () + ), + ], + (), + ), +] 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 1ae512db..72c8aa79 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 @@ -45,11 +45,11 @@ let callInternal = ( ->Ok } - let arrayAtIndex = (aValueArray: array, fIndex: float) => - switch Belt.Array.get(aValueArray, Belt.Int.fromFloat(fIndex)) { - | Some(value) => value->Ok - | None => REArrayIndexNotFound("Array index not found", Belt.Int.fromFloat(fIndex))->Error - } + // let arrayAtIndex = (aValueArray: array, fIndex: float) => + // switch Belt.Array.get(aValueArray, Belt.Int.fromFloat(fIndex)) { + // | Some(value) => value->Ok + // | None => REArrayIndexNotFound("Array index not found", Belt.Int.fromFloat(fIndex))->Error + // } let moduleAtIndex = (nameSpace: Reducer_T.nameSpace, sIndex) => switch Bindings.get(nameSpace, sIndex) { @@ -57,11 +57,11 @@ let callInternal = ( | None => RERecordPropertyNotFound("Bindings property not found", sIndex)->Error } - let recordAtIndex = (dict: Belt.Map.String.t, sIndex) => - switch Belt.Map.String.get(dict, sIndex) { - | Some(value) => value->Ok - | None => RERecordPropertyNotFound("Record property not found", sIndex)->Error - } + // let recordAtIndex = (dict: Belt.Map.String.t, sIndex) => + // switch Belt.Map.String.get(dict, sIndex) { + // | Some(value) => value->Ok + // | None => RERecordPropertyNotFound("Record property not found", sIndex)->Error + // } let doAddArray = (originalA, b) => { let a = originalA->Js.Array2.copy @@ -107,10 +107,10 @@ let callInternal = ( // } switch call { - | ("$_atIndex_$", [IEvArray(aValueArray), IEvNumber(fIndex)]) => arrayAtIndex(aValueArray, fIndex) + // | ("$_atIndex_$", [IEvArray(aValueArray), IEvNumber(fIndex)]) => arrayAtIndex(aValueArray, fIndex) | ("$_atIndex_$", [IEvBindings(dict), IEvString(sIndex)]) => moduleAtIndex(dict, sIndex) - | ("$_atIndex_$", [IEvRecord(dict), IEvString(sIndex)]) => recordAtIndex(dict, sIndex) - | ("$_constructArray_$", args) => IEvArray(args)->Ok + // | ("$_atIndex_$", [IEvRecord(dict), IEvString(sIndex)]) => recordAtIndex(dict, sIndex) + // | ("$_constructArray_$", args) => IEvArray(args)->Ok | ("$_constructRecord_$", [IEvArray(arrayOfPairs)]) => constructRecord(arrayOfPairs) // | ("$_exportBindings_$", [IEvBindings(nameSpace)]) => doExportBindings(nameSpace) // | ("$_exportBindings_$", [evValue]) => doIdentity(evValue) @@ -167,18 +167,12 @@ let dispatch = ( ): Reducer_T.value => try { let (fn, args) = call - if fn->Js.String2.startsWith("$") { - switch callInternal((fn, args), env, reducer) { - | Ok(v) => v - | Error(e) => raise(ErrorException(e)) - } - } else { - // There is a bug that prevents string match in patterns - // So we have to recreate a copy of the string - switch ExternalLibrary.dispatch((Js.String.make(fn), args), env, reducer, callInternal) { - | Ok(v) => v - | Error(e) => raise(ErrorException(e)) - } + + // There is a bug that prevents string match in patterns + // So we have to recreate a copy of the string + switch ExternalLibrary.dispatch((Js.String.make(fn), args), env, reducer, callInternal) { + | Ok(v) => v + | Error(e) => raise(ErrorException(e)) } } catch { | ErrorException(e) => raise(ErrorException(e)) 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 62a1f200..ecf6c29a 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 @@ -19,7 +19,7 @@ let rec evaluate: T.reducerFn = ( | T.EBlock(statements) => { let innerContext = {...context, bindings: context.bindings->Bindings.extend} statements->Js.Array2.reduce( - (acc, statement) => statement->evaluate(innerContext), + (_, statement) => statement->evaluate(innerContext), T.IEvVoid ) } @@ -27,7 +27,7 @@ let rec evaluate: T.reducerFn = ( | T.EProgram(statements) => { // Js.log(`bindings: ${context.bindings->Reducer_Bindings.toString}`) let res = statements->Js.Array2.reduce( - (acc, statement) => statement->evaluate(context), + (_, statement) => statement->evaluate(context), T.IEvVoid ) // Js.log(`bindings after: ${context.bindings->Reducer_Bindings.toString}`) @@ -37,8 +37,16 @@ let rec evaluate: T.reducerFn = ( | T.EArray(elements) => elements->Js.Array2.map(element => evaluate(element, context))->T.IEvArray - | T.ERecord(map) => - RETodo("TODO")->ErrorException->raise + | 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) => { let result = right->evaluate(context) 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 f45125c7..b11baa6e 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 @@ -24,7 +24,7 @@ let eLambda = ( let eNumber = aNumber => aNumber->T.IEvNumber->T.EValue -let eRecord = aMap => aMap->T.IEvRecord->T.EValue +let eRecord = (aMap: array<(T.expression, T.expression)>) => aMap->T.ERecord let eString = aString => aString->T.IEvString->T.EValue 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 b5099c36..58bfbb70 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 @@ -21,12 +21,14 @@ let parse = (expr: string): result => type nodeBlock = {...node, "statements": array} type nodeProgram = {...node, "statements": array} +type nodeArray = {...node, "elements": array} type nodeBoolean = {...node, "value": bool} type nodeCall = {...node, "fn": node, "args": array} type nodeFloat = {...node, "value": float} type nodeIdentifier = {...node, "value": string} type nodeInteger = {...node, "value": int} type nodeKeyValue = {...node, "key": node, "value": node} +type nodeRecord = {...node, "elements": array} type nodeLambda = {...node, "args": array, "body": nodeBlock} type nodeLetStatement = {...node, "variable": nodeIdentifier, "value": node} type nodeModuleIdentifier = {...node, "value": string} @@ -37,7 +39,9 @@ type nodeVoid = node type peggyNode = | PgNodeBlock(nodeBlock) - | PgNodeProgram(nodeBlock) + | PgNodeProgram(nodeProgram) + | PgNodeArray(nodeArray) + | PgNodeRecord(nodeRecord) | PgNodeBoolean(nodeBoolean) | PgNodeFloat(nodeFloat) | PgNodeCall(nodeCall) @@ -54,6 +58,8 @@ type peggyNode = external castNodeBlock: node => nodeBlock = "%identity" external castNodeProgram: node => nodeProgram = "%identity" +external castNodeArray: node => nodeArray = "%identity" +external castNodeRecord: node => nodeRecord = "%identity" external castNodeBoolean: node => nodeBoolean = "%identity" external castNodeCall: node => nodeCall = "%identity" external castNodeFloat: node => nodeFloat = "%identity" @@ -73,6 +79,8 @@ let castNodeType = (node: node) => switch node["type"] { | "Block" => node->castNodeBlock->PgNodeBlock | "Program" => node->castNodeBlock->PgNodeProgram + | "Array" => node->castNodeArray->PgNodeArray + | "Record" => node->castNodeRecord->PgNodeRecord | "Boolean" => node->castNodeBoolean->PgNodeBoolean | "Call" => node->castNodeCall->PgNodeCall | "Float" => node->castNodeFloat->PgNodeFloat @@ -96,10 +104,17 @@ let rec pgToString = (peggyNode: peggyNode): string => { let nodesToStringUsingSeparator = (nodes: array, separator: string): string => nodes->Js.Array2.map(toString)->Extra.Array.intersperse(separator)->Js.String.concatMany("") + let pgNodesToStringUsingSeparator = (nodes: array, separator: string): string => + nodes->Js.Array2.map(pgToString)->Extra.Array.intersperse(separator)->Js.String.concatMany("") + 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(", ") ++ "}" | PgNodeBoolean(node) => node["value"]->Js.String.make | PgNodeCall(node) => "(" ++ node["fn"]->toString ++ " " ++ node["args"]->nodesToStringUsingSeparator(" ") ++ ")" | PgNodeFloat(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 3b997440..c1823f5c 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 @@ -18,11 +18,22 @@ let rec fromNode = (node: Parse.node): expression => { let body = nodeLambda["body"]->caseBlock ExpressionBuilder.eLambda(args, body) + + } + + let caseRecord = (nodeRecord): expression => { + nodeRecord["elements"] + ->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)) + | PgNodeRecord(nodeRecord) => caseRecord(nodeRecord) | PgNodeBoolean(nodeBoolean) => ExpressionBuilder.eBool(nodeBoolean["value"]) | PgNodeCall(nodeCall) => ExpressionBuilder.eCall(fromNode(nodeCall["fn"]), nodeCall["args"]->Js.Array2.map(fromNode)) | PgNodeFloat(nodeFloat) => ExpressionBuilder.eNumber(nodeFloat["value"]) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts index ebf6dd2e..4dd66205 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts @@ -45,6 +45,16 @@ type NodeProgram = { statements: AnyPeggyNode[]; }; +type NodeArray = { + type: "Array"; + elements: AnyPeggyNode[]; +}; + +type NodeRecord = { + type: "Record"; + elements: NodeKeyValue[]; +}; + type NodeCall = { type: "Call"; fn: AnyPeggyNode; @@ -103,6 +113,8 @@ type NodeBoolean = { }; export type AnyPeggyNode = + | NodeArray + | NodeRecord | NodeBlock | NodeProgram | NodeCall @@ -124,11 +136,11 @@ export function makeFunctionCall(fn: string, args: AnyPeggyNode[]) { } } -export function constructArray(elems: AnyPeggyNode[]) { - return makeFunctionCall("$_constructArray_$", elems); +export function constructArray(elements: AnyPeggyNode[]) { + return { type: "Array", elements }; } -export function constructRecord(elems: AnyPeggyNode[]) { - return makeFunctionCall("$_constructRecord_$", elems); +export function constructRecord(elements: AnyPeggyNode[]) { + return { type: "Record", elements }; } export function nodeBlock(statements: AnyPeggyNode[]): NodeBlock { diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res index a70e0183..a207f69c 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res @@ -34,7 +34,7 @@ and expression = | EBlock(array) | EProgram(array) // programs are similar to blocks, but don't create an inner scope. there can be only one program at the top level of the expression. | EArray(array) - | ERecord(Belt.Map.String.t) + | ERecord(array<(expression, expression)>) | ESymbol(string) | ETernary(expression, expression, expression) | EAssign(string, expression) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res index 81daff42..2e356984 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res @@ -1,3 +1,5 @@ +exception ErrorException = Reducer_ErrorValue.ErrorException + let internalStdLib: Reducer_Bindings.t = { let res = Reducer_Bindings.makeEmptyBindings() ->SquiggleLibrary_Math.makeBindings @@ -12,6 +14,51 @@ let internalStdLib: Reducer_Bindings.t = { } )->Reducer_T.IEvLambda) + 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)) { + | Some(value) => value + | None => REArrayIndexNotFound("Array index not found", Belt.Int.fromFloat(fIndex))->ErrorException->raise + } + } + | [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) + + // 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( From 6dc1cea045584b916caf7fc7a445995f1b281239 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Mon, 12 Sep 2022 03:07:34 +0400 Subject: [PATCH 05/46] more WIP --- .../FunctionRegistry_Core.res | 291 +++--------------- .../FunctionRegistry_Library.res | 2 +- .../FunctionRegistry/Library/FR_Builtin.res | 22 ++ .../Reducer_Peggy_GeneratedParser.peggy | 2 +- .../Reducer_Peggy/Reducer_Peggy_Parse.res | 4 +- .../Reducer_Peggy_ToExpression.res | 2 +- .../ReducerInterface_ExternalLibrary.res | 2 +- .../ReducerInterface_StdLib.res | 11 +- 8 files changed, 72 insertions(+), 264 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res index e217cad9..145c9a60 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res @@ -62,7 +62,7 @@ type function = { isExperimental: bool, } -type fnNameDict = Js.Dict.t> +type fnNameDict = Js.Dict.t> type registry = {functions: array, fnNameDict: fnNameDict} module FRType = { @@ -181,188 +181,6 @@ module FRType = { } } -/* - This module, Matcher, is fairly lengthy. However, only two functions from it - are meant to be used outside of it. These are findMatches and matchToDef in Matches.Registry. - The rest of it is just called from those two functions. - - Update: This really should be completely re-done sometime, and tested. It works, but it's pretty messy. I'm sure - there are internal bugs, but the end functionality works, so I'm not too worried. -*/ -module Matcher = { - module MatchSimple = { - type t = DifferentName | SameNameDifferentArguments | FullMatch - - let isFullMatch = (match: t) => - switch match { - | FullMatch => true - | _ => false - } - - let isNameMatchOnly = (match: t) => - switch match { - | SameNameDifferentArguments => true - | _ => false - } - } - - module Match = { - type t<'a, 'b> = DifferentName | SameNameDifferentArguments('a) | FullMatch('b) - - let isFullMatch = (match: t<'a, 'b>): bool => - switch match { - | FullMatch(_) => true - | _ => false - } - - let isNameMatchOnly = (match: t<'a, 'b>) => - switch match { - | SameNameDifferentArguments(_) => true - | _ => false - } - } - - module FnDefinition = { - let matchAssumingSameName = (f: fnDefinition, args: array) => { - switch FRType.matchWithExpressionValueArray(f.inputs, args) { - | Some(_) => MatchSimple.FullMatch - | None => MatchSimple.SameNameDifferentArguments - } - } - - let match = (f: fnDefinition, fnName: string, args: array) => { - if f.name !== fnName { - MatchSimple.DifferentName - } else { - matchAssumingSameName(f, args) - } - } - } - - module Function = { - type definitionId = int - type match = Match.t, definitionId> - - let match = ( - f: function, - nameSpace: option, - fnName: string, - args: array, - ): match => { - switch nameSpace { - | Some(ns) if ns !== f.nameSpace => Match.DifferentName - | _ => { - let matchedDefinition = () => - E.A.getIndexBy(f.definitions, r => - MatchSimple.isFullMatch(FnDefinition.match(r, fnName, args)) - ) |> E.O.fmap(r => Match.FullMatch(r)) - let getMatchedNameOnlyDefinition = () => { - let nameMatchIndexes = - f.definitions - ->E.A2.fmapi((index, r) => - MatchSimple.isNameMatchOnly(FnDefinition.match(r, fnName, args)) - ? Some(index) - : None - ) - ->E.A.O.concatSomes - switch nameMatchIndexes { - | [] => None - | elements => Some(Match.SameNameDifferentArguments(elements)) - } - } - - E.A.O.firstSomeFnWithDefault( - [matchedDefinition, getMatchedNameOnlyDefinition], - Match.DifferentName, - ) - } - } - } - } - - module RegistryMatch = { - type match = { - nameSpace: string, - fnName: string, - inputIndex: int, - } - let makeMatch = (nameSpace: string, fnName: string, inputIndex: int) => { - nameSpace: nameSpace, - fnName: fnName, - inputIndex: inputIndex, - } - } - - module Registry = { - let _findExactMatches = ( - r: registry, - nameSpace: option, - fnName: string, - args: array, - ) => { - let functionMatchPairs = - r.functions->E.A2.fmap(l => (l, Function.match(l, nameSpace, fnName, args))) - let fullMatch = functionMatchPairs->E.A.getBy(((_, match)) => Match.isFullMatch(match)) - fullMatch->E.O.bind(((fn, match)) => - switch match { - | FullMatch(index) => Some(RegistryMatch.makeMatch(fn.nameSpace, fn.name, index)) - | _ => None - } - ) - } - - let _findNameMatches = ( - r: registry, - nameSpace: option, - fnName: string, - args: array, - ) => { - let functionMatchPairs = - r.functions->E.A2.fmap(l => (l, Function.match(l, nameSpace, fnName, args))) - let getNameMatches = - functionMatchPairs - ->E.A2.fmap(((fn, match)) => Match.isNameMatchOnly(match) ? Some((fn, match)) : None) - ->E.A.O.concatSomes - let matches = - getNameMatches - ->E.A2.fmap(((fn, match)) => - switch match { - | SameNameDifferentArguments(indexes) => - indexes->E.A2.fmap(index => RegistryMatch.makeMatch(fn.nameSpace, fn.name, index)) - | _ => [] - } - ) - ->Belt.Array.concatMany - E.A.toNoneIfEmpty(matches) - } - - let findMatches = (r: registry, fnName: string, args: array) => { - let fnNameInParts = Js.String.split(".", fnName) - let fnToSearch = E.A.get(fnNameInParts, 1) |> E.O.default(fnNameInParts[0]) - let nameSpace = E.A.length(fnNameInParts) > 1 ? Some(fnNameInParts[0]) : None - - switch _findExactMatches(r, nameSpace, fnToSearch, args) { - | Some(r) => Match.FullMatch(r) - | None => - switch _findNameMatches(r, nameSpace, fnToSearch, args) { - | Some(r) => Match.SameNameDifferentArguments(r) - | None => Match.DifferentName - } - } - } - - let matchToDef = ( - registry: registry, - {nameSpace, fnName, inputIndex}: RegistryMatch.match, - ): option => - registry.functions - ->E.A.getBy(fn => { - nameSpace === fn.nameSpace && fnName === fn.name - }) - ->E.O.bind(fn => E.A.get(fn.definitions, inputIndex)) - } -} - module FnDefinition = { type t = fnDefinition @@ -440,13 +258,6 @@ module Function = { } } -module NameSpace = { - type t = {name: string, functions: array} - let definitions = (t: t) => t.functions->E.A2.fmap(f => f.definitions)->E.A.concatMany - let uniqueFnNames = (t: t) => definitions(t)->E.A2.fmap(r => r.name)->E.A.uniq - let nameToDefinitions = (t: t, name: string) => definitions(t)->E.A2.filter(r => r.name == name) -} - module Registry = { let toJson = (r: registry) => r.functions->E.A2.fmap(Function.toJson) let allExamples = (r: registry) => r.functions->E.A2.fmap(r => r.examples)->E.A.concatMany @@ -454,29 +265,24 @@ module Registry = { r.functions->E.A2.fmap(fn => fn.examples->E.A2.fmap(example => (fn, example)))->E.A.concatMany let _buildFnNameDict = (r: array): fnNameDict => { - let allDefinitionsWithFns = - r - ->E.A2.fmap(fn => fn.definitions->E.A2.fmap(definitions => (fn, definitions))) - ->E.A.concatMany - let functionsWithFnNames = - allDefinitionsWithFns - ->E.A2.fmap(((fn, def)) => { + // 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 => + fn.definitions->Js.Array2.forEach(def => { let nameWithNamespace = `${fn.nameSpace}.${def.name}` let nameWithoutNamespace = def.name - fn.requiresNamespace - ? [(nameWithNamespace, fn)] - : [(nameWithNamespace, fn), (nameWithoutNamespace, fn)] + let names = fn.requiresNamespace ? [nameWithNamespace] : [nameWithNamespace, nameWithoutNamespace] + names->Js.Array2.forEach(name => { + switch res->Js.Dict.get(name) { + | Some(fns) => { + let _ = fns->Js.Array2.push(def) + } + | None => res->Js.Dict.set(name, [def]) + } + }) }) - ->E.A.concatMany - let uniqueNames = functionsWithFnNames->E.A2.fmap(((name, _)) => name)->E.A.uniq - let cacheAsArray: array<(string, array)> = uniqueNames->E.A2.fmap(uniqueName => { - let relevantItems = - E.A2.filter(functionsWithFnNames, ((defName, _)) => defName == uniqueName)->E.A2.fmap( - E.Tuple2.second, - ) - (uniqueName, relevantItems) - }) - cacheAsArray->Js.Dict.fromArray + ) + res } let make = (fns: array): registry => { @@ -484,48 +290,33 @@ module Registry = { {functions: fns, fnNameDict: dict} } - /* - There's a (potential+minor) bug here: If a function definition is called outside of the calls - to the registry, then it's possible that there could be a match after the registry is - called. However, for now, we could just call the registry last. - */ - let _matchAndRun = ( - ~registry: registry, - ~fnName: string, - ~args: array, - ~env: Reducer_T.environment, - ~reducer: Reducer_T.reducerFn, - ) => { - let relevantFunctions = Js.Dict.get(registry.fnNameDict, fnName) |> E.O.default([]) - let modified = {functions: relevantFunctions, fnNameDict: registry.fnNameDict} - let matchToDef = m => Matcher.Registry.matchToDef(registry, m) - let showNameMatchDefinitions = matches => { - let defs = - matches - ->E.A2.fmap(matchToDef) - ->E.A.O.concatSomes - ->E.A2.fmap(FnDefinition.toString) - ->E.A2.fmap(r => `[${r}]`) - ->E.A2.joinWith("; ") - `There are function matches for ${fnName}(), but with different arguments: ${defs}` - } - - switch Matcher.Registry.findMatches(modified, fnName, args) { - | Matcher.Match.FullMatch(match) => - match->matchToDef->E.O2.fmap(FnDefinition.run(_, args, env, reducer)) - | SameNameDifferentArguments(m) => Some(Error(showNameMatchDefinitions(m))) - | _ => None - } - } - - let dispatch = ( + let call = ( registry, - (fnName, args): ReducerInterface_InternalExpressionValue.functionCall, + fnName: string, + args: array, env: Reducer_T.environment, reducer: Reducer_T.reducerFn, - ) => { - _matchAndRun(~registry, ~fnName, ~args, ~env, ~reducer)->E.O2.fmap( - E.R2.errMap(_, s => Reducer_ErrorValue.RETodo(s)), - ) + ): result => { + switch Js.Dict.get(registry.fnNameDict, fnName) { + | Some(definitions) => { + let showNameMatchDefinitions = () => { + let defsString = + definitions + ->E.A2.fmap(FnDefinition.toString) + ->E.A2.fmap(r => `[${r}]`) + ->E.A2.joinWith("; ") + `There are function matches for ${fnName}(), but with different arguments: ${defsString}` + } + + 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 + } + } + } + | None => Reducer_ErrorValue.RESymbolNotFound(fnName)->Error + } } } diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res index d8c2c04b..0d54dee3 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res @@ -12,4 +12,4 @@ let fnList = Belt.Array.concatMany([ ]) let registry = FunctionRegistry_Core.Registry.make(fnList) -let dispatch = FunctionRegistry_Core.Registry.dispatch(registry) +let call = FunctionRegistry_Core.Registry.call(registry) 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 6bced75d..da064f94 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res @@ -45,6 +45,28 @@ let library = [ }, () ), + 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) + } + }, + () + ), ], (), ), diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy index 4beba469..469fcba1 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy @@ -264,7 +264,7 @@ lambda { statements.push(finalExpression) return h.nodeLambda(args, h.nodeBlock(statements)) } / '{' _nl '|' _nl args:array_parameters _nl '|' _nl finalExpression: expression _nl '}' - { return h.nodeLambda(args, h.nodeBlock([finalExpression])) } + { return h.nodeLambda(args, finalExpression) } arrayConstructor 'array' = '[' _nl ']' 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 58bfbb70..ed8d8f18 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 @@ -29,7 +29,7 @@ type nodeIdentifier = {...node, "value": string} type nodeInteger = {...node, "value": int} type nodeKeyValue = {...node, "key": node, "value": node} type nodeRecord = {...node, "elements": array} -type nodeLambda = {...node, "args": array, "body": nodeBlock} +type nodeLambda = {...node, "args": array, "body": node} type nodeLetStatement = {...node, "variable": nodeIdentifier, "value": node} type nodeModuleIdentifier = {...node, "value": string} type nodeString = {...node, "value": string} @@ -122,7 +122,7 @@ let rec pgToString = (peggyNode: peggyNode): string => { | PgNodeInteger(node) => node["value"]->Js.String.make | PgNodeKeyValue(node) => toString(node["key"]) ++ ": " ++ toString(node["value"]) | PgNodeLambda(node) => - "{|" ++ node["args"]->argsToString ++ "| " ++ pgToString(PgNodeBlock(node["body"])) ++ "}" + "{|" ++ node["args"]->argsToString ++ "| " ++ node["body"]->toString ++ "}" | PgNodeLetStatement(node) => pgToString(PgNodeIdentifier(node["variable"])) ++ " = " ++ toString(node["value"]) | PgNodeModuleIdentifier(node) => `@${node["value"]}` 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 c1823f5c..cf8ad010 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 @@ -15,7 +15,7 @@ let rec fromNode = (node: Parse.node): expression => { let args = nodeLambda["args"] ->Js.Array2.map((argNode: Parse.nodeIdentifier) => argNode["value"]) - let body = nodeLambda["body"]->caseBlock + let body = nodeLambda["body"]->fromNode ExpressionBuilder.eLambda(args, body) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res index f60c4f95..0c9703d7 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res @@ -14,7 +14,7 @@ let dispatch = ( () => ReducerInterface_Date.dispatch(call, environment), () => ReducerInterface_Duration.dispatch(call, environment), () => ReducerInterface_Number.dispatch(call, environment), - () => FunctionRegistry_Library.dispatch(call, environment, reducer), + // () => FunctionRegistry_Library.dispatch(call, environment, reducer), ])->E.O2.defaultFn(() => chain(call, environment, reducer)) } diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res index 2e356984..21f40d72 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res @@ -63,14 +63,9 @@ let internalStdLib: Reducer_Bindings.t = { (name) => { let _ = res->Reducer_Bindings.set(name, Reducer_Expression_Lambda.makeFFILambda( (arguments, environment, reducer) => { - switch FunctionRegistry_Library.dispatch((name, arguments), environment, reducer) { - | Some(result) => { - switch result { - | Ok(value) => value - | Error(error) => error->Reducer_ErrorValue.ErrorException->raise - } - } - | None => Reducer_ErrorValue.RESymbolNotFound("Not found in registry")->Reducer_ErrorValue.ErrorException->raise + switch FunctionRegistry_Library.call(name, arguments, environment, reducer) { + | Ok(value) => value + | Error(error) => error->Reducer_ErrorValue.ErrorException->raise } } )->Reducer_T.IEvLambda) From 681a1b42c6c0864fe3d87702af787992d02150ac Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Mon, 12 Sep 2022 03:21:49 +0400 Subject: [PATCH 06/46] delete unused --- .../Reducer_Dispatch_BuiltInMacros.res | 189 ------------------ .../Reducer_ExpressionWithContext.res | 50 ----- .../Reducer_Expression_BindingsReplacer.res | 49 ----- .../Reducer_Expression_Macro.res | 26 --- 4 files changed, 314 deletions(-) delete mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res delete mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_ExpressionWithContext.res delete mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_BindingsReplacer.res delete mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res deleted file mode 100644 index 22b5f0d6..00000000 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ /dev/null @@ -1,189 +0,0 @@ -// /* -// Macros are like functions but instead of taking values as parameters, -// they take expressions as parameters and return a new expression. -// Macros are used to define language building blocks. They are like Lisp macros. -// */ -// module BindingsReplacer = Reducer_Expression_BindingsReplacer -// module ErrorValue = Reducer_ErrorValue -// module ExpressionBuilder = Reducer_Expression_ExpressionBuilder -// module ExpressionT = Reducer_Expression_T -// module ExpressionWithContext = Reducer_ExpressionWithContext -// module InternalExpressionValue = ReducerInterface_InternalExpressionValue -// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -// module ProjectReducerFnT = ReducerProject_ReducerFn_T - -// open Reducer_Expression_ExpressionBuilder - -// exception ErrorException = ErrorValue.ErrorException -// type expression = ExpressionT.expression -// type expressionWithContext = ExpressionWithContext.expressionWithContext - -// let dispatchMacroCall = ( -// macroExpression: expression, -// bindings: ExpressionT.bindings, -// accessors: ProjectAccessorsT.t, -// reduceExpression: ProjectReducerFnT.t, -// ): expressionWithContext => { -// let useExpressionToSetBindings = (bindingExpr: expression, accessors, statement, newCode) => { -// let nameSpaceValue = reduceExpression(bindingExpr, bindings, accessors) - -// let newBindings = Reducer_Bindings.fromExpressionValue(nameSpaceValue) - -// let boundStatement = BindingsReplacer.replaceSymbols(newBindings, statement) - -// ExpressionWithContext.withContext(newCode(newBindings->eModule, boundStatement), newBindings) -// } - -// let correspondingSetBindingsFn = (fnName: string): string => -// switch fnName { -// | "$_let_$" => "$_setBindings_$" -// | "$_typeOf_$" => "$_setTypeOfBindings_$" -// | "$_typeAlias_$" => "$_setTypeAliasBindings_$" -// | "$_endOfOuterBlock_$" => "$_dumpBindings_$" -// | _ => "" -// } - -// let doBindStatement = (bindingExpr: expression, statement: expression, accessors) => { -// let defaultStatement = ErrorValue.REAssignmentExpected->ErrorException -// switch statement { -// | ExpressionT.EList(list{ExpressionT.EValue(IEvCall(callName)), ExpressionT.EValue(IEvSymbol(symbolExpr)), statement}) => { -// let setBindingsFn = correspondingSetBindingsFn(callName) -// if setBindingsFn !== "" { -// useExpressionToSetBindings(bindingExpr, accessors, statement, ( -// newBindingsExpr, -// boundStatement, -// ) => eFunction(setBindingsFn, list{newBindingsExpr, symbolExpr->IEvSymbol->ExpressionT.EValue, boundStatement})) -// } else { -// raise(defaultStatement) -// } -// } -// | _ => raise(defaultStatement) -// } -// } - -// let doBindExpression = ( -// bindingExpr: expression, -// statement: expression, -// accessors, -// ): expressionWithContext => { -// let defaultStatement = () => -// useExpressionToSetBindings(bindingExpr, accessors, statement, ( -// _newBindingsExpr, -// boundStatement, -// ) => boundStatement) - -// switch statement { -// | ExpressionT.EList(list{ExpressionT.EValue(IEvCall(callName)), symbolExpr, statement}) => { -// let setBindingsFn = correspondingSetBindingsFn(callName) -// if setBindingsFn !== "" { -// useExpressionToSetBindings(bindingExpr, accessors, statement, ( -// newBindingsExpr, -// boundStatement, -// ) => -// eFunction( -// "$_exportBindings_$", -// list{eFunction(setBindingsFn, list{newBindingsExpr, symbolExpr, boundStatement})}, // expression returning bindings -// ) -// ) -// } else { -// defaultStatement() -// } -// } -// | _ => defaultStatement() -// } -// } - -// let doBlock = ( -// exprs: list, -// _bindings: ExpressionT.bindings, -// _accessors, -// ): expressionWithContext => { -// let exprsArray = Belt.List.toArray(exprs) -// let maxIndex = Js.Array2.length(exprsArray) - 1 -// let newStatement = exprsArray->Js.Array2.reducei((acc, statement, index) => -// if index == 0 { -// if index == maxIndex { -// eBindExpressionDefault(statement) -// } else { -// eBindStatementDefault(statement) -// } -// } else if index == maxIndex { -// eBindExpression(acc, statement) -// } else { -// eBindStatement(acc, statement) -// } -// , eSymbol("undefined block")) -// ExpressionWithContext.noContext(newStatement) -// } - -// let doLambdaDefinition = ( -// bindings: ExpressionT.bindings, -// parameters: array, -// lambdaDefinition: ExpressionT.expression, -// ) => ExpressionWithContext.noContext(eLambda(parameters, bindings, lambdaDefinition)) - -// let doTernary = ( -// condition: expression, -// ifTrue: expression, -// ifFalse: expression, -// bindings: ExpressionT.bindings, -// accessors, -// ): expressionWithContext => { -// let blockCondition = ExpressionBuilder.eBlock(list{condition}) -// let conditionValue = reduceExpression(blockCondition, bindings, accessors) - -// switch conditionValue { -// | InternalExpressionValue.IEvBool(false) => { -// let ifFalseBlock = eBlock(list{ifFalse}) -// ExpressionWithContext.withContext(ifFalseBlock, bindings) -// } -// | InternalExpressionValue.IEvBool(true) => { -// let ifTrueBlock = eBlock(list{ifTrue}) -// ExpressionWithContext.withContext(ifTrueBlock, bindings) -// } -// | _ => raise(ErrorException(REExpectedType("Boolean", ""))) -// } -// } - -// let expandExpressionList = ( -// aList, -// bindings: ExpressionT.bindings, -// accessors, -// ): expressionWithContext => -// switch aList { -// | list{ -// ExpressionT.EValue(IEvCall("$$_bindStatement_$$")), -// bindingExpr: ExpressionT.expression, -// statement, -// } => -// doBindStatement(bindingExpr, statement, accessors) -// | list{ExpressionT.EValue(IEvCall("$$_bindStatement_$$")), statement} => -// // bindings of the context are used when there is no binding expression -// doBindStatement(eModule(bindings), statement, accessors) -// | list{ -// ExpressionT.EValue(IEvCall("$$_bindExpression_$$")), -// bindingExpr: ExpressionT.expression, -// expression, -// } => -// doBindExpression(bindingExpr, expression, accessors) -// | list{ExpressionT.EValue(IEvCall("$$_bindExpression_$$")), expression} => -// // bindings of the context are used when there is no binding expression -// doBindExpression(eModule(bindings), expression, accessors) -// | list{ExpressionT.EValue(IEvCall("$$_block_$$")), ...exprs} => -// doBlock(exprs, bindings, accessors) -// | list{ -// ExpressionT.EValue(IEvCall("$$_lambda_$$")), -// ExpressionT.EValue(IEvArrayString(parameters)), -// lambdaDefinition, -// } => -// doLambdaDefinition(bindings, parameters, lambdaDefinition) -// | list{ExpressionT.EValue(IEvCall("$$_ternary_$$")), condition, ifTrue, ifFalse} => -// doTernary(condition, ifTrue, ifFalse, bindings, accessors) -// | _ => ExpressionWithContext.noContext(ExpressionT.EList(aList)) -// } - -// switch macroExpression { -// | EList(aList) => expandExpressionList(aList, bindings, accessors) -// | _ => ExpressionWithContext.noContext(macroExpression) -// } -// } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_ExpressionWithContext.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_ExpressionWithContext.res deleted file mode 100644 index 47bcf817..00000000 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_ExpressionWithContext.res +++ /dev/null @@ -1,50 +0,0 @@ -// module Bindings = Reducer_Bindings -// module ErrorValue = Reducer_ErrorValue -// module ExpressionT = Reducer_Expression_T -// module InternalExpressionValue = ReducerInterface_InternalExpressionValue -// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -// module Result = Belt.Result - -// type bindings = Reducer_T.nameSpace -// type context = bindings -// type environment = InternalExpressionValue.environment -// type errorValue = Reducer_ErrorValue.errorValue -// type expression = ExpressionT.expression - -// type expressionWithContext = -// | ExpressionWithContext(expression, context) -// | ExpressionNoContext(expression) - -// let callReducer = ( -// expressionWithContext: expressionWithContext, -// bindings: bindings, -// accessors: ProjectAccessorsT.t, -// reducer: Reducer_T.reducerFn, -// ): Reducer_T.value => { -// switch expressionWithContext { -// | ExpressionNoContext(expr) => -// // Js.log(`callReducer: bindings ${Bindings.toString(bindings)} expr ${ExpressionT.toString(expr)}`) -// reducer(expr, bindings, accessors) -// | ExpressionWithContext(expr, context) => -// // Js.log(`callReducer: context ${Bindings.toString(context)} expr ${ExpressionT.toString(expr)}`) -// reducer(expr, context, accessors) -// } -// } - -// let withContext = (expression, context) => ExpressionWithContext(expression, context) -// let noContext = expression => ExpressionNoContext(expression) - -// let toString = expressionWithContext => -// switch expressionWithContext { -// | ExpressionNoContext(expr) => ExpressionT.toString(expr) -// | ExpressionWithContext(expr, context) => -// `${ExpressionT.toString(expr)} context: ${context -// ->Bindings.toExpressionValue -// ->InternalExpressionValue.toString}` -// } - -// let toStringResult = rExpressionWithContext => -// switch rExpressionWithContext { -// | Ok(expressionWithContext) => `Ok(${toString(expressionWithContext)})` -// | Error(errorValue) => ErrorValue.errorToString(errorValue) -// } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_BindingsReplacer.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_BindingsReplacer.res deleted file mode 100644 index f818ee27..00000000 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_BindingsReplacer.res +++ /dev/null @@ -1,49 +0,0 @@ -// module ErrorValue = Reducer_ErrorValue -// module ExpressionT = Reducer_Expression_T -// module InternalExpressionValue = ReducerInterface_InternalExpressionValue -// module Bindings = Reducer_Bindings - -// type errorValue = Reducer_ErrorValue.errorValue -// type expression = ExpressionT.expression -// type internalExpressionValue = InternalExpressionValue.t - -// let isMacroName = (fName: string): bool => fName->Js.String2.startsWith("$$") - -// let rec replaceSymbols = (bindings: ExpressionT.bindings, expression: expression): expression => -// switch expression { -// | ExpressionT.EValue(value) => replaceSymbolOnValue(bindings, value)->ExpressionT.EValue -// | ExpressionT.EList(list) => -// switch list { -// | list{EValue(IEvCall(fName)), ..._args} => -// switch isMacroName(fName) { -// // A macro reduces itself so we dont dive in it -// | true => expression -// | false => replaceSymbolsOnExpressionList(bindings, list) -// } -// | _ => replaceSymbolsOnExpressionList(bindings, list) -// } -// } - -// and replaceSymbolsOnExpressionList = (bindings, list) => { -// let racc = -// list->Belt.List.reduceReverse(list{}, (acc, each: expression) => -// replaceSymbols(bindings, each)->Belt.List.add(acc, _) -// ) -// ExpressionT.EList(racc) -// } -// and replaceSymbolOnValue = (bindings, evValue: internalExpressionValue) => -// switch evValue { -// | IEvSymbol(symbol) => Reducer_Bindings.getWithDefault(bindings, symbol, evValue) -// | IEvCall(symbol) => Reducer_Bindings.getWithDefault(bindings, symbol, evValue)->checkIfCallable -// | _ => evValue -// } -// and checkIfCallable = (evValue: internalExpressionValue) => -// switch evValue { -// | IEvCall(_) | IEvLambda(_) => evValue -// | _ => -// raise( -// ErrorValue.ErrorException( -// ErrorValue.RENotAFunction(InternalExpressionValue.toString(evValue)), -// ), -// ) -// } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res deleted file mode 100644 index 442c4e98..00000000 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res +++ /dev/null @@ -1,26 +0,0 @@ -// module ExpressionT = Reducer_Expression_T -// module InternalExpressionValue = ReducerInterface_InternalExpressionValue -// module ExpressionWithContext = Reducer_ExpressionWithContext -// module Result = Belt.Result -// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -// module ProjectReducerFnT = ReducerProject_ReducerFn_T - -// type environment = InternalExpressionValue.environment -// type expression = ExpressionT.expression -// type internalExpressionValue = InternalExpressionValue.t -// type expressionWithContext = ExpressionWithContext.expressionWithContext - -// let doMacroCall = ( -// macroExpression: expression, -// bindings: ExpressionT.bindings, -// accessors: ProjectAccessorsT.t, -// reduceExpression: ProjectReducerFnT.t, -// ): internalExpressionValue => -// Reducer_Dispatch_BuiltInMacros.dispatchMacroCall( -// macroExpression, -// bindings, -// (accessors: ProjectAccessorsT.t), -// (reduceExpression: ProjectReducerFnT.t), -// )->ExpressionWithContext.callReducer(bindings, accessors, reduceExpression) - -// let isMacroName = (fName: string): bool => fName->Js.String2.startsWith("$$") From 757d458ecfb9408e65fb8add56094ea3093aaf15 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Mon, 12 Sep 2022 13:33:20 +0400 Subject: [PATCH 07/46] 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) // } + From 97ff56b46ae9cac9135ea18a4f5125d272e9c70d Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Mon, 12 Sep 2022 13:42:39 +0400 Subject: [PATCH 08/46] link dependencies --- .../ReducerInterface/ReducerInterface_ExternalLibrary.res | 2 +- .../src/rescript/ReducerProject/ReducerProject.res | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res index cb296904..6976471a 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res @@ -13,7 +13,7 @@ let dispatch = ( // () => ReducerInterface_GenericDistribution.dispatch(call, environment), () => ReducerInterface_Date.dispatch(call, environment), () => ReducerInterface_Duration.dispatch(call, environment), - () => ReducerInterface_Number.dispatch(call, environment), + // () => ReducerInterface_Number.dispatch(call, environment), // () => FunctionRegistry_Library.dispatch(call, environment, reducer), ])->E.O2.defaultFn(() => chain(call, environment, reducer)) } diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res index fe7718d6..0730dee0 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res @@ -187,8 +187,12 @@ let linkDependencies = (project: t, sourceId: string): ProjectItem.T.continuatio let doLinkAndRun = (project: t, sourceId: string): unit => { let context = Reducer_Context.createContext(project->getStdLib, project->getEnvironment) // FIXME: fill context with dependencies - // let continuation = linkDependencies(project, sourceId) - let newItem = project->getItem(sourceId)->ProjectItem.run(context) + let continuation = linkDependencies(project, sourceId) + let contextWithContinuation = { + ...context, + bindings: continuation->Reducer_Bindings.extend, + } + let newItem = project->getItem(sourceId)->ProjectItem.run(contextWithContinuation) // Js.log("after run " ++ newItem.continuation->Reducer_Bindings.toString) project->setItem(sourceId, newItem) } From 36127d8947a7518ea5c213dd1bc46f40c3fbcc16 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Mon, 12 Sep 2022 14:44:35 +0400 Subject: [PATCH 09/46] cleanup benchmark script --- packages/squiggle-lang/bench-bio.js | 30 ----------------------------- 1 file changed, 30 deletions(-) delete mode 100755 packages/squiggle-lang/bench-bio.js diff --git a/packages/squiggle-lang/bench-bio.js b/packages/squiggle-lang/bench-bio.js deleted file mode 100755 index 2bc78095..00000000 --- a/packages/squiggle-lang/bench-bio.js +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env node -const s = require("./dist/src/js"); -const fs = require("fs"); - -const measure = (cb, times = 1) => { - const t1 = new Date(); - - for (let i = 1; i <= times; i++) { - cb(); - } - const t2 = new Date(); - return (t2 - t1) / 1000; -}; - -const maxP = 0; - -const bioSrc = fs.readFileSync( - "/Users/berekuk/Downloads/Bio.squiggle", - "utf-8" -); - -for (let p = 0; p <= maxP; p++) { - const size = Math.pow(10, p); - const prj = s.SqProject.create(); - prj.setSource("main", bioSrc); - const t = measure(() => { - prj.run("main"); - }); - console.log(`1e${p}`, "\t", t); -} From 02c84983a4353316d4d59a0ff4711a4231821c17 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Tue, 13 Sep 2022 03:51:49 +0400 Subject: [PATCH 10/46] more builtin functions --- .../FunctionRegistry/Library/FR_Builtin.res | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) 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 067d8e17..3bc610a4 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res @@ -38,10 +38,39 @@ let makeBinaryFn = (name: string, fn: (float, float) => float) => { ) } +let makeBinaryCmpFn = (name: string, fn: (float, float) => bool) => { + makeFn( + name, + [FRTypeNumber, FRTypeNumber], + inputs => { + switch inputs { + | [IEvNumber(x), IEvNumber(y)] => fn(x, y)->IEvBool->Ok + | _ => Error(impossibleError) + } + } + ) +} + let library = [ // 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), + makeBinaryFn("pow", (x, y) => Js.Math.pow_float(~base=x, ~exp=y)), + makeBinaryCmpFn("equal", (x, y) => x == y), + makeBinaryCmpFn("smaller", (x, y) => x < y), + makeBinaryCmpFn("smallerEq", (x, y) => x <= y), + makeBinaryCmpFn("larger", (x, y) => x > y), + makeBinaryCmpFn("largerEq", (x, y) => x >= y), + makeFn( + "unaryMinus", + [FRTypeNumber], + inputs => { + switch inputs { + | [IEvNumber(x)] => IEvNumber(-.x)->Ok + | _ => Error(impossibleError) + } + } + ) ] From 294acffb89a03ced611ba7ce5bbc43515e926e4f Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Wed, 14 Sep 2022 14:48:58 +0400 Subject: [PATCH 11/46] minor cleanups --- .../FunctionRegistry_Core.res | 20 +++++++++---------- .../Library/FR_GenericDist.res | 2 -- .../src/rescript/Reducer/Reducer_T.res | 3 --- 3 files changed, 10 insertions(+), 15 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res index 28f55f1c..d76a8cbc 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res @@ -212,9 +212,9 @@ module FnDefinition = { } let make = (~name, ~inputs, ~run, ()): t => { - name: name, - inputs: inputs, - run: run, + name, + inputs, + run, } } @@ -240,14 +240,14 @@ module Function = { ~isExperimental=false, (), ): t => { - name: name, - nameSpace: nameSpace, - definitions: definitions, - output: output, + name, + nameSpace, + definitions, + output, examples: examples |> E.O.default([]), - isExperimental: isExperimental, - requiresNamespace: requiresNamespace, - description: description, + isExperimental, + requiresNamespace, + description, } let toJson = (t: t): functionJson => { diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_GenericDist.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_GenericDist.res index 5d5b4d98..adb510cb 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_GenericDist.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_GenericDist.res @@ -393,8 +393,6 @@ let library = E.A.concatMany([ 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]), diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res index b4eb4d43..7e71e343 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res @@ -5,7 +5,6 @@ type rec value = | IEvArray(arrayValue) | IEvArrayString(array) | IEvBool(bool) - // | IEvCall(string) // External function call | IEvDate(Js.Date.t) | IEvDeclaration(lambdaDeclaration) | IEvDistribution(DistributionTypes.genericDist) @@ -14,7 +13,6 @@ type rec value = | IEvNumber(float) | IEvRecord(map) | IEvString(string) - // | IEvSymbol(string) | IEvTimeDuration(float) | IEvType(map) | IEvTypeIdentifier(string) @@ -26,7 +24,6 @@ and lambdaBody = (array, environment, reducerFn) => value @genType.opaque and lambdaValue = { parameters: array, - // context: nameSpace, body: (array, environment, reducerFn) => value, } @genType.opaque and lambdaDeclaration = Declaration.declaration From 6463b52052e712af2e035bd980f8a52b6f7dfc3f Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Thu, 15 Sep 2022 15:17:19 +0400 Subject: [PATCH 12/46] benchmark and other scripts --- .../benchmark/Benchmark_Array.res | 76 +++++++++++++++++++ .../benchmark/Benchmark_Helpers.res | 11 +++ .../squiggle-lang/benchmark/Benchmark_Map.res | 65 ++++++++++++++++ packages/squiggle-lang/bsconfig.json | 12 ++- .../squiggle-lang/examples/integrate.squiggle | 13 ++++ packages/squiggle-lang/package.json | 1 + packages/squiggle-lang/scripts/README.md | 3 + .../{bench.js => scripts/bench-map-reduce.js} | 14 ++-- packages/squiggle-lang/scripts/bench-map.js | 27 +++++++ packages/squiggle-lang/scripts/run-file.js | 38 ++++++++++ packages/squiggle-lang/scripts/run.js | 18 +++++ yarn.lock | 22 ++++-- 12 files changed, 287 insertions(+), 13 deletions(-) create mode 100644 packages/squiggle-lang/benchmark/Benchmark_Array.res create mode 100644 packages/squiggle-lang/benchmark/Benchmark_Helpers.res create mode 100644 packages/squiggle-lang/benchmark/Benchmark_Map.res create mode 100644 packages/squiggle-lang/examples/integrate.squiggle create mode 100644 packages/squiggle-lang/scripts/README.md rename packages/squiggle-lang/{bench.js => scripts/bench-map-reduce.js} (61%) create mode 100755 packages/squiggle-lang/scripts/bench-map.js create mode 100755 packages/squiggle-lang/scripts/run-file.js create mode 100755 packages/squiggle-lang/scripts/run.js diff --git a/packages/squiggle-lang/benchmark/Benchmark_Array.res b/packages/squiggle-lang/benchmark/Benchmark_Array.res new file mode 100644 index 00000000..61562732 --- /dev/null +++ b/packages/squiggle-lang/benchmark/Benchmark_Array.res @@ -0,0 +1,76 @@ +module Map: Benchmark_Helpers.BenchmarkTopic = { + let arraySize = 1000 + let iterations = 300_000 + + let beltArray = () => { + let x = Belt.Array.make(arraySize, 0.) + Belt.Range.forEach(1, iterations, _ => { + let _ = x->Belt.Array.map(v => v) + }) + } + + let jsArray2 = () => { + let x = Belt.Array.make(arraySize, 0.) + Belt.Range.forEach(1, iterations, _ => { + let _ = x->Js.Array2.map(v => v) + }) + } + + let ocamlArray = () => { + let x = Belt.Array.make(arraySize, 0.) + Belt.Range.forEach(1, iterations, _ => { + let _ = x->Array.map(v => v, _) + }) + } + + let runAll = () => { + Js.log(`Mapping identity function over arrays of size ${arraySize->Js.Int.toString} (${iterations->Js.Int.toString} iterations)`) + Benchmark_Helpers.measure("Belt.Array.map", beltArray) + Benchmark_Helpers.measure("Js.Array2.map", jsArray2) + Benchmark_Helpers.measure("Array.map", ocamlArray) + } +} + +module Sort: Benchmark_Helpers.BenchmarkTopic = { + let arraySize = 1000 + let iterations = 30000 + + let jsArray2 = () => { + let x = Belt.Array.make(arraySize, 0.) + let compare = (a: float, b: float) => { + if a < b { + -1 + } else { + 1 + } + } + + Belt.Range.forEach(1, iterations, _ => { + let _ = x->Js.Array2.sortInPlaceWith(compare) + }) + } + + let jsArray2withOcamlCompare = () => { + let x = Belt.Array.make(arraySize, 0.) + Belt.Range.forEach(1, iterations, _ => { + let _ = x->Js.Array2.sortInPlaceWith(Pervasives.compare) + }) + } + + let ocamlArray = () => { + let x = Belt.Array.make(arraySize, 0.) + Belt.Range.forEach(1, iterations, _ => { + let _ = x->Array.fast_sort(compare, _) + }) + } + + let runAll = () => { + Js.log(`Sorting arrays of size ${arraySize->Js.Int.toString} (${iterations->Js.Int.toString} iterations)`) + Benchmark_Helpers.measure("Js.Array2.sort", jsArray2) + Benchmark_Helpers.measure("Js.Array2.sort with Ocaml compare", jsArray2withOcamlCompare) + Benchmark_Helpers.measure("Array.fast_sort", ocamlArray) + } +} + +Map.runAll() +Sort.runAll() diff --git a/packages/squiggle-lang/benchmark/Benchmark_Helpers.res b/packages/squiggle-lang/benchmark/Benchmark_Helpers.res new file mode 100644 index 00000000..0e889d15 --- /dev/null +++ b/packages/squiggle-lang/benchmark/Benchmark_Helpers.res @@ -0,0 +1,11 @@ +module type BenchmarkTopic = { + let runAll: () => unit +} + +let measure = (name: string, f: () => unit) => { + let start = Js.Date.make()->Js.Date.valueOf + f() + let end = Js.Date.make()->Js.Date.valueOf + let duration = (end -. start) /. 1000. + Js.log2(duration, name) +} diff --git a/packages/squiggle-lang/benchmark/Benchmark_Map.res b/packages/squiggle-lang/benchmark/Benchmark_Map.res new file mode 100644 index 00000000..d04d501d --- /dev/null +++ b/packages/squiggle-lang/benchmark/Benchmark_Map.res @@ -0,0 +1,65 @@ +module StringMap: Benchmark_Helpers.BenchmarkTopic = { + let size = 1000 + let iterations = 10_000 + + let kv = Belt.Array.range(1, size)->Belt.Array.map( + v => ("key" ++ v->Belt.Int.toString, v) + ) + + let beltMap = () => { + Belt.Range.forEach(1, iterations, _ => { + let m = Belt.Map.String.empty + let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => acc->Belt.Map.String.set(k, v)) + }) + } + + let beltMutableMap = () => { + Belt.Range.forEach(1, iterations, _ => { + let m = Belt.MutableMap.String.make() + let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => { + acc->Belt.MutableMap.String.set(k, v) + acc + }) + }) + } + + let beltHashMap = () => { + Belt.Range.forEach(1, iterations, _ => { + let m = Belt.HashMap.String.make(~hintSize=100) + let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => { + acc->Belt.HashMap.String.set(k, v) + acc + }) + }) + } + + let jsDict = () => { + Belt.Range.forEach(1, iterations, _ => { + let m = Js.Dict.empty() + let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => { + acc->Js.Dict.set(k, v) + acc + }) + }) + } + + let jsMap = () => { + Belt.Range.forEach(1, iterations, _ => { + let m = Js_map.make() + let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => + acc->Js_map.set(k, v) + ) + }) + } + + let runAll = () => { + Js.log(`Filling a map with ("key{i}" => "i") key-value pairs, size ${size->Js.Int.toString} (${iterations->Js.Int.toString} iterations)`) + Benchmark_Helpers.measure("Belt.Map.String", beltMap) + Benchmark_Helpers.measure("Belt.MutableMap.String", beltMutableMap) + Benchmark_Helpers.measure("Belt.HashMap.String", beltHashMap) + Benchmark_Helpers.measure("Js.Dict", jsDict) + Benchmark_Helpers.measure("Js.Map", jsMap) + } +} + +let runAll = StringMap.runAll() diff --git a/packages/squiggle-lang/bsconfig.json b/packages/squiggle-lang/bsconfig.json index 1fa663ac..a05df290 100644 --- a/packages/squiggle-lang/bsconfig.json +++ b/packages/squiggle-lang/bsconfig.json @@ -9,6 +9,11 @@ "dir": "__tests__", "type": "dev", "subdirs": true + }, + { + "dir": "benchmark", + "type": "dev", + "subdirs": true } ], "bsc-flags": ["-bs-super-errors", "-bs-no-version-header", "-bs-g"], @@ -21,7 +26,12 @@ "suffix": ".bs.js", "namespace": true, "bs-dependencies": ["bisect_ppx"], - "bs-dev-dependencies": ["@glennsl/rescript-jest", "rescript-fast-check"], + "bs-dev-dependencies": [ + "@glennsl/rescript-jest", + "rescript-fast-check", + "rescript-js-map", + "rescript-js-iterator" + ], "gentypeconfig": { "language": "typescript", "module": "commonjs", diff --git a/packages/squiggle-lang/examples/integrate.squiggle b/packages/squiggle-lang/examples/integrate.squiggle new file mode 100644 index 00000000..d41e18c7 --- /dev/null +++ b/packages/squiggle-lang/examples/integrate.squiggle @@ -0,0 +1,13 @@ +integrate(fun, min, max) = { + // assume that min and max are integers. + epsilon = 1 + l = max - min + meanF(t) = fun(t) + intervals = map(List.upTo(0, (l/epsilon)), ({|n| min + n*epsilon})) + values = map(intervals, ({ |x | meanF(x)})) + result = reduce(values, 0, ({|acc, x| acc + x})) * epsilon + result +} + +f(x) = x +integrate(f, 1, 100k) diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index 80c542f5..89ea4432 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -66,6 +66,7 @@ "reanalyze": "^2.23.0", "rescript": "^9.1.4", "rescript-fast-check": "^1.1.1", + "rescript-js-map": "^1.1.0", "ts-jest": "^27.1.4", "ts-loader": "^9.3.0", "ts-node": "^10.9.1", diff --git a/packages/squiggle-lang/scripts/README.md b/packages/squiggle-lang/scripts/README.md new file mode 100644 index 00000000..e8dea081 --- /dev/null +++ b/packages/squiggle-lang/scripts/README.md @@ -0,0 +1,3 @@ +Various scripts used for development, benchmarking and testing. + +None of these are bundled in NPM package yet. diff --git a/packages/squiggle-lang/bench.js b/packages/squiggle-lang/scripts/bench-map-reduce.js similarity index 61% rename from packages/squiggle-lang/bench.js rename to packages/squiggle-lang/scripts/bench-map-reduce.js index effccdfa..ffada066 100755 --- a/packages/squiggle-lang/bench.js +++ b/packages/squiggle-lang/scripts/bench-map-reduce.js @@ -1,5 +1,5 @@ #!/usr/bin/env node -const s = require("./dist/src/js"); +const s = require("@quri/squiggle-lang"); const measure = (cb, times = 1) => { const t1 = new Date(); @@ -11,17 +11,17 @@ const measure = (cb, times = 1) => { return (t2 - t1) / 1000; }; -const maxP = 7; +const maxP = 5; for (let p = 0; p <= maxP; p++) { const size = Math.pow(10, p); const prj = s.SqProject.create(); - prj.setSource("list", `l = List.upTo(1,${size})`); - prj.run("list"); - prj.setSource("map", "l |> map({|x| x})"); - prj.setContinues("map", ["list"]); + prj.setSource( + "main", + `List.upTo(1, ${size}) |> map({|x| List.upTo(1, 100) |> reduce(0, {|a,b|a+b})})` + ); const t = measure(() => { - prj.run("map"); + prj.run("main"); }); console.log(`1e${p}`, "\t", t); } diff --git a/packages/squiggle-lang/scripts/bench-map.js b/packages/squiggle-lang/scripts/bench-map.js new file mode 100755 index 00000000..befa1a7b --- /dev/null +++ b/packages/squiggle-lang/scripts/bench-map.js @@ -0,0 +1,27 @@ +#!/usr/bin/env node +const s = require("@quri/squiggle-lang"); + +const measure = (cb, times = 1) => { + const t1 = new Date(); + + for (let i = 1; i <= times; i++) { + cb(); + } + const t2 = new Date(); + return (t2 - t1) / 1000; +}; + +const maxP = 7; + +for (let p = 0; p <= maxP; p++) { + const size = Math.pow(10, p); + const project = s.SqProject.create(); + project.setSource("list", `l = List.upTo(1,${size})`); + project.run("list"); + project.setSource("map", "l |> map({|x| x})"); + project.setContinues("map", ["list"]); + const time = measure(() => { + project.run("map"); + }); + console.log(`1e${p}`, "\t", time); +} diff --git a/packages/squiggle-lang/scripts/run-file.js b/packages/squiggle-lang/scripts/run-file.js new file mode 100755 index 00000000..fb09aa23 --- /dev/null +++ b/packages/squiggle-lang/scripts/run-file.js @@ -0,0 +1,38 @@ +#!/usr/bin/env node +const s = require("@quri/squiggle-lang"); +const fs = require("fs"); + +const measure = (cb, times = 1) => { + const t1 = new Date(); + + for (let i = 1; i <= times; i++) { + cb(); + } + const t2 = new Date(); + return (t2 - t1) / 1000; +}; + +const project = s.SqProject.create(); +const sampleCount = process.env.SAMPLE_COUNT; +if (sampleCount) { + project.setEnvironment({ + sampleCount, + xyPointLength: sampleCount, + }); +} + +const src = fs.readFileSync(process.argv[2], "utf-8"); +if (!src) { + throw new Error("Expected src"); +} +console.log(`Running ${src}`); +project.setSource("a", src); + +const t = measure(() => project.run("a")); +console.log(`Time: ${t}`); + +const result = project.getResult("a"); +console.log("Result:", result.tag, result.value.toString()); + +const bindings = project.getBindings("a"); +console.log("Bindings:", bindings.asValue().toString()); diff --git a/packages/squiggle-lang/scripts/run.js b/packages/squiggle-lang/scripts/run.js new file mode 100755 index 00000000..e77b953b --- /dev/null +++ b/packages/squiggle-lang/scripts/run.js @@ -0,0 +1,18 @@ +#!/usr/bin/env node +const s = require("@quri/squiggle-lang"); + +const p = s.SqProject.create(); + +const src = process.argv[2]; +if (!src) { + throw new Error("Expected src"); +} +console.log(`Running ${src}`); +p.setSource("a", src); +p.run("a"); + +const result = p.getResult("a"); +console.log(result.tag, result.value.toString()); + +const bindings = p.getBindings("a"); +console.log(bindings.asValue().toString()); diff --git a/yarn.lock b/yarn.lock index 9a156c50..f4ed4bd8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4797,10 +4797,10 @@ "@types/history" "^4.7.11" "@types/react" "*" -"@types/react@*", "@types/react@^18.0.1", "@types/react@^18.0.18": - version "18.0.19" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.19.tgz#269a5f35b9a73c69dfb0c7189017013ab02acbaa" - integrity sha512-BDc3Q+4Q3zsn7k9xZrKfjWyJsSlEDMs38gD1qp2eDazLCdcPqAT+vq1ND+Z8AGel/UiwzNUk8ptpywgNQcJ1MQ== +"@types/react@*", "@types/react@^18.0.18": + version "18.0.20" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.20.tgz#e4c36be3a55eb5b456ecf501bd4a00fd4fd0c9ab" + integrity sha512-MWul1teSPxujEHVwZl4a5HxQ9vVNsjTchVA+xRqv/VYGCuKGAU6UhfrTdF5aBefwD1BHUD8i/zq+O/vyCm/FrA== dependencies: "@types/prop-types" "*" "@types/scheduler" "*" @@ -15152,7 +15152,7 @@ react-vega@^7.6.0: prop-types "^15.8.1" vega-embed "^6.5.1" -react@^18.0.0, react@^18.1.0: +react@^18.1.0: version "18.2.0" resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ== @@ -15578,6 +15578,18 @@ rescript-fast-check@^1.1.1: dependencies: fast-check "^2.17.0" +rescript-js-iterator@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/rescript-js-iterator/-/rescript-js-iterator-1.1.0.tgz#7fc1e6097cec5f3b847189e112deed0bca331f4d" + integrity sha512-9VSGfAUXdmOl0OoersJZknpGjCi4gsIuejcHQwIYKwoPPlfswFvrKjwOLTy4SoqM2037RxiwxsMPRlWgfDY22A== + +rescript-js-map@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/rescript-js-map/-/rescript-js-map-1.1.0.tgz#5e4e57d9147733bd2d14307d65f0f8febb5850fc" + integrity sha512-kJB43pIRv/Cd9OY17Fpof+xq6WTCqagdW+zrmBxFIj8SpK48rG4nF8jXSsYK3ksdwIJwh7J3sx3pwA27YkeM+A== + dependencies: + rescript-js-iterator "^1.1.0" + rescript@^9.1.4: version "9.1.4" resolved "https://registry.yarnpkg.com/rescript/-/rescript-9.1.4.tgz#1eb126f98d6c16942c0bf0df67c050198e580515" From f62e90fa98fc374a0f2a2667c66d02870aa078f6 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Sat, 17 Sep 2022 00:30:44 +0400 Subject: [PATCH 13/46] Reducer_Namespace; remove Module type; temporarily disable tests compilation --- packages/squiggle-lang/bsconfig.json | 10 +-- packages/squiggle-lang/scripts/run.js | 2 +- packages/squiggle-lang/src/js/SqModule.ts | 30 -------- packages/squiggle-lang/src/js/SqProject.ts | 4 +- packages/squiggle-lang/src/js/SqValue.ts | 32 --------- .../rescript/ForTS/ForTS_ReducerProject.res | 8 +-- .../ForTS_SquiggleValue.res | 34 --------- .../ForTS_SquiggleValue_Module.res | 16 ----- .../ForTS_SquiggleValue_tag.ts | 3 - .../src/rescript/ForTS/ForTS__Types.res | 1 - .../Reducer_Bindings/Reducer_Bindings.res | 72 ++++++------------- .../src/rescript/Reducer/Reducer_Context.res | 4 +- .../Reducer_Dispatch_BuiltIn.res | 14 ++-- .../Reducer_Expression_ExpressionBuilder.res | 5 -- .../Reducer_Expression_Lambda.res | 2 +- .../rescript/Reducer/Reducer_Namespace.res | 38 ++++++++++ .../src/rescript/Reducer/Reducer_T.res | 15 ++-- ...ducerInterface_InternalExpressionValue.res | 27 ------- .../ReducerInterface_StdLib.res | 14 ++-- .../ReducerInterface_Value_Continuation.res | 21 ------ .../ReducerProject/ReducerProject.res | 66 ++++++++--------- .../ReducerProject_ProjectItem.res | 6 +- .../ReducerProject_ProjectItem_T.res | 5 +- .../ReducerProject/ReducerProject_T.res | 2 +- .../SquiggleLibrary/SquiggleLibrary_Math.res | 9 +-- .../SquiggleLibrary_Versions.res | 9 +-- 26 files changed, 136 insertions(+), 313 deletions(-) delete mode 100644 packages/squiggle-lang/src/js/SqModule.ts delete mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Module.res create mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res delete mode 100644 packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Value/ReducerInterface_Value_Continuation.res diff --git a/packages/squiggle-lang/bsconfig.json b/packages/squiggle-lang/bsconfig.json index a05df290..d9c352a5 100644 --- a/packages/squiggle-lang/bsconfig.json +++ b/packages/squiggle-lang/bsconfig.json @@ -5,11 +5,11 @@ "dir": "src/rescript", "subdirs": true }, - { - "dir": "__tests__", - "type": "dev", - "subdirs": true - }, + // { + // "dir": "__tests__", + // "type": "dev", + // "subdirs": true + // }, { "dir": "benchmark", "type": "dev", diff --git a/packages/squiggle-lang/scripts/run.js b/packages/squiggle-lang/scripts/run.js index e77b953b..97ae76bc 100755 --- a/packages/squiggle-lang/scripts/run.js +++ b/packages/squiggle-lang/scripts/run.js @@ -15,4 +15,4 @@ const result = p.getResult("a"); console.log(result.tag, result.value.toString()); const bindings = p.getBindings("a"); -console.log(bindings.asValue().toString()); +console.log(bindings.toString()); diff --git a/packages/squiggle-lang/src/js/SqModule.ts b/packages/squiggle-lang/src/js/SqModule.ts deleted file mode 100644 index c50d3be3..00000000 --- a/packages/squiggle-lang/src/js/SqModule.ts +++ /dev/null @@ -1,30 +0,0 @@ -import * as RSModuleValue from "../rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Module.gen"; -import { SqModuleValue, wrapValue } from "./SqValue"; -import { SqValueLocation } from "./SqValueLocation"; - -export class SqModule { - constructor( - private _value: RSModuleValue.squiggleValue_Module, - public location: SqValueLocation - ) {} - - entries() { - return RSModuleValue.getKeyValuePairs(this._value).map( - ([k, v]) => [k, wrapValue(v, this.location.extend(k))] as const - ); - } - - asValue() { - return new SqModuleValue( - RSModuleValue.toSquiggleValue(this._value), - this.location - ); - } - - get(k: string) { - const v = RSModuleValue.get(this._value, k); - return v === undefined || v === null - ? undefined - : wrapValue(v, this.location.extend(k)); - } -} diff --git a/packages/squiggle-lang/src/js/SqProject.ts b/packages/squiggle-lang/src/js/SqProject.ts index 4c2dea7c..eb54bc4a 100644 --- a/packages/squiggle-lang/src/js/SqProject.ts +++ b/packages/squiggle-lang/src/js/SqProject.ts @@ -2,7 +2,7 @@ import * as RSProject from "../rescript/ForTS/ForTS_ReducerProject.gen"; import { reducerErrorValue } from "../rescript/ForTS/ForTS_Reducer_ErrorValue.gen"; import { environment } from "../rescript/ForTS/ForTS_Distribution/ForTS_Distribution_Environment.gen"; import { SqError } from "./SqError"; -import { SqModule } from "./SqModule"; +import { SqRecord } from "./SqRecord"; import { wrapValue } from "./SqValue"; import { resultMap2 } from "./types"; import { SqValueLocation } from "./SqValueLocation"; @@ -83,7 +83,7 @@ export class SqProject { } getBindings(sourceId: string) { - return new SqModule( + return new SqRecord( RSProject.getBindings(this._value, sourceId), new SqValueLocation(this, sourceId, { root: "bindings", diff --git a/packages/squiggle-lang/src/js/SqValue.ts b/packages/squiggle-lang/src/js/SqValue.ts index fbde4f80..7207b859 100644 --- a/packages/squiggle-lang/src/js/SqValue.ts +++ b/packages/squiggle-lang/src/js/SqValue.ts @@ -3,11 +3,9 @@ import { squiggleValueTag as Tag } from "../rescript/ForTS/ForTS_SquiggleValue/F import { wrapDistribution } from "./SqDistribution"; import { SqLambda } from "./SqLambda"; import { SqLambdaDeclaration } from "./SqLambdaDeclaration"; -import { SqModule } from "./SqModule"; import { SqRecord } from "./SqRecord"; import { SqArray } from "./SqArray"; import { SqType } from "./SqType"; -import { SqProject } from "./SqProject"; import { SqValueLocation } from "./SqValueLocation"; export { Tag as SqValueTag }; @@ -62,14 +60,6 @@ export class SqBoolValue extends SqAbstractValue { } } -// export class SqCallValue extends SqAbstractValue { -// tag = Tag.Call as const; - -// get value() { -// return this.valueMethod(RSValue.getCall); -// } -// } - export class SqDateValue extends SqAbstractValue { tag = Tag.Date as const; @@ -102,14 +92,6 @@ export class SqLambdaValue extends SqAbstractValue { } } -export class SqModuleValue extends SqAbstractValue { - tag = Tag.Module as const; - - get value() { - return new SqModule(this.valueMethod(RSValue.getModule), this.location); - } -} - export class SqNumberValue extends SqAbstractValue { tag = Tag.Number as const; @@ -134,14 +116,6 @@ export class SqStringValue extends SqAbstractValue { } } -// export class SqSymbolValue extends SqAbstractValue { -// tag = Tag.Symbol as const; - -// get value(): string { -// return this.valueMethod(RSValue.getSymbol); -// } -// } - export class SqTimeDurationValue extends SqAbstractValue { tag = Tag.TimeDuration as const; @@ -178,16 +152,13 @@ const tagToClass = { [Tag.Array]: SqArrayValue, [Tag.ArrayString]: SqArrayStringValue, [Tag.Bool]: SqBoolValue, - // [Tag.Call]: SqCallValue, [Tag.Date]: SqDateValue, [Tag.Declaration]: SqDeclarationValue, [Tag.Distribution]: SqDistributionValue, [Tag.Lambda]: SqLambdaValue, - [Tag.Module]: SqModuleValue, [Tag.Number]: SqNumberValue, [Tag.Record]: SqRecordValue, [Tag.String]: SqStringValue, - // [Tag.Symbol]: SqSymbolValue, [Tag.TimeDuration]: SqTimeDurationValue, [Tag.Type]: SqTypeValue, [Tag.TypeIdentifier]: SqTypeIdentifierValue, @@ -200,16 +171,13 @@ export type SqValue = | SqArrayValue | SqArrayStringValue | SqBoolValue - // | SqCallValue | SqDateValue | SqDeclarationValue | SqDistributionValue | SqLambdaValue - | SqModuleValue | SqNumberValue | SqRecordValue | SqStringValue - // | SqSymbolValue | SqTimeDurationValue | SqTypeValue | SqTypeIdentifierValue diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res index 68a143bd..5b48b8f7 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res @@ -3,7 +3,7 @@ type reducerErrorValue = ForTS_Reducer_ErrorValue.reducerErrorValue //use type squiggleValue = ForTS_SquiggleValue.squiggleValue //use -type squiggleValue_Module = ForTS_SquiggleValue_Module.squiggleValue_Module //use +type squiggleValue_Record = ForTS_SquiggleValue.squiggleValue_Record //use type environment = ForTS_Distribution_Environment.environment //use @@ -184,8 +184,8 @@ let runAll = (project: reducerProject): unit => project->Private.runAll Get the bindings after running this source fil. The bindings are local to the source */ @genType -let getBindings = (project: reducerProject, sourceId: string): squiggleValue_Module => - project->Private.getBindings(sourceId) +let getBindings = (project: reducerProject, sourceId: string): squiggleValue_Record => + project->Private.getBindings(sourceId)->Reducer_Namespace.toMap /* Get the result after running this source file or the project @@ -204,7 +204,7 @@ The source has to be include free @genType let evaluate = (sourceCode: string): ( result, - squiggleValue_Module, + squiggleValue_Record, ) => Private.evaluate(sourceCode) @genType diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res index 1dd3887d..de3cced2 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res @@ -2,7 +2,6 @@ type reducerErrorValue = ForTS_Reducer_ErrorValue.reducerErrorValue //use @genType type squiggleValue_Array = Reducer_T.arrayValue //re-export recursive type -@genType type squiggleValue_Module = Reducer_T.nameSpace //re-export recursive type @genType type squiggleValue_Record = Reducer_T.map //re-export recursive type @genType type squiggleValue_Type = Reducer_T.map //re-export recursive type type squiggleValue_Declaration = ForTS_SquiggleValue_Declaration.squiggleValue_Declaration //use @@ -20,9 +19,6 @@ external svtArrayString_: string = "ArrayString" @module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtBool_: string = "Bool" -// @module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -// external svtCall_: string = "Call" - @module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtDate_: string = "Date" @@ -35,9 +31,6 @@ external svtDistribution_: string = "Distribution" @module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtLambda_: string = "Lambda" -@module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -external svtModule_: string = "Module" - @module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtNumber_: string = "Number" @@ -47,9 +40,6 @@ external svtRecord_: string = "Record" @module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtString_: string = "String" -// @module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -// external svtSymbol_: string = "Symbol" - @module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtTimeDuration_: string = "TimeDuration" @@ -73,16 +63,13 @@ let getTag = (variant: squiggleValue): squiggleValueTag => | IEvArray(_) => svtArray_->castEnum | IEvArrayString(_) => svtArrayString_->castEnum | IEvBool(_) => svtBool_->castEnum - // | IEvCall(_) => svtCall_->castEnum //Impossible | IEvDate(_) => svtDate_->castEnum | IEvDeclaration(_) => svtDeclaration_->castEnum | IEvDistribution(_) => svtDistribution_->castEnum | IEvLambda(_) => svtLambda_->castEnum - | IEvBindings(_) => svtModule_->castEnum //Impossible | IEvNumber(_) => svtNumber_->castEnum | IEvRecord(_) => svtRecord_->castEnum | IEvString(_) => svtString_->castEnum - // | IEvSymbol(_) => svtSymbol_->castEnum | IEvTimeDuration(_) => svtTimeDuration_->castEnum | IEvType(_) => svtType_->castEnum | IEvTypeIdentifier(_) => svtTypeIdentifier_->castEnum @@ -121,13 +108,6 @@ let getBool = (variant: squiggleValue): option => | _ => None } -// @genType -// let getCall = (variant: squiggleValue): option => -// switch variant { -// | IEvCall(value) => value->Some -// | _ => None -// } - @genType let getDate = (variant: squiggleValue): option => switch variant { @@ -156,13 +136,6 @@ let getLambda = (variant: squiggleValue): option => | _ => None } -@genType -let getModule = (variant: squiggleValue): option => - switch variant { - | IEvBindings(value) => value->Some - | _ => None - } - @genType let getNumber = (variant: squiggleValue): option => switch variant { @@ -184,13 +157,6 @@ let getString = (variant: squiggleValue): option => | _ => None } -// @genType -// let getSymbol = (variant: squiggleValue): option => -// switch variant { -// | IEvSymbol(value) => value->Some -// | _ => None -// } - @genType let getTimeDuration = (variant: squiggleValue): option => switch variant { diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Module.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Module.res deleted file mode 100644 index 12021fbf..00000000 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Module.res +++ /dev/null @@ -1,16 +0,0 @@ -type squiggleValue = ForTS_SquiggleValue.squiggleValue //use -@genType type squiggleValue_Module = ForTS_SquiggleValue.squiggleValue_Module //re-export recursive type - -@genType -let getKeyValuePairs = (v: squiggleValue_Module): array<(string, squiggleValue)> => - v->Reducer_Bindings.toKeyValuePairs - -@genType -let toString = (v: squiggleValue_Module): string => - ReducerInterface_InternalExpressionValue.toStringNameSpace(v) - -@genType -let toSquiggleValue = (v: squiggleValue_Module): squiggleValue => IEvBindings(v) - -@genType -let get = (v: squiggleValue_Module, k: string): option => Reducer_Bindings.get(v, k) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_tag.ts b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_tag.ts index 45957e8d..31174e84 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_tag.ts +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_tag.ts @@ -2,16 +2,13 @@ export enum squiggleValueTag { Array = "Array", ArrayString = "ArrayString", Bool = "Bool", - // Call = "Call", Date = "Date", Declaration = "Declaration", Distribution = "Distribution", Lambda = "Lambda", - Module = "Module", Number = "Number", Record = "Record", String = "String", - // Symbol = "Symbol", TimeDuration = "TimeDuration", Type = "Type", TypeIdentifier = "TypeIdentifier", diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res index b97c93e0..b36aaf81 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res @@ -6,7 +6,6 @@ @genType type squiggleValue_Array = ForTS_SquiggleValue_Array.squiggleValue_Array //re-export @genType type squiggleValue_Declaration = ForTS_SquiggleValue_Declaration.squiggleValue_Declaration //re-export @genType type squiggleValue_Lambda = ForTS_SquiggleValue_Lambda.squiggleValue_Lambda //re-export -@genType type squiggleValue_Module = ForTS_SquiggleValue_Module.squiggleValue_Module //re-export @genType type squiggleValue_Record = ForTS_SquiggleValue_Record.squiggleValue_Record //re-export @genType type squiggleValue_Type = ForTS_SquiggleValue_Type.squiggleValue_Type //re-export 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 d58a7abd..ddf250dc 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 @@ -4,13 +4,11 @@ module ExpressionT = Reducer_Expression_T module T = Reducer_T -type t = Reducer_T.nameSpace +type t = Reducer_T.bindings type internalExpressionValue = Reducer_T.value -let rec get = (nameSpace: t, id: string) => { - let T.NameSpace(container, parent) = nameSpace - - switch container->Belt.MutableMap.String.get(id) { +let rec get = ({ namespace, parent }: t, id: string) => { + switch namespace->Reducer_Namespace.get(id) { | Some(v) => Some(v) | None => switch parent { @@ -20,64 +18,38 @@ let rec get = (nameSpace: t, id: string) => { } } -let getWithDefault = (nameSpace: t, id: string, default) => - switch get(nameSpace, id) { +let getWithDefault = (namespace: t, id: string, default) => + switch namespace->get(id) { | Some(v) => Some(v) | None => default } -let toString = ReducerInterface_InternalExpressionValue.toStringNameSpace - -let makeEmptyMap = () => Belt.MutableMap.String.make() - -let set = (nameSpace: t, id: string, value): t => { - let T.NameSpace(container, _) = nameSpace - Belt.MutableMap.String.set(container, id, value) - nameSpace +let set = ({ namespace } as bindings: t, id: string, value): t => { + let _ = namespace->Reducer_Namespace.set(id, value) + bindings } -let extend = (nameSpace: t) => T.NameSpace(makeEmptyMap(), nameSpace->Some) +let rec toString = ({ namespace, parent }: t) => { + let pairs = namespace->Reducer_Namespace.toString -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) -let fromExpressionValue = (aValue: internalExpressionValue): t => - switch aValue { - | IEvBindings(nameSpace) => nameSpace - | _ => makeEmptyBindings() + switch parent { + | Some(p) => `{${pairs}} / ${toString(p)}` + | None => `{${pairs}}` } - -let fromArray = a => T.NameSpace(Belt.MutableMap.String.fromArray(a), None) - -let mergeFrom = (T.NameSpace(container, _): t, T.NameSpace(newContainer, parent): t): t => { - NameSpace( - newContainer->Belt.MutableMap.String.reduce(container, (container, key, value) => { - if key != "__result__" { - Belt.MutableMap.String.set(container, key, value) - } - container - }), - parent, - ) } -let chainTo = (nameSpace: t, previousNameSpaces: array) => { - previousNameSpaces->Belt.Array.reduce(nameSpace, (topNameSpace, prevNameSpace) => - mergeFrom(prevNameSpace, topNameSpace) - ) +let extend = (bindings: t): t => { namespace: Reducer_Namespace.make(), parent: bindings->Some } + +let make = (): t => { namespace: Reducer_Namespace.make(), parent: None } + +let removeResult = ({ namespace } as bindings: t): t => { + namespace->Belt.MutableMap.String.remove("__result__") + bindings } -let removeResult = (nameSpace: t): t => { - let T.NameSpace(container, _) = nameSpace - container->Belt.MutableMap.String.remove("__result__") - nameSpace -} +let locals = ({ namespace }: t): Reducer_T.namespace => namespace -let locals = (T.NameSpace(container, _): t) => T.NameSpace(container, None) +let fromNamespace = (namespace: Reducer_Namespace.t): t => { namespace, parent: None } // let typeAliasesKey = "_typeAliases_" // let typeReferencesKey = "_typeReferences_" diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res index 9fed751c..60adcb1e 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res @@ -1,8 +1,8 @@ type t = Reducer_T.context -let createContext = (stdLib: Reducer_T.nameSpace, environment: Reducer_T.environment): t => { +let createContext = (stdLib: Reducer_Namespace.t, environment: Reducer_T.environment): t => { { - bindings: stdLib->Reducer_Bindings.extend, + bindings: stdLib->Reducer_Bindings.fromNamespace, environment: environment, } } 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 bec8bb44..6d032523 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 @@ -1,5 +1,5 @@ module Bindings = Reducer_Bindings -module Continuation = ReducerInterface_Value_Continuation +// module Continuation = ReducerInterface_Value_Continuation module ExpressionT = Reducer_Expression_T module ExternalLibrary = ReducerInterface.ExternalLibrary module InternalExpressionValue = ReducerInterface_InternalExpressionValue @@ -52,11 +52,11 @@ let callInternal = ( // | None => REArrayIndexNotFound("Array index not found", Belt.Int.fromFloat(fIndex))->Error // } - let moduleAtIndex = (nameSpace: Reducer_T.nameSpace, sIndex) => - switch Bindings.get(nameSpace, sIndex) { - | Some(value) => value->Ok - | None => RERecordPropertyNotFound("Bindings property not found", sIndex)->Error - } + // let moduleAtIndex = (nameSpace: Reducer_T.nameSpace, sIndex) => + // switch Bindings.get(nameSpace, sIndex) { + // | Some(value) => value->Ok + // | None => RERecordPropertyNotFound("Bindings property not found", sIndex)->Error + // } // let recordAtIndex = (dict: Belt.Map.String.t, sIndex) => // switch Belt.Map.String.get(dict, sIndex) { @@ -109,7 +109,7 @@ let callInternal = ( switch call { // | ("$_atIndex_$", [IEvArray(aValueArray), IEvNumber(fIndex)]) => arrayAtIndex(aValueArray, fIndex) - | ("$_atIndex_$", [IEvBindings(dict), IEvString(sIndex)]) => moduleAtIndex(dict, sIndex) + // | ("$_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) 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 08e51890..4d87e534 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 @@ -8,9 +8,6 @@ let eArray = (anArray: array) => anArray->T.EArray let eArrayString = anArray => anArray->T.IEvArrayString->T.EValue -let eBindings = (anArray: array<(string, T.value)>) => - anArray->Reducer_Bindings.fromArray->Reducer_Bindings.toExpressionValue->T.EValue - let eBool = aBool => aBool->T.IEvBool->T.EValue let eCall = (fn: expression, args: array): expression => T.ECall(fn, args) @@ -29,8 +26,6 @@ let eBlock = (exprs: array): expression => T.EBlock(exprs) let eProgram = (exprs: array): expression => T.EProgram(exprs) -let eModule = (nameSpace: T.nameSpace): expression => nameSpace->T.IEvBindings->T.EValue - let eLetStatement = (symbol: string, valueExpression: expression): expression => T.EAssign( symbol, valueExpression, 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 5f52fe12..49ca0cde 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 @@ -14,7 +14,7 @@ let doLambdaCall = ( let makeLambda = ( parameters: array, - bindings: Reducer_T.nameSpace, + bindings: Reducer_T.bindings, body: Reducer_T.expression, ): Reducer_T.lambdaValue => { // TODO - clone bindings to avoid later redefinitions affecting lambdas? diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res new file mode 100644 index 00000000..581f765b --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res @@ -0,0 +1,38 @@ +type t = Reducer_T.namespace + +let make = (): t => Belt.MutableMap.String.make() + +let get = (namespace: t, id: string): option => + namespace->Belt.MutableMap.String.get(id) + +let set = (namespace: t, id: string, value): t => { + namespace->Belt.MutableMap.String.set(id, value) + namespace +} + +let mergeFrom = (from: t, to: t): t => { + to->Belt.MutableMap.String.reduce(from, (namespace, key, value) => { + if key != "__result__" { + namespace->Belt.MutableMap.String.set(key, value) + } + namespace + }) +} + +let mergeMany = (namespaces: array): t => + Belt.Array.reduce(namespaces, make(), (acc, ns) => acc->mergeFrom(ns)) + +let toString = (namespace: t) => + namespace + ->Belt.MutableMap.String.toArray + ->Belt.Array.map(((eachKey, eachValue)) => `${eachKey}: ${eachValue->ReducerInterface_InternalExpressionValue.toString}`) + ->Js.Array2.toString + +let fromArray = (a): t => + Belt.MutableMap.String.fromArray(a) + +let toMap = (namespace: t): Reducer_T.map => + namespace->Belt.MutableMap.String.toArray->Belt.Map.String.fromArray + +let toRecord = (namespace: t): Reducer_T.value => + namespace->toMap->IEvRecord diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res index 7e71e343..08f0b74a 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res @@ -9,7 +9,6 @@ type rec value = | IEvDeclaration(lambdaDeclaration) | IEvDistribution(DistributionTypes.genericDist) | IEvLambda(lambdaValue) - | IEvBindings(nameSpace) | IEvNumber(float) | IEvRecord(map) | IEvString(string) @@ -19,17 +18,17 @@ type rec value = | IEvVoid @genType.opaque and arrayValue = array @genType.opaque and map = Belt.Map.String.t -@genType.opaque and nameSpace = NameSpace(Belt.MutableMap.String.t, option) and lambdaBody = (array, environment, reducerFn) => value @genType.opaque and lambdaValue = { parameters: array, - body: (array, environment, reducerFn) => value, + body: lambdaBody, } @genType.opaque and lambdaDeclaration = Declaration.declaration and expression = | EBlock(array) - | EProgram(array) // programs are similar to blocks, but don't create an inner scope. there can be only one program at the top level of the expression. + // programs are similar to blocks, but don't create an inner scope. there can be only one program at the top level of the expression. + | EProgram(array) | EArray(array) | ERecord(array<(expression, expression)>) | ESymbol(string) @@ -39,8 +38,14 @@ and expression = | ELambda(array, expression) | EValue(value) +and namespace = Belt.MutableMap.String.t +and bindings = { + namespace: namespace, + parent: option, +} + and context = { - bindings: nameSpace, + bindings: bindings, environment: environment, } diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res index 9ef0c3bf..5e880820 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res @@ -18,9 +18,7 @@ let rec toString = (aValue: T.value) => switch aValue { | IEvArray(anArray) => toStringArray(anArray) | IEvArrayString(anArray) => toStringArrayString(anArray) - | IEvBindings(m) => toStringBindings(m) | IEvBool(aBool) => toStringBool(aBool) - // | IEvCall(fName) => toStringCall(fName) | IEvDate(date) => toStringDate(date) | IEvDeclaration(d) => toStringDeclaration(d) | IEvDistribution(dist) => toStringDistribution(dist) @@ -28,7 +26,6 @@ let rec toString = (aValue: T.value) => | IEvNumber(aNumber) => toStringNumber(aNumber) | IEvRecord(aMap) => aMap->toStringRecord | IEvString(aString) => toStringString(aString) - // | IEvSymbol(aString) => toStringSymbol(aString) | IEvTimeDuration(t) => toStringTimeDuration(t) | IEvType(aMap) => toStringType(aMap) | IEvTypeIdentifier(id) => toStringTypeIdentifier(id) @@ -42,7 +39,6 @@ and toStringArrayString = anArray => { let args = anArray->Js.Array2.toString `[${args}]` } -and toStringBindings = m => `@${m->toStringNameSpace}` and toStringBool = aBool => Js.String.make(aBool) and toStringCall = fName => `:${fName}` and toStringDate = date => DateTime.Date.toString(date) @@ -69,35 +65,19 @@ and toStringMap = aMap => { ->Js.Array2.toString `{${pairs}}` } -and toStringNameSpace = nameSpace => { - let T.NameSpace(container, parent) = nameSpace - let pairs = - container - ->Belt.MutableMap.String.toArray - ->Js.Array2.map(((eachKey, eachValue)) => `${eachKey}: ${toString(eachValue)}`) - ->Js.Array2.toString - - switch parent { - | Some(p) => `{${pairs}} / ${toStringNameSpace(p)}` - | None => `{${pairs}}` - } -} let toStringWithType = (aValue: T.value) => switch aValue { | IEvArray(_) => `Array::${toString(aValue)}` | IEvArrayString(_) => `ArrayString::${toString(aValue)}` | IEvBool(_) => `Bool::${toString(aValue)}` - // | IEvCall(_) => `Call::${toString(aValue)}` | IEvDate(_) => `Date::${toString(aValue)}` | IEvDeclaration(_) => `Declaration::${toString(aValue)}` | IEvDistribution(_) => `Distribution::${toString(aValue)}` | IEvLambda(_) => `Lambda::${toString(aValue)}` - | IEvBindings(_) => `Bindings::${toString(aValue)}` | IEvNumber(_) => `Number::${toString(aValue)}` | IEvRecord(_) => `Record::${toString(aValue)}` | IEvString(_) => `String::${toString(aValue)}` - // | IEvSymbol(_) => `Symbol::${toString(aValue)}` | IEvTimeDuration(_) => `Date::${toString(aValue)}` | IEvType(_) => `Type::${toString(aValue)}` | IEvTypeIdentifier(_) => `TypeIdentifier::${toString(aValue)}` @@ -138,16 +118,13 @@ type internalExpressionValueType = | EvtArray | EvtArrayString | EvtBool - // | EvtCall | EvtDate | EvtDeclaration | EvtDistribution | EvtLambda - | EvtModule | EvtNumber | EvtRecord | EvtString - // | EvtSymbol | EvtTimeDuration | EvtType | EvtTypeIdentifier @@ -162,16 +139,13 @@ let valueToValueType = (value: T.value) => | IEvArray(_) => EvtArray | IEvArrayString(_) => EvtArrayString | IEvBool(_) => EvtBool - // | IEvCall(_) => EvtCall | IEvDate(_) => EvtDate | IEvDeclaration(_) => EvtDeclaration | IEvDistribution(_) => EvtDistribution | IEvLambda(_) => EvtLambda - | IEvBindings(_) => EvtModule | IEvNumber(_) => EvtNumber | IEvRecord(_) => EvtRecord | IEvString(_) => EvtString - // | IEvSymbol(_) => EvtSymbol | IEvTimeDuration(_) => EvtTimeDuration | IEvType(_) => EvtType | IEvTypeIdentifier(_) => EvtTypeIdentifier @@ -193,7 +167,6 @@ let valueTypeToString = (valueType: internalExpressionValueType): string => | EvtDeclaration => `Declaration` | EvtDistribution => `Distribution` | EvtLambda => `Lambda` - | EvtModule => `Module` | EvtNumber => `Number` | EvtRecord => `Record` | EvtString => `String` diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res index d9bc517a..6b757b9a 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res @@ -1,12 +1,12 @@ exception ErrorException = Reducer_ErrorValue.ErrorException -let internalStdLib: Reducer_Bindings.t = { +let internalStdLib: Reducer_T.namespace = { let res = - Reducer_Bindings.makeEmptyBindings() - ->SquiggleLibrary_Math.makeBindings - ->SquiggleLibrary_Versions.makeBindings + Reducer_Namespace.make() + ->Reducer_Namespace.mergeFrom(SquiggleLibrary_Math.make()) + ->Reducer_Namespace.mergeFrom(SquiggleLibrary_Versions.make()) - let _ = res->Reducer_Bindings.set( + let _ = res->Reducer_Namespace.set( "$_atIndex_$", Reducer_Expression_Lambda.makeFFILambda((inputs, _, _) => { switch inputs { @@ -31,7 +31,7 @@ let internalStdLib: Reducer_Bindings.t = { FunctionRegistry_Library.nonRegistryLambdas->Js.Array2.forEach( ((name, lambda)) => { - let _ = res->Reducer_Bindings.set(name, lambda->Reducer_T.IEvLambda) + let _ = res->Reducer_Namespace.set(name, lambda->Reducer_T.IEvLambda) } ) @@ -62,7 +62,7 @@ let internalStdLib: Reducer_Bindings.t = { FunctionRegistry_Library.registry.fnNameDict ->Js.Dict.keys ->Js.Array2.forEach(name => { - let _ = res->Reducer_Bindings.set( + let _ = res->Reducer_Namespace.set( name, Reducer_Expression_Lambda.makeFFILambda((arguments, environment, reducer) => { switch FunctionRegistry_Library.call(name, arguments, environment, reducer) { diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Value/ReducerInterface_Value_Continuation.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Value/ReducerInterface_Value_Continuation.res deleted file mode 100644 index d22d75dd..00000000 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Value/ReducerInterface_Value_Continuation.res +++ /dev/null @@ -1,21 +0,0 @@ -module InternalExpressionValue = ReducerInterface_InternalExpressionValue - -type t = Reducer_T.nameSpace - -let toValue = nameSpace => Reducer_T.IEvBindings(nameSpace) -let toString = nameSpace => InternalExpressionValue.toString(toValue(nameSpace)) -let toStringResult = rNameSpace => - Belt.Result.map(rNameSpace, toValue(_))->InternalExpressionValue.toStringResult -let toStringOptionResult = orNameSpace => - Belt.Option.map( - orNameSpace, - Belt.Result.map(_, toValue(_)), - )->InternalExpressionValue.toStringOptionResult - -let inspect = (nameSpace, label: string) => Js.log(`${label}: ${toString(nameSpace)}`) - -let inspectOption = (oNameSpace, label: string) => - switch oNameSpace { - | Some(nameSpace) => inspect(nameSpace, label) - | None => Js.log(`${label}: None`) - } diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res index 0730dee0..ea888d71 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res @@ -1,7 +1,6 @@ // TODO: Auto clean project based on topology module Bindings = Reducer_Bindings -module Continuation = ReducerInterface_Value_Continuation module ErrorValue = Reducer_ErrorValue module InternalExpressionValue = ReducerInterface_InternalExpressionValue module ProjectItem = ReducerProject_ProjectItem @@ -97,7 +96,7 @@ let setContinues = (project: t, sourceId: string, continues: array): uni handleNewTopology(project) } let getContinues = (project: t, sourceId: string): array => - ProjectItem.getContinues(project->getItem(sourceId)) + project->getItem(sourceId)->ProjectItem.getContinues let removeContinues = (project: t, sourceId: string): unit => { let newItem = project->getItem(sourceId)->ProjectItem.removeContinues @@ -105,9 +104,6 @@ let removeContinues = (project: t, sourceId: string): unit => { handleNewTopology(project) } -let getContinuation = (project: t, sourceId: string): ProjectItem.T.continuationArgumentType => - project->getItem(sourceId)->ProjectItem.getContinuation - let setContinuation = ( project: t, sourceId: string, @@ -142,8 +138,8 @@ let rawParse = (project: t, sourceId): unit => { project->setItem(sourceId, newItem) } -let getStdLib = (project: t): Reducer_Bindings.t => project.stdLib -let setStdLib = (project: t, value: Reducer_Bindings.t): unit => { +let getStdLib = (project: t): Reducer_T.namespace => project.stdLib +let setStdLib = (project: t, value: Reducer_T.namespace): unit => { project.stdLib = value } @@ -152,47 +148,41 @@ let setEnvironment = (project: t, value: InternalExpressionValue.environment): u project.environment = value } -let getBindings = (project: t, sourceId: string): ProjectItem.T.bindingsArgumentType => { - project->getContinuation(sourceId)->Reducer_Bindings.locals +let getBindings = (project: t, sourceId: string): Reducer_T.namespace => { + project->getItem(sourceId)->ProjectItem.getContinuation } -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 { - // `getContinuationBefore ${sourceId}: stdLib`->Js.log - [project->getStdLib] - } else { - // `getContinuationBefore ${sourceId}: ${lastOne} = ${InternalExpressionValue.toStringBindings( - // project->getBindings(lastOne), - // )}`->Js.log - pastNameSpaces - } +let getBindingsAsRecord = (project: t, sourceId: string): Reducer_T.value => { + project->getBindings(sourceId)->Reducer_Namespace.toRecord } -let linkDependencies = (project: t, sourceId: string): ProjectItem.T.continuation => { - let continuationsBefore = project->getContinuationsBefore(sourceId) - let nameSpace = - Reducer_Bindings.makeEmptyBindings()->Reducer_Bindings.chainTo(continuationsBefore) +let getContinuationsBefore = (project: t, sourceId: string): array => { + project->getPastChain(sourceId)->Belt.Array.map(project->getBindings) +} + +let linkDependencies = (project: t, sourceId: string): Reducer_T.namespace => { + let nameSpace = Reducer_Namespace.mergeMany( + Belt.Array.concat( + [project->getStdLib], + project->getContinuationsBefore(sourceId) + ) + ) + let includesAsVariables = project->getIncludesAsVariables(sourceId) - Belt.Array.reduce(includesAsVariables, nameSpace, (currentNameSpace, (variable, includeFile)) => - Bindings.set( - currentNameSpace, + Belt.Array.reduce(includesAsVariables, nameSpace, (acc, (variable, includeFile)) => + acc->Reducer_Namespace.set( variable, - getBindings(project, includeFile)->Reducer_T.IEvBindings, + project->getBindings(includeFile)->Reducer_Namespace.toRecord ) ) } let doLinkAndRun = (project: t, sourceId: string): unit => { - let context = Reducer_Context.createContext(project->getStdLib, project->getEnvironment) - // FIXME: fill context with dependencies - let continuation = linkDependencies(project, sourceId) - let contextWithContinuation = { - ...context, - bindings: continuation->Reducer_Bindings.extend, - } - let newItem = project->getItem(sourceId)->ProjectItem.run(contextWithContinuation) + let context = Reducer_Context.createContext( + project->linkDependencies(sourceId), + project->getEnvironment + ) + let newItem = project->getItem(sourceId)->ProjectItem.run(context) // Js.log("after run " ++ newItem.continuation->Reducer_Bindings.toString) project->setItem(sourceId, newItem) } @@ -243,6 +233,6 @@ let evaluate = (sourceCode: string) => { ( getResultOption(project, "main")->Belt.Option.getWithDefault(Reducer_T.IEvVoid->Ok), - project->getBindings("main"), + project->getBindings("main")->Reducer_Namespace.toMap, ) } diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res index e870bcfb..271b3ac9 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res @@ -8,7 +8,7 @@ let emptyItem: projectItem = { source: "", rawParse: None, expression: None, - continuation: Reducer_Bindings.makeEmptyBindings(), + continuation: Reducer_Namespace.make(), result: None, continues: [], includes: []->Ok, @@ -168,14 +168,14 @@ let buildExpression = (this: t): t => { } let failRun = (this: t, e: Reducer_ErrorValue.errorValue): t => - this->setResult(e->Error)->setContinuation(Reducer_Bindings.makeEmptyBindings()) + this->setResult(e->Error)->setContinuation(Reducer_Namespace.make()) 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) + this->setResult(result->Ok)->setContinuation(context.bindings->Reducer_Bindings.locals) } catch { | Reducer_ErrorValue.ErrorException(e) => this->failRun(e) | _ => this->failRun(RETodo("unhandled rescript exception")) diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem_T.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem_T.res index e696534e..bf1cbfcb 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem_T.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem_T.res @@ -8,12 +8,9 @@ type rawParseArgumentType = result type rawParseType = option type expressionArgumentType = result type expressionType = option -type continuation = Reducer_T.nameSpace -type continuationArgumentType = Reducer_T.nameSpace +type continuationArgumentType = Reducer_T.namespace type continuationType = option type continuationResultType = option> -type bindingsArgumentType = Reducer_T.nameSpace -type bindingsType = option type resultArgumentType = result type resultType = option type continuesArgumentType = array diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res index 78a3e2a3..8d53e7fe 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res @@ -4,7 +4,7 @@ module ExpressionT = Reducer_Expression_T @genType.opaque type project = { items: Belt.MutableMap.String.t, - mutable stdLib: Reducer_Bindings.t, + mutable stdLib: Reducer_Namespace.t, mutable environment: ExpressionT.environment, mutable previousRunOrder: array, } diff --git a/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Math.res b/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Math.res index 2a433c5a..4682fa01 100644 --- a/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Math.res +++ b/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Math.res @@ -1,5 +1,3 @@ -module Bindings = Reducer_Bindings - let availableNumbers: array<(string, float)> = [ ("Math.pi", Js.Math._PI), ("Math.e", Js.Math._E), @@ -13,8 +11,5 @@ let availableNumbers: array<(string, float)> = [ ("Math.tau", 6.283185307179586), ] -let mathBindings: Bindings.t = - availableNumbers->E.A2.fmap(((name, v)) => (name, Reducer_T.IEvNumber(v)))->Bindings.fromArray - -let makeBindings = (previousBindings: Bindings.t): Bindings.t => - previousBindings->Bindings.mergeFrom(mathBindings) +let make = (): Reducer_Namespace.t => + availableNumbers->E.A2.fmap(((name, v)) => (name, Reducer_T.IEvNumber(v)))->Reducer_Namespace.fromArray diff --git a/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Versions.res b/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Versions.res index 30b64b81..70cf7b1e 100644 --- a/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Versions.res +++ b/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Versions.res @@ -1,7 +1,2 @@ -module Bindings = Reducer_Bindings - -let bindings: Reducer_T.nameSpace = - [("System.version", Reducer_T.IEvString("0.4.0-dev"))]->Bindings.fromArray - -let makeBindings = (previousBindings: Reducer_T.nameSpace): Reducer_T.nameSpace => - previousBindings->Bindings.mergeFrom(bindings) +let make = (): Reducer_Namespace.t => + [("System.version", Reducer_T.IEvString("0.4.0-dev"))]->Reducer_Namespace.fromArray From 89397d3584288ec94ecac0db9873f41a099bd10a Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Sat, 17 Sep 2022 00:41:58 +0400 Subject: [PATCH 14/46] ERecord->toString, fix warning --- .../src/rescript/FunctionRegistry/Library/FR_Danger.res | 2 +- .../Reducer/Reducer_Expression/Reducer_Expression_T.res | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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 c3d25799..71624f60 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Danger.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Danger.res @@ -245,7 +245,7 @@ module DiminishingReturns = { optimalAllocations: array, currentMarginalReturns: result, errorValue>, } - let findBiggestElementIndex = xs => + let findBiggestElementIndex = (xs: array) => E.A.reducei(xs, 0, (acc, newElement, index) => { switch newElement > xs[acc] { | true => index 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 b1eb6058..91fb3b1c 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 @@ -30,7 +30,7 @@ let rec toString = (expression: 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}]` - | ERecord(map) => "TODO" + | ERecord(map) => `{${map->Belt.Array.map(((key, value)) => `${key->toString}: ${value->toString}`)->Js.Array2.toString}}` | ESymbol(name) => name | ETernary(predicate, trueCase, falseCase) => `${predicate->toString} ? (${trueCase->toString}) : (${falseCase->toString})` From 065a7aeec01e492aca700ed0669593c4db011956 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Sun, 18 Sep 2022 02:19:08 +0400 Subject: [PATCH 15/46] immutable bindings; test fixes --- .../Reducer_Bindings_test.res | 43 ++- .../__tests__/Reducer/Reducer_Helpers.res | 10 +- .../Reducer/Reducer_Namespace_test.res | 57 ++++ .../Reducer_Peggy_Parse_test.res | 265 +++++++++--------- ...cer_Peggy_ToExpression_outerBlock_test.res | 10 +- .../Reducer_Peggy_ToExpression_test.res | 103 +++---- .../Reducer/Reducer_constructArray_test.res | 6 +- .../Reducer_functionAssignment_test.res | 4 +- .../Reducer/Reducer_ternaryOperator_test.res | 2 +- .../ReducerInterface_Distribution_test.res | 20 +- .../ReducerProject_includes_test.res | 218 +++++++------- .../ReducerProject/ReducerProject_test.res | 27 +- .../ReducerProject_tutorial_1_test.res | 40 +-- ...cerProject_tutorial_2_multisource_test.res | 59 ++-- ...educerProject_tutorial_3_includes_test.res | 52 ++-- packages/squiggle-lang/bsconfig.json | 10 +- packages/squiggle-lang/scripts/run-file.js | 2 +- packages/squiggle-lang/src/js/SqRecord.ts | 4 + .../FunctionRegistry_Core.res | 5 + .../FunctionRegistry/Library/FR_Builtin.res | 22 +- .../Reducer_Bindings/Reducer_Bindings.res | 26 +- .../src/rescript/Reducer/Reducer_Context.res | 2 +- .../Reducer_Dispatch_BuiltIn.res | 34 --- .../Reducer_Expression/Reducer_Expression.res | 93 +++--- .../Reducer_Expression_Lambda.res | 9 +- .../Reducer_Expression_T.res | 46 +-- .../rescript/Reducer/Reducer_Namespace.res | 20 +- .../src/rescript/Reducer/Reducer_T.res | 4 +- .../ReducerInterface_StdLib.res | 15 +- .../ReducerProject/ReducerProject.res | 18 +- .../ReducerProject_ProjectItem.res | 4 +- .../ReducerProject/ReducerProject_T.res | 3 +- 32 files changed, 637 insertions(+), 596 deletions(-) create mode 100644 packages/squiggle-lang/__tests__/Reducer/Reducer_Namespace_test.res diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Bindings/Reducer_Bindings_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Bindings/Reducer_Bindings_test.res index 8b9f2064..f43944d4 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Bindings/Reducer_Bindings_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Bindings/Reducer_Bindings_test.res @@ -1,27 +1,46 @@ @@warning("-44") -module InternalExpressionValue = ReducerInterface_InternalExpressionValue module Bindings = Reducer_Bindings +module Namespace = Reducer_Namespace open Jest open Expect open Expect.Operators -describe("Name Space", () => { +describe("Bindings", () => { let value = Reducer_T.IEvNumber(1967.0) - let nameSpace = Bindings.makeEmptyBindings()->Bindings.set("value", value) + let bindings = Bindings.make()->Bindings.set("value", value) test("get", () => { - expect(Bindings.get(nameSpace, "value")) == Some(value) + expect(bindings->Bindings.get("value")) == Some(value) }) - test("chain and get", () => { - let mainNameSpace = Bindings.makeEmptyBindings()->Bindings.chainTo([nameSpace]) - expect(Bindings.get(mainNameSpace, "value")) == Some(value) + test("get nonexisting value", () => { + expect(bindings->Bindings.get("nosuchvalue")) == None }) - test("chain and set", () => { - let mainNameSpace0 = Bindings.makeEmptyBindings()->Bindings.chainTo([nameSpace]) - let mainNameSpace = - mainNameSpace0->Bindings.set("value", Reducer_T.IEvNumber(1968.0)) - expect(Bindings.get(mainNameSpace, "value")) == Some(Reducer_T.IEvNumber(1968.0)) + test("get on extended", () => { + expect(bindings->Bindings.extend->Bindings.get("value")) == Some(value) + }) + + test("locals", () => { + expect(bindings->Bindings.locals->Namespace.get("value")) == Some(value) + }) + + test("locals on extendeed", () => { + expect(bindings->Bindings.extend->Bindings.locals->Namespace.get("value")) == None + }) + + describe("extend", () => { + let value2 = Reducer_T.IEvNumber(5.) + let extendedBindings = bindings + ->Bindings.extend + ->Bindings.set("value", value2) + + test("get on extended", () => { + expect(extendedBindings->Bindings.get("value")) == Some(value2) + }) + + test("get on original", () => { + expect(bindings->Bindings.get("value")) == Some(value) + }) }) }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Helpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Helpers.res index 706e4c8e..4bbeff17 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Helpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Helpers.res @@ -3,15 +3,7 @@ module ErrorValue = Reducer_ErrorValue module InternalExpressionValue = ReducerInterface.InternalExpressionValue let removeDefaultsInternal = (iev: InternalExpressionValue.t) => { - Not_found->raise - // switch iev { - // | Reducer_T.IEvBindings(nameSpace) => - // Reducer_Bindings.removeOther( - // nameSpace, - // ReducerInterface.StdLib.internalStdLib, - // )->Reducer_T.IEvBindings - // | value => value - // } + iev // TODO - cleanup, noop } let rRemoveDefaultsInternal = r => Belt.Result.map(r, removeDefaultsInternal) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Namespace_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Namespace_test.res new file mode 100644 index 00000000..64401e32 --- /dev/null +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Namespace_test.res @@ -0,0 +1,57 @@ +@@warning("-44") +module Namespace = Reducer_Namespace + +open Jest +open Expect +open Expect.Operators + +let makeValue = (v: float) => v->Reducer_T.IEvNumber + +describe("Namespace", () => { + let value = makeValue(5.) + let v2 = makeValue(2.) + let ns = Namespace.make()->Namespace.set("value", value) + + test("get", () => { + expect(ns->Namespace.get("value")) == Some(value) + }) + + test("get nonexisting value", () => { + expect(ns->Namespace.get("nosuchvalue")) == None + }) + + test("set", () => { + let ns2 = ns->Namespace.set("v2", v2) + expect(ns2->Namespace.get("v2")) == Some(v2) + }) + + test("immutable", () => { + let _ = ns->Namespace.set("v2", Reducer_T.IEvNumber(2.)) + expect(ns->Namespace.get("v2")) == None + }) + + describe("merge many", () => { + let x1 = makeValue(10.) + let x2 = makeValue(20.) + let x3 = makeValue(30.) + let x4 = makeValue(40.) + let ns1 = Namespace.make() + ->Namespace.set("x1", x1) + ->Namespace.set("x2", x2) + let ns2 = Namespace.make() + ->Namespace.set("x3", x3) + ->Namespace.set("x4", x4) + + let nsMerged = Namespace.mergeMany([ns, ns1, ns2]) + + test("merge many 1", () => { + expect(nsMerged->Namespace.get("x1")) == Some(x1) + }) + test("merge many 2", () => { + expect(nsMerged->Namespace.get("x4")) == Some(x4) + }) + test("merge many 3", () => { + expect(nsMerged->Namespace.get("value")) == Some(value) + }) + }) +}) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_Parse_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_Parse_test.res index 3440c3e0..416e0178 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_Parse_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_Parse_test.res @@ -3,346 +3,345 @@ open Reducer_Peggy_TestHelpers describe("Peggy parse", () => { describe("float", () => { - testParse("1.", "{(::$_endOfOuterBlock_$ () 1)}") - testParse("1.1", "{(::$_endOfOuterBlock_$ () 1.1)}") - testParse(".1", "{(::$_endOfOuterBlock_$ () 0.1)}") - testParse("0.1", "{(::$_endOfOuterBlock_$ () 0.1)}") - testParse("1e1", "{(::$_endOfOuterBlock_$ () 10)}") - testParse("1e-1", "{(::$_endOfOuterBlock_$ () 0.1)}") - testParse(".1e1", "{(::$_endOfOuterBlock_$ () 1)}") - testParse("0.1e1", "{(::$_endOfOuterBlock_$ () 1)}") + testParse("1.", "{1}") + testParse("1.1", "{1.1}") + testParse(".1", "{0.1}") + testParse("0.1", "{0.1}") + testParse("1e1", "{10}") + testParse("1e-1", "{0.1}") + testParse(".1e1", "{1}") + testParse("0.1e1", "{1}") }) describe("literals operators parenthesis", () => { - // Note that there is always an outer block. Otherwise, external bindings are ignrored at the first statement - testParse("1", "{(::$_endOfOuterBlock_$ () 1)}") - testParse("'hello'", "{(::$_endOfOuterBlock_$ () 'hello')}") - testParse("true", "{(::$_endOfOuterBlock_$ () true)}") - testParse("1+2", "{(::$_endOfOuterBlock_$ () (::add 1 2))}") - testParse("add(1,2)", "{(::$_endOfOuterBlock_$ () (::add 1 2))}") - testParse("(1)", "{(::$_endOfOuterBlock_$ () 1)}") - testParse("(1+2)", "{(::$_endOfOuterBlock_$ () (::add 1 2))}") + testParse("1", "{1}") + testParse("'hello'", "{'hello'}") + testParse("true", "{true}") + testParse("1+2", "{(:add 1 2)}") + testParse("add(1,2)", "{(:add 1 2)}") + testParse("(1)", "{1}") + testParse("(1+2)", "{(:add 1 2)}") }) describe("unary", () => { - testParse("-1", "{(::$_endOfOuterBlock_$ () (::unaryMinus 1))}") - testParse("!true", "{(::$_endOfOuterBlock_$ () (::not true))}") - testParse("1 + -1", "{(::$_endOfOuterBlock_$ () (::add 1 (::unaryMinus 1)))}") - testParse("-a[0]", "{(::$_endOfOuterBlock_$ () (::unaryMinus (::$_atIndex_$ :a 0)))}") - testParse("!a[0]", "{(::$_endOfOuterBlock_$ () (::not (::$_atIndex_$ :a 0)))}") + testParse("-1", "{(:unaryMinus 1)}") + testParse("!true", "{(:not true)}") + testParse("1 + -1", "{(:add 1 (:unaryMinus 1))}") + testParse("-a[0]", "{(:unaryMinus (:$_atIndex_$ :a 0))}") + testParse("!a[0]", "{(:not (:$_atIndex_$ :a 0))}") }) describe("multiplicative", () => { - testParse("1 * 2", "{(::$_endOfOuterBlock_$ () (::multiply 1 2))}") - testParse("1 / 2", "{(::$_endOfOuterBlock_$ () (::divide 1 2))}") - testParse("1 * 2 * 3", "{(::$_endOfOuterBlock_$ () (::multiply (::multiply 1 2) 3))}") - testParse("1 * 2 / 3", "{(::$_endOfOuterBlock_$ () (::divide (::multiply 1 2) 3))}") - testParse("1 / 2 * 3", "{(::$_endOfOuterBlock_$ () (::multiply (::divide 1 2) 3))}") - testParse("1 / 2 / 3", "{(::$_endOfOuterBlock_$ () (::divide (::divide 1 2) 3))}") + testParse("1 * 2", "{(:multiply 1 2)}") + testParse("1 / 2", "{(:divide 1 2)}") + testParse("1 * 2 * 3", "{(:multiply (:multiply 1 2) 3)}") + testParse("1 * 2 / 3", "{(:divide (:multiply 1 2) 3)}") + testParse("1 / 2 * 3", "{(:multiply (:divide 1 2) 3)}") + testParse("1 / 2 / 3", "{(:divide (:divide 1 2) 3)}") testParse( "1 * 2 + 3 * 4", - "{(::$_endOfOuterBlock_$ () (::add (::multiply 1 2) (::multiply 3 4)))}", + "{(:add (:multiply 1 2) (:multiply 3 4))}", ) testParse( "1 * 2 - 3 * 4", - "{(::$_endOfOuterBlock_$ () (::subtract (::multiply 1 2) (::multiply 3 4)))}", + "{(:subtract (:multiply 1 2) (:multiply 3 4))}", ) testParse( "1 * 2 .+ 3 * 4", - "{(::$_endOfOuterBlock_$ () (::dotAdd (::multiply 1 2) (::multiply 3 4)))}", + "{(:dotAdd (:multiply 1 2) (:multiply 3 4))}", ) testParse( "1 * 2 .- 3 * 4", - "{(::$_endOfOuterBlock_$ () (::dotSubtract (::multiply 1 2) (::multiply 3 4)))}", + "{(:dotSubtract (:multiply 1 2) (:multiply 3 4))}", ) testParse( "1 * 2 + 3 .* 4", - "{(::$_endOfOuterBlock_$ () (::add (::multiply 1 2) (::dotMultiply 3 4)))}", + "{(:add (:multiply 1 2) (:dotMultiply 3 4))}", ) testParse( "1 * 2 + 3 / 4", - "{(::$_endOfOuterBlock_$ () (::add (::multiply 1 2) (::divide 3 4)))}", + "{(:add (:multiply 1 2) (:divide 3 4))}", ) testParse( "1 * 2 + 3 ./ 4", - "{(::$_endOfOuterBlock_$ () (::add (::multiply 1 2) (::dotDivide 3 4)))}", + "{(:add (:multiply 1 2) (:dotDivide 3 4))}", ) testParse( "1 * 2 - 3 .* 4", - "{(::$_endOfOuterBlock_$ () (::subtract (::multiply 1 2) (::dotMultiply 3 4)))}", + "{(:subtract (:multiply 1 2) (:dotMultiply 3 4))}", ) testParse( "1 * 2 - 3 / 4", - "{(::$_endOfOuterBlock_$ () (::subtract (::multiply 1 2) (::divide 3 4)))}", + "{(:subtract (:multiply 1 2) (:divide 3 4))}", ) testParse( "1 * 2 - 3 ./ 4", - "{(::$_endOfOuterBlock_$ () (::subtract (::multiply 1 2) (::dotDivide 3 4)))}", + "{(:subtract (:multiply 1 2) (:dotDivide 3 4))}", ) testParse( "1 * 2 - 3 * 4^5", - "{(::$_endOfOuterBlock_$ () (::subtract (::multiply 1 2) (::multiply 3 (::pow 4 5))))}", + "{(:subtract (:multiply 1 2) (:multiply 3 (:pow 4 5)))}", ) testParse( "1 * 2 - 3 * 4^5^6", - "{(::$_endOfOuterBlock_$ () (::subtract (::multiply 1 2) (::multiply 3 (::pow (::pow 4 5) 6))))}", + "{(:subtract (:multiply 1 2) (:multiply 3 (:pow (:pow 4 5) 6)))}", ) testParse( "1 * -a[-2]", - "{(::$_endOfOuterBlock_$ () (::multiply 1 (::unaryMinus (::$_atIndex_$ :a (::unaryMinus 2)))))}", + "{(:multiply 1 (:unaryMinus (:$_atIndex_$ :a (:unaryMinus 2))))}", ) }) describe("multi-line", () => { - testParse("x=1; 2", "{:x = {1}; (::$_endOfOuterBlock_$ () 2)}") - testParse("x=1; y=2", "{:x = {1}; :y = {2}; (::$_endOfOuterBlock_$ () ())}") + testParse("x=1; 2", "{:x = {1}; 2}") + testParse("x=1; y=2", "{:x = {1}; :y = {2}}") }) describe("variables", () => { - testParse("x = 1", "{:x = {1}; (::$_endOfOuterBlock_$ () ())}") - testParse("x", "{(::$_endOfOuterBlock_$ () :x)}") - testParse("x = 1; x", "{:x = {1}; (::$_endOfOuterBlock_$ () :x)}") + testParse("x = 1", "{:x = {1}}") + testParse("x", "{:x}") + testParse("x = 1; x", "{:x = {1}; :x}") }) describe("functions", () => { - testParse("identity(x) = x", "{:identity = {|:x| {:x}}; (::$_endOfOuterBlock_$ () ())}") // Function definitions become lambda assignments - testParse("identity(x)", "{(::$_endOfOuterBlock_$ () (::identity :x))}") + testParse("identity(x) = x", "{:identity = {|:x| {:x}}}") // Function definitions become lambda assignments + testParse("identity(x)", "{(:identity :x)}") }) describe("arrays", () => { - testParse("[]", "{(::$_endOfOuterBlock_$ () (::$_constructArray_$))}") - testParse("[0, 1, 2]", "{(::$_endOfOuterBlock_$ () (::$_constructArray_$ 0 1 2))}") + testParse("[]", "{[]}") + testParse("[0, 1, 2]", "{[0; 1; 2]}") testParse( "['hello', 'world']", - "{(::$_endOfOuterBlock_$ () (::$_constructArray_$ 'hello' 'world'))}", + "{['hello'; 'world']}", ) testParse( "([0,1,2])[1]", - "{(::$_endOfOuterBlock_$ () (::$_atIndex_$ (::$_constructArray_$ 0 1 2) 1))}", + "{(:$_atIndex_$ [0; 1; 2] 1)}", ) }) describe("records", () => { testParse( "{a: 1, b: 2}", - "{(::$_endOfOuterBlock_$ () (::$_constructRecord_$ ('a': 1 'b': 2)))}", + "{{'a': 1, 'b': 2}}", ) testParse( "{1+0: 1, 2+0: 2}", - "{(::$_endOfOuterBlock_$ () (::$_constructRecord_$ ((::add 1 0): 1 (::add 2 0): 2)))}", + "{{(:add 1 0): 1, (:add 2 0): 2}}", ) // key can be any expression - testParse("record.property", "{(::$_endOfOuterBlock_$ () (::$_atIndex_$ :record 'property'))}") + testParse("record.property", "{(:$_atIndex_$ :record 'property')}") }) describe("post operators", () => { //function call, array and record access are post operators with higher priority than unary operators - testParse("a==!b(1)", "{(::$_endOfOuterBlock_$ () (::equal :a (::not (::b 1))))}") - testParse("a==!b[1]", "{(::$_endOfOuterBlock_$ () (::equal :a (::not (::$_atIndex_$ :b 1))))}") + testParse("a==!b(1)", "{(:equal :a (:not (:b 1)))}") + testParse("a==!b[1]", "{(:equal :a (:not (:$_atIndex_$ :b 1)))}") testParse( "a==!b.one", - "{(::$_endOfOuterBlock_$ () (::equal :a (::not (::$_atIndex_$ :b 'one'))))}", + "{(:equal :a (:not (:$_atIndex_$ :b 'one')))}", ) }) describe("comments", () => { - testParse("1 # This is a line comment", "{(::$_endOfOuterBlock_$ () 1)}") - testParse("1 // This is a line comment", "{(::$_endOfOuterBlock_$ () 1)}") - testParse("1 /* This is a multi line comment */", "{(::$_endOfOuterBlock_$ () 1)}") - testParse("/* This is a multi line comment */ 1", "{(::$_endOfOuterBlock_$ () 1)}") + testParse("1 # This is a line comment", "{1}") + testParse("1 // This is a line comment", "{1}") + testParse("1 /* This is a multi line comment */", "{1}") + testParse("/* This is a multi line comment */ 1", "{1}") testParse( ` /* This is a multi line comment */ 1`, - "{(::$_endOfOuterBlock_$ () 1)}", + "{1}", ) }) describe("ternary operator", () => { - testParse("true ? 2 : 3", "{(::$_endOfOuterBlock_$ () (::$$_ternary_$$ true 2 3))}") + testParse("true ? 2 : 3", "{(::$$_ternary_$$ true 2 3)}") testParse( "false ? 2 : false ? 4 : 5", - "{(::$_endOfOuterBlock_$ () (::$$_ternary_$$ false 2 (::$$_ternary_$$ false 4 5)))}", + "{(::$$_ternary_$$ false 2 (::$$_ternary_$$ false 4 5))}", ) // nested ternary }) describe("if then else", () => { testParse( "if true then 2 else 3", - "{(::$_endOfOuterBlock_$ () (::$$_ternary_$$ true {2} {3}))}", + "{(::$$_ternary_$$ true {2} {3})}", ) testParse( "if false then {2} else {3}", - "{(::$_endOfOuterBlock_$ () (::$$_ternary_$$ false {2} {3}))}", + "{(::$$_ternary_$$ false {2} {3})}", ) testParse( "if false then {2} else if false then {4} else {5}", - "{(::$_endOfOuterBlock_$ () (::$$_ternary_$$ false {2} (::$$_ternary_$$ false {4} {5})))}", + "{(::$$_ternary_$$ false {2} (::$$_ternary_$$ false {4} {5}))}", ) //nested if }) describe("logical", () => { - testParse("true || false", "{(::$_endOfOuterBlock_$ () (::or true false))}") - testParse("true && false", "{(::$_endOfOuterBlock_$ () (::and true false))}") - testParse("a * b + c", "{(::$_endOfOuterBlock_$ () (::add (::multiply :a :b) :c))}") // for comparison - testParse("a && b || c", "{(::$_endOfOuterBlock_$ () (::or (::and :a :b) :c))}") - testParse("a && b || c && d", "{(::$_endOfOuterBlock_$ () (::or (::and :a :b) (::and :c :d)))}") - testParse("a && !b || c", "{(::$_endOfOuterBlock_$ () (::or (::and :a (::not :b)) :c))}") - testParse("a && b==c || d", "{(::$_endOfOuterBlock_$ () (::or (::and :a (::equal :b :c)) :d))}") + testParse("true || false", "{(:or true false)}") + testParse("true && false", "{(:and true false)}") + testParse("a * b + c", "{(:add (:multiply :a :b) :c)}") // for comparison + testParse("a && b || c", "{(:or (:and :a :b) :c)}") + testParse("a && b || c && d", "{(:or (:and :a :b) (:and :c :d))}") + testParse("a && !b || c", "{(:or (:and :a (:not :b)) :c)}") + testParse("a && b==c || d", "{(:or (:and :a (:equal :b :c)) :d)}") testParse( "a && b!=c || d", - "{(::$_endOfOuterBlock_$ () (::or (::and :a (::unequal :b :c)) :d))}", + "{(:or (:and :a (:unequal :b :c)) :d)}", ) testParse( "a && !(b==c) || d", - "{(::$_endOfOuterBlock_$ () (::or (::and :a (::not (::equal :b :c))) :d))}", + "{(:or (:and :a (:not (:equal :b :c))) :d)}", ) testParse( "a && b>=c || d", - "{(::$_endOfOuterBlock_$ () (::or (::and :a (::largerEq :b :c)) :d))}", + "{(:or (:and :a (:largerEq :b :c)) :d)}", ) testParse( "a && !(b>=c) || d", - "{(::$_endOfOuterBlock_$ () (::or (::and :a (::not (::largerEq :b :c))) :d))}", + "{(:or (:and :a (:not (:largerEq :b :c))) :d)}", ) testParse( "a && b<=c || d", - "{(::$_endOfOuterBlock_$ () (::or (::and :a (::smallerEq :b :c)) :d))}", + "{(:or (:and :a (:smallerEq :b :c)) :d)}", ) - testParse("a && b>c || d", "{(::$_endOfOuterBlock_$ () (::or (::and :a (::larger :b :c)) :d))}") + testParse("a && b>c || d", "{(:or (:and :a (:larger :b :c)) :d)}") testParse( "a && b { - testParse("1 -> add(2)", "{(::$_endOfOuterBlock_$ () (::add 1 2))}") - testParse("-1 -> add(2)", "{(::$_endOfOuterBlock_$ () (::add (::unaryMinus 1) 2))}") + testParse("1 -> add(2)", "{(:add 1 2)}") + testParse("-1 -> add(2)", "{(:add (:unaryMinus 1) 2)}") testParse( "-a[1] -> add(2)", - "{(::$_endOfOuterBlock_$ () (::add (::unaryMinus (::$_atIndex_$ :a 1)) 2))}", + "{(:add (:unaryMinus (:$_atIndex_$ :a 1)) 2)}", ) - testParse("-f(1) -> add(2)", "{(::$_endOfOuterBlock_$ () (::add (::unaryMinus (::f 1)) 2))}") - testParse("1 + 2 -> add(3)", "{(::$_endOfOuterBlock_$ () (::add 1 (::add 2 3)))}") - testParse("1 -> add(2) * 3", "{(::$_endOfOuterBlock_$ () (::multiply (::add 1 2) 3))}") - testParse("1 -> subtract(2)", "{(::$_endOfOuterBlock_$ () (::subtract 1 2))}") - testParse("-1 -> subtract(2)", "{(::$_endOfOuterBlock_$ () (::subtract (::unaryMinus 1) 2))}") + testParse("-f(1) -> add(2)", "{(:add (:unaryMinus (:f 1)) 2)}") + testParse("1 + 2 -> add(3)", "{(:add 1 (:add 2 3))}") + testParse("1 -> add(2) * 3", "{(:multiply (:add 1 2) 3)}") + testParse("1 -> subtract(2)", "{(:subtract 1 2)}") + testParse("-1 -> subtract(2)", "{(:subtract (:unaryMinus 1) 2)}") testParse( "1 -> subtract(2) * 3", - "{(::$_endOfOuterBlock_$ () (::multiply (::subtract 1 2) 3))}", + "{(:multiply (:subtract 1 2) 3)}", ) }) describe("elixir pipe", () => { //handled together with -> so there is no need for seperate tests - testParse("1 |> add(2)", "{(::$_endOfOuterBlock_$ () (::add 1 2))}") + testParse("1 |> add(2)", "{(:add 1 2)}") }) describe("to", () => { - testParse("1 to 2", "{(::$_endOfOuterBlock_$ () (::credibleIntervalToDistribution 1 2))}") + testParse("1 to 2", "{(:credibleIntervalToDistribution 1 2)}") testParse( "-1 to -2", - "{(::$_endOfOuterBlock_$ () (::credibleIntervalToDistribution (::unaryMinus 1) (::unaryMinus 2)))}", + "{(:credibleIntervalToDistribution (:unaryMinus 1) (:unaryMinus 2))}", ) // lower than unary testParse( "a[1] to a[2]", - "{(::$_endOfOuterBlock_$ () (::credibleIntervalToDistribution (::$_atIndex_$ :a 1) (::$_atIndex_$ :a 2)))}", + "{(:credibleIntervalToDistribution (:$_atIndex_$ :a 1) (:$_atIndex_$ :a 2))}", ) // lower than post testParse( "a.p1 to a.p2", - "{(::$_endOfOuterBlock_$ () (::credibleIntervalToDistribution (::$_atIndex_$ :a 'p1') (::$_atIndex_$ :a 'p2')))}", + "{(:credibleIntervalToDistribution (:$_atIndex_$ :a 'p1') (:$_atIndex_$ :a 'p2'))}", ) // lower than post testParse( "1 to 2 + 3", - "{(::$_endOfOuterBlock_$ () (::add (::credibleIntervalToDistribution 1 2) 3))}", + "{(:add (:credibleIntervalToDistribution 1 2) 3)}", ) // higher than binary operators testParse( "1->add(2) to 3->add(4) -> add(4)", - "{(::$_endOfOuterBlock_$ () (::credibleIntervalToDistribution (::add 1 2) (::add (::add 3 4) 4)))}", + "{(:credibleIntervalToDistribution (:add 1 2) (:add (:add 3 4) 4))}", ) // lower than chain }) describe("inner block", () => { // inner blocks are 0 argument lambdas. They can be used whenever a value is required. // Like lambdas they have a local scope. - testParse("x={y=1; y}; x", "{:x = {:y = {1}; :y}; (::$_endOfOuterBlock_$ () :x)}") + testParse("x={y=1; y}; x", "{:x = {:y = {1}; :y}; :x}") }) describe("lambda", () => { - testParse("{|x| x}", "{(::$_endOfOuterBlock_$ () {|:x| {:x}})}") - testParse("f={|x| x}", "{:f = {{|:x| {:x}}}; (::$_endOfOuterBlock_$ () ())}") - testParse("f(x)=x", "{:f = {|:x| {:x}}; (::$_endOfOuterBlock_$ () ())}") // Function definitions are lambda assignments + testParse("{|x| x}", "{{|:x| :x}}") + testParse("f={|x| x}", "{:f = {{|:x| :x}}}") + testParse("f(x)=x", "{:f = {|:x| {:x}}}") // Function definitions are lambda assignments testParse( "f(x)=x ? 1 : 0", - "{:f = {|:x| {(::$$_ternary_$$ :x 1 0)}}; (::$_endOfOuterBlock_$ () ())}", + "{:f = {|:x| {(::$$_ternary_$$ :x 1 0)}}}", ) // Function definitions are lambda assignments }) describe("Using lambda as value", () => { testParse( "myadd(x,y)=x+y; z=myadd; z", - "{:myadd = {|:x,:y| {(::add :x :y)}}; :z = {:myadd}; (::$_endOfOuterBlock_$ () :z)}", + "{:myadd = {|:x,:y| {(:add :x :y)}}; :z = {:myadd}; :z}", ) testParse( "myadd(x,y)=x+y; z=[myadd]; z", - "{:myadd = {|:x,:y| {(::add :x :y)}}; :z = {(::$_constructArray_$ :myadd)}; (::$_endOfOuterBlock_$ () :z)}", + "{:myadd = {|:x,:y| {(:add :x :y)}}; :z = {[:myadd]}; :z}", ) testParse( "myaddd(x,y)=x+y; z={x: myaddd}; z", - "{:myaddd = {|:x,:y| {(::add :x :y)}}; :z = {(::$_constructRecord_$ ('x': :myaddd))}; (::$_endOfOuterBlock_$ () :z)}", + "{:myaddd = {|:x,:y| {(:add :x :y)}}; :z = {{'x': :myaddd}}; :z}", ) - testParse("f({|x| x+1})", "{(::$_endOfOuterBlock_$ () (::f {|:x| {(::add :x 1)}}))}") + testParse("f({|x| x+1})", "{(:f {|:x| (:add :x 1)})}") testParse( "map(arr, {|x| x+1})", - "{(::$_endOfOuterBlock_$ () (::map :arr {|:x| {(::add :x 1)}}))}", + "{(:map :arr {|:x| (:add :x 1)})}", ) testParse( "map([1,2,3], {|x| x+1})", - "{(::$_endOfOuterBlock_$ () (::map (::$_constructArray_$ 1 2 3) {|:x| {(::add :x 1)}}))}", + "{(:map [1; 2; 3] {|:x| (:add :x 1)})}", ) testParse( "[1,2,3]->map({|x| x+1})", - "{(::$_endOfOuterBlock_$ () (::map (::$_constructArray_$ 1 2 3) {|:x| {(::add :x 1)}}))}", + "{(:map [1; 2; 3] {|:x| (:add :x 1)})}", ) }) describe("unit", () => { - testParse("1m", "{(::$_endOfOuterBlock_$ () (::fromUnit_m 1))}") - testParse("1M", "{(::$_endOfOuterBlock_$ () (::fromUnit_M 1))}") - testParse("1m+2cm", "{(::$_endOfOuterBlock_$ () (::add (::fromUnit_m 1) (::fromUnit_cm 2)))}") + testParse("1m", "{(:fromUnit_m 1)}") + testParse("1M", "{(:fromUnit_M 1)}") + testParse("1m+2cm", "{(:add (:fromUnit_m 1) (:fromUnit_cm 2))}") }) describe("Module", () => { - testParse("x", "{(::$_endOfOuterBlock_$ () :x)}") - testParse("Math.pi", "{(::$_endOfOuterBlock_$ () :Math.pi)}") + testParse("x", "{:x}") + testParse("Math.pi", "{:Math.pi}") }) }) @@ -351,19 +350,19 @@ describe("parsing new line", () => { ` a + b`, - "{(::$_endOfOuterBlock_$ () (::add :a :b))}", + "{(:add :a :b)}", ) testParse( ` x= 1`, - "{:x = {1}; (::$_endOfOuterBlock_$ () ())}", + "{:x = {1}}", ) testParse( ` x=1 y=2`, - "{:x = {1}; :y = {2}; (::$_endOfOuterBlock_$ () ())}", + "{:x = {1}; :y = {2}}", ) testParse( ` @@ -371,7 +370,7 @@ describe("parsing new line", () => { y=2; y } x`, - "{:x = {:y = {2}; :y}; (::$_endOfOuterBlock_$ () :x)}", + "{:x = {:y = {2}; :y}; :x}", ) testParse( ` @@ -379,7 +378,7 @@ describe("parsing new line", () => { y=2 y } x`, - "{:x = {:y = {2}; :y}; (::$_endOfOuterBlock_$ () :x)}", + "{:x = {:y = {2}; :y}; :x}", ) testParse( ` @@ -388,7 +387,7 @@ describe("parsing new line", () => { y } x`, - "{:x = {:y = {2}; :y}; (::$_endOfOuterBlock_$ () :x)}", + "{:x = {:y = {2}; :y}; :x}", ) testParse( ` @@ -396,7 +395,7 @@ describe("parsing new line", () => { y=2 z=3 `, - "{:x = {1}; :y = {2}; :z = {3}; (::$_endOfOuterBlock_$ () ())}", + "{:x = {1}; :y = {2}; :z = {3}}", ) testParse( ` @@ -407,7 +406,7 @@ describe("parsing new line", () => { x+y+z } `, - "{:f = {:x = {1}; :y = {2}; :z = {3}; (::add (::add :x :y) :z)}; (::$_endOfOuterBlock_$ () ())}", + "{:f = {:x = {1}; :y = {2}; :z = {3}; (:add (:add :x :y) :z)}}", ) testParse( ` @@ -420,7 +419,7 @@ describe("parsing new line", () => { g=f+4 g `, - "{:f = {:x = {1}; :y = {2}; :z = {3}; (::add (::add :x :y) :z)}; :g = {(::add :f 4)}; (::$_endOfOuterBlock_$ () :g)}", + "{:f = {:x = {1}; :y = {2}; :z = {3}; (:add (:add :x :y) :z)}; :g = {(:add :f 4)}; :g}" ) testParse( ` @@ -442,7 +441,7 @@ describe("parsing new line", () => { p -> q `, - "{:f = {:x = {1}; :y = {2}; :z = {3}; (::add (::add :x :y) :z)}; :g = {(::add :f 4)}; (::$_endOfOuterBlock_$ () (::q (::p (::h :g))))}", + "{:f = {:x = {1}; :y = {2}; :z = {3}; (:add (:add :x :y) :z)}; :g = {(:add :f 4)}; (:q (:p (:h :g)))}" ) testParse( ` @@ -451,7 +450,7 @@ describe("parsing new line", () => { c |> d `, - "{(::$_endOfOuterBlock_$ () (::d (::c (::b :a))))}", + "{(:d (:c (:b :a)))}", ) testParse( ` @@ -461,6 +460,6 @@ describe("parsing new line", () => { d + e `, - "{(::$_endOfOuterBlock_$ () (::add (::d (::c (::b :a))) :e))}", + "{(:add (:d (:c (:b :a))) :e)}" ) }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_outerBlock_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_outerBlock_test.res index 951005c2..bcc99bfb 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_outerBlock_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_outerBlock_test.res @@ -5,18 +5,18 @@ open Jest open Reducer_Peggy_TestHelpers describe("Peggy Outer Block", () => { - testToExpression("1", "{(:$_endOfOuterBlock_$ () 1)}", ~v="1", ()) - testToExpression("x=1", "{(:$_let_$ :x {1}); (:$_endOfOuterBlock_$ () ())}", ~v="()", ()) + testToExpression("1", "1", ~v="1", ()) + testToExpression("x=1", "x = {1}", ~v="()", ()) testToExpression( "x=1; y=2", - "{(:$_let_$ :x {1}); (:$_let_$ :y {2}); (:$_endOfOuterBlock_$ () ())}", + "x = {1}; y = {2}", ~v="()", (), ) - testToExpression("x=1; 2", "{(:$_let_$ :x {1}); (:$_endOfOuterBlock_$ () 2)}", ~v="2", ()) + testToExpression("x=1; 2", "x = {1}; 2", ~v="2", ()) testToExpression( "x={a=1; a}; x", - "{(:$_let_$ :x {(:$_let_$ :a {1}); :a}); (:$_endOfOuterBlock_$ () :x)}", + "x = {a = {1}; a}; x", ~v="1", (), ) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_test.res index eefa2294..d2e64393 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_test.res @@ -7,69 +7,69 @@ open Reducer_Peggy_TestHelpers describe("Peggy to Expression", () => { describe("literals operators parenthesis", () => { // Note that there is always an outer block. Otherwise, external bindings are ignored at the first statement - testToExpression("1", "{(:$_endOfOuterBlock_$ () 1)}", ~v="1", ()) - testToExpression("'hello'", "{(:$_endOfOuterBlock_$ () 'hello')}", ~v="'hello'", ()) - testToExpression("true", "{(:$_endOfOuterBlock_$ () true)}", ~v="true", ()) - testToExpression("1+2", "{(:$_endOfOuterBlock_$ () (:add 1 2))}", ~v="3", ()) - testToExpression("add(1,2)", "{(:$_endOfOuterBlock_$ () (:add 1 2))}", ~v="3", ()) - testToExpression("(1)", "{(:$_endOfOuterBlock_$ () 1)}", ()) - testToExpression("(1+2)", "{(:$_endOfOuterBlock_$ () (:add 1 2))}", ()) + testToExpression("1", "1", ~v="1", ()) + testToExpression("'hello'", "'hello'", ~v="'hello'", ()) + testToExpression("true", "true", ~v="true", ()) + testToExpression("1+2", "(add)(1, 2)", ~v="3", ()) + testToExpression("add(1,2)", "(add)(1, 2)", ~v="3", ()) + testToExpression("(1)", "1", ()) + testToExpression("(1+2)", "(add)(1, 2)", ()) }) describe("unary", () => { - testToExpression("-1", "{(:$_endOfOuterBlock_$ () (:unaryMinus 1))}", ~v="-1", ()) - testToExpression("!true", "{(:$_endOfOuterBlock_$ () (:not true))}", ~v="false", ()) - testToExpression("1 + -1", "{(:$_endOfOuterBlock_$ () (:add 1 (:unaryMinus 1)))}", ~v="0", ()) - testToExpression("-a[0]", "{(:$_endOfOuterBlock_$ () (:unaryMinus (:$_atIndex_$ :a 0)))}", ()) + testToExpression("-1", "(unaryMinus)(1)", ~v="-1", ()) + testToExpression("!true", "(not)(true)", ~v="false", ()) + testToExpression("1 + -1", "(add)(1, (unaryMinus)(1))", ~v="0", ()) + testToExpression("-a[0]", "(unaryMinus)(($_atIndex_$)(a, 0))", ()) }) describe("multi-line", () => { - testToExpression("x=1; 2", "{(:$_let_$ :x {1}); (:$_endOfOuterBlock_$ () 2)}", ~v="2", ()) + testToExpression("x=1; 2", "x = {1}; 2", ~v="2", ()) testToExpression( "x=1; y=2", - "{(:$_let_$ :x {1}); (:$_let_$ :y {2}); (:$_endOfOuterBlock_$ () ())}", + "x = {1}; y = {2}", (), ) }) describe("variables", () => { - testToExpression("x = 1", "{(:$_let_$ :x {1}); (:$_endOfOuterBlock_$ () ())}", ()) - testToExpression("x", "{(:$_endOfOuterBlock_$ () :x)}", ~v="Error(x is not defined)", ()) //TODO: value should return error - testToExpression("x = 1; x", "{(:$_let_$ :x {1}); (:$_endOfOuterBlock_$ () :x)}", ~v="1", ()) + testToExpression("x = 1", "x = {1}", ()) + testToExpression("x", "x", ~v="Error(x is not defined)", ()) //TODO: value should return error + testToExpression("x = 1; x", "x = {1}; x", ~v="1", ()) }) describe("functions", () => { testToExpression( "identity(x) = x", - "{(:$_let_$ :identity (:$$_lambda_$$ [x] {:x})); (:$_endOfOuterBlock_$ () ())}", + "identity = {|x| {x}}", (), ) // Function definitions become lambda assignments - testToExpression("identity(x)", "{(:$_endOfOuterBlock_$ () (:identity :x))}", ()) // Note value returns error properly + testToExpression("identity(x)", "(identity)(x)", ()) // Note value returns error properly testToExpression( "f(x) = x> 2 ? 0 : 1; f(3)", - "{(:$_let_$ :f (:$$_lambda_$$ [x] {(:$$_ternary_$$ (:larger :x 2) 0 1)})); (:$_endOfOuterBlock_$ () (:f 3))}", + "f = {|x| {(larger)(x, 2) ? (0) : (1)}}; (f)(3)", ~v="0", (), ) }) describe("arrays", () => { - testToExpression("[]", "{(:$_endOfOuterBlock_$ () (:$_constructArray_$))}", ~v="[]", ()) + testToExpression("[]", "[]", ~v="[]", ()) testToExpression( "[0, 1, 2]", - "{(:$_endOfOuterBlock_$ () (:$_constructArray_$ 0 1 2))}", + "[0, 1, 2]", ~v="[0,1,2]", (), ) testToExpression( "['hello', 'world']", - "{(:$_endOfOuterBlock_$ () (:$_constructArray_$ 'hello' 'world'))}", + "['hello', 'world']", ~v="['hello','world']", (), ) testToExpression( "([0,1,2])[1]", - "{(:$_endOfOuterBlock_$ () (:$_atIndex_$ (:$_constructArray_$ 0 1 2) 1))}", + "($_atIndex_$)([0, 1, 2], 1)", ~v="1", (), ) @@ -78,40 +78,40 @@ describe("Peggy to Expression", () => { describe("records", () => { testToExpression( "{a: 1, b: 2}", - "{(:$_endOfOuterBlock_$ () (:$_constructRecord_$ (('a' 1) ('b' 2))))}", + "{'a': 1, 'b': 2}", ~v="{a: 1,b: 2}", (), ) testToExpression( "{1+0: 1, 2+0: 2}", - "{(:$_endOfOuterBlock_$ () (:$_constructRecord_$ (((:add 1 0) 1) ((:add 2 0) 2))))}", + "{(add)(1, 0): 1, (add)(2, 0): 2}", (), ) // key can be any expression testToExpression( "record.property", - "{(:$_endOfOuterBlock_$ () (:$_atIndex_$ :record 'property'))}", + "($_atIndex_$)(record, 'property')", (), ) testToExpression( "record={property: 1}; record.property", - "{(:$_let_$ :record {(:$_constructRecord_$ (('property' 1)))}); (:$_endOfOuterBlock_$ () (:$_atIndex_$ :record 'property'))}", + "record = {{'property': 1}}; ($_atIndex_$)(record, 'property')", ~v="1", (), ) }) describe("comments", () => { - testToExpression("1 # This is a line comment", "{(:$_endOfOuterBlock_$ () 1)}", ~v="1", ()) - testToExpression("1 // This is a line comment", "{(:$_endOfOuterBlock_$ () 1)}", ~v="1", ()) + testToExpression("1 # This is a line comment", "1", ~v="1", ()) + testToExpression("1 // This is a line comment", "1", ~v="1", ()) testToExpression( "1 /* This is a multi line comment */", - "{(:$_endOfOuterBlock_$ () 1)}", + "1", ~v="1", (), ) testToExpression( "/* This is a multi line comment */ 1", - "{(:$_endOfOuterBlock_$ () 1)}", + "1", ~v="1", (), ) @@ -120,25 +120,25 @@ describe("Peggy to Expression", () => { describe("ternary operator", () => { testToExpression( "true ? 1 : 0", - "{(:$_endOfOuterBlock_$ () (:$$_ternary_$$ true 1 0))}", + "true ? (1) : (0)", ~v="1", (), ) testToExpression( "false ? 1 : 0", - "{(:$_endOfOuterBlock_$ () (:$$_ternary_$$ false 1 0))}", + "false ? (1) : (0)", ~v="0", (), ) testToExpression( "true ? 1 : false ? 2 : 0", - "{(:$_endOfOuterBlock_$ () (:$$_ternary_$$ true 1 (:$$_ternary_$$ false 2 0)))}", + "true ? (1) : (false ? (2) : (0))", ~v="1", (), ) // nested ternary testToExpression( "false ? 1 : false ? 2 : 0", - "{(:$_endOfOuterBlock_$ () (:$$_ternary_$$ false 1 (:$$_ternary_$$ false 2 0)))}", + "false ? (1) : (false ? (2) : (0))", ~v="0", (), ) // nested ternary @@ -146,21 +146,21 @@ describe("Peggy to Expression", () => { testToExpression( // expression binding "f(a) = a > 5 ? 1 : 0; f(6)", - "{(:$_let_$ :f (:$$_lambda_$$ [a] {(:$$_ternary_$$ (:larger :a 5) 1 0)})); (:$_endOfOuterBlock_$ () (:f 6))}", + "f = {|a| {(larger)(a, 5) ? (1) : (0)}}; (f)(6)", ~v="1", (), ) testToExpression( // when true binding "f(a) = a > 5 ? a : 0; f(6)", - "{(:$_let_$ :f (:$$_lambda_$$ [a] {(:$$_ternary_$$ (:larger :a 5) :a 0)})); (:$_endOfOuterBlock_$ () (:f 6))}", + "f = {|a| {(larger)(a, 5) ? (a) : (0)}}; (f)(6)", ~v="6", (), ) testToExpression( // when false binding "f(a) = a < 5 ? 1 : a; f(6)", - "{(:$_let_$ :f (:$$_lambda_$$ [a] {(:$$_ternary_$$ (:smaller :a 5) 1 :a)})); (:$_endOfOuterBlock_$ () (:f 6))}", + "f = {|a| {(smaller)(a, 5) ? (1) : (a)}}; (f)(6)", ~v="6", (), ) @@ -170,39 +170,39 @@ describe("Peggy to Expression", () => { describe("if then else", () => { testToExpression( "if true then 2 else 3", - "{(:$_endOfOuterBlock_$ () (:$$_ternary_$$ true {2} {3}))}", + "true ? ({2}) : ({3})", (), ) testToExpression( "if true then {2} else {3}", - "{(:$_endOfOuterBlock_$ () (:$$_ternary_$$ true {2} {3}))}", + "true ? ({2}) : ({3})", (), ) testToExpression( "if false then {2} else if false then {4} else {5}", - "{(:$_endOfOuterBlock_$ () (:$$_ternary_$$ false {2} (:$$_ternary_$$ false {4} {5})))}", + "false ? ({2}) : (false ? ({4}) : ({5}))", (), ) //nested if }) describe("pipe", () => { - testToExpression("1 -> add(2)", "{(:$_endOfOuterBlock_$ () (:add 1 2))}", ~v="3", ()) + testToExpression("1 -> add(2)", "(add)(1, 2)", ~v="3", ()) testToExpression( "-1 -> add(2)", - "{(:$_endOfOuterBlock_$ () (:add (:unaryMinus 1) 2))}", + "(add)((unaryMinus)(1), 2)", ~v="1", (), ) // note that unary has higher priority naturally testToExpression( "1 -> add(2) * 3", - "{(:$_endOfOuterBlock_$ () (:multiply (:add 1 2) 3))}", + "(multiply)((add)(1, 2), 3)", ~v="9", (), ) }) describe("elixir pipe", () => { - testToExpression("1 |> add(2)", "{(:$_endOfOuterBlock_$ () (:add 1 2))}", ~v="3", ()) + testToExpression("1 |> add(2)", "(add)(1, 2)", ~v="3", ()) }) // see testParse for priorities of to and credibleIntervalToDistribution @@ -212,7 +212,8 @@ describe("Peggy to Expression", () => { // Like lambdas they have a local scope. testToExpression( "y=99; x={y=1; y}", - "{(:$_let_$ :y {99}); (:$_let_$ :x {(:$_let_$ :y {1}); :y}); (:$_endOfOuterBlock_$ () ())}", + "y = {99}; x = {y = {1}; y}", + // "{(:$_let_$ :y {99}); (:$_let_$ :x {(:$_let_$ :y {1}); :y}); (:$_endOfOuterBlock_$ () ())}", (), ) }) @@ -220,23 +221,23 @@ describe("Peggy to Expression", () => { describe("lambda", () => { testToExpression( "{|x| x}", - "{(:$_endOfOuterBlock_$ () (:$$_lambda_$$ [x] {:x}))}", + "{|x| x}", ~v="lambda(x=>internal code)", (), ) testToExpression( "f={|x| x}", - "{(:$_let_$ :f {(:$$_lambda_$$ [x] {:x})}); (:$_endOfOuterBlock_$ () ())}", + "f = {{|x| x}}", (), ) testToExpression( "f(x)=x", - "{(:$_let_$ :f (:$$_lambda_$$ [x] {:x})); (:$_endOfOuterBlock_$ () ())}", + "f = {|x| {x}}", (), ) // Function definitions are lambda assignments testToExpression( "f(x)=x ? 1 : 0", - "{(:$_let_$ :f (:$$_lambda_$$ [x] {(:$$_ternary_$$ :x 1 0)})); (:$_endOfOuterBlock_$ () ())}", + "f = {|x| {x ? (1) : (0)}}", (), ) }) @@ -250,6 +251,6 @@ describe("Peggy to Expression", () => { // ->expect // ->toBe("") // }) - testToExpression("Math.pi", "{(:$_endOfOuterBlock_$ () :Math.pi)}", ~v="3.141592653589793", ()) + testToExpression("Math.pi", "Math.pi", ~v="3.141592653589793", ()) }) }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_constructArray_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_constructArray_test.res index 205d4883..55ffff27 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_constructArray_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_constructArray_test.res @@ -2,11 +2,11 @@ open Jest open Reducer_Peggy_TestHelpers describe("Construct Array", () => { - testToExpression("[1,2]", "{(:$_endOfOuterBlock_$ () (:$_constructArray_$ 1 2))}", ~v="[1,2]", ()) - testToExpression("[]", "{(:$_endOfOuterBlock_$ () (:$_constructArray_$))}", ~v="[]", ()) + testToExpression("[1,2]", "[1, 2]", ~v="[1,2]", ()) + testToExpression("[]", "[]", ~v="[]", ()) testToExpression( "f(x)=x; g(x)=x; [f, g]", - "{(:$_let_$ :f (:$$_lambda_$$ [x] {:x})); (:$_let_$ :g (:$$_lambda_$$ [x] {:x})); (:$_endOfOuterBlock_$ () (:$_constructArray_$ :f :g))}", + "f = {|x| {x}}; g = {|x| {x}}; [f, g]", ~v="[lambda(x=>internal code),lambda(x=>internal code)]", (), ) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res index a2abb85d..52f8329b 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res @@ -4,11 +4,11 @@ open Reducer_TestHelpers describe("Parse function assignment", () => { testParseToBe( "f(x)=x", - "Ok({(:$_let_$ :f (:$$_lambda_$$ [x] {:x})); (:$_endOfOuterBlock_$ () ())})", + "Ok(f = {|x| {x}})" ) testParseToBe( "f(x)=2*x", - "Ok({(:$_let_$ :f (:$$_lambda_$$ [x] {(:multiply 2 :x)})); (:$_endOfOuterBlock_$ () ())})", + "Ok(f = {|x| {(multiply)(2, x)}})" ) //MathJs does not allow blocks in function definitions }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res index c86f4bca..c1af1d59 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res @@ -4,7 +4,7 @@ open Reducer_TestHelpers describe("Parse ternary operator", () => { testParseToBe( "true ? 'YES' : 'NO'", - "Ok({(:$_endOfOuterBlock_$ () (:$$_ternary_$$ true 'YES' 'NO'))})", + "Ok({(:$$_ternary_$$ true 'YES' 'NO')})", ) }) diff --git a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res index c8207131..330767df 100644 --- a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res +++ b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res @@ -121,38 +121,38 @@ describe("parse on distribution functions", () => { describe("power", () => { testParse( "normal(5,2) ^ normal(5,1)", - "Ok({(:$_endOfOuterBlock_$ () (:pow (:normal 5 2) (:normal 5 1)))})", + "Ok((pow)((normal)(5, 2), (normal)(5, 1)))", ) - testParse("3 ^ normal(5,1)", "Ok({(:$_endOfOuterBlock_$ () (:pow 3 (:normal 5 1)))})") - testParse("normal(5,2) ^ 3", "Ok({(:$_endOfOuterBlock_$ () (:pow (:normal 5 2) 3))})") + testParse("3 ^ normal(5,1)", "Ok((pow)(3, (normal)(5, 1)))") + testParse("normal(5,2) ^ 3", "Ok((pow)((normal)(5, 2), 3))") }) describe("subtraction", () => { - testParse("10 - normal(5,1)", "Ok({(:$_endOfOuterBlock_$ () (:subtract 10 (:normal 5 1)))})") - testParse("normal(5,1) - 10", "Ok({(:$_endOfOuterBlock_$ () (:subtract (:normal 5 1) 10))})") + testParse("10 - normal(5,1)", "Ok((subtract)(10, (normal)(5, 1)))") + testParse("normal(5,1) - 10", "Ok((subtract)((normal)(5, 1), 10))") }) describe("pointwise arithmetic expressions", () => { testParse(~skip=true, "normal(5,2) .+ normal(5,1)", "Ok((:dotAdd (:normal 5 2) (:normal 5 1)))") testParse( ~skip=true, "normal(5,2) .- normal(5,1)", - "Ok((:$_endOfOuterBlock_$ () (:$$_block_$$ (:dotSubtract (:normal 5 2) (:normal 5 1)))))", + "Ok((:$$_block_$$ (:dotSubtract (:normal 5 2) (:normal 5 1))))", // TODO: !!! returns "Ok({(:dotPow (:normal 5 2) (:normal 5 1))})" ) testParse( "normal(5,2) .* normal(5,1)", - "Ok({(:$_endOfOuterBlock_$ () (:dotMultiply (:normal 5 2) (:normal 5 1)))})", + "Ok((dotMultiply)((normal)(5, 2), (normal)(5, 1)))", ) testParse( "normal(5,2) ./ normal(5,1)", - "Ok({(:$_endOfOuterBlock_$ () (:dotDivide (:normal 5 2) (:normal 5 1)))})", + "Ok((dotDivide)((normal)(5, 2), (normal)(5, 1)))", ) testParse( "normal(5,2) .^ normal(5,1)", - "Ok({(:$_endOfOuterBlock_$ () (:dotPow (:normal 5 2) (:normal 5 1)))})", + "Ok((dotPow)((normal)(5, 2), (normal)(5, 1)))", ) }) describe("equality", () => { - testParse("5 == normal(5,2)", "Ok({(:$_endOfOuterBlock_$ () (:equal 5 (:normal 5 2)))})") + testParse("5 == normal(5,2)", "Ok((equal)(5, (normal)(5, 2)))") }) describe("pointwise adding two normals", () => { testParse(~skip=true, "normal(5,2) .+ normal(5,1)", "Ok((:dotAdd (:normal 5 2) (:normal 5 1)))") diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res index 471ac55b..3097d74a 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res @@ -1,121 +1,117 @@ -// @@warning("-44") -// module InternalExpressionValue = ReducerInterface_InternalExpressionValue -// module Project = ForTS_ReducerProject -// module Bindings = Reducer_Bindings +@@warning("-44") +module InternalExpressionValue = ReducerInterface_InternalExpressionValue +module Project = ForTS_ReducerProject +module Bindings = Reducer_Bindings -// open Jest -// open Expect -// open Expect.Operators +open Jest +open Expect +open Expect.Operators -// describe("Parse includes", () => { -// let project = Project.createProject() -// Project.setSource( -// project, -// "main", -// ` -// #include 'common' -// x=1`, -// ) -// Project.parseIncludes(project, "main") -// test("dependencies", () => { -// expect(Project.getDependencies(project, "main")) == ["common"] -// }) -// test("dependents", () => { -// expect(Project.getDependents(project, "main")) == [] -// }) -// test("getIncludes", () => { -// let mainIncludes = Project.getIncludes(project, "main") -// switch mainIncludes { -// | Ok(includes) => expect(includes) == ["common"] -// | Error(error) => fail(error->Reducer_ErrorValue.errorToString) -// } -// }) -// let internalProject = project->Project.T.Private.castToInternalProject -// test("past chain", () => { -// expect(Project.Private.getPastChain(internalProject, "main")) == ["common"] -// }) -// test("import as variables", () => { -// expect(Project.Private.getIncludesAsVariables(internalProject, "main")) == [] -// }) -// }) +describe("Parse includes", () => { + let project = Project.createProject() + Project.setSource( + project, + "main", + ` +#include 'common' +x=1`, + ) + Project.parseIncludes(project, "main") + test("dependencies", () => { + expect(Project.getDependencies(project, "main")) == ["common"] + }) + test("dependents", () => { + expect(Project.getDependents(project, "main")) == [] + }) + test("getIncludes", () => { + let mainIncludes = Project.getIncludes(project, "main") + switch mainIncludes { + | Ok(includes) => expect(includes) == ["common"] + | Error(error) => fail(error->Reducer_ErrorValue.errorToString) + } + }) + test("past chain", () => { + expect(project->Project.getPastChain("main")) == ["common"] + }) + test("import as variables", () => { + expect(project->Project.Private.getIncludesAsVariables("main")) == [] + }) +}) -// describe("Parse includes", () => { -// let project = Project.createProject() -// Project.setSource( -// project, -// "main", -// ` -// #include 'common' -// #include 'myModule' as myVariable -// x=1`, -// ) -// Project.parseIncludes(project, "main") +describe("Parse includes", () => { + let project = Project.createProject() + Project.setSource( + project, + "main", + ` +#include 'common' +#include 'myModule' as myVariable +x=1`, + ) + Project.parseIncludes(project, "main") -// test("dependencies", () => { -// expect(Project.getDependencies(project, "main")) == ["common", "myModule"] -// }) + test("dependencies", () => { + expect(Project.getDependencies(project, "main")) == ["common", "myModule"] + }) -// test("dependents", () => { -// expect(Project.getDependents(project, "main")) == [] -// }) + test("dependents", () => { + expect(Project.getDependents(project, "main")) == [] + }) -// test("getIncludes", () => { -// let mainIncludes = Project.getIncludes(project, "main") -// switch mainIncludes { -// | Ok(includes) => expect(includes) == ["common", "myModule"] -// | Error(error) => fail(error->Reducer_ErrorValue.errorToString) -// } -// }) + test("getIncludes", () => { + let mainIncludes = Project.getIncludes(project, "main") + switch mainIncludes { + | Ok(includes) => expect(includes) == ["common", "myModule"] + | Error(error) => fail(error->Reducer_ErrorValue.errorToString) + } + }) -// let internalProject = project->Project.T.Private.castToInternalProject + test("direct past chain", () => { + expect(project->Project.Private.getPastChain("main")) == ["common"] + }) -// test("direct past chain", () => { -// expect(Project.Private.getPastChain(internalProject, "main")) == ["common"] -// }) + test("direct includes", () => { + expect(project->Project.Private.getDirectIncludes("main")) == ["common"] + }) -// test("direct includes", () => { -// expect(Project.Private.getDirectIncludes(internalProject, "main")) == ["common"] -// }) + test("include as variables", () => { + expect(project->Project.Private.getIncludesAsVariables("main")) == [ + ("myVariable", "myModule"), + ] + }) +}) -// test("include as variables", () => { -// expect(Project.Private.getIncludesAsVariables(internalProject, "main")) == [ -// ("myVariable", "myModule"), -// ] -// }) -// }) - -// describe("Parse multiple direct includes", () => { -// let project = Project.createProject() -// Project.setSource( -// project, -// "main", -// ` -// #include 'common' -// #include 'common2' -// #include 'myModule' as myVariable -// x=1`, -// ) -// Project.parseIncludes(project, "main") -// test("dependencies", () => { -// expect(Project.getDependencies(project, "main")) == ["common", "common2", "myModule"] -// }) -// test("dependents", () => { -// expect(Project.getDependents(project, "main")) == [] -// }) -// test("getIncludes", () => { -// let mainIncludes = Project.getIncludes(project, "main") -// switch mainIncludes { -// | Ok(includes) => expect(includes) == ["common", "common2", "myModule"] -// | Error(error) => fail(error->Reducer_ErrorValue.errorToString) -// } -// }) -// let internalProject = project->Project.T.Private.castToInternalProject -// test("direct past chain", () => { -// expect(Project.getPastChain(project, "main")) == ["common", "common2"] -// }) -// test("include as variables", () => { -// expect(Project.Private.getIncludesAsVariables(internalProject, "main")) == [ -// ("myVariable", "myModule"), -// ] -// }) -// }) +describe("Parse multiple direct includes", () => { + let project = Project.createProject() + Project.setSource( + project, + "main", + ` +#include 'common' +#include 'common2' +#include 'myModule' as myVariable +x=1`, + ) + Project.parseIncludes(project, "main") + test("dependencies", () => { + expect(Project.getDependencies(project, "main")) == ["common", "common2", "myModule"] + }) + test("dependents", () => { + expect(Project.getDependents(project, "main")) == [] + }) + test("getIncludes", () => { + let mainIncludes = Project.getIncludes(project, "main") + switch mainIncludes { + | Ok(includes) => expect(includes) == ["common", "common2", "myModule"] + | Error(error) => fail(error->Reducer_ErrorValue.errorToString) + } + }) + test("direct past chain", () => { + expect(Project.getPastChain(project, "main")) == ["common", "common2"] + }) + test("include as variables", () => { + expect(project->Project.Private.getIncludesAsVariables("main")) == [ + ("myVariable", "myModule"), + ] + }) +}) diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res index 1bfe8c36..ccda4b4f 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res @@ -7,8 +7,6 @@ open Jest open Expect open Expect.Operators -// test("", () => expect(1)->toBe(1)) - let runFetchResult = (project, sourceId) => { Project.run(project, sourceId) Project.getResult(project, sourceId)->InternalExpressionValue.toStringResult @@ -17,18 +15,9 @@ let runFetchResult = (project, sourceId) => { let runFetchFlatBindings = (project, sourceId) => { Project.run(project, sourceId) Project.getBindings(project, sourceId) - ->Bindings.removeResult - ->InternalExpressionValue.toStringBindings + ->InternalExpressionValue.toStringRecord } -test("setting continuation", () => { - let project = Project.createProject() - let sampleBindings = Bindings.makeEmptyBindings()->Bindings.set("test", IEvVoid) - ReducerProject.setContinuation(project, "main", sampleBindings) - let answer = ReducerProject.getContinuation(project, "main") - expect(answer)->toBe(sampleBindings) -}) - test("test result true", () => { let project = Project.createProject() Project.setSource(project, "main", "true") @@ -50,7 +39,7 @@ test("test library", () => { test("test bindings", () => { let project = Project.createProject() Project.setSource(project, "variables", "myVariable=666") - runFetchFlatBindings(project, "variables")->expect->toBe("@{myVariable: 666}") + runFetchFlatBindings(project, "variables")->expect->toBe("{myVariable: 666}") }) describe("project1", () => { @@ -86,7 +75,7 @@ describe("project1", () => { runFetchResult(project, "main")->expect->toBe("Ok(1)") }) test("test bindings", () => { - runFetchFlatBindings(project, "first")->expect->toBe("@{x: 1}") + runFetchFlatBindings(project, "first")->expect->toBe("{x: 1}") }) }) @@ -96,7 +85,7 @@ describe("project2", () => { Project.setContinues(project, "second", ["first"]) Project.setSource(project, "first", "x=1") Project.setSource(project, "second", "y=2") - Project.setSource(project, "main", "y") + Project.setSource(project, "main", "z=3;y") test("runOrder", () => { expect(Project.getRunOrder(project)) == ["first", "second", "main"] @@ -120,7 +109,8 @@ describe("project2", () => { runFetchResult(project, "main")->expect->toBe("Ok(2)") }) test("test bindings", () => { - runFetchFlatBindings(project, "main")->expect->toBe("@{x: 1,y: 2}") + // bindings from continues are not exposed! + runFetchFlatBindings(project, "main")->expect->toBe("{z: 3}") }) }) @@ -150,7 +140,7 @@ describe("project with include", () => { ) Project.parseIncludes(project, "second") //The only way of setting includes - Project.setSource(project, "main", "y") + Project.setSource(project, "main", "z=3; y") test("runOrder", () => { expect(Project.getRunOrder(project)) == ["common", "first", "second", "main"] @@ -176,7 +166,8 @@ describe("project with include", () => { runFetchResult(project, "main")->expect->toBe("Ok(2)") }) test("test bindings", () => { - runFetchFlatBindings(project, "main")->expect->toBe("@{common: 0,x: 1,y: 2}") + // bindings from continues are not exposed! + runFetchFlatBindings(project, "main")->expect->toBe("{z: 3}") }) }) diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_test.res index 59579c80..13cab7aa 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_test.res @@ -16,13 +16,13 @@ Case "Running a single source". /* Let's start with running a single source and getting Result as well as the Bindings First you need to create a project. A project is a collection of sources. Project takes care of the dependencies between the sources, correct compilation and run order. - You can run any source in the project. It will be compiled and run if it is not already done else already existing results will be presented. + You can run any source in the project. It will be compiled and run if it hasn't happened already; otherwise already existing results will be presented. The dependencies will be automatically compiled and run. So you don't need to worry about that in a multi source project. In summary you issue a run command on the whole project or on a specific source to ensure that there is a result for that source. */ let project = Project.createProject() /* Every source has a name. This is used for debugging, dependencies and error messages. */ - Project.setSource(project, "main", "1 + 2") + project->Project.setSource("main", "1 + 2") /* Let's run "main" source. */ project->Project.run("main") /* Now you have a result for "main" source. @@ -46,27 +46,27 @@ Case "Running a single source". Getting None means you have forgotten to run the source. */ let result = project->Project.getResult("main") - let bindings = project->Project.getBindings("main")->Bindings.removeResult + let bindings = project->Project.getBindings("main") /* Let's display the result and bindings */ ( result->InternalExpressionValue.toStringResult, - bindings->InternalExpressionValue.toStringBindings, - )->expect == ("Ok(3)", "@{}") + bindings->InternalExpressionValue.toStringRecord, + )->expect == ("Ok(3)", "{}") /* You've got 3 with empty bindings. */ }) test("run summary", () => { let project = Project.createProject() - Project.setSource(project, "main", "1 + 2") - Project.runAll(project) - let result = Project.getResult(project, "main") - let bindings = Project.getBindings(project, "main")->Bindings.removeResult + project->Project.setSource("main", "1 + 2") + project->Project.runAll + let result = project->Project.getResult("main") + let bindings = project->Project.getBindings("main") /* Now you have external bindings and external result. */ ( result->InternalExpressionValue.toStringResult, - bindings->Reducer_T.IEvBindings->InternalExpressionValue.toString, - )->expect == ("Ok(3)", "@{}") + bindings->Reducer_T.IEvRecord->InternalExpressionValue.toString, + )->expect == ("Ok(3)", "{}") }) test("run with an environment", () => { @@ -74,12 +74,12 @@ Case "Running a single source". let project = Project.createProject() /* Optional. Set your custom environment anytime before running */ - Project.setEnvironment(project, InternalExpressionValue.defaultEnvironment) + project->Project.setEnvironment(InternalExpressionValue.defaultEnvironment) - Project.setSource(project, "main", "1 + 2") - Project.runAll(project) - let result = Project.getResult(project, "main") - let _bindings = Project.getBindings(project, "main") + project->Project.setSource("main", "1 + 2") + project->Project.runAll + let result = project->Project.getResult("main") + let _bindings = project->Project.getBindings("main") result->InternalExpressionValue.toStringResult->expect == "Ok(3)" }) @@ -89,12 +89,16 @@ Case "Running a single source". let (result, bindings) = Project.evaluate("1+2") ( result->InternalExpressionValue.toStringResult, - bindings->Bindings.removeResult->InternalExpressionValue.toStringBindings, - )->expect == ("Ok(3)", "@{}") + bindings->InternalExpressionValue.toStringRecord, + )->expect == ("Ok(3)", "{}") }) }) }) +// s1: { x = 1 } / { stdlib } +// s2 (deps=[s1]): { y = 2 } / { { x = 1 } + stdlib } +// s3 (deps=[s2]): { z = 3 } / { { y = 2 } + stdlib } + //TODO multiple sources //TODO multiple sources with includes. Introduction to includes //TODO multiple sources with multi level includes. Cycle detection diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_multisource_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_multisource_test.res index 80c73c9e..d50ec544 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_multisource_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_multisource_test.res @@ -14,27 +14,27 @@ describe("ReducerProject Tutorial", () => { test("Chaining", () => { let project = Project.createProject() /* This time let's add 3 sources and chain them together */ - Project.setSource(project, "source1", "x=1") + project->Project.setSource("source1", "x=1") - Project.setSource(project, "source2", "y=2") + project->Project.setSource("source2", "y=x+1") /* To run, source2 depends on source1 */ - Project.setContinues(project, "source2", ["source1"]) + project->Project.setContinues("source2", ["source1"]) - Project.setSource(project, "source3", "z=3") + project->Project.setSource("source3", "z=y+1") /* To run, source3 depends on source2 */ - Project.setContinues(project, "source3", ["source2"]) + project->Project.setContinues("source3", ["source2"]) /* Now we can run the project */ - Project.runAll(project) + project->Project.runAll /* And let's check the result and bindings of source3 */ - let result3 = Project.getResult(project, "source3") - let bindings3 = Project.getBindings(project, "source3")->Bindings.removeResult + let result3 = project->Project.getResult("source3") + let bindings3 = project->Project.getBindings("source3") ( result3->InternalExpressionValue.toStringResult, - bindings3->InternalExpressionValue.toStringBindings, - )->expect == ("Ok(())", "@{x: 1,y: 2,z: 3}") + bindings3->InternalExpressionValue.toStringRecord, + )->expect == ("Ok(())", "{z: 3}") }) test("Depending", () => { @@ -43,24 +43,24 @@ describe("ReducerProject Tutorial", () => { let project = Project.createProject() /* This time source1 and source2 are not depending on anything */ - Project.setSource(project, "source1", "x=1") - Project.setSource(project, "source2", "y=2") + project->Project.setSource("source1", "x=1") + project->Project.setSource("source2", "y=2") - Project.setSource(project, "source3", "z=3") + project->Project.setSource("source3", "z=x+y") /* To run, source3 depends on source1 and source3 together */ - Project.setContinues(project, "source3", ["source1", "source2"]) + project->Project.setContinues("source3", ["source1", "source2"]) /* Now we can run the project */ - Project.runAll(project) + project->Project.runAll /* And let's check the result and bindings of source3 */ - let result3 = Project.getResult(project, "source3") - let bindings3 = Project.getBindings(project, "source3")->Bindings.removeResult + let result3 = project->Project.getResult("source3") + let bindings3 = project->Project.getBindings("source3") ( result3->InternalExpressionValue.toStringResult, - bindings3->InternalExpressionValue.toStringBindings, - )->expect == ("Ok(())", "@{x: 1,y: 2,z: 3}") + bindings3->InternalExpressionValue.toStringRecord, + )->expect == ("Ok(())", "{z: 3}") }) test("Intro to including", () => { @@ -70,33 +70,32 @@ describe("ReducerProject Tutorial", () => { let project = Project.createProject() /* This time source1 and source2 are not depending on anything */ - Project.setSource(project, "source1", "x=1") - Project.setSource(project, "source2", "y=2") + project->Project.setSource("source1", "x=1") + project->Project.setSource("source2", "y=2") - Project.setSource( - project, + project->Project.setSource( "source3", ` #include "source1" #include "source2" - z=3`, + z=x+y`, ) /* We need to parse the includes to set the dependencies */ - Project.parseIncludes(project, "source3") + project->Project.parseIncludes("source3") /* Now we can run the project */ - Project.runAll(project) + project->Project.runAll /* And let's check the result and bindings of source3 This time you are getting all the variables because we are including the other sources Behind the scenes parseIncludes is setting the dependencies */ - let result3 = Project.getResult(project, "source3") - let bindings3 = Project.getBindings(project, "source3")->Bindings.removeResult + let result3 = project->Project.getResult("source3") + let bindings3 = project->Project.getBindings("source3") ( result3->InternalExpressionValue.toStringResult, - bindings3->InternalExpressionValue.toStringBindings, - )->expect == ("Ok(())", "@{x: 1,y: 2,z: 3}") + bindings3->InternalExpressionValue.toStringRecord, + )->expect == ("Ok(())", "{z: 3}") /* Doing it like this is too verbose for a storybook But I hope you have seen the relation of setContinues and parseIncludes */ diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_3_includes_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_3_includes_test.res index 12c14468..8e584576 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_3_includes_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_3_includes_test.res @@ -16,8 +16,7 @@ Here we will finally proceed to a real life scenario. */ /* Here we investigate the details about parseIncludes, before setting up a real life scenario in the next section. */ /* Everything happens inside a project, so let's have a project */ let project = Project.createProject() - Project.setSource( - project, + project->Project.setSource( "main", ` #include "common" @@ -25,10 +24,10 @@ Here we will finally proceed to a real life scenario. */ `, ) /* We need to parse includes after changing the source */ - Project.parseIncludes(project, "main") + project->Project.parseIncludes("main") test("getDependencies", () => { /* Parse includes has set the dependencies */ - Project.getDependencies(project, "main")->expect == ["common"] + project->Project.getDependencies("main")->expect == ["common"] /* If there were no includes than there would be no dependencies */ /* However if there was a syntax error at includes then would be no dependencies also */ /* Therefore looking at dependencies is not the right way to load includes */ @@ -36,7 +35,7 @@ Here we will finally proceed to a real life scenario. */ }) test("getIncludes", () => { /* Parse includes has set the includes */ - switch Project.getIncludes(project, "main") { + switch project->Project.getIncludes("main") { | Ok(includes) => includes->expect == ["common"] | Error(err) => err->Reducer_ErrorValue.errorToString->fail } @@ -50,7 +49,7 @@ Here we will finally proceed to a real life scenario. */ include or depend on the current source. But you don't need to use this to execute the projects. It is provided for completeness of information. */ - Project.getDependents(project, "main")->expect == [] + project->Project.getDependents("main")->expect == [] /* Nothing is depending on or including main */ }) @@ -76,29 +75,29 @@ Here we will finally proceed to a real life scenario. */ /* let's recursively load the sources */ let rec loadIncludesRecursively = (project, sourceName, visited) => { - if Js.Array2.includes(visited, sourceName) { + if visited->Js.Array2.includes(sourceName) { /* Oh we have already visited this source. There is an include cycle */ "Cyclic include ${sourceName}"->Js.Exn.raiseError } else { let newVisited = Js.Array2.copy(visited) - let _ = Js.Array2.push(newVisited, sourceName) + let _ = newVisited->Js.Array2.push(sourceName) /* Let's parse the includes and dive into them */ Project.parseIncludes(project, sourceName) - let rIncludes = Project.getIncludes(project, sourceName) + let rIncludes = project->Project.getIncludes(sourceName) switch rIncludes { /* Maybe there is an include syntax error */ | Error(err) => err->Reducer_ErrorValue.errorToString->Js.Exn.raiseError | Ok(includes) => - Belt.Array.forEach(includes, newIncludeName => { + includes->Belt.Array.forEach(newIncludeName => { /* We have got one of the new includes. Let's load it and add it to the project */ let newSource = loadSource(newIncludeName) - Project.setSource(project, newIncludeName, newSource) + project->Project.setSource(newIncludeName, newSource) /* The new source is loaded and added to the project. */ /* Of course the new source might have includes too. */ /* Let's recursively load them */ - loadIncludesRecursively(project, newIncludeName, newVisited) + project->loadIncludesRecursively(newIncludeName, newVisited) }) } } @@ -110,45 +109,46 @@ Here we will finally proceed to a real life scenario. */ let project = Project.createProject() - /* main includes source3 which includes source2 which includes source1 */ - Project.setSource( - project, + project->Project.setSource( "main", ` + #include "source1" + #include "source2" #include "source3" - x+y+z + a = x+y+z + b = doubleX + a `, ) /* Setting source requires parsing and loading the includes recursively */ - loadIncludesRecursively(project, "main", []) //No visited yet + project->loadIncludesRecursively("main", []) // Not visited yet /* Let's salt it more. Let's have another source in the project which also has includes */ /* doubleX includes source1 which is eventually included by main as well */ - Project.setSource( - project, + project->Project.setSource( "doubleX", ` #include "source1" doubleX = x * 2 `, ) - loadIncludesRecursively(project, "doubleX", []) + project->loadIncludesRecursively("doubleX", []) /* Remember, any time you set a source, you need to load includes recursively */ /* As doubleX is not included by main, it is not loaded recursively. So we link it to the project as a dependency */ - Project.setContinues(project, "main", ["doubleX"]) + project->Project.setContinues("main", ["doubleX"]) /* Let's run the project */ - Project.runAll(project) - let result = Project.getResult(project, "main") - let bindings = Project.getBindings(project, "main") + project->Project.runAll + let result = project->Project.getResult("main") + let bindings = project->Project.getBindings("main") /* And see the result and bindings.. */ test("recursive includes", () => { ( result->InternalExpressionValue.toStringResult, - bindings->Bindings.removeResult->InternalExpressionValue.toStringBindings, - )->expect == ("Ok(6)", "@{doubleX: 2,x: 1,y: 2,z: 3}") + bindings->InternalExpressionValue.toStringRecord, + )->expect == ("Ok(6)", "{a: 6,b: 2}") /* Everything as expected */ }) }) diff --git a/packages/squiggle-lang/bsconfig.json b/packages/squiggle-lang/bsconfig.json index d9c352a5..a05df290 100644 --- a/packages/squiggle-lang/bsconfig.json +++ b/packages/squiggle-lang/bsconfig.json @@ -5,11 +5,11 @@ "dir": "src/rescript", "subdirs": true }, - // { - // "dir": "__tests__", - // "type": "dev", - // "subdirs": true - // }, + { + "dir": "__tests__", + "type": "dev", + "subdirs": true + }, { "dir": "benchmark", "type": "dev", diff --git a/packages/squiggle-lang/scripts/run-file.js b/packages/squiggle-lang/scripts/run-file.js index fb09aa23..f697f909 100755 --- a/packages/squiggle-lang/scripts/run-file.js +++ b/packages/squiggle-lang/scripts/run-file.js @@ -35,4 +35,4 @@ const result = project.getResult("a"); console.log("Result:", result.tag, result.value.toString()); const bindings = project.getBindings("a"); -console.log("Bindings:", bindings.asValue().toString()); +console.log("Bindings:", bindings.toString()); diff --git a/packages/squiggle-lang/src/js/SqRecord.ts b/packages/squiggle-lang/src/js/SqRecord.ts index 85eac76d..6ce3823e 100644 --- a/packages/squiggle-lang/src/js/SqRecord.ts +++ b/packages/squiggle-lang/src/js/SqRecord.ts @@ -12,4 +12,8 @@ export class SqRecord { ([k, v]) => [k, wrapValue(v, this.location.extend(k))] as const ); } + + toString() { + return RSRecord.toString(this._value); + } } diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res index d76a8cbc..96f5b0a8 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res @@ -8,6 +8,7 @@ type errorValue = Reducer_ErrorValue.errorValue */ type rec frType = | FRTypeNumber + | FRTypeBool | FRTypeNumeric | FRTypeDistOrNumber | FRTypeDist @@ -27,6 +28,7 @@ and frTypeRecordParam = (string, frType) */ type rec frValue = | FRValueNumber(float) + | FRValueBool(bool) | FRValueDist(DistributionTypes.genericDist) | FRValueArray(array) | FRValueDistOrNumber(frValueDistOrNumber) @@ -71,6 +73,7 @@ module FRType = { let rec toString = (t: t) => switch t { | FRTypeNumber => "number" + | FRTypeBool => "bool" | FRTypeNumeric => "numeric" | FRTypeDist => "distribution" | FRTypeDistOrNumber => "distribution|number" @@ -107,6 +110,7 @@ module FRType = { | (FRTypeAny, f) => toFrValue(f) | (FRTypeString, IEvString(f)) => Some(FRValueString(f)) | (FRTypeNumber, IEvNumber(f)) => Some(FRValueNumber(f)) + | (FRTypeBool, IEvBool(f)) => Some(FRValueBool(f)) | (FRTypeDistOrNumber, IEvNumber(f)) => Some(FRValueDistOrNumber(FRValueNumber(f))) | (FRTypeDistOrNumber, IEvDistribution(Symbolic(#Float(f)))) => Some(FRValueDistOrNumber(FRValueNumber(f))) @@ -142,6 +146,7 @@ module FRType = { let rec matchReverse = (e: frValue): internalExpressionValue => switch e { | FRValueNumber(f) => IEvNumber(f) + | FRValueBool(f) => IEvBool(f) | FRValueDistOrNumber(FRValueNumber(n)) => IEvNumber(n) | FRValueDistOrNumber(FRValueDist(n)) => IEvDistribution(n) | FRValueDist(dist) => IEvDistribution(dist) 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 3bc610a4..f5f7c818 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res @@ -72,5 +72,25 @@ let library = [ | _ => Error(impossibleError) } } - ) + ), + makeFn( + "not", + [FRTypeNumber], + inputs => { + switch inputs { + | [IEvNumber(x)] => IEvBool(x != 0.)->Ok + | _ => Error(impossibleError) + } + } + ), + makeFn( + "not", + [FRTypeBool], + inputs => { + switch inputs { + | [IEvBool(x)] => IEvBool(!x)->Ok + | _ => Error(impossibleError) + } + } + ), ] 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 ddf250dc..c00dbe5c 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 @@ -18,15 +18,11 @@ let rec get = ({ namespace, parent }: t, id: string) => { } } -let getWithDefault = (namespace: t, id: string, default) => - switch namespace->get(id) { - | Some(v) => Some(v) - | None => default - } - let set = ({ namespace } as bindings: t, id: string, value): t => { - let _ = namespace->Reducer_Namespace.set(id, value) - bindings + { + ...bindings, + namespace: namespace->Reducer_Namespace.set(id, value), + } } let rec toString = ({ namespace, parent }: t) => { @@ -43,8 +39,8 @@ let extend = (bindings: t): t => { namespace: Reducer_Namespace.make(), parent: let make = (): t => { namespace: Reducer_Namespace.make(), parent: None } let removeResult = ({ namespace } as bindings: t): t => { - namespace->Belt.MutableMap.String.remove("__result__") - bindings + ...bindings, + namespace: namespace->Belt.Map.String.remove("__result__"), } let locals = ({ namespace }: t): Reducer_T.namespace => namespace @@ -92,16 +88,6 @@ let fromNamespace = (namespace: Reducer_Namespace.t): t => { namespace, parent: // NameSpace(Belt.Map.String.set(container, typeReferencesKey, r2)) // } -// let removeOther = (NameSpace(container): t, NameSpace(otherContainer): t): t => { -// let keys = Belt.Map.String.keysToArray(otherContainer) -// NameSpace( -// Belt.Map.String.keep(container, (key, _value) => { -// let removeThis = Js.Array2.includes(keys, key) -// !removeThis -// }), -// ) -// } - // 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 60adcb1e..f9b8a2c8 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res @@ -2,7 +2,7 @@ type t = Reducer_T.context let createContext = (stdLib: Reducer_Namespace.t, environment: Reducer_T.environment): t => { { - bindings: stdLib->Reducer_Bindings.fromNamespace, + bindings: stdLib->Reducer_Bindings.fromNamespace->Reducer_Bindings.extend, environment: environment, } } 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 6d032523..62ec6cff 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 @@ -34,36 +34,6 @@ 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 arrayAtIndex = (aValueArray: array, fIndex: float) => - // switch Belt.Array.get(aValueArray, Belt.Int.fromFloat(fIndex)) { - // | Some(value) => value->Ok - // | None => REArrayIndexNotFound("Array index not found", Belt.Int.fromFloat(fIndex))->Error - // } - - // let moduleAtIndex = (nameSpace: Reducer_T.nameSpace, sIndex) => - // switch Bindings.get(nameSpace, sIndex) { - // | Some(value) => value->Ok - // | None => RERecordPropertyNotFound("Bindings property not found", sIndex)->Error - // } - - // let recordAtIndex = (dict: Belt.Map.String.t, sIndex) => - // switch Belt.Map.String.get(dict, sIndex) { - // | Some(value) => value->Ok - // | None => RERecordPropertyNotFound("Record property not found", sIndex)->Error - // } - let doAddArray = (originalA, b) => { let a = originalA->Js.Array2.copy let _ = Js.Array2.pushMany(a, b) @@ -84,10 +54,6 @@ let callInternal = ( value->Ok } - // let doSetBindings = (bindings: Reducer_T.nameSpace, symbol: string, value: Reducer_T.value) => { - // Bindings.set(bindings, symbol, value)->IEvBindings->Ok - // } - // let doSetTypeAliasBindings = ( // bindings: nameSpace, // symbol: string, 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 c0e623bc..bfaf993a 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 @@ -8,55 +8,74 @@ type errorValue = Reducer_ErrorValue.errorValue /* Recursively evaluate the expression */ -let rec evaluate: T.reducerFn = (expression, context) => { +let rec evaluate: T.reducerFn = (expression, context): (T.value, T.context) => { // Js.log(`reduce: ${expression->Reducer_Expression_T.toString}`) switch expression { | T.EBlock(statements) => { let innerContext = {...context, bindings: context.bindings->Bindings.extend} - statements->Js.Array2.reduce((_, statement) => statement->evaluate(innerContext), T.IEvVoid) + let (value, _) = statements->Belt.Array.reduce( + (T.IEvVoid, innerContext), + ((_, currentContext), statement) => statement->evaluate(currentContext) + ) + (value, context) // inner context can be dropped } | T.EProgram(statements) => { - // Js.log(`bindings: ${context.bindings->Reducer_Bindings.toString}`) - let res = - statements->Js.Array2.reduce((_, statement) => statement->evaluate(context), T.IEvVoid) + // Js.log(`bindings: ${context.bindings->Bindings.locals->Reducer_Namespace.toString}`) + let (value, finalContext) = statements->Belt.Array.reduce( + (T.IEvVoid, context), + ((_, currentContext), statement) => statement->evaluate(currentContext)) - // Js.log(`bindings after: ${context.bindings->Reducer_Bindings.toString}`) - res + // Js.log(`bindings after: ${finalContext.bindings->Bindings.locals->Reducer_Namespace.toString}`) + (value, finalContext) } - | T.EArray(elements) => elements->Js.Array2.map(element => evaluate(element, context))->T.IEvArray + | T.EArray(elements) => { + let value = elements->Belt.Array.map(element => { + let (value, _) = evaluate(element, context) + value + })->T.IEvArray + (value, context) + } - | 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")->Reducer_ErrorValue.ErrorException->raise - } - let value = eValue->evaluate(context) - (keyString, value) - }) - ->Belt.Map.String.fromArray - ->IEvRecord + | T.ERecord(pairs) => { + let value = + pairs + ->Belt.Array.map(((eKey, eValue)) => { + let (key, _) = eKey->evaluate(context) + let keyString = switch key { + | IEvString(s) => s + | _ => REOther("Record keys must be strings")->Reducer_ErrorValue.ErrorException->raise + } + let (value, _) = eValue->evaluate(context) + (keyString, value) + }) + ->Belt.Map.String.fromArray + ->T.IEvRecord + (value, context) + } | T.EAssign(left, right) => { - let result = right->evaluate(context) - let _ = context.bindings->Bindings.set(left, result) - T.IEvVoid + let (result, _) = right->evaluate(context) + ( + T.IEvVoid, + { + ...context, + bindings: context.bindings->Bindings.set(left, result), + } + ) } | T.ESymbol(name) => switch context.bindings->Bindings.get(name) { - | Some(v) => v + | Some(v) => (v, context) | None => Reducer_ErrorValue.RESymbolNotFound(name)->Reducer_ErrorValue.ErrorException->raise } - | T.EValue(value) => value + | T.EValue(value) => (value, context) | T.ETernary(predicate, trueCase, falseCase) => { - let predicateResult = predicate->evaluate(context) + let (predicateResult, _) = predicate->evaluate(context) switch predicateResult { | T.IEvBool(value) => (value ? trueCase : falseCase)->evaluate(context) | _ => REExpectedType("Boolean", "")->Reducer_ErrorValue.ErrorException->raise @@ -64,13 +83,16 @@ let rec evaluate: T.reducerFn = (expression, context) => { } | T.ELambda(parameters, body) => - Lambda.makeLambda(parameters, context.bindings, body)->T.IEvLambda + (Lambda.makeLambda(parameters, context.bindings, body)->T.IEvLambda, context) | T.ECall(fn, args) => { - let lambda = fn->evaluate(context) - let argValues = Js.Array2.map(args, arg => arg->evaluate(context)) + let (lambda, _) = fn->evaluate(context) + let argValues = Js.Array2.map(args, arg => { + let (argValue, _) = arg->evaluate(context) + argValue + }) switch lambda { - | T.IEvLambda(lambda) => Lambda.doLambdaCall(lambda, argValues, context.environment, evaluate) + | T.IEvLambda(lambda) => (Lambda.doLambdaCall(lambda, argValues, context.environment, evaluate), context) | _ => REExpectedType("Lambda", "")->Reducer_ErrorValue.ErrorException->raise } } @@ -80,18 +102,19 @@ let rec evaluate: T.reducerFn = (expression, context) => { module BackCompatible = { // Those methods are used to support the existing tests // If they are used outside limited testing context, error location reporting will fail - let parse = (peggyCode: string): result => + let parse = (peggyCode: string): result => peggyCode->Reducer_Peggy_Parse.parse->Result.map(Reducer_Peggy_ToExpression.fromNode) - let evaluate = (expression: Reducer_T.expression): result => { + let evaluate = (expression: T.expression): result => { let context = Reducer_Context.createDefaultContext() try { - expression->evaluate(context)->Ok + let (value, _) = expression->evaluate(context) + value->Ok } catch { | exn => Reducer_ErrorValue.fromException(exn)->Error } } - let evaluateString = (peggyCode: string): result => + let evaluateString = (peggyCode: string): result => parse(peggyCode)->Result.flatMap(evaluate) } 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 49ca0cde..f6cc4ffa 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 @@ -34,11 +34,14 @@ let makeLambda = ( } let localBindings = bindings->Reducer_Bindings.extend - parameters->Js.Array2.forEachi((parameter, index) => { - let _ = localBindings->Reducer_Bindings.set(parameter, arguments[index]) + let localBindingsWithParameters = parameters->Belt.Array.reduceWithIndex( + localBindings, + (currentBindings, parameter, index) => { + currentBindings->Reducer_Bindings.set(parameter, arguments[index]) }) - reducer(body, {bindings: localBindings, environment: environment}) + let (value, _) = reducer(body, {bindings: localBindingsWithParameters, environment: environment}) + value } { 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 91fb3b1c..1aa64246 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 @@ -1,36 +1,23 @@ /* - An expression is a Lisp AST. An expression is either a primitive value or a list of expressions. - In the case of a list of expressions (e1, e2, e3, ...eN), the semantic is - apply e1, e2 -> apply e3 -> ... -> apply eN - This is Lisp semantics. It holds true in both eager and lazy evaluations. - A Lisp AST contains only expressions/primitive values to apply to their left. - The act of defining the semantics of a functional language is to write it in terms of Lisp AST. + An expression is an intermediate representation of a Squiggle code. + Expressions are evaluated by `Reducer_Expression.evaluate` function. */ -module Extra = Reducer_Extra module InternalExpressionValue = ReducerInterface_InternalExpressionValue -type internalExpressionValue = Reducer_T.value -type environment = Reducer_T.environment - -type expression = Reducer_T.expression - -type t = expression - -type context = Reducer_T.context - -type reducerFn = Reducer_T.reducerFn +type t = Reducer_T.expression let commaJoin = values => values->Reducer_Extra_Array.intersperse(", ")->Js.String.concatMany("") +let semicolonJoin = values => values->Reducer_Extra_Array.intersperse("; ")->Js.String.concatMany("") /* Converts the expression to String */ -let rec toString = (expression: expression) => +let rec toString = (expression: t) => switch expression { - | EBlock(statements) => `{${Js.Array2.map(statements, aValue => toString(aValue))->commaJoin}}` - | EProgram(statements) => `<${Js.Array2.map(statements, aValue => toString(aValue))->commaJoin}>` + | EBlock(statements) => `{${Js.Array2.map(statements, aValue => toString(aValue))->semicolonJoin}}` + | EProgram(statements) => Js.Array2.map(statements, aValue => toString(aValue))->semicolonJoin | EArray(aList) => `[${Js.Array2.map(aList, aValue => toString(aValue))->commaJoin}]` - | ERecord(map) => `{${map->Belt.Array.map(((key, value)) => `${key->toString}: ${value->toString}`)->Js.Array2.toString}}` + | ERecord(map) => `{${map->Belt.Array.map(((key, value)) => `${key->toString}: ${value->toString}`)->commaJoin}}` | ESymbol(name) => name | ETernary(predicate, trueCase, falseCase) => `${predicate->toString} ? (${trueCase->toString}) : (${falseCase->toString})` @@ -52,30 +39,19 @@ let toStringResultOkless = codeResult => | Error(m) => `Error(${Reducer_ErrorValue.errorToString(m)})` } -let inspect = (expr: expression): expression => { +let inspect = (expr: t): t => { Js.log(toString(expr)) expr } -let inspectResult = (r: result): result< - expression, +let inspectResult = (r: result): result< + t, Reducer_ErrorValue.errorValue, > => { Js.log(toStringResult(r)) r } -type ffiFn = ( - array, - environment, -) => result - -type optionFfiFn = (array, environment) => option -type optionFfiFnReturningResult = ( - array, - environment, -) => option> - let resultToValue = (rExpression: result): t => switch rExpression { | Ok(expression) => expression diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res index 581f765b..7a95f58d 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res @@ -1,21 +1,21 @@ type t = Reducer_T.namespace -let make = (): t => Belt.MutableMap.String.make() +let make = (): t => Belt.Map.String.empty let get = (namespace: t, id: string): option => - namespace->Belt.MutableMap.String.get(id) + namespace->Belt.Map.String.get(id) let set = (namespace: t, id: string, value): t => { - namespace->Belt.MutableMap.String.set(id, value) - namespace + namespace->Belt.Map.String.set(id, value) } let mergeFrom = (from: t, to: t): t => { - to->Belt.MutableMap.String.reduce(from, (namespace, key, value) => { + to->Belt.Map.String.reduce(from, (namespace, key, value) => { if key != "__result__" { - namespace->Belt.MutableMap.String.set(key, value) + namespace->set(key, value) + } else { + namespace } - namespace }) } @@ -24,15 +24,15 @@ let mergeMany = (namespaces: array): t => let toString = (namespace: t) => namespace - ->Belt.MutableMap.String.toArray + ->Belt.Map.String.toArray ->Belt.Array.map(((eachKey, eachValue)) => `${eachKey}: ${eachValue->ReducerInterface_InternalExpressionValue.toString}`) ->Js.Array2.toString let fromArray = (a): t => - Belt.MutableMap.String.fromArray(a) + Belt.Map.String.fromArray(a) let toMap = (namespace: t): Reducer_T.map => - namespace->Belt.MutableMap.String.toArray->Belt.Map.String.fromArray + namespace let toRecord = (namespace: t): Reducer_T.value => namespace->toMap->IEvRecord diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res index 08f0b74a..e7fe07f3 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res @@ -38,7 +38,7 @@ and expression = | ELambda(array, expression) | EValue(value) -and namespace = Belt.MutableMap.String.t +and namespace = Belt.Map.String.t and bindings = { namespace: namespace, parent: option, @@ -49,4 +49,4 @@ and context = { environment: environment, } -and reducerFn = (expression, context) => value +and reducerFn = (expression, context) => (value, context) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res index 6b757b9a..c3ebf5e3 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res @@ -6,7 +6,7 @@ let internalStdLib: Reducer_T.namespace = { ->Reducer_Namespace.mergeFrom(SquiggleLibrary_Math.make()) ->Reducer_Namespace.mergeFrom(SquiggleLibrary_Versions.make()) - let _ = res->Reducer_Namespace.set( + let res = res->Reducer_Namespace.set( "$_atIndex_$", Reducer_Expression_Lambda.makeFFILambda((inputs, _, _) => { switch inputs { @@ -29,9 +29,10 @@ let internalStdLib: Reducer_T.namespace = { })->Reducer_T.IEvLambda, ) - FunctionRegistry_Library.nonRegistryLambdas->Js.Array2.forEach( - ((name, lambda)) => { - let _ = res->Reducer_Namespace.set(name, lambda->Reducer_T.IEvLambda) + let res = FunctionRegistry_Library.nonRegistryLambdas->Belt.Array.reduce( + res, + (cur, (name, lambda)) => { + cur->Reducer_Namespace.set(name, lambda->Reducer_T.IEvLambda) } ) @@ -59,10 +60,10 @@ let internalStdLib: Reducer_T.namespace = { // [ ] | (_, [IEvNumber(_), IEvNumber(_)]) // [ ] | (_, [IEvString(_), IEvString(_)]) => callMathJs(call) - FunctionRegistry_Library.registry.fnNameDict + let res = FunctionRegistry_Library.registry.fnNameDict ->Js.Dict.keys - ->Js.Array2.forEach(name => { - let _ = res->Reducer_Namespace.set( + ->Belt.Array.reduce(res, (cur, name) => { + cur->Reducer_Namespace.set( name, Reducer_Expression_Lambda.makeFFILambda((arguments, environment, reducer) => { switch FunctionRegistry_Library.call(name, arguments, environment, reducer) { diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res index ea888d71..cfbd6ec9 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res @@ -194,17 +194,17 @@ let tryRunWithResult = ( sourceId: string, rPrevResult: ProjectItem.T.resultArgumentType, ): ProjectItem.T.resultArgumentType => { - switch getResultOption(project, sourceId) { + switch project->getResultOption(sourceId) { | Some(result) => result // already ran | None => switch rPrevResult { | Error(error) => { - setResult(project, sourceId, Error(error)) + project->setResult(sourceId, Error(error)) Error(error) } | Ok(_prevResult) => { - doLinkAndRun(project, sourceId) - getResultOption(project, sourceId)->Belt.Option.getWithDefault(rPrevResult) + project->doLinkAndRun(sourceId) + project->getResultOption(sourceId)->Belt.Option.getWithDefault(rPrevResult) } } } @@ -214,7 +214,7 @@ let runAll = (project: t): unit => { let runOrder = Topology.getRunOrder(project) let initialState = Ok(Reducer_T.IEvVoid) let _finalState = Belt.Array.reduce(runOrder, initialState, (currState, currId) => - tryRunWithResult(project, currId, currState) + project->tryRunWithResult(currId, currState) ) } @@ -222,17 +222,17 @@ let run = (project: t, sourceId: string): unit => { let runOrder = Topology.getRunOrderFor(project, sourceId) let initialState = Ok(Reducer_T.IEvVoid) let _finalState = Belt.Array.reduce(runOrder, initialState, (currState, currId) => - tryRunWithResult(project, currId, currState) + project->tryRunWithResult(currId, currState) ) } let evaluate = (sourceCode: string) => { let project = createProject() - setSource(project, "main", sourceCode) - runAll(project) + project->setSource("main", sourceCode) + project->runAll ( - getResultOption(project, "main")->Belt.Option.getWithDefault(Reducer_T.IEvVoid->Ok), + project->getResultOption("main")->Belt.Option.getWithDefault(Reducer_T.IEvVoid->Ok), project->getBindings("main")->Reducer_Namespace.toMap, ) } diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res index 271b3ac9..e51f7d4b 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res @@ -174,8 +174,8 @@ 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->Reducer_Bindings.locals) + let (result, contextAfterEvaluation) = Reducer_Expression.evaluate(expression, context) + this->setResult(result->Ok)->setContinuation(contextAfterEvaluation.bindings->Reducer_Bindings.locals) } catch { | Reducer_ErrorValue.ErrorException(e) => this->failRun(e) | _ => this->failRun(RETodo("unhandled rescript exception")) diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res index 8d53e7fe..0eac623a 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res @@ -1,11 +1,10 @@ module ProjectItem = ReducerProject_ProjectItem -module ExpressionT = Reducer_Expression_T @genType.opaque type project = { items: Belt.MutableMap.String.t, mutable stdLib: Reducer_Namespace.t, - mutable environment: ExpressionT.environment, + mutable environment: Reducer_T.environment, mutable previousRunOrder: array, } type t = project From 43635bd39b9fec955f074aaae58e2709a00034c6 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Sun, 18 Sep 2022 03:15:58 +0400 Subject: [PATCH 16/46] remove IEvArrayString, implement __result__, cleanups --- .../SquiggleViewer/ExpressionViewer.tsx | 42 +++++++-------- .../Reducer/Reducer_ternaryOperator_test.res | 2 +- .../__tests__/Reducer/Reducer_test.res | 1 + packages/squiggle-lang/src/js/SqRecord.ts | 9 +++- packages/squiggle-lang/src/js/SqValue.ts | 10 ---- .../ForTS_SquiggleValue.res | 11 ---- .../ForTS_SquiggleValue_Record.res | 3 ++ .../ForTS_SquiggleValue_tag.ts | 1 - .../FunctionRegistry/Library/FR_Builtin.res | 53 +++++++++++++++++++ .../Reducer_Dispatch_BuiltIn.res | 26 ++++----- .../Reducer_Expression_ExpressionBuilder.res | 2 - .../rescript/Reducer/Reducer_Namespace.res | 6 +-- .../src/rescript/Reducer/Reducer_T.res | 1 - ...ducerInterface_InternalExpressionValue.res | 9 ---- .../ReducerInterface_StdLib.res | 2 +- .../ReducerProject/ReducerProject.res | 20 +++++-- 16 files changed, 114 insertions(+), 84 deletions(-) diff --git a/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx b/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx index 1ef5e150..1ae2a7b0 100644 --- a/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx +++ b/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx @@ -152,12 +152,6 @@ export const ExpressionViewer: React.FC = ({ value, width }) => { // {() => value.value} // // ); - case SqValueTag.ArrayString: - return ( - - {() => value.value.map((r) => `"${r}"`).join(", ")} - - ); case SqValueTag.Date: return ( @@ -242,24 +236,24 @@ export const ExpressionViewer: React.FC = ({ value, width }) => { ); } - case SqValueTag.Module: { - return ( - - {(_) => - value.value - .entries() - .filter(([key, _]) => !key.match(/^(__result__)$/)) - .map(([key, r]) => ( - - )) - } - - ); - } + // case SqValueTag.Module: { + // return ( + // + // {(_) => + // value.value + // .entries() + // .filter(([key, _]) => !key.match(/^(__result__)$/)) + // .map(([key, r]) => ( + // + // )) + // } + // + // ); + // } case SqValueTag.Record: const plot = makePlot(value.value); if (plot) { diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res index c1af1d59..3f66649b 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res @@ -4,7 +4,7 @@ open Reducer_TestHelpers describe("Parse ternary operator", () => { testParseToBe( "true ? 'YES' : 'NO'", - "Ok({(:$$_ternary_$$ true 'YES' 'NO')})", + "Ok(true ? ('YES') : ('NO'))", ) }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res index f6b9ad77..769937de 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res @@ -11,6 +11,7 @@ describe("eval", () => { testEvalToBe("(1+2)*3", "Ok(9)") testEvalToBe("2>1", "Ok(true)") testEvalToBe("concat('a ', 'b')", "Ok('a b')") + testEvalToBe("concat([3,4], [5,6,7])", "Ok([3,4,5,6,7])") testEvalToBe("log(10)", "Ok(2.302585092994046)") testEvalToBe("cos(10)", "Ok(-0.8390715290764524)") // TODO more built ins diff --git a/packages/squiggle-lang/src/js/SqRecord.ts b/packages/squiggle-lang/src/js/SqRecord.ts index 6ce3823e..27949220 100644 --- a/packages/squiggle-lang/src/js/SqRecord.ts +++ b/packages/squiggle-lang/src/js/SqRecord.ts @@ -1,5 +1,5 @@ import * as RSRecord from "../rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Record.gen"; -import { wrapValue } from "./SqValue"; +import { SqRecordValue, wrapValue } from "./SqValue"; import { SqValueLocation } from "./SqValueLocation"; type T = RSRecord.squiggleValue_Record; @@ -16,4 +16,11 @@ export class SqRecord { toString() { return RSRecord.toString(this._value); } + + asValue() { + return new SqRecordValue( + RSRecord.toSquiggleValue(this._value), + this.location + ); + } } diff --git a/packages/squiggle-lang/src/js/SqValue.ts b/packages/squiggle-lang/src/js/SqValue.ts index 7207b859..c0781937 100644 --- a/packages/squiggle-lang/src/js/SqValue.ts +++ b/packages/squiggle-lang/src/js/SqValue.ts @@ -44,14 +44,6 @@ export class SqArrayValue extends SqAbstractValue { } } -export class SqArrayStringValue extends SqAbstractValue { - tag = Tag.ArrayString as const; - - get value() { - return this.valueMethod(RSValue.getArrayString); - } -} - export class SqBoolValue extends SqAbstractValue { tag = Tag.Bool as const; @@ -150,7 +142,6 @@ export class SqVoidValue extends SqAbstractValue { const tagToClass = { [Tag.Array]: SqArrayValue, - [Tag.ArrayString]: SqArrayStringValue, [Tag.Bool]: SqBoolValue, [Tag.Date]: SqDateValue, [Tag.Declaration]: SqDeclarationValue, @@ -169,7 +160,6 @@ const tagToClass = { // type SqValue = typeof tagToClass[keyof typeof tagToClass]; export type SqValue = | SqArrayValue - | SqArrayStringValue | SqBoolValue | SqDateValue | SqDeclarationValue diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res index de3cced2..07dccc50 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res @@ -13,9 +13,6 @@ type squiggleValue_Lambda = ForTS_SquiggleValue_Lambda.squiggleValue_Lambda //us @module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtArray_: string = "Array" -@module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -external svtArrayString_: string = "ArrayString" - @module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtBool_: string = "Bool" @@ -61,7 +58,6 @@ external castEnum: string => squiggleValueTag = "%identity" let getTag = (variant: squiggleValue): squiggleValueTag => switch variant { | IEvArray(_) => svtArray_->castEnum - | IEvArrayString(_) => svtArrayString_->castEnum | IEvBool(_) => svtBool_->castEnum | IEvDate(_) => svtDate_->castEnum | IEvDeclaration(_) => svtDeclaration_->castEnum @@ -94,13 +90,6 @@ let getArray = (variant: squiggleValue): option => | _ => None } -@genType -let getArrayString = (variant: squiggleValue): option> => - switch variant { - | IEvArrayString(value) => value->Some - | _ => None - } - @genType let getBool = (variant: squiggleValue): option => switch variant { diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Record.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Record.res index 340abcfc..e145eefc 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Record.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Record.res @@ -7,3 +7,6 @@ let getKeyValuePairs = (value: squiggleValue_Record): array<(string, squiggleVal @genType let toString = (v: squiggleValue_Record) => ReducerInterface_InternalExpressionValue.toStringMap(v) + +@genType +let toSquiggleValue = (v: squiggleValue_Record): squiggleValue => IEvRecord(v) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_tag.ts b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_tag.ts index 31174e84..eec17c5b 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_tag.ts +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_tag.ts @@ -1,6 +1,5 @@ export enum squiggleValueTag { Array = "Array", - ArrayString = "ArrayString", Bool = "Bool", Date = "Date", Declaration = "Declaration", 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 f5f7c818..d5b79fc8 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res @@ -93,4 +93,57 @@ let library = [ } } ), + makeFn( + "concat", + [FRTypeString, FRTypeString], + inputs => { + switch inputs { + | [IEvString(a), IEvString(b)] => { + let answer = Js.String2.concat(a, b) + answer->Reducer_T.IEvString->Ok + } + | _ => Error(impossibleError) + } + } + ), + makeFn( + "concat", + [FRTypeArray(FRTypeAny), FRTypeArray(FRTypeAny)], + inputs => { + switch inputs { + | [IEvArray(originalA), IEvArray(b)] => { + let a = originalA->Js.Array2.copy + let _ = Js.Array2.pushMany(a, b) + a->Reducer_T.IEvArray->Ok + } + | _ => Error(impossibleError) + } + } + ), + makeFn( + "inspect", + [FRTypeAny], + inputs => { + switch inputs { + | [value] => { + Js.log(value->ReducerInterface_InternalExpressionValue.toString) + value->Ok + } + | _ => Error(impossibleError) + } + } + ), + makeFn( + "inspect", + [FRTypeAny, FRTypeString], + inputs => { + switch inputs { + | [value, IEvString(label)] => { + Js.log(`${label}: ${value->ReducerInterface_InternalExpressionValue.toString}`) + value->Ok + } + | _ => Error(impossibleError) + } + } + ), ] diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index 62ec6cff..1ef4a543 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 @@ -34,15 +34,15 @@ let callInternal = ( | call => call->IEV.toStringFunctionCall->MathJs.Eval.eval } - let doAddArray = (originalA, b) => { - let a = originalA->Js.Array2.copy - let _ = Js.Array2.pushMany(a, b) - a->Reducer_T.IEvArray->Ok - } - let doAddString = (a, b) => { - let answer = Js.String2.concat(a, b) - answer->Reducer_T.IEvString->Ok - } + // let doAddArray = (originalA, b) => { + // let a = originalA->Js.Array2.copy + // let _ = Js.Array2.pushMany(a, b) + // a->Reducer_T.IEvArray->Ok + // } + // let doAddString = (a, b) => { + // let answer = Js.String2.concat(a, b) + // answer->Reducer_T.IEvString->Ok + // } let inspect = (value: Reducer_T.value) => { Js.log(value->IEV.toString) @@ -107,10 +107,10 @@ let callInternal = ( // | ("$_typeTuple_$", [IEvArray(elems)]) => TypeBuilder.typeTuple(elems) // | ("$_typeArray_$", [elem]) => TypeBuilder.typeArray(elem) // | ("$_typeRecord_$", [IEvRecord(propertyMap)]) => TypeBuilder.typeRecord(propertyMap) - | ("concat", [IEvArray(aValueArray), IEvArray(bValueArray)]) => - doAddArray(aValueArray, bValueArray) - | ("concat", [IEvString(aValueString), IEvString(bValueString)]) => - doAddString(aValueString, bValueString) + // | ("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(_)]) 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 4d87e534..9f1ed5fb 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 @@ -6,8 +6,6 @@ type expression = Reducer_T.expression let eArray = (anArray: array) => anArray->T.EArray -let eArrayString = anArray => anArray->T.IEvArrayString->T.EValue - let eBool = aBool => aBool->T.IEvBool->T.EValue let eCall = (fn: expression, args: array): expression => T.ECall(fn, args) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res index 7a95f58d..638bdbcd 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res @@ -11,11 +11,7 @@ let set = (namespace: t, id: string, value): t => { let mergeFrom = (from: t, to: t): t => { to->Belt.Map.String.reduce(from, (namespace, key, value) => { - if key != "__result__" { - namespace->set(key, value) - } else { - namespace - } + namespace->set(key, value) }) } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res index e7fe07f3..4fda2e34 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res @@ -3,7 +3,6 @@ type environment = GenericDist.env @genType.opaque type rec value = | IEvArray(arrayValue) - | IEvArrayString(array) | IEvBool(bool) | IEvDate(Js.Date.t) | IEvDeclaration(lambdaDeclaration) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res index 5e880820..27b0a546 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res @@ -17,7 +17,6 @@ type functionCall = (string, array) let rec toString = (aValue: T.value) => switch aValue { | IEvArray(anArray) => toStringArray(anArray) - | IEvArrayString(anArray) => toStringArrayString(anArray) | IEvBool(aBool) => toStringBool(aBool) | IEvDate(date) => toStringDate(date) | IEvDeclaration(d) => toStringDeclaration(d) @@ -35,10 +34,6 @@ and toStringArray = anArray => { let args = anArray->Js.Array2.map(each => toString(each))->Js.Array2.toString `[${args}]` } -and toStringArrayString = anArray => { - let args = anArray->Js.Array2.toString - `[${args}]` -} and toStringBool = aBool => Js.String.make(aBool) and toStringCall = fName => `:${fName}` and toStringDate = date => DateTime.Date.toString(date) @@ -69,7 +64,6 @@ and toStringMap = aMap => { let toStringWithType = (aValue: T.value) => switch aValue { | IEvArray(_) => `Array::${toString(aValue)}` - | IEvArrayString(_) => `ArrayString::${toString(aValue)}` | IEvBool(_) => `Bool::${toString(aValue)}` | IEvDate(_) => `Date::${toString(aValue)}` | IEvDeclaration(_) => `Declaration::${toString(aValue)}` @@ -116,7 +110,6 @@ let toStringResultRecord = x => type internalExpressionValueType = | EvtArray - | EvtArrayString | EvtBool | EvtDate | EvtDeclaration @@ -137,7 +130,6 @@ type functionDefinitionSignature = let valueToValueType = (value: T.value) => switch value { | IEvArray(_) => EvtArray - | IEvArrayString(_) => EvtArrayString | IEvBool(_) => EvtBool | IEvDate(_) => EvtDate | IEvDeclaration(_) => EvtDeclaration @@ -160,7 +152,6 @@ let functionCallToCallSignature = (functionCall: functionCall): functionCallSign let valueTypeToString = (valueType: internalExpressionValueType): string => switch valueType { | EvtArray => `Array` - | EvtArrayString => `ArrayString` | EvtBool => `Bool` // | EvtCall => `Call` | EvtDate => `Date` diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res index c3ebf5e3..a3d41106 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res @@ -22,7 +22,7 @@ let internalStdLib: Reducer_T.namespace = { } | [IEvRecord(dict), IEvString(sIndex)] => switch Belt.Map.String.get(dict, sIndex) { | Some(value) => value - | None => RERecordPropertyNotFound("Record index not found", sIndex)->ErrorException->raise + | None => RERecordPropertyNotFound("Record property not found", sIndex)->ErrorException->raise } | _ => REOther("Trying to access key on wrong value")->ErrorException->raise } diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res index cfbd6ec9..12933e21 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res @@ -161,15 +161,25 @@ let getContinuationsBefore = (project: t, sourceId: string): array { - let nameSpace = Reducer_Namespace.mergeMany( - Belt.Array.concat( + let pastChain = project->getPastChain(sourceId) + let namespace = Reducer_Namespace.mergeMany( + Belt.Array.concatMany([ [project->getStdLib], - project->getContinuationsBefore(sourceId) - ) + pastChain->Belt.Array.map(project->getBindings), + pastChain->Belt.Array.map( + id => Reducer_Namespace.fromArray([ + ("__result__", + switch project->getResult(id) { + | Ok(result) => result + | Error(error) => error->Reducer_ErrorValue.ErrorException->raise + }) + ]) + ), + ]) ) let includesAsVariables = project->getIncludesAsVariables(sourceId) - Belt.Array.reduce(includesAsVariables, nameSpace, (acc, (variable, includeFile)) => + Belt.Array.reduce(includesAsVariables, namespace, (acc, (variable, includeFile)) => acc->Reducer_Namespace.set( variable, project->getBindings(includeFile)->Reducer_Namespace.toRecord From fd4137b596d03698d635582db077eb5b31360520 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Sun, 18 Sep 2022 18:32:53 +0400 Subject: [PATCH 17/46] run-file.js improvements --- packages/squiggle-lang/scripts/run-file.js | 38 ------------- packages/squiggle-lang/scripts/run-file.mjs | 60 +++++++++++++++++++++ 2 files changed, 60 insertions(+), 38 deletions(-) delete mode 100755 packages/squiggle-lang/scripts/run-file.js create mode 100755 packages/squiggle-lang/scripts/run-file.mjs diff --git a/packages/squiggle-lang/scripts/run-file.js b/packages/squiggle-lang/scripts/run-file.js deleted file mode 100755 index f697f909..00000000 --- a/packages/squiggle-lang/scripts/run-file.js +++ /dev/null @@ -1,38 +0,0 @@ -#!/usr/bin/env node -const s = require("@quri/squiggle-lang"); -const fs = require("fs"); - -const measure = (cb, times = 1) => { - const t1 = new Date(); - - for (let i = 1; i <= times; i++) { - cb(); - } - const t2 = new Date(); - return (t2 - t1) / 1000; -}; - -const project = s.SqProject.create(); -const sampleCount = process.env.SAMPLE_COUNT; -if (sampleCount) { - project.setEnvironment({ - sampleCount, - xyPointLength: sampleCount, - }); -} - -const src = fs.readFileSync(process.argv[2], "utf-8"); -if (!src) { - throw new Error("Expected src"); -} -console.log(`Running ${src}`); -project.setSource("a", src); - -const t = measure(() => project.run("a")); -console.log(`Time: ${t}`); - -const result = project.getResult("a"); -console.log("Result:", result.tag, result.value.toString()); - -const bindings = project.getBindings("a"); -console.log("Bindings:", bindings.toString()); diff --git a/packages/squiggle-lang/scripts/run-file.mjs b/packages/squiggle-lang/scripts/run-file.mjs new file mode 100755 index 00000000..65d67cdc --- /dev/null +++ b/packages/squiggle-lang/scripts/run-file.mjs @@ -0,0 +1,60 @@ +#!/usr/bin/env node +import { SqProject } from "@quri/squiggle-lang"; +import fs from "fs"; + +import { Command } from "commander"; + +const measure = (cb, times = 1) => { + const t1 = new Date(); + + for (let i = 1; i <= times; i++) { + cb(); + } + const t2 = new Date(); + return (t2 - t1) / 1000; +}; + +const red = (s) => `\x1b[31m${s}\x1b[0m`; +const green = (s) => `\x1b[32m${s}\x1b[0m`; + +const program = new Command(); + +program.option("-t, --time"); +program.option("-o, --output"); +program.arguments(""); + +const options = program.parse(process.argv); + +const project = SqProject.create(); +const sampleCount = process.env.SAMPLE_COUNT; +if (sampleCount) { + project.setEnvironment({ + sampleCount: Number(sampleCount), + xyPointLength: Number(sampleCount), + }); +} + +const src = fs.readFileSync(program.args[0], "utf-8"); +if (!src) { + throw new Error("Expected src"); +} + +project.setSource("main", src); +const t = measure(() => project.run("main")); + +const bindings = project.getBindings("main"); +const result = project.getResult("main"); + +if (options.output) { + console.log("Result:", result.tag, result.value.toString()); + console.log("Bindings:", bindings.toString()); +} + +if (options.time) { + console.log( + "Time:", + String(t), + result.tag === "Error" ? red(result.tag) : green(result.tag), + result.tag === "Error" ? result.value.toString() : "" + ); +} From bbc1bee3137e393c6950da289a79d5f2a8c33697 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Sun, 18 Sep 2022 18:33:01 +0400 Subject: [PATCH 18/46] fix more tests --- .../Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res | 4 ++-- .../__tests__/Reducer/Reducer_functionTricks_test.res | 4 ++-- .../ReducerInterface/ReducerInterface_Distribution_test.res | 2 +- .../SquiggleLibrary_FunctionRegistryLibrary_test.res | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res index 4932af3b..5c6848b8 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res @@ -24,9 +24,9 @@ describe("builtin", () => { }) describe("builtin exception", () => { - //It's a pity that MathJs does not return error position + //MathJS is no more, this is just a normal function call (TODO - refactor tests) test("MathJs Exception", () => - expectEvalToBe("testZadanga(1)", "Error(JS Exception: Error: Undefined function testZadanga)") + expectEvalToBe("testZadanga(1)", "Error(testZadanga is not defined)") ) }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res index 9b111354..8045d0d2 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res @@ -34,7 +34,7 @@ describe("symbol not defined", () => { testEvalToBe("f(x)=x(y); f(f)", "Error(y is not defined)") testEvalToBe("f(x)=x; f(f)", "Ok(lambda(x=>internal code))") testEvalToBe("f(x)=x(y); f(z)", "Error(z is not defined)") - testEvalToBe("f(x)=x(y); f(2)", "Error(2 is not a function)") + testEvalToBe("f(x)=x(y); f(2)", "Error(y is not defined)") testEvalToBe("f(x)=x(1); f(2)", "Error(2 is not a function)") }) @@ -48,7 +48,7 @@ describe("call and bindings", () => { testEvalToBe("f(x)=x+1; g(x)=f(x)+1; g(0)", "Ok(2)") testParseToBe( "f=99; g(x)=f; g(2)", - "Ok({(:$_let_$ :f {99}); (:$_let_$ :g (:$$_lambda_$$ [x] {:f})); (:$_endOfOuterBlock_$ () (:g 2))})", + "Ok(f = {99}; g = {|x| {f}}; (g)(2))", ) testEvalToBe("f=99; g(x)=f; g(2)", "Ok(99)") testEvalToBe("f(x)=x; g(x)=f(x); g(2)", "Ok(2)") diff --git a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res index 330767df..21a0e9c3 100644 --- a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res +++ b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res @@ -23,7 +23,7 @@ describe("eval on distribution functions", () => { testEval("-normal(5,2)", "Ok(Normal(-5,2))") }) describe("to", () => { - testEval("5 to 2", "Error(TODO: Low value must be less than high value.)") + testEval("5 to 2", "Error(Error: Low value must be less than high value.)") testEval("to(2,5)", "Ok(Lognormal(1.1512925464970227,0.27853260523016377))") testEval("to(-2,2)", "Ok(Normal(0,1.2159136638235384))") }) diff --git a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res index 831eb271..95fdbdf6 100644 --- a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res +++ b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res @@ -15,7 +15,7 @@ let examples = E.A.to_list(FunctionRegistry_Core.Registry.allExamples(registry)) describe("FunctionRegistry Library", () => { describe("Regular tests", () => { testEvalToBe("List.make(3, 'HI')", "Ok(['HI','HI','HI'])") - testEvalToBe("make(3, 'HI')", "Error(Function not found: make(Number,String))") + testEvalToBe("make(3, 'HI')", "Error(make is not defined)") testEvalToBe("List.upTo(1,3)", "Ok([1,2,3])") testEvalToBe("List.first([3,5,8])", "Ok(3)") testEvalToBe("List.last([3,5,8])", "Ok(8)") From 6aa2280543b1e0ced47739950c7ae1b7b340ad49 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Sun, 18 Sep 2022 18:33:20 +0400 Subject: [PATCH 19/46] conver the rest of dispatch functions (Date, Duration) --- packages/squiggle-lang/src/js/SqProject.ts | 4 + .../rescript/ForTS/ForTS_ReducerProject.res | 4 + .../FunctionRegistry_Core.res | 45 +++-- .../FunctionRegistry_Library.res | 2 + .../FunctionRegistry/Library/FR_Builtin.res | 16 +- .../FunctionRegistry/Library/FR_Date.res | 155 ++++++++++++++++++ .../Library/FR_GenericDist.res | 5 +- .../FunctionRegistry/Library/FR_Mathjs.res | 38 +++++ .../Reducer_Expression/Reducer_Expression.res | 2 +- .../ReducerInterface_Date.res | 27 --- .../ReducerInterface_Duration.res | 36 ---- .../ReducerInterface_ExternalLibrary.res | 4 +- .../ReducerInterface_StdLib.res | 4 +- .../src/rescript/Utility/Mathjs.res | 10 -- .../src/rescript/Utility/MathjsWrapper.js | 9 - 15 files changed, 256 insertions(+), 105 deletions(-) create mode 100644 packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Date.res create mode 100644 packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Mathjs.res delete mode 100644 packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Date.res delete mode 100644 packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Duration.res delete mode 100644 packages/squiggle-lang/src/rescript/Utility/Mathjs.res delete mode 100644 packages/squiggle-lang/src/rescript/Utility/MathjsWrapper.js diff --git a/packages/squiggle-lang/src/js/SqProject.ts b/packages/squiggle-lang/src/js/SqProject.ts index eb54bc4a..9e79b564 100644 --- a/packages/squiggle-lang/src/js/SqProject.ts +++ b/packages/squiggle-lang/src/js/SqProject.ts @@ -111,4 +111,8 @@ export class SqProject { setEnvironment(environment: environment) { RSProject.setEnvironment(this._value, environment); } + + getEnvironment(): environment { + return RSProject.getEnvironment(this._value); + } } diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res index 5b48b8f7..dabd72a5 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res @@ -211,6 +211,10 @@ let evaluate = (sourceCode: string): ( let setEnvironment = (project: reducerProject, environment: environment): unit => project->Private.setEnvironment(environment) +@genType +let getEnvironment = (project: reducerProject): environment => + project->Private.getEnvironment + /* Foreign function interface is intentionally demolished. There is another way to do that: Umur. diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res index 96f5b0a8..714456a8 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res @@ -10,6 +10,8 @@ type rec frType = | FRTypeNumber | FRTypeBool | FRTypeNumeric + | FRTypeDate + | FRTypeTimeDuration | FRTypeDistOrNumber | FRTypeDist | FRTypeLambda @@ -29,6 +31,8 @@ and frTypeRecordParam = (string, frType) type rec frValue = | FRValueNumber(float) | FRValueBool(bool) + | FRValueDate(Js.Date.t) + | FRValueTimeDuration(float) | FRValueDist(DistributionTypes.genericDist) | FRValueArray(array) | FRValueDistOrNumber(frValueDistOrNumber) @@ -65,15 +69,14 @@ type function = { isExperimental: bool, } -type fnNameDict = Js.Dict.t> -type registry = {functions: array, fnNameDict: fnNameDict} - module FRType = { type t = frType let rec toString = (t: t) => switch t { | FRTypeNumber => "number" | FRTypeBool => "bool" + | FRTypeDate => "date" + | FRTypeTimeDuration => "duration" | FRTypeNumeric => "numeric" | FRTypeDist => "distribution" | FRTypeDistOrNumber => "distribution|number" @@ -90,6 +93,7 @@ module FRType = { } let rec toFrValue = (r: internalExpressionValue): option => + // not all value variants are supported, but it's not important (we'll probably deprecate frValues soon anyway) switch r { | IEvNumber(f) => Some(FRValueNumber(f)) | IEvString(f) => Some(FRValueString(f)) @@ -111,6 +115,8 @@ module FRType = { | (FRTypeString, IEvString(f)) => Some(FRValueString(f)) | (FRTypeNumber, IEvNumber(f)) => Some(FRValueNumber(f)) | (FRTypeBool, IEvBool(f)) => Some(FRValueBool(f)) + | (FRTypeDate, IEvDate(f)) => Some(FRValueDate(f)) + | (FRTypeTimeDuration, IEvTimeDuration(f)) => Some(FRValueTimeDuration(f)) | (FRTypeDistOrNumber, IEvNumber(f)) => Some(FRValueDistOrNumber(FRValueNumber(f))) | (FRTypeDistOrNumber, IEvDistribution(Symbolic(#Float(f)))) => Some(FRValueDistOrNumber(FRValueNumber(f))) @@ -147,6 +153,8 @@ module FRType = { switch e { | FRValueNumber(f) => IEvNumber(f) | FRValueBool(f) => IEvBool(f) + | FRValueDate(f) => IEvDate(f) + | FRValueTimeDuration(f) => IEvTimeDuration(f) | FRValueDistOrNumber(FRValueNumber(n)) => IEvNumber(n) | FRValueDistOrNumber(FRValueDist(n)) => IEvDistribution(n) | FRValueDist(dist) => IEvDistribution(dist) @@ -265,33 +273,44 @@ module Function = { } module Registry = { + type fnNameDict = Belt.Map.String.t> + type registry = {functions: array, fnNameDict: fnNameDict} + let toJson = (r: registry) => r.functions->E.A2.fmap(Function.toJson) let allExamples = (r: registry) => r.functions->E.A2.fmap(r => r.examples)->E.A.concatMany let allExamplesWithFns = (r: registry) => r.functions->E.A2.fmap(fn => fn.examples->E.A2.fmap(example => (fn, example)))->E.A.concatMany + let allNames = (r: registry) => r.fnNameDict->Belt.Map.String.keysToArray + 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 => - fn.definitions->Js.Array2.forEach(def => { + // Three layers of reduce: + // 1. functions + // 2. definitions of each function + // 3. name variations of each definition + r->Belt.Array.reduce( + Belt.Map.String.empty, + (acc, fn) => + fn.definitions->Belt.Array.reduce( + acc, + (acc, def) => { 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) { + names->Belt.Array.reduce(acc, (acc, name) => { + switch acc->Belt.Map.String.get(name) { | Some(fns) => { - let _ = fns->Js.Array2.push(def) + let _ = fns->Js.Array2.push(def) // mutates the array, no need to update acc + acc } - | None => res->Js.Dict.set(name, [def]) + | None => acc->Belt.Map.String.set(name, [def]) } }) }) ) - res } let make = (fns: array): registry => { @@ -306,7 +325,7 @@ module Registry = { env: Reducer_T.environment, reducer: Reducer_T.reducerFn, ): result => { - switch Js.Dict.get(registry.fnNameDict, fnName) { + switch Belt.Map.String.get(registry.fnNameDict, fnName) { | Some(definitions) => { let showNameMatchDefinitions = () => { let defsString = diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res index ce14c6da..34de2e2b 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res @@ -11,6 +11,8 @@ let fnList = Belt.Array.concatMany([ FR_Scoring.library, FR_GenericDist.library, FR_Units.library, + FR_Date.library, + FR_Mathjs.library, ]) let registry = FunctionRegistry_Core.Registry.make(fnList) 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 d5b79fc8..b3103add 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res @@ -51,8 +51,20 @@ let makeBinaryCmpFn = (name: string, fn: (float, float) => bool) => { ) } +let makeBinaryBooleanFn = (name: string, fn: (bool, bool) => bool) => { + makeFn( + name, + [FRTypeBool, FRTypeBool], + inputs => { + switch inputs { + | [IEvBool(x), IEvBool(y)] => fn(x, y)->IEvBool->Ok + | _ => Error(impossibleError) + } + } + ) +} + let library = [ - // TODO - other MathJS makeBinaryFn("add", (x, y) => x +. y), makeBinaryFn("subtract", (x, y) => x -. y), makeBinaryFn("multiply", (x, y) => x *. y), @@ -63,6 +75,8 @@ let library = [ makeBinaryCmpFn("smallerEq", (x, y) => x <= y), makeBinaryCmpFn("larger", (x, y) => x > y), makeBinaryCmpFn("largerEq", (x, y) => x >= y), + makeBinaryBooleanFn("or", (x, y) => x || y), + makeBinaryBooleanFn("and", (x, y) => x && y), makeFn( "unaryMinus", [FRTypeNumber], diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Date.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Date.res new file mode 100644 index 00000000..0e79d8cd --- /dev/null +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Date.res @@ -0,0 +1,155 @@ +open FunctionRegistry_Core +open FunctionRegistry_Helpers + +let makeFn = ( + name: string, + inputs: array, + fn: array => result +) => + Function.make( + ~name, + ~nameSpace="", + ~requiresNamespace=false, + ~definitions=[ + FnDefinition.make(~name, ~inputs, ~run=(inputs, _, _, _) => fn(inputs), ()) + ], + () + ) + +let makeNumberToDurationFn = ( + name: string, + fn: float => DateTime.Duration.t, +) => + Function.make( + ~name, + ~nameSpace="", + ~requiresNamespace=false, + ~definitions=[ + FnDefinition.make(~name, ~inputs=[FRTypeNumber], ~run=(inputs, _, _, _) => + switch inputs { + | [IEvNumber(t)] => IEvTimeDuration(fn(t))->Ok + | _ => Error(impossibleError) + }, ()) + ], + () + ) + +let makeDurationToNumberFn = ( + name: string, + fn: DateTime.Duration.t => float, +) => + Function.make( + ~name, + ~nameSpace="", + ~requiresNamespace=false, + ~definitions=[ + FnDefinition.make(~name, ~inputs=[FRTypeTimeDuration], ~run=(inputs, _, _, _) => + switch inputs { + | [IEvTimeDuration(t)] => IEvNumber(fn(t))->Ok + | _ => Error(impossibleError) + }, ()) + ], + () + ) + +let library = [ + makeFn("toString", [FRTypeDate], (inputs) => + switch inputs { + | [IEvDate(t)] => IEvString(DateTime.Date.toString(t))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("makeDateFromYear", [FRTypeNumber], (inputs) => + switch inputs { + | [IEvNumber(year)] => + switch DateTime.Date.makeFromYear(year) { + | Ok(t) => IEvDate(t)->Ok + | Error(e) => Reducer_ErrorValue.RETodo(e)->Error + } + | _ => Error(impossibleError) + } + ), + makeFn("dateFromNumber", [FRTypeNumber], (inputs) => + switch inputs { + | [IEvNumber(f)] => IEvDate(DateTime.Date.fromFloat(f))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("toNumber", [FRTypeDate], (inputs) => + switch inputs { + | [IEvDate(f)] => IEvNumber(DateTime.Date.toFloat(f))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("subtract", [FRTypeDate, FRTypeDate], (inputs) => + switch inputs { + | [IEvDate(d1), IEvDate(d2)] => switch DateTime.Date.subtract(d1, d2) { + | Ok(d) => IEvTimeDuration(d)->Ok + | Error(e) => Error(RETodo(e)) + } + | _ => Error(impossibleError) + } + ), + makeFn("subtract", [FRTypeDate, FRTypeTimeDuration], (inputs) => + switch inputs { + | [IEvDate(d1), IEvTimeDuration(d2)] => + IEvDate(DateTime.Date.subtractDuration(d1, d2))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("add", [FRTypeDate, FRTypeTimeDuration], (inputs) => + switch inputs { + | [IEvDate(d1), IEvTimeDuration(d2)] => + IEvDate(DateTime.Date.addDuration(d1, d2))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("toString", [FRTypeTimeDuration], (inputs) => + switch inputs { + | [IEvTimeDuration(t)] => IEvString(DateTime.Duration.toString(t))->Ok + | _ => Error(impossibleError) + } + ), + makeNumberToDurationFn("minutes", DateTime.Duration.fromMinutes), + makeNumberToDurationFn("fromUnit_minutes", DateTime.Duration.fromMinutes), + makeNumberToDurationFn("hours", DateTime.Duration.fromHours), + makeNumberToDurationFn("fromUnit_hours", DateTime.Duration.fromHours), + makeNumberToDurationFn("days", DateTime.Duration.fromDays), + makeNumberToDurationFn("fromUnit_days", DateTime.Duration.fromDays), + makeNumberToDurationFn("years", DateTime.Duration.fromYears), + makeNumberToDurationFn("fromUnit_years", DateTime.Duration.fromYears), + makeDurationToNumberFn("toMinutes", DateTime.Duration.toMinutes), + makeDurationToNumberFn("toHours", DateTime.Duration.toHours), + makeDurationToNumberFn("toDays", DateTime.Duration.toDays), + makeDurationToNumberFn("toYears", DateTime.Duration.toYears), + makeFn("add", [FRTypeTimeDuration, FRTypeTimeDuration], (inputs) => + switch inputs { + | [IEvTimeDuration(d1), IEvTimeDuration(d2)] => IEvTimeDuration(DateTime.Duration.add(d1, d2))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("subtract", [FRTypeTimeDuration, FRTypeTimeDuration], (inputs) => + switch inputs { + | [IEvTimeDuration(d1), IEvTimeDuration(d2)] => IEvTimeDuration(DateTime.Duration.subtract(d1, d2))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("multiply", [FRTypeTimeDuration, FRTypeNumber], (inputs) => + switch inputs { + | [IEvTimeDuration(d1), IEvNumber(d2)] => IEvTimeDuration(DateTime.Duration.multiply(d1, d2))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("divide", [FRTypeTimeDuration, FRTypeNumber], (inputs) => + switch inputs { + | [IEvTimeDuration(d1), IEvNumber(d2)] => IEvTimeDuration(DateTime.Duration.divide(d1, d2))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("divide", [FRTypeTimeDuration, FRTypeTimeDuration], (inputs) => + switch inputs { + | [IEvTimeDuration(d1), IEvTimeDuration(d2)] => IEvNumber(d1 /. d2)->Ok + | _ => Error(impossibleError) + } + ), +] diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_GenericDist.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_GenericDist.res index adb510cb..5b7d5dca 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_GenericDist.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_GenericDist.res @@ -310,8 +310,6 @@ module Old = { | 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)) } @@ -370,8 +368,7 @@ let library = E.A.concatMany([ makeProxyFn("max", [FRTypeDist]), makeProxyFn("mode", [FRTypeDist]), makeProxyFn("integralSum", [FRTypeDist]), - // // FIXME: doesn't work with Js.Dict in FunctionRegistry_Core - // makeProxyFn("toString", [FRTypeDist]), + makeProxyFn("toString", [FRTypeDist]), makeProxyFn("sparkline", [FRTypeDist]), makeProxyFn("sparkline", [FRTypeDist, FRTypeNumber]), makeProxyFn("exp", [FRTypeDist]), diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Mathjs.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Mathjs.res new file mode 100644 index 00000000..c1141545 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Mathjs.res @@ -0,0 +1,38 @@ +open FunctionRegistry_Core +open FunctionRegistry_Helpers + +// FIXME - copy-pasted (see FR_Date.res and others) +let makeFn = ( + name: string, + inputs: array, + fn: array => result +) => + Function.make( + ~name, + ~nameSpace="", + ~requiresNamespace=false, + ~definitions=[ + FnDefinition.make(~name, ~inputs, ~run=(inputs, _, _, _) => fn(inputs), ()) + ], + () + ) + +@module("mathjs") external dummy_: string => unit = "evaluate" +let dummy1_ = dummy_ //Deceive the compiler to make the import although we wont make a call from rescript. Otherwise the optimizer deletes the import + +let mathjsFactorial: float => 'a = %raw(`function (expr) { return Mathjs.factorial(expr); }`) + +let library = [ + // TODO - other MathJS + // https://mathjs.org/docs/reference/functions.html + makeFn( + "factorial", + [FRTypeNumber], + inputs => { + switch inputs { + | [IEvNumber(x)] => mathjsFactorial(x)->Reducer_Js_Gate.jsToIEv + | _ => Error(impossibleError) + } + } + ), +] 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 bfaf993a..1136990b 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 @@ -93,7 +93,7 @@ let rec evaluate: T.reducerFn = (expression, context): (T.value, T.context) => { }) switch lambda { | T.IEvLambda(lambda) => (Lambda.doLambdaCall(lambda, argValues, context.environment, evaluate), context) - | _ => REExpectedType("Lambda", "")->Reducer_ErrorValue.ErrorException->raise + | _ => RENotAFunction(lambda->ReducerInterface_InternalExpressionValue.toString)->Reducer_ErrorValue.ErrorException->raise } } } diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Date.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Date.res deleted file mode 100644 index bde1459f..00000000 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Date.res +++ /dev/null @@ -1,27 +0,0 @@ -module T = Reducer_T - -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)]) => - switch DateTime.Date.makeFromYear(year) { - | Ok(t) => T.IEvDate(t)->Ok->Some - | Error(e) => Reducer_ErrorValue.RETodo(e)->Error->Some - } - | ("dateFromNumber", [IEvNumber(f)]) => T.IEvDate(DateTime.Date.fromFloat(f))->Ok->Some - | ("toNumber", [IEvDate(f)]) => T.IEvNumber(DateTime.Date.toFloat(f))->Ok->Some - | ("subtract", [IEvDate(d1), IEvDate(d2)]) => - switch DateTime.Date.subtract(d1, d2) { - | Ok(d) => T.IEvTimeDuration(d)->Ok - | Error(e) => Error(RETodo(e)) - }->Some - | ("subtract", [IEvDate(d1), IEvTimeDuration(d2)]) => - T.IEvDate(DateTime.Date.subtractDuration(d1, d2))->Ok->Some - | ("add", [IEvDate(d1), IEvTimeDuration(d2)]) => - T.IEvDate(DateTime.Date.addDuration(d1, d2))->Ok->Some - | _ => None - } -} diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Duration.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Duration.res deleted file mode 100644 index 889df52a..00000000 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Duration.res +++ /dev/null @@ -1,36 +0,0 @@ -module IEV = ReducerInterface_InternalExpressionValue -module T = Reducer_T -type internalExpressionValue = IEV.t - -let dispatch = (call: IEV.functionCall, _: T.environment): option< - result, -> => { - switch call { - | ("toString", [IEvTimeDuration(t)]) => T.IEvString(DateTime.Duration.toString(t))->Ok->Some - | ("minutes", [IEvNumber(f)]) => T.IEvTimeDuration(DateTime.Duration.fromMinutes(f))->Ok->Some - | ("fromUnit_minutes", [IEvNumber(f)]) => - T.IEvTimeDuration(DateTime.Duration.fromMinutes(f))->Ok->Some - | ("hours", [IEvNumber(f)]) => T.IEvTimeDuration(DateTime.Duration.fromHours(f))->Ok->Some - | ("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 - | ("years", [IEvNumber(f)]) => T.IEvTimeDuration(DateTime.Duration.fromYears(f))->Ok->Some - | ("fromUnit_years", [IEvNumber(f)]) => - T.IEvTimeDuration(DateTime.Duration.fromYears(f))->Ok->Some - | ("toHours", [IEvTimeDuration(f)]) => T.IEvNumber(DateTime.Duration.toHours(f))->Ok->Some - | ("toMinutes", [IEvTimeDuration(f)]) => T.IEvNumber(DateTime.Duration.toMinutes(f))->Ok->Some - | ("toDays", [IEvTimeDuration(f)]) => T.IEvNumber(DateTime.Duration.toDays(f))->Ok->Some - | ("toYears", [IEvTimeDuration(f)]) => T.IEvNumber(DateTime.Duration.toYears(f))->Ok->Some - | ("add", [IEvTimeDuration(d1), IEvTimeDuration(d2)]) => - T.IEvTimeDuration(DateTime.Duration.add(d1, d2))->Ok->Some - | ("subtract", [IEvTimeDuration(d1), IEvTimeDuration(d2)]) => - T.IEvTimeDuration(DateTime.Duration.subtract(d1, d2))->Ok->Some - | ("multiply", [IEvTimeDuration(d1), IEvNumber(d2)]) => - T.IEvTimeDuration(DateTime.Duration.multiply(d1, d2))->Ok->Some - | ("divide", [IEvTimeDuration(d1), IEvNumber(d2)]) => - T.IEvTimeDuration(DateTime.Duration.divide(d1, d2))->Ok->Some - | ("divide", [IEvTimeDuration(d1), IEvTimeDuration(d2)]) => T.IEvNumber(d1 /. d2)->Ok->Some - | _ => None - } -} diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res index 6976471a..4ce11eea 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res @@ -11,8 +11,8 @@ let dispatch = ( ): result => { E.A.O.firstSomeFn([ // () => ReducerInterface_GenericDistribution.dispatch(call, environment), - () => ReducerInterface_Date.dispatch(call, environment), - () => ReducerInterface_Duration.dispatch(call, environment), + // () => ReducerInterface_Date.dispatch(call, environment), + // () => ReducerInterface_Duration.dispatch(call, environment), // () => ReducerInterface_Number.dispatch(call, environment), // () => FunctionRegistry_Library.dispatch(call, environment, reducer), ])->E.O2.defaultFn(() => chain(call, environment, reducer)) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res index a3d41106..dc74135a 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res @@ -60,8 +60,8 @@ let internalStdLib: Reducer_T.namespace = { // [ ] | (_, [IEvNumber(_), IEvNumber(_)]) // [ ] | (_, [IEvString(_), IEvString(_)]) => callMathJs(call) - let res = FunctionRegistry_Library.registry.fnNameDict - ->Js.Dict.keys + let res = FunctionRegistry_Library.registry + ->FunctionRegistry_Core.Registry.allNames ->Belt.Array.reduce(res, (cur, name) => { cur->Reducer_Namespace.set( name, diff --git a/packages/squiggle-lang/src/rescript/Utility/Mathjs.res b/packages/squiggle-lang/src/rescript/Utility/Mathjs.res deleted file mode 100644 index ccf43100..00000000 --- a/packages/squiggle-lang/src/rescript/Utility/Mathjs.res +++ /dev/null @@ -1,10 +0,0 @@ -// @module("./MathjsWrapper.js") -// external parseMathExt: string => Js.Json.t = "parseMath" - -// let parseMath = (str: string): result => -// switch parseMathExt(str) { -// | exception Js.Exn.Error(err) => Error(Js.Exn.message(err) |> E.O.default("MathJS Parse Error")) -// | exception _ => Error("MathJS Parse Error") -// | j => Ok(j) -// } - diff --git a/packages/squiggle-lang/src/rescript/Utility/MathjsWrapper.js b/packages/squiggle-lang/src/rescript/Utility/MathjsWrapper.js deleted file mode 100644 index 99bb3776..00000000 --- a/packages/squiggle-lang/src/rescript/Utility/MathjsWrapper.js +++ /dev/null @@ -1,9 +0,0 @@ -const math = require("mathjs"); - -function parseMath(f) { - return JSON.parse(JSON.stringify(math.parse(f))); -} - -module.exports = { - parseMath, -}; From 271303fb5f76523076db62d0b3bc3c88ccb7d043 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Mon, 19 Sep 2022 15:00:38 +0400 Subject: [PATCH 20/46] fix more tests; FR improvements/refactorings --- .../Reducer_Bindings_test.res | 4 +- .../Reducer_Dispatch_BuiltInMacros_test.res | 1 + .../Reducer/Reducer_Namespace_test.res | 10 +- .../Reducer_Peggy_Parse_test.res | 196 ++++-------------- ...cer_Peggy_ToExpression_outerBlock_test.res | 16 +- .../Reducer_Peggy_ToExpression_test.res | 145 ++----------- .../Reducer/Reducer_TestMacroHelpers.res | 1 + .../Reducer_Type_Compile_test.res | 1 + ...educer_Type_TypeChecker_arguments_test.res | 1 + .../Reducer_Type_TypeChecker_test.res | 1 + .../Reducer_Type_switch_replacement_test.res | 1 + .../Reducer_functionAssignment_test.res | 10 +- .../Reducer/Reducer_functionTricks_test.res | 5 +- .../Reducer/Reducer_ternaryOperator_test.res | 5 +- .../ReducerInterface_Distribution_test.res | 20 +- .../ReducerProject_includes_test.res | 8 +- .../ReducerProject/ReducerProject_test.res | 3 +- .../benchmark/Benchmark_Array.res | 8 +- .../benchmark/Benchmark_Helpers.res | 14 +- .../squiggle-lang/benchmark/Benchmark_Map.res | 58 +++--- .../src/rescript/FR/FR_Builtin.res | 123 +++++++++++ .../Library => FR}/FR_Danger.res | 51 ++--- .../squiggle-lang/src/rescript/FR/FR_Date.res | 159 ++++++++++++++ .../Library => FR}/FR_Dict.res | 5 +- .../Library => FR}/FR_Dist.res | 0 .../Library => FR}/FR_Fn.res | 0 .../Library => FR}/FR_GenericDist.res | 55 +++-- .../Library => FR}/FR_List.res | 7 +- .../src/rescript/FR/FR_Mathjs.res | 70 +++++++ .../Library => FR}/FR_Number.res | 12 -- .../Library => FR}/FR_Pointset.res | 6 +- .../Library => FR}/FR_Sampleset.res | 7 +- .../Library => FR}/FR_Scoring.res | 0 .../Library => FR}/FR_Units.res | 17 +- .../rescript/ForTS/ForTS_ReducerProject.res | 3 +- .../FunctionRegistry_Core.res | 31 ++- .../FunctionRegistry_Helpers.res | 34 ++- .../FunctionRegistry/Library/FR_Builtin.res | 163 --------------- .../FunctionRegistry/Library/FR_Date.res | 155 -------------- .../FunctionRegistry/Library/FR_Mathjs.res | 38 ---- .../src/rescript/FunctionRegistry/README.md | 2 + .../src/rescript/Reducer/Reducer_Bindings.res | 89 ++++++++ .../Reducer_Bindings/Reducer_Bindings.res | 141 ------------- .../Reducer_Dispatch_BuiltIn.res | 148 ------------- .../Reducer_Expression/Reducer_Expression.res | 80 ++++--- .../Reducer_Expression_Lambda.res | 13 +- .../Reducer_Expression_T.res | 9 +- .../rescript/Reducer/Reducer_Namespace.res | 22 +- .../Reducer_Peggy_GeneratedParser.peggy | 4 +- .../rescript/Reducer/Reducer_Peggy/helpers.ts | 3 +- .../ReducerInterface_ExternalLibrary.res | 11 +- ...ducerInterface_InternalExpressionValue.res | 1 - .../ReducerInterface_StdLib.res | 71 +++---- .../ReducerProject/ReducerProject.res | 18 +- .../ReducerProject_ProjectItem.res | 10 +- .../SquiggleLibrary/SquiggleLibrary_Math.res | 4 +- 56 files changed, 810 insertions(+), 1260 deletions(-) create mode 100644 packages/squiggle-lang/src/rescript/FR/FR_Builtin.res rename packages/squiggle-lang/src/rescript/{FunctionRegistry/Library => FR}/FR_Danger.res (92%) create mode 100644 packages/squiggle-lang/src/rescript/FR/FR_Date.res rename packages/squiggle-lang/src/rescript/{FunctionRegistry/Library => FR}/FR_Dict.res (98%) rename packages/squiggle-lang/src/rescript/{FunctionRegistry/Library => FR}/FR_Dist.res (100%) rename packages/squiggle-lang/src/rescript/{FunctionRegistry/Library => FR}/FR_Fn.res (100%) rename packages/squiggle-lang/src/rescript/{FunctionRegistry/Library => FR}/FR_GenericDist.res (94%) rename packages/squiggle-lang/src/rescript/{FunctionRegistry/Library => FR}/FR_List.res (98%) create mode 100644 packages/squiggle-lang/src/rescript/FR/FR_Mathjs.res rename packages/squiggle-lang/src/rescript/{FunctionRegistry/Library => FR}/FR_Number.res (94%) rename packages/squiggle-lang/src/rescript/{FunctionRegistry/Library => FR}/FR_Pointset.res (96%) rename packages/squiggle-lang/src/rescript/{FunctionRegistry/Library => FR}/FR_Sampleset.res (98%) rename packages/squiggle-lang/src/rescript/{FunctionRegistry/Library => FR}/FR_Scoring.res (100%) rename packages/squiggle-lang/src/rescript/{FunctionRegistry/Library => FR}/FR_Units.res (72%) delete mode 100644 packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res delete mode 100644 packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Date.res delete mode 100644 packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Mathjs.res create mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings.res delete mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings/Reducer_Bindings.res delete mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Bindings/Reducer_Bindings_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Bindings/Reducer_Bindings_test.res index f43944d4..c386d343 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Bindings/Reducer_Bindings_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Bindings/Reducer_Bindings_test.res @@ -31,9 +31,7 @@ describe("Bindings", () => { describe("extend", () => { let value2 = Reducer_T.IEvNumber(5.) - let extendedBindings = bindings - ->Bindings.extend - ->Bindings.set("value", value2) + let extendedBindings = bindings->Bindings.extend->Bindings.set("value", value2) test("get on extended", () => { expect(extendedBindings->Bindings.get("value")) == Some(value2) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros_test.res index 7e667acd..71b9c86d 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros_test.res @@ -144,3 +144,4 @@ // let callLambdaExpression = eList(list{lambdaExpression, eNumber(1.)}) // testMacroEval([("y", IEvNumber(666.))], callLambdaExpression, "Ok(667)") // }) + diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Namespace_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Namespace_test.res index 64401e32..e745dc64 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Namespace_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Namespace_test.res @@ -35,13 +35,9 @@ describe("Namespace", () => { let x2 = makeValue(20.) let x3 = makeValue(30.) let x4 = makeValue(40.) - let ns1 = Namespace.make() - ->Namespace.set("x1", x1) - ->Namespace.set("x2", x2) - let ns2 = Namespace.make() - ->Namespace.set("x3", x3) - ->Namespace.set("x4", x4) - + let ns1 = Namespace.make()->Namespace.set("x1", x1)->Namespace.set("x2", x2) + let ns2 = Namespace.make()->Namespace.set("x3", x3)->Namespace.set("x4", x4) + let nsMerged = Namespace.mergeMany([ns, ns1, ns2]) test("merge many 1", () => { diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_Parse_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_Parse_test.res index 416e0178..6c60c187 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_Parse_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_Parse_test.res @@ -38,58 +38,22 @@ describe("Peggy parse", () => { testParse("1 * 2 / 3", "{(:divide (:multiply 1 2) 3)}") testParse("1 / 2 * 3", "{(:multiply (:divide 1 2) 3)}") testParse("1 / 2 / 3", "{(:divide (:divide 1 2) 3)}") - testParse( - "1 * 2 + 3 * 4", - "{(:add (:multiply 1 2) (:multiply 3 4))}", - ) - testParse( - "1 * 2 - 3 * 4", - "{(:subtract (:multiply 1 2) (:multiply 3 4))}", - ) - testParse( - "1 * 2 .+ 3 * 4", - "{(:dotAdd (:multiply 1 2) (:multiply 3 4))}", - ) - testParse( - "1 * 2 .- 3 * 4", - "{(:dotSubtract (:multiply 1 2) (:multiply 3 4))}", - ) - testParse( - "1 * 2 + 3 .* 4", - "{(:add (:multiply 1 2) (:dotMultiply 3 4))}", - ) - testParse( - "1 * 2 + 3 / 4", - "{(:add (:multiply 1 2) (:divide 3 4))}", - ) - testParse( - "1 * 2 + 3 ./ 4", - "{(:add (:multiply 1 2) (:dotDivide 3 4))}", - ) - testParse( - "1 * 2 - 3 .* 4", - "{(:subtract (:multiply 1 2) (:dotMultiply 3 4))}", - ) - testParse( - "1 * 2 - 3 / 4", - "{(:subtract (:multiply 1 2) (:divide 3 4))}", - ) - testParse( - "1 * 2 - 3 ./ 4", - "{(:subtract (:multiply 1 2) (:dotDivide 3 4))}", - ) - testParse( - "1 * 2 - 3 * 4^5", - "{(:subtract (:multiply 1 2) (:multiply 3 (:pow 4 5)))}", - ) + testParse("1 * 2 + 3 * 4", "{(:add (:multiply 1 2) (:multiply 3 4))}") + testParse("1 * 2 - 3 * 4", "{(:subtract (:multiply 1 2) (:multiply 3 4))}") + testParse("1 * 2 .+ 3 * 4", "{(:dotAdd (:multiply 1 2) (:multiply 3 4))}") + testParse("1 * 2 .- 3 * 4", "{(:dotSubtract (:multiply 1 2) (:multiply 3 4))}") + testParse("1 * 2 + 3 .* 4", "{(:add (:multiply 1 2) (:dotMultiply 3 4))}") + testParse("1 * 2 + 3 / 4", "{(:add (:multiply 1 2) (:divide 3 4))}") + testParse("1 * 2 + 3 ./ 4", "{(:add (:multiply 1 2) (:dotDivide 3 4))}") + testParse("1 * 2 - 3 .* 4", "{(:subtract (:multiply 1 2) (:dotMultiply 3 4))}") + testParse("1 * 2 - 3 / 4", "{(:subtract (:multiply 1 2) (:divide 3 4))}") + testParse("1 * 2 - 3 ./ 4", "{(:subtract (:multiply 1 2) (:dotDivide 3 4))}") + testParse("1 * 2 - 3 * 4^5", "{(:subtract (:multiply 1 2) (:multiply 3 (:pow 4 5)))}") testParse( "1 * 2 - 3 * 4^5^6", "{(:subtract (:multiply 1 2) (:multiply 3 (:pow (:pow 4 5) 6)))}", ) - testParse( - "1 * -a[-2]", - "{(:multiply 1 (:unaryMinus (:$_atIndex_$ :a (:unaryMinus 2))))}", - ) + testParse("1 * -a[-2]", "{(:multiply 1 (:unaryMinus (:$_atIndex_$ :a (:unaryMinus 2))))}") }) describe("multi-line", () => { @@ -111,25 +75,13 @@ describe("Peggy parse", () => { describe("arrays", () => { testParse("[]", "{[]}") testParse("[0, 1, 2]", "{[0; 1; 2]}") - testParse( - "['hello', 'world']", - "{['hello'; 'world']}", - ) - testParse( - "([0,1,2])[1]", - "{(:$_atIndex_$ [0; 1; 2] 1)}", - ) + testParse("['hello', 'world']", "{['hello'; 'world']}") + testParse("([0,1,2])[1]", "{(:$_atIndex_$ [0; 1; 2] 1)}") }) describe("records", () => { - testParse( - "{a: 1, b: 2}", - "{{'a': 1, 'b': 2}}", - ) - testParse( - "{1+0: 1, 2+0: 2}", - "{{(:add 1 0): 1, (:add 2 0): 2}}", - ) // key can be any expression + testParse("{a: 1, b: 2}", "{{'a': 1, 'b': 2}}") + testParse("{1+0: 1, 2+0: 2}", "{{(:add 1 0): 1, (:add 2 0): 2}}") // key can be any expression testParse("record.property", "{(:$_atIndex_$ :record 'property')}") }) @@ -137,10 +89,7 @@ describe("Peggy parse", () => { //function call, array and record access are post operators with higher priority than unary operators testParse("a==!b(1)", "{(:equal :a (:not (:b 1)))}") testParse("a==!b[1]", "{(:equal :a (:not (:$_atIndex_$ :b 1)))}") - testParse( - "a==!b.one", - "{(:equal :a (:not (:$_atIndex_$ :b 'one')))}", - ) + testParse("a==!b.one", "{(:equal :a (:not (:$_atIndex_$ :b 'one')))}") }) describe("comments", () => { @@ -167,14 +116,8 @@ describe("Peggy parse", () => { }) describe("if then else", () => { - testParse( - "if true then 2 else 3", - "{(::$$_ternary_$$ true {2} {3})}", - ) - testParse( - "if false then {2} else {3}", - "{(::$$_ternary_$$ false {2} {3})}", - ) + testParse("if true then 2 else 3", "{(::$$_ternary_$$ true {2} {3})}") + testParse("if false then {2} else {3}", "{(::$$_ternary_$$ false {2} {3})}") testParse( "if false then {2} else if false then {4} else {5}", "{(::$$_ternary_$$ false {2} (::$$_ternary_$$ false {4} {5}))}", @@ -189,51 +132,18 @@ describe("Peggy parse", () => { testParse("a && b || c && d", "{(:or (:and :a :b) (:and :c :d))}") testParse("a && !b || c", "{(:or (:and :a (:not :b)) :c)}") testParse("a && b==c || d", "{(:or (:and :a (:equal :b :c)) :d)}") - testParse( - "a && b!=c || d", - "{(:or (:and :a (:unequal :b :c)) :d)}", - ) - testParse( - "a && !(b==c) || d", - "{(:or (:and :a (:not (:equal :b :c))) :d)}", - ) - testParse( - "a && b>=c || d", - "{(:or (:and :a (:largerEq :b :c)) :d)}", - ) - testParse( - "a && !(b>=c) || d", - "{(:or (:and :a (:not (:largerEq :b :c))) :d)}", - ) - testParse( - "a && b<=c || d", - "{(:or (:and :a (:smallerEq :b :c)) :d)}", - ) + testParse("a && b!=c || d", "{(:or (:and :a (:unequal :b :c)) :d)}") + testParse("a && !(b==c) || d", "{(:or (:and :a (:not (:equal :b :c))) :d)}") + testParse("a && b>=c || d", "{(:or (:and :a (:largerEq :b :c)) :d)}") + testParse("a && !(b>=c) || d", "{(:or (:and :a (:not (:largerEq :b :c))) :d)}") + testParse("a && b<=c || d", "{(:or (:and :a (:smallerEq :b :c)) :d)}") testParse("a && b>c || d", "{(:or (:and :a (:larger :b :c)) :d)}") - testParse( - "a && b { describe("pipe", () => { testParse("1 -> add(2)", "{(:add 1 2)}") testParse("-1 -> add(2)", "{(:add (:unaryMinus 1) 2)}") - testParse( - "-a[1] -> add(2)", - "{(:add (:unaryMinus (:$_atIndex_$ :a 1)) 2)}", - ) + testParse("-a[1] -> add(2)", "{(:add (:unaryMinus (:$_atIndex_$ :a 1)) 2)}") testParse("-f(1) -> add(2)", "{(:add (:unaryMinus (:f 1)) 2)}") testParse("1 + 2 -> add(3)", "{(:add 1 (:add 2 3))}") testParse("1 -> add(2) * 3", "{(:multiply (:add 1 2) 3)}") testParse("1 -> subtract(2)", "{(:subtract 1 2)}") testParse("-1 -> subtract(2)", "{(:subtract (:unaryMinus 1) 2)}") - testParse( - "1 -> subtract(2) * 3", - "{(:multiply (:subtract 1 2) 3)}", - ) + testParse("1 -> subtract(2) * 3", "{(:multiply (:subtract 1 2) 3)}") }) describe("elixir pipe", () => { @@ -269,10 +173,7 @@ describe("Peggy parse", () => { describe("to", () => { testParse("1 to 2", "{(:credibleIntervalToDistribution 1 2)}") - testParse( - "-1 to -2", - "{(:credibleIntervalToDistribution (:unaryMinus 1) (:unaryMinus 2))}", - ) // lower than unary + testParse("-1 to -2", "{(:credibleIntervalToDistribution (:unaryMinus 1) (:unaryMinus 2))}") // lower than unary testParse( "a[1] to a[2]", "{(:credibleIntervalToDistribution (:$_atIndex_$ :a 1) (:$_atIndex_$ :a 2))}", @@ -281,10 +182,7 @@ describe("Peggy parse", () => { "a.p1 to a.p2", "{(:credibleIntervalToDistribution (:$_atIndex_$ :a 'p1') (:$_atIndex_$ :a 'p2'))}", ) // lower than post - testParse( - "1 to 2 + 3", - "{(:add (:credibleIntervalToDistribution 1 2) 3)}", - ) // higher than binary operators + testParse("1 to 2 + 3", "{(:add (:credibleIntervalToDistribution 1 2) 3)}") // higher than binary operators testParse( "1->add(2) to 3->add(4) -> add(4)", "{(:credibleIntervalToDistribution (:add 1 2) (:add (:add 3 4) 4))}", @@ -301,10 +199,7 @@ describe("Peggy parse", () => { testParse("{|x| x}", "{{|:x| :x}}") testParse("f={|x| x}", "{:f = {{|:x| :x}}}") testParse("f(x)=x", "{:f = {|:x| {:x}}}") // Function definitions are lambda assignments - testParse( - "f(x)=x ? 1 : 0", - "{:f = {|:x| {(::$$_ternary_$$ :x 1 0)}}}", - ) // Function definitions are lambda assignments + testParse("f(x)=x ? 1 : 0", "{:f = {|:x| {(::$$_ternary_$$ :x 1 0)}}}") // Function definitions are lambda assignments }) describe("Using lambda as value", () => { @@ -321,18 +216,9 @@ describe("Peggy parse", () => { "{:myaddd = {|:x,:y| {(:add :x :y)}}; :z = {{'x': :myaddd}}; :z}", ) testParse("f({|x| x+1})", "{(:f {|:x| (:add :x 1)})}") - testParse( - "map(arr, {|x| x+1})", - "{(:map :arr {|:x| (:add :x 1)})}", - ) - testParse( - "map([1,2,3], {|x| x+1})", - "{(:map [1; 2; 3] {|:x| (:add :x 1)})}", - ) - testParse( - "[1,2,3]->map({|x| x+1})", - "{(:map [1; 2; 3] {|:x| (:add :x 1)})}", - ) + testParse("map(arr, {|x| x+1})", "{(:map :arr {|:x| (:add :x 1)})}") + testParse("map([1,2,3], {|x| x+1})", "{(:map [1; 2; 3] {|:x| (:add :x 1)})}") + testParse("[1,2,3]->map({|x| x+1})", "{(:map [1; 2; 3] {|:x| (:add :x 1)})}") }) describe("unit", () => { testParse("1m", "{(:fromUnit_m 1)}") @@ -419,7 +305,7 @@ describe("parsing new line", () => { g=f+4 g `, - "{:f = {:x = {1}; :y = {2}; :z = {3}; (:add (:add :x :y) :z)}; :g = {(:add :f 4)}; :g}" + "{:f = {:x = {1}; :y = {2}; :z = {3}; (:add (:add :x :y) :z)}; :g = {(:add :f 4)}; :g}", ) testParse( ` @@ -441,7 +327,7 @@ describe("parsing new line", () => { p -> q `, - "{:f = {:x = {1}; :y = {2}; :z = {3}; (:add (:add :x :y) :z)}; :g = {(:add :f 4)}; (:q (:p (:h :g)))}" + "{:f = {:x = {1}; :y = {2}; :z = {3}; (:add (:add :x :y) :z)}; :g = {(:add :f 4)}; (:q (:p (:h :g)))}", ) testParse( ` @@ -460,6 +346,6 @@ describe("parsing new line", () => { d + e `, - "{(:add (:d (:c (:b :a))) :e)}" + "{(:add (:d (:c (:b :a))) :e)}", ) }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_outerBlock_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_outerBlock_test.res index bcc99bfb..03ef24c8 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_outerBlock_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_outerBlock_test.res @@ -4,20 +4,12 @@ module InternalExpressionValue = ReducerInterface_InternalExpressionValue open Jest open Reducer_Peggy_TestHelpers +// Note: these tests aren't useful anymore since outer block macro got deleted. +// Probably can be removed or folded into other Peggy tests. describe("Peggy Outer Block", () => { testToExpression("1", "1", ~v="1", ()) testToExpression("x=1", "x = {1}", ~v="()", ()) - testToExpression( - "x=1; y=2", - "x = {1}; y = {2}", - ~v="()", - (), - ) + testToExpression("x=1; y=2", "x = {1}; y = {2}", ~v="()", ()) testToExpression("x=1; 2", "x = {1}; 2", ~v="2", ()) - testToExpression( - "x={a=1; a}; x", - "x = {a = {1}; a}; x", - ~v="1", - (), - ) + testToExpression("x={a=1; a}; x", "x = {a = {1}; a}; x", ~v="1", ()) }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_test.res index d2e64393..3016e3c2 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_test.res @@ -25,11 +25,7 @@ describe("Peggy to Expression", () => { describe("multi-line", () => { testToExpression("x=1; 2", "x = {1}; 2", ~v="2", ()) - testToExpression( - "x=1; y=2", - "x = {1}; y = {2}", - (), - ) + testToExpression("x=1; y=2", "x = {1}; y = {2}", ()) }) describe("variables", () => { @@ -39,11 +35,7 @@ describe("Peggy to Expression", () => { }) describe("functions", () => { - testToExpression( - "identity(x) = x", - "identity = {|x| {x}}", - (), - ) // Function definitions become lambda assignments + testToExpression("identity(x) = x", "identity = {|x| {x}}", ()) // Function definitions become lambda assignments testToExpression("identity(x)", "(identity)(x)", ()) // Note value returns error properly testToExpression( "f(x) = x> 2 ? 0 : 1; f(3)", @@ -55,43 +47,15 @@ describe("Peggy to Expression", () => { describe("arrays", () => { testToExpression("[]", "[]", ~v="[]", ()) - testToExpression( - "[0, 1, 2]", - "[0, 1, 2]", - ~v="[0,1,2]", - (), - ) - testToExpression( - "['hello', 'world']", - "['hello', 'world']", - ~v="['hello','world']", - (), - ) - testToExpression( - "([0,1,2])[1]", - "($_atIndex_$)([0, 1, 2], 1)", - ~v="1", - (), - ) + testToExpression("[0, 1, 2]", "[0, 1, 2]", ~v="[0,1,2]", ()) + testToExpression("['hello', 'world']", "['hello', 'world']", ~v="['hello','world']", ()) + testToExpression("([0,1,2])[1]", "($_atIndex_$)([0, 1, 2], 1)", ~v="1", ()) }) describe("records", () => { - testToExpression( - "{a: 1, b: 2}", - "{'a': 1, 'b': 2}", - ~v="{a: 1,b: 2}", - (), - ) - testToExpression( - "{1+0: 1, 2+0: 2}", - "{(add)(1, 0): 1, (add)(2, 0): 2}", - (), - ) // key can be any expression - testToExpression( - "record.property", - "($_atIndex_$)(record, 'property')", - (), - ) + testToExpression("{a: 1, b: 2}", "{'a': 1, 'b': 2}", ~v="{a: 1,b: 2}", ()) + testToExpression("{1+0: 1, 2+0: 2}", "{(add)(1, 0): 1, (add)(2, 0): 2}", ()) // key can be any expression + testToExpression("record.property", "($_atIndex_$)(record, 'property')", ()) testToExpression( "record={property: 1}; record.property", "record = {{'property': 1}}; ($_atIndex_$)(record, 'property')", @@ -103,45 +67,15 @@ describe("Peggy to Expression", () => { describe("comments", () => { testToExpression("1 # This is a line comment", "1", ~v="1", ()) testToExpression("1 // This is a line comment", "1", ~v="1", ()) - testToExpression( - "1 /* This is a multi line comment */", - "1", - ~v="1", - (), - ) - testToExpression( - "/* This is a multi line comment */ 1", - "1", - ~v="1", - (), - ) + testToExpression("1 /* This is a multi line comment */", "1", ~v="1", ()) + testToExpression("/* This is a multi line comment */ 1", "1", ~v="1", ()) }) describe("ternary operator", () => { - testToExpression( - "true ? 1 : 0", - "true ? (1) : (0)", - ~v="1", - (), - ) - testToExpression( - "false ? 1 : 0", - "false ? (1) : (0)", - ~v="0", - (), - ) - testToExpression( - "true ? 1 : false ? 2 : 0", - "true ? (1) : (false ? (2) : (0))", - ~v="1", - (), - ) // nested ternary - testToExpression( - "false ? 1 : false ? 2 : 0", - "false ? (1) : (false ? (2) : (0))", - ~v="0", - (), - ) // nested ternary + testToExpression("true ? 1 : 0", "true ? (1) : (0)", ~v="1", ()) + testToExpression("false ? 1 : 0", "false ? (1) : (0)", ~v="0", ()) + testToExpression("true ? 1 : false ? 2 : 0", "true ? (1) : (false ? (2) : (0))", ~v="1", ()) // nested ternary + testToExpression("false ? 1 : false ? 2 : 0", "false ? (1) : (false ? (2) : (0))", ~v="0", ()) // nested ternary describe("ternary bindings", () => { testToExpression( // expression binding @@ -168,16 +102,8 @@ describe("Peggy to Expression", () => { }) describe("if then else", () => { - testToExpression( - "if true then 2 else 3", - "true ? ({2}) : ({3})", - (), - ) - testToExpression( - "if true then {2} else {3}", - "true ? ({2}) : ({3})", - (), - ) + testToExpression("if true then 2 else 3", "true ? ({2}) : ({3})", ()) + testToExpression("if true then {2} else {3}", "true ? ({2}) : ({3})", ()) testToExpression( "if false then {2} else if false then {4} else {5}", "false ? ({2}) : (false ? ({4}) : ({5}))", @@ -187,18 +113,8 @@ describe("Peggy to Expression", () => { describe("pipe", () => { testToExpression("1 -> add(2)", "(add)(1, 2)", ~v="3", ()) - testToExpression( - "-1 -> add(2)", - "(add)((unaryMinus)(1), 2)", - ~v="1", - (), - ) // note that unary has higher priority naturally - testToExpression( - "1 -> add(2) * 3", - "(multiply)((add)(1, 2), 3)", - ~v="9", - (), - ) + testToExpression("-1 -> add(2)", "(add)((unaryMinus)(1), 2)", ~v="1", ()) // note that unary has higher priority naturally + testToExpression("1 -> add(2) * 3", "(multiply)((add)(1, 2), 3)", ~v="9", ()) }) describe("elixir pipe", () => { @@ -219,27 +135,10 @@ describe("Peggy to Expression", () => { }) describe("lambda", () => { - testToExpression( - "{|x| x}", - "{|x| x}", - ~v="lambda(x=>internal code)", - (), - ) - testToExpression( - "f={|x| x}", - "f = {{|x| x}}", - (), - ) - testToExpression( - "f(x)=x", - "f = {|x| {x}}", - (), - ) // Function definitions are lambda assignments - testToExpression( - "f(x)=x ? 1 : 0", - "f = {|x| {x ? (1) : (0)}}", - (), - ) + testToExpression("{|x| x}", "{|x| x}", ~v="lambda(x=>internal code)", ()) + testToExpression("f={|x| x}", "f = {{|x| x}}", ()) + testToExpression("f(x)=x", "f = {|x| {x}}", ()) // Function definitions are lambda assignments + testToExpression("f(x)=x ? 1 : 0", "f = {|x| {x ? (1) : (0)}}", ()) }) describe("module", () => { diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res index a8c9717e..c69d060c 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res @@ -86,3 +86,4 @@ // expectedValue: string, // ) => testMacroEval_(Only.test, bindArray, expr, expectedValue) // } + diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_Compile_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_Compile_test.res index 7d3ab86b..8abf5f7a 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_Compile_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_Compile_test.res @@ -50,3 +50,4 @@ // "Ok({properties: {age: #number,name: #string},typeTag: 'typeRecord'})", // ) // myTypeTest(test, "{age: number, name: string}", "{age: number, name: string}") + diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res index be20c5fd..64f2554a 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res @@ -40,3 +40,4 @@ // test(aTypeSourceCode, () => myCheckArgumentsExpectEqual(aTypeSourceCode, sourceCode, answer)) // myCheckArgumentsTest(test, "number=>number=>number", "[1,2]", "Ok") + diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res index f935c7b0..c4272880 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res @@ -71,3 +71,4 @@ // myTypeCheckTest(test, "number<-min(10)", "0", "Expected type: number<-min(10) but got: 0") // myTypeCheckTest(test, "any", "0", "Ok") // myTypeCheckTest(test, "any", "'a'", "Ok") + diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_switch_replacement_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_switch_replacement_test.res index 27fe6fce..88f3d9a6 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_switch_replacement_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_switch_replacement_test.res @@ -124,3 +124,4 @@ // expect(result)->toEqual(Some(Ok(IEvString("helloworld")))) // }) // }) + diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res index 52f8329b..e48d1223 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res @@ -2,14 +2,8 @@ open Jest open Reducer_TestHelpers describe("Parse function assignment", () => { - testParseToBe( - "f(x)=x", - "Ok(f = {|x| {x}})" - ) - testParseToBe( - "f(x)=2*x", - "Ok(f = {|x| {(multiply)(2, x)}})" - ) + testParseToBe("f(x)=x", "Ok(f = {|x| {x}})") + testParseToBe("f(x)=2*x", "Ok(f = {|x| {(multiply)(2, x)}})") //MathJs does not allow blocks in function definitions }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res index 8045d0d2..14f7f380 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res @@ -46,10 +46,7 @@ describe("call and bindings", () => { testEvalToBe("f(x)=x+1; y=f(1); f(1)", "Ok(2)") testEvalToBe("f(x)=x+1; y=f(1); z=f(1); z", "Ok(2)") testEvalToBe("f(x)=x+1; g(x)=f(x)+1; g(0)", "Ok(2)") - testParseToBe( - "f=99; g(x)=f; g(2)", - "Ok(f = {99}; g = {|x| {f}}; (g)(2))", - ) + testParseToBe("f=99; g(x)=f; g(2)", "Ok(f = {99}; g = {|x| {f}}; (g)(2))") testEvalToBe("f=99; g(x)=f; g(2)", "Ok(99)") testEvalToBe("f(x)=x; g(x)=f(x); g(2)", "Ok(2)") testEvalToBe("f(x)=x+1; g(x)=f(x)+1; y=g(2); y", "Ok(4)") diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res index 3f66649b..e157ccbf 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res @@ -2,10 +2,7 @@ open Jest open Reducer_TestHelpers describe("Parse ternary operator", () => { - testParseToBe( - "true ? 'YES' : 'NO'", - "Ok(true ? ('YES') : ('NO'))", - ) + testParseToBe("true ? 'YES' : 'NO'", "Ok(true ? ('YES') : ('NO'))") }) describe("Evaluate ternary operator", () => { diff --git a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res index 21a0e9c3..78d3f900 100644 --- a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res +++ b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res @@ -119,10 +119,7 @@ describe("eval on distribution functions", () => { describe("parse on distribution functions", () => { describe("power", () => { - testParse( - "normal(5,2) ^ normal(5,1)", - "Ok((pow)((normal)(5, 2), (normal)(5, 1)))", - ) + testParse("normal(5,2) ^ normal(5,1)", "Ok((pow)((normal)(5, 2), (normal)(5, 1)))") testParse("3 ^ normal(5,1)", "Ok((pow)(3, (normal)(5, 1)))") testParse("normal(5,2) ^ 3", "Ok((pow)((normal)(5, 2), 3))") }) @@ -138,18 +135,9 @@ describe("parse on distribution functions", () => { "Ok((:$$_block_$$ (:dotSubtract (:normal 5 2) (:normal 5 1))))", // TODO: !!! returns "Ok({(:dotPow (:normal 5 2) (:normal 5 1))})" ) - testParse( - "normal(5,2) .* normal(5,1)", - "Ok((dotMultiply)((normal)(5, 2), (normal)(5, 1)))", - ) - testParse( - "normal(5,2) ./ normal(5,1)", - "Ok((dotDivide)((normal)(5, 2), (normal)(5, 1)))", - ) - testParse( - "normal(5,2) .^ normal(5,1)", - "Ok((dotPow)((normal)(5, 2), (normal)(5, 1)))", - ) + testParse("normal(5,2) .* normal(5,1)", "Ok((dotMultiply)((normal)(5, 2), (normal)(5, 1)))") + testParse("normal(5,2) ./ normal(5,1)", "Ok((dotDivide)((normal)(5, 2), (normal)(5, 1)))") + testParse("normal(5,2) .^ normal(5,1)", "Ok((dotPow)((normal)(5, 2), (normal)(5, 1)))") }) describe("equality", () => { testParse("5 == normal(5,2)", "Ok((equal)(5, (normal)(5, 2)))") diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res index 3097d74a..3d1fcddc 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res @@ -75,9 +75,7 @@ x=1`, }) test("include as variables", () => { - expect(project->Project.Private.getIncludesAsVariables("main")) == [ - ("myVariable", "myModule"), - ] + expect(project->Project.Private.getIncludesAsVariables("main")) == [("myVariable", "myModule")] }) }) @@ -110,8 +108,6 @@ x=1`, expect(Project.getPastChain(project, "main")) == ["common", "common2"] }) test("include as variables", () => { - expect(project->Project.Private.getIncludesAsVariables("main")) == [ - ("myVariable", "myModule"), - ] + expect(project->Project.Private.getIncludesAsVariables("main")) == [("myVariable", "myModule")] }) }) diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res index ccda4b4f..d85d636c 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res @@ -14,8 +14,7 @@ let runFetchResult = (project, sourceId) => { let runFetchFlatBindings = (project, sourceId) => { Project.run(project, sourceId) - Project.getBindings(project, sourceId) - ->InternalExpressionValue.toStringRecord + Project.getBindings(project, sourceId)->InternalExpressionValue.toStringRecord } test("test result true", () => { diff --git a/packages/squiggle-lang/benchmark/Benchmark_Array.res b/packages/squiggle-lang/benchmark/Benchmark_Array.res index 61562732..268fea01 100644 --- a/packages/squiggle-lang/benchmark/Benchmark_Array.res +++ b/packages/squiggle-lang/benchmark/Benchmark_Array.res @@ -24,7 +24,9 @@ module Map: Benchmark_Helpers.BenchmarkTopic = { } let runAll = () => { - Js.log(`Mapping identity function over arrays of size ${arraySize->Js.Int.toString} (${iterations->Js.Int.toString} iterations)`) + Js.log( + `Mapping identity function over arrays of size ${arraySize->Js.Int.toString} (${iterations->Js.Int.toString} iterations)`, + ) Benchmark_Helpers.measure("Belt.Array.map", beltArray) Benchmark_Helpers.measure("Js.Array2.map", jsArray2) Benchmark_Helpers.measure("Array.map", ocamlArray) @@ -65,7 +67,9 @@ module Sort: Benchmark_Helpers.BenchmarkTopic = { } let runAll = () => { - Js.log(`Sorting arrays of size ${arraySize->Js.Int.toString} (${iterations->Js.Int.toString} iterations)`) + Js.log( + `Sorting arrays of size ${arraySize->Js.Int.toString} (${iterations->Js.Int.toString} iterations)`, + ) Benchmark_Helpers.measure("Js.Array2.sort", jsArray2) Benchmark_Helpers.measure("Js.Array2.sort with Ocaml compare", jsArray2withOcamlCompare) Benchmark_Helpers.measure("Array.fast_sort", ocamlArray) diff --git a/packages/squiggle-lang/benchmark/Benchmark_Helpers.res b/packages/squiggle-lang/benchmark/Benchmark_Helpers.res index 0e889d15..e6365bea 100644 --- a/packages/squiggle-lang/benchmark/Benchmark_Helpers.res +++ b/packages/squiggle-lang/benchmark/Benchmark_Helpers.res @@ -1,11 +1,11 @@ module type BenchmarkTopic = { - let runAll: () => unit + let runAll: unit => unit } -let measure = (name: string, f: () => unit) => { - let start = Js.Date.make()->Js.Date.valueOf - f() - let end = Js.Date.make()->Js.Date.valueOf - let duration = (end -. start) /. 1000. - Js.log2(duration, name) +let measure = (name: string, f: unit => unit) => { + let start = Js.Date.make()->Js.Date.valueOf + f() + let end = Js.Date.make()->Js.Date.valueOf + let duration = (end -. start) /. 1000. + Js.log2(duration, name) } diff --git a/packages/squiggle-lang/benchmark/Benchmark_Map.res b/packages/squiggle-lang/benchmark/Benchmark_Map.res index d04d501d..ee9ae51b 100644 --- a/packages/squiggle-lang/benchmark/Benchmark_Map.res +++ b/packages/squiggle-lang/benchmark/Benchmark_Map.res @@ -2,63 +2,61 @@ module StringMap: Benchmark_Helpers.BenchmarkTopic = { let size = 1000 let iterations = 10_000 - let kv = Belt.Array.range(1, size)->Belt.Array.map( - v => ("key" ++ v->Belt.Int.toString, v) - ) + let kv = Belt.Array.range(1, size)->Belt.Array.map(v => ("key" ++ v->Belt.Int.toString, v)) let beltMap = () => { Belt.Range.forEach(1, iterations, _ => { - let m = Belt.Map.String.empty - let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => acc->Belt.Map.String.set(k, v)) + let m = Belt.Map.String.empty + let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => acc->Belt.Map.String.set(k, v)) }) } let beltMutableMap = () => { Belt.Range.forEach(1, iterations, _ => { - let m = Belt.MutableMap.String.make() - let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => { - acc->Belt.MutableMap.String.set(k, v) - acc - }) + let m = Belt.MutableMap.String.make() + let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => { + acc->Belt.MutableMap.String.set(k, v) + acc + }) }) } let beltHashMap = () => { Belt.Range.forEach(1, iterations, _ => { - let m = Belt.HashMap.String.make(~hintSize=100) - let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => { - acc->Belt.HashMap.String.set(k, v) - acc - }) + let m = Belt.HashMap.String.make(~hintSize=100) + let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => { + acc->Belt.HashMap.String.set(k, v) + acc + }) }) } let jsDict = () => { Belt.Range.forEach(1, iterations, _ => { - let m = Js.Dict.empty() - let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => { - acc->Js.Dict.set(k, v) - acc - }) + let m = Js.Dict.empty() + let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => { + acc->Js.Dict.set(k, v) + acc + }) }) } let jsMap = () => { Belt.Range.forEach(1, iterations, _ => { - let m = Js_map.make() - let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => - acc->Js_map.set(k, v) - ) + let m = Js_map.make() + let _ = Belt.Array.reduce(kv, m, (acc, (k, v)) => acc->Js_map.set(k, v)) }) } let runAll = () => { - Js.log(`Filling a map with ("key{i}" => "i") key-value pairs, size ${size->Js.Int.toString} (${iterations->Js.Int.toString} iterations)`) - Benchmark_Helpers.measure("Belt.Map.String", beltMap) - Benchmark_Helpers.measure("Belt.MutableMap.String", beltMutableMap) - Benchmark_Helpers.measure("Belt.HashMap.String", beltHashMap) - Benchmark_Helpers.measure("Js.Dict", jsDict) - Benchmark_Helpers.measure("Js.Map", jsMap) + Js.log( + `Filling a map with ("key{i}" => "i") key-value pairs, size ${size->Js.Int.toString} (${iterations->Js.Int.toString} iterations)`, + ) + Benchmark_Helpers.measure("Belt.Map.String", beltMap) + Benchmark_Helpers.measure("Belt.MutableMap.String", beltMutableMap) + Benchmark_Helpers.measure("Belt.HashMap.String", beltHashMap) + Benchmark_Helpers.measure("Js.Dict", jsDict) + Benchmark_Helpers.measure("Js.Map", jsMap) } } diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Builtin.res b/packages/squiggle-lang/src/rescript/FR/FR_Builtin.res new file mode 100644 index 00000000..7ab3b1a9 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/FR/FR_Builtin.res @@ -0,0 +1,123 @@ +open FunctionRegistry_Core +open FunctionRegistry_Helpers + +let nameSpace = "" // no namespaced versions + +type simpleDefinition = { + inputs: array, + fn: array => result, +} + +let makeFnMany = (name: string, definitions: array) => + Function.make( + ~name, + ~nameSpace, + ~requiresNamespace=false, + ~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: inputs, fn: fn}]) + +let makeFF2F = (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 makeFF2B = (name: string, fn: (float, float) => bool) => { + makeFn(name, [FRTypeNumber, FRTypeNumber], inputs => { + switch inputs { + | [IEvNumber(x), IEvNumber(y)] => fn(x, y)->IEvBool->Ok + | _ => Error(impossibleError) + } + }) +} + +let makeBB2B = (name: string, fn: (bool, bool) => bool) => { + makeFn(name, [FRTypeBool, FRTypeBool], inputs => { + switch inputs { + | [IEvBool(x), IEvBool(y)] => fn(x, y)->IEvBool->Ok + | _ => Error(impossibleError) + } + }) +} + +let library = [ + makeFF2F("add", (x, y) => x +. y), // infix + (see Reducer/Reducer_Peggy/helpers.ts) + makeFF2F("subtract", (x, y) => x -. y), // infix - + makeFF2F("multiply", (x, y) => x *. y), // infix * + makeFF2F("divide", (x, y) => x /. y), // infix / + makeFF2F("pow", (x, y) => Js.Math.pow_float(~base=x, ~exp=y)), // infix ^ + makeFF2B("equal", (x, y) => x == y), // infix == + makeFF2B("smaller", (x, y) => x < y), // infix < + makeFF2B("smallerEq", (x, y) => x <= y), // infix <= + makeFF2B("larger", (x, y) => x > y), // infix > + makeFF2B("largerEq", (x, y) => x >= y), // infix >= + makeBB2B("or", (x, y) => x || y), // infix || + makeBB2B("and", (x, y) => x && y), // infix && + makeFn("unaryMinus", [FRTypeNumber], inputs => { // unary prefix - + switch inputs { + | [IEvNumber(x)] => IEvNumber(-.x)->Ok + | _ => Error(impossibleError) + } + }), + makeFn("not", [FRTypeNumber], inputs => { // unary prefix ! + switch inputs { + | [IEvNumber(x)] => IEvBool(x != 0.)->Ok + | _ => Error(impossibleError) + } + }), + makeFn("not", [FRTypeBool], inputs => { // unary prefix ! + switch inputs { + | [IEvBool(x)] => IEvBool(!x)->Ok + | _ => Error(impossibleError) + } + }), + makeFn("concat", [FRTypeString, FRTypeString], inputs => { + switch inputs { + | [IEvString(a), IEvString(b)] => { + let answer = Js.String2.concat(a, b) + answer->Reducer_T.IEvString->Ok + } + | _ => Error(impossibleError) + } + }), + makeFn("concat", [FRTypeArray(FRTypeAny), FRTypeArray(FRTypeAny)], inputs => { + switch inputs { + | [IEvArray(originalA), IEvArray(b)] => { + let a = originalA->Js.Array2.copy + let _ = Js.Array2.pushMany(a, b) + a->Reducer_T.IEvArray->Ok + } + | _ => Error(impossibleError) + } + }), + makeFn("inspect", [FRTypeAny], inputs => { + switch inputs { + | [value] => { + Js.log(value->ReducerInterface_InternalExpressionValue.toString) + value->Ok + } + | _ => Error(impossibleError) + } + }), + makeFn("inspect", [FRTypeAny, FRTypeString], inputs => { + switch inputs { + | [value, IEvString(label)] => { + Js.log(`${label}: ${value->ReducerInterface_InternalExpressionValue.toString}`) + value->Ok + } + | _ => Error(impossibleError) + } + }), +] diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Danger.res b/packages/squiggle-lang/src/rescript/FR/FR_Danger.res similarity index 92% rename from packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Danger.res rename to packages/squiggle-lang/src/rescript/FR/FR_Danger.res index 71624f60..f457a8f7 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Danger.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Danger.res @@ -8,11 +8,11 @@ let requiresNamespace = true module Combinatorics = { module Helpers = { - let laplace = ((successes, trials)) => (successes +. 1.0) /. (trials +. 2.0) + let laplace = (successes, trials) => (successes +. 1.0) /. (trials +. 2.0) let factorial = Stdlib.Math.factorial - let choose = ((n, k)) => factorial(n) /. (factorial(n -. k) *. factorial(k)) + let choose = (n, k) => factorial(n) /. (factorial(n -. k) *. factorial(k)) let pow = (base, exp) => Js.Math.pow_float(~base, ~exp) - let binomial = ((n, k, p)) => choose((n, k)) *. pow(p, k) *. pow(1.0 -. p, n -. k) + let binomial = (n, k, p) => choose(n, k) *. pow(p, k) *. pow(1.0 -. p, n -. k) } module Lib = { let laplace = Function.make( @@ -77,8 +77,7 @@ module Integration = { | 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" - ->Reducer_ErrorValue.REOther + "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 @@ -142,11 +141,11 @@ module Integration = { resultWithOuterPoints } | Error(b) => - ( - "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->Reducer_ErrorValue.errorToString - )->Reducer_ErrorValue.REOther->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->Reducer_ErrorValue.errorToString) + ->Reducer_ErrorValue.REOther + ->Error } result } @@ -169,7 +168,9 @@ module Integration = { ~run=(inputs, _, env, reducer) => { let result = switch inputs { | [_, _, _, IEvNumber(0.0)] => - "Integration error 4 in Danger.integrate: Increment can't be 0."->Reducer_ErrorValue.REOther->Error + "Integration error 4 in Danger.integrate: Increment can't be 0." + ->Reducer_ErrorValue.REOther + ->Error | [ IEvLambda(aLambda), IEvNumber(min), @@ -186,7 +187,9 @@ module Integration = { ) | _ => Error( - Reducer_ErrorValue.REOther("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 @@ -221,8 +224,8 @@ module Integration = { env, reducer, )->E.R2.errMap(b => - ("Integration error 7 in Danger.integrate. Something went wrong along the way: " ++ b->Reducer_ErrorValue.errorToString) - ->Reducer_ErrorValue.REOther + ("Integration error 7 in Danger.integrate. Something went wrong along the way: " ++ + b->Reducer_ErrorValue.errorToString)->Reducer_ErrorValue.REOther ) | _ => "Integration error 8 in Danger.integrate. Remember that inputs are (function, number (min), number (max), number(increment))" @@ -287,23 +290,19 @@ module DiminishingReturns = { ) { | (false, _, _, _) => Error( - "Error in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions, number of functions should be greater than 1." - ->Reducer_ErrorValue.REOther + "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." - ->Reducer_ErrorValue.REOther + "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." - ->Reducer_ErrorValue.REOther + "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." - ->Reducer_ErrorValue.REOther + "Error in Danger.optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions, approximateIncrement should be smaller than funds amount."->Reducer_ErrorValue.REOther, ) | (true, true, true, true) => { let applyFunctionAtPoint = (lambda, point: float) => { @@ -319,8 +318,7 @@ module DiminishingReturns = { | 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" - ->Reducer_ErrorValue.REOther + "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, ) } } @@ -433,7 +431,10 @@ module DiminishingReturns = { } result } - | _ => "Error in Danger.diminishingMarginalReturnsForTwoFunctions"->Reducer_ErrorValue.REOther->Error + | _ => + "Error in Danger.diminishingMarginalReturnsForTwoFunctions" + ->Reducer_ErrorValue.REOther + ->Error }, (), ), diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Date.res b/packages/squiggle-lang/src/rescript/FR/FR_Date.res new file mode 100644 index 00000000..96f94b9d --- /dev/null +++ b/packages/squiggle-lang/src/rescript/FR/FR_Date.res @@ -0,0 +1,159 @@ +open FunctionRegistry_Core +open FunctionRegistry_Helpers + +let makeFn = ( + name: string, + inputs: array, + fn: array => result, +) => + Function.make( + ~name, + ~nameSpace="", + ~requiresNamespace=false, + ~definitions=[FnDefinition.make(~name, ~inputs, ~run=(inputs, _, _, _) => fn(inputs), ())], + (), + ) + +let makeNumberToDurationFn = (name: string, fn: float => DateTime.Duration.t) => + Function.make( + ~name, + ~nameSpace="", + ~requiresNamespace=false, + ~definitions=[ + FnDefinition.make( + ~name, + ~inputs=[FRTypeNumber], + ~run=(inputs, _, _, _) => + switch inputs { + | [IEvNumber(t)] => IEvTimeDuration(fn(t))->Ok + | _ => Error(impossibleError) + }, + (), + ), + ], + (), + ) + +let makeDurationToNumberFn = (name: string, fn: DateTime.Duration.t => float) => + Function.make( + ~name, + ~nameSpace="", + ~requiresNamespace=false, + ~definitions=[ + FnDefinition.make( + ~name, + ~inputs=[FRTypeTimeDuration], + ~run=(inputs, _, _, _) => + switch inputs { + | [IEvTimeDuration(t)] => IEvNumber(fn(t))->Ok + | _ => Error(impossibleError) + }, + (), + ), + ], + (), + ) + +let library = [ + makeFn("toString", [FRTypeDate], inputs => + switch inputs { + | [IEvDate(t)] => IEvString(DateTime.Date.toString(t))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("makeDateFromYear", [FRTypeNumber], inputs => + switch inputs { + | [IEvNumber(year)] => + switch DateTime.Date.makeFromYear(year) { + | Ok(t) => IEvDate(t)->Ok + | Error(e) => Reducer_ErrorValue.RETodo(e)->Error + } + | _ => Error(impossibleError) + } + ), + makeFn("dateFromNumber", [FRTypeNumber], inputs => + switch inputs { + | [IEvNumber(f)] => IEvDate(DateTime.Date.fromFloat(f))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("toNumber", [FRTypeDate], inputs => + switch inputs { + | [IEvDate(f)] => IEvNumber(DateTime.Date.toFloat(f))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("subtract", [FRTypeDate, FRTypeDate], inputs => + switch inputs { + | [IEvDate(d1), IEvDate(d2)] => + switch DateTime.Date.subtract(d1, d2) { + | Ok(d) => IEvTimeDuration(d)->Ok + | Error(e) => Error(RETodo(e)) + } + | _ => Error(impossibleError) + } + ), + makeFn("subtract", [FRTypeDate, FRTypeTimeDuration], inputs => + switch inputs { + | [IEvDate(d1), IEvTimeDuration(d2)] => IEvDate(DateTime.Date.subtractDuration(d1, d2))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("add", [FRTypeDate, FRTypeTimeDuration], inputs => + switch inputs { + | [IEvDate(d1), IEvTimeDuration(d2)] => IEvDate(DateTime.Date.addDuration(d1, d2))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("toString", [FRTypeTimeDuration], inputs => + switch inputs { + | [IEvTimeDuration(t)] => IEvString(DateTime.Duration.toString(t))->Ok + | _ => Error(impossibleError) + } + ), + makeNumberToDurationFn("minutes", DateTime.Duration.fromMinutes), + makeNumberToDurationFn("fromUnit_minutes", DateTime.Duration.fromMinutes), + makeNumberToDurationFn("hours", DateTime.Duration.fromHours), + makeNumberToDurationFn("fromUnit_hours", DateTime.Duration.fromHours), + makeNumberToDurationFn("days", DateTime.Duration.fromDays), + makeNumberToDurationFn("fromUnit_days", DateTime.Duration.fromDays), + makeNumberToDurationFn("years", DateTime.Duration.fromYears), + makeNumberToDurationFn("fromUnit_years", DateTime.Duration.fromYears), + makeDurationToNumberFn("toMinutes", DateTime.Duration.toMinutes), + makeDurationToNumberFn("toHours", DateTime.Duration.toHours), + makeDurationToNumberFn("toDays", DateTime.Duration.toDays), + makeDurationToNumberFn("toYears", DateTime.Duration.toYears), + makeFn("add", [FRTypeTimeDuration, FRTypeTimeDuration], inputs => + switch inputs { + | [IEvTimeDuration(d1), IEvTimeDuration(d2)] => + IEvTimeDuration(DateTime.Duration.add(d1, d2))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("subtract", [FRTypeTimeDuration, FRTypeTimeDuration], inputs => + switch inputs { + | [IEvTimeDuration(d1), IEvTimeDuration(d2)] => + IEvTimeDuration(DateTime.Duration.subtract(d1, d2))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("multiply", [FRTypeTimeDuration, FRTypeNumber], inputs => + switch inputs { + | [IEvTimeDuration(d1), IEvNumber(d2)] => + IEvTimeDuration(DateTime.Duration.multiply(d1, d2))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("divide", [FRTypeTimeDuration, FRTypeNumber], inputs => + switch inputs { + | [IEvTimeDuration(d1), IEvNumber(d2)] => IEvTimeDuration(DateTime.Duration.divide(d1, d2))->Ok + | _ => Error(impossibleError) + } + ), + makeFn("divide", [FRTypeTimeDuration, FRTypeTimeDuration], inputs => + switch inputs { + | [IEvTimeDuration(d1), IEvTimeDuration(d2)] => IEvNumber(d1 /. d2)->Ok + | _ => Error(impossibleError) + } + ), +] diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res b/packages/squiggle-lang/src/rescript/FR/FR_Dict.res similarity index 98% rename from packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res rename to packages/squiggle-lang/src/rescript/FR/FR_Dict.res index f1cd86f3..310d295d 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dict.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Dict.res @@ -17,7 +17,10 @@ module Internals = { ->E.A2.fmap(((key, value)) => Wrappers.evArray([IEvString(key), value])) ->Wrappers.evArray - let fromList = (items: array): result => + let fromList = (items: array): result< + internalExpressionValue, + errorValue, + > => items ->E.A2.fmap(item => { switch (item: internalExpressionValue) { diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dist.res b/packages/squiggle-lang/src/rescript/FR/FR_Dist.res similarity index 100% rename from packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Dist.res rename to packages/squiggle-lang/src/rescript/FR/FR_Dist.res diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Fn.res b/packages/squiggle-lang/src/rescript/FR/FR_Fn.res similarity index 100% rename from packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Fn.res rename to packages/squiggle-lang/src/rescript/FR/FR_Fn.res diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_GenericDist.res b/packages/squiggle-lang/src/rescript/FR/FR_GenericDist.res similarity index 94% rename from packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_GenericDist.res rename to packages/squiggle-lang/src/rescript/FR/FR_GenericDist.res index 5b7d5dca..dc449ee4 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_GenericDist.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_GenericDist.res @@ -315,10 +315,11 @@ module Old = { 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 + | Some(o) => genericOutputToReducerValue(o) + | None => + Reducer_ErrorValue.REOther("Internal error in FR_GenericDist implementation") + ->Reducer_ErrorValue.ErrorException + ->raise } } @@ -340,24 +341,32 @@ let makeProxyFn = (name: string, inputs: array) => { } 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], - ] + 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 + 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]), @@ -394,14 +403,14 @@ let library = E.A.concatMany([ makeProxyFn("log10", [FRTypeDist]), makeProxyFn("unaryMinus", [FRTypeDist]), makeProxyFn("dotExp", [FRTypeDist]), - ], - makeOperationFns() + ], + 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 - } + 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/FR/FR_List.res similarity index 98% rename from packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res rename to packages/squiggle-lang/src/rescript/FR/FR_List.res index da9228ca..eb6a653a 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_List.res @@ -66,12 +66,7 @@ module Internals = { reducer: Reducer_T.reducerFn, ) => { Js.Array2.filter(aValueArray, elem => { - let result = Reducer_Expression_Lambda.doLambdaCall( - aLambdaValue, - [elem], - env, - reducer, - ) + let result = Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, [elem], env, reducer) switch result { | IEvBool(true) => true | _ => false diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Mathjs.res b/packages/squiggle-lang/src/rescript/FR/FR_Mathjs.res new file mode 100644 index 00000000..9bffde42 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/FR/FR_Mathjs.res @@ -0,0 +1,70 @@ +open FunctionRegistry_Core +open FunctionRegistry_Helpers + +// FIXME - copy-pasted (see FR_Date.res and others) +let makeFn = ( + name: string, + inputs: array, + fn: array => result, +) => + Function.make( + ~name, + ~nameSpace="", + ~requiresNamespace=false, + ~definitions=[FnDefinition.make(~name, ~inputs, ~run=(inputs, _, _, _) => fn(inputs), ())], + (), + ) + +@module("mathjs") external dummy_: string => unit = "evaluate" +let dummy1_ = dummy_ //Deceive the compiler to make the import although we wont make a call from rescript. Otherwise the optimizer deletes the import + +let mathjsCall1: (string, float) => 'a = %raw(`function (name, arg) { return Mathjs[name](arg); }`) +let mathjsCall2: (string, float, float) => 'a = %raw(`function (name, arg1, arg2) { return Mathjs[name](arg1, arg2); }`) + +let makeMathjsFn1 = ( + name: string +) => { + makeFn(name, [FRTypeNumber], inputs => { + switch inputs { + | [IEvNumber(x)] => mathjsCall1(name, x)->Reducer_Js_Gate.jsToIEv + | _ => Error(impossibleError) + } + }) +} + +let makeMathjsFn2 = ( + name: string +) => { + makeFn(name, [FRTypeNumber, FRTypeNumber], inputs => { + switch inputs { + | [IEvNumber(x), IEvNumber(y)] => mathjsCall2(name, x, y)->Reducer_Js_Gate.jsToIEv + | _ => Error(impossibleError) + } + }) +} + +let library = [ + // TODO - other MathJS + // https://mathjs.org/docs/reference/functions.html + + // Arithmetic functions + makeMathjsFn1("abs"), + makeMathjsFn1("cbrt"), + makeMathjsFn1("ceil"), + makeMathjsFn1("cube"), + makeMathjsFn1("exp"), + makeMathjsFn1("fix"), + makeMathjsFn1("floor"), + + makeMathjsFn2("gcd"), + makeMathjsFn2("hypot"), + makeMathjsFn2("invmod"), + makeMathjsFn2("lcm"), + makeMathjsFn1("log"), // Do we need makeMathjsFn2 for `log` too? + makeMathjsFn1("log10"), + makeMathjsFn1("log2"), + + makeMathjsFn1("factorial"), + makeMathjsFn1("cos"), + +] diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Number.res b/packages/squiggle-lang/src/rescript/FR/FR_Number.res similarity index 94% rename from packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Number.res rename to packages/squiggle-lang/src/rescript/FR/FR_Number.res index 90707891..bd05164c 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Number.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Number.res @@ -17,18 +17,6 @@ module ArrayNumberDist = { (), ) } - let make2 = (name, fn) => { - FnDefinition.make( - ~name, - ~inputs=[FRTypeArray(FRTypeAny)], - ~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.R2.errMap(wrapError), - (), - ) - } } let library = [ diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res b/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res similarity index 96% rename from packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res rename to packages/squiggle-lang/src/rescript/FR/FR_Pointset.res index 324843d7..61d03c9d 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res @@ -111,8 +111,7 @@ let library = [ ~name="makeContinuous", ~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))], ~run=(_, inputs, _, _) => - inputsTodist(inputs, r => Continuous(Continuous.make(r))) - ->E.R2.errMap(wrapError), + inputsTodist(inputs, r => Continuous(Continuous.make(r)))->E.R2.errMap(wrapError), (), ), ], @@ -136,8 +135,7 @@ let library = [ ~name="makeDiscrete", ~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))], ~run=(_, inputs, _, _) => - inputsTodist(inputs, r => Discrete(Discrete.make(r))) - ->E.R2.errMap(wrapError), + 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/FR/FR_Sampleset.res similarity index 98% rename from packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res rename to packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res index b27b423e..4c04489b 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res @@ -120,7 +120,8 @@ 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) + sampleSet + ->E.R2.fmap(Wrappers.sampleSet) ->E.R2.fmap(Wrappers.evDistribution) ->E.R2.errMap(wrapError) }, @@ -291,7 +292,9 @@ module Comparison = { let wrapper = r => r ->E.R2.fmap(r => r->Wrappers.sampleSet->Wrappers.evDistribution) - ->E.R2.errMap(e => e->DistributionTypes.Error.sampleErrorToDistErr->Reducer_ErrorValue.REDistributionError) + ->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/FR/FR_Scoring.res similarity index 100% rename from packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Scoring.res rename to packages/squiggle-lang/src/rescript/FR/FR_Scoring.res diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Units.res b/packages/squiggle-lang/src/rescript/FR/FR_Units.res similarity index 72% rename from packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Units.res rename to packages/squiggle-lang/src/rescript/FR/FR_Units.res index 90ea56bc..3935b197 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Units.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Units.res @@ -22,14 +22,13 @@ let makeUnitFn = (name: string, multiplier: float) => { ) } - 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), + 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/ForTS/ForTS_ReducerProject.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res index dabd72a5..ac9c167c 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res @@ -212,8 +212,7 @@ let setEnvironment = (project: reducerProject, environment: environment): unit = project->Private.setEnvironment(environment) @genType -let getEnvironment = (project: reducerProject): environment => - project->Private.getEnvironment +let getEnvironment = (project: reducerProject): environment => project->Private.getEnvironment /* Foreign function interface is intentionally demolished. diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res index 714456a8..a5685f2e 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res @@ -225,9 +225,9 @@ module FnDefinition = { } let make = (~name, ~inputs, ~run, ()): t => { - name, - inputs, - run, + name: name, + inputs: inputs, + run: run, } } @@ -253,14 +253,14 @@ module Function = { ~isExperimental=false, (), ): t => { - name, - nameSpace, - definitions, - output, + name: name, + nameSpace: nameSpace, + definitions: definitions, + output: output, examples: examples |> E.O.default([]), - isExperimental, - requiresNamespace, - description, + isExperimental: isExperimental, + requiresNamespace: requiresNamespace, + description: description, } let toJson = (t: t): functionJson => { @@ -288,12 +288,8 @@ module Registry = { // 1. functions // 2. definitions of each function // 3. name variations of each definition - r->Belt.Array.reduce( - Belt.Map.String.empty, - (acc, fn) => - fn.definitions->Belt.Array.reduce( - acc, - (acc, def) => { + r->Belt.Array.reduce(Belt.Map.String.empty, (acc, fn) => + fn.definitions->Belt.Array.reduce(acc, (acc, def) => { let names = [ fn.nameSpace == "" ? [] : [`${fn.nameSpace}.${def.name}`], @@ -338,8 +334,7 @@ module Registry = { let match = definitions->Js.Array2.find(def => def->FnDefinition.isMatch(args)) switch match { - | Some(def) => - def->FnDefinition.run(args, env, reducer) + | Some(def) => def->FnDefinition.run(args, env, reducer) | None => REOther(showNameMatchDefinitions())->Error } } diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res index 6a3931af..cf24bfc4 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res @@ -225,13 +225,11 @@ module DefineFn = { FnDefinition.make( ~name, ~inputs=[FRTypeNumber], - ~run=(_, inputs, _, _) => { - inputs - ->getOrError(0) - ->E.R.bind(Prepare.oneNumber) - ->E.R2.fmap(fn) - ->E.R2.fmap(Wrappers.evNumber) - ->E.R2.errMap(e => Reducer_ErrorValue.REOther(e)) + ~run=(inputs, _, _, _) => { + switch inputs { + | [IEvNumber(x)] => fn(x)->IEvNumber->Ok + | _ => Error(impossibleError) + } }, (), ) @@ -239,12 +237,11 @@ module DefineFn = { FnDefinition.make( ~name, ~inputs=[FRTypeNumber, FRTypeNumber], - ~run=(_, inputs, _, _) => { - inputs - ->Prepare.ToValueTuple.twoNumbers - ->E.R2.fmap(fn) - ->E.R2.fmap(Wrappers.evNumber) - ->E.R2.errMap(e => Reducer_ErrorValue.REOther(e)) + ~run=(inputs, _, _, _) => { + switch inputs { + | [IEvNumber(x), IEvNumber(y)] => fn(x, y)->IEvNumber->Ok + | _ => Error(impossibleError) + } }, (), ) @@ -252,12 +249,11 @@ module DefineFn = { FnDefinition.make( ~name, ~inputs=[FRTypeNumber, FRTypeNumber, FRTypeNumber], - ~run=(_, inputs, _, _) => { - inputs - ->Prepare.ToValueTuple.threeNumbers - ->E.R2.fmap(fn) - ->E.R2.fmap(Wrappers.evNumber) - ->E.R2.errMap(e => Reducer_ErrorValue.REOther(e)) + ~run=(inputs, _, _, _) => { + switch inputs { + | [IEvNumber(x), IEvNumber(y), IEvNumber(z)] => fn(x, y, z)->IEvNumber->Ok + | _ => Error(impossibleError) + } }, (), ) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res deleted file mode 100644 index b3103add..00000000 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Builtin.res +++ /dev/null @@ -1,163 +0,0 @@ -open FunctionRegistry_Core -open FunctionRegistry_Helpers - -let nameSpace = "" // no namespaced versions - -type simpleDefinition = { - inputs: array, - fn: array => result, -} - -let makeFnMany = (name: string, definitions: array) => - Function.make( - ~name, - ~nameSpace, - ~requiresNamespace=false, - ~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 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 makeBinaryCmpFn = (name: string, fn: (float, float) => bool) => { - makeFn( - name, - [FRTypeNumber, FRTypeNumber], - inputs => { - switch inputs { - | [IEvNumber(x), IEvNumber(y)] => fn(x, y)->IEvBool->Ok - | _ => Error(impossibleError) - } - } - ) -} - -let makeBinaryBooleanFn = (name: string, fn: (bool, bool) => bool) => { - makeFn( - name, - [FRTypeBool, FRTypeBool], - inputs => { - switch inputs { - | [IEvBool(x), IEvBool(y)] => fn(x, y)->IEvBool->Ok - | _ => Error(impossibleError) - } - } - ) -} - -let library = [ - makeBinaryFn("add", (x, y) => x +. y), - makeBinaryFn("subtract", (x, y) => x -. y), - makeBinaryFn("multiply", (x, y) => x *. y), - makeBinaryFn("divide", (x, y) => x /. y), - makeBinaryFn("pow", (x, y) => Js.Math.pow_float(~base=x, ~exp=y)), - makeBinaryCmpFn("equal", (x, y) => x == y), - makeBinaryCmpFn("smaller", (x, y) => x < y), - makeBinaryCmpFn("smallerEq", (x, y) => x <= y), - makeBinaryCmpFn("larger", (x, y) => x > y), - makeBinaryCmpFn("largerEq", (x, y) => x >= y), - makeBinaryBooleanFn("or", (x, y) => x || y), - makeBinaryBooleanFn("and", (x, y) => x && y), - makeFn( - "unaryMinus", - [FRTypeNumber], - inputs => { - switch inputs { - | [IEvNumber(x)] => IEvNumber(-.x)->Ok - | _ => Error(impossibleError) - } - } - ), - makeFn( - "not", - [FRTypeNumber], - inputs => { - switch inputs { - | [IEvNumber(x)] => IEvBool(x != 0.)->Ok - | _ => Error(impossibleError) - } - } - ), - makeFn( - "not", - [FRTypeBool], - inputs => { - switch inputs { - | [IEvBool(x)] => IEvBool(!x)->Ok - | _ => Error(impossibleError) - } - } - ), - makeFn( - "concat", - [FRTypeString, FRTypeString], - inputs => { - switch inputs { - | [IEvString(a), IEvString(b)] => { - let answer = Js.String2.concat(a, b) - answer->Reducer_T.IEvString->Ok - } - | _ => Error(impossibleError) - } - } - ), - makeFn( - "concat", - [FRTypeArray(FRTypeAny), FRTypeArray(FRTypeAny)], - inputs => { - switch inputs { - | [IEvArray(originalA), IEvArray(b)] => { - let a = originalA->Js.Array2.copy - let _ = Js.Array2.pushMany(a, b) - a->Reducer_T.IEvArray->Ok - } - | _ => Error(impossibleError) - } - } - ), - makeFn( - "inspect", - [FRTypeAny], - inputs => { - switch inputs { - | [value] => { - Js.log(value->ReducerInterface_InternalExpressionValue.toString) - value->Ok - } - | _ => Error(impossibleError) - } - } - ), - makeFn( - "inspect", - [FRTypeAny, FRTypeString], - inputs => { - switch inputs { - | [value, IEvString(label)] => { - Js.log(`${label}: ${value->ReducerInterface_InternalExpressionValue.toString}`) - value->Ok - } - | _ => Error(impossibleError) - } - } - ), -] diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Date.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Date.res deleted file mode 100644 index 0e79d8cd..00000000 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Date.res +++ /dev/null @@ -1,155 +0,0 @@ -open FunctionRegistry_Core -open FunctionRegistry_Helpers - -let makeFn = ( - name: string, - inputs: array, - fn: array => result -) => - Function.make( - ~name, - ~nameSpace="", - ~requiresNamespace=false, - ~definitions=[ - FnDefinition.make(~name, ~inputs, ~run=(inputs, _, _, _) => fn(inputs), ()) - ], - () - ) - -let makeNumberToDurationFn = ( - name: string, - fn: float => DateTime.Duration.t, -) => - Function.make( - ~name, - ~nameSpace="", - ~requiresNamespace=false, - ~definitions=[ - FnDefinition.make(~name, ~inputs=[FRTypeNumber], ~run=(inputs, _, _, _) => - switch inputs { - | [IEvNumber(t)] => IEvTimeDuration(fn(t))->Ok - | _ => Error(impossibleError) - }, ()) - ], - () - ) - -let makeDurationToNumberFn = ( - name: string, - fn: DateTime.Duration.t => float, -) => - Function.make( - ~name, - ~nameSpace="", - ~requiresNamespace=false, - ~definitions=[ - FnDefinition.make(~name, ~inputs=[FRTypeTimeDuration], ~run=(inputs, _, _, _) => - switch inputs { - | [IEvTimeDuration(t)] => IEvNumber(fn(t))->Ok - | _ => Error(impossibleError) - }, ()) - ], - () - ) - -let library = [ - makeFn("toString", [FRTypeDate], (inputs) => - switch inputs { - | [IEvDate(t)] => IEvString(DateTime.Date.toString(t))->Ok - | _ => Error(impossibleError) - } - ), - makeFn("makeDateFromYear", [FRTypeNumber], (inputs) => - switch inputs { - | [IEvNumber(year)] => - switch DateTime.Date.makeFromYear(year) { - | Ok(t) => IEvDate(t)->Ok - | Error(e) => Reducer_ErrorValue.RETodo(e)->Error - } - | _ => Error(impossibleError) - } - ), - makeFn("dateFromNumber", [FRTypeNumber], (inputs) => - switch inputs { - | [IEvNumber(f)] => IEvDate(DateTime.Date.fromFloat(f))->Ok - | _ => Error(impossibleError) - } - ), - makeFn("toNumber", [FRTypeDate], (inputs) => - switch inputs { - | [IEvDate(f)] => IEvNumber(DateTime.Date.toFloat(f))->Ok - | _ => Error(impossibleError) - } - ), - makeFn("subtract", [FRTypeDate, FRTypeDate], (inputs) => - switch inputs { - | [IEvDate(d1), IEvDate(d2)] => switch DateTime.Date.subtract(d1, d2) { - | Ok(d) => IEvTimeDuration(d)->Ok - | Error(e) => Error(RETodo(e)) - } - | _ => Error(impossibleError) - } - ), - makeFn("subtract", [FRTypeDate, FRTypeTimeDuration], (inputs) => - switch inputs { - | [IEvDate(d1), IEvTimeDuration(d2)] => - IEvDate(DateTime.Date.subtractDuration(d1, d2))->Ok - | _ => Error(impossibleError) - } - ), - makeFn("add", [FRTypeDate, FRTypeTimeDuration], (inputs) => - switch inputs { - | [IEvDate(d1), IEvTimeDuration(d2)] => - IEvDate(DateTime.Date.addDuration(d1, d2))->Ok - | _ => Error(impossibleError) - } - ), - makeFn("toString", [FRTypeTimeDuration], (inputs) => - switch inputs { - | [IEvTimeDuration(t)] => IEvString(DateTime.Duration.toString(t))->Ok - | _ => Error(impossibleError) - } - ), - makeNumberToDurationFn("minutes", DateTime.Duration.fromMinutes), - makeNumberToDurationFn("fromUnit_minutes", DateTime.Duration.fromMinutes), - makeNumberToDurationFn("hours", DateTime.Duration.fromHours), - makeNumberToDurationFn("fromUnit_hours", DateTime.Duration.fromHours), - makeNumberToDurationFn("days", DateTime.Duration.fromDays), - makeNumberToDurationFn("fromUnit_days", DateTime.Duration.fromDays), - makeNumberToDurationFn("years", DateTime.Duration.fromYears), - makeNumberToDurationFn("fromUnit_years", DateTime.Duration.fromYears), - makeDurationToNumberFn("toMinutes", DateTime.Duration.toMinutes), - makeDurationToNumberFn("toHours", DateTime.Duration.toHours), - makeDurationToNumberFn("toDays", DateTime.Duration.toDays), - makeDurationToNumberFn("toYears", DateTime.Duration.toYears), - makeFn("add", [FRTypeTimeDuration, FRTypeTimeDuration], (inputs) => - switch inputs { - | [IEvTimeDuration(d1), IEvTimeDuration(d2)] => IEvTimeDuration(DateTime.Duration.add(d1, d2))->Ok - | _ => Error(impossibleError) - } - ), - makeFn("subtract", [FRTypeTimeDuration, FRTypeTimeDuration], (inputs) => - switch inputs { - | [IEvTimeDuration(d1), IEvTimeDuration(d2)] => IEvTimeDuration(DateTime.Duration.subtract(d1, d2))->Ok - | _ => Error(impossibleError) - } - ), - makeFn("multiply", [FRTypeTimeDuration, FRTypeNumber], (inputs) => - switch inputs { - | [IEvTimeDuration(d1), IEvNumber(d2)] => IEvTimeDuration(DateTime.Duration.multiply(d1, d2))->Ok - | _ => Error(impossibleError) - } - ), - makeFn("divide", [FRTypeTimeDuration, FRTypeNumber], (inputs) => - switch inputs { - | [IEvTimeDuration(d1), IEvNumber(d2)] => IEvTimeDuration(DateTime.Duration.divide(d1, d2))->Ok - | _ => Error(impossibleError) - } - ), - makeFn("divide", [FRTypeTimeDuration, FRTypeTimeDuration], (inputs) => - switch inputs { - | [IEvTimeDuration(d1), IEvTimeDuration(d2)] => IEvNumber(d1 /. d2)->Ok - | _ => Error(impossibleError) - } - ), -] diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Mathjs.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Mathjs.res deleted file mode 100644 index c1141545..00000000 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Mathjs.res +++ /dev/null @@ -1,38 +0,0 @@ -open FunctionRegistry_Core -open FunctionRegistry_Helpers - -// FIXME - copy-pasted (see FR_Date.res and others) -let makeFn = ( - name: string, - inputs: array, - fn: array => result -) => - Function.make( - ~name, - ~nameSpace="", - ~requiresNamespace=false, - ~definitions=[ - FnDefinition.make(~name, ~inputs, ~run=(inputs, _, _, _) => fn(inputs), ()) - ], - () - ) - -@module("mathjs") external dummy_: string => unit = "evaluate" -let dummy1_ = dummy_ //Deceive the compiler to make the import although we wont make a call from rescript. Otherwise the optimizer deletes the import - -let mathjsFactorial: float => 'a = %raw(`function (expr) { return Mathjs.factorial(expr); }`) - -let library = [ - // TODO - other MathJS - // https://mathjs.org/docs/reference/functions.html - makeFn( - "factorial", - [FRTypeNumber], - inputs => { - switch inputs { - | [IEvNumber(x)] => mathjsFactorial(x)->Reducer_Js_Gate.jsToIEv - | _ => Error(impossibleError) - } - } - ), -] diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/README.md b/packages/squiggle-lang/src/rescript/FunctionRegistry/README.md index e974b189..cf22d878 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/README.md +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/README.md @@ -42,5 +42,7 @@ Key types, internal functionality, and a `Registry` module with a `matchAndRun` **FunctionRegistry_Library** A list of all the Functions defined in the Function Registry. +The definition arrays are stored in `FR_*` modules, by convention. + **FunctionRegistry_Helpers** A list of helper functions for the FunctionRegistry_Library. diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings.res new file mode 100644 index 00000000..4ca31638 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings.res @@ -0,0 +1,89 @@ +/* + Bindings describe the entire set of bound variables accessible to the squiggle code. + Bindings objects are stored as linked lists of scopes: + { localX: ..., localY: ... } <- { globalZ: ..., ... } <- { importedT: ..., ... } <- { stdlibFunction: ..., ... } +*/ + +type t = Reducer_T.bindings +type internalExpressionValue = Reducer_T.value + +let rec get = ({namespace, parent}: t, id: string) => { + switch namespace->Reducer_Namespace.get(id) { + | Some(v) => Some(v) + | None => + switch parent { + | Some(p) => p->get(id) + | None => None + } + } +} + +let set = ({namespace} as bindings: t, id: string, value): t => { + { + ...bindings, + namespace: namespace->Reducer_Namespace.set(id, value), + } +} + +let rec toString = ({namespace, parent}: t) => { + let pairs = namespace->Reducer_Namespace.toString + + switch parent { + | Some(p) => `{${pairs}} / ${toString(p)}` + | None => `{${pairs}}` + } +} + +let extend = (bindings: t): t => {namespace: Reducer_Namespace.make(), parent: bindings->Some} + +let make = (): t => {namespace: Reducer_Namespace.make(), parent: None} + +let removeResult = ({namespace} as bindings: t): t => { + ...bindings, + namespace: namespace->Belt.Map.String.remove("__result__"), +} + +let locals = ({namespace}: t): Reducer_T.namespace => namespace + +let fromNamespace = (namespace: Reducer_Namespace.t): t => {namespace: namespace, parent: None} + +// let typeAliasesKey = "_typeAliases_" +// let typeReferencesKey = "_typeReferences_" + +// let getType = (NameSpace(container): t, id: string) => { +// Belt.Map.String.get(container, typeAliasesKey)->Belt.Option.flatMap(aliases => +// switch aliases { +// | IEvRecord(r) => Belt.Map.String.get(r, id) +// | _ => None +// } +// ) +// } + +// let getTypeOf = (NameSpace(container): t, id: string) => { +// Belt.Map.String.get(container, typeReferencesKey)->Belt.Option.flatMap(defs => +// switch defs { +// | IEvRecord(r) => Belt.Map.String.get(r, id) +// | _ => None +// } +// ) +// } + +// let setTypeAlias = (NameSpace(container): t, id: string, value): t => { +// let rValue = Belt.Map.String.getWithDefault(container, typeAliasesKey, IEvRecord(emptyMap)) +// let r = switch rValue { +// | IEvRecord(r) => r +// | _ => emptyMap +// } +// let r2 = Belt.Map.String.set(r, id, value)->IEvRecord +// NameSpace(Belt.Map.String.set(container, typeAliasesKey, r2)) +// } + +// let setTypeOf = (NameSpace(container): t, id: string, value): t => { +// let rValue = Belt.Map.String.getWithDefault(container, typeReferencesKey, IEvRecord(emptyMap)) +// let r = switch rValue { +// | IEvRecord(r) => r +// | _ => emptyMap +// } +// let r2 = Belt.Map.String.set(r, id, value)->IEvRecord +// NameSpace(Belt.Map.String.set(container, typeReferencesKey, r2)) +// } 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 deleted file mode 100644 index c00dbe5c..00000000 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings/Reducer_Bindings.res +++ /dev/null @@ -1,141 +0,0 @@ -// Only Bindings as the global module is supported -// Other module operations such as import export will be preprocessed jobs - -module ExpressionT = Reducer_Expression_T -module T = Reducer_T - -type t = Reducer_T.bindings -type internalExpressionValue = Reducer_T.value - -let rec get = ({ namespace, parent }: t, id: string) => { - switch namespace->Reducer_Namespace.get(id) { - | Some(v) => Some(v) - | None => - switch parent { - | Some(p) => get(p, id) - | None => None - } - } -} - -let set = ({ namespace } as bindings: t, id: string, value): t => { - { - ...bindings, - namespace: namespace->Reducer_Namespace.set(id, value), - } -} - -let rec toString = ({ namespace, parent }: t) => { - let pairs = namespace->Reducer_Namespace.toString - - switch parent { - | Some(p) => `{${pairs}} / ${toString(p)}` - | None => `{${pairs}}` - } -} - -let extend = (bindings: t): t => { namespace: Reducer_Namespace.make(), parent: bindings->Some } - -let make = (): t => { namespace: Reducer_Namespace.make(), parent: None } - -let removeResult = ({ namespace } as bindings: t): t => { - ...bindings, - namespace: namespace->Belt.Map.String.remove("__result__"), -} - -let locals = ({ namespace }: t): Reducer_T.namespace => namespace - -let fromNamespace = (namespace: Reducer_Namespace.t): t => { namespace, parent: None } - -// let typeAliasesKey = "_typeAliases_" -// let typeReferencesKey = "_typeReferences_" - -// let getType = (NameSpace(container): t, id: string) => { -// Belt.Map.String.get(container, typeAliasesKey)->Belt.Option.flatMap(aliases => -// switch aliases { -// | IEvRecord(r) => Belt.Map.String.get(r, id) -// | _ => None -// } -// ) -// } - -// let getTypeOf = (NameSpace(container): t, id: string) => { -// Belt.Map.String.get(container, typeReferencesKey)->Belt.Option.flatMap(defs => -// switch defs { -// | IEvRecord(r) => Belt.Map.String.get(r, id) -// | _ => None -// } -// ) -// } - -// let setTypeAlias = (NameSpace(container): t, id: string, value): t => { -// let rValue = Belt.Map.String.getWithDefault(container, typeAliasesKey, IEvRecord(emptyMap)) -// let r = switch rValue { -// | IEvRecord(r) => r -// | _ => emptyMap -// } -// let r2 = Belt.Map.String.set(r, id, value)->IEvRecord -// NameSpace(Belt.Map.String.set(container, typeAliasesKey, r2)) -// } - -// let setTypeOf = (NameSpace(container): t, id: string, value): t => { -// let rValue = Belt.Map.String.getWithDefault(container, typeReferencesKey, IEvRecord(emptyMap)) -// let r = switch rValue { -// | IEvRecord(r) => r -// | _ => emptyMap -// } -// let r2 = Belt.Map.String.set(r, id, value)->IEvRecord -// NameSpace(Belt.Map.String.set(container, typeReferencesKey, r2)) -// } - -// let functionNotFoundError = (call: functionCall) => -// REFunctionNotFound(call->functionCallToCallSignature->functionCallSignatureToString)->Error - -// let functionNotFoundErrorFFIFn = (functionName: string): ExpressionT.ffiFn => { -// (args: array, _environment: environment): result< -// internalExpressionValue, -// errorValue, -// > => { -// let call = (functionName, args) -// functionNotFoundError(call) -// } -// } - -// let convertOptionToFfiFnReturningResult = ( -// myFunctionName: string, -// myFunction: ExpressionT.optionFfiFnReturningResult, -// ): ExpressionT.ffiFn => { -// (args: array, environment) => { -// myFunction(args, environment)->Belt.Option.getWithDefault( -// functionNotFoundErrorFFIFn(myFunctionName)(args, environment), -// ) -// } -// } - -// let convertOptionToFfiFn = ( -// myFunctionName: string, -// myFunction: ExpressionT.optionFfiFn, -// ): ExpressionT.ffiFn => { -// (args: array, environment) => { -// myFunction(args, environment) -// ->Belt.Option.map(v => v->Ok) -// ->Belt.Option.getWithDefault(functionNotFoundErrorFFIFn(myFunctionName)(args, environment)) -// } -// } - -// -- Module definition -// let define = (NameSpace(container): t, identifier: string, ev: internalExpressionValue): t => { -// NameSpace(Belt.Map.String.set(container, identifier, ev)) -// } - -// let defineNumber = (nameSpace: t, identifier: string, value: float): t => -// nameSpace->define(identifier, IEvNumber(value)) - -// let defineString = (nameSpace: t, identifier: string, value: string): t => -// nameSpace->define(identifier, IEvString(value)) - -// let defineBool = (nameSpace: t, identifier: string, value: bool): t => -// nameSpace->define(identifier, IEvBool(value)) - -// let defineModule = (nameSpace: t, identifier: string, value: t): t => -// nameSpace->define(identifier, toExpressionValue(value)) 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 deleted file mode 100644 index 1ef4a543..00000000 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ /dev/null @@ -1,148 +0,0 @@ -module Bindings = Reducer_Bindings -// module Continuation = ReducerInterface_Value_Continuation -module ExpressionT = Reducer_Expression_T -module ExternalLibrary = ReducerInterface.ExternalLibrary -module InternalExpressionValue = ReducerInterface_InternalExpressionValue -module Lambda = Reducer_Expression_Lambda -module MathJs = Reducer_MathJs -module Result = Belt.Result -module TypeBuilder = Reducer_Type_TypeBuilder - -module IEV = ReducerInterface_InternalExpressionValue - -open Reducer_ErrorValue - -/* - MathJs provides default implementations for built-ins - This is where all the expected built-ins like + = * / sin cos log ln etc are handled - DO NOT try to add external function mapping here! -*/ - -//TODO: pow to xor - -exception TestRescriptException - -let callInternal = ( - call: IEV.functionCall, - _: Reducer_T.environment, - _: Reducer_T.reducerFn, -): result<'b, errorValue> => { - let callMathJs = (call: IEV.functionCall): result<'b, errorValue> => - switch call { - | ("javascriptraise", [msg]) => Js.Exn.raiseError(IEV.toString(msg)) // For Tests - | ("rescriptraise", _) => raise(TestRescriptException) // For Tests - | call => call->IEV.toStringFunctionCall->MathJs.Eval.eval - } - - // let doAddArray = (originalA, b) => { - // let a = originalA->Js.Array2.copy - // let _ = Js.Array2.pushMany(a, b) - // a->Reducer_T.IEvArray->Ok - // } - // let doAddString = (a, b) => { - // let answer = Js.String2.concat(a, b) - // answer->Reducer_T.IEvString->Ok - // } - - let inspect = (value: Reducer_T.value) => { - Js.log(value->IEV.toString) - value->Ok - } - - let inspectLabel = (value: Reducer_T.value, label: string) => { - Js.log(`${label}: ${value->IEV.toString}`) - value->Ok - } - - // let doSetTypeAliasBindings = ( - // bindings: nameSpace, - // symbol: string, - // value: internalExpressionValue, - // ) => Bindings.setTypeAlias(bindings, symbol, value)->IEvBindings->Ok - - // let doSetTypeOfBindings = (bindings: nameSpace, symbol: string, value: internalExpressionValue) => - // Bindings.setTypeOf(bindings, symbol, value)->IEvBindings->Ok - - // let doExportBindings = (bindings: nameSpace) => bindings->Bindings.toExpressionValue->Ok - - // let doIdentity = (value: Reducer_T.value) => value->Ok - - // let doDumpBindings = (continuation: Reducer_T.nameSpace, value: Reducer_T.value) => { - // // let _ = Continuation.inspect(continuation, "doDumpBindings") - // accessors.states.continuation = continuation->Bindings.set("__result__", value) - // value->Ok - // } - - switch call { - // | ("$_atIndex_$", [IEvArray(aValueArray), IEvNumber(fIndex)]) => arrayAtIndex(aValueArray, fIndex) - // | ("$_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) - // | ("$_exportBindings_$", [IEvBindings(nameSpace)]) => doExportBindings(nameSpace) - // | ("$_exportBindings_$", [evValue]) => doIdentity(evValue) - // | ("$_setBindings_$", [IEvBindings(nameSpace), IEvSymbol(symbol), value]) => - // doSetBindings(nameSpace, symbol, value) - // | ("$_setTypeAliasBindings_$", [IEvBindings(nameSpace), IEvTypeIdentifier(symbol), value]) => - // doSetTypeAliasBindings(nameSpace, symbol, value) - // | ("$_setTypeOfBindings_$", [IEvBindings(nameSpace), IEvSymbol(symbol), value]) => - // doSetTypeOfBindings(nameSpace, symbol, value) - // | ("$_dumpBindings_$", [IEvBindings(nameSpace), _, evValue]) => doDumpBindings(nameSpace, evValue) - // | ("$_typeModifier_memberOf_$", [IEvTypeIdentifier(typeIdentifier), IEvArray(arr)]) => - // TypeBuilder.typeModifier_memberOf(IEvTypeIdentifier(typeIdentifier), IEvArray(arr)) - // | ("$_typeModifier_memberOf_$", [IEvType(typeRecord), IEvArray(arr)]) => - // TypeBuilder.typeModifier_memberOf_update(typeRecord, IEvArray(arr)) - // | ("$_typeModifier_min_$", [IEvTypeIdentifier(typeIdentifier), value]) => - // TypeBuilder.typeModifier_min(IEvTypeIdentifier(typeIdentifier), value) - // | ("$_typeModifier_min_$", [IEvType(typeRecord), value]) => - // TypeBuilder.typeModifier_min_update(typeRecord, value) - // | ("$_typeModifier_max_$", [IEvTypeIdentifier(typeIdentifier), value]) => - // TypeBuilder.typeModifier_max(IEvTypeIdentifier(typeIdentifier), value) - // | ("$_typeModifier_max_$", [IEvType(typeRecord), value]) => - // TypeBuilder.typeModifier_max_update(typeRecord, value) - // | ("$_typeModifier_opaque_$", [IEvType(typeRecord)]) => - // TypeBuilder.typeModifier_opaque_update(typeRecord) - // | ("$_typeOr_$", [IEvArray(arr)]) => TypeBuilder.typeOr(IEvArray(arr)) - // | ("$_typeFunction_$", [IEvArray(arr)]) => TypeBuilder.typeFunction(arr) - // | ("$_typeTuple_$", [IEvArray(elems)]) => TypeBuilder.typeTuple(elems) - // | ("$_typeArray_$", [elem]) => TypeBuilder.typeArray(elem) - // | ("$_typeRecord_$", [IEvRecord(propertyMap)]) => TypeBuilder.typeRecord(propertyMap) - // | ("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) - | call => - Error( - REFunctionNotFound(call->IEV.functionCallToCallSignature->IEV.functionCallSignatureToString), - ) // Report full type signature as error - } -} -/* - Reducer uses Result monad while reducing expressions -*/ -let dispatch = ( - call: IEV.functionCall, - env: Reducer_T.environment, - reducer: Reducer_T.reducerFn, -): Reducer_T.value => - try { - let (fn, args) = call - - // There is a bug that prevents string match in patterns - // So we have to recreate a copy of the string - switch ExternalLibrary.dispatch((Js.String.make(fn), args), env, reducer, callInternal) { - | Ok(v) => v - | Error(e) => raise(ErrorException(e)) - } - } catch { - | exn => Reducer_ErrorValue.fromException(exn)->Reducer_ErrorValue.toException - } 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 1136990b..1bcdc030 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 @@ -13,47 +13,51 @@ let rec evaluate: T.reducerFn = (expression, context): (T.value, T.context) => { switch expression { | T.EBlock(statements) => { let innerContext = {...context, bindings: context.bindings->Bindings.extend} - let (value, _) = statements->Belt.Array.reduce( - (T.IEvVoid, innerContext), - ((_, currentContext), statement) => statement->evaluate(currentContext) - ) - (value, context) // inner context can be dropped + let (value, _) = + statements->Belt.Array.reduce((T.IEvVoid, innerContext), ((_, currentContext), statement) => + statement->evaluate(currentContext) + ) + (value, context) } | T.EProgram(statements) => { // Js.log(`bindings: ${context.bindings->Bindings.locals->Reducer_Namespace.toString}`) - let (value, finalContext) = statements->Belt.Array.reduce( - (T.IEvVoid, context), - ((_, currentContext), statement) => statement->evaluate(currentContext)) + let (value, finalContext) = + statements->Belt.Array.reduce((T.IEvVoid, context), ((_, currentContext), statement) => + statement->evaluate(currentContext) + ) // Js.log(`bindings after: ${finalContext.bindings->Bindings.locals->Reducer_Namespace.toString}`) (value, finalContext) } | T.EArray(elements) => { - let value = elements->Belt.Array.map(element => { - let (value, _) = evaluate(element, context) - value - })->T.IEvArray - (value, context) - } + let value = + elements + ->Belt.Array.map(element => { + let (value, _) = evaluate(element, context) + value + }) + ->T.IEvArray + (value, context) + } | T.ERecord(pairs) => { - let value = - pairs - ->Belt.Array.map(((eKey, eValue)) => { - let (key, _) = eKey->evaluate(context) - let keyString = switch key { - | IEvString(s) => s - | _ => REOther("Record keys must be strings")->Reducer_ErrorValue.ErrorException->raise - } - let (value, _) = eValue->evaluate(context) - (keyString, value) - }) - ->Belt.Map.String.fromArray - ->T.IEvRecord - (value, context) - } + let value = + pairs + ->Belt.Array.map(((eKey, eValue)) => { + let (key, _) = eKey->evaluate(context) + let keyString = switch key { + | IEvString(s) => s + | _ => REOther("Record keys must be strings")->Reducer_ErrorValue.ErrorException->raise + } + let (value, _) = eValue->evaluate(context) + (keyString, value) + }) + ->Belt.Map.String.fromArray + ->T.IEvRecord + (value, context) + } | T.EAssign(left, right) => { let (result, _) = right->evaluate(context) @@ -62,7 +66,7 @@ let rec evaluate: T.reducerFn = (expression, context): (T.value, T.context) => { { ...context, bindings: context.bindings->Bindings.set(left, result), - } + }, ) } @@ -82,8 +86,10 @@ let rec evaluate: T.reducerFn = (expression, context): (T.value, T.context) => { } } - | T.ELambda(parameters, body) => - (Lambda.makeLambda(parameters, context.bindings, body)->T.IEvLambda, context) + | T.ELambda(parameters, body) => ( + Lambda.makeLambda(parameters, context.bindings, body)->T.IEvLambda, + context, + ) | T.ECall(fn, args) => { let (lambda, _) = fn->evaluate(context) @@ -92,8 +98,14 @@ let rec evaluate: T.reducerFn = (expression, context): (T.value, T.context) => { argValue }) switch lambda { - | T.IEvLambda(lambda) => (Lambda.doLambdaCall(lambda, argValues, context.environment, evaluate), context) - | _ => RENotAFunction(lambda->ReducerInterface_InternalExpressionValue.toString)->Reducer_ErrorValue.ErrorException->raise + | T.IEvLambda(lambda) => ( + Lambda.doLambdaCall(lambda, argValues, context.environment, evaluate), + context, + ) + | _ => + RENotAFunction(lambda->ReducerInterface_InternalExpressionValue.toString) + ->Reducer_ErrorValue.ErrorException + ->raise } } } 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 f6cc4ffa..bb4e80c5 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 @@ -34,13 +34,18 @@ let makeLambda = ( } let localBindings = bindings->Reducer_Bindings.extend - let localBindingsWithParameters = parameters->Belt.Array.reduceWithIndex( - localBindings, - (currentBindings, parameter, index) => { + let localBindingsWithParameters = parameters->Belt.Array.reduceWithIndex(localBindings, ( + currentBindings, + parameter, + index, + ) => { currentBindings->Reducer_Bindings.set(parameter, arguments[index]) }) - let (value, _) = reducer(body, {bindings: localBindingsWithParameters, environment: environment}) + let (value, _) = reducer( + body, + {bindings: localBindingsWithParameters, environment: environment}, + ) value } 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 1aa64246..365d0836 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 @@ -7,17 +7,20 @@ module InternalExpressionValue = ReducerInterface_InternalExpressionValue type t = Reducer_T.expression let commaJoin = values => values->Reducer_Extra_Array.intersperse(", ")->Js.String.concatMany("") -let semicolonJoin = values => values->Reducer_Extra_Array.intersperse("; ")->Js.String.concatMany("") +let semicolonJoin = values => + values->Reducer_Extra_Array.intersperse("; ")->Js.String.concatMany("") /* Converts the expression to String */ let rec toString = (expression: t) => switch expression { - | EBlock(statements) => `{${Js.Array2.map(statements, aValue => toString(aValue))->semicolonJoin}}` + | EBlock(statements) => + `{${Js.Array2.map(statements, aValue => toString(aValue))->semicolonJoin}}` | EProgram(statements) => Js.Array2.map(statements, aValue => toString(aValue))->semicolonJoin | EArray(aList) => `[${Js.Array2.map(aList, aValue => toString(aValue))->commaJoin}]` - | ERecord(map) => `{${map->Belt.Array.map(((key, value)) => `${key->toString}: ${value->toString}`)->commaJoin}}` + | ERecord(map) => + `{${map->Belt.Array.map(((key, value)) => `${key->toString}: ${value->toString}`)->commaJoin}}` | ESymbol(name) => name | ETernary(predicate, trueCase, falseCase) => `${predicate->toString} ? (${trueCase->toString}) : (${falseCase->toString})` diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res index 638bdbcd..5793fe07 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res @@ -1,9 +1,12 @@ +/* + Namespace is a flat mapping of names to Squiggle values. + The full context of variables accessible to Squiggle is called "bindings"; see Reducer_Bindings module for details on it. +*/ type t = Reducer_T.namespace let make = (): t => Belt.Map.String.empty -let get = (namespace: t, id: string): option => - namespace->Belt.Map.String.get(id) +let get = (namespace: t, id: string): option => namespace->Belt.Map.String.get(id) let set = (namespace: t, id: string, value): t => { namespace->Belt.Map.String.set(id, value) @@ -16,19 +19,18 @@ let mergeFrom = (from: t, to: t): t => { } let mergeMany = (namespaces: array): t => - Belt.Array.reduce(namespaces, make(), (acc, ns) => acc->mergeFrom(ns)) + Belt.Array.reduce(namespaces, make(), (acc, ns) => acc->mergeFrom(ns)) let toString = (namespace: t) => namespace ->Belt.Map.String.toArray - ->Belt.Array.map(((eachKey, eachValue)) => `${eachKey}: ${eachValue->ReducerInterface_InternalExpressionValue.toString}`) + ->Belt.Array.map(((eachKey, eachValue)) => + `${eachKey}: ${eachValue->ReducerInterface_InternalExpressionValue.toString}` + ) ->Js.Array2.toString -let fromArray = (a): t => - Belt.Map.String.fromArray(a) +let fromArray = (a): t => Belt.Map.String.fromArray(a) -let toMap = (namespace: t): Reducer_T.map => - namespace +let toMap = (namespace: t): Reducer_T.map => namespace -let toRecord = (namespace: t): Reducer_T.value => - namespace->toMap->IEvRecord +let toRecord = (namespace: t): Reducer_T.value => namespace->toMap->IEvRecord diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy index 469fcba1..3bf11162 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy @@ -11,7 +11,7 @@ zeroOMoreArgumentsBlockOrExpression = innerBlockOrExpression / lambda outerBlock = statements:array_statements finalExpression: (statementSeparator @expression)? - { if (finalExpression) statements.push(finalExpression) + { if (finalExpression) statements.push(finalExpression) return h.nodeProgram(statements) } / finalExpression: expression { return h.nodeProgram([finalExpression]) } @@ -23,7 +23,7 @@ innerBlockOrExpression quotedInnerBlock = '{' _nl statements:array_statements finalExpression: (statementSeparator @expression) _nl '}' - { if (finalExpression) statements.push(finalExpression) + { if (finalExpression) statements.push(finalExpression) return h.nodeBlock(statements) } / '{' _nl finalExpression: expression _nl '}' { return h.nodeBlock([finalExpression]) } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts index 4dd66205..f24fd819 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/helpers.ts @@ -1,8 +1,8 @@ import { LocationRange } from "peggy"; export const toFunction = { + "+": "add", "-": "subtract", - "->": "pipe", "!=": "unequal", ".-": "dotSubtract", ".*": "dotMultiply", @@ -13,7 +13,6 @@ export const toFunction = { "/": "divide", "&&": "and", "^": "pow", // or xor - "+": "add", "<": "smaller", "<=": "smallerEq", "==": "equal", diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res index 4ce11eea..0922c8a7 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res @@ -9,12 +9,11 @@ let dispatch = ( reducer: Reducer_T.reducerFn, chain, ): result => { - E.A.O.firstSomeFn([ - // () => ReducerInterface_GenericDistribution.dispatch(call, environment), - // () => ReducerInterface_Date.dispatch(call, environment), - // () => ReducerInterface_Duration.dispatch(call, environment), - // () => ReducerInterface_Number.dispatch(call, environment), - // () => FunctionRegistry_Library.dispatch(call, environment, reducer), + E.A.O.firstSomeFn([// () => ReducerInterface_GenericDistribution.dispatch(call, environment), + // () => ReducerInterface_Date.dispatch(call, environment), + // () => ReducerInterface_Duration.dispatch(call, environment), + // () => ReducerInterface_Number.dispatch(call, environment), + // () => FunctionRegistry_Library.dispatch(call, environment, reducer), ])->E.O2.defaultFn(() => chain(call, environment, reducer)) } diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res index 27b0a546..dd0d6e51 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res @@ -2,7 +2,6 @@ // (value methods should be moved to Reducer_Value.res) module ErrorValue = Reducer_ErrorValue -module Extra_Array = Reducer_Extra_Array type environment = GenericDist.env module T = Reducer_T diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res index dc74135a..18957474 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res @@ -10,49 +10,37 @@ let internalStdLib: Reducer_T.namespace = { "$_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)] => { + let index = Belt.Int.fromFloat(fIndex) // TODO - fail on non-integer indices? + + switch Belt.Array.get(aValueArray, index) { | Some(value) => value | None => - REArrayIndexNotFound("Array index not found", Belt.Int.fromFloat(fIndex)) + REArrayIndexNotFound("Array index not found", index) ->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 property not found", sIndex)->ErrorException->raise + | None => + RERecordPropertyNotFound("Record property not found", sIndex)->ErrorException->raise } | _ => REOther("Trying to access key on wrong value")->ErrorException->raise } })->Reducer_T.IEvLambda, ) - let res = FunctionRegistry_Library.nonRegistryLambdas->Belt.Array.reduce( - res, - (cur, (name, lambda)) => { - cur->Reducer_Namespace.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), + let res = FunctionRegistry_Library.nonRegistryLambdas->Belt.Array.reduce(res, ( + cur, + (name, lambda), + ) => { + cur->Reducer_Namespace.set(name, lambda->Reducer_T.IEvLambda) + }) // 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(_)]) @@ -60,19 +48,20 @@ let internalStdLib: Reducer_T.namespace = { // [ ] | (_, [IEvNumber(_), IEvNumber(_)]) // [ ] | (_, [IEvString(_), IEvString(_)]) => callMathJs(call) - let res = FunctionRegistry_Library.registry - ->FunctionRegistry_Core.Registry.allNames - ->Belt.Array.reduce(res, (cur, name) => { - cur->Reducer_Namespace.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, - ) - }) + let res = + FunctionRegistry_Library.registry + ->FunctionRegistry_Core.Registry.allNames + ->Belt.Array.reduce(res, (cur, name) => { + cur->Reducer_Namespace.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 12933e21..01996b32 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res @@ -166,23 +166,25 @@ let linkDependencies = (project: t, sourceId: string): Reducer_T.namespace => { Belt.Array.concatMany([ [project->getStdLib], pastChain->Belt.Array.map(project->getBindings), - pastChain->Belt.Array.map( - id => Reducer_Namespace.fromArray([ - ("__result__", - switch project->getResult(id) { + pastChain->Belt.Array.map(id => + Reducer_Namespace.fromArray([ + ( + "__result__", + switch project->getResult(id) { | Ok(result) => result | Error(error) => error->Reducer_ErrorValue.ErrorException->raise - }) + }, + ), ]) ), - ]) + ]), ) let includesAsVariables = project->getIncludesAsVariables(sourceId) Belt.Array.reduce(includesAsVariables, namespace, (acc, (variable, includeFile)) => acc->Reducer_Namespace.set( variable, - project->getBindings(includeFile)->Reducer_Namespace.toRecord + project->getBindings(includeFile)->Reducer_Namespace.toRecord, ) ) } @@ -190,7 +192,7 @@ let linkDependencies = (project: t, sourceId: string): Reducer_T.namespace => { let doLinkAndRun = (project: t, sourceId: string): unit => { let context = Reducer_Context.createContext( project->linkDependencies(sourceId), - project->getEnvironment + project->getEnvironment, ) let newItem = project->getItem(sourceId)->ProjectItem.run(context) // Js.log("after run " ++ newItem.continuation->Reducer_Bindings.toString) diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res index e51f7d4b..93d434a3 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res @@ -172,10 +172,14 @@ let failRun = (this: t, e: Reducer_ErrorValue.errorValue): t => let doRun = (this: t, context: Reducer_T.context): t => switch this->getExpression { - | Some(expressionResult) => switch expressionResult { - | Ok(expression) => try { + | Some(expressionResult) => + switch expressionResult { + | Ok(expression) => + try { let (result, contextAfterEvaluation) = Reducer_Expression.evaluate(expression, context) - this->setResult(result->Ok)->setContinuation(contextAfterEvaluation.bindings->Reducer_Bindings.locals) + this + ->setResult(result->Ok) + ->setContinuation(contextAfterEvaluation.bindings->Reducer_Bindings.locals) } catch { | Reducer_ErrorValue.ErrorException(e) => this->failRun(e) | _ => this->failRun(RETodo("unhandled rescript exception")) diff --git a/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Math.res b/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Math.res index 4682fa01..631b05fb 100644 --- a/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Math.res +++ b/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_Math.res @@ -12,4 +12,6 @@ let availableNumbers: array<(string, float)> = [ ] let make = (): Reducer_Namespace.t => - availableNumbers->E.A2.fmap(((name, v)) => (name, Reducer_T.IEvNumber(v)))->Reducer_Namespace.fromArray + availableNumbers + ->E.A2.fmap(((name, v)) => (name, Reducer_T.IEvNumber(v))) + ->Reducer_Namespace.fromArray From f8b743feb51a562cc36a362323233ba426bbeddd Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Mon, 19 Sep 2022 21:46:37 +0400 Subject: [PATCH 21/46] tests; drop mathjs; new FR helpers; disable type tests --- .../Reducer_Dispatch_BuiltInMacros_test.res | 147 ------------------ .../Reducer_Dispatch_BuiltIn_test.res | 41 ----- .../Reducer_MathJsEval_test.res | 31 ---- .../Reducer_Peggy_ToExpression_void_test.res | 8 +- .../Reducer/Reducer_TestMacroHelpers.res | 89 ----------- .../Reducer_functionAssignment_test.res | 4 + .../Reducer/Reducer_mapReduce_test.res | 4 + .../__tests__/Reducer/Reducer_test.res | 21 ++- packages/squiggle-lang/jest.config.js | 2 + .../src/rescript/FR/FR_Builtin.res | 133 ++++++++++------ .../squiggle-lang/src/rescript/FR/FR_Math.res | 58 +++++++ .../src/rescript/FR/FR_Mathjs.res | 70 --------- .../src/rescript/FR/FR_Number.res | 5 +- .../FunctionRegistry_Helpers.res | 140 +++++++++++++++++ .../FunctionRegistry_Library.res | 2 +- .../src/rescript/FunctionRegistry/README.md | 38 +++-- .../Reducer/Reducer_MathJs/Reducer_MathJs.res | 1 - .../Reducer_MathJs/Reducer_MathJs_Eval.res | 27 ---- .../ReducerInterface/ReducerInterface.res | 1 - .../ReducerInterface_ExternalLibrary.res | 35 ----- .../ReducerInterface_StdLib.res | 13 +- .../src/rescript/shims/Js.shim.ts | 1 - 22 files changed, 342 insertions(+), 529 deletions(-) delete mode 100644 packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros_test.res delete mode 100644 packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res delete mode 100644 packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsEval_test.res delete mode 100644 packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res create mode 100644 packages/squiggle-lang/src/rescript/FR/FR_Math.res delete mode 100644 packages/squiggle-lang/src/rescript/FR/FR_Mathjs.res delete mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs.res delete mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Eval.res delete mode 100644 packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res delete mode 100644 packages/squiggle-lang/src/rescript/shims/Js.shim.ts diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros_test.res deleted file mode 100644 index 71b9c86d..00000000 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros_test.res +++ /dev/null @@ -1,147 +0,0 @@ -// open Jest -// // open Expect - -// open Reducer_Expression_ExpressionBuilder -// open Reducer_TestMacroHelpers -// module ExpressionT = Reducer_Expression_T - -// let exampleExpression = eNumber(1.) -// let exampleExpressionY = eSymbol("y") -// let exampleStatementY = eLetStatement("y", eNumber(1.)) -// let exampleStatementX = eLetStatement("y", eSymbol("x")) -// let exampleStatementZ = eLetStatement("z", eSymbol("y")) - -// // If it is not a macro then it is not expanded -// testMacro([], exampleExpression, "Ok(1)") - -// describe("bindStatement", () => { -// // A statement is bound by the bindings created by the previous statement -// testMacro( -// [], -// eBindStatement(eBindings([]), exampleStatementY), -// "Ok((:$_setBindings_$ @{} :y 1) context: @{})", -// ) -// // Then it answers the bindings for the next statement when reduced -// testMacroEval([], eBindStatement(eBindings([]), exampleStatementY), "Ok(@{y: 1})") -// // Now let's feed a binding to see what happens -// testMacro( -// [], -// eBindStatement(eBindings([("x", IEvNumber(2.))]), exampleStatementX), -// "Ok((:$_setBindings_$ @{x: 2} :y 2) context: @{x: 2})", -// ) -// // An expression does not return a binding, thus error -// testMacro([], eBindStatement(eBindings([]), exampleExpression), "Assignment expected") -// // When bindings from previous statement are missing the context is injected. This must be the first statement of a block -// testMacro( -// [("z", IEvNumber(99.))], -// eBindStatementDefault(exampleStatementY), -// "Ok((:$_setBindings_$ @{z: 99} :y 1) context: @{z: 99})", -// ) -// }) - -// describe("bindExpression", () => { -// // x is simply bound in the expression -// testMacro( -// [], -// eBindExpression(eBindings([("x", IEvNumber(2.))]), eSymbol("x")), -// "Ok(2 context: @{x: 2})", -// ) -// // When an let statement is the end expression then bindings are returned -// testMacro( -// [], -// eBindExpression(eBindings([("x", IEvNumber(2.))]), exampleStatementY), -// "Ok((:$_exportBindings_$ (:$_setBindings_$ @{x: 2} :y 1)) context: @{x: 2})", -// ) -// // Now let's reduce that expression -// testMacroEval( -// [], -// eBindExpression(eBindings([("x", IEvNumber(2.))]), exampleStatementY), -// "Ok(@{x: 2,y: 1})", -// ) -// // When bindings are missing the context is injected. This must be the first and last statement of a block -// testMacroEval( -// [("z", IEvNumber(99.))], -// eBindExpressionDefault(exampleStatementY), -// "Ok(@{y: 1,z: 99})", -// ) -// }) - -// describe("block", () => { -// // Block with a single expression -// testMacro([], eBlock(list{exampleExpression}), "Ok((:$$_bindExpression_$$ 1))") -// testMacroEval([], eBlock(list{exampleExpression}), "Ok(1)") -// // Block with a single statement -// testMacro([], eBlock(list{exampleStatementY}), "Ok((:$$_bindExpression_$$ (:$_let_$ :y 1)))") -// testMacroEval([], eBlock(list{exampleStatementY}), "Ok(@{y: 1})") -// // Block with a statement and an expression -// testMacro( -// [], -// eBlock(list{exampleStatementY, exampleExpressionY}), -// "Ok((:$$_bindExpression_$$ (:$$_bindStatement_$$ (:$_let_$ :y 1)) :y))", -// ) -// testMacroEval([], eBlock(list{exampleStatementY, exampleExpressionY}), "Ok(1)") -// // Block with a statement and another statement -// testMacro( -// [], -// eBlock(list{exampleStatementY, exampleStatementZ}), -// "Ok((:$$_bindExpression_$$ (:$$_bindStatement_$$ (:$_let_$ :y 1)) (:$_let_$ :z :y)))", -// ) -// testMacroEval([], eBlock(list{exampleStatementY, exampleStatementZ}), "Ok(@{y: 1,z: 1})") -// // Block inside a block -// testMacro([], eBlock(list{eBlock(list{exampleExpression})}), "Ok((:$$_bindExpression_$$ {1}))") -// testMacroEval([], eBlock(list{eBlock(list{exampleExpression})}), "Ok(1)") -// // Block assigned to a variable -// testMacro( -// [], -// eBlock(list{eLetStatement("z", eBlock(list{eBlock(list{exampleExpressionY})}))}), -// "Ok((:$$_bindExpression_$$ (:$_let_$ :z {{:y}})))", -// ) -// testMacroEval( -// [], -// eBlock(list{eLetStatement("z", eBlock(list{eBlock(list{exampleExpressionY})}))}), -// "Ok(@{z: :y})", -// ) -// // Empty block -// testMacro([], eBlock(list{}), "Ok(:undefined block)") //TODO: should be an error -// // :$$_block_$$ (:$$_block_$$ (:$_let_$ :y (:add :x 1)) :y)" -// testMacro( -// [], -// eBlock(list{ -// eBlock(list{ -// eLetStatement("y", eFunction("add", list{eSymbol("x"), eNumber(1.)})), -// eSymbol("y"), -// }), -// }), -// "Ok((:$$_bindExpression_$$ {(:$_let_$ :y (:add :x 1)); :y}))", -// ) -// testMacroEval( -// [("x", IEvNumber(1.))], -// eBlock(list{ -// eBlock(list{ -// eLetStatement("y", eFunction("add", list{eSymbol("x"), eNumber(1.)})), -// eSymbol("y"), -// }), -// }), -// "Ok(2)", -// ) -// }) - -// describe("lambda", () => { -// // assign a lambda to a variable -// let lambdaExpression = eFunction("$$_lambda_$$", list{eArrayString(["y"]), exampleExpressionY}) -// testMacro([], lambdaExpression, "Ok(lambda(y=>internal code))") -// // call a lambda -// let callLambdaExpression = list{lambdaExpression, eNumber(1.)}->ExpressionT.EList -// testMacro([], callLambdaExpression, "Ok(((:$$_lambda_$$ [y] :y) 1))") -// testMacroEval([], callLambdaExpression, "Ok(1)") -// // Parameters shadow the outer scope -// testMacroEval([("y", IEvNumber(666.))], callLambdaExpression, "Ok(1)") -// // When not shadowed by the parameters, the outer scope variables are available -// let lambdaExpression = eFunction( -// "$$_lambda_$$", -// list{eArrayString(["z"]), eFunction("add", list{eSymbol("y"), eSymbol("z")})}, -// ) -// let callLambdaExpression = eList(list{lambdaExpression, eNumber(1.)}) -// testMacroEval([("y", IEvNumber(666.))], callLambdaExpression, "Ok(667)") -// }) - diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res deleted file mode 100644 index 5c6848b8..00000000 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res +++ /dev/null @@ -1,41 +0,0 @@ -module ExpressionValue = ReducerInterface.InternalExpressionValue -module Expression = Reducer_Expression - -open Jest -open Expect - -let expectEvalToBe = (sourceCode: string, answer: string) => - Expression.BackCompatible.evaluateString(sourceCode) - ->ExpressionValue.toStringResult - ->expect - ->toBe(answer) - -let testEval = (expr, answer) => test(expr, () => expectEvalToBe(expr, answer)) - -describe("builtin", () => { - // All MathJs operators and functions are available for string, number and boolean - // .e.g + - / * > >= < <= == /= not and or - // See https://mathjs.org/docs/expressions/syntax.html - // See https://mathjs.org/docs/reference/functions.html - testEval("-1", "Ok(-1)") - testEval("1-1", "Ok(0)") - testEval("2>1", "Ok(true)") - testEval("concat('a','b')", "Ok('ab')") -}) - -describe("builtin exception", () => { - //MathJS is no more, this is just a normal function call (TODO - refactor tests) - test("MathJs Exception", () => - expectEvalToBe("testZadanga(1)", "Error(testZadanga is not defined)") - ) -}) - -describe("error reporting from collection functions", () => { - testEval("arr=[1,2,3]; map(arr, {|x| x*2})", "Ok([2,4,6])") - testEval( - "arr = [normal(3,2)]; map(arr, zarathsuzaWasHere)", - "Error(zarathsuzaWasHere is not defined)", - ) - // FIXME: returns "Error(Function not found: map(Array,Symbol))" - // Actually this error is correct but not informative -}) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsEval_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsEval_test.res deleted file mode 100644 index e56c04d7..00000000 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsEval_test.res +++ /dev/null @@ -1,31 +0,0 @@ -module MathJs = Reducer_MathJs -module ErrorValue = Reducer_ErrorValue - -open Jest -open ExpectJs - -describe("eval", () => { - test("Number", () => expect(MathJs.Eval.eval("1"))->toEqual(Ok(IEvNumber(1.)))) - test("Number expr", () => expect(MathJs.Eval.eval("1-1"))->toEqual(Ok(IEvNumber(0.)))) - test("String", () => expect(MathJs.Eval.eval("'hello'"))->toEqual(Ok(IEvString("hello")))) - test("String expr", () => - expect(MathJs.Eval.eval("concat('hello ','world')"))->toEqual(Ok(IEvString("hello world"))) - ) - test("Boolean", () => expect(MathJs.Eval.eval("true"))->toEqual(Ok(IEvBool(true)))) - test("Boolean expr", () => expect(MathJs.Eval.eval("2>1"))->toEqual(Ok(IEvBool(true)))) -}) - -describe("errors", () => { - // All those errors propagete up and are returned by the resolver - test("unknown function", () => - expect(MathJs.Eval.eval("testZadanga()"))->toEqual( - Error(ErrorValue.REJavaScriptExn(Some("Undefined function testZadanga"), Some("Error"))), - ) - ) - - test("unknown answer type", () => - expect(MathJs.Eval.eval("1+1i"))->toEqual( - Error(ErrorValue.RETodo("Unhandled MathJs literal type: object")), - ) - ) -}) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_void_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_void_test.res index f46d387f..451656cb 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_void_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_void_test.res @@ -3,22 +3,22 @@ open Reducer_Peggy_TestHelpers describe("Peggy void", () => { //literal - testToExpression("()", "{(:$_endOfOuterBlock_$ () ())}", ~v="()", ()) + testToExpression("()", "()", ~v="()", ()) testToExpression( "fn()=1", - "{(:$_let_$ :fn (:$$_lambda_$$ [_] {1})); (:$_endOfOuterBlock_$ () ())}", + "fn = {|_| {1}}", // ~v="@{fn: lambda(_=>internal code)}", (), ) testToExpression( "fn()=1; fn()", - "{(:$_let_$ :fn (:$$_lambda_$$ [_] {1})); (:$_endOfOuterBlock_$ () (:fn ()))}", + "fn = {|_| {1}}; (fn)(())", ~v="1", (), ) testToExpression( "fn(a)=(); call fn(1)", - "{(:$_let_$ :fn (:$$_lambda_$$ [a] {()})); (:$_let_$ :_ {(:fn 1)}); (:$_endOfOuterBlock_$ () ())}", + "fn = {|a| {()}}; _ = {(fn)(1)}", // ~v="@{_: (),fn: lambda(a=>internal code)}", (), ) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res deleted file mode 100644 index c69d060c..00000000 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res +++ /dev/null @@ -1,89 +0,0 @@ -// open Jest -// open Expect - -// module BindingsReplacer = Reducer_Expression_BindingsReplacer -// module Expression = Reducer_Expression -// module ExpressionWithContext = Reducer_ExpressionWithContext -// module InternalExpressionValue = ReducerInterface.InternalExpressionValue -// module Macro = Reducer_Expression_Macro -// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -// module T = Reducer_Expression_T - -// let testMacro_ = ( -// tester, -// bindArray: array<(string, InternalExpressionValue.t)>, -// expr: T.expression, -// expectedCode: string, -// ) => { -// let bindings = Bindings.fromArray(bindArray) -// tester(expr->T.toString, () => -// expr -// ->Macro.expandMacroCallRs( -// bindings, -// ProjectAccessorsT.identityAccessors, -// Expression.reduceExpressionInProject, -// ) -// ->ExpressionWithContext.toStringResult -// ->expect -// ->toEqual(expectedCode) -// ) -// } - -// let testMacroEval_ = ( -// tester, -// bindArray: array<(string, InternalExpressionValue.t)>, -// expr: T.expression, -// expectedValue: string, -// ) => { -// let bindings = Reducer_Bindings.fromArray(bindArray) -// tester(expr->T.toString, () => -// expr -// ->Macro.doMacroCall( -// bindings, -// ProjectAccessorsT.identityAccessors, -// Expression.reduceExpressionInProject, -// ) -// ->Ok -// ->InternalExpressionValue.toStringResult -// ->expect -// ->toEqual(expectedValue) -// ) -// } - -// let testMacro = ( -// bindArray: array<(string, InternalExpressionValue.t)>, -// expr: T.expression, -// expectedExpr: string, -// ) => testMacro_(test, bindArray, expr, expectedExpr) -// let testMacroEval = ( -// bindArray: array<(string, InternalExpressionValue.t)>, -// expr: T.expression, -// expectedValue: string, -// ) => testMacroEval_(test, bindArray, expr, expectedValue) - -// module MySkip = { -// let testMacro = ( -// bindArray: array<(string, InternalExpressionValue.t)>, -// expr: T.expression, -// expectedExpr: string, -// ) => testMacro_(Skip.test, bindArray, expr, expectedExpr) -// let testMacroEval = ( -// bindArray: array<(string, InternalExpressionValue.t)>, -// expr: T.expression, -// expectedValue: string, -// ) => testMacroEval_(Skip.test, bindArray, expr, expectedValue) -// } - -// module MyOnly = { -// let testMacro = ( -// bindArray: array<(string, InternalExpressionValue.t)>, -// expr: T.expression, -// expectedExpr: string, -// ) => testMacro_(Only.test, bindArray, expr, expectedExpr) -// let testMacroEval = ( -// bindArray: array<(string, InternalExpressionValue.t)>, -// expr: T.expression, -// expectedValue: string, -// ) => testMacroEval_(Only.test, bindArray, expr, expectedValue) -// } - diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res index e48d1223..95f9b4c8 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res @@ -10,3 +10,7 @@ describe("Parse function assignment", () => { describe("Evaluate function assignment", () => { testEvalToBe("f(x)=x; f(1)", "Ok(1)") }) + +describe("Shadowing", () => { + testEvalToBe("x = 5; f(y) = x*y; x = 6; f(2)", "Ok(10)") +}) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_mapReduce_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_mapReduce_test.res index f89173d5..d75004d5 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_mapReduce_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_mapReduce_test.res @@ -5,3 +5,7 @@ Skip.describe("map reduce (sam)", () => { testEvalToBe("addone(x)=x+1; map(2, addone)", "Error???") testEvalToBe("addone(x)=x+1; map(2, {x: addone})", "Error???") }) + +describe("map", () => { + testEvalToBe("arr=[1,2,3]; map(arr, {|x| x*2})", "Ok([2,4,6])") +}) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res index 769937de..49180135 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res @@ -2,20 +2,29 @@ open Jest open Reducer_TestHelpers describe("eval", () => { - // All MathJs operators and functions are builtin for string, float and boolean - // .e.g + - / * > >= < <= == /= not and or - // See https://mathjs.org/docs/reference/functions.html describe("expressions", () => { testEvalToBe("1", "Ok(1)") + testEvalToBe("-1", "Ok(-1)") + testEvalToBe("1-1", "Ok(0)") testEvalToBe("1+2", "Ok(3)") testEvalToBe("(1+2)*3", "Ok(9)") testEvalToBe("2>1", "Ok(true)") testEvalToBe("concat('a ', 'b')", "Ok('a b')") testEvalToBe("concat([3,4], [5,6,7])", "Ok([3,4,5,6,7])") testEvalToBe("log(10)", "Ok(2.302585092994046)") - testEvalToBe("cos(10)", "Ok(-0.8390715290764524)") + testEvalToBe("Math.cos(10)", "Ok(-0.8390715290764524)") // TODO more built ins }) + + describe("missing function", () => { + testEvalToBe("testZadanga(1)", "Error(testZadanga is not defined)") + + testEvalToBe( + "arr = [normal(3,2)]; map(arr, zarathsuzaWasHere)", + "Error(zarathsuzaWasHere is not defined)", + ) + }) + describe("arrays", () => { test("empty array", () => expectEvalToBe("[]", "Ok([])")) testEvalToBe("[1, 2, 3]", "Ok([1,2,3])") @@ -51,6 +60,10 @@ describe("eval", () => { testEvalError("1; 1") testEvalToBe("x=1; x=1; x", "Ok(1)") }) + + describe("blocks", () => { + testEvalToBe("x = { y = { z = 5; z * 2 }; y + 3 }; x", "Ok(13)") + }) }) describe("test exceptions", () => { diff --git a/packages/squiggle-lang/jest.config.js b/packages/squiggle-lang/jest.config.js index 71babb3c..6fe2b2f4 100644 --- a/packages/squiggle-lang/jest.config.js +++ b/packages/squiggle-lang/jest.config.js @@ -10,5 +10,7 @@ module.exports = { "/node_modules/", ".*Helpers.bs.js", ".*Helpers.ts", + ".*Reducer_Type.*", + ".*_type_test.bs.js", ], }; diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Builtin.res b/packages/squiggle-lang/src/rescript/FR/FR_Builtin.res index 7ab3b1a9..e346075d 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Builtin.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Builtin.res @@ -25,52 +25,87 @@ let makeFn = ( fn: array => result, ) => makeFnMany(name, [{inputs: inputs, fn: fn}]) -let makeFF2F = (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 makeFF2B = (name: string, fn: (float, float) => bool) => { - makeFn(name, [FRTypeNumber, FRTypeNumber], inputs => { - switch inputs { - | [IEvNumber(x), IEvNumber(y)] => fn(x, y)->IEvBool->Ok - | _ => Error(impossibleError) - } - }) -} - -let makeBB2B = (name: string, fn: (bool, bool) => bool) => { - makeFn(name, [FRTypeBool, FRTypeBool], inputs => { - switch inputs { - | [IEvBool(x), IEvBool(y)] => fn(x, y)->IEvBool->Ok - | _ => Error(impossibleError) - } - }) -} - let library = [ - makeFF2F("add", (x, y) => x +. y), // infix + (see Reducer/Reducer_Peggy/helpers.ts) - makeFF2F("subtract", (x, y) => x -. y), // infix - - makeFF2F("multiply", (x, y) => x *. y), // infix * - makeFF2F("divide", (x, y) => x /. y), // infix / - makeFF2F("pow", (x, y) => Js.Math.pow_float(~base=x, ~exp=y)), // infix ^ - makeFF2B("equal", (x, y) => x == y), // infix == - makeFF2B("smaller", (x, y) => x < y), // infix < - makeFF2B("smallerEq", (x, y) => x <= y), // infix <= - makeFF2B("larger", (x, y) => x > y), // infix > - makeFF2B("largerEq", (x, y) => x >= y), // infix >= - makeBB2B("or", (x, y) => x || y), // infix || - makeBB2B("and", (x, y) => x && y), // infix && - makeFn("unaryMinus", [FRTypeNumber], inputs => { // unary prefix - - switch inputs { - | [IEvNumber(x)] => IEvNumber(-.x)->Ok - | _ => Error(impossibleError) - } - }), + Make.ff2f( + ~name="add", // infix + (see Reducer/Reducer_Peggy/helpers.ts) + ~fn=(x, y) => x +. y, + () + ), + Make.ff2f( + ~name="subtract", // infix - + ~fn=(x, y) => x -. y, + () + ), + Make.ff2f( + ~name="multiply", // infix * + ~fn=(x, y) => x *. y, + () + ), + Make.ff2f( + ~name="divide", // infix / + ~fn=(x, y) => x /. y, + () + ), + Make.ff2f( + ~name="pow", // infix ^ + ~fn=(x, y) => Js.Math.pow_float(~base=x, ~exp=y), + () + ), + Make.ff2b( + ~name="equal", // infix == on numbers + ~fn=(x, y) => x == y, + () + ), + Make.bb2b( + ~name="equal", // infix == on booleans + ~fn=(x, y) => x == y, + () + ), + Make.ff2b( + ~name="unequal", // infix != on numbers + ~fn=(x, y) => x != y, + () + ), + Make.ff2b( + ~name="unequal", // infix != on booleans + ~fn=(x, y) => x != y, + () + ), + Make.ff2b( + ~name="smaller", // infix < + ~fn=(x, y) => x < y, + () + ), + Make.ff2b( + ~name="smallerEq", // infix <= + ~fn=(x, y) => x <= y, + () + ), + Make.ff2b( + ~name="larger", // infix > + ~fn=(x, y) => x > y, + () + ), + Make.ff2b( + ~name="largerEq", // infix >= + ~fn=(x, y) => x >= y, + () + ), + Make.bb2b( + ~name="or", // infix || + ~fn=(x, y) => x || y, + () + ), + Make.bb2b( + ~name="and", // infix && + ~fn=(x, y) => x && y, + () + ), + Make.f2f( + ~name="unaryMinus", // unary prefix - + ~fn=x => -.x, + () + ), makeFn("not", [FRTypeNumber], inputs => { // unary prefix ! switch inputs { | [IEvNumber(x)] => IEvBool(x != 0.)->Ok @@ -120,4 +155,12 @@ let library = [ | _ => Error(impossibleError) } }), + makeFn("javascriptraise", [FRTypeAny], inputs => { + switch inputs { + | [msg] => { + Js.Exn.raiseError(msg->ReducerInterface_InternalExpressionValue.toString) + } + | _ => Error(impossibleError) + } + }), ] diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Math.res b/packages/squiggle-lang/src/rescript/FR/FR_Math.res new file mode 100644 index 00000000..98ed37b2 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/FR/FR_Math.res @@ -0,0 +1,58 @@ +open FunctionRegistry_Helpers + +let library = [ + // ported MathJS functions + // https://docs.google.com/spreadsheets/d/1bUK2RaBFg8aJHuzZcw9yXp8StCBH5If5sU2iRw1T_HY/edit + // TODO - implement the rest of useful stuff + + Make.f2f( + ~name="sqrt", + ~nameSpace="Math", + ~requiresNamespace=true, + ~fn=(x) => Js.Math.pow_float(~base=x, ~exp=0.5), + (), + ), + + Make.f2f( + ~name="sin", + ~nameSpace="Math", + ~requiresNamespace=true, + ~fn=Js.Math.sin, + (), + ), + Make.f2f( + ~name="cos", + ~nameSpace="Math", + ~requiresNamespace=true, + ~fn=Js.Math.cos, + (), + ), + Make.f2f( + ~name="tan", + ~nameSpace="Math", + ~requiresNamespace=true, + ~fn=Js.Math.tan, + (), + ), + Make.f2f( + ~name="asin", + ~nameSpace="Math", + ~requiresNamespace=true, + ~fn=Js.Math.asin, + (), + ), + Make.f2f( + ~name="acos", + ~nameSpace="Math", + ~requiresNamespace=true, + ~fn=Js.Math.acos, + (), + ), + Make.f2f( + ~name="atan", + ~nameSpace="Math", + ~requiresNamespace=true, + ~fn=Js.Math.atan, + (), + ), +] diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Mathjs.res b/packages/squiggle-lang/src/rescript/FR/FR_Mathjs.res deleted file mode 100644 index 9bffde42..00000000 --- a/packages/squiggle-lang/src/rescript/FR/FR_Mathjs.res +++ /dev/null @@ -1,70 +0,0 @@ -open FunctionRegistry_Core -open FunctionRegistry_Helpers - -// FIXME - copy-pasted (see FR_Date.res and others) -let makeFn = ( - name: string, - inputs: array, - fn: array => result, -) => - Function.make( - ~name, - ~nameSpace="", - ~requiresNamespace=false, - ~definitions=[FnDefinition.make(~name, ~inputs, ~run=(inputs, _, _, _) => fn(inputs), ())], - (), - ) - -@module("mathjs") external dummy_: string => unit = "evaluate" -let dummy1_ = dummy_ //Deceive the compiler to make the import although we wont make a call from rescript. Otherwise the optimizer deletes the import - -let mathjsCall1: (string, float) => 'a = %raw(`function (name, arg) { return Mathjs[name](arg); }`) -let mathjsCall2: (string, float, float) => 'a = %raw(`function (name, arg1, arg2) { return Mathjs[name](arg1, arg2); }`) - -let makeMathjsFn1 = ( - name: string -) => { - makeFn(name, [FRTypeNumber], inputs => { - switch inputs { - | [IEvNumber(x)] => mathjsCall1(name, x)->Reducer_Js_Gate.jsToIEv - | _ => Error(impossibleError) - } - }) -} - -let makeMathjsFn2 = ( - name: string -) => { - makeFn(name, [FRTypeNumber, FRTypeNumber], inputs => { - switch inputs { - | [IEvNumber(x), IEvNumber(y)] => mathjsCall2(name, x, y)->Reducer_Js_Gate.jsToIEv - | _ => Error(impossibleError) - } - }) -} - -let library = [ - // TODO - other MathJS - // https://mathjs.org/docs/reference/functions.html - - // Arithmetic functions - makeMathjsFn1("abs"), - makeMathjsFn1("cbrt"), - makeMathjsFn1("ceil"), - makeMathjsFn1("cube"), - makeMathjsFn1("exp"), - makeMathjsFn1("fix"), - makeMathjsFn1("floor"), - - makeMathjsFn2("gcd"), - makeMathjsFn2("hypot"), - makeMathjsFn2("invmod"), - makeMathjsFn2("lcm"), - makeMathjsFn1("log"), // Do we need makeMathjsFn2 for `log` too? - makeMathjsFn1("log10"), - makeMathjsFn1("log2"), - - makeMathjsFn1("factorial"), - makeMathjsFn1("cos"), - -] diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Number.res b/packages/squiggle-lang/src/rescript/FR/FR_Number.res index bd05164c..6e5426ac 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Number.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Number.res @@ -20,13 +20,12 @@ module ArrayNumberDist = { } let library = [ - Function.make( + Make.f2f( ~name="floor", ~nameSpace, ~requiresNamespace, - ~output=EvtNumber, ~examples=[`floor(3.5)`], - ~definitions=[DefineFn.Numbers.oneToOne("floor", Js.Math.floor_float)], + ~fn=Js.Math.floor_float, (), ), Function.make( diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res index cf24bfc4..82c99d6c 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res @@ -259,3 +259,143 @@ module DefineFn = { ) } } + +module Make = { + /* + Opinionated explanations for API choices here: + + Q: Why such short names? + A: Because we have to type them a lot in definitions. + + Q: Why not DefineFn.Numbers.oneToOne / DefineFn.Numbers.twoToOne / ...? + A: Because return values matter too, and we have many possible combinations: numbers to numbers, pairs of numbers to numbers, pair of numbers to bools. + + Q: Does this approach scale? + A: It's good enough for most cases, and we can fall back on raw `Function.make` if necessary. We should figure out the better API powered by parameterized types, but it's hard (and might require PPX). + + Q: What about `frValue` types? + A: I hope we'll get rid of them soon. + + Q: What about polymorphic functions with multiple definitions? Why ~fn is not an array? + A: We often define the same function in multiple `FR_*` files, so that doesn't work well anyway. In 90%+ cases there's a single definition. And having to write `name` twice is annoying. + */ + let f2f = ( + ~name: string, + ~fn: (float) => float, + ~nameSpace="", + ~requiresNamespace=false, + ~examples=?, + (), + ) => { + Function.make( + ~name, + ~nameSpace, + ~requiresNamespace=requiresNamespace, + ~examples=examples->E.O.default([], _), + ~output=EvtNumber, + ~definitions=[ + FnDefinition.make( + ~name, + ~inputs=[FRTypeNumber], + ~run=((inputs, _, _, _) => + switch inputs { + | [IEvNumber(x)] => fn(x)->IEvNumber->Ok + | _ => Error(impossibleError) + }), + () + ) + ], + () + ) + } + + let ff2f = ( + ~name: string, + ~fn: (float, float) => float, + ~nameSpace="", + ~requiresNamespace=false, + ~examples=?, + (), + ) => { + Function.make( + ~name, + ~nameSpace, + ~requiresNamespace=requiresNamespace, + ~examples=examples->E.O.default([], _), + ~output=EvtNumber, + ~definitions=[ + FnDefinition.make( + ~name, + ~inputs=[FRTypeNumber, FRTypeNumber], + ~run=((inputs, _, _, _) => + switch inputs { + | [IEvNumber(x), IEvNumber(y)] => fn(x, y)->IEvNumber->Ok + | _ => Error(impossibleError) + }), + () + ) + ], + () + ) + } + + let ff2b = ( + ~name: string, + ~fn: (float, float) => bool, + ~nameSpace="", + ~requiresNamespace=false, + ~examples=?, + (), + ) => { + Function.make( + ~name, + ~nameSpace, + ~requiresNamespace=requiresNamespace, + ~examples=examples->E.O.default([], _), + ~output=EvtBool, + ~definitions=[ + FnDefinition.make( + ~name, + ~inputs=[FRTypeNumber, FRTypeNumber], + ~run=((inputs, _, _, _) => + switch inputs { + | [IEvNumber(x), IEvNumber(y)] => fn(x, y)->IEvBool->Ok + | _ => Error(impossibleError) + }), + () + ) + ], + () + ) + } + + let bb2b = ( + ~name: string, + ~fn: (bool, bool) => bool, + ~nameSpace="", + ~requiresNamespace=false, + ~examples=?, + (), + ) => { + Function.make( + ~name, + ~nameSpace, + ~requiresNamespace=requiresNamespace, + ~examples=examples->E.O.default([], _), + ~output=EvtBool, + ~definitions=[ + FnDefinition.make( + ~name, + ~inputs=[FRTypeBool, FRTypeBool], + ~run=((inputs, _, _, _) => + switch inputs { + | [IEvBool(x), IEvBool(y)] => fn(x, y)->IEvBool->Ok + | _ => Error(impossibleError) + }), + () + ) + ], + () + ) + } +} diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res index 34de2e2b..7dc7aa0b 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Library.res @@ -12,7 +12,7 @@ let fnList = Belt.Array.concatMany([ FR_GenericDist.library, FR_Units.library, FR_Date.library, - FR_Mathjs.library, + FR_Math.library, ]) let registry = FunctionRegistry_Core.Registry.make(fnList) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/README.md b/packages/squiggle-lang/src/rescript/FunctionRegistry/README.md index cf22d878..38bf1858 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/README.md +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/README.md @@ -9,35 +9,33 @@ The main interface is fairly constrained. Basically, write functions like the fo ~name="Normal", ~definitions=[ FnDefinition.make( - ~name="Normal", - ~definitions=[ - FnDefinition.make(~name="normal", ~inputs=[FRTypeDistOrNumber, FRTypeDistOrNumber], ~run=( - inputs, - env, - ) => - inputs - ->Prepare.ToValueTuple.twoDistOrNumber - ->E.R.bind( - Process.twoDistsOrNumbersToDistUsingSymbolicDist( - ~fn=E.Tuple2.toFnCall(SymbolicDist.Normal.make), - ~env, - ~values=_, - ), - ) - ->E.R2.fmap(Wrappers.evDistribution) + ~name="normal", + ~inputs=[FRTypeDistOrNumber, FRTypeDistOrNumber], + ~run=( + inputs, + env, + ) => + inputs + ->Prepare.ToValueTuple.twoDistOrNumber + ->E.R.bind( + Process.twoDistsOrNumbersToDistUsingSymbolicDist( + ~fn=E.Tuple2.toFnCall(SymbolicDist.Normal.make), + ~env, + ~values=_, ), - ], + ) + ->E.R2.fmap(Wrappers.evDistribution) ) ], ) ``` -The Function name is just there for future documentation. The function defintions +The Function name is just there for future documentation. ## Key Files **FunctionRegistry_Core** -Key types, internal functionality, and a `Registry` module with a `matchAndRun` function to call function definitions. +Key types, internal functionality, and a `Registry` module with a `call` function to call function definitions. **FunctionRegistry_Library** A list of all the Functions defined in the Function Registry. @@ -45,4 +43,4 @@ A list of all the Functions defined in the Function Registry. The definition arrays are stored in `FR_*` modules, by convention. **FunctionRegistry_Helpers** -A list of helper functions for the FunctionRegistry_Library. +A list of helper functions for the `FunctionRegistry_Library`. diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs.res deleted file mode 100644 index 640f010a..00000000 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs.res +++ /dev/null @@ -1 +0,0 @@ -module Eval = Reducer_MathJs_Eval diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Eval.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Eval.res deleted file mode 100644 index 30cb2014..00000000 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_MathJs/Reducer_MathJs_Eval.res +++ /dev/null @@ -1,27 +0,0 @@ -module JavaScript = Reducer_Js -open ReducerInterface_InternalExpressionValue -open Reducer_ErrorValue - -@module("mathjs") external dummy_: string => unit = "evaluate" -let dummy1_ = dummy_ //Deceive the compiler to make the import although we wont make a call from rescript. Otherwise the optimizer deletes the import - -type answer = {"value": unit} - -/* - The result has to be delivered in an object so that we can type cast. - Rescript cannot type cast on basic values passed on their own. - This is why we call evalua inside Javascript and wrap the result in an Object - */ -let eval__: string => 'a = %raw(`function (expr) { return {value: Mathjs.evaluate(expr)}; }`) - -/* - Call MathJs evaluate and return as a variant -*/ -let eval = (expr: string): result => { - try { - let answer = eval__(expr) - answer["value"]->JavaScript.Gate.jsToIEv - } catch { - | Js.Exn.Error(obj) => REJavaScriptExn(Js.Exn.message(obj), Js.Exn.name(obj))->Error - } -} diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface.res index d19b93b3..5153e413 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface.res @@ -1,3 +1,2 @@ -module ExternalLibrary = ReducerInterface_ExternalLibrary module InternalExpressionValue = ReducerInterface_InternalExpressionValue module StdLib = ReducerInterface_StdLib diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res deleted file mode 100644 index 0922c8a7..00000000 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res +++ /dev/null @@ -1,35 +0,0 @@ -module InternalExpressionValue = ReducerInterface_InternalExpressionValue - -/* - Map external calls of Reducer -*/ -let dispatch = ( - call: InternalExpressionValue.functionCall, - environment: Reducer_T.environment, - reducer: Reducer_T.reducerFn, - chain, -): result => { - E.A.O.firstSomeFn([// () => ReducerInterface_GenericDistribution.dispatch(call, environment), - // () => ReducerInterface_Date.dispatch(call, environment), - // () => ReducerInterface_Duration.dispatch(call, environment), - // () => ReducerInterface_Number.dispatch(call, environment), - // () => FunctionRegistry_Library.dispatch(call, environment, reducer), - ])->E.O2.defaultFn(() => chain(call, environment, reducer)) -} - -/* -If your dispatch is too big you can divide it into smaller dispatches and pass the call so that it gets called finally. - -The final chain(call) invokes the builtin default functions of the interpreter. - -Via chain(call), all MathJs operators and functions are available for string, number, boolean, array and record - .e.g + - / * > >= < <= == /= not and or sin cos log ln concat, etc. - -// See https://mathjs.org/docs/expressions/syntax.html -// See https://mathjs.org/docs/reference/functions.html - -Remember from the users point of view, there are no different modules: -// "doSth( constructorType1 )" -// "doSth( constructorType2 )" -doSth gets dispatched to the correct module because of the type signature. You get function and operator abstraction for free. You don't need to combine different implementations into one type. That would be duplicating the repsonsibility of the dispatcher. -*/ diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res index 18957474..f619d488 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res @@ -1,11 +1,13 @@ exception ErrorException = Reducer_ErrorValue.ErrorException let internalStdLib: Reducer_T.namespace = { + // constants let res = Reducer_Namespace.make() ->Reducer_Namespace.mergeFrom(SquiggleLibrary_Math.make()) ->Reducer_Namespace.mergeFrom(SquiggleLibrary_Versions.make()) + // array and record lookups let res = res->Reducer_Namespace.set( "$_atIndex_$", Reducer_Expression_Lambda.makeFFILambda((inputs, _, _) => { @@ -32,6 +34,7 @@ let internalStdLib: Reducer_T.namespace = { })->Reducer_T.IEvLambda, ) + // some lambdas can't be expressed in function registry (e.g. `mx` with its variadic number of parameters) let res = FunctionRegistry_Library.nonRegistryLambdas->Belt.Array.reduce(res, ( cur, (name, lambda), @@ -39,15 +42,7 @@ let internalStdLib: Reducer_T.namespace = { cur->Reducer_Namespace.set(name, lambda->Reducer_T.IEvLambda) }) - // Reducer_Dispatch_BuiltIn: - - // [ ] | (_, [IEvBool(_)]) - // [ ] | (_, [IEvNumber(_)]) - // [ ] | (_, [IEvString(_)]) - // [ ] | (_, [IEvBool(_), IEvBool(_)]) - // [ ] | (_, [IEvNumber(_), IEvNumber(_)]) - // [ ] | (_, [IEvString(_), IEvString(_)]) => callMathJs(call) - + // bind the entire FunctionRegistry let res = FunctionRegistry_Library.registry ->FunctionRegistry_Core.Registry.allNames diff --git a/packages/squiggle-lang/src/rescript/shims/Js.shim.ts b/packages/squiggle-lang/src/rescript/shims/Js.shim.ts deleted file mode 100644 index 76f971a3..00000000 --- a/packages/squiggle-lang/src/rescript/shims/Js.shim.ts +++ /dev/null @@ -1 +0,0 @@ -export type Dict_t = { [key: string]: T }; From 674213360caa7facfa1cf92e0f35f15df08e5c31 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Mon, 19 Sep 2022 22:00:01 +0400 Subject: [PATCH 22/46] trim lodash usage, remove unused module --- .../squiggle-lang/__tests__/Lodash_test.res | 20 ------------------- .../squiggle-lang/src/js/SqPointSetDist.ts | 4 ++-- .../Distributions/SampleSetDist/KdeLibrary.js | 13 ++++++------ .../src/rescript/Utility/Lodash.res | 5 ----- packages/squiggle-lang/tsconfig.json | 3 ++- 5 files changed, 11 insertions(+), 34 deletions(-) delete mode 100644 packages/squiggle-lang/__tests__/Lodash_test.res delete mode 100644 packages/squiggle-lang/src/rescript/Utility/Lodash.res diff --git a/packages/squiggle-lang/__tests__/Lodash_test.res b/packages/squiggle-lang/__tests__/Lodash_test.res deleted file mode 100644 index f0782019..00000000 --- a/packages/squiggle-lang/__tests__/Lodash_test.res +++ /dev/null @@ -1,20 +0,0 @@ -open Jest -open Expect - -let makeTest = (~only=false, str, item1, item2) => - only - ? Only.test(str, () => expect(item1)->toEqual(item2)) - : test(str, () => expect(item1)->toEqual(item2)) - -describe("Lodash", () => - describe("Lodash", () => { - makeTest("min", Lodash.min([1, 3, 4]), 1) - makeTest("max", Lodash.max([1, 3, 4]), 4) - makeTest("uniq", Lodash.uniq([1, 3, 4, 4]), [1, 3, 4]) - makeTest( - "countBy", - Lodash.countBy([1, 3, 4, 4], r => r), - Js.Dict.fromArray([("1", 1), ("3", 1), ("4", 2)]), - ) - }) -) diff --git a/packages/squiggle-lang/src/js/SqPointSetDist.ts b/packages/squiggle-lang/src/js/SqPointSetDist.ts index 524c9319..19a6b178 100644 --- a/packages/squiggle-lang/src/js/SqPointSetDist.ts +++ b/packages/squiggle-lang/src/js/SqPointSetDist.ts @@ -1,4 +1,4 @@ -import * as _ from "lodash"; +import zipWith from "lodash/zipWith"; import { wrapDistribution } from "./SqDistribution"; import * as RSPointSetDist from "../rescript/ForTS/ForTS_Distribution/ForTS_Distribution_PointSetDistribution.gen"; import { pointSetDistributionTag as Tag } from "../rescript/ForTS/ForTS_Distribution/ForTS_Distribution_PointSetDistribution_tag"; @@ -16,7 +16,7 @@ const shapePoints = ( ): SqPoint[] => { let xs = x.xyShape.xs; let ys = x.xyShape.ys; - return _.zipWith(xs, ys, (x, y) => ({ x, y })); + return zipWith(xs, ys, (x, y) => ({ x, y })); }; export const wrapPointSetDist = (value: T) => { diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/KdeLibrary.js b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/KdeLibrary.js index 9cc75b39..e9592745 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/KdeLibrary.js +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/KdeLibrary.js @@ -1,5 +1,6 @@ const pdfast = require("pdfast"); -const _ = require("lodash"); +const filter = require("lodash/filter"); +const isFinite = require("lodash/isFinite"); const samplesToContinuousPdf = ( samples, @@ -8,12 +9,12 @@ const samplesToContinuousPdf = ( min = false, max = false ) => { - let _samples = _.filter(samples, _.isFinite); - if (_.isFinite(min)) { - _samples = _.filter(_samples, (r) => r > min); + let _samples = filter(samples, isFinite); + if (isFinite(min)) { + _samples = filter(_samples, (r) => r > min); } - if (_.isFinite(max)) { - _samples = _.filter(_samples, (r) => r < max); + if (isFinite(max)) { + _samples = filter(_samples, (r) => r < max); } // The pdf that's created from this function is not a pdf but a pmf. y values diff --git a/packages/squiggle-lang/src/rescript/Utility/Lodash.res b/packages/squiggle-lang/src/rescript/Utility/Lodash.res deleted file mode 100644 index d4359408..00000000 --- a/packages/squiggle-lang/src/rescript/Utility/Lodash.res +++ /dev/null @@ -1,5 +0,0 @@ -@module("lodash") external min: array<'a> => 'a = "min" -@module("lodash") external max: array<'a> => 'a = "max" -@module("lodash") external uniq: array<'a> => array<'a> = "uniq" -@module("lodash") -external countBy: (array<'a>, 'a => 'b) => Js.Dict.t = "countBy" diff --git a/packages/squiggle-lang/tsconfig.json b/packages/squiggle-lang/tsconfig.json index b9433729..92350eb1 100644 --- a/packages/squiggle-lang/tsconfig.json +++ b/packages/squiggle-lang/tsconfig.json @@ -12,7 +12,8 @@ "declarationDir": "./dist", "declaration": true, "composite": true, - "target": "ES6" + "target": "ES6", + "esModuleInterop": true }, "include": ["src/**/*"], "exclude": ["node_modules", "**/*.spec.ts", "webpack.config.js"] From b24cfbc3284076de697c3c608d4cdff787525a3e Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Mon, 19 Sep 2022 23:10:09 +0400 Subject: [PATCH 23/46] cleanups; ReducerInterface is no more --- .../__tests__/Reducer/Reducer_Helpers.res | 9 --- .../Reducer_Peggy_TestHelpers.res | 4 +- ...cer_Peggy_ToExpression_outerBlock_test.res | 3 - .../Reducer_Peggy_ToExpression_test.res | 5 +- .../__tests__/Reducer/Reducer_TestHelpers.res | 6 +- .../Reducer_Type_Compile_test.res | 3 +- ...educer_Type_TypeChecker_arguments_test.res | 2 - .../Reducer_Type_TypeChecker_test.res | 1 - .../Reducer_Type_switch_replacement_test.res | 12 ++-- .../ReducerInterface_ExpressionValue_test.res | 9 ++- .../ReducerProject_includes_test.res | 2 - .../ReducerProject/ReducerProject_test.res | 5 +- .../ReducerProject_tutorial_1_test.res | 17 +++--- ...cerProject_tutorial_2_multisource_test.res | 13 ++--- ...educerProject_tutorial_3_includes_test.res | 5 +- ...oject_tutorial_4_injecting_user_values.res | 4 +- ...erProject_tutorial_5_calling_functions.res | 3 +- ...leLibrary_FunctionRegistryLibrary_test.res | 3 +- .../src/rescript/FR/FR_Builtin.res | 10 ++-- .../squiggle-lang/src/rescript/FR/FR_Date.res | 2 +- .../squiggle-lang/src/rescript/FR/FR_Dict.res | 16 ++--- .../squiggle-lang/src/rescript/FR/FR_Dist.res | 2 +- .../squiggle-lang/src/rescript/FR/FR_Fn.res | 2 +- .../src/rescript/FR/FR_GenericDist.res | 18 +++--- .../squiggle-lang/src/rescript/FR/FR_List.res | 16 ++--- .../src/rescript/FR/FR_Pointset.res | 8 +-- .../src/rescript/FR/FR_Sampleset.res | 24 ++++---- .../ForTS_Distribution/ForTS_Distribution.res | 2 +- .../ForTS_SquiggleValue.res | 4 +- .../ForTS_SquiggleValue_Array.res | 4 +- .../ForTS_SquiggleValue_Declaration.res | 2 +- .../ForTS_SquiggleValue_Distribution.res | 2 +- .../ForTS_SquiggleValue_Lambda.res | 2 +- .../ForTS_SquiggleValue_Record.res | 4 +- .../ForTS_SquiggleValue_Type.res | 4 +- .../FunctionRegistry_Core.res | 23 ++++---- .../src/rescript/Reducer/Reducer_Bindings.res | 1 - .../src/rescript/Reducer/Reducer_Context.res | 7 +-- .../Reducer_Dispatch_ChainPiece.res | 2 +- .../Reducer_Dispatch/Reducer_Dispatch_T.res | 5 +- .../Reducer_Expression/Reducer_Expression.res | 2 +- .../Reducer_Expression_Lambda.res | 4 +- .../Reducer_Expression_T.res | 4 +- .../Reducer/Reducer_Js/Reducer_Js.res | 1 - .../Reducer/Reducer_Js/Reducer_Js_Gate.res | 17 ------ .../rescript/Reducer/Reducer_Namespace.res | 2 +- .../Reducer_Type/Reducer_Type_Compile.res | 5 +- .../Reducer_Type/Reducer_Type_Contracts.res | 17 +++--- .../Reducer/Reducer_Type/Reducer_Type_T.res | 31 +++++----- .../Reducer_Type/Reducer_Type_TypeChecker.res | 25 ++++---- .../Reducer_Value.res} | 4 -- .../ReducerInterface/ReducerInterface.res | 2 - .../ReducerProject/ReducerProject.res | 9 ++- .../ReducerProject_ProjectAccessors_T.res | 31 ---------- .../SquiggleLibrary_StdLib.res} | 2 +- .../src/rescript/TypescriptInterface.res | 58 ------------------- 56 files changed, 160 insertions(+), 320 deletions(-) delete mode 100644 packages/squiggle-lang/__tests__/Reducer/Reducer_Helpers.res delete mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js.res delete mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js_Gate.res rename packages/squiggle-lang/src/rescript/{ReducerInterface/ReducerInterface_InternalExpressionValue.res => Reducer/Reducer_Value.res} (98%) delete mode 100644 packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface.res delete mode 100644 packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectAccessors_T.res rename packages/squiggle-lang/src/rescript/{ReducerInterface/ReducerInterface_StdLib.res => SquiggleLibrary/SquiggleLibrary_StdLib.res} (97%) delete mode 100644 packages/squiggle-lang/src/rescript/TypescriptInterface.res diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Helpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Helpers.res deleted file mode 100644 index 4bbeff17..00000000 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Helpers.res +++ /dev/null @@ -1,9 +0,0 @@ -// Reducer_Helpers -module ErrorValue = Reducer_ErrorValue -module InternalExpressionValue = ReducerInterface.InternalExpressionValue - -let removeDefaultsInternal = (iev: InternalExpressionValue.t) => { - iev // TODO - cleanup, noop -} - -let rRemoveDefaultsInternal = r => Belt.Result.map(r, removeDefaultsInternal) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_TestHelpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_TestHelpers.res index 303f66ee..0dadae86 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_TestHelpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_TestHelpers.res @@ -1,6 +1,5 @@ module Expression = Reducer_Expression module ExpressionT = Reducer_Expression_T -module ExpressionValue = ReducerInterface.InternalExpressionValue module Parse = Reducer_Peggy_Parse module Result = Belt.Result module ToExpression = Reducer_Peggy_ToExpression @@ -24,8 +23,7 @@ let expectToExpressionToBe = (expr, answer, ~v="_", ()) => { let a2 = rExpr ->Result.flatMap(expr => Expression.BackCompatible.evaluate(expr)) - ->Reducer_Helpers.rRemoveDefaultsInternal - ->ExpressionValue.toStringResultOkless + ->Reducer_Value.toStringResultOkless (a1, a2)->expect->toEqual((answer, v)) } } diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_outerBlock_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_outerBlock_test.res index 03ef24c8..80f93fdc 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_outerBlock_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_outerBlock_test.res @@ -1,6 +1,3 @@ -module Bindings = Reducer_Bindings -module InternalExpressionValue = ReducerInterface_InternalExpressionValue - open Jest open Reducer_Peggy_TestHelpers diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_test.res index 3016e3c2..cab84681 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_test.res @@ -1,5 +1,4 @@ module Bindings = Reducer_Bindings -module InternalExpressionValue = ReducerInterface_InternalExpressionValue open Jest open Reducer_Peggy_TestHelpers @@ -144,9 +143,9 @@ describe("Peggy to Expression", () => { describe("module", () => { // testToExpression("Math.pi", "{:Math.pi}", ~v="3.141592653589793", ()) // Only.test("stdlibrary", () => { - // ReducerInterface_StdLib.internalStdLib + // SquiggleLibrary_StdLib.stdLib // ->IEvBindings - // ->InternalExpressionValue.toString + // ->Reducer_Value.toString // ->expect // ->toBe("") // }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res index e9057671..5d335556 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res @@ -1,7 +1,6 @@ module ErrorValue = Reducer_ErrorValue module Expression = Reducer_Expression module ExpressionT = Reducer_Expression_T -module InternalExpressionValue = ReducerInterface.InternalExpressionValue open Jest open Expect @@ -19,14 +18,13 @@ let expectParseToBe = (code: string, answer: string) => let expectEvalToBe = (code: string, answer: string) => Expression.BackCompatible.evaluateString(code) - ->Reducer_Helpers.rRemoveDefaultsInternal - ->InternalExpressionValue.toStringResult + ->Reducer_Value.toStringResult ->expect ->toBe(answer) let expectEvalError = (code: string) => Expression.BackCompatible.evaluateString(code) - ->InternalExpressionValue.toStringResult + ->Reducer_Value.toStringResult ->expect ->toMatch("Error\(") diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_Compile_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_Compile_test.res index 8abf5f7a..4c0812fd 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_Compile_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_Compile_test.res @@ -1,5 +1,4 @@ // module Expression = Reducer_Expression -// module InternalExpressionValue = ReducerInterface_InternalExpressionValue // module Bindings = Reducer_Bindings // module T = Reducer_Type_T // module TypeCompile = Reducer_Type_Compile @@ -10,7 +9,7 @@ // let myIevEval = (aTypeSourceCode: string) => // TypeCompile.ievFromTypeExpression(aTypeSourceCode, Expression.reduceExpressionInProject) // let myIevEvalToString = (aTypeSourceCode: string) => -// myIevEval(aTypeSourceCode)->InternalExpressionValue.toStringResult +// myIevEval(aTypeSourceCode)->Reducer_Value.toStringResult // let myIevExpectEqual = (aTypeSourceCode, answer) => // expect(myIevEvalToString(aTypeSourceCode))->toEqual(answer) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res index 64f2554a..723ff00b 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res @@ -1,8 +1,6 @@ // module Bindings = Reducer_Bindings // module ErrorValue = Reducer_ErrorValue // module Expression = Reducer_Expression -// module ExpressionT = Reducer_Expression_T -// module InternalExpressionValue = ReducerInterface_InternalExpressionValue // module ProjectAccessorsT = ReducerProject_ProjectAccessors_T // module T = Reducer_Type_T // module TypeChecker = Reducer_Type_TypeChecker diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res index c4272880..5f59c60a 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res @@ -1,7 +1,6 @@ // module Expression = Reducer_Expression // module ExpressionT = Reducer_Expression_T // module ErrorValue = Reducer_ErrorValue -// module InternalExpressionValue = ReducerInterface_InternalExpressionValue // module Bindings = Reducer_Bindings // module T = Reducer_Type_T // module TypeChecker = Reducer_Type_TypeChecker diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_switch_replacement_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_switch_replacement_test.res index 88f3d9a6..fcba831d 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_switch_replacement_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_switch_replacement_test.res @@ -8,15 +8,13 @@ // module TypeChecker = Reducer_Type_TypeChecker // module TypeCompile = Reducer_Type_Compile -// open ReducerInterface_InternalExpressionValue - // type errorValue = Reducer_ErrorValue.errorValue // // Let's build a function to replace switch statements // // In dispatchChainPiece, we execute an return the result of execution if there is a type match. // // Otherwise we return None so that the call chain can continue. // // So we want to build a function like -// // dispatchChainPiece = (call: functionCall, accessors): option> +// // dispatchChainPiece = (call: functionCall, accessors): option> // // Use accessors.environment to get the environment finally. // // Now lets make the dispatchChainPiece itself. @@ -28,9 +26,9 @@ // module Implementation = { // let stringConcat = (a: string, b: string): string => Js.String2.concat(a, b) // let arrayConcat = ( -// a: Js.Array2.t, -// b: Js.Array2.t, -// ): Js.Array2.t => Js.Array2.concat(a, b) +// a: Js.Array2.t, +// b: Js.Array2.t, +// ): Js.Array2.t => Js.Array2.concat(a, b) // let plot = _r => "yey, plotted" // } @@ -104,7 +102,7 @@ // accessors: ProjectAccessorsT.t, // reducer: Reducer_T.reducerFn, // chain, -// ): result => { +// ): result => { // let dispatchChainPiece = makeMyDispatchChainPiece(reducer) // dispatchChainPiece(call, accessors)->E.O2.defaultFn(() => chain(call, accessors, reducer)) // } diff --git a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_ExpressionValue_test.res b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_ExpressionValue_test.res index 71fd9f61..31054a67 100644 --- a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_ExpressionValue_test.res +++ b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_ExpressionValue_test.res @@ -1,11 +1,14 @@ -open ReducerInterface.InternalExpressionValue open Jest open Expect describe("ExpressionValue", () => { - test("argsToString", () => expect([IEvNumber(1.), IEvString("a")]->argsToString)->toBe("1,'a'")) + test("argsToString", () => expect( + [IEvNumber(1.), IEvString("a")]->Reducer_Value.argsToString)->toBe("1,'a'") + ) test("toStringFunctionCall", () => - expect(("fn", [IEvNumber(1.), IEvString("a")])->toStringFunctionCall)->toBe("fn(1,'a')") + expect( + ("fn", [IEvNumber(1.), IEvString("a")])->Reducer_Value.toStringFunctionCall)->toBe("fn(1,'a')" + ) ) }) diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res index 3d1fcddc..07660044 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res @@ -1,7 +1,5 @@ @@warning("-44") -module InternalExpressionValue = ReducerInterface_InternalExpressionValue module Project = ForTS_ReducerProject -module Bindings = Reducer_Bindings open Jest open Expect diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res index d85d636c..aee917a3 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res @@ -1,5 +1,4 @@ @@warning("-44") -module InternalExpressionValue = ReducerInterface_InternalExpressionValue module Project = ForTS_ReducerProject module Bindings = Reducer_Bindings @@ -9,12 +8,12 @@ open Expect.Operators let runFetchResult = (project, sourceId) => { Project.run(project, sourceId) - Project.getResult(project, sourceId)->InternalExpressionValue.toStringResult + Project.getResult(project, sourceId)->Reducer_Value.toStringResult } let runFetchFlatBindings = (project, sourceId) => { Project.run(project, sourceId) - Project.getBindings(project, sourceId)->InternalExpressionValue.toStringRecord + Project.getBindings(project, sourceId)->Reducer_Value.toStringRecord } test("test result true", () => { diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_test.res index 13cab7aa..fec3ee66 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_test.res @@ -1,5 +1,4 @@ @@warning("-44") -module InternalExpressionValue = ReducerInterface_InternalExpressionValue module Project = ForTS_ReducerProject module Bindings = Reducer_Bindings @@ -50,8 +49,8 @@ Case "Running a single source". /* Let's display the result and bindings */ ( - result->InternalExpressionValue.toStringResult, - bindings->InternalExpressionValue.toStringRecord, + result->Reducer_Value.toStringResult, + bindings->Reducer_Value.toStringRecord, )->expect == ("Ok(3)", "{}") /* You've got 3 with empty bindings. */ }) @@ -64,8 +63,8 @@ Case "Running a single source". let bindings = project->Project.getBindings("main") /* Now you have external bindings and external result. */ ( - result->InternalExpressionValue.toStringResult, - bindings->Reducer_T.IEvRecord->InternalExpressionValue.toString, + result->Reducer_Value.toStringResult, + bindings->Reducer_T.IEvRecord->Reducer_Value.toString, )->expect == ("Ok(3)", "{}") }) @@ -74,13 +73,13 @@ Case "Running a single source". let project = Project.createProject() /* Optional. Set your custom environment anytime before running */ - project->Project.setEnvironment(InternalExpressionValue.defaultEnvironment) + project->Project.setEnvironment(Reducer_Context.defaultEnvironment) project->Project.setSource("main", "1 + 2") project->Project.runAll let result = project->Project.getResult("main") let _bindings = project->Project.getBindings("main") - result->InternalExpressionValue.toStringResult->expect == "Ok(3)" + result->Reducer_Value.toStringResult->expect == "Ok(3)" }) test("shortcut", () => { @@ -88,8 +87,8 @@ Case "Running a single source". /* Examples above was to prepare you for the multi source tutorial. */ let (result, bindings) = Project.evaluate("1+2") ( - result->InternalExpressionValue.toStringResult, - bindings->InternalExpressionValue.toStringRecord, + result->Reducer_Value.toStringResult, + bindings->Reducer_Value.toStringRecord, )->expect == ("Ok(3)", "{}") }) }) diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_multisource_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_multisource_test.res index d50ec544..b2c3738a 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_multisource_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_multisource_test.res @@ -1,5 +1,4 @@ @@warning("-44") -module InternalExpressionValue = ReducerInterface_InternalExpressionValue module Project = ForTS_ReducerProject module Bindings = Reducer_Bindings @@ -32,8 +31,8 @@ describe("ReducerProject Tutorial", () => { let bindings3 = project->Project.getBindings("source3") ( - result3->InternalExpressionValue.toStringResult, - bindings3->InternalExpressionValue.toStringRecord, + result3->Reducer_Value.toStringResult, + bindings3->Reducer_Value.toStringRecord, )->expect == ("Ok(())", "{z: 3}") }) @@ -58,8 +57,8 @@ describe("ReducerProject Tutorial", () => { let bindings3 = project->Project.getBindings("source3") ( - result3->InternalExpressionValue.toStringResult, - bindings3->InternalExpressionValue.toStringRecord, + result3->Reducer_Value.toStringResult, + bindings3->Reducer_Value.toStringRecord, )->expect == ("Ok(())", "{z: 3}") }) @@ -93,8 +92,8 @@ describe("ReducerProject Tutorial", () => { let bindings3 = project->Project.getBindings("source3") ( - result3->InternalExpressionValue.toStringResult, - bindings3->InternalExpressionValue.toStringRecord, + result3->Reducer_Value.toStringResult, + bindings3->Reducer_Value.toStringRecord, )->expect == ("Ok(())", "{z: 3}") /* Doing it like this is too verbose for a storybook diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_3_includes_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_3_includes_test.res index 8e584576..e5af0e3f 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_3_includes_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_3_includes_test.res @@ -1,5 +1,4 @@ @@warning("-44") -module InternalExpressionValue = ReducerInterface_InternalExpressionValue module Project = ForTS_ReducerProject module Bindings = Reducer_Bindings @@ -146,8 +145,8 @@ Here we will finally proceed to a real life scenario. */ /* And see the result and bindings.. */ test("recursive includes", () => { ( - result->InternalExpressionValue.toStringResult, - bindings->InternalExpressionValue.toStringRecord, + result->Reducer_Value.toStringResult, + bindings->Reducer_Value.toStringRecord, )->expect == ("Ok(6)", "{a: 6,b: 2}") /* Everything as expected */ }) diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_4_injecting_user_values.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_4_injecting_user_values.res index 38d655c1..507e12cc 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_4_injecting_user_values.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_4_injecting_user_values.res @@ -1,7 +1,5 @@ @@warning("-44") -module InternalExpressionValue = ReducerInterface_InternalExpressionValue module Project = ForTS_ReducerProject -module Bindings = Reducer_Bindings open Jest open Expect @@ -30,7 +28,7 @@ describe("ReducerProject Tutorial", () => { /* We can now run the project */ Project.runAll(project) let result = Project.getResult(project, "main") - result->InternalExpressionValue.toStringResult->expect == "Ok(6)" + result->Reducer_Value.toStringResult->expect == "Ok(6)" }) }) diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_5_calling_functions.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_5_calling_functions.res index 7e2471b5..35643c77 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_5_calling_functions.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_5_calling_functions.res @@ -1,5 +1,4 @@ @@warning("-44") -module InternalExpressionValue = ReducerInterface_InternalExpressionValue module Project = ForTS_ReducerProject module Bindings = Reducer_Bindings @@ -32,7 +31,7 @@ describe("ReducerProject Tutorial", () => { test("userResults", () => { let userResultsAsString = Belt.Array.map(userResults, aResult => - aResult->InternalExpressionValue.toStringResult + aResult->Reducer_Value.toStringResult ) userResultsAsString->expect == ["Ok(2)", "Ok(4)", "Ok(6)", "Ok(8)", "Ok(10)"] }) diff --git a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res index 95fdbdf6..da4788e5 100644 --- a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res +++ b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res @@ -4,7 +4,6 @@ open Reducer_TestHelpers let expectEvalToBeOk = (code: string) => Reducer_Expression.BackCompatible.evaluateString(code) - ->Reducer_Helpers.rRemoveDefaultsInternal ->E.R.isOk ->expect ->toBe(true) @@ -102,7 +101,7 @@ describe("FunctionRegistry Library", () => { let responseType = example ->Reducer_Expression.BackCompatible.evaluateString - ->E.R2.fmap(ReducerInterface_InternalExpressionValue.valueToValueType) + ->E.R2.fmap(Reducer_Value.valueToValueType) let expectedOutputType = fn.output |> E.O.toExn("") expect(responseType)->toEqual(Ok(expectedOutputType)) }, diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Builtin.res b/packages/squiggle-lang/src/rescript/FR/FR_Builtin.res index e346075d..e0bc776a 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Builtin.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Builtin.res @@ -5,7 +5,7 @@ let nameSpace = "" // no namespaced versions type simpleDefinition = { inputs: array, - fn: array => result, + fn: array => result, } let makeFnMany = (name: string, definitions: array) => @@ -22,7 +22,7 @@ let makeFnMany = (name: string, definitions: array) => let makeFn = ( name: string, inputs: array, - fn: array => result, + fn: array => result, ) => makeFnMany(name, [{inputs: inputs, fn: fn}]) let library = [ @@ -140,7 +140,7 @@ let library = [ makeFn("inspect", [FRTypeAny], inputs => { switch inputs { | [value] => { - Js.log(value->ReducerInterface_InternalExpressionValue.toString) + Js.log(value->Reducer_Value.toString) value->Ok } | _ => Error(impossibleError) @@ -149,7 +149,7 @@ let library = [ makeFn("inspect", [FRTypeAny, FRTypeString], inputs => { switch inputs { | [value, IEvString(label)] => { - Js.log(`${label}: ${value->ReducerInterface_InternalExpressionValue.toString}`) + Js.log(`${label}: ${value->Reducer_Value.toString}`) value->Ok } | _ => Error(impossibleError) @@ -158,7 +158,7 @@ let library = [ makeFn("javascriptraise", [FRTypeAny], inputs => { switch inputs { | [msg] => { - Js.Exn.raiseError(msg->ReducerInterface_InternalExpressionValue.toString) + Js.Exn.raiseError(msg->Reducer_Value.toString) } | _ => Error(impossibleError) } diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Date.res b/packages/squiggle-lang/src/rescript/FR/FR_Date.res index 96f94b9d..bf7e2120 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Date.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Date.res @@ -4,7 +4,7 @@ open FunctionRegistry_Helpers let makeFn = ( name: string, inputs: array, - fn: array => result, + fn: array => result, ) => Function.make( ~name, diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Dict.res b/packages/squiggle-lang/src/rescript/FR/FR_Dict.res index 310d295d..c8a82b9c 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Dict.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Dict.res @@ -6,24 +6,24 @@ let nameSpace = "Dict" module Internals = { type t = Reducer_T.map - let keys = (a: t): internalExpressionValue => IEvArray( + let keys = (a: t): Reducer_T.value => IEvArray( Belt.Map.String.keysToArray(a)->E.A2.fmap(Wrappers.evString), ) - let values = (a: t): internalExpressionValue => IEvArray(Belt.Map.String.valuesToArray(a)) + let values = (a: t): Reducer_T.value => IEvArray(Belt.Map.String.valuesToArray(a)) - let toList = (a: t): internalExpressionValue => + let toList = (a: t): Reducer_T.value => Belt.Map.String.toArray(a) ->E.A2.fmap(((key, value)) => Wrappers.evArray([IEvString(key), value])) ->Wrappers.evArray - let fromList = (items: array): result< - internalExpressionValue, + let fromList = (items: array): result< + Reducer_T.value, errorValue, > => items ->E.A2.fmap(item => { - switch (item: internalExpressionValue) { + switch (item: Reducer_T.value) { | IEvArray([IEvString(string), value]) => (string, value)->Ok | _ => Error(impossibleError) } @@ -32,12 +32,12 @@ module Internals = { ->E.R2.fmap(Belt.Map.String.fromArray) ->E.R2.fmap(Wrappers.evRecord) - let merge = (a: t, b: t): internalExpressionValue => IEvRecord( + let merge = (a: t, b: t): Reducer_T.value => IEvRecord( Belt.Map.String.merge(a, b, (_, _, c) => c), ) //Belt.Map.String has a function for mergeMany, but I couldn't understand how to use it yet. - let mergeMany = (a: array): internalExpressionValue => { + let mergeMany = (a: array): Reducer_T.value => { let mergedValues = a->E.A2.fmap(Belt.Map.String.toArray)->Belt.Array.concatMany->Belt.Map.String.fromArray IEvRecord(mergedValues) diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Dist.res b/packages/squiggle-lang/src/rescript/FR/FR_Dist.res index 8482f3f8..1ee92c87 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Dist.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Dist.res @@ -4,7 +4,7 @@ let twoArgs = E.Tuple2.toFnCall module DistributionCreation = { let nameSpace = "Dist" - let output = ReducerInterface_InternalExpressionValue.EvtDistribution + let output = Reducer_Value.EvtDistribution let requiresNamespace = false let fnMake = (~name, ~examples, ~definitions) => { diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Fn.res b/packages/squiggle-lang/src/rescript/FR/FR_Fn.res index 44d8882b..86db7edc 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Fn.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Fn.res @@ -7,7 +7,7 @@ module Declaration = { ("inputs", FRTypeArray(FRTypeRecord([("min", FRTypeNumber), ("max", FRTypeNumber)]))), ]) - let fromExpressionValue = (e: frValue): result => { + let fromExpressionValue = (e: frValue): result => { switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.twoArgs([e]) { | Ok([FRValueLambda(lambda), FRValueArray(inputs)]) => { open FunctionRegistry_Helpers.Prepare diff --git a/packages/squiggle-lang/src/rescript/FR/FR_GenericDist.res b/packages/squiggle-lang/src/rescript/FR/FR_GenericDist.res index dc449ee4..93f720b4 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_GenericDist.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_GenericDist.res @@ -18,7 +18,7 @@ module Old = { | _ => #Multiply } - let catchAndConvertTwoArgsToDists = (args: array): option<( + let catchAndConvertTwoArgsToDists = (args: array): option<( DistributionTypes.genericDist, DistributionTypes.genericDist, )> => @@ -68,18 +68,18 @@ module Old = { )->DistributionOperation.run(~env) } - let parseNumber = (args: internalExpressionValue): Belt.Result.t => + let parseNumber = (args: Reducer_T.value): Belt.Result.t => switch args { | IEvNumber(x) => Ok(x) | _ => Error("Not a number") } - let parseNumberArray = (ags: array): Belt.Result.t< + 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< + let parseDist = (args: Reducer_T.value): Belt.Result.t< DistributionTypes.genericDist, string, > => @@ -89,7 +89,7 @@ module Old = { | _ => Error("Not a distribution") } - let parseDistributionArray = (ags: array): Belt.Result.t< + let parseDistributionArray = (ags: array): Belt.Result.t< array, string, > => E.A.fmap(parseDist, ags) |> E.A.R.firstErrorOrOpen @@ -115,7 +115,7 @@ module Old = { } let mixture = ( - args: array, + args: array, ~env: GenericDist.env, ): DistributionOperation.outputType => { let error = (err: string): DistributionOperation.outputType => @@ -174,7 +174,7 @@ module Old = { } let dispatchToGenericOutput = ( - call: ReducerInterface_InternalExpressionValue.functionCall, + call: Reducer_Value.functionCall, env: GenericDist.env, ): option => { let (fnName, args) = call @@ -301,7 +301,7 @@ module Old = { } let genericOutputToReducerValue = (o: DistributionOperation.outputType): result< - internalExpressionValue, + Reducer_T.value, Reducer_ErrorValue.errorValue, > => switch o { @@ -313,7 +313,7 @@ module Old = { | GenDistError(err) => Error(REDistributionError(err)) } - let dispatch = (call: ReducerInterface_InternalExpressionValue.functionCall, environment) => + let dispatch = (call: Reducer_Value.functionCall, environment) => switch dispatchToGenericOutput(call, environment) { | Some(o) => genericOutputToReducerValue(o) | None => diff --git a/packages/squiggle-lang/src/rescript/FR/FR_List.res b/packages/squiggle-lang/src/rescript/FR/FR_List.res index eb6a653a..9bc68847 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_List.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_List.res @@ -7,29 +7,29 @@ let requiresNamespace = true module Internals = { let makeFromNumber = ( n: float, - value: internalExpressionValue, - ): internalExpressionValue => IEvArray(Belt.Array.make(E.Float.toInt(n), value)) + value: Reducer_T.value, + ): Reducer_T.value => IEvArray(Belt.Array.make(E.Float.toInt(n), value)) - let upTo = (low: float, high: float): internalExpressionValue => IEvArray( + let upTo = (low: float, high: float): Reducer_T.value => IEvArray( E.A.Floats.range(low, high, (high -. low +. 1.0)->E.Float.toInt)->E.A2.fmap(Wrappers.evNumber), ) - let first = (v: array): result => + let first = (v: array): result => v->E.A.first |> E.O.toResult("No first element") - let last = (v: array): result => + let last = (v: array): result => v->E.A.last |> E.O.toResult("No last element") - let reverse = (array: array): internalExpressionValue => IEvArray( + let reverse = (array: array): Reducer_T.value => IEvArray( Belt.Array.reverse(array), ) let map = ( - array: array, + array: array, eLambdaValue, env: Reducer_T.environment, reducer: Reducer_T.reducerFn, - ): internalExpressionValue => { + ): Reducer_T.value => { Belt.Array.map(array, elem => Reducer_Expression_Lambda.doLambdaCall(eLambdaValue, [elem], env, reducer) )->Wrappers.evArray diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res b/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res index 61d03c9d..54b8706d 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res @@ -48,7 +48,7 @@ let library = [ ~nameSpace, ~requiresNamespace=true, ~examples=[`PointSet.fromDist(normal(5,2))`], - ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, + ~output=Reducer_Value.EvtDistribution, ~definitions=[ FnDefinition.make( ~name="fromDist", @@ -77,7 +77,7 @@ let library = [ ~nameSpace, ~requiresNamespace=true, ~examples=[`PointSet.mapY(mx(normal(5,2)), {|x| x + 1})`], - ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, + ~output=Reducer_Value.EvtDistribution, ~definitions=[ FnDefinition.make( ~name="mapY", @@ -105,7 +105,7 @@ let library = [ {x: 3, y: 0.2} ])`, ], - ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, + ~output=Reducer_Value.EvtDistribution, ~definitions=[ FnDefinition.make( ~name="makeContinuous", @@ -129,7 +129,7 @@ let library = [ {x: 3, y: 0.2} ])`, ], - ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, + ~output=Reducer_Value.EvtDistribution, ~definitions=[ FnDefinition.make( ~name="makeDiscrete", diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res b/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res index 4c04489b..228e8805 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res @@ -48,10 +48,10 @@ module Internal = { SampleSetDist.map3(~fn, ~t1, ~t2, ~t3)->toType } - let parseSampleSetArray = (arr: array): option< + let parseSampleSetArray = (arr: array): option< array, > => { - let parseSampleSet = (value: internalExpressionValue): option => + let parseSampleSet = (value: Reducer_T.value): option => switch value { | IEvDistribution(SampleSet(dist)) => Some(dist) | _ => None @@ -60,7 +60,7 @@ module Internal = { } let mapN = ( - aValueArray: array, + aValueArray: array, aLambdaValue, environment: Reducer_T.environment, reducer, @@ -86,7 +86,7 @@ let libaryBase = [ ~nameSpace, ~requiresNamespace=true, ~examples=[`SampleSet.fromDist(normal(5,2))`], - ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, + ~output=Reducer_Value.EvtDistribution, ~definitions=[ FnDefinition.make( ~name="fromDist", @@ -110,7 +110,7 @@ let libaryBase = [ ~nameSpace, ~requiresNamespace=true, ~examples=[`SampleSet.fromList([3,5,2,3,5,2,3,5,2,3,3,5,3,2,3,1,1,3])`], - ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, + ~output=Reducer_Value.EvtDistribution, ~definitions=[ FnDefinition.make( ~name="fromList", @@ -135,7 +135,7 @@ let libaryBase = [ ~nameSpace, ~requiresNamespace=true, ~examples=[`SampleSet.toList(SampleSet.fromDist(normal(5,2)))`], - ~output=ReducerInterface_InternalExpressionValue.EvtArray, + ~output=Reducer_Value.EvtArray, ~definitions=[ FnDefinition.make( ~name="toList", @@ -156,7 +156,7 @@ let libaryBase = [ ~nameSpace, ~requiresNamespace=true, ~examples=[`SampleSet.fromFn({|| sample(normal(5,2))})`], - ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, + ~output=Reducer_Value.EvtDistribution, ~definitions=[ FnDefinition.make( ~name="fromFn", @@ -180,7 +180,7 @@ let libaryBase = [ ~nameSpace, ~requiresNamespace, ~examples=[`SampleSet.map(SampleSet.fromDist(normal(5,2)), {|x| x + 1})`], - ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, + ~output=Reducer_Value.EvtDistribution, ~definitions=[ FnDefinition.make( ~name="map", @@ -203,7 +203,7 @@ let libaryBase = [ ~examples=[ `SampleSet.map2(SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(5,2)), {|x, y| x + y})`, ], - ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, + ~output=Reducer_Value.EvtDistribution, ~definitions=[ FnDefinition.make( ~name="map2", @@ -231,7 +231,7 @@ let libaryBase = [ ~examples=[ `SampleSet.map3(SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(5,2)), {|x, y, z| max([x,y,z])})`, ], - ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, + ~output=Reducer_Value.EvtDistribution, ~definitions=[ FnDefinition.make( ~name="map3", @@ -259,7 +259,7 @@ let libaryBase = [ ~examples=[ `SampleSet.mapN([SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(5,2)), SampleSet.fromDist(normal(5,2))], {|x| max(x)})`, ], - ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, + ~output=Reducer_Value.EvtDistribution, ~definitions=[ FnDefinition.make( ~name="mapN", @@ -306,7 +306,7 @@ module Comparison = { `SampleSet.${name}(SampleSet.fromDist(normal(5,2)), 3.0)`, `SampleSet.${name}(4.0, SampleSet.fromDist(normal(6,2)))`, ], - ~output=ReducerInterface_InternalExpressionValue.EvtDistribution, + ~output=Reducer_Value.EvtDistribution, ~definitions=[ template(name, [FRTypeDist, FRTypeDist], inputs => { switch inputs { diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution.res index 80824ba9..6701b580 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution.res @@ -8,7 +8,7 @@ type environment = ForTS_Distribution_Environment.environment //use @genType -let defaultEnvironment: environment = DistributionOperation.defaultEnv +let defaultEnvironment: environment = Reducer_Context.defaultEnvironment @module("./ForTS_Distribution_tag") @scope("distributionTag") external dtPointSet_: string = "PointSet" diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res index 07dccc50..0b6b9d93 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res @@ -74,13 +74,13 @@ let getTag = (variant: squiggleValue): squiggleValueTag => @genType let toString = (variant: squiggleValue) => - ReducerInterface_InternalExpressionValue.toString(variant) + Reducer_Value.toString(variant) // This is a useful method for unit tests. // Convert the result along with the error message to a string. @genType let toStringResult = (variantResult: result) => - ReducerInterface_InternalExpressionValue.toStringResult(variantResult) + Reducer_Value.toStringResult(variantResult) @genType let getArray = (variant: squiggleValue): option => diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Array.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Array.res index cfe128e7..823fde5c 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Array.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Array.res @@ -3,8 +3,8 @@ type squiggleValue = ForTS_SquiggleValue.squiggleValue @genType let getValues = (v: squiggleValue_Array): array => - ReducerInterface_InternalExpressionValue.arrayToValueArray(v) + Reducer_Value.arrayToValueArray(v) @genType let toString = (v: squiggleValue_Array): string => - ReducerInterface_InternalExpressionValue.toStringArray(v) + Reducer_Value.toStringArray(v) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Declaration.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Declaration.res index d7da5e1e..5c8eae49 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Declaration.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Declaration.res @@ -2,4 +2,4 @@ @genType let toString = (v: squiggleValue_Declaration): string => - ReducerInterface_InternalExpressionValue.toStringDeclaration(v) + Reducer_Value.toStringDeclaration(v) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Distribution.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Distribution.res index c346701c..b1d6b440 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Distribution.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Distribution.res @@ -2,4 +2,4 @@ @genType let toString = (v: squiggleValue_Distribution): string => - ReducerInterface_InternalExpressionValue.toStringDistribution(v) + Reducer_Value.toStringDistribution(v) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Lambda.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Lambda.res index ef4c460f..f6ec66d3 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Lambda.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Lambda.res @@ -2,7 +2,7 @@ @genType let toString = (v: squiggleValue_Lambda): string => - ReducerInterface_InternalExpressionValue.toStringFunction(v) + Reducer_Value.toStringFunction(v) @genType let parameters = (v: squiggleValue_Lambda): array => { diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Record.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Record.res index e145eefc..2f0d034a 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Record.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Record.res @@ -3,10 +3,10 @@ type squiggleValue = ForTS_SquiggleValue.squiggleValue //use @genType let getKeyValuePairs = (value: squiggleValue_Record): array<(string, squiggleValue)> => - ReducerInterface_InternalExpressionValue.recordToKeyValuePairs(value) + Reducer_Value.recordToKeyValuePairs(value) @genType -let toString = (v: squiggleValue_Record) => ReducerInterface_InternalExpressionValue.toStringMap(v) +let toString = (v: squiggleValue_Record) => Reducer_Value.toStringMap(v) @genType let toSquiggleValue = (v: squiggleValue_Record): squiggleValue => IEvRecord(v) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Type.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Type.res index 1399dcf4..0c002040 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Type.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Type.res @@ -3,8 +3,8 @@ type squiggleValue = ForTS_SquiggleValue.squiggleValue //use @genType let getKeyValuePairs = (value: squiggleValue_Type): array<(string, squiggleValue)> => - ReducerInterface_InternalExpressionValue.recordToKeyValuePairs(value) + Reducer_Value.recordToKeyValuePairs(value) @genType let toString = (value: squiggleValue_Type): string => - ReducerInterface_InternalExpressionValue.toStringType(value) + Reducer_Value.toStringType(value) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res index a5685f2e..901915e3 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res @@ -1,5 +1,4 @@ -type internalExpressionValue = Reducer_T.value -type internalExpressionValueType = ReducerInterface_InternalExpressionValue.internalExpressionValueType +type internalExpressionValueType = Reducer_Value.internalExpressionValueType type errorValue = Reducer_ErrorValue.errorValue /* @@ -51,11 +50,11 @@ type fnDefinition = { name: string, inputs: array, run: ( - array, + array, array, Reducer_T.environment, Reducer_T.reducerFn, - ) => result, + ) => result, } type function = { @@ -92,7 +91,7 @@ module FRType = { | FRTypeAny => `any` } - let rec toFrValue = (r: internalExpressionValue): option => + let rec toFrValue = (r: Reducer_T.value): option => // not all value variants are supported, but it's not important (we'll probably deprecate frValues soon anyway) switch r { | IEvNumber(f) => Some(FRValueNumber(f)) @@ -109,7 +108,7 @@ module FRType = { | _ => None } - let rec matchWithExpressionValue = (t: t, r: internalExpressionValue): option => + let rec matchWithExpressionValue = (t: t, r: Reducer_T.value): option => switch (t, r) { | (FRTypeAny, f) => toFrValue(f) | (FRTypeString, IEvString(f)) => Some(FRValueString(f)) @@ -149,7 +148,7 @@ module FRType = { | _ => None } - let rec matchReverse = (e: frValue): internalExpressionValue => + let rec matchReverse = (e: frValue): Reducer_T.value => switch e { | FRValueNumber(f) => IEvNumber(f) | FRValueBool(f) => IEvBool(f) @@ -182,7 +181,7 @@ module FRType = { let matchWithExpressionValueArray = ( inputs: array, - args: array, + args: array, ): option> => { let isSameLength = E.A.length(inputs) == E.A.length(args) if !isSameLength { @@ -203,7 +202,7 @@ module FnDefinition = { t.name ++ `(${inputs})` } - let isMatch = (t: t, args: array) => { + let isMatch = (t: t, args: array) => { let argValues = FRType.matchWithExpressionValueArray(t.inputs, args) switch argValues { | Some(_) => true @@ -213,7 +212,7 @@ module FnDefinition = { let run = ( t: t, - args: array, + args: array, env: Reducer_T.environment, reducer: Reducer_T.reducerFn, ) => { @@ -317,10 +316,10 @@ module Registry = { let call = ( registry, fnName: string, - args: array, + args: array, env: Reducer_T.environment, reducer: Reducer_T.reducerFn, - ): result => { + ): result => { switch Belt.Map.String.get(registry.fnNameDict, fnName) { | Some(definitions) => { let showNameMatchDefinitions = () => { diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings.res index 4ca31638..8311792b 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings.res @@ -5,7 +5,6 @@ */ type t = Reducer_T.bindings -type internalExpressionValue = Reducer_T.value let rec get = ({namespace, parent}: t, id: string) => { switch namespace->Reducer_Namespace.get(id) { diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res index f9b8a2c8..ff835e96 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res @@ -1,5 +1,7 @@ type t = Reducer_T.context +let defaultEnvironment: Reducer_T.environment = DistributionOperation.defaultEnv + let createContext = (stdLib: Reducer_Namespace.t, environment: Reducer_T.environment): t => { { bindings: stdLib->Reducer_Bindings.fromNamespace->Reducer_Bindings.extend, @@ -8,7 +10,4 @@ let createContext = (stdLib: Reducer_Namespace.t, environment: Reducer_T.environ } let createDefaultContext = (): t => - createContext( - ReducerInterface_StdLib.internalStdLib, - ReducerInterface_InternalExpressionValue.defaultEnvironment, - ) + createContext(SquiggleLibrary_StdLib.stdLib, defaultEnvironment) 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 ebeb7f43..f0506f8a 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 @@ -1,7 +1,7 @@ // module ProjectAccessorsT = ReducerProject_ProjectAccessors_T // module T = Reducer_Dispatch_T // module TypeChecker = Reducer_Type_TypeChecker -// open ReducerInterface_InternalExpressionValue +// open Reducer_Value // type errorValue = Reducer_ErrorValue.errorValue 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 a60a92b5..0d852783 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 @@ -1,15 +1,14 @@ -// module InternalExpressionValue = ReducerInterface_InternalExpressionValue // module ExpressionT = Reducer_Expression_T // module ProjectAccessorsT = ReducerProject_ProjectAccessors_T // // Each piece of the dispatch chain computes the result or returns None so that the chain can continue // type dispatchChainPiece = ( -// InternalExpressionValue.functionCall, +// Reducer_Value.functionCall, // ProjectAccessorsT.t, // ) => option> // type dispatchChainPieceWithReducer = ( -// InternalExpressionValue.functionCall, +// Reducer_Value.functionCall, // ProjectAccessorsT.t, // Reducer_T.reducerFn, // ) => option> 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 1bcdc030..e608036a 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 @@ -103,7 +103,7 @@ let rec evaluate: T.reducerFn = (expression, context): (T.value, T.context) => { context, ) | _ => - RENotAFunction(lambda->ReducerInterface_InternalExpressionValue.toString) + RENotAFunction(lambda->Reducer_Value.toString) ->Reducer_ErrorValue.ErrorException ->raise } 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 bb4e80c5..e9a85a1a 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 @@ -1,8 +1,5 @@ -module Bindings = Reducer_Bindings module ErrorValue = Reducer_ErrorValue -type internalExpressionValue = ReducerInterface_InternalExpressionValue.t - let doLambdaCall = ( lambdaValue: Reducer_T.lambdaValue, args, @@ -21,6 +18,7 @@ let makeLambda = ( // Note: with this implementation, FFI lambdas (created by other methods than calling `makeLambda`) are allowed to violate the rules, pollute the bindings, etc. // Not sure yet if that's a bug or a feature. + // FunctionRegistry functions are unaffected by this, their API is too limited. let lambda = ( arguments: array, 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 365d0836..71995c0a 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 @@ -2,8 +2,6 @@ An expression is an intermediate representation of a Squiggle code. Expressions are evaluated by `Reducer_Expression.evaluate` function. */ -module InternalExpressionValue = ReducerInterface_InternalExpressionValue - type t = Reducer_T.expression let commaJoin = values => values->Reducer_Extra_Array.intersperse(", ")->Js.String.concatMany("") @@ -27,7 +25,7 @@ let rec toString = (expression: t) => | EAssign(name, value) => `${name} = ${value->toString}` | ECall(fn, args) => `(${fn->toString})(${args->Js.Array2.map(toString)->commaJoin})` | ELambda(parameters, body) => `{|${parameters->commaJoin}| ${body->toString}}` - | EValue(aValue) => InternalExpressionValue.toString(aValue) + | EValue(aValue) => Reducer_Value.toString(aValue) } let toStringResult = codeResult => diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js.res deleted file mode 100644 index 8e7bd1f2..00000000 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js.res +++ /dev/null @@ -1 +0,0 @@ -module Gate = Reducer_Js_Gate diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js_Gate.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js_Gate.res deleted file mode 100644 index d7a267e2..00000000 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Js/Reducer_Js_Gate.res +++ /dev/null @@ -1,17 +0,0 @@ -open ReducerInterface_InternalExpressionValue -open Reducer_ErrorValue - -external castBool: unit => bool = "%identity" -external castNumber: unit => float = "%identity" -external castString: unit => string = "%identity" - -/* - As JavaScript returns us any type, we need to type check and cast type propertype before using it -*/ -let jsToIEv = (jsValue): result => - switch Js.typeof(jsValue) { - | "boolean" => jsValue->castBool->IEvBool->Ok - | "number" => jsValue->castNumber->IEvNumber->Ok - | "string" => jsValue->castString->IEvString->Ok - | other => RETodo(`Unhandled MathJs literal type: ${Js.String.make(other)}`)->Error - } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res index 5793fe07..14afae95 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res @@ -25,7 +25,7 @@ let toString = (namespace: t) => namespace ->Belt.Map.String.toArray ->Belt.Array.map(((eachKey, eachValue)) => - `${eachKey}: ${eachValue->ReducerInterface_InternalExpressionValue.toString}` + `${eachKey}: ${eachValue->Reducer_Value.toString}` ) ->Js.Array2.toString 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 5335ece7..2d636d2b 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 @@ -1,15 +1,12 @@ // module Bindings = Reducer_Bindings // module ErrorValue = Reducer_ErrorValue -// module Expression = Reducer_Expression -// module ExpressionT = Reducer_Expression_T -// module InternalExpressionValue = ReducerInterface_InternalExpressionValue // module ProjectAccessorsT = ReducerProject_ProjectAccessors_T // module T = Reducer_Type_T // let ievFromTypeExpression = ( // typeExpressionSourceCode: string, // reducerFn: ProjectReducerFnT.t, -// ): result => { +// ): result => { // let sIndex = "compiled" // let sourceCode = `type ${sIndex}=${typeExpressionSourceCode}` // Reducer_Expression.BackCompatible.parse(sourceCode)->Belt.Result.flatMap(expr => { diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Contracts.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Contracts.res index 7b68f178..8433ef22 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Contracts.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Contracts.res @@ -1,7 +1,6 @@ -module InternalExpressionValue = ReducerInterface_InternalExpressionValue module T = Reducer_Type_T -let isMin = (modifierArg: InternalExpressionValue.t, aValue: InternalExpressionValue.t): bool => { +let isMin = (modifierArg: Reducer_Value.t, aValue: Reducer_Value.t): bool => { let pair = (modifierArg, aValue) switch pair { | (IEvNumber(a), IEvNumber(b)) => a <= b @@ -9,7 +8,7 @@ let isMin = (modifierArg: InternalExpressionValue.t, aValue: InternalExpressionV } } -let isMax = (modifierArg: InternalExpressionValue.t, aValue: InternalExpressionValue.t): bool => { +let isMax = (modifierArg: Reducer_Value.t, aValue: Reducer_Value.t): bool => { let pair = (modifierArg, aValue) switch pair { | (IEvNumber(a), IEvNumber(b)) => a >= b @@ -18,8 +17,8 @@ let isMax = (modifierArg: InternalExpressionValue.t, aValue: InternalExpressionV } let isMemberOf = ( - modifierArg: InternalExpressionValue.t, - aValue: InternalExpressionValue.t, + modifierArg: Reducer_Value.t, + aValue: Reducer_Value.t, ): bool => { let pair = (modifierArg, aValue) switch pair { @@ -30,8 +29,8 @@ let isMemberOf = ( let checkModifier = ( key: string, - modifierArg: InternalExpressionValue.t, - aValue: InternalExpressionValue.t, + modifierArg: Reducer_Value.t, + aValue: Reducer_Value.t, ): bool => switch key { | "min" => isMin(modifierArg, aValue) @@ -41,8 +40,8 @@ let checkModifier = ( } let checkModifiers = ( - contracts: Belt.Map.String.t, - aValue: InternalExpressionValue.t, + contracts: Belt.Map.String.t, + aValue: Reducer_Value.t, ): bool => { contracts->Belt.Map.String.reduce(true, (acc, key, modifierArg) => switch acc { 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 e7bab837..8f293d53 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 @@ -1,9 +1,6 @@ -// module InternalExpressionValue = ReducerInterface_InternalExpressionValue -// open InternalExpressionValue - // type rec iType = // | ItTypeIdentifier(string) -// | ItModifiedType({modifiedType: iType, contracts: Belt.Map.String.t}) +// | ItModifiedType({modifiedType: iType, contracts: Belt.Map.String.t}) // | ItTypeOr({typeOr: array}) // | ItTypeFunction({inputs: array, output: iType}) // | ItTypeArray({element: iType}) @@ -11,14 +8,14 @@ // | ItTypeRecord({properties: Belt.Map.String.t}) // type t = iType -// type typeErrorValue = TypeMismatch(t, InternalExpressionValue.t) +// type typeErrorValue = TypeMismatch(t, Reducer_Value.t) // let rec toString = (t: t): string => { // switch t { // | ItTypeIdentifier(s) => s // | ItModifiedType({modifiedType, contracts}) => // `${toString(modifiedType)}${contracts->Belt.Map.String.reduce("", (acc, k, v) => -// Js.String2.concatMany(acc, ["<-", k, "(", InternalExpressionValue.toString(v), ")"]) +// Js.String2.concatMany(acc, ["<-", k, "(", Reducer_Value.toString(v), ")"]) // )}` // | ItTypeOr({typeOr}) => `(${Js.Array2.map(typeOr, toString)->Js.Array2.joinWith(" | ")})` // | ItTypeFunction({inputs, output}) => @@ -41,42 +38,42 @@ // let rec fromTypeMap = typeMap => { // let default = IEvString("") -// let evTypeTag: InternalExpressionValue.t = Belt.Map.String.getWithDefault( +// let evTypeTag: Reducer_Value.t = Belt.Map.String.getWithDefault( // typeMap, // "typeTag", // default, // ) -// let evTypeIdentifier: InternalExpressionValue.t = Belt.Map.String.getWithDefault( +// let evTypeIdentifier: Reducer_Value.t = Belt.Map.String.getWithDefault( // typeMap, // "typeIdentifier", // default, // ) -// let evTypeOr: InternalExpressionValue.t = Belt.Map.String.getWithDefault( +// let evTypeOr: Reducer_Value.t = Belt.Map.String.getWithDefault( // typeMap, // "typeOr", // default, // ) -// let evInputs: InternalExpressionValue.t = Belt.Map.String.getWithDefault( +// let evInputs: Reducer_Value.t = Belt.Map.String.getWithDefault( // typeMap, // "inputs", // default, // ) -// let evOutput: InternalExpressionValue.t = Belt.Map.String.getWithDefault( +// let evOutput: Reducer_Value.t = Belt.Map.String.getWithDefault( // typeMap, // "output", // default, // ) -// let evElement: InternalExpressionValue.t = Belt.Map.String.getWithDefault( +// let evElement: Reducer_Value.t = Belt.Map.String.getWithDefault( // typeMap, // "element", // default, // ) -// let evElements: InternalExpressionValue.t = Belt.Map.String.getWithDefault( +// let evElements: Reducer_Value.t = Belt.Map.String.getWithDefault( // typeMap, // "elements", // default, // ) -// let evProperties: InternalExpressionValue.t = Belt.Map.String.getWithDefault( +// let evProperties: Reducer_Value.t = Belt.Map.String.getWithDefault( // typeMap, // "properties", // default, @@ -101,18 +98,18 @@ // : ItModifiedType({modifiedType: makeIt, contracts: contracts}) // } -// and fromIEvValue = (ievValue: InternalExpressionValue.t): iType => +// and fromIEvValue = (ievValue: Reducer_Value.t): iType => // switch ievValue { // | IEvTypeIdentifier(typeIdentifier) => ItTypeIdentifier({typeIdentifier}) // | IEvType(typeMap) => fromTypeMap(typeMap) // | _ => raise(Reducer_Exception.ImpossibleException("Reducer_Type_T-ievValue")) // } -// and fromIEvArray = (ievArray: InternalExpressionValue.t) => +// and fromIEvArray = (ievArray: Reducer_Value.t) => // switch ievArray { // | IEvArray(array) => array->Belt.Array.map(fromIEvValue) // | _ => raise(Reducer_Exception.ImpossibleException("Reducer_Type_T-ievArray")) // } -// and fromIEvRecord = (ievRecord: InternalExpressionValue.t) => +// and fromIEvRecord = (ievRecord: Reducer_Value.t) => // switch ievRecord { // | 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_TypeChecker.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_TypeChecker.res index af712587..5d2be602 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 @@ -1,9 +1,8 @@ // module ExpressionT = Reducer_Expression_T -// module InternalExpressionValue = ReducerInterface_InternalExpressionValue // module ProjectAccessorsT = ReducerProject_ProjectAccessors_T // module T = Reducer_Type_T // module TypeContracts = Reducer_Type_Contracts -// open InternalExpressionValue +// open Reducer_Value // let rec isITypeOf = (anIType: T.iType, aValue): result => { // let caseTypeIdentifier = (anUpperTypeName, aValue) => { @@ -98,8 +97,8 @@ // let caseModifiedType = ( // anIType: T.iType, // modifiedType: T.iType, -// contracts: Belt.Map.String.t, -// aValue: InternalExpressionValue.t, +// contracts: Belt.Map.String.t, +// aValue: Reducer_Value.t, // ) => { // isITypeOf(modifiedType, aValue)->Belt.Result.flatMap(_result => { // if TypeContracts.checkModifiers(contracts, aValue) { @@ -113,7 +112,7 @@ // switch anIType { // | ItTypeIdentifier(name) => caseTypeIdentifier(name, aValue) // | ItModifiedType({modifiedType, contracts}) => -// caseModifiedType(anIType, modifiedType, contracts, aValue) //{modifiedType: iType, contracts: Belt.Map.String.t} +// caseModifiedType(anIType, modifiedType, contracts, aValue) //{modifiedType: iType, contracts: Belt.Map.String.t} // | ItTypeOr({typeOr}) => caseOr(anIType, typeOr, aValue) // | ItTypeFunction(_) => // raise( @@ -129,23 +128,23 @@ // let isTypeOf = ( // typeExpressionSourceCode: string, -// aValue: InternalExpressionValue.t, +// aValue: Reducer_Value.t, // reducerFn: Reducer_T.reducerFn, -// ): result => { +// ): result => { // switch typeExpressionSourceCode->Reducer_Type_Compile.fromTypeExpression(reducerFn) { // | Ok(anIType) => // switch isITypeOf(anIType, aValue) { // | Ok(_) => Ok(aValue) // | Error(T.TypeMismatch(anIType, evValue)) => // Error( -// ErrorValue.REExpectedType(anIType->T.toString, evValue->InternalExpressionValue.toString), +// ErrorValue.REExpectedType(anIType->T.toString, evValue->Reducer_Value.toString), // ) // } // | Error(error) => Error(error) // Directly propagating - err => err - causes type mismatch // } // } -// let checkITypeArguments = (anIType: T.iType, args: array): result< +// let checkITypeArguments = (anIType: T.iType, args: array): result< // bool, // T.typeErrorValue, // > => { @@ -155,7 +154,7 @@ // } // } -// let checkITypeArgumentsBool = (anIType: T.iType, args: array): bool => { +// let checkITypeArgumentsBool = (anIType: T.iType, args: array): bool => { // switch checkITypeArguments(anIType, args) { // | Ok(_) => true // | _ => false @@ -164,16 +163,16 @@ // let checkArguments = ( // typeExpressionSourceCode: string, -// args: array, +// args: array, // reducerFn: ReducerT.reducerFn, -// ): result => { +// ): result => { // switch typeExpressionSourceCode->Reducer_Type_Compile.fromTypeExpression(reducerFn) { // | Ok(anIType) => // switch checkITypeArguments(anIType, args) { // | Ok(_) => Ok(args->IEvArray) // | Error(T.TypeMismatch(anIType, evValue)) => // Error( -// ErrorValue.REExpectedType(anIType->T.toString, evValue->InternalExpressionValue.toString), +// ErrorValue.REExpectedType(anIType->T.toString, evValue->Reducer_Value.toString), // ) // } // | Error(error) => Error(error) // Directly propagating - err => err - causes type mismatch diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Value.res similarity index 98% rename from packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res rename to packages/squiggle-lang/src/rescript/Reducer/Reducer_Value.res index dd0d6e51..093dc196 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Value.res @@ -5,12 +5,8 @@ module ErrorValue = Reducer_ErrorValue type environment = GenericDist.env module T = Reducer_T -let defaultEnvironment: environment = DistributionOperation.defaultEnv - type t = Reducer_T.value -type internalExpressionValue = t - type functionCall = (string, array) let rec toString = (aValue: T.value) => diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface.res deleted file mode 100644 index 5153e413..00000000 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface.res +++ /dev/null @@ -1,2 +0,0 @@ -module InternalExpressionValue = ReducerInterface_InternalExpressionValue -module StdLib = ReducerInterface_StdLib diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res index 01996b32..1942a136 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res @@ -2,7 +2,6 @@ module Bindings = Reducer_Bindings module ErrorValue = Reducer_ErrorValue -module InternalExpressionValue = ReducerInterface_InternalExpressionValue module ProjectItem = ReducerProject_ProjectItem module T = ReducerProject_T module Topology = ReducerProject_Topology @@ -19,8 +18,8 @@ let getRunOrderFor = Topology.getRunOrderFor let createProject = () => { let project: t = { items: Belt.MutableMap.String.make(), - stdLib: ReducerInterface_StdLib.internalStdLib, - environment: InternalExpressionValue.defaultEnvironment, + stdLib: SquiggleLibrary_StdLib.stdLib, + environment: Reducer_Context.defaultEnvironment, previousRunOrder: [], } project @@ -143,8 +142,8 @@ let setStdLib = (project: t, value: Reducer_T.namespace): unit => { project.stdLib = value } -let getEnvironment = (project: t): InternalExpressionValue.environment => project.environment -let setEnvironment = (project: t, value: InternalExpressionValue.environment): unit => { +let getEnvironment = (project: t): Reducer_T.environment => project.environment +let setEnvironment = (project: t, value: Reducer_T.environment): unit => { project.environment = value } diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectAccessors_T.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectAccessors_T.res deleted file mode 100644 index 51fd41e3..00000000 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectAccessors_T.res +++ /dev/null @@ -1,31 +0,0 @@ -// module ProjectItemT = ReducerProject_ProjectItem_T -// module InternalExpressionValue = ReducerInterface_InternalExpressionValue - -// type states = {mutable continuation: ProjectItemT.continuationArgumentType} - -// type projectAccessors = { -// stdLib: Reducer_Bindings.t, -// environment: Reducer_T.environment, -// states: states, -// } - -// type t = projectAccessors - -// let identityAccessors: t = { -// // We need the states at the end of the runtime. -// // Accessors can be modified but states will stay as the same pointer -// states: { -// continuation: Reducer_Bindings.emptyBindings, -// }, -// stdLib: ReducerInterface_StdLib.internalStdLib, -// environment: InternalExpressionValue.defaultEnvironment, -// } - -// // to support change of environment in runtime -// let setEnvironment = (this: t, environment: Reducer_T.environment): t => { -// { -// ...this, -// environment: environment, -// } -// } - diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res b/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_StdLib.res similarity index 97% rename from packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res rename to packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_StdLib.res index f619d488..454983f7 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res +++ b/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_StdLib.res @@ -1,6 +1,6 @@ exception ErrorException = Reducer_ErrorValue.ErrorException -let internalStdLib: Reducer_T.namespace = { +let stdLib: Reducer_T.namespace = { // constants let res = Reducer_Namespace.make() diff --git a/packages/squiggle-lang/src/rescript/TypescriptInterface.res b/packages/squiggle-lang/src/rescript/TypescriptInterface.res deleted file mode 100644 index fa537347..00000000 --- a/packages/squiggle-lang/src/rescript/TypescriptInterface.res +++ /dev/null @@ -1,58 +0,0 @@ -open ForTS__Types -/* -This is meant as a file to contain @genType declarations as needed for Typescript. -I would ultimately want to have all @genType declarations here, vs. other files, but -@genType doesn't play as nicely with renaming Modules and functions as -would be preferable. - -The below few seem to work fine. In the future there's definitely more work to do here. -*/ - -// For backwards compatibility: -//Alternatives if one wants to keep the old habits -@genType type samplingParams = environment -@genType type squiggleValue_Dist = squiggleValue_Distribution //alternative -@genType type genericDist = squiggleValue_Distribution //alternative -@genType type sampleSetDist = sampleSetDistribution //alternative -@genType type symbolicDist = symbolicDistribution //alternative -@genType type resultDist = result //alternative -@genType type resultFloat = result //alternative -@genType type resultString = result //alternative - -@genType -let makeSampleSetDist: array => result< - sampleSetDist, - SampleSetDist.sampleSetError, -> = SampleSetDist.make - -//TODO: ForTS Interface module candid -@genType -let toPointSet: ( - squiggleValue_Distribution, - ~xyPointLength: int, - ~sampleCount: int, - ~xSelection: DistributionTypes.DistributionOperation.pointsetXSelection=?, - unit, -) => result = GenericDist.toPointSet - -@genType -type mixedShape = PointSetTypes.mixedShape - -@genType -type discreteShape = PointSetTypes.discreteShape - -@genType -type continuousShape = PointSetTypes.continuousShape - -@genType -let distributionErrorToString = ForTS_Distribution_Error.toString - -@genType -let defaultSamplingEnv = ForTS_Distribution.defaultEnvironment - -// Umur: opaque types -// @genType -// type declarationArg = Declaration.arg - -// @genType -// type declaration<'a> = Declaration.declaration<'a> From 8e13caae84db16304fbce847cf814e8e58d10911 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Mon, 19 Sep 2022 23:20:28 +0400 Subject: [PATCH 24/46] fix merge artifacts --- packages/squiggle-lang/scripts/README.md | 4 ---- packages/squiggle-lang/scripts/run-file.mjs | 24 --------------------- 2 files changed, 28 deletions(-) diff --git a/packages/squiggle-lang/scripts/README.md b/packages/squiggle-lang/scripts/README.md index c81dbc90..bb3c3028 100644 --- a/packages/squiggle-lang/scripts/README.md +++ b/packages/squiggle-lang/scripts/README.md @@ -1,8 +1,5 @@ Various scripts used for development, benchmarking and testing. -<<<<<<< HEAD -None of these are bundled in NPM package yet. -======= None of these are bundled in the NPM package yet. # run.mjs @@ -26,4 +23,3 @@ Time: 3.18 Ok ``` To see the result and bindings, add the `-o` or `--output` flag. ->>>>>>> develop diff --git a/packages/squiggle-lang/scripts/run-file.mjs b/packages/squiggle-lang/scripts/run-file.mjs index 2df67bd3..23041a5a 100755 --- a/packages/squiggle-lang/scripts/run-file.mjs +++ b/packages/squiggle-lang/scripts/run-file.mjs @@ -14,20 +14,11 @@ const measure = (cb, times = 1) => { return (t2 - t1) / 1000; }; -<<<<<<< HEAD -const red = (s) => `\x1b[31m${s}\x1b[0m`; -const green = (s) => `\x1b[32m${s}\x1b[0m`; - -const program = new Command(); - -program.option("-t, --time"); -======= const red = (str) => `\x1b[31m${str}\x1b[0m`; const green = (str) => `\x1b[32m${str}\x1b[0m`; const program = new Command(); ->>>>>>> develop program.option("-o, --output"); program.arguments(""); @@ -48,11 +39,7 @@ if (!src) { } project.setSource("main", src); -<<<<<<< HEAD -const t = measure(() => project.run("main")); -======= const time = measure(() => project.run("main")); ->>>>>>> develop const bindings = project.getBindings("main"); const result = project.getResult("main"); @@ -62,20 +49,9 @@ if (options.output) { console.log("Bindings:", bindings.toString()); } -<<<<<<< HEAD -if (options.time) { - console.log( - "Time:", - String(t), - result.tag === "Error" ? red(result.tag) : green(result.tag), - result.tag === "Error" ? result.value.toString() : "" - ); -} -======= console.log( "Time:", String(time), result.tag === "Error" ? red(result.tag) : green(result.tag), result.tag === "Error" ? result.value.toString() : "" ); ->>>>>>> develop From 4f90dccdf12494a2f97b2b615592cb02136483ed Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Tue, 20 Sep 2022 00:55:32 +0400 Subject: [PATCH 25/46] refactor scripts --- .../squiggle-lang/scripts/bench-map-reduce.js | 27 ------------ .../scripts/bench-map-reduce.mjs | 11 +---- packages/squiggle-lang/scripts/bench-map.js | 27 ------------ packages/squiggle-lang/scripts/bench-map.mjs | 11 +---- packages/squiggle-lang/scripts/lib.mjs | 41 +++++++++++++++++++ packages/squiggle-lang/scripts/run-file.mjs | 39 +----------------- packages/squiggle-lang/scripts/run.js | 18 -------- packages/squiggle-lang/scripts/run.mjs | 12 +----- 8 files changed, 47 insertions(+), 139 deletions(-) delete mode 100755 packages/squiggle-lang/scripts/bench-map-reduce.js delete mode 100755 packages/squiggle-lang/scripts/bench-map.js create mode 100644 packages/squiggle-lang/scripts/lib.mjs delete mode 100755 packages/squiggle-lang/scripts/run.js diff --git a/packages/squiggle-lang/scripts/bench-map-reduce.js b/packages/squiggle-lang/scripts/bench-map-reduce.js deleted file mode 100755 index ffada066..00000000 --- a/packages/squiggle-lang/scripts/bench-map-reduce.js +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env node -const s = require("@quri/squiggle-lang"); - -const measure = (cb, times = 1) => { - const t1 = new Date(); - - for (let i = 1; i <= times; i++) { - cb(); - } - const t2 = new Date(); - return (t2 - t1) / 1000; -}; - -const maxP = 5; - -for (let p = 0; p <= maxP; p++) { - const size = Math.pow(10, p); - const prj = s.SqProject.create(); - prj.setSource( - "main", - `List.upTo(1, ${size}) |> map({|x| List.upTo(1, 100) |> reduce(0, {|a,b|a+b})})` - ); - const t = measure(() => { - prj.run("main"); - }); - console.log(`1e${p}`, "\t", t); -} diff --git a/packages/squiggle-lang/scripts/bench-map-reduce.mjs b/packages/squiggle-lang/scripts/bench-map-reduce.mjs index 5dfbca0f..82c6d8e8 100755 --- a/packages/squiggle-lang/scripts/bench-map-reduce.mjs +++ b/packages/squiggle-lang/scripts/bench-map-reduce.mjs @@ -1,15 +1,6 @@ #!/usr/bin/env node import { SqProject } from "@quri/squiggle-lang"; - -const measure = (cb, times = 1) => { - const t1 = new Date(); - - for (let i = 1; i <= times; i++) { - cb(); - } - const t2 = new Date(); - return (t2 - t1) / 1000; -}; +import { measure } from "./lib.mjs"; const maxP = 5; diff --git a/packages/squiggle-lang/scripts/bench-map.js b/packages/squiggle-lang/scripts/bench-map.js deleted file mode 100755 index befa1a7b..00000000 --- a/packages/squiggle-lang/scripts/bench-map.js +++ /dev/null @@ -1,27 +0,0 @@ -#!/usr/bin/env node -const s = require("@quri/squiggle-lang"); - -const measure = (cb, times = 1) => { - const t1 = new Date(); - - for (let i = 1; i <= times; i++) { - cb(); - } - const t2 = new Date(); - return (t2 - t1) / 1000; -}; - -const maxP = 7; - -for (let p = 0; p <= maxP; p++) { - const size = Math.pow(10, p); - const project = s.SqProject.create(); - project.setSource("list", `l = List.upTo(1,${size})`); - project.run("list"); - project.setSource("map", "l |> map({|x| x})"); - project.setContinues("map", ["list"]); - const time = measure(() => { - project.run("map"); - }); - console.log(`1e${p}`, "\t", time); -} diff --git a/packages/squiggle-lang/scripts/bench-map.mjs b/packages/squiggle-lang/scripts/bench-map.mjs index c7a00477..5959a2fb 100755 --- a/packages/squiggle-lang/scripts/bench-map.mjs +++ b/packages/squiggle-lang/scripts/bench-map.mjs @@ -1,15 +1,6 @@ #!/usr/bin/env node import { SqProject } from "@quri/squiggle-lang"; - -const measure = (cb, times = 1) => { - const t1 = new Date(); - - for (let i = 1; i <= times; i++) { - cb(); - } - const t2 = new Date(); - return (t2 - t1) / 1000; -}; +import { measure } from "./lib.mjs"; const maxP = 7; diff --git a/packages/squiggle-lang/scripts/lib.mjs b/packages/squiggle-lang/scripts/lib.mjs new file mode 100644 index 00000000..ffa1d84f --- /dev/null +++ b/packages/squiggle-lang/scripts/lib.mjs @@ -0,0 +1,41 @@ +import { SqProject } from "@quri/squiggle-lang"; + +export const measure = (cb, times = 1) => { + const t1 = new Date(); + + for (let i = 1; i <= times; i++) { + cb(); + } + const t2 = new Date(); + return (t2 - t1) / 1000; +}; + +export const red = (str) => `\x1b[31m${str}\x1b[0m`; +export const green = (str) => `\x1b[32m${str}\x1b[0m`; + +export const run = (src, { output, sampleCount }) => { + const project = SqProject.create(); + if (sampleCount) { + project.setEnvironment({ + sampleCount: Number(sampleCount), + xyPointLength: Number(sampleCount), + }); + } + project.setSource("main", src); + const time = measure(() => project.run("main")); + + const bindings = project.getBindings("main"); + const result = project.getResult("main"); + + if (output) { + console.log("Result:", result.tag, result.value.toString()); + console.log("Bindings:", bindings.toString()); + } + + console.log( + "Time:", + String(time), + result.tag === "Error" ? red(result.tag) : green(result.tag), + result.tag === "Error" ? result.value.toString() : "" + ); +}; diff --git a/packages/squiggle-lang/scripts/run-file.mjs b/packages/squiggle-lang/scripts/run-file.mjs index 23041a5a..21d9de2d 100755 --- a/packages/squiggle-lang/scripts/run-file.mjs +++ b/packages/squiggle-lang/scripts/run-file.mjs @@ -1,21 +1,9 @@ #!/usr/bin/env node -import { SqProject } from "@quri/squiggle-lang"; import fs from "fs"; import { Command } from "commander"; -const measure = (cb, times = 1) => { - const t1 = new Date(); - - for (let i = 1; i <= times; i++) { - cb(); - } - const t2 = new Date(); - return (t2 - t1) / 1000; -}; - -const red = (str) => `\x1b[31m${str}\x1b[0m`; -const green = (str) => `\x1b[32m${str}\x1b[0m`; +import { run } from "./lib.mjs"; const program = new Command(); @@ -24,34 +12,11 @@ program.arguments(""); const options = program.parse(process.argv); -const project = SqProject.create(); const sampleCount = process.env.SAMPLE_COUNT; -if (sampleCount) { - project.setEnvironment({ - sampleCount: Number(sampleCount), - xyPointLength: Number(sampleCount), - }); -} const src = fs.readFileSync(program.args[0], "utf-8"); if (!src) { throw new Error("Expected src"); } -project.setSource("main", src); -const time = measure(() => project.run("main")); - -const bindings = project.getBindings("main"); -const result = project.getResult("main"); - -if (options.output) { - console.log("Result:", result.tag, result.value.toString()); - console.log("Bindings:", bindings.toString()); -} - -console.log( - "Time:", - String(time), - result.tag === "Error" ? red(result.tag) : green(result.tag), - result.tag === "Error" ? result.value.toString() : "" -); +run(src, { output: options.output, sampleCount }); diff --git a/packages/squiggle-lang/scripts/run.js b/packages/squiggle-lang/scripts/run.js deleted file mode 100755 index 97ae76bc..00000000 --- a/packages/squiggle-lang/scripts/run.js +++ /dev/null @@ -1,18 +0,0 @@ -#!/usr/bin/env node -const s = require("@quri/squiggle-lang"); - -const p = s.SqProject.create(); - -const src = process.argv[2]; -if (!src) { - throw new Error("Expected src"); -} -console.log(`Running ${src}`); -p.setSource("a", src); -p.run("a"); - -const result = p.getResult("a"); -console.log(result.tag, result.value.toString()); - -const bindings = p.getBindings("a"); -console.log(bindings.toString()); diff --git a/packages/squiggle-lang/scripts/run.mjs b/packages/squiggle-lang/scripts/run.mjs index 6f842eef..bc17314b 100755 --- a/packages/squiggle-lang/scripts/run.mjs +++ b/packages/squiggle-lang/scripts/run.mjs @@ -1,18 +1,10 @@ #!/usr/bin/env node -import { SqProject } from "@quri/squiggle-lang"; - -const project = SqProject.create(); +import { run } from "./lib.mjs"; const src = process.argv[2]; if (!src) { throw new Error("Expected src"); } console.log(`Running ${src}`); -project.setSource("a", src); -project.run("a"); -const result = project.getResult("a"); -console.log(result.tag, result.value.toString()); - -const bindings = project.getBindings("a"); -console.log(bindings.asValue().toString()); +run(src); From 4a08718184584d9fce0c4c33621388fe02fb94fb Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Tue, 20 Sep 2022 01:39:23 +0400 Subject: [PATCH 26/46] v0.5.0-alpha.0 --- packages/squiggle-lang/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index bd4d63ec..47545ba7 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -1,6 +1,6 @@ { "name": "@quri/squiggle-lang", - "version": "0.4.2", + "version": "0.5.0-alpha.0", "homepage": "https://squiggle-language.com", "license": "MIT", "scripts": { From 239200217265d0b8daefdd5880085c473321b806 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Tue, 20 Sep 2022 02:07:47 +0400 Subject: [PATCH 27/46] 0.5.0-alpha.1 versions --- packages/components/package.json | 4 ++-- packages/vscode-ext/package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index 110608bc..412f2f90 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@quri/squiggle-components", - "version": "0.4.3", + "version": "0.5.0-alpha.1", "license": "MIT", "dependencies": { "@floating-ui/react-dom": "^1.0.0", @@ -8,7 +8,7 @@ "@headlessui/react": "^1.6.6", "@heroicons/react": "^1.0.6", "@hookform/resolvers": "^2.9.8", - "@quri/squiggle-lang": "^0.4.2", + "@quri/squiggle-lang": "^0.5.0-alpha.0", "@react-hook/size": "^2.1.2", "clsx": "^1.2.1", "framer-motion": "^7.3.2", diff --git a/packages/vscode-ext/package.json b/packages/vscode-ext/package.json index 210b4a23..8dfbeb48 100644 --- a/packages/vscode-ext/package.json +++ b/packages/vscode-ext/package.json @@ -3,7 +3,7 @@ "displayName": "Squiggle", "description": "Squiggle language support", "license": "MIT", - "version": "0.4.2", + "version": "0.5.0-alpha.1", "publisher": "QURI", "repository": { "type": "git", From 92483e66e0623fb75309f361147c0ec262e63e13 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Tue, 20 Sep 2022 02:19:55 +0400 Subject: [PATCH 28/46] yarn format --- .../Reducer_Peggy_ToExpression_void_test.res | 7 +- .../__tests__/Reducer/Reducer_TestHelpers.res | 5 +- .../ReducerInterface_ExpressionValue_test.res | 8 +- .../ReducerProject_tutorial_1_test.res | 12 +- ...cerProject_tutorial_2_multisource_test.res | 18 +-- ...educerProject_tutorial_3_includes_test.res | 6 +- ...leLibrary_FunctionRegistryLibrary_test.res | 5 +- .../src/rescript/FR/FR_Builtin.res | 106 ++++-------------- .../squiggle-lang/src/rescript/FR/FR_Dict.res | 5 +- .../src/rescript/FR/FR_GenericDist.res | 18 +-- .../squiggle-lang/src/rescript/FR/FR_List.res | 7 +- .../squiggle-lang/src/rescript/FR/FR_Math.res | 51 ++------- .../src/rescript/FR/FR_Sampleset.res | 4 +- .../ForTS_SquiggleValue.res | 3 +- .../ForTS_SquiggleValue_Array.res | 6 +- .../ForTS_SquiggleValue_Declaration.res | 3 +- .../ForTS_SquiggleValue_Distribution.res | 3 +- .../ForTS_SquiggleValue_Lambda.res | 3 +- .../ForTS_SquiggleValue_Type.res | 3 +- .../FunctionRegistry_Core.res | 7 +- .../FunctionRegistry_Helpers.res | 52 ++++----- .../src/rescript/Reducer/Reducer_Context.res | 3 +- .../Reducer_Expression/Reducer_Expression.res | 4 +- .../rescript/Reducer/Reducer_Namespace.res | 4 +- .../Reducer_Type/Reducer_Type_Contracts.res | 11 +- .../SquiggleLibrary_StdLib.res | 13 +-- 26 files changed, 104 insertions(+), 263 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_void_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_void_test.res index 451656cb..465789da 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_void_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_void_test.res @@ -10,12 +10,7 @@ describe("Peggy void", () => { // ~v="@{fn: lambda(_=>internal code)}", (), ) - testToExpression( - "fn()=1; fn()", - "fn = {|_| {1}}; (fn)(())", - ~v="1", - (), - ) + testToExpression("fn()=1; fn()", "fn = {|_| {1}}; (fn)(())", ~v="1", ()) testToExpression( "fn(a)=(); call fn(1)", "fn = {|a| {()}}; _ = {(fn)(1)}", diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res index 5d335556..43de902e 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res @@ -17,10 +17,7 @@ let expectParseToBe = (code: string, answer: string) => Expression.BackCompatible.parse(code)->ExpressionT.toStringResult->expect->toBe(answer) let expectEvalToBe = (code: string, answer: string) => - Expression.BackCompatible.evaluateString(code) - ->Reducer_Value.toStringResult - ->expect - ->toBe(answer) + Expression.BackCompatible.evaluateString(code)->Reducer_Value.toStringResult->expect->toBe(answer) let expectEvalError = (code: string) => Expression.BackCompatible.evaluateString(code) diff --git a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_ExpressionValue_test.res b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_ExpressionValue_test.res index 31054a67..9b1558c1 100644 --- a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_ExpressionValue_test.res +++ b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_ExpressionValue_test.res @@ -2,13 +2,13 @@ open Jest open Expect describe("ExpressionValue", () => { - test("argsToString", () => expect( - [IEvNumber(1.), IEvString("a")]->Reducer_Value.argsToString)->toBe("1,'a'") + test("argsToString", () => + expect([IEvNumber(1.), IEvString("a")]->Reducer_Value.argsToString)->toBe("1,'a'") ) test("toStringFunctionCall", () => - expect( - ("fn", [IEvNumber(1.), IEvString("a")])->Reducer_Value.toStringFunctionCall)->toBe("fn(1,'a')" + expect(("fn", [IEvNumber(1.), IEvString("a")])->Reducer_Value.toStringFunctionCall)->toBe( + "fn(1,'a')", ) ) }) diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_test.res index fec3ee66..21907acc 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_test.res @@ -48,10 +48,8 @@ Case "Running a single source". let bindings = project->Project.getBindings("main") /* Let's display the result and bindings */ - ( - result->Reducer_Value.toStringResult, - bindings->Reducer_Value.toStringRecord, - )->expect == ("Ok(3)", "{}") + (result->Reducer_Value.toStringResult, bindings->Reducer_Value.toStringRecord)->expect == + ("Ok(3)", "{}") /* You've got 3 with empty bindings. */ }) @@ -86,10 +84,8 @@ Case "Running a single source". /* If you are running single source without includes and you don't need a custom environment, you can use the shortcut. */ /* Examples above was to prepare you for the multi source tutorial. */ let (result, bindings) = Project.evaluate("1+2") - ( - result->Reducer_Value.toStringResult, - bindings->Reducer_Value.toStringRecord, - )->expect == ("Ok(3)", "{}") + (result->Reducer_Value.toStringResult, bindings->Reducer_Value.toStringRecord)->expect == + ("Ok(3)", "{}") }) }) }) diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_multisource_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_multisource_test.res index b2c3738a..a31b9811 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_multisource_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_multisource_test.res @@ -30,10 +30,8 @@ describe("ReducerProject Tutorial", () => { let result3 = project->Project.getResult("source3") let bindings3 = project->Project.getBindings("source3") - ( - result3->Reducer_Value.toStringResult, - bindings3->Reducer_Value.toStringRecord, - )->expect == ("Ok(())", "{z: 3}") + (result3->Reducer_Value.toStringResult, bindings3->Reducer_Value.toStringRecord)->expect == + ("Ok(())", "{z: 3}") }) test("Depending", () => { @@ -56,10 +54,8 @@ describe("ReducerProject Tutorial", () => { let result3 = project->Project.getResult("source3") let bindings3 = project->Project.getBindings("source3") - ( - result3->Reducer_Value.toStringResult, - bindings3->Reducer_Value.toStringRecord, - )->expect == ("Ok(())", "{z: 3}") + (result3->Reducer_Value.toStringResult, bindings3->Reducer_Value.toStringRecord)->expect == + ("Ok(())", "{z: 3}") }) test("Intro to including", () => { @@ -91,10 +87,8 @@ describe("ReducerProject Tutorial", () => { let result3 = project->Project.getResult("source3") let bindings3 = project->Project.getBindings("source3") - ( - result3->Reducer_Value.toStringResult, - bindings3->Reducer_Value.toStringRecord, - )->expect == ("Ok(())", "{z: 3}") + (result3->Reducer_Value.toStringResult, bindings3->Reducer_Value.toStringRecord)->expect == + ("Ok(())", "{z: 3}") /* Doing it like this is too verbose for a storybook But I hope you have seen the relation of setContinues and parseIncludes */ diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_3_includes_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_3_includes_test.res index e5af0e3f..2c63dfff 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_3_includes_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_3_includes_test.res @@ -144,10 +144,8 @@ Here we will finally proceed to a real life scenario. */ let bindings = project->Project.getBindings("main") /* And see the result and bindings.. */ test("recursive includes", () => { - ( - result->Reducer_Value.toStringResult, - bindings->Reducer_Value.toStringRecord, - )->expect == ("Ok(6)", "{a: 6,b: 2}") + (result->Reducer_Value.toStringResult, bindings->Reducer_Value.toStringRecord)->expect == + ("Ok(6)", "{a: 6,b: 2}") /* Everything as expected */ }) }) diff --git a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res index da4788e5..34a09172 100644 --- a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res +++ b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res @@ -3,10 +3,7 @@ open Expect open Reducer_TestHelpers let expectEvalToBeOk = (code: string) => - Reducer_Expression.BackCompatible.evaluateString(code) - ->E.R.isOk - ->expect - ->toBe(true) + Reducer_Expression.BackCompatible.evaluateString(code)->E.R.isOk->expect->toBe(true) let registry = FunctionRegistry_Library.registry let examples = E.A.to_list(FunctionRegistry_Core.Registry.allExamples(registry)) diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Builtin.res b/packages/squiggle-lang/src/rescript/FR/FR_Builtin.res index e0bc776a..aee18e8b 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Builtin.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Builtin.res @@ -26,93 +26,31 @@ let makeFn = ( ) => makeFnMany(name, [{inputs: inputs, fn: fn}]) let library = [ - Make.ff2f( - ~name="add", // infix + (see Reducer/Reducer_Peggy/helpers.ts) - ~fn=(x, y) => x +. y, - () - ), - Make.ff2f( - ~name="subtract", // infix - - ~fn=(x, y) => x -. y, - () - ), - Make.ff2f( - ~name="multiply", // infix * - ~fn=(x, y) => x *. y, - () - ), - Make.ff2f( - ~name="divide", // infix / - ~fn=(x, y) => x /. y, - () - ), - Make.ff2f( - ~name="pow", // infix ^ - ~fn=(x, y) => Js.Math.pow_float(~base=x, ~exp=y), - () - ), - Make.ff2b( - ~name="equal", // infix == on numbers - ~fn=(x, y) => x == y, - () - ), - Make.bb2b( - ~name="equal", // infix == on booleans - ~fn=(x, y) => x == y, - () - ), - Make.ff2b( - ~name="unequal", // infix != on numbers - ~fn=(x, y) => x != y, - () - ), - Make.ff2b( - ~name="unequal", // infix != on booleans - ~fn=(x, y) => x != y, - () - ), - Make.ff2b( - ~name="smaller", // infix < - ~fn=(x, y) => x < y, - () - ), - Make.ff2b( - ~name="smallerEq", // infix <= - ~fn=(x, y) => x <= y, - () - ), - Make.ff2b( - ~name="larger", // infix > - ~fn=(x, y) => x > y, - () - ), - Make.ff2b( - ~name="largerEq", // infix >= - ~fn=(x, y) => x >= y, - () - ), - Make.bb2b( - ~name="or", // infix || - ~fn=(x, y) => x || y, - () - ), - Make.bb2b( - ~name="and", // infix && - ~fn=(x, y) => x && y, - () - ), - Make.f2f( - ~name="unaryMinus", // unary prefix - - ~fn=x => -.x, - () - ), - makeFn("not", [FRTypeNumber], inputs => { // unary prefix ! + Make.ff2f(~name="add", ~fn=(x, y) => x +. y, ()), // infix + (see Reducer/Reducer_Peggy/helpers.ts) + Make.ff2f(~name="subtract", ~fn=(x, y) => x -. y, ()), // infix - + Make.ff2f(~name="multiply", ~fn=(x, y) => x *. y, ()), // infix * + Make.ff2f(~name="divide", ~fn=(x, y) => x /. y, ()), // infix / + Make.ff2f(~name="pow", ~fn=(x, y) => Js.Math.pow_float(~base=x, ~exp=y), ()), // infix ^ + Make.ff2b(~name="equal", ~fn=(x, y) => x == y, ()), // infix == on numbers + Make.bb2b(~name="equal", ~fn=(x, y) => x == y, ()), // infix == on booleans + Make.ff2b(~name="unequal", ~fn=(x, y) => x != y, ()), // infix != on numbers + Make.ff2b(~name="unequal", ~fn=(x, y) => x != y, ()), // infix != on booleans + Make.ff2b(~name="smaller", ~fn=(x, y) => x < y, ()), // infix < + Make.ff2b(~name="smallerEq", ~fn=(x, y) => x <= y, ()), // infix <= + Make.ff2b(~name="larger", ~fn=(x, y) => x > y, ()), // infix > + Make.ff2b(~name="largerEq", ~fn=(x, y) => x >= y, ()), // infix >= + Make.bb2b(~name="or", ~fn=(x, y) => x || y, ()), // infix || + Make.bb2b(~name="and", ~fn=(x, y) => x && y, ()), // infix && + Make.f2f(~name="unaryMinus", ~fn=x => -.x, ()), // unary prefix - + makeFn("not", [FRTypeNumber], inputs => { + // unary prefix ! switch inputs { | [IEvNumber(x)] => IEvBool(x != 0.)->Ok | _ => Error(impossibleError) } }), - makeFn("not", [FRTypeBool], inputs => { // unary prefix ! + makeFn("not", [FRTypeBool], inputs => { + // unary prefix ! switch inputs { | [IEvBool(x)] => IEvBool(!x)->Ok | _ => Error(impossibleError) @@ -157,9 +95,7 @@ let library = [ }), makeFn("javascriptraise", [FRTypeAny], inputs => { switch inputs { - | [msg] => { - Js.Exn.raiseError(msg->Reducer_Value.toString) - } + | [msg] => Js.Exn.raiseError(msg->Reducer_Value.toString) | _ => Error(impossibleError) } }), diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Dict.res b/packages/squiggle-lang/src/rescript/FR/FR_Dict.res index c8a82b9c..2f36871c 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Dict.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Dict.res @@ -17,10 +17,7 @@ module Internals = { ->E.A2.fmap(((key, value)) => Wrappers.evArray([IEvString(key), value])) ->Wrappers.evArray - let fromList = (items: array): result< - Reducer_T.value, - errorValue, - > => + let fromList = (items: array): result => items ->E.A2.fmap(item => { switch (item: Reducer_T.value) { diff --git a/packages/squiggle-lang/src/rescript/FR/FR_GenericDist.res b/packages/squiggle-lang/src/rescript/FR/FR_GenericDist.res index 93f720b4..443e101b 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_GenericDist.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_GenericDist.res @@ -74,15 +74,10 @@ module Old = { | _ => Error("Not a number") } - let parseNumberArray = (ags: array): Belt.Result.t< - array, - string, - > => E.A.fmap(parseNumber, ags) |> E.A.R.firstErrorOrOpen + let parseNumberArray = (ags: array): Belt.Result.t, string> => + E.A.fmap(parseNumber, ags) |> E.A.R.firstErrorOrOpen - let parseDist = (args: Reducer_T.value): Belt.Result.t< - DistributionTypes.genericDist, - string, - > => + let parseDist = (args: Reducer_T.value): Belt.Result.t => switch args { | IEvDistribution(x) => Ok(x) | IEvNumber(x) => Ok(GenericDist.fromFloat(x)) @@ -173,10 +168,9 @@ module Old = { } } - let dispatchToGenericOutput = ( - call: Reducer_Value.functionCall, - env: GenericDist.env, - ): option => { + let dispatchToGenericOutput = (call: Reducer_Value.functionCall, env: GenericDist.env): option< + DistributionOperation.outputType, + > => { let (fnName, args) = call switch (fnName, args) { | ("triangular" as fnName, [IEvNumber(f1), IEvNumber(f2), IEvNumber(f3)]) => diff --git a/packages/squiggle-lang/src/rescript/FR/FR_List.res b/packages/squiggle-lang/src/rescript/FR/FR_List.res index 9bc68847..081d453a 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_List.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_List.res @@ -5,10 +5,9 @@ let nameSpace = "List" let requiresNamespace = true module Internals = { - let makeFromNumber = ( - n: float, - value: Reducer_T.value, - ): Reducer_T.value => IEvArray(Belt.Array.make(E.Float.toInt(n), value)) + let makeFromNumber = (n: float, value: Reducer_T.value): Reducer_T.value => IEvArray( + Belt.Array.make(E.Float.toInt(n), value), + ) let upTo = (low: float, high: float): Reducer_T.value => IEvArray( E.A.Floats.range(low, high, (high -. low +. 1.0)->E.Float.toInt)->E.A2.fmap(Wrappers.evNumber), diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Math.res b/packages/squiggle-lang/src/rescript/FR/FR_Math.res index 98ed37b2..5d98485b 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Math.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Math.res @@ -9,50 +9,13 @@ let library = [ ~name="sqrt", ~nameSpace="Math", ~requiresNamespace=true, - ~fn=(x) => Js.Math.pow_float(~base=x, ~exp=0.5), - (), - ), - - Make.f2f( - ~name="sin", - ~nameSpace="Math", - ~requiresNamespace=true, - ~fn=Js.Math.sin, - (), - ), - Make.f2f( - ~name="cos", - ~nameSpace="Math", - ~requiresNamespace=true, - ~fn=Js.Math.cos, - (), - ), - Make.f2f( - ~name="tan", - ~nameSpace="Math", - ~requiresNamespace=true, - ~fn=Js.Math.tan, - (), - ), - Make.f2f( - ~name="asin", - ~nameSpace="Math", - ~requiresNamespace=true, - ~fn=Js.Math.asin, - (), - ), - Make.f2f( - ~name="acos", - ~nameSpace="Math", - ~requiresNamespace=true, - ~fn=Js.Math.acos, - (), - ), - Make.f2f( - ~name="atan", - ~nameSpace="Math", - ~requiresNamespace=true, - ~fn=Js.Math.atan, + ~fn=x => Js.Math.pow_float(~base=x, ~exp=0.5), (), ), + Make.f2f(~name="sin", ~nameSpace="Math", ~requiresNamespace=true, ~fn=Js.Math.sin, ()), + Make.f2f(~name="cos", ~nameSpace="Math", ~requiresNamespace=true, ~fn=Js.Math.cos, ()), + Make.f2f(~name="tan", ~nameSpace="Math", ~requiresNamespace=true, ~fn=Js.Math.tan, ()), + Make.f2f(~name="asin", ~nameSpace="Math", ~requiresNamespace=true, ~fn=Js.Math.asin, ()), + Make.f2f(~name="acos", ~nameSpace="Math", ~requiresNamespace=true, ~fn=Js.Math.acos, ()), + Make.f2f(~name="atan", ~nameSpace="Math", ~requiresNamespace=true, ~fn=Js.Math.atan, ()), ] diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res b/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res index 228e8805..49f069ef 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res @@ -48,9 +48,7 @@ module Internal = { SampleSetDist.map3(~fn, ~t1, ~t2, ~t3)->toType } - let parseSampleSetArray = (arr: array): option< - array, - > => { + let parseSampleSetArray = (arr: array): option> => { let parseSampleSet = (value: Reducer_T.value): option => switch value { | IEvDistribution(SampleSet(dist)) => Some(dist) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res index 0b6b9d93..4fac710f 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res @@ -73,8 +73,7 @@ let getTag = (variant: squiggleValue): squiggleValueTag => } @genType -let toString = (variant: squiggleValue) => - Reducer_Value.toString(variant) +let toString = (variant: squiggleValue) => Reducer_Value.toString(variant) // This is a useful method for unit tests. // Convert the result along with the error message to a string. diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Array.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Array.res index 823fde5c..51854580 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Array.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Array.res @@ -2,9 +2,7 @@ type squiggleValue = ForTS_SquiggleValue.squiggleValue @genType type squiggleValue_Array = ForTS_SquiggleValue.squiggleValue_Array //re-export recursive type @genType -let getValues = (v: squiggleValue_Array): array => - Reducer_Value.arrayToValueArray(v) +let getValues = (v: squiggleValue_Array): array => Reducer_Value.arrayToValueArray(v) @genType -let toString = (v: squiggleValue_Array): string => - Reducer_Value.toStringArray(v) +let toString = (v: squiggleValue_Array): string => Reducer_Value.toStringArray(v) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Declaration.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Declaration.res index 5c8eae49..996668de 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Declaration.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Declaration.res @@ -1,5 +1,4 @@ @genType type squiggleValue_Declaration = Reducer_T.lambdaDeclaration //re-export @genType -let toString = (v: squiggleValue_Declaration): string => - Reducer_Value.toStringDeclaration(v) +let toString = (v: squiggleValue_Declaration): string => Reducer_Value.toStringDeclaration(v) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Distribution.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Distribution.res index b1d6b440..ff3e45d8 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Distribution.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Distribution.res @@ -1,5 +1,4 @@ @genType type squiggleValue_Distribution = ForTS_Distribution.distribution @genType -let toString = (v: squiggleValue_Distribution): string => - Reducer_Value.toStringDistribution(v) +let toString = (v: squiggleValue_Distribution): string => Reducer_Value.toStringDistribution(v) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Lambda.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Lambda.res index f6ec66d3..a9793e87 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Lambda.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Lambda.res @@ -1,8 +1,7 @@ @genType type squiggleValue_Lambda = Reducer_T.lambdaValue //re-export @genType -let toString = (v: squiggleValue_Lambda): string => - Reducer_Value.toStringFunction(v) +let toString = (v: squiggleValue_Lambda): string => Reducer_Value.toStringFunction(v) @genType let parameters = (v: squiggleValue_Lambda): array => { diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Type.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Type.res index 0c002040..14845512 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Type.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Type.res @@ -6,5 +6,4 @@ let getKeyValuePairs = (value: squiggleValue_Type): array<(string, squiggleValue Reducer_Value.recordToKeyValuePairs(value) @genType -let toString = (value: squiggleValue_Type): string => - Reducer_Value.toStringType(value) +let toString = (value: squiggleValue_Type): string => Reducer_Value.toStringType(value) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res index 901915e3..4ae50fa3 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res @@ -179,10 +179,9 @@ module FRType = { | FRValueAny(f) => matchReverse(f) } - let matchWithExpressionValueArray = ( - inputs: array, - args: array, - ): option> => { + let matchWithExpressionValueArray = (inputs: array, args: array): option< + array, + > => { let isSameLength = E.A.length(inputs) == E.A.length(args) if !isSameLength { None diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res index 82c99d6c..1b94c6bf 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res @@ -278,10 +278,10 @@ module Make = { Q: What about polymorphic functions with multiple definitions? Why ~fn is not an array? A: We often define the same function in multiple `FR_*` files, so that doesn't work well anyway. In 90%+ cases there's a single definition. And having to write `name` twice is annoying. - */ + */ let f2f = ( ~name: string, - ~fn: (float) => float, + ~fn: float => float, ~nameSpace="", ~requiresNamespace=false, ~examples=?, @@ -290,22 +290,22 @@ module Make = { Function.make( ~name, ~nameSpace, - ~requiresNamespace=requiresNamespace, + ~requiresNamespace, ~examples=examples->E.O.default([], _), ~output=EvtNumber, ~definitions=[ FnDefinition.make( ~name, ~inputs=[FRTypeNumber], - ~run=((inputs, _, _, _) => + ~run=(inputs, _, _, _) => switch inputs { | [IEvNumber(x)] => fn(x)->IEvNumber->Ok | _ => Error(impossibleError) - }), - () - ) + }, + (), + ), ], - () + (), ) } @@ -320,22 +320,22 @@ module Make = { Function.make( ~name, ~nameSpace, - ~requiresNamespace=requiresNamespace, + ~requiresNamespace, ~examples=examples->E.O.default([], _), ~output=EvtNumber, ~definitions=[ FnDefinition.make( ~name, ~inputs=[FRTypeNumber, FRTypeNumber], - ~run=((inputs, _, _, _) => + ~run=(inputs, _, _, _) => switch inputs { | [IEvNumber(x), IEvNumber(y)] => fn(x, y)->IEvNumber->Ok | _ => Error(impossibleError) - }), - () - ) + }, + (), + ), ], - () + (), ) } @@ -350,22 +350,22 @@ module Make = { Function.make( ~name, ~nameSpace, - ~requiresNamespace=requiresNamespace, + ~requiresNamespace, ~examples=examples->E.O.default([], _), ~output=EvtBool, ~definitions=[ FnDefinition.make( ~name, ~inputs=[FRTypeNumber, FRTypeNumber], - ~run=((inputs, _, _, _) => + ~run=(inputs, _, _, _) => switch inputs { | [IEvNumber(x), IEvNumber(y)] => fn(x, y)->IEvBool->Ok | _ => Error(impossibleError) - }), - () - ) + }, + (), + ), ], - () + (), ) } @@ -380,22 +380,22 @@ module Make = { Function.make( ~name, ~nameSpace, - ~requiresNamespace=requiresNamespace, + ~requiresNamespace, ~examples=examples->E.O.default([], _), ~output=EvtBool, ~definitions=[ FnDefinition.make( ~name, ~inputs=[FRTypeBool, FRTypeBool], - ~run=((inputs, _, _, _) => + ~run=(inputs, _, _, _) => switch inputs { | [IEvBool(x), IEvBool(y)] => fn(x, y)->IEvBool->Ok | _ => Error(impossibleError) - }), - () - ) + }, + (), + ), ], - () + (), ) } } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res index ff835e96..c45994bb 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Context.res @@ -9,5 +9,4 @@ let createContext = (stdLib: Reducer_Namespace.t, environment: Reducer_T.environ } } -let createDefaultContext = (): t => - createContext(SquiggleLibrary_StdLib.stdLib, defaultEnvironment) +let createDefaultContext = (): t => createContext(SquiggleLibrary_StdLib.stdLib, defaultEnvironment) 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 e608036a..c28e121e 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 @@ -103,9 +103,7 @@ let rec evaluate: T.reducerFn = (expression, context): (T.value, T.context) => { context, ) | _ => - RENotAFunction(lambda->Reducer_Value.toString) - ->Reducer_ErrorValue.ErrorException - ->raise + RENotAFunction(lambda->Reducer_Value.toString)->Reducer_ErrorValue.ErrorException->raise } } } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res index 14afae95..e2757f60 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Namespace.res @@ -24,9 +24,7 @@ let mergeMany = (namespaces: array): t => let toString = (namespace: t) => namespace ->Belt.Map.String.toArray - ->Belt.Array.map(((eachKey, eachValue)) => - `${eachKey}: ${eachValue->Reducer_Value.toString}` - ) + ->Belt.Array.map(((eachKey, eachValue)) => `${eachKey}: ${eachValue->Reducer_Value.toString}`) ->Js.Array2.toString let fromArray = (a): t => Belt.Map.String.fromArray(a) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Contracts.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Contracts.res index 8433ef22..59230a9e 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Contracts.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Contracts.res @@ -16,10 +16,7 @@ let isMax = (modifierArg: Reducer_Value.t, aValue: Reducer_Value.t): bool => { } } -let isMemberOf = ( - modifierArg: Reducer_Value.t, - aValue: Reducer_Value.t, -): bool => { +let isMemberOf = (modifierArg: Reducer_Value.t, aValue: Reducer_Value.t): bool => { let pair = (modifierArg, aValue) switch pair { | (ievA, IEvArray(b)) => Js.Array2.includes(b, ievA) @@ -27,11 +24,7 @@ let isMemberOf = ( } } -let checkModifier = ( - key: string, - modifierArg: Reducer_Value.t, - aValue: Reducer_Value.t, -): bool => +let checkModifier = (key: string, modifierArg: Reducer_Value.t, aValue: Reducer_Value.t): bool => switch key { | "min" => isMin(modifierArg, aValue) | "max" => isMax(modifierArg, aValue) diff --git a/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_StdLib.res b/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_StdLib.res index 454983f7..3be93851 100644 --- a/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_StdLib.res +++ b/packages/squiggle-lang/src/rescript/SquiggleLibrary/SquiggleLibrary_StdLib.res @@ -13,16 +13,13 @@ let stdLib: Reducer_T.namespace = { Reducer_Expression_Lambda.makeFFILambda((inputs, _, _) => { switch inputs { | [IEvArray(aValueArray), IEvNumber(fIndex)] => { - let index = Belt.Int.fromFloat(fIndex) // TODO - fail on non-integer indices? + let index = Belt.Int.fromFloat(fIndex) // TODO - fail on non-integer indices? - switch Belt.Array.get(aValueArray, index) { - | Some(value) => value - | None => - REArrayIndexNotFound("Array index not found", index) - ->ErrorException - ->raise + switch Belt.Array.get(aValueArray, index) { + | Some(value) => value + | None => REArrayIndexNotFound("Array index not found", index)->ErrorException->raise + } } - } | [IEvRecord(dict), IEvString(sIndex)] => switch Belt.Map.String.get(dict, sIndex) { | Some(value) => value From 4779ac24768f7adcffc0b465cdf3e105779b13fa Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Tue, 20 Sep 2022 02:25:28 +0400 Subject: [PATCH 29/46] fix build errors --- .../src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res index 1b94c6bf..3edbe5da 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res @@ -1,7 +1,8 @@ open FunctionRegistry_Core +open Reducer_T let impossibleErrorString = "Wrong inputs / Logically impossible" -let impossibleError: errorValue = impossibleErrorString->REOther +let impossibleError: errorValue = impossibleErrorString->Reducer_ErrorValue.REOther let wrapError = e => Reducer_ErrorValue.REOther(e) module Wrappers = { From 630128ae3f46295cc198b6f0e1efa84780c3eba5 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Tue, 20 Sep 2022 02:32:57 +0400 Subject: [PATCH 30/46] bump website -> components dependency --- packages/website/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/website/package.json b/packages/website/package.json index 2cfbb0c8..f4f8d2ee 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -15,7 +15,7 @@ "@docusaurus/core": "2.1.0", "@docusaurus/preset-classic": "2.1.0", "@heroicons/react": "^1.0.6", - "@quri/squiggle-components": "^0.4.1", + "@quri/squiggle-components": "^0.5.0-alpha.1", "base64-js": "^1.5.1", "clsx": "^1.2.1", "hast-util-is-element": "2.1.2", From 5cf17f5dbfbb8c08d74a8e1242851176f7971cef Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Tue, 20 Sep 2022 02:47:29 +0400 Subject: [PATCH 31/46] cleanups --- .../SquiggleViewer/ExpressionViewer.tsx | 35 ------------------- .../ReducerProject_tutorial_1_test.res | 4 --- 2 files changed, 39 deletions(-) diff --git a/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx b/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx index 1ae2a7b0..8bd32292 100644 --- a/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx +++ b/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx @@ -135,23 +135,6 @@ export const ExpressionViewer: React.FC = ({ value, width }) => { {() => value.value.toString()} ); - // case SqValueTag.Symbol: - // return ( - // - // {() => ( - // <> - // Undefined Symbol: - // {value.value} - // - // )} - // - // ); - // case SqValueTag.Call: - // return ( - // - // {() => value.value} - // - // ); case SqValueTag.Date: return ( @@ -236,24 +219,6 @@ export const ExpressionViewer: React.FC = ({ value, width }) => { ); } - // case SqValueTag.Module: { - // return ( - // - // {(_) => - // value.value - // .entries() - // .filter(([key, _]) => !key.match(/^(__result__)$/)) - // .map(([key, r]) => ( - // - // )) - // } - // - // ); - // } case SqValueTag.Record: const plot = makePlot(value.value); if (plot) { diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_test.res index 21907acc..3c67fe4e 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_test.res @@ -90,10 +90,6 @@ Case "Running a single source". }) }) -// s1: { x = 1 } / { stdlib } -// s2 (deps=[s1]): { y = 2 } / { { x = 1 } + stdlib } -// s3 (deps=[s2]): { z = 3 } / { { y = 2 } + stdlib } - //TODO multiple sources //TODO multiple sources with includes. Introduction to includes //TODO multiple sources with multi level includes. Cycle detection From cdc49b378ad49f614df55c79f5301b02cb21797d Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Tue, 20 Sep 2022 03:06:56 +0400 Subject: [PATCH 32/46] cleanup --- packages/squiggle-lang/examples/integrate.squiggle | 13 ------------- 1 file changed, 13 deletions(-) delete mode 100644 packages/squiggle-lang/examples/integrate.squiggle diff --git a/packages/squiggle-lang/examples/integrate.squiggle b/packages/squiggle-lang/examples/integrate.squiggle deleted file mode 100644 index d41e18c7..00000000 --- a/packages/squiggle-lang/examples/integrate.squiggle +++ /dev/null @@ -1,13 +0,0 @@ -integrate(fun, min, max) = { - // assume that min and max are integers. - epsilon = 1 - l = max - min - meanF(t) = fun(t) - intervals = map(List.upTo(0, (l/epsilon)), ({|n| min + n*epsilon})) - values = map(intervals, ({ |x | meanF(x)})) - result = reduce(values, 0, ({|acc, x| acc + x})) * epsilon - result -} - -f(x) = x -integrate(f, 1, 100k) From 4ed5ce0d4786c062819fc4b6297e42d6d97955fd Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Tue, 20 Sep 2022 19:42:50 +0400 Subject: [PATCH 33/46] WIP --- ...leLibrary_FunctionRegistryLibrary_test.res | 7 + packages/squiggle-lang/scripts/lib.mjs | 2 +- packages/squiggle-lang/scripts/run.mjs | 4 +- .../squiggle-lang/src/rescript/FR/FR_Dict.res | 29 ++-- .../squiggle-lang/src/rescript/FR/FR_Dist.res | 12 +- .../squiggle-lang/src/rescript/FR/FR_Fn.res | 10 +- .../squiggle-lang/src/rescript/FR/FR_List.res | 10 +- .../src/rescript/FR/FR_Number.res | 5 +- .../src/rescript/FR/FR_Pointset.res | 49 +++--- .../src/rescript/FR/FR_Sampleset.res | 8 +- .../src/rescript/FR/FR_Scoring.res | 24 +-- .../FunctionRegistry_Core.res | 151 ++++-------------- .../FunctionRegistry_Helpers.res | 78 +++++---- 13 files changed, 156 insertions(+), 233 deletions(-) diff --git a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res index 34a09172..fd1ec78e 100644 --- a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res +++ b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res @@ -80,6 +80,13 @@ describe("FunctionRegistry Library", () => { "SampleSet.toList(SampleSet.mapN([SampleSet.fromList([1,2,3,4,5,6]), SampleSet.fromList([6, 5, 4, 3, 2, 1])], {|x| x[0] > x[1] ? x[0] : x[1]}))", "Ok([6,5,4,4,5,6])", ) + + testEvalToBe("Dict.merge({a: 1, b: 2}, {b: 3, c: 4, d: 5})", "Ok({a: 1,b: 3,c: 4,d: 5})") + testEvalToBe("Dict.mergeMany([{a: 1, b: 2}, {c: 3, d: 4}, {c: 5, e: 6}])", "Ok({a: 1,b: 2,c: 5,d: 4,e: 6})") + testEvalToBe("Dict.keys({a: 1, b: 2})", "Ok(['a','b'])") + testEvalToBe("Dict.values({a: 1, b: 2})", "Ok([1,2])") + testEvalToBe("Dict.toList({a: 1, b: 2})", "Ok([['a',1],['b',2]])") + testEvalToBe("Dict.fromList([['a', 1], ['b', 2]])", "Ok({a: 1,b: 2})") }) describe("Fn auto-testing", () => { diff --git a/packages/squiggle-lang/scripts/lib.mjs b/packages/squiggle-lang/scripts/lib.mjs index ffa1d84f..6f778769 100644 --- a/packages/squiggle-lang/scripts/lib.mjs +++ b/packages/squiggle-lang/scripts/lib.mjs @@ -13,7 +13,7 @@ export const measure = (cb, times = 1) => { export const red = (str) => `\x1b[31m${str}\x1b[0m`; export const green = (str) => `\x1b[32m${str}\x1b[0m`; -export const run = (src, { output, sampleCount }) => { +export const run = (src, { output, sampleCount } = {}) => { const project = SqProject.create(); if (sampleCount) { project.setEnvironment({ diff --git a/packages/squiggle-lang/scripts/run.mjs b/packages/squiggle-lang/scripts/run.mjs index bc17314b..6dde265f 100755 --- a/packages/squiggle-lang/scripts/run.mjs +++ b/packages/squiggle-lang/scripts/run.mjs @@ -7,4 +7,6 @@ if (!src) { } console.log(`Running ${src}`); -run(src); +const sampleCount = process.env.SAMPLE_COUNT; + +run(src, { output: true, sampleCount }); diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Dict.res b/packages/squiggle-lang/src/rescript/FR/FR_Dict.res index 2f36871c..f1f258ee 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Dict.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Dict.res @@ -29,10 +29,6 @@ module Internals = { ->E.R2.fmap(Belt.Map.String.fromArray) ->E.R2.fmap(Wrappers.evRecord) - let merge = (a: t, b: t): Reducer_T.value => IEvRecord( - Belt.Map.String.merge(a, b, (_, _, c) => c), - ) - //Belt.Map.String has a function for mergeMany, but I couldn't understand how to use it yet. let mergeMany = (a: array): Reducer_T.value => { let mergedValues = @@ -54,8 +50,8 @@ let library = [ ~inputs=[FRTypeDict(FRTypeAny), FRTypeDict(FRTypeAny)], ~run=(inputs, _, _, _) => { switch inputs { - | [IEvRecord(d1), IEvRecord(d2)] => Internals.merge(d1, d2)->Ok - | _ => Error(impossibleError) + | [IEvRecord(d1), IEvRecord(d2)] => Internals.mergeMany([d1, d2])->Ok + | _ => impossibleError->Error } }, (), @@ -63,7 +59,7 @@ let library = [ ], (), ), - //TODO: Change to use new mergeMany() function. + Function.make( ~name="mergeMany", ~nameSpace, @@ -74,14 +70,17 @@ let library = [ FnDefinition.make( ~name="mergeMany", ~inputs=[FRTypeArray(FRTypeDict(FRTypeAny))], - ~run=(_, inputs, _, _) => - inputs - ->Prepare.ToTypedArray.dicts - ->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.errMap(e => e->Reducer_ErrorValue.REOther), + ~run=(inputs, _, _, _) => { + switch inputs { + | [IEvArray(dicts)] => { + dicts->Belt.Array.map(dictValue => switch dictValue { + | IEvRecord(dict) => dict + | _ => impossibleError->Reducer_ErrorValue.toException + })->Internals.mergeMany->Ok + } + | _ => impossibleError->Error + } + }, (), ), ], diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Dist.res b/packages/squiggle-lang/src/rescript/FR/FR_Dist.res index 1ee92c87..1ff4c3c5 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Dist.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Dist.res @@ -22,7 +22,7 @@ module DistributionCreation = { FnDefinition.make( ~name, ~inputs=[FRTypeDistOrNumber, FRTypeDistOrNumber], - ~run=(_, inputs, env, _) => + ~run=(inputs, _, env, _) => inputs->Prepare.ToValueTuple.twoDistOrNumber->process(~fn, ~env), (), ) @@ -32,8 +32,8 @@ module DistributionCreation = { FnDefinition.make( ~name, ~inputs=[FRTypeRecord([("p5", FRTypeDistOrNumber), ("p95", FRTypeDistOrNumber)])], - ~run=(_, inputs, env, _) => - inputs->Prepare.ToValueTuple.Record.twoDistOrNumber->process(~fn, ~env), + ~run=(inputs, _, env, _) => + inputs->Prepare.ToValueTuple.Record.twoDistOrNumber(("p5", "p95"))->process(~fn, ~env), (), ) } @@ -42,8 +42,8 @@ module DistributionCreation = { FnDefinition.make( ~name, ~inputs=[FRTypeRecord([("mean", FRTypeDistOrNumber), ("stdev", FRTypeDistOrNumber)])], - ~run=(_, inputs, env, _) => - inputs->Prepare.ToValueTuple.Record.twoDistOrNumber->process(~fn, ~env), + ~run=(inputs, _, env, _) => + inputs->Prepare.ToValueTuple.Record.twoDistOrNumber(("mean", "stdev"))->process(~fn, ~env), (), ) } @@ -60,7 +60,7 @@ module DistributionCreation = { FnDefinition.make( ~name, ~inputs=[FRTypeDistOrNumber], - ~run=(_, inputs, env, _) => + ~run=(inputs, _, env, _) => inputs->Prepare.ToValueTuple.oneDistOrNumber->process(~fn, ~env), (), ) diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Fn.res b/packages/squiggle-lang/src/rescript/FR/FR_Fn.res index 86db7edc..efd64bff 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Fn.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Fn.res @@ -7,12 +7,12 @@ module Declaration = { ("inputs", FRTypeArray(FRTypeRecord([("min", FRTypeNumber), ("max", FRTypeNumber)]))), ]) - let fromExpressionValue = (e: frValue): result => { - switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.twoArgs([e]) { - | Ok([FRValueLambda(lambda), FRValueArray(inputs)]) => { + let fromExpressionValue = (e: Reducer_T.value): result => { + switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.twoArgs([e], ("fn", "inputs")) { + | Ok([IEvLambda(lambda), IEvArray(inputs)]) => { open FunctionRegistry_Helpers.Prepare let getMinMax = arg => - ToValueArray.Record.toArgs([arg]) + ToValueArray.Record.twoArgs([arg], ("min", "max")) ->E.R.bind(ToValueTuple.twoNumbers) ->E.R2.fmap(((min, max)) => Declaration.ContinuousFloatArg.make(min, max)) inputs @@ -49,7 +49,7 @@ let library = [ FnDefinition.make( ~name="declare", ~inputs=[Declaration.frType], - ~run=(_, inputs, _, _) => { + ~run=(inputs, _, _, _) => { inputs->getOrError(0)->E.R.bind(Declaration.fromExpressionValue)->E.R2.errMap(wrapError) }, (), diff --git a/packages/squiggle-lang/src/rescript/FR/FR_List.res b/packages/squiggle-lang/src/rescript/FR/FR_List.res index 081d453a..f4942b00 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_List.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_List.res @@ -107,11 +107,11 @@ let library = [ FnDefinition.make( ~name="upTo", ~inputs=[FRTypeNumber, FRTypeNumber], - ~run=(_, inputs, _, _) => - inputs - ->Prepare.ToValueTuple.twoNumbers - ->E.R2.fmap(((low, high)) => Internals.upTo(low, high)) - ->E.R2.errMap(wrapError), + ~run=(inputs, _, _, _) => + switch inputs { + | [IEvNumber(low), IEvNumber(high)] => Internals.upTo(low, high)->Ok + | _ => impossibleError->Error + }, (), ), ], diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Number.res b/packages/squiggle-lang/src/rescript/FR/FR_Number.res index 6e5426ac..91146ac5 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Number.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Number.res @@ -9,8 +9,9 @@ module ArrayNumberDist = { FnDefinition.make( ~name, ~inputs=[FRTypeArray(FRTypeNumber)], - ~run=(_, inputs, _, _) => - Prepare.ToTypedArray.numbers(inputs) + ~run=(inputs, _, _, _) => + inputs + ->Prepare.ToTypedArray.numbers ->E.R.bind(r => E.A.length(r) === 0 ? Error("List is empty") : Ok(r)) ->E.R.bind(fn) ->E.R2.errMap(wrapError), diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res b/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res index 54b8706d..dc428f0c 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res @@ -4,21 +4,28 @@ open FunctionRegistry_Helpers let nameSpace = "PointSet" let requiresNamespace = true -let inputsTodist = (inputs: array, makeDist) => { - let array = inputs->getOrError(0)->E.R.bind(Prepare.ToValueArray.Array.openA) - let xyCoords = - array->E.R.bind(xyCoords => - xyCoords - ->E.A2.fmap(xyCoord => - [xyCoord]->Prepare.ToValueArray.Record.twoArgs->E.R.bind(Prepare.ToValueTuple.twoNumbers) - ) - ->E.A.R.firstErrorOrOpen - ) - 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)))) - expressionValue +let inputsToDist = (inputs: array, xyShapeToPointSetDist) => { + // TODO - rewritein more functional/functor-based style + switch inputs { + | [IEvArray(items)] => { + items->Belt.Array.map( + item => + switch item { + | IEvRecord(map) => { + let xValue = map->Belt.Map.String.getExn("x") + let yValue = map->Belt.Map.String.getExn("y") + switch (xValue, yValue) { + | (IEvNumber(x), IEvNumber(y)) => (x, y) + | _ => impossibleError->Reducer_ErrorValue.toException + } + } + | _ => impossibleError->Reducer_ErrorValue.toException + } + )->Ok->E.R.bind(r => r->XYShape.T.makeFromZipped->E.R2.errMap(XYShape.Error.toString)) + ->E.R2.fmap(r => Reducer_T.IEvDistribution(PointSet(r->xyShapeToPointSetDist))) + } + | _ => impossibleError->Reducer_ErrorValue.toException + } } module Internal = { @@ -53,9 +60,9 @@ let library = [ FnDefinition.make( ~name="fromDist", ~inputs=[FRTypeDist], - ~run=(_, inputs, env, _) => + ~run=(inputs, _, env, _) => switch inputs { - | [FRValueDist(dist)] => + | [IEvDistribution(dist)] => GenericDist.toPointSet( dist, ~xyPointLength=env.xyPointLength, @@ -110,8 +117,8 @@ let library = [ FnDefinition.make( ~name="makeContinuous", ~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))], - ~run=(_, inputs, _, _) => - inputsTodist(inputs, r => Continuous(Continuous.make(r)))->E.R2.errMap(wrapError), + ~run=(inputs, _, _, _) => + inputsToDist(inputs, r => Continuous(Continuous.make(r)))->E.R2.errMap(wrapError), (), ), ], @@ -134,8 +141,8 @@ let library = [ FnDefinition.make( ~name="makeDiscrete", ~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))], - ~run=(_, inputs, _, _) => - inputsTodist(inputs, r => Discrete(Discrete.make(r)))->E.R2.errMap(wrapError), + ~run=(inputs, _, _, _) => + inputsToDist(inputs, r => Discrete(Discrete.make(r)))->E.R2.errMap(wrapError), (), ), ], diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res b/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res index 49f069ef..f21a6fde 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res @@ -89,9 +89,9 @@ let libaryBase = [ FnDefinition.make( ~name="fromDist", ~inputs=[FRTypeDist], - ~run=(_, inputs, environment, _) => + ~run=(inputs, _, environment, _) => switch inputs { - | [FRValueDist(dist)] => + | [IEvDistribution(dist)] => GenericDist.toSampleSetDist(dist, environment.sampleCount) ->E.R2.fmap(Wrappers.sampleSet) ->E.R2.fmap(Wrappers.evDistribution) @@ -113,9 +113,9 @@ let libaryBase = [ FnDefinition.make( ~name="fromList", ~inputs=[FRTypeArray(FRTypeNumber)], - ~run=(_, inputs, _, _) => { + ~run=(inputs, _, _, _) => { let sampleSet = - Prepare.ToTypedArray.numbers(inputs) |> E.R2.bind(r => + inputs->Prepare.ToTypedArray.numbers |> E.R2.bind(r => SampleSetDist.make(r)->E.R2.errMap(_ => "AM I HERE? WHYERE AMI??") ) sampleSet diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Scoring.res b/packages/squiggle-lang/src/rescript/FR/FR_Scoring.res index 0f9b5811..450b9d63 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Scoring.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Scoring.res @@ -30,14 +30,14 @@ let library = [ ("prior", FRTypeDist), ]), ], - ~run=(_, inputs, environment, _) => { - switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.threeArgs(inputs) { - | Ok([FRValueDist(estimate), FRValueDistOrNumber(FRValueDist(d)), FRValueDist(prior)]) => + ~run=(inputs, _, environment, _) => { + switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.threeArgs(inputs, ("estimate", "answer", "prior")) { + | Ok([IEvDistribution(estimate), IEvDistribution(d), IEvDistribution(prior)]) => runScoring(estimate, Score_Dist(d), Some(prior), environment) | Ok([ - FRValueDist(estimate), - FRValueDistOrNumber(FRValueNumber(d)), - FRValueDist(prior), + IEvDistribution(estimate), + IEvNumber(d), + IEvDistribution(prior), ]) => runScoring(estimate, Score_Scalar(d), Some(prior), environment) | Error(e) => Error(e->FunctionRegistry_Helpers.wrapError) @@ -49,11 +49,11 @@ let library = [ FnDefinition.make( ~name="logScore", ~inputs=[FRTypeRecord([("estimate", FRTypeDist), ("answer", FRTypeDistOrNumber)])], - ~run=(_, inputs, environment, _) => { - switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.twoArgs(inputs) { - | Ok([FRValueDist(estimate), FRValueDistOrNumber(FRValueDist(d))]) => + ~run=(inputs, _, environment, _) => { + switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.twoArgs(inputs, ("estimate", "answer")) { + | Ok([IEvDistribution(estimate), IEvDistribution(d)]) => runScoring(estimate, Score_Dist(d), None, environment) - | Ok([FRValueDist(estimate), FRValueDistOrNumber(FRValueNumber(d))]) => + | Ok([IEvDistribution(estimate), IEvNumber(d)]) => runScoring(estimate, Score_Scalar(d), None, environment) | Error(e) => Error(e->FunctionRegistry_Helpers.wrapError) | _ => Error(FunctionRegistry_Helpers.impossibleError) @@ -74,9 +74,9 @@ let library = [ FnDefinition.make( ~name="klDivergence", ~inputs=[FRTypeDist, FRTypeDist], - ~run=(_, inputs, environment, _) => { + ~run=(inputs, _, environment, _) => { switch inputs { - | [FRValueDist(estimate), FRValueDist(d)] => + | [IEvDistribution(estimate), IEvDistribution(d)] => runScoring(estimate, Score_Dist(d), None, environment) | _ => Error(FunctionRegistry_Helpers.impossibleError) } diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res index 4ae50fa3..128d0b8e 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res @@ -23,35 +23,14 @@ type rec frType = and frTypeRecord = array and frTypeRecordParam = (string, frType) -/* - Function Registry "Value". A type, with the information of that type. - Like, #Float(40.0) -*/ -type rec frValue = - | FRValueNumber(float) - | FRValueBool(bool) - | FRValueDate(Js.Date.t) - | FRValueTimeDuration(float) - | FRValueDist(DistributionTypes.genericDist) - | FRValueArray(array) - | FRValueDistOrNumber(frValueDistOrNumber) - | FRValueRecord(frValueRecord) - | FRValueLambda(Reducer_T.lambdaValue) - | FRValueString(string) - | FRValueVariant(string) - | FRValueAny(frValue) - | FRValueDict(Js.Dict.t) -and frValueRecord = array -and frValueRecordParam = (string, frValue) -and frValueDictParam = (string, frValue) -and frValueDistOrNumber = FRValueNumber(float) | FRValueDist(DistributionTypes.genericDist) +type frValueDistOrNumber = FRValueNumber(float) | FRValueDist(DistributionTypes.genericDist) type fnDefinition = { name: string, inputs: array, run: ( array, - array, + unit, Reducer_T.environment, Reducer_T.reducerFn, ) => result, @@ -91,104 +70,43 @@ module FRType = { | FRTypeAny => `any` } - let rec toFrValue = (r: Reducer_T.value): option => - // not all value variants are supported, but it's not important (we'll probably deprecate frValues soon anyway) - switch r { - | IEvNumber(f) => Some(FRValueNumber(f)) - | IEvString(f) => Some(FRValueString(f)) - | IEvDistribution(f) => Some(FRValueDistOrNumber(FRValueDist(f))) - | IEvLambda(f) => Some(FRValueLambda(f)) - | IEvArray(elements) => - elements->E.A2.fmap(toFrValue)->E.A.O.openIfAllSome->E.O2.fmap(r => FRValueArray(r)) - | IEvRecord(map) => - Belt.Map.String.toArray(map) - ->E.A2.fmap(((key, item)) => item->toFrValue->E.O2.fmap(o => (key, o))) - ->E.A.O.openIfAllSome - ->E.O2.fmap(r => FRValueRecord(r)) - | _ => None - } - - let rec matchWithExpressionValue = (t: t, r: Reducer_T.value): option => + let rec matchWithValue = (t: t, r: Reducer_T.value): bool => switch (t, r) { - | (FRTypeAny, f) => toFrValue(f) - | (FRTypeString, IEvString(f)) => Some(FRValueString(f)) - | (FRTypeNumber, IEvNumber(f)) => Some(FRValueNumber(f)) - | (FRTypeBool, IEvBool(f)) => Some(FRValueBool(f)) - | (FRTypeDate, IEvDate(f)) => Some(FRValueDate(f)) - | (FRTypeTimeDuration, IEvTimeDuration(f)) => Some(FRValueTimeDuration(f)) - | (FRTypeDistOrNumber, IEvNumber(f)) => Some(FRValueDistOrNumber(FRValueNumber(f))) - | (FRTypeDistOrNumber, IEvDistribution(Symbolic(#Float(f)))) => - Some(FRValueDistOrNumber(FRValueNumber(f))) - | (FRTypeDistOrNumber, IEvDistribution(f)) => Some(FRValueDistOrNumber(FRValueDist(f))) - | (FRTypeDist, IEvDistribution(f)) => Some(FRValueDist(f)) - | (FRTypeNumeric, IEvNumber(f)) => Some(FRValueNumber(f)) - | (FRTypeNumeric, IEvDistribution(Symbolic(#Float(f)))) => Some(FRValueNumber(f)) - | (FRTypeLambda, IEvLambda(f)) => Some(FRValueLambda(f)) + | (FRTypeAny, _) => true + | (FRTypeString, IEvString(_)) => true + | (FRTypeNumber, IEvNumber(_)) => true + | (FRTypeBool, IEvBool(_)) => true + | (FRTypeDate, IEvDate(_)) => true + | (FRTypeTimeDuration, IEvTimeDuration(_)) => true + | (FRTypeDistOrNumber, IEvNumber(_)) => true + | (FRTypeDistOrNumber, IEvDistribution(_)) => true + | (FRTypeDist, IEvDistribution(_)) => true + | (FRTypeNumeric, IEvNumber(_)) => true + | (FRTypeNumeric, IEvDistribution(Symbolic(#Float(_)))) => true + | (FRTypeLambda, IEvLambda(_)) => true | (FRTypeArray(intendedType), IEvArray(elements)) => { - let el = elements->E.A2.fmap(matchWithExpressionValue(intendedType)) - E.A.O.openIfAllSome(el)->E.O2.fmap(r => FRValueArray(r)) + elements->Belt.Array.every(v => matchWithValue(intendedType, v)) } | (FRTypeDict(r), IEvRecord(map)) => - map - ->Belt.Map.String.toArray - ->E.A2.fmap(((key, item)) => matchWithExpressionValue(r, item)->E.O2.fmap(o => (key, o))) - ->E.A.O.openIfAllSome - ->E.O2.fmap(r => FRValueDict(Js.Dict.fromArray(r))) + map->Belt.Map.String.valuesToArray->Belt.Array.every(v => matchWithValue(r, v)) | (FRTypeRecord(recordParams), IEvRecord(map)) => { - let getAndMatch = (name, input) => - Belt.Map.String.get(map, name)->E.O.bind(matchWithExpressionValue(input)) - //All names in the type must be present. If any are missing, the corresponding - //value will be None, and this function would return None. - let namesAndValues: array> = - recordParams->E.A2.fmap(((name, input)) => - getAndMatch(name, input)->E.O2.fmap(match => (name, match)) - ) - namesAndValues->E.A.O.openIfAllSome->E.O2.fmap(r => FRValueRecord(r)) - } - | _ => None + recordParams->Belt.Array.every(((name, input)) => { + switch map->Belt.Map.String.get(name) { + | Some(v) => matchWithValue(input, v) + | None => false + } + }) + } + | _ => false } - let rec matchReverse = (e: frValue): Reducer_T.value => - switch e { - | FRValueNumber(f) => IEvNumber(f) - | FRValueBool(f) => IEvBool(f) - | FRValueDate(f) => IEvDate(f) - | FRValueTimeDuration(f) => IEvTimeDuration(f) - | FRValueDistOrNumber(FRValueNumber(n)) => IEvNumber(n) - | FRValueDistOrNumber(FRValueDist(n)) => IEvDistribution(n) - | FRValueDist(dist) => IEvDistribution(dist) - | FRValueArray(elements) => IEvArray(elements->E.A2.fmap(matchReverse)) - | FRValueRecord(frValueRecord) => { - let map = - frValueRecord - ->E.A2.fmap(((name, value)) => (name, matchReverse(value))) - ->Belt.Map.String.fromArray - IEvRecord(map) - } - | FRValueDict(frValueRecord) => { - let map = - frValueRecord - ->Js.Dict.entries - ->E.A2.fmap(((name, value)) => (name, matchReverse(value))) - ->Belt.Map.String.fromArray - IEvRecord(map) - } - | FRValueLambda(l) => IEvLambda(l) - | FRValueString(string) => IEvString(string) - | FRValueVariant(string) => IEvString(string) - | FRValueAny(f) => matchReverse(f) - } - - let matchWithExpressionValueArray = (inputs: array, args: array): option< - array, - > => { + let matchWithValueArray = (inputs: array, args: array): bool => { let isSameLength = E.A.length(inputs) == E.A.length(args) if !isSameLength { - None + false } else { E.A.zip(inputs, args) - ->E.A2.fmap(((input, arg)) => matchWithExpressionValue(input, arg)) - ->E.A.O.openIfAllSome + ->Belt.Array.every(((input, arg)) => matchWithValue(input, arg)) } } } @@ -202,11 +120,7 @@ module FnDefinition = { } let isMatch = (t: t, args: array) => { - let argValues = FRType.matchWithExpressionValueArray(t.inputs, args) - switch argValues { - | Some(_) => true - | None => false - } + FRType.matchWithValueArray(t.inputs, args) } let run = ( @@ -215,10 +129,9 @@ module FnDefinition = { env: Reducer_T.environment, reducer: Reducer_T.reducerFn, ) => { - let argValues = FRType.matchWithExpressionValueArray(t.inputs, args) - switch argValues { - | Some(values) => t.run(args, values, env, reducer) - | None => REOther("Incorrect Types")->Error + switch t->isMatch(args) { + | true => t.run(args, (), env, reducer) + | false => REOther("Incorrect Types")->Error } } diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res index 3edbe5da..3b1bd7d7 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res @@ -21,27 +21,30 @@ module Wrappers = { let getOrError = (a, g) => E.A.get(a, g) |> E.O.toResult(impossibleErrorString) module Prepare = { - type t = frValue - type ts = array + type t = value + type ts = array type err = string module ToValueArray = { module Record = { - let twoArgs = (inputs: ts): result => + let twoArgs = (inputs: ts, (arg1: string, arg2: string)): result => switch inputs { - | [FRValueRecord([(_, n1), (_, n2)])] => Ok([n1, n2]) + | [IEvRecord(map)] => { + let n1 = map->Belt.Map.String.getExn(arg1) + let n2 = map->Belt.Map.String.getExn(arg2) + Ok([n1, n2]) + } | _ => Error(impossibleErrorString) } - let threeArgs = (inputs: ts): result => + let threeArgs = (inputs: ts, (arg1: string, arg2: string, arg3: string)): result => switch inputs { - | [FRValueRecord([(_, n1), (_, n2), (_, n3)])] => Ok([n1, n2, n3]) - | _ => Error(impossibleErrorString) + | [IEvRecord(map)] => { + let n1 = map->Belt.Map.String.getExn(arg1) + let n2 = map->Belt.Map.String.getExn(arg2) + let n3 = map->Belt.Map.String.getExn(arg3) + Ok([n1, n2, n3]) } - - let toArgs = (inputs: ts): result => - switch inputs { - | [FRValueRecord(args)] => args->E.A2.fmap(((_, b)) => b)->Ok | _ => Error(impossibleErrorString) } } @@ -49,13 +52,13 @@ module Prepare = { module Array = { let openA = (inputs: t): result => switch inputs { - | FRValueArray(n) => Ok(n) + | IEvArray(n) => Ok(n) | _ => Error(impossibleErrorString) } let arrayOfArrays = (inputs: t): result, err> => switch inputs { - | FRValueArray(n) => n->E.A2.fmap(openA)->E.A.R.firstErrorOrOpen + | IEvArray(n) => n->E.A2.fmap(openA)->E.A.R.firstErrorOrOpen | _ => Error(impossibleErrorString) } } @@ -64,7 +67,10 @@ module Prepare = { module ToValueTuple = { let twoDistOrNumber = (values: ts): result<(frValueDistOrNumber, frValueDistOrNumber), err> => { switch values { - | [FRValueDistOrNumber(a1), FRValueDistOrNumber(a2)] => Ok(a1, a2) + | [IEvDistribution(a1), IEvDistribution(a2)] => Ok(FRValueDist(a1), FRValueDist(a2)) + | [IEvDistribution(a1), IEvNumber(a2)] => Ok(FRValueDist(a1), FRValueNumber(a2)) + | [IEvNumber(a1), IEvDistribution(a2)] => Ok(FRValueNumber(a1), FRValueDist(a2)) + | [IEvNumber(a1), IEvNumber(a2)] => Ok(FRValueNumber(a1), FRValueNumber(a2)) | _ => Error(impossibleErrorString) } } @@ -74,66 +80,54 @@ module Prepare = { err, > => { switch values { - | [FRValueDist(a1), FRValueDist(a2)] => Ok(a1, a2) + | [IEvDistribution(a1), IEvDistribution(a2)] => Ok(a1, a2) | _ => Error(impossibleErrorString) } } let twoNumbers = (values: ts): result<(float, float), err> => { switch values { - | [FRValueNumber(a1), FRValueNumber(a2)] => Ok(a1, a2) + | [IEvNumber(a1), IEvNumber(a2)] => Ok(a1, a2) | _ => Error(impossibleErrorString) } } let threeNumbers = (values: ts): result<(float, float, float), err> => { switch values { - | [FRValueNumber(a1), FRValueNumber(a2), FRValueNumber(a3)] => Ok(a1, a2, a3) + | [IEvNumber(a1), IEvNumber(a2), IEvNumber(a3)] => Ok(a1, a2, a3) | _ => Error(impossibleErrorString) } } let oneDistOrNumber = (values: ts): result => { switch values { - | [FRValueDistOrNumber(a1)] => Ok(a1) + | [IEvNumber(a1)] => FRValueNumber(a1)->Ok + | [IEvDistribution(a2)] => FRValueDist(a2)->Ok | _ => Error(impossibleErrorString) } } module Record = { - let twoDistOrNumber = (values: ts): result<(frValueDistOrNumber, frValueDistOrNumber), err> => - values->ToValueArray.Record.twoArgs->E.R.bind(twoDistOrNumber) + let twoDistOrNumber = (values: ts, labels: (string, string)): result<(frValueDistOrNumber, frValueDistOrNumber), err> => + values->ToValueArray.Record.twoArgs(labels)->E.R.bind(twoDistOrNumber) - let twoDist = (values: ts): result< + let twoDist = (values: ts, labels: (string, string)): result< (DistributionTypes.genericDist, DistributionTypes.genericDist), err, - > => values->ToValueArray.Record.twoArgs->E.R.bind(twoDist) + > => values->ToValueArray.Record.twoArgs(labels)->E.R.bind(twoDist) } } - module ToArrayRecordPairs = { - let twoArgs = (input: t): result, err> => { - let array = input->ToValueArray.Array.openA - let pairs = - array->E.R.bind(pairs => - pairs - ->E.A2.fmap(xyCoord => [xyCoord]->ToValueArray.Record.twoArgs) - ->E.A.R.firstErrorOrOpen - ) - pairs - } - } - - let oneNumber = (values: t): result => { - switch values { - | FRValueNumber(a1) => Ok(a1) + let oneNumber = (value: t): result => { + switch value { + | IEvNumber(a1) => Ok(a1) | _ => Error(impossibleErrorString) } } - let oneDict = (values: t): result, err> => { - switch values { - | FRValueDict(a1) => Ok(a1) + let oneDict = (value: t): result => { + switch value { + | IEvRecord(a1) => Ok(a1) | _ => Error(impossibleErrorString) } } @@ -145,7 +139,7 @@ module Prepare = { inputs->getOrError(0)->E.R.bind(ToValueArray.Array.openA)->E.R.bind(openNumbers) } - let dicts = (inputs: ts): Belt.Result.t>, err> => { + let dicts = (inputs: ts): Belt.Result.t, err> => { let openDicts = (elements: array) => elements->E.A2.fmap(oneDict)->E.A.R.firstErrorOrOpen inputs->getOrError(0)->E.R.bind(ToValueArray.Array.openA)->E.R.bind(openDicts) } From e07236c22d7cb8fbda30d6d43e9a4601ecf9c7f5 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Tue, 20 Sep 2022 20:54:26 +0400 Subject: [PATCH 34/46] fix scripts, support SAMPLE_COUNT --- packages/squiggle-lang/scripts/lib.mjs | 2 +- packages/squiggle-lang/scripts/run.mjs | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/squiggle-lang/scripts/lib.mjs b/packages/squiggle-lang/scripts/lib.mjs index ffa1d84f..6f778769 100644 --- a/packages/squiggle-lang/scripts/lib.mjs +++ b/packages/squiggle-lang/scripts/lib.mjs @@ -13,7 +13,7 @@ export const measure = (cb, times = 1) => { export const red = (str) => `\x1b[31m${str}\x1b[0m`; export const green = (str) => `\x1b[32m${str}\x1b[0m`; -export const run = (src, { output, sampleCount }) => { +export const run = (src, { output, sampleCount } = {}) => { const project = SqProject.create(); if (sampleCount) { project.setEnvironment({ diff --git a/packages/squiggle-lang/scripts/run.mjs b/packages/squiggle-lang/scripts/run.mjs index bc17314b..6dde265f 100755 --- a/packages/squiggle-lang/scripts/run.mjs +++ b/packages/squiggle-lang/scripts/run.mjs @@ -7,4 +7,6 @@ if (!src) { } console.log(`Running ${src}`); -run(src); +const sampleCount = process.env.SAMPLE_COUNT; + +run(src, { output: true, sampleCount }); From 9f103f5cbe8930cc43956201f99308c012b1f390 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Tue, 20 Sep 2022 21:08:42 +0400 Subject: [PATCH 35/46] 3-arg fnDefinition --- .../src/rescript/FR/FR_Builtin.res | 2 +- .../src/rescript/FR/FR_Danger.res | 6 +++--- .../squiggle-lang/src/rescript/FR/FR_Date.res | 6 +++--- .../squiggle-lang/src/rescript/FR/FR_Dict.res | 12 ++++++------ .../squiggle-lang/src/rescript/FR/FR_Dist.res | 8 ++++---- .../squiggle-lang/src/rescript/FR/FR_Fn.res | 2 +- .../src/rescript/FR/FR_GenericDist.res | 2 +- .../squiggle-lang/src/rescript/FR/FR_List.res | 18 +++++++++--------- .../src/rescript/FR/FR_Number.res | 2 +- .../src/rescript/FR/FR_Pointset.res | 8 ++++---- .../src/rescript/FR/FR_Sampleset.res | 18 +++++++++--------- .../src/rescript/FR/FR_Scoring.res | 6 +++--- .../squiggle-lang/src/rescript/FR/FR_Units.res | 2 +- .../FunctionRegistry/FunctionRegistry_Core.res | 3 +-- .../FunctionRegistry_Helpers.res | 14 +++++++------- 15 files changed, 54 insertions(+), 55 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Builtin.res b/packages/squiggle-lang/src/rescript/FR/FR_Builtin.res index aee18e8b..84e6a50f 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Builtin.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Builtin.res @@ -14,7 +14,7 @@ let makeFnMany = (name: string, definitions: array) => ~nameSpace, ~requiresNamespace=false, ~definitions=definitions->Js.Array2.map(({inputs, fn}) => - FnDefinition.make(~name, ~inputs, ~run=(inputs, _, _, _) => fn(inputs), ()) + FnDefinition.make(~name, ~inputs, ~run=(inputs, _, _) => fn(inputs), ()) ), (), ) diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Danger.res b/packages/squiggle-lang/src/rescript/FR/FR_Danger.res index f457a8f7..2d60f556 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Danger.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Danger.res @@ -165,7 +165,7 @@ module Integration = { FnDefinition.make( ~name="integrateFunctionBetweenWithNumIntegrationPoints", ~inputs=[FRTypeLambda, FRTypeNumber, FRTypeNumber, FRTypeNumber], - ~run=(inputs, _, env, reducer) => { + ~run=(inputs, env, reducer) => { let result = switch inputs { | [_, _, _, IEvNumber(0.0)] => "Integration error 4 in Danger.integrate: Increment can't be 0." @@ -209,7 +209,7 @@ module Integration = { FnDefinition.make( ~name="integrateFunctionBetweenWithEpsilon", ~inputs=[FRTypeLambda, FRTypeNumber, FRTypeNumber, FRTypeNumber], - ~run=(inputs, _, env, reducer) => { + ~run=(inputs, env, reducer) => { let result = switch inputs { | [_, _, _, IEvNumber(0.0)] => "Integration error in Danger.integrate: Increment can't be 0." @@ -403,7 +403,7 @@ module DiminishingReturns = { FnDefinition.make( ~name="optimalAllocationGivenDiminishingMarginalReturnsForManyFunctions", ~inputs=[FRTypeArray(FRTypeLambda), FRTypeNumber, FRTypeNumber], - ~run=(inputs, _, environment, reducer) => + ~run=(inputs, environment, reducer) => switch inputs { | [IEvArray(innerlambdas), IEvNumber(funds), IEvNumber(approximateIncrement)] => { let individuallyWrappedLambdas = E.A.fmap(innerLambda => { diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Date.res b/packages/squiggle-lang/src/rescript/FR/FR_Date.res index bf7e2120..c9732980 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Date.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Date.res @@ -10,7 +10,7 @@ let makeFn = ( ~name, ~nameSpace="", ~requiresNamespace=false, - ~definitions=[FnDefinition.make(~name, ~inputs, ~run=(inputs, _, _, _) => fn(inputs), ())], + ~definitions=[FnDefinition.make(~name, ~inputs, ~run=(inputs, _, _) => fn(inputs), ())], (), ) @@ -23,7 +23,7 @@ let makeNumberToDurationFn = (name: string, fn: float => DateTime.Duration.t) => FnDefinition.make( ~name, ~inputs=[FRTypeNumber], - ~run=(inputs, _, _, _) => + ~run=(inputs, _, _) => switch inputs { | [IEvNumber(t)] => IEvTimeDuration(fn(t))->Ok | _ => Error(impossibleError) @@ -43,7 +43,7 @@ let makeDurationToNumberFn = (name: string, fn: DateTime.Duration.t => float) => FnDefinition.make( ~name, ~inputs=[FRTypeTimeDuration], - ~run=(inputs, _, _, _) => + ~run=(inputs, _, _) => switch inputs { | [IEvTimeDuration(t)] => IEvNumber(fn(t))->Ok | _ => Error(impossibleError) diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Dict.res b/packages/squiggle-lang/src/rescript/FR/FR_Dict.res index f1f258ee..13bcfe33 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Dict.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Dict.res @@ -48,7 +48,7 @@ let library = [ FnDefinition.make( ~name="merge", ~inputs=[FRTypeDict(FRTypeAny), FRTypeDict(FRTypeAny)], - ~run=(inputs, _, _, _) => { + ~run=(inputs, _, _) => { switch inputs { | [IEvRecord(d1), IEvRecord(d2)] => Internals.mergeMany([d1, d2])->Ok | _ => impossibleError->Error @@ -70,7 +70,7 @@ let library = [ FnDefinition.make( ~name="mergeMany", ~inputs=[FRTypeArray(FRTypeDict(FRTypeAny))], - ~run=(inputs, _, _, _) => { + ~run=(inputs, _, _) => { switch inputs { | [IEvArray(dicts)] => { dicts->Belt.Array.map(dictValue => switch dictValue { @@ -96,7 +96,7 @@ let library = [ FnDefinition.make( ~name="keys", ~inputs=[FRTypeDict(FRTypeAny)], - ~run=(inputs, _, _, _) => + ~run=(inputs, _, _) => switch inputs { | [IEvRecord(d1)] => Internals.keys(d1)->Ok | _ => Error(impossibleError) @@ -116,7 +116,7 @@ let library = [ FnDefinition.make( ~name="values", ~inputs=[FRTypeDict(FRTypeAny)], - ~run=(inputs, _, _, _) => + ~run=(inputs, _, _) => switch inputs { | [IEvRecord(d1)] => Internals.values(d1)->Ok | _ => Error(impossibleError) @@ -136,7 +136,7 @@ let library = [ FnDefinition.make( ~name="toList", ~inputs=[FRTypeDict(FRTypeAny)], - ~run=(inputs, _, _, _) => + ~run=(inputs, _, _) => switch inputs { | [IEvRecord(dict)] => dict->Internals.toList->Ok | _ => Error(impossibleError) @@ -156,7 +156,7 @@ let library = [ FnDefinition.make( ~name="fromList", ~inputs=[FRTypeArray(FRTypeArray(FRTypeAny))], - ~run=(inputs, _, _, _) => { + ~run=(inputs, _, _) => { switch inputs { | [IEvArray(items)] => Internals.fromList(items) | _ => Error(impossibleError) diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Dist.res b/packages/squiggle-lang/src/rescript/FR/FR_Dist.res index 1ff4c3c5..3a7504f2 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Dist.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Dist.res @@ -22,7 +22,7 @@ module DistributionCreation = { FnDefinition.make( ~name, ~inputs=[FRTypeDistOrNumber, FRTypeDistOrNumber], - ~run=(inputs, _, env, _) => + ~run=(inputs, env, _) => inputs->Prepare.ToValueTuple.twoDistOrNumber->process(~fn, ~env), (), ) @@ -32,7 +32,7 @@ module DistributionCreation = { FnDefinition.make( ~name, ~inputs=[FRTypeRecord([("p5", FRTypeDistOrNumber), ("p95", FRTypeDistOrNumber)])], - ~run=(inputs, _, env, _) => + ~run=(inputs, env, _) => inputs->Prepare.ToValueTuple.Record.twoDistOrNumber(("p5", "p95"))->process(~fn, ~env), (), ) @@ -42,7 +42,7 @@ module DistributionCreation = { FnDefinition.make( ~name, ~inputs=[FRTypeRecord([("mean", FRTypeDistOrNumber), ("stdev", FRTypeDistOrNumber)])], - ~run=(inputs, _, env, _) => + ~run=(inputs, env, _) => inputs->Prepare.ToValueTuple.Record.twoDistOrNumber(("mean", "stdev"))->process(~fn, ~env), (), ) @@ -60,7 +60,7 @@ module DistributionCreation = { FnDefinition.make( ~name, ~inputs=[FRTypeDistOrNumber], - ~run=(inputs, _, env, _) => + ~run=(inputs, env, _) => inputs->Prepare.ToValueTuple.oneDistOrNumber->process(~fn, ~env), (), ) diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Fn.res b/packages/squiggle-lang/src/rescript/FR/FR_Fn.res index efd64bff..66d20c1f 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Fn.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Fn.res @@ -49,7 +49,7 @@ let library = [ FnDefinition.make( ~name="declare", ~inputs=[Declaration.frType], - ~run=(inputs, _, _, _) => { + ~run=(inputs, _, _) => { inputs->getOrError(0)->E.R.bind(Declaration.fromExpressionValue)->E.R2.errMap(wrapError) }, (), diff --git a/packages/squiggle-lang/src/rescript/FR/FR_GenericDist.res b/packages/squiggle-lang/src/rescript/FR/FR_GenericDist.res index 443e101b..6f98d132 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_GenericDist.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_GenericDist.res @@ -326,7 +326,7 @@ let makeProxyFn = (name: string, inputs: array) => { FnDefinition.make( ~name, ~inputs, - ~run=(inputs, _, env, _) => Old.dispatch((name, inputs), env), + ~run=(inputs, env, _) => Old.dispatch((name, inputs), env), (), ), ], diff --git a/packages/squiggle-lang/src/rescript/FR/FR_List.res b/packages/squiggle-lang/src/rescript/FR/FR_List.res index f4942b00..fb675417 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_List.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_List.res @@ -86,7 +86,7 @@ let library = [ FnDefinition.make( ~name="make", ~inputs=[FRTypeNumber, FRTypeAny], - ~run=(inputs, _, _, _) => { + ~run=(inputs, _, _) => { switch inputs { | [IEvNumber(number), value] => Internals.makeFromNumber(number, value)->Ok | _ => Error(impossibleError) @@ -107,7 +107,7 @@ let library = [ FnDefinition.make( ~name="upTo", ~inputs=[FRTypeNumber, FRTypeNumber], - ~run=(inputs, _, _, _) => + ~run=(inputs, _, _) => switch inputs { | [IEvNumber(low), IEvNumber(high)] => Internals.upTo(low, high)->Ok | _ => impossibleError->Error @@ -126,7 +126,7 @@ let library = [ FnDefinition.make( ~name="first", ~inputs=[FRTypeArray(FRTypeAny)], - ~run=(inputs, _, _, _) => + ~run=(inputs, _, _) => switch inputs { | [IEvArray(array)] => Internals.first(array)->E.R2.errMap(wrapError) | _ => Error(impossibleError) @@ -145,7 +145,7 @@ let library = [ FnDefinition.make( ~name="last", ~inputs=[FRTypeArray(FRTypeAny)], - ~run=(inputs, _, _, _) => + ~run=(inputs, _, _) => switch inputs { | [IEvArray(array)] => Internals.last(array)->E.R2.errMap(wrapError) | _ => Error(impossibleError) @@ -165,7 +165,7 @@ let library = [ FnDefinition.make( ~name="reverse", ~inputs=[FRTypeArray(FRTypeAny)], - ~run=(inputs, _, _, _) => + ~run=(inputs, _, _) => switch inputs { | [IEvArray(array)] => Internals.reverse(array)->Ok | _ => Error(impossibleError) @@ -185,7 +185,7 @@ let library = [ FnDefinition.make( ~name="map", ~inputs=[FRTypeArray(FRTypeAny), FRTypeLambda], - ~run=(inputs, _, env, reducer) => + ~run=(inputs, env, reducer) => switch inputs { | [IEvArray(array), IEvLambda(lambda)] => Ok(Internals.map(array, lambda, env, reducer)) | _ => Error(impossibleError) @@ -204,7 +204,7 @@ let library = [ FnDefinition.make( ~name="reduce", ~inputs=[FRTypeArray(FRTypeAny), FRTypeAny, FRTypeLambda], - ~run=(inputs, _, env, reducer) => + ~run=(inputs, env, reducer) => switch inputs { | [IEvArray(array), initialValue, IEvLambda(lambda)] => Ok(Internals.reduce(array, initialValue, lambda, env, reducer)) @@ -224,7 +224,7 @@ let library = [ FnDefinition.make( ~name="reduceReverse", ~inputs=[FRTypeArray(FRTypeAny), FRTypeAny, FRTypeLambda], - ~run=(inputs, _, env, reducer) => + ~run=(inputs, env, reducer) => switch inputs { | [IEvArray(array), initialValue, IEvLambda(lambda)] => Ok(Internals.reduceReverse(array, initialValue, lambda, env, reducer)) @@ -244,7 +244,7 @@ let library = [ FnDefinition.make( ~name="filter", ~inputs=[FRTypeArray(FRTypeAny), FRTypeLambda], - ~run=(inputs, _, env, reducer) => + ~run=(inputs, env, reducer) => switch inputs { | [IEvArray(array), IEvLambda(lambda)] => Ok(Internals.filter(array, lambda, env, reducer)) diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Number.res b/packages/squiggle-lang/src/rescript/FR/FR_Number.res index 91146ac5..336a3f2b 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Number.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Number.res @@ -9,7 +9,7 @@ module ArrayNumberDist = { FnDefinition.make( ~name, ~inputs=[FRTypeArray(FRTypeNumber)], - ~run=(inputs, _, _, _) => + ~run=(inputs, _, _) => inputs ->Prepare.ToTypedArray.numbers ->E.R.bind(r => E.A.length(r) === 0 ? Error("List is empty") : Ok(r)) diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res b/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res index dc428f0c..8996ac3b 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res @@ -60,7 +60,7 @@ let library = [ FnDefinition.make( ~name="fromDist", ~inputs=[FRTypeDist], - ~run=(inputs, _, env, _) => + ~run=(inputs, env, _) => switch inputs { | [IEvDistribution(dist)] => GenericDist.toPointSet( @@ -89,7 +89,7 @@ let library = [ FnDefinition.make( ~name="mapY", ~inputs=[FRTypeDist, FRTypeLambda], - ~run=(inputs, _, env, reducer) => + ~run=(inputs, env, reducer) => switch inputs { | [IEvDistribution(PointSet(dist)), IEvLambda(lambda)] => Internal.mapY(dist, lambda, env, reducer) @@ -117,7 +117,7 @@ let library = [ FnDefinition.make( ~name="makeContinuous", ~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))], - ~run=(inputs, _, _, _) => + ~run=(inputs, _, _) => inputsToDist(inputs, r => Continuous(Continuous.make(r)))->E.R2.errMap(wrapError), (), ), @@ -141,7 +141,7 @@ let library = [ FnDefinition.make( ~name="makeDiscrete", ~inputs=[FRTypeArray(FRTypeRecord([("x", FRTypeNumeric), ("y", FRTypeNumeric)]))], - ~run=(inputs, _, _, _) => + ~run=(inputs, _, _) => inputsToDist(inputs, r => Discrete(Discrete.make(r)))->E.R2.errMap(wrapError), (), ), diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res b/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res index f21a6fde..5bbfb506 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res @@ -89,7 +89,7 @@ let libaryBase = [ FnDefinition.make( ~name="fromDist", ~inputs=[FRTypeDist], - ~run=(inputs, _, environment, _) => + ~run=(inputs, environment, _) => switch inputs { | [IEvDistribution(dist)] => GenericDist.toSampleSetDist(dist, environment.sampleCount) @@ -113,7 +113,7 @@ let libaryBase = [ FnDefinition.make( ~name="fromList", ~inputs=[FRTypeArray(FRTypeNumber)], - ~run=(inputs, _, _, _) => { + ~run=(inputs, _, _) => { let sampleSet = inputs->Prepare.ToTypedArray.numbers |> E.R2.bind(r => SampleSetDist.make(r)->E.R2.errMap(_ => "AM I HERE? WHYERE AMI??") @@ -138,7 +138,7 @@ let libaryBase = [ FnDefinition.make( ~name="toList", ~inputs=[FRTypeDist], - ~run=(inputs, _, _, _) => + ~run=(inputs, _, _) => switch inputs { | [IEvDistribution(SampleSet(dist))] => dist->E.A2.fmap(Wrappers.evNumber)->Wrappers.evArray->Ok @@ -159,7 +159,7 @@ let libaryBase = [ FnDefinition.make( ~name="fromFn", ~inputs=[FRTypeLambda], - ~run=(inputs, _, environment, reducer) => + ~run=(inputs, environment, reducer) => switch inputs { | [IEvLambda(lambda)] => switch Internal.fromFn(lambda, environment, reducer) { @@ -183,7 +183,7 @@ let libaryBase = [ FnDefinition.make( ~name="map", ~inputs=[FRTypeDist, FRTypeLambda], - ~run=(inputs, _, environment, reducer) => + ~run=(inputs, environment, reducer) => switch inputs { | [IEvDistribution(SampleSet(dist)), IEvLambda(lambda)] => Internal.map1(dist, lambda, environment, reducer) @@ -206,7 +206,7 @@ let libaryBase = [ FnDefinition.make( ~name="map2", ~inputs=[FRTypeDist, FRTypeDist, FRTypeLambda], - ~run=(inputs, _, environment, reducer) => { + ~run=(inputs, environment, reducer) => { switch inputs { | [ IEvDistribution(SampleSet(dist1)), @@ -234,7 +234,7 @@ let libaryBase = [ FnDefinition.make( ~name="map3", ~inputs=[FRTypeDist, FRTypeDist, FRTypeDist, FRTypeLambda], - ~run=(inputs, _, environment, reducer) => + ~run=(inputs, environment, reducer) => switch inputs { | [ IEvDistribution(SampleSet(dist1)), @@ -262,7 +262,7 @@ let libaryBase = [ FnDefinition.make( ~name="mapN", ~inputs=[FRTypeArray(FRTypeDist), FRTypeLambda], - ~run=(inputs, _, environment, reducer) => + ~run=(inputs, environment, reducer) => switch inputs { | [IEvArray(dists), IEvLambda(lambda)] => Internal.mapN(dists, lambda, environment, reducer) @@ -280,7 +280,7 @@ module Comparison = { FnDefinition.make( ~name, ~inputs, - ~run=(inputs, _, _, _) => { + ~run=(inputs, _, _) => { run(inputs) }, (), diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Scoring.res b/packages/squiggle-lang/src/rescript/FR/FR_Scoring.res index 450b9d63..63589e83 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Scoring.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Scoring.res @@ -30,7 +30,7 @@ let library = [ ("prior", FRTypeDist), ]), ], - ~run=(inputs, _, environment, _) => { + ~run=(inputs, environment, _) => { switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.threeArgs(inputs, ("estimate", "answer", "prior")) { | Ok([IEvDistribution(estimate), IEvDistribution(d), IEvDistribution(prior)]) => runScoring(estimate, Score_Dist(d), Some(prior), environment) @@ -49,7 +49,7 @@ let library = [ FnDefinition.make( ~name="logScore", ~inputs=[FRTypeRecord([("estimate", FRTypeDist), ("answer", FRTypeDistOrNumber)])], - ~run=(inputs, _, environment, _) => { + ~run=(inputs, environment, _) => { switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.twoArgs(inputs, ("estimate", "answer")) { | Ok([IEvDistribution(estimate), IEvDistribution(d)]) => runScoring(estimate, Score_Dist(d), None, environment) @@ -74,7 +74,7 @@ let library = [ FnDefinition.make( ~name="klDivergence", ~inputs=[FRTypeDist, FRTypeDist], - ~run=(inputs, _, environment, _) => { + ~run=(inputs, environment, _) => { switch inputs { | [IEvDistribution(estimate), IEvDistribution(d)] => runScoring(estimate, Score_Dist(d), None, environment) diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Units.res b/packages/squiggle-lang/src/rescript/FR/FR_Units.res index 3935b197..8934b5d8 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Units.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Units.res @@ -9,7 +9,7 @@ let makeUnitFn = (name: string, multiplier: float) => { FnDefinition.make( ~name="fromUnit_" ++ name, ~inputs=[FRTypeNumber], - ~run=(inputs, _, _, _) => { + ~run=(inputs, _, _) => { switch inputs { | [IEvNumber(f)] => IEvNumber(f *. multiplier)->Ok | _ => FunctionRegistry_Helpers.impossibleError->Error diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res index 128d0b8e..e6929761 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res @@ -30,7 +30,6 @@ type fnDefinition = { inputs: array, run: ( array, - unit, Reducer_T.environment, Reducer_T.reducerFn, ) => result, @@ -130,7 +129,7 @@ module FnDefinition = { reducer: Reducer_T.reducerFn, ) => { switch t->isMatch(args) { - | true => t.run(args, (), env, reducer) + | true => t.run(args, env, reducer) | false => REOther("Incorrect Types")->Error } } diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res index 3b1bd7d7..a5a0f523 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res @@ -220,7 +220,7 @@ module DefineFn = { FnDefinition.make( ~name, ~inputs=[FRTypeNumber], - ~run=(inputs, _, _, _) => { + ~run=(inputs, _, _) => { switch inputs { | [IEvNumber(x)] => fn(x)->IEvNumber->Ok | _ => Error(impossibleError) @@ -232,7 +232,7 @@ module DefineFn = { FnDefinition.make( ~name, ~inputs=[FRTypeNumber, FRTypeNumber], - ~run=(inputs, _, _, _) => { + ~run=(inputs, _, _) => { switch inputs { | [IEvNumber(x), IEvNumber(y)] => fn(x, y)->IEvNumber->Ok | _ => Error(impossibleError) @@ -244,7 +244,7 @@ module DefineFn = { FnDefinition.make( ~name, ~inputs=[FRTypeNumber, FRTypeNumber, FRTypeNumber], - ~run=(inputs, _, _, _) => { + ~run=(inputs, _, _) => { switch inputs { | [IEvNumber(x), IEvNumber(y), IEvNumber(z)] => fn(x, y, z)->IEvNumber->Ok | _ => Error(impossibleError) @@ -292,7 +292,7 @@ module Make = { FnDefinition.make( ~name, ~inputs=[FRTypeNumber], - ~run=(inputs, _, _, _) => + ~run=(inputs, _, _) => switch inputs { | [IEvNumber(x)] => fn(x)->IEvNumber->Ok | _ => Error(impossibleError) @@ -322,7 +322,7 @@ module Make = { FnDefinition.make( ~name, ~inputs=[FRTypeNumber, FRTypeNumber], - ~run=(inputs, _, _, _) => + ~run=(inputs, _, _) => switch inputs { | [IEvNumber(x), IEvNumber(y)] => fn(x, y)->IEvNumber->Ok | _ => Error(impossibleError) @@ -352,7 +352,7 @@ module Make = { FnDefinition.make( ~name, ~inputs=[FRTypeNumber, FRTypeNumber], - ~run=(inputs, _, _, _) => + ~run=(inputs, _, _) => switch inputs { | [IEvNumber(x), IEvNumber(y)] => fn(x, y)->IEvBool->Ok | _ => Error(impossibleError) @@ -382,7 +382,7 @@ module Make = { FnDefinition.make( ~name, ~inputs=[FRTypeBool, FRTypeBool], - ~run=(inputs, _, _, _) => + ~run=(inputs, _, _) => switch inputs { | [IEvBool(x), IEvBool(y)] => fn(x, y)->IEvBool->Ok | _ => Error(impossibleError) From 5db63fbe9ffe2e1326449ba72d6f7508f4d4c6d3 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Wed, 21 Sep 2022 01:42:54 +0400 Subject: [PATCH 36/46] fastSort in toPointSet conversion --- .../SampleSetDist/SampleSetDist_ToPointSet.res | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res index 81bfc760..7d5498f7 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res @@ -39,6 +39,13 @@ module Internals = { module T = { type t = array + let fastSort = (samples: t): t => { + let typedSamples = samples->Js.TypedArray2.Float64Array.make->Js.TypedArray2.Float64Array.sortInPlace + // why is there no standard function in Resctipt for this? + let typedToArray: Js.TypedArray2.Float64Array.t => t = %raw(`a => Array.from(a)`) + typedToArray(typedSamples) + } + let xWidthToUnitWidth = (samples, outputXYPoints, xWidth) => { let xyPointRange = E.A.Sorted.range(samples)->E.O2.default(0.0) let xyPointWidth = xyPointRange /. float_of_int(outputXYPoints) @@ -62,7 +69,7 @@ let toPointSetDist = ( ~samplingInputs: SamplingInputs.samplingInputs, (), ): Internals.Types.outputs => { - let samples = samples->Js.Array2.copy->Js.Array2.sortInPlaceWith(compare) + let samples = samples->Internals.T.fastSort let minDiscreteToKeep = MagicNumbers.ToPointSet.minDiscreteToKeep(samples) let (continuousPart, discretePart) = E.A.Floats.Sorted.splitContinuousAndDiscreteForMinWeight( From 25dce72f11aa762c9853c96b80f7c2ad05c25f8d Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Wed, 21 Sep 2022 03:03:17 +0400 Subject: [PATCH 37/46] getExn -> get --- packages/squiggle-lang/src/rescript/FR/FR_Pointset.res | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res b/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res index 8996ac3b..4babe231 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res @@ -5,17 +5,17 @@ let nameSpace = "PointSet" let requiresNamespace = true let inputsToDist = (inputs: array, xyShapeToPointSetDist) => { - // TODO - rewritein more functional/functor-based style + // TODO - rewrite in more functional/functor-based style switch inputs { | [IEvArray(items)] => { items->Belt.Array.map( item => switch item { | IEvRecord(map) => { - let xValue = map->Belt.Map.String.getExn("x") - let yValue = map->Belt.Map.String.getExn("y") + let xValue = map->Belt.Map.String.get("x") + let yValue = map->Belt.Map.String.get("y") switch (xValue, yValue) { - | (IEvNumber(x), IEvNumber(y)) => (x, y) + | (Some(IEvNumber(x)), Some(IEvNumber(y))) => (x, y) | _ => impossibleError->Reducer_ErrorValue.toException } } From 59d38f7885240d97a41526401ca4803a39f1ccb7 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Wed, 21 Sep 2022 03:17:25 +0400 Subject: [PATCH 38/46] E.A.Floats.sort uses typed arrays --- .../SampleSetDist/SampleSetDist_ToPointSet.res | 9 +-------- packages/squiggle-lang/src/rescript/Utility/E/E_A.res | 7 ++++--- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res index 7d5498f7..4cf2b868 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res +++ b/packages/squiggle-lang/src/rescript/Distributions/SampleSetDist/SampleSetDist_ToPointSet.res @@ -39,13 +39,6 @@ module Internals = { module T = { type t = array - let fastSort = (samples: t): t => { - let typedSamples = samples->Js.TypedArray2.Float64Array.make->Js.TypedArray2.Float64Array.sortInPlace - // why is there no standard function in Resctipt for this? - let typedToArray: Js.TypedArray2.Float64Array.t => t = %raw(`a => Array.from(a)`) - typedToArray(typedSamples) - } - let xWidthToUnitWidth = (samples, outputXYPoints, xWidth) => { let xyPointRange = E.A.Sorted.range(samples)->E.O2.default(0.0) let xyPointWidth = xyPointRange /. float_of_int(outputXYPoints) @@ -69,7 +62,7 @@ let toPointSetDist = ( ~samplingInputs: SamplingInputs.samplingInputs, (), ): Internals.Types.outputs => { - let samples = samples->Internals.T.fastSort + let samples = samples->E.A.Floats.sort let minDiscreteToKeep = MagicNumbers.ToPointSet.minDiscreteToKeep(samples) let (continuousPart, discretePart) = E.A.Floats.Sorted.splitContinuousAndDiscreteForMinWeight( diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_A.res b/packages/squiggle-lang/src/rescript/Utility/E/E_A.res index 46ada15f..dd7b7c90 100644 --- a/packages/squiggle-lang/src/rescript/Utility/E/E_A.res +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_A.res @@ -229,9 +229,10 @@ module Floats = { let floatCompare: (float, float) => int = compare let sort = t => { - let r = t - r |> Array.fast_sort(floatCompare) - r + let typed = t->Js.TypedArray2.Float64Array.make->Js.TypedArray2.Float64Array.sortInPlace + // why is there no standard function in Resctipt for this? + let typedToArray: Js.TypedArray2.Float64Array.t => t = %raw(`a => Array.from(a)`) + typedToArray(typed) } let getNonFinite = (t: t) => Belt.Array.getBy(t, r => !Js.Float.isFinite(r)) From 824749976e98af72ac2faa243a0f5e9f97ee6bc3 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Wed, 21 Sep 2022 03:19:39 +0400 Subject: [PATCH 39/46] tweaking names --- packages/squiggle-lang/src/rescript/Utility/E/E_A.res | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Utility/E/E_A.res b/packages/squiggle-lang/src/rescript/Utility/E/E_A.res index dd7b7c90..14ba187c 100644 --- a/packages/squiggle-lang/src/rescript/Utility/E/E_A.res +++ b/packages/squiggle-lang/src/rescript/Utility/E/E_A.res @@ -229,10 +229,11 @@ module Floats = { let floatCompare: (float, float) => int = compare let sort = t => { - let typed = t->Js.TypedArray2.Float64Array.make->Js.TypedArray2.Float64Array.sortInPlace + let typedArray = t->Js.TypedArray2.Float64Array.make + typedArray->Js.TypedArray2.Float64Array.sortInPlace->ignore // why is there no standard function in Resctipt for this? - let typedToArray: Js.TypedArray2.Float64Array.t => t = %raw(`a => Array.from(a)`) - typedToArray(typed) + let typedArrayToArray: Js.TypedArray2.Float64Array.t => t = %raw(`a => Array.from(a)`) + typedArrayToArray(typedArray) } let getNonFinite = (t: t) => Belt.Array.getBy(t, r => !Js.Float.isFinite(r)) From 4be410e33b4af551c71fda304fd6c7b1cba94c9e Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Wed, 21 Sep 2022 03:41:12 +0400 Subject: [PATCH 40/46] 0.5.0-alpha.2 --- packages/components/package.json | 4 ++-- packages/squiggle-lang/package.json | 2 +- packages/vscode-ext/package.json | 2 +- packages/website/package.json | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/components/package.json b/packages/components/package.json index 21914316..2db664af 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,6 +1,6 @@ { "name": "@quri/squiggle-components", - "version": "0.5.0-alpha.1", + "version": "0.5.0-alpha.2", "license": "MIT", "dependencies": { "@floating-ui/react-dom": "^1.0.0", @@ -8,7 +8,7 @@ "@headlessui/react": "^1.7.2", "@heroicons/react": "^1.0.6", "@hookform/resolvers": "^2.9.8", - "@quri/squiggle-lang": "^0.5.0-alpha.0", + "@quri/squiggle-lang": "^0.5.0-alpha.2", "@react-hook/size": "^2.1.2", "clsx": "^1.2.1", "framer-motion": "^7.3.5", diff --git a/packages/squiggle-lang/package.json b/packages/squiggle-lang/package.json index 62198441..195ddcd2 100644 --- a/packages/squiggle-lang/package.json +++ b/packages/squiggle-lang/package.json @@ -1,6 +1,6 @@ { "name": "@quri/squiggle-lang", - "version": "0.5.0-alpha.0", + "version": "0.5.0-alpha.2", "homepage": "https://squiggle-language.com", "license": "MIT", "scripts": { diff --git a/packages/vscode-ext/package.json b/packages/vscode-ext/package.json index 8dfbeb48..6c5a5a23 100644 --- a/packages/vscode-ext/package.json +++ b/packages/vscode-ext/package.json @@ -3,7 +3,7 @@ "displayName": "Squiggle", "description": "Squiggle language support", "license": "MIT", - "version": "0.5.0-alpha.1", + "version": "0.5.0-alpha.2", "publisher": "QURI", "repository": { "type": "git", diff --git a/packages/website/package.json b/packages/website/package.json index f4f8d2ee..185d6204 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -15,7 +15,7 @@ "@docusaurus/core": "2.1.0", "@docusaurus/preset-classic": "2.1.0", "@heroicons/react": "^1.0.6", - "@quri/squiggle-components": "^0.5.0-alpha.1", + "@quri/squiggle-components": "^0.5.0-alpha.2", "base64-js": "^1.5.1", "clsx": "^1.2.1", "hast-util-is-element": "2.1.2", From c337211af645454f01afe4dc43f4365afdd163cb Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Sat, 24 Sep 2022 20:39:09 +0400 Subject: [PATCH 41/46] rename tests --- .../Reducer_Value_test.res} | 0 .../SquiggleLibrary_Distribution_test.res} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename packages/squiggle-lang/__tests__/{ReducerInterface/ReducerInterface_ExpressionValue_test.res => Reducer/Reducer_Value_test.res} (100%) rename packages/squiggle-lang/__tests__/{ReducerInterface/ReducerInterface_Distribution_test.res => SquiggleLibrary/SquiggleLibrary_Distribution_test.res} (100%) diff --git a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_ExpressionValue_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Value_test.res similarity index 100% rename from packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_ExpressionValue_test.res rename to packages/squiggle-lang/__tests__/Reducer/Reducer_Value_test.res diff --git a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_Distribution_test.res similarity index 100% rename from packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res rename to packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_Distribution_test.res From d3bc08ab9d7c01bc557c4f21149ce8b9fb61a544 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Sat, 24 Sep 2022 21:26:44 +0400 Subject: [PATCH 42/46] remove all type-related code --- .../Reducer_Type_Compile_test.res | 52 ----- ...educer_Type_TypeChecker_arguments_test.res | 41 ---- .../Reducer_Type_TypeChecker_test.res | 73 ------- .../Reducer_Type_switch_replacement_test.res | 125 ------------ packages/squiggle-lang/src/js/SqType.ts | 7 - packages/squiggle-lang/src/js/SqValue.ts | 21 -- .../ForTS_SquiggleValue.res | 23 --- .../ForTS_SquiggleValue_Type.res | 9 - .../ForTS_SquiggleValue_tag.ts | 2 - .../src/rescript/ForTS/ForTS__Types.res | 1 - .../src/rescript/Reducer/Reducer_Bindings.res | 41 ---- .../Reducer_Dispatch_ChainPiece.res | 45 +++-- .../Reducer_Peggy_GeneratedParser.peggy | 79 -------- .../src/rescript/Reducer/Reducer_T.res | 2 - .../Reducer_Type/Reducer_Type_Compile.res | 39 ---- .../Reducer_Type/Reducer_Type_Contracts.res | 45 ----- .../Reducer/Reducer_Type/Reducer_Type_T.res | 117 ----------- .../Reducer_Type/Reducer_Type_TypeBuilder.res | 81 -------- .../Reducer_Type/Reducer_Type_TypeChecker.res | 181 ------------------ .../src/rescript/Reducer/Reducer_Value.res | 14 -- 20 files changed, 24 insertions(+), 974 deletions(-) delete mode 100644 packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_Compile_test.res delete mode 100644 packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res delete mode 100644 packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res delete mode 100644 packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_switch_replacement_test.res delete mode 100644 packages/squiggle-lang/src/js/SqType.ts delete mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Type.res delete mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Compile.res delete mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Contracts.res delete mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_T.res delete mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_TypeBuilder.res delete mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_TypeChecker.res diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_Compile_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_Compile_test.res deleted file mode 100644 index 4c0812fd..00000000 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_Compile_test.res +++ /dev/null @@ -1,52 +0,0 @@ -// module Expression = Reducer_Expression -// module Bindings = Reducer_Bindings -// module T = Reducer_Type_T -// module TypeCompile = Reducer_Type_Compile - -// open Jest -// open Expect - -// let myIevEval = (aTypeSourceCode: string) => -// TypeCompile.ievFromTypeExpression(aTypeSourceCode, Expression.reduceExpressionInProject) -// let myIevEvalToString = (aTypeSourceCode: string) => -// myIevEval(aTypeSourceCode)->Reducer_Value.toStringResult - -// let myIevExpectEqual = (aTypeSourceCode, answer) => -// expect(myIevEvalToString(aTypeSourceCode))->toEqual(answer) - -// let myIevTest = (test, aTypeSourceCode, answer) => -// test(aTypeSourceCode, () => myIevExpectEqual(aTypeSourceCode, answer)) - -// let myTypeEval = (aTypeSourceCode: string) => -// TypeCompile.fromTypeExpression(aTypeSourceCode, Expression.reduceExpressionInProject) -// let myTypeEvalToString = (aTypeSourceCode: string) => myTypeEval(aTypeSourceCode)->T.toStringResult - -// let myTypeExpectEqual = (aTypeSourceCode, answer) => -// expect(myTypeEvalToString(aTypeSourceCode))->toEqual(answer) - -// let myTypeTest = (test, aTypeSourceCode, answer) => -// test(aTypeSourceCode, () => myTypeExpectEqual(aTypeSourceCode, answer)) - -// // | ItTypeIdentifier(string) -// myTypeTest(test, "number", "number") -// myTypeTest(test, "(number)", "number") -// // | ItModifiedType({modifiedType: iType}) -// myIevTest(test, "number<-min(0)", "Ok({min: 0,typeIdentifier: #number,typeTag: 'typeIdentifier'})") -// myTypeTest(test, "number<-min(0)", "number<-min(0)") -// // | ItTypeOr({typeOr: array}) -// myTypeTest(test, "number | string", "(number | string)") -// // | ItTypeFunction({inputs: array, output: iType}) -// myTypeTest(test, "number => number => number", "(number => number => number)") -// // | ItTypeArray({element: iType}) -// myIevTest(test, "[number]", "Ok({element: #number,typeTag: 'typeArray'})") -// myTypeTest(test, "[number]", "[number]") -// // | ItTypeTuple({elements: array}) -// myTypeTest(test, "[number, string]", "[number, string]") -// // | ItTypeRecord({properties: Belt.Map.String.t}) -// myIevTest( -// test, -// "{age: number, name: string}", -// "Ok({properties: {age: #number,name: #string},typeTag: 'typeRecord'})", -// ) -// myTypeTest(test, "{age: number, name: string}", "{age: number, name: string}") - diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res deleted file mode 100644 index 723ff00b..00000000 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_arguments_test.res +++ /dev/null @@ -1,41 +0,0 @@ -// module Bindings = Reducer_Bindings -// module ErrorValue = Reducer_ErrorValue -// module Expression = Reducer_Expression -// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -// module T = Reducer_Type_T -// module TypeChecker = Reducer_Type_TypeChecker - -// open Jest -// open Expect - -// let checkArgumentsSourceCode = (aTypeSourceCode: string, sourceCode: string): result< -// 'v, -// ErrorValue.t, -// > => { -// let reducerFn = Expression.reduceExpressionInProject -// let rResult = -// Expression.BackCompatible.parse(sourceCode)->Belt.Result.map(expr => -// reducerFn(expr, Bindings.emptyBindings, ProjectAccessorsT.identityAccessors) -// ) -// rResult->Belt.Result.flatMap(result => -// switch result { -// | IEvArray(args) => TypeChecker.checkArguments(aTypeSourceCode, args, reducerFn) -// | _ => Js.Exn.raiseError("Arguments has to be an array") -// } -// ) -// } - -// let myCheckArguments = (aTypeSourceCode: string, sourceCode: string): string => -// switch checkArgumentsSourceCode(aTypeSourceCode, sourceCode) { -// | Ok(_) => "Ok" -// | Error(error) => ErrorValue.errorToString(error) -// } - -// let myCheckArgumentsExpectEqual = (aTypeSourceCode, sourceCode, answer) => -// expect(myCheckArguments(aTypeSourceCode, sourceCode))->toEqual(answer) - -// let myCheckArgumentsTest = (test, aTypeSourceCode, sourceCode, answer) => -// test(aTypeSourceCode, () => myCheckArgumentsExpectEqual(aTypeSourceCode, sourceCode, answer)) - -// myCheckArgumentsTest(test, "number=>number=>number", "[1,2]", "Ok") - diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res deleted file mode 100644 index 5f59c60a..00000000 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res +++ /dev/null @@ -1,73 +0,0 @@ -// module Expression = Reducer_Expression -// module ExpressionT = Reducer_Expression_T -// module ErrorValue = Reducer_ErrorValue -// module Bindings = Reducer_Bindings -// module T = Reducer_Type_T -// module TypeChecker = Reducer_Type_TypeChecker -// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T - -// open Jest -// open Expect - -// // In development, you are expected to use TypeChecker.isTypeOf(aTypeSourceCode, result, reducerFn). -// // isTypeOfSourceCode is written to use strings instead of expression values. - -// let isTypeOfSourceCode = (aTypeSourceCode: string, sourceCode: string): result< -// 'v, -// ErrorValue.t, -// > => { -// let reducerFn = Expression.reduceExpressionInProject -// let rResult = -// Expression.BackCompatible.parse(sourceCode)->Belt.Result.map(expr => -// reducerFn(expr, Bindings.emptyBindings, ProjectAccessorsT.identityAccessors) -// ) -// rResult->Belt.Result.flatMap(result => TypeChecker.isTypeOf(aTypeSourceCode, result, reducerFn)) -// } - -// let myTypeCheck = (aTypeSourceCode: string, sourceCode: string): string => -// switch isTypeOfSourceCode(aTypeSourceCode, sourceCode) { -// | Ok(_) => "Ok" -// | Error(error) => ErrorValue.errorToString(error) -// } - -// let myTypeCheckExpectEqual = (aTypeSourceCode, sourceCode, answer) => -// expect(myTypeCheck(aTypeSourceCode, sourceCode))->toEqual(answer) - -// let myTypeCheckTest = (test, aTypeSourceCode, sourceCode, answer) => -// test(aTypeSourceCode, () => myTypeCheckExpectEqual(aTypeSourceCode, sourceCode, answer)) - -// myTypeCheckTest(test, "number", "1", "Ok") -// myTypeCheckTest(test, "number", "'2'", "Expected type: number but got: '2'") -// myTypeCheckTest(test, "string", "3", "Expected type: string but got: 3") -// myTypeCheckTest(test, "string", "'a'", "Ok") -// myTypeCheckTest(test, "[number]", "[1,2,3]", "Ok") -// myTypeCheckTest(test, "[number]", "['a','a','a']", "Expected type: number but got: 'a'") -// myTypeCheckTest(test, "[number]", "[1,'a',3]", "Expected type: number but got: 'a'") -// myTypeCheckTest(test, "[number, string]", "[1,'a']", "Ok") -// myTypeCheckTest(test, "[number, string]", "[1, 2]", "Expected type: string but got: 2") -// myTypeCheckTest( -// test, -// "[number, string, string]", -// "[1,'a']", -// "Expected type: [number, string, string] but got: [1,'a']", -// ) -// myTypeCheckTest( -// test, -// "[number, string]", -// "[1,'a', 3]", -// "Expected type: [number, string] but got: [1,'a',3]", -// ) -// myTypeCheckTest(test, "{age: number, name: string}", "{age: 1, name: 'a'}", "Ok") -// myTypeCheckTest( -// test, -// "{age: number, name: string}", -// "{age: 1, name: 'a', job: 'IT'}", -// "Expected type: {age: number, name: string} but got: {age: 1,job: 'IT',name: 'a'}", -// ) -// myTypeCheckTest(test, "number | string", "1", "Ok") -// myTypeCheckTest(test, "date | string", "1", "Expected type: (date | string) but got: 1") -// myTypeCheckTest(test, "number<-min(10)", "10", "Ok") -// myTypeCheckTest(test, "number<-min(10)", "0", "Expected type: number<-min(10) but got: 0") -// myTypeCheckTest(test, "any", "0", "Ok") -// myTypeCheckTest(test, "any", "'a'", "Ok") - diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_switch_replacement_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_switch_replacement_test.res deleted file mode 100644 index fcba831d..00000000 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_switch_replacement_test.res +++ /dev/null @@ -1,125 +0,0 @@ -// open Jest -// open Expect - -// module DispatchT = Reducer_Dispatch_T -// module Expression = Reducer_Expression -// module ExpressionT = Reducer_Expression_T -// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -// module TypeChecker = Reducer_Type_TypeChecker -// module TypeCompile = Reducer_Type_Compile - -// type errorValue = Reducer_ErrorValue.errorValue - -// // Let's build a function to replace switch statements -// // In dispatchChainPiece, we execute an return the result of execution if there is a type match. -// // Otherwise we return None so that the call chain can continue. -// // So we want to build a function like -// // dispatchChainPiece = (call: functionCall, accessors): option> -// // Use accessors.environment to get the environment finally. - -// // Now lets make the dispatchChainPiece itself. -// // Note that I am not passing the reducer to the dispatchChainPiece as an argument because it is in the context anyway. -// // Keep in mind that reducerFn is necessary for map/reduce so dispatchChainPiece should have a reducerFn in context. - -// let makeMyDispatchChainPiece = (reducer: Reducer_T.reducerFn): DispatchT.dispatchChainPiece => { -// // Let's have a pure implementations -// module Implementation = { -// let stringConcat = (a: string, b: string): string => Js.String2.concat(a, b) -// let arrayConcat = ( -// a: Js.Array2.t, -// b: Js.Array2.t, -// ): Js.Array2.t => Js.Array2.concat(a, b) -// let plot = _r => "yey, plotted" -// } - -// let extractStringString = args => -// switch args { -// | [IEvString(a), IEvString(b)] => (a, b) -// | _ => raise(Reducer_Exception.ImpossibleException("extractStringString developer error")) -// } - -// let extractArrayArray = args => -// switch args { -// | [IEvArray(a), IEvArray(b)] => (a, b) -// | _ => raise(Reducer_Exception.ImpossibleException("extractArrayArray developer error")) -// } - -// // Let's bridge the pure implementation to expression values -// module Bridge = { -// let stringConcat: DispatchT.genericIEvFunction = (args, _accessors: ProjectAccessorsT.t) => { -// let (a, b) = extractStringString(args) -// Implementation.stringConcat(a, b)->IEvString->Ok -// } -// let arrayConcat: DispatchT.genericIEvFunction = (args, _accessors: ProjectAccessorsT.t) => { -// let (a, b) = extractArrayArray(args) -// Implementation.arrayConcat(a, b)->IEvArray->Ok -// } -// let plot: DispatchT.genericIEvFunction = (args, _accessors: ProjectAccessorsT.t) => { -// switch args { -// // Just assume that we are doing the business of extracting and converting the deep record -// | [IEvRecord(_)] => Implementation.plot({"title": "This is a plot"})->IEvString->Ok -// | _ => raise(Reducer_Exception.ImpossibleException("plot developer error")) -// } -// } -// } - -// // concat functions are to illustrate polymoprhism. And the plot function is to illustrate complex types -// let jumpTable = [ -// ( -// "concat", -// TypeCompile.fromTypeExpressionExn("string=>string=>string", reducer), -// Bridge.stringConcat, -// ), -// ( -// "concat", -// TypeCompile.fromTypeExpressionExn("[any]=>[any]=>[any]", reducer), -// Bridge.arrayConcat, -// ), -// ( -// "plot", -// TypeCompile.fromTypeExpressionExn( -// // Nested complex types are available -// // records {property: type} -// // arrays [type] -// // tuples [type, type] -// // <- type contracts are available naturally and they become part of dispatching -// // Here we are not enumerating the possibilities because type checking has a dedicated test -// "{title: string, line: {width: number, color: string}}=>string", -// reducer, -// ), -// Bridge.plot, -// ), -// ] - -// //Here we are creating a dispatchChainPiece function that will do the actual dispatch from the jumpTable -// Reducer_Dispatch_ChainPiece.makeFromTypes(jumpTable) -// } - -// // And finally, let's write a library dispatch for our external library -// // Exactly the same as the one used in real life -// let _dispatch = ( -// call: functionCall, -// accessors: ProjectAccessorsT.t, -// reducer: Reducer_T.reducerFn, -// chain, -// ): result => { -// let dispatchChainPiece = makeMyDispatchChainPiece(reducer) -// dispatchChainPiece(call, accessors)->E.O2.defaultFn(() => chain(call, accessors, reducer)) -// } - -// // What is important about this implementation? -// // A) Exactly the same function jump table can be used to create type guarded lambda functions -// // Guarded lambda functions will be the basis of the next version of Squiggle -// // B) Complicated recursive record types are not a problem. - -// describe("Type Dispatch", () => { -// let reducerFn = Expression.reduceExpressionInProject -// let dispatchChainPiece = makeMyDispatchChainPiece(reducerFn) -// test("stringConcat", () => { -// let call: functionCall = ("concat", [IEvString("hello"), IEvString("world")]) - -// let result = dispatchChainPiece(call, ProjectAccessorsT.identityAccessors) -// expect(result)->toEqual(Some(Ok(IEvString("helloworld")))) -// }) -// }) - diff --git a/packages/squiggle-lang/src/js/SqType.ts b/packages/squiggle-lang/src/js/SqType.ts deleted file mode 100644 index 45fe4c9d..00000000 --- a/packages/squiggle-lang/src/js/SqType.ts +++ /dev/null @@ -1,7 +0,0 @@ -import * as RSType from "../rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Type.gen"; - -type T = RSType.squiggleValue_Type; - -export class SqType { - constructor(private _value: T) {} -} diff --git a/packages/squiggle-lang/src/js/SqValue.ts b/packages/squiggle-lang/src/js/SqValue.ts index c0781937..ef2cfca6 100644 --- a/packages/squiggle-lang/src/js/SqValue.ts +++ b/packages/squiggle-lang/src/js/SqValue.ts @@ -5,7 +5,6 @@ import { SqLambda } from "./SqLambda"; import { SqLambdaDeclaration } from "./SqLambdaDeclaration"; import { SqRecord } from "./SqRecord"; import { SqArray } from "./SqArray"; -import { SqType } from "./SqType"; import { SqValueLocation } from "./SqValueLocation"; export { Tag as SqValueTag }; @@ -116,22 +115,6 @@ export class SqTimeDurationValue extends SqAbstractValue { } } -export class SqTypeValue extends SqAbstractValue { - tag = Tag.Type as const; - - get value() { - return new SqType(this.valueMethod(RSValue.getType)); - } -} - -export class SqTypeIdentifierValue extends SqAbstractValue { - tag = Tag.TypeIdentifier as const; - - get value() { - return this.valueMethod(RSValue.getTypeIdentifier); - } -} - export class SqVoidValue extends SqAbstractValue { tag = Tag.Void as const; @@ -151,8 +134,6 @@ const tagToClass = { [Tag.Record]: SqRecordValue, [Tag.String]: SqStringValue, [Tag.TimeDuration]: SqTimeDurationValue, - [Tag.Type]: SqTypeValue, - [Tag.TypeIdentifier]: SqTypeIdentifierValue, [Tag.Void]: SqVoidValue, } as const; @@ -169,6 +150,4 @@ export type SqValue = | SqRecordValue | SqStringValue | SqTimeDurationValue - | SqTypeValue - | SqTypeIdentifierValue | SqVoidValue; diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res index 4fac710f..8331e776 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res @@ -3,7 +3,6 @@ type reducerErrorValue = ForTS_Reducer_ErrorValue.reducerErrorValue //use @genType type squiggleValue_Array = Reducer_T.arrayValue //re-export recursive type @genType type squiggleValue_Record = Reducer_T.map //re-export recursive type -@genType type squiggleValue_Type = Reducer_T.map //re-export recursive type type squiggleValue_Declaration = ForTS_SquiggleValue_Declaration.squiggleValue_Declaration //use type squiggleValue_Distribution = ForTS_SquiggleValue_Distribution.squiggleValue_Distribution //use type squiggleValue_Lambda = ForTS_SquiggleValue_Lambda.squiggleValue_Lambda //use @@ -40,12 +39,6 @@ external svtString_: string = "String" @module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtTimeDuration_: string = "TimeDuration" -@module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -external svtType_: string = "Type" - -@module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -external svtTypeIdentifier_: string = "TypeIdentifier" - @module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtVoid_: string = "Void" @@ -67,8 +60,6 @@ let getTag = (variant: squiggleValue): squiggleValueTag => | IEvRecord(_) => svtRecord_->castEnum | IEvString(_) => svtString_->castEnum | IEvTimeDuration(_) => svtTimeDuration_->castEnum - | IEvType(_) => svtType_->castEnum - | IEvTypeIdentifier(_) => svtTypeIdentifier_->castEnum | IEvVoid => svtVoid_->castEnum } @@ -151,17 +142,3 @@ let getTimeDuration = (variant: squiggleValue): option => | IEvTimeDuration(value) => value->Some | _ => None } - -@genType -let getType = (variant: squiggleValue): option => - switch variant { - | IEvType(value) => value->Some - | _ => None - } - -@genType -let getTypeIdentifier = (variant: squiggleValue): option => - switch variant { - | IEvTypeIdentifier(value) => value->Some - | _ => None - } diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Type.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Type.res deleted file mode 100644 index 14845512..00000000 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Type.res +++ /dev/null @@ -1,9 +0,0 @@ -type squiggleValue = ForTS_SquiggleValue.squiggleValue //use -@genType type squiggleValue_Type = ForTS_SquiggleValue.squiggleValue_Type //re-export recursive type - -@genType -let getKeyValuePairs = (value: squiggleValue_Type): array<(string, squiggleValue)> => - Reducer_Value.recordToKeyValuePairs(value) - -@genType -let toString = (value: squiggleValue_Type): string => Reducer_Value.toStringType(value) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_tag.ts b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_tag.ts index eec17c5b..11d82e6d 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_tag.ts +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_tag.ts @@ -9,7 +9,5 @@ export enum squiggleValueTag { Record = "Record", String = "String", TimeDuration = "TimeDuration", - Type = "Type", - TypeIdentifier = "TypeIdentifier", Void = "Void", } diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res index b36aaf81..1cd74827 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res @@ -7,7 +7,6 @@ @genType type squiggleValue_Declaration = ForTS_SquiggleValue_Declaration.squiggleValue_Declaration //re-export @genType type squiggleValue_Lambda = ForTS_SquiggleValue_Lambda.squiggleValue_Lambda //re-export @genType type squiggleValue_Record = ForTS_SquiggleValue_Record.squiggleValue_Record //re-export -@genType type squiggleValue_Type = ForTS_SquiggleValue_Type.squiggleValue_Type //re-export /* Distribution related */ @genType type squiggleValue_Distribution = ForTS_Distribution.distribution //re-export diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings.res index 8311792b..5c0fbc59 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings.res @@ -45,44 +45,3 @@ let removeResult = ({namespace} as bindings: t): t => { let locals = ({namespace}: t): Reducer_T.namespace => namespace let fromNamespace = (namespace: Reducer_Namespace.t): t => {namespace: namespace, parent: None} - -// let typeAliasesKey = "_typeAliases_" -// let typeReferencesKey = "_typeReferences_" - -// let getType = (NameSpace(container): t, id: string) => { -// Belt.Map.String.get(container, typeAliasesKey)->Belt.Option.flatMap(aliases => -// switch aliases { -// | IEvRecord(r) => Belt.Map.String.get(r, id) -// | _ => None -// } -// ) -// } - -// let getTypeOf = (NameSpace(container): t, id: string) => { -// Belt.Map.String.get(container, typeReferencesKey)->Belt.Option.flatMap(defs => -// switch defs { -// | IEvRecord(r) => Belt.Map.String.get(r, id) -// | _ => None -// } -// ) -// } - -// let setTypeAlias = (NameSpace(container): t, id: string, value): t => { -// let rValue = Belt.Map.String.getWithDefault(container, typeAliasesKey, IEvRecord(emptyMap)) -// let r = switch rValue { -// | IEvRecord(r) => r -// | _ => emptyMap -// } -// let r2 = Belt.Map.String.set(r, id, value)->IEvRecord -// NameSpace(Belt.Map.String.set(container, typeAliasesKey, r2)) -// } - -// let setTypeOf = (NameSpace(container): t, id: string, value): t => { -// let rValue = Belt.Map.String.getWithDefault(container, typeReferencesKey, IEvRecord(emptyMap)) -// let r = switch rValue { -// | IEvRecord(r) => r -// | _ => emptyMap -// } -// let r2 = Belt.Map.String.set(r, id, value)->IEvRecord -// NameSpace(Belt.Map.String.set(container, typeReferencesKey, r2)) -// } 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 f0506f8a..e545bb2d 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 @@ -1,24 +1,27 @@ -// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -// module T = Reducer_Dispatch_T -// module TypeChecker = Reducer_Type_TypeChecker -// open Reducer_Value +// types are disabled until review and rewrite for 0.5 interpreter compatibility +/* +module ProjectAccessorsT = ReducerProject_ProjectAccessors_T +module T = Reducer_Dispatch_T +module TypeChecker = Reducer_Type_TypeChecker +open Reducer_Value -// type errorValue = Reducer_ErrorValue.errorValue +type errorValue = Reducer_ErrorValue.errorValue -// let makeFromTypes = jumpTable => { -// let dispatchChainPiece: T.dispatchChainPiece = ( -// (fnName, fnArgs): functionCall, -// accessors: ProjectAccessorsT.t, -// ) => { -// let jumpTableEntry = jumpTable->Js.Array2.find(elem => { -// let (candidName, candidType, _) = elem -// candidName == fnName && TypeChecker.checkITypeArgumentsBool(candidType, fnArgs) -// }) -// switch jumpTableEntry { -// | Some((_, _, bridgeFn)) => bridgeFn(fnArgs, accessors)->Some -// | _ => None -// } -// } -// dispatchChainPiece -// } +let makeFromTypes = jumpTable => { + let dispatchChainPiece: T.dispatchChainPiece = ( + (fnName, fnArgs): functionCall, + accessors: ProjectAccessorsT.t, + ) => { + let jumpTableEntry = jumpTable->Js.Array2.find(elem => { + let (candidName, candidType, _) = elem + candidName == fnName && TypeChecker.checkITypeArgumentsBool(candidType, fnArgs) + }) + switch jumpTableEntry { + | Some((_, _, bridgeFn)) => bridgeFn(fnArgs, accessors)->Some + | _ => None + } + } + dispatchChainPiece +} +*/ diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy index 3bf11162..4d8cc135 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Peggy/Reducer_Peggy_GeneratedParser.peggy @@ -37,7 +37,6 @@ array_statements statement = letStatement / defunStatement - // / typeStatement / voidStatement voidStatement @@ -323,81 +322,3 @@ statementSeparator 'statement separator' newLine "newline" = [\n\r] - -// // Types - -// noArguments = ('(' _nl ')' )? - -// typeIdentifier 'type identifier' -// = ([a-z]+[_a-z0-9]i*) {return h.nodeTypeIdentifier(text())} - -// typeConstructorIdentifier 'type constructor identifier' -// = ([A-Z]+[_a-z0-9]i*) {return h.nodeTypeIdentifier(text())} - -// typeExpression = typePostModifierExpression - -// typePostModifierExpression = head:typeOr tail:(_ '$' _nl @typeModifier)* -// { -// return tail.reduce((result, element) => { -// return h.makeFunctionCall('$_typeModifier_'+element.modifier.value+'_$', [result, ...element.args]) -// }, head) -// } - -// typeOr = head:typeFunction tail:(_ '|' _nl @typeFunction)* -// { return tail.length === 0 ? head : h.makeFunctionCall('$_typeOr_$', [h.constructArray([head, ...tail])]); } - -// typeFunction = head:typeModifierExpression tail:(_ '=>' _nl @typeModifierExpression)* -// { return tail.length === 0 ? head : h.makeFunctionCall( '$_typeFunction_$', [h.constructArray([head, ...tail])]); } - -// typeModifierExpression = head:basicType tail:(_ '<-' _nl @typeModifier)* -// { -// return tail.reduce((result, element) => { -// return h.makeFunctionCall('$_typeModifier_'+element.modifier.value+'_$', [result, ...element.args]) -// }, head) -// } - -// typeModifier -// = modifier:identifier _ '(' _nl args:array_elements _nl ')' -// { return {modifier: modifier, args: args}; } -// / modifier:identifier _ noArguments -// { return {modifier: modifier, args: []}; } - -// basicType = typeConstructor / typeArray / typeTuple / typeRecord / typeInParanthesis / typeIdentifier - -// typeArray = '[' _nl elem:typeExpression _nl ']' -// {return h.makeFunctionCall('$_typeArray_$', [elem])} - -// typeTuple = '[' _nl elems:array_typeTupleArguments _nl ']' -// { return h.makeFunctionCall('$_typeTuple_$', [h.constructArray(elems)])} - -// array_typeTupleArguments -// = head:typeExpression tail:(_ ',' _nl @typeExpression)* -// { return [head, ...tail]; } - -// typeRecord = '{' _nl elems:array_typeRecordArguments _nl '}' -// { return h.makeFunctionCall('$_typeRecord_$', [h.constructRecord(elems)]); } - -// array_typeRecordArguments -// = head:typeKeyValuePair tail:(_ ',' _nl @typeKeyValuePair)* -// { return [head, ...tail]; } - -// typeKeyValuePair -// = key:identifier _ ':' _nl value:typeExpression -// { return h.nodeKeyValue(key, value)} - -// typeConstructor -// = constructor:typeConstructorIdentifier _ '(' _nl args:array_types _nl ')' -// { return h.makeFunctionCall('$_typeConstructor_$', [constructor, h.constructArray(args)]); } -// / constructor:typeConstructorIdentifier _ noArguments -// { return h.makeFunctionCall('$_typeConstructor_$', [constructor, h.constructArray([])]); } - -// array_types = head:typeExpression tail:(_ ',' _nl @typeExpression)* -// { return [head, ...tail]; } - -// typeStatement = typeAliasStatement / typeOfStatement -// typeAliasStatement = 'type' __nl typeIdentifier:typeIdentifier _nl '=' _nl typeExpression:typeExpression -// { return h.makeFunctionCall('$_typeAlias_$', [typeIdentifier, typeExpression])} -// typeOfStatement = identifier:identifier _ ':' _nl typeExpression:typeExpression -// { return h.makeFunctionCall('$_typeOf_$', [identifier, typeExpression])} - -// typeInParanthesis = '(' _nl typeExpression:typeExpression _nl ')' {return typeExpression} diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res index 4fda2e34..85546905 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_T.res @@ -12,8 +12,6 @@ type rec value = | IEvRecord(map) | IEvString(string) | IEvTimeDuration(float) - | IEvType(map) - | IEvTypeIdentifier(string) | IEvVoid @genType.opaque and arrayValue = array @genType.opaque and map = Belt.Map.String.t 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 deleted file mode 100644 index 2d636d2b..00000000 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Compile.res +++ /dev/null @@ -1,39 +0,0 @@ -// module Bindings = Reducer_Bindings -// module ErrorValue = Reducer_ErrorValue -// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -// module T = Reducer_Type_T - -// let ievFromTypeExpression = ( -// typeExpressionSourceCode: string, -// reducerFn: ProjectReducerFnT.t, -// ): result => { -// let sIndex = "compiled" -// let sourceCode = `type ${sIndex}=${typeExpressionSourceCode}` -// Reducer_Expression.BackCompatible.parse(sourceCode)->Belt.Result.flatMap(expr => { -// let accessors = ProjectAccessorsT.identityAccessors -// let _result = reducerFn(expr, Bindings.emptyBindings, accessors) -// let nameSpace = accessors.states.continuation - -// switch Bindings.getType(nameSpace, sIndex) { -// | Some(value) => value->Ok -// | None => raise(Reducer_Exception.ImpossibleException("Reducer_Type_Compile-none")) -// } -// }) -// } - -// let fromTypeExpression = (typeExpressionSourceCode: string, reducerFn: Reducer_T.reducerFn): result< -// T.t, -// ErrorValue.t, -// > => { -// ievFromTypeExpression(typeExpressionSourceCode, reducerFn)->Belt.Result.map(T.fromIEvValue) -// } - -// let fromTypeExpressionExn = ( -// typeExpressionSourceCode: string, -// reducerFn: Reducer_T.reducerFn, -// ): T.t => -// switch fromTypeExpression(typeExpressionSourceCode, reducerFn) { -// | Ok(value) => value -// | _ => `Cannot compile ${typeExpressionSourceCode}`->Reducer_Exception.ImpossibleException->raise -// } - diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Contracts.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Contracts.res deleted file mode 100644 index 59230a9e..00000000 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_Contracts.res +++ /dev/null @@ -1,45 +0,0 @@ -module T = Reducer_Type_T - -let isMin = (modifierArg: Reducer_Value.t, aValue: Reducer_Value.t): bool => { - let pair = (modifierArg, aValue) - switch pair { - | (IEvNumber(a), IEvNumber(b)) => a <= b - | _ => false - } -} - -let isMax = (modifierArg: Reducer_Value.t, aValue: Reducer_Value.t): bool => { - let pair = (modifierArg, aValue) - switch pair { - | (IEvNumber(a), IEvNumber(b)) => a >= b - | _ => false - } -} - -let isMemberOf = (modifierArg: Reducer_Value.t, aValue: Reducer_Value.t): bool => { - let pair = (modifierArg, aValue) - switch pair { - | (ievA, IEvArray(b)) => Js.Array2.includes(b, ievA) - | _ => false - } -} - -let checkModifier = (key: string, modifierArg: Reducer_Value.t, aValue: Reducer_Value.t): bool => - switch key { - | "min" => isMin(modifierArg, aValue) - | "max" => isMax(modifierArg, aValue) - | "isMemberOf" => isMemberOf(modifierArg, aValue) - | _ => false - } - -let checkModifiers = ( - contracts: Belt.Map.String.t, - aValue: Reducer_Value.t, -): bool => { - contracts->Belt.Map.String.reduce(true, (acc, key, modifierArg) => - switch acc { - | true => checkModifier(key, modifierArg, aValue) - | _ => acc - } - ) -} 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 deleted file mode 100644 index 8f293d53..00000000 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_T.res +++ /dev/null @@ -1,117 +0,0 @@ -// type rec iType = -// | ItTypeIdentifier(string) -// | ItModifiedType({modifiedType: iType, contracts: Belt.Map.String.t}) -// | ItTypeOr({typeOr: array}) -// | ItTypeFunction({inputs: array, output: iType}) -// | ItTypeArray({element: iType}) -// | ItTypeTuple({elements: array}) -// | ItTypeRecord({properties: Belt.Map.String.t}) - -// type t = iType -// type typeErrorValue = TypeMismatch(t, Reducer_Value.t) - -// let rec toString = (t: t): string => { -// switch t { -// | ItTypeIdentifier(s) => s -// | ItModifiedType({modifiedType, contracts}) => -// `${toString(modifiedType)}${contracts->Belt.Map.String.reduce("", (acc, k, v) => -// Js.String2.concatMany(acc, ["<-", k, "(", Reducer_Value.toString(v), ")"]) -// )}` -// | ItTypeOr({typeOr}) => `(${Js.Array2.map(typeOr, toString)->Js.Array2.joinWith(" | ")})` -// | ItTypeFunction({inputs, output}) => -// `(${inputs->Js.Array2.map(toString)->Js.Array2.joinWith(" => ")} => ${toString(output)})` -// | ItTypeArray({element}) => `[${toString(element)}]` -// | ItTypeTuple({elements}) => `[${Js.Array2.map(elements, toString)->Js.Array2.joinWith(", ")}]` -// | ItTypeRecord({properties}) => -// `{${properties -// ->Belt.Map.String.toArray -// ->Js.Array2.map(((k, v)) => Js.String2.concatMany(k, [": ", toString(v)])) -// ->Js.Array2.joinWith(", ")}}` -// } -// } - -// let toStringResult = (rt: result) => -// switch rt { -// | Ok(t) => toString(t) -// | Error(e) => ErrorValue.errorToString(e) -// } - -// let rec fromTypeMap = typeMap => { -// let default = IEvString("") -// let evTypeTag: Reducer_Value.t = Belt.Map.String.getWithDefault( -// typeMap, -// "typeTag", -// default, -// ) -// let evTypeIdentifier: Reducer_Value.t = Belt.Map.String.getWithDefault( -// typeMap, -// "typeIdentifier", -// default, -// ) -// let evTypeOr: Reducer_Value.t = Belt.Map.String.getWithDefault( -// typeMap, -// "typeOr", -// default, -// ) -// let evInputs: Reducer_Value.t = Belt.Map.String.getWithDefault( -// typeMap, -// "inputs", -// default, -// ) -// let evOutput: Reducer_Value.t = Belt.Map.String.getWithDefault( -// typeMap, -// "output", -// default, -// ) -// let evElement: Reducer_Value.t = Belt.Map.String.getWithDefault( -// typeMap, -// "element", -// default, -// ) -// let evElements: Reducer_Value.t = Belt.Map.String.getWithDefault( -// typeMap, -// "elements", -// default, -// ) -// let evProperties: Reducer_Value.t = Belt.Map.String.getWithDefault( -// typeMap, -// "properties", -// default, -// ) - -// let contracts = -// typeMap->Belt.Map.String.keep((k, _v) => ["min", "max", "memberOf"]->Js.Array2.includes(k)) - -// let makeIt = switch evTypeTag { -// | IEvString("typeIdentifier") => fromIEvValue(evTypeIdentifier) -// | IEvString("typeOr") => ItTypeOr({typeOr: fromIEvArray(evTypeOr)}) -// | IEvString("typeFunction") => -// ItTypeFunction({inputs: fromIEvArray(evInputs), output: fromIEvValue(evOutput)}) -// | IEvString("typeArray") => ItTypeArray({element: fromIEvValue(evElement)}) -// | IEvString("typeTuple") => ItTypeTuple({elements: fromIEvArray(evElements)}) -// | IEvString("typeRecord") => ItTypeRecord({properties: fromIEvRecord(evProperties)}) -// | _ => raise(Reducer_Exception.ImpossibleException("Reducer_Type_T-evTypeTag")) -// } - -// Belt.Map.String.isEmpty(contracts) -// ? makeIt -// : ItModifiedType({modifiedType: makeIt, contracts: contracts}) -// } - -// and fromIEvValue = (ievValue: Reducer_Value.t): iType => -// switch ievValue { -// | IEvTypeIdentifier(typeIdentifier) => ItTypeIdentifier({typeIdentifier}) -// | IEvType(typeMap) => fromTypeMap(typeMap) -// | _ => raise(Reducer_Exception.ImpossibleException("Reducer_Type_T-ievValue")) -// } -// and fromIEvArray = (ievArray: Reducer_Value.t) => -// switch ievArray { -// | IEvArray(array) => array->Belt.Array.map(fromIEvValue) -// | _ => raise(Reducer_Exception.ImpossibleException("Reducer_Type_T-ievArray")) -// } -// and fromIEvRecord = (ievRecord: Reducer_Value.t) => -// switch ievRecord { -// | 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 deleted file mode 100644 index 0acfae19..00000000 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_TypeBuilder.res +++ /dev/null @@ -1,81 +0,0 @@ -// open ReducerInterface_InternalExpressionValue - -// let typeModifier_memberOf = (aType, anArray) => { -// let newRecord = Belt.Map.String.fromArray([ -// ("typeTag", IEvString("typeIdentifier")), -// ("typeIdentifier", aType), -// ]) -// newRecord->Belt.Map.String.set("memberOf", anArray)->IEvType->Ok -// } - -// let typeModifier_memberOf_update = (aRecord, anArray) => { -// aRecord->Belt.Map.String.set("memberOf", anArray)->IEvType->Ok -// } - -// let typeModifier_min = (aType, value) => { -// let newRecord = Belt.Map.String.fromArray([ -// ("typeTag", IEvString("typeIdentifier")), -// ("typeIdentifier", aType), -// ]) -// newRecord->Belt.Map.String.set("min", value)->IEvType->Ok -// } - -// let typeModifier_min_update = (aRecord, value) => { -// aRecord->Belt.Map.String.set("min", value)->IEvType->Ok -// } - -// let typeModifier_max = (aType, value) => { -// let newRecord = Belt.Map.String.fromArray([ -// ("typeTag", IEvString("typeIdentifier")), -// ("typeIdentifier", aType), -// ]) -// newRecord->Belt.Map.String.set("max", value)->IEvType->Ok -// } - -// let typeModifier_max_update = (aRecord, value) => -// aRecord->Belt.Map.String.set("max", value)->IEvType->Ok - -// let typeModifier_opaque_update = aRecord => -// aRecord->Belt.Map.String.set("opaque", IEvBool(true))->IEvType->Ok - -// let typeOr = evArray => { -// let newRecord = Belt.Map.String.fromArray([("typeTag", IEvString("typeOr")), ("typeOr", evArray)]) -// newRecord->IEvType->Ok -// } - -// let typeFunction = anArray => { -// let output = Belt.Array.getUnsafe(anArray, Js.Array2.length(anArray) - 1) -// let inputs = Js.Array2.slice(anArray, ~start=0, ~end_=-1) -// let newRecord = Belt.Map.String.fromArray([ -// ("typeTag", IEvString("typeFunction")), -// ("inputs", IEvArray(inputs)), -// ("output", output), -// ]) -// newRecord->IEvType->Ok -// } - -// let typeArray = element => { -// let newRecord = Belt.Map.String.fromArray([ -// ("typeTag", IEvString("typeArray")), -// ("element", element), -// ]) -// newRecord->IEvType->Ok -// } - -// let typeTuple = anArray => { -// let newRecord = Belt.Map.String.fromArray([ -// ("typeTag", IEvString("typeTuple")), -// ("elements", IEvArray(anArray)), -// ]) -// newRecord->IEvType->Ok -// } - -// let typeRecord = propertyMap => { -// let newProperties = propertyMap->IEvRecord -// let newRecord = Belt.Map.String.fromArray([ -// ("typeTag", IEvString("typeRecord")), -// ("properties", newProperties), -// ]) -// 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 deleted file mode 100644 index 5d2be602..00000000 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Type/Reducer_Type_TypeChecker.res +++ /dev/null @@ -1,181 +0,0 @@ -// module ExpressionT = Reducer_Expression_T -// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -// module T = Reducer_Type_T -// module TypeContracts = Reducer_Type_Contracts -// open Reducer_Value - -// let rec isITypeOf = (anIType: T.iType, aValue): result => { -// let caseTypeIdentifier = (anUpperTypeName, aValue) => { -// let aTypeName = anUpperTypeName->Js.String2.toLowerCase -// switch aTypeName { -// | "any" => Ok(true) -// | _ => { -// let valueTypeName = aValue->valueToValueType->valueTypeToString->Js.String2.toLowerCase -// switch aTypeName == valueTypeName { -// | true => Ok(true) -// | false => T.TypeMismatch(anIType, aValue)->Error -// } -// } -// } -// } - -// let caseRecord = (anIType, propertyMap: Belt.Map.String.t, evValue) => -// switch evValue { -// | IEvRecord(aRecord) => -// if ( -// Js.Array2.length(propertyMap->Belt.Map.String.keysToArray) == -// Js.Array2.length(aRecord->Belt.Map.String.keysToArray) -// ) { -// Belt.Map.String.reduce(propertyMap, Ok(true), (acc, property, propertyType) => { -// Belt.Result.flatMap(acc, _ => -// switch Belt.Map.String.get(aRecord, property) { -// | Some(propertyValue) => isITypeOf(propertyType, propertyValue) -// | None => T.TypeMismatch(anIType, evValue)->Error -// } -// ) -// }) -// } else { -// T.TypeMismatch(anIType, evValue)->Error -// } - -// | _ => T.TypeMismatch(anIType, evValue)->Error -// } - -// let caseArray = (anIType, elementType, evValue) => -// switch evValue { -// | IEvArray(anArray) => -// Belt.Array.reduce(anArray, Ok(true), (acc, element) => -// Belt.Result.flatMap(acc, _ => -// switch isITypeOf(elementType, element) { -// | Ok(_) => Ok(true) -// | Error(error) => error->Error -// } -// ) -// ) -// | _ => T.TypeMismatch(anIType, evValue)->Error -// } - -// let caseTuple = (anIType, elementTypes, evValue) => -// switch evValue { -// | IEvArray(anArray) => -// if Js.Array2.length(elementTypes) == Js.Array2.length(anArray) { -// let zipped = Belt.Array.zip(elementTypes, anArray) -// Belt.Array.reduce(zipped, Ok(true), (acc, (elementType, element)) => -// switch acc { -// | Ok(_) => -// switch isITypeOf(elementType, element) { -// | Ok(_) => acc -// | Error(error) => Error(error) -// } -// | _ => acc -// } -// ) -// } else { -// T.TypeMismatch(anIType, evValue)->Error -// } -// | _ => T.TypeMismatch(anIType, evValue)->Error -// } - -// let caseOr = (anIType, anITypeArray, evValue) => -// switch Belt.Array.reduce(anITypeArray, Ok(false), (acc, anIType) => -// Belt.Result.flatMap(acc, _ => -// switch acc { -// | Ok(false) => -// switch isITypeOf(anIType, evValue) { -// | Ok(_) => Ok(true) -// | Error(_) => acc -// } -// | _ => acc -// } -// ) -// ) { -// | Ok(true) => Ok(true) -// | Ok(false) => T.TypeMismatch(anIType, evValue)->Error -// | Error(error) => Error(error) -// } - -// let caseModifiedType = ( -// anIType: T.iType, -// modifiedType: T.iType, -// contracts: Belt.Map.String.t, -// aValue: Reducer_Value.t, -// ) => { -// isITypeOf(modifiedType, aValue)->Belt.Result.flatMap(_result => { -// if TypeContracts.checkModifiers(contracts, aValue) { -// Ok(true) -// } else { -// T.TypeMismatch(anIType, aValue)->Error -// } -// }) -// } - -// switch anIType { -// | ItTypeIdentifier(name) => caseTypeIdentifier(name, aValue) -// | ItModifiedType({modifiedType, contracts}) => -// caseModifiedType(anIType, modifiedType, contracts, aValue) //{modifiedType: iType, contracts: Belt.Map.String.t} -// | ItTypeOr({typeOr}) => caseOr(anIType, typeOr, aValue) -// | ItTypeFunction(_) => -// raise( -// Reducer_Exception.ImpossibleException( -// "Reducer_TypeChecker-functions are without a type at the moment", -// ), -// ) -// | ItTypeArray({element}) => caseArray(anIType, element, aValue) -// | ItTypeTuple({elements}) => caseTuple(anIType, elements, aValue) -// | ItTypeRecord({properties}) => caseRecord(anIType, properties, aValue) -// } -// } - -// let isTypeOf = ( -// typeExpressionSourceCode: string, -// aValue: Reducer_Value.t, -// reducerFn: Reducer_T.reducerFn, -// ): result => { -// switch typeExpressionSourceCode->Reducer_Type_Compile.fromTypeExpression(reducerFn) { -// | Ok(anIType) => -// switch isITypeOf(anIType, aValue) { -// | Ok(_) => Ok(aValue) -// | Error(T.TypeMismatch(anIType, evValue)) => -// Error( -// ErrorValue.REExpectedType(anIType->T.toString, evValue->Reducer_Value.toString), -// ) -// } -// | Error(error) => Error(error) // Directly propagating - err => err - causes type mismatch -// } -// } - -// let checkITypeArguments = (anIType: T.iType, args: array): result< -// bool, -// T.typeErrorValue, -// > => { -// switch anIType { -// | T.ItTypeFunction({inputs}) => isITypeOf(T.ItTypeTuple({elements: inputs}), args->IEvArray) -// | _ => T.TypeMismatch(anIType, args->IEvArray)->Error -// } -// } - -// let checkITypeArgumentsBool = (anIType: T.iType, args: array): bool => { -// switch checkITypeArguments(anIType, args) { -// | Ok(_) => true -// | _ => false -// } -// } - -// let checkArguments = ( -// typeExpressionSourceCode: string, -// args: array, -// reducerFn: ReducerT.reducerFn, -// ): result => { -// switch typeExpressionSourceCode->Reducer_Type_Compile.fromTypeExpression(reducerFn) { -// | Ok(anIType) => -// switch checkITypeArguments(anIType, args) { -// | Ok(_) => Ok(args->IEvArray) -// | Error(T.TypeMismatch(anIType, evValue)) => -// Error( -// ErrorValue.REExpectedType(anIType->T.toString, evValue->Reducer_Value.toString), -// ) -// } -// | Error(error) => Error(error) // Directly propagating - err => err - causes type mismatch -// } -// } - diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Value.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Value.res index 093dc196..cd1eefef 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Value.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Value.res @@ -21,8 +21,6 @@ let rec toString = (aValue: T.value) => | IEvRecord(aMap) => aMap->toStringRecord | IEvString(aString) => toStringString(aString) | IEvTimeDuration(t) => toStringTimeDuration(t) - | IEvType(aMap) => toStringType(aMap) - | IEvTypeIdentifier(id) => toStringTypeIdentifier(id) | IEvVoid => toStringVoid } and toStringArray = anArray => { @@ -43,8 +41,6 @@ and toStringRecord = aMap => aMap->toStringMap and toStringString = aString => `'${aString}'` and toStringSymbol = aString => `:${aString}` and toStringTimeDuration = t => DateTime.Duration.toString(t) -and toStringType = aMap => aMap->toStringMap -and toStringTypeIdentifier = id => `#${id}` and toStringVoid = `()` and toStringMap = aMap => { @@ -68,8 +64,6 @@ let toStringWithType = (aValue: T.value) => | IEvRecord(_) => `Record::${toString(aValue)}` | IEvString(_) => `String::${toString(aValue)}` | IEvTimeDuration(_) => `Date::${toString(aValue)}` - | IEvType(_) => `Type::${toString(aValue)}` - | IEvTypeIdentifier(_) => `TypeIdentifier::${toString(aValue)}` | IEvVoid => `Void` } @@ -114,8 +108,6 @@ type internalExpressionValueType = | EvtRecord | EvtString | EvtTimeDuration - | EvtType - | EvtTypeIdentifier | EvtVoid type functionCallSignature = CallSignature(string, array) @@ -134,8 +126,6 @@ let valueToValueType = (value: T.value) => | IEvRecord(_) => EvtRecord | IEvString(_) => EvtString | IEvTimeDuration(_) => EvtTimeDuration - | IEvType(_) => EvtType - | IEvTypeIdentifier(_) => EvtTypeIdentifier | IEvVoid => EvtVoid } @@ -148,7 +138,6 @@ let valueTypeToString = (valueType: internalExpressionValueType): string => switch valueType { | EvtArray => `Array` | EvtBool => `Bool` - // | EvtCall => `Call` | EvtDate => `Date` | EvtDeclaration => `Declaration` | EvtDistribution => `Distribution` @@ -156,10 +145,7 @@ let valueTypeToString = (valueType: internalExpressionValueType): string => | EvtNumber => `Number` | EvtRecord => `Record` | EvtString => `String` - // | EvtSymbol => `Symbol` | EvtTimeDuration => `Duration` - | EvtType => `Type` - | EvtTypeIdentifier => `TypeIdentifier` | EvtVoid => `Void` } From c9e5b114169e374eaee9fb5ba5aee0475e79e486 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Wed, 28 Sep 2022 14:16:05 +1000 Subject: [PATCH 43/46] Format rescript --- ...leLibrary_FunctionRegistryLibrary_test.res | 5 ++- .../squiggle-lang/src/rescript/FR/FR_Dict.res | 18 ++++++----- .../squiggle-lang/src/rescript/FR/FR_Dist.res | 10 +++--- .../squiggle-lang/src/rescript/FR/FR_List.res | 4 +-- .../src/rescript/FR/FR_Pointset.res | 32 +++++++++---------- .../src/rescript/FR/FR_Sampleset.res | 5 ++- .../src/rescript/FR/FR_Scoring.res | 16 ++++++---- .../FunctionRegistry_Core.res | 20 ++++++------ .../FunctionRegistry_Helpers.res | 24 +++++++------- 9 files changed, 71 insertions(+), 63 deletions(-) diff --git a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res index fd1ec78e..af2c3d7a 100644 --- a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res +++ b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res @@ -82,7 +82,10 @@ describe("FunctionRegistry Library", () => { ) testEvalToBe("Dict.merge({a: 1, b: 2}, {b: 3, c: 4, d: 5})", "Ok({a: 1,b: 3,c: 4,d: 5})") - testEvalToBe("Dict.mergeMany([{a: 1, b: 2}, {c: 3, d: 4}, {c: 5, e: 6}])", "Ok({a: 1,b: 2,c: 5,d: 4,e: 6})") + testEvalToBe( + "Dict.mergeMany([{a: 1, b: 2}, {c: 3, d: 4}, {c: 5, e: 6}])", + "Ok({a: 1,b: 2,c: 5,d: 4,e: 6})", + ) testEvalToBe("Dict.keys({a: 1, b: 2})", "Ok(['a','b'])") testEvalToBe("Dict.values({a: 1, b: 2})", "Ok([1,2])") testEvalToBe("Dict.toList({a: 1, b: 2})", "Ok([['a',1],['b',2]])") diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Dict.res b/packages/squiggle-lang/src/rescript/FR/FR_Dict.res index 13bcfe33..d135717c 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Dict.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Dict.res @@ -59,7 +59,6 @@ let library = [ ], (), ), - Function.make( ~name="mergeMany", ~nameSpace, @@ -72,13 +71,16 @@ let library = [ ~inputs=[FRTypeArray(FRTypeDict(FRTypeAny))], ~run=(inputs, _, _) => { switch inputs { - | [IEvArray(dicts)] => { - dicts->Belt.Array.map(dictValue => switch dictValue { - | IEvRecord(dict) => dict - | _ => impossibleError->Reducer_ErrorValue.toException - })->Internals.mergeMany->Ok - } - | _ => impossibleError->Error + | [IEvArray(dicts)] => dicts + ->Belt.Array.map(dictValue => + switch dictValue { + | IEvRecord(dict) => dict + | _ => impossibleError->Reducer_ErrorValue.toException + } + ) + ->Internals.mergeMany + ->Ok + | _ => impossibleError->Error } }, (), diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Dist.res b/packages/squiggle-lang/src/rescript/FR/FR_Dist.res index 3a7504f2..97befcd4 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Dist.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Dist.res @@ -22,8 +22,7 @@ module DistributionCreation = { FnDefinition.make( ~name, ~inputs=[FRTypeDistOrNumber, FRTypeDistOrNumber], - ~run=(inputs, env, _) => - inputs->Prepare.ToValueTuple.twoDistOrNumber->process(~fn, ~env), + ~run=(inputs, env, _) => inputs->Prepare.ToValueTuple.twoDistOrNumber->process(~fn, ~env), (), ) } @@ -43,7 +42,9 @@ module DistributionCreation = { ~name, ~inputs=[FRTypeRecord([("mean", FRTypeDistOrNumber), ("stdev", FRTypeDistOrNumber)])], ~run=(inputs, env, _) => - inputs->Prepare.ToValueTuple.Record.twoDistOrNumber(("mean", "stdev"))->process(~fn, ~env), + inputs + ->Prepare.ToValueTuple.Record.twoDistOrNumber(("mean", "stdev")) + ->process(~fn, ~env), (), ) } @@ -60,8 +61,7 @@ module DistributionCreation = { FnDefinition.make( ~name, ~inputs=[FRTypeDistOrNumber], - ~run=(inputs, env, _) => - inputs->Prepare.ToValueTuple.oneDistOrNumber->process(~fn, ~env), + ~run=(inputs, env, _) => inputs->Prepare.ToValueTuple.oneDistOrNumber->process(~fn, ~env), (), ) } diff --git a/packages/squiggle-lang/src/rescript/FR/FR_List.res b/packages/squiggle-lang/src/rescript/FR/FR_List.res index fb675417..21106978 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_List.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_List.res @@ -109,8 +109,8 @@ let library = [ ~inputs=[FRTypeNumber, FRTypeNumber], ~run=(inputs, _, _) => switch inputs { - | [IEvNumber(low), IEvNumber(high)] => Internals.upTo(low, high)->Ok - | _ => impossibleError->Error + | [IEvNumber(low), IEvNumber(high)] => Internals.upTo(low, high)->Ok + | _ => impossibleError->Error }, (), ), diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res b/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res index 4babe231..ee4f7ca8 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res @@ -7,24 +7,24 @@ let requiresNamespace = true let inputsToDist = (inputs: array, xyShapeToPointSetDist) => { // TODO - rewrite in more functional/functor-based style switch inputs { - | [IEvArray(items)] => { - items->Belt.Array.map( - item => - switch item { - | IEvRecord(map) => { - let xValue = map->Belt.Map.String.get("x") - let yValue = map->Belt.Map.String.get("y") - switch (xValue, yValue) { - | (Some(IEvNumber(x)), Some(IEvNumber(y))) => (x, y) - | _ => impossibleError->Reducer_ErrorValue.toException - } - } + | [IEvArray(items)] => items + ->Belt.Array.map(item => + switch item { + | IEvRecord(map) => { + let xValue = map->Belt.Map.String.get("x") + let yValue = map->Belt.Map.String.get("y") + switch (xValue, yValue) { + | (Some(IEvNumber(x)), Some(IEvNumber(y))) => (x, y) | _ => impossibleError->Reducer_ErrorValue.toException + } } - )->Ok->E.R.bind(r => r->XYShape.T.makeFromZipped->E.R2.errMap(XYShape.Error.toString)) - ->E.R2.fmap(r => Reducer_T.IEvDistribution(PointSet(r->xyShapeToPointSetDist))) - } - | _ => impossibleError->Reducer_ErrorValue.toException + | _ => impossibleError->Reducer_ErrorValue.toException + } + ) + ->Ok + ->E.R.bind(r => r->XYShape.T.makeFromZipped->E.R2.errMap(XYShape.Error.toString)) + ->E.R2.fmap(r => Reducer_T.IEvDistribution(PointSet(r->xyShapeToPointSetDist))) + | _ => impossibleError->Reducer_ErrorValue.toException } } diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res b/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res index 5bbfb506..9263bf29 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Sampleset.res @@ -115,9 +115,8 @@ let libaryBase = [ ~inputs=[FRTypeArray(FRTypeNumber)], ~run=(inputs, _, _) => { let sampleSet = - inputs->Prepare.ToTypedArray.numbers |> E.R2.bind(r => - SampleSetDist.make(r)->E.R2.errMap(_ => "AM I HERE? WHYERE AMI??") - ) + inputs->Prepare.ToTypedArray.numbers + |> 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) diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Scoring.res b/packages/squiggle-lang/src/rescript/FR/FR_Scoring.res index 63589e83..5b780da5 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Scoring.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Scoring.res @@ -31,14 +31,13 @@ let library = [ ]), ], ~run=(inputs, environment, _) => { - switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.threeArgs(inputs, ("estimate", "answer", "prior")) { + switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.threeArgs( + inputs, + ("estimate", "answer", "prior"), + ) { | Ok([IEvDistribution(estimate), IEvDistribution(d), IEvDistribution(prior)]) => runScoring(estimate, Score_Dist(d), Some(prior), environment) - | Ok([ - IEvDistribution(estimate), - IEvNumber(d), - IEvDistribution(prior), - ]) => + | Ok([IEvDistribution(estimate), IEvNumber(d), IEvDistribution(prior)]) => runScoring(estimate, Score_Scalar(d), Some(prior), environment) | Error(e) => Error(e->FunctionRegistry_Helpers.wrapError) | _ => Error(FunctionRegistry_Helpers.impossibleError) @@ -50,7 +49,10 @@ let library = [ ~name="logScore", ~inputs=[FRTypeRecord([("estimate", FRTypeDist), ("answer", FRTypeDistOrNumber)])], ~run=(inputs, environment, _) => { - switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.twoArgs(inputs, ("estimate", "answer")) { + switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.twoArgs( + inputs, + ("estimate", "answer"), + ) { | Ok([IEvDistribution(estimate), IEvDistribution(d)]) => runScoring(estimate, Score_Dist(d), None, environment) | Ok([IEvDistribution(estimate), IEvNumber(d)]) => diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res index e6929761..5d606bb8 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res @@ -83,19 +83,20 @@ module FRType = { | (FRTypeNumeric, IEvNumber(_)) => true | (FRTypeNumeric, IEvDistribution(Symbolic(#Float(_)))) => true | (FRTypeLambda, IEvLambda(_)) => true - | (FRTypeArray(intendedType), IEvArray(elements)) => { - elements->Belt.Array.every(v => matchWithValue(intendedType, v)) - } + | (FRTypeArray(intendedType), IEvArray(elements)) => elements->Belt.Array.every(v => + matchWithValue(intendedType, v) + ) | (FRTypeDict(r), IEvRecord(map)) => map->Belt.Map.String.valuesToArray->Belt.Array.every(v => matchWithValue(r, v)) - | (FRTypeRecord(recordParams), IEvRecord(map)) => { - recordParams->Belt.Array.every(((name, input)) => { + | (FRTypeRecord(recordParams), IEvRecord(map)) => recordParams->Belt.Array.every((( + name, + input, + )) => { switch map->Belt.Map.String.get(name) { - | Some(v) => matchWithValue(input, v) - | None => false + | Some(v) => matchWithValue(input, v) + | None => false } }) - } | _ => false } @@ -104,8 +105,7 @@ module FRType = { if !isSameLength { false } else { - E.A.zip(inputs, args) - ->Belt.Array.every(((input, arg)) => matchWithValue(input, arg)) + E.A.zip(inputs, args)->Belt.Array.every(((input, arg)) => matchWithValue(input, arg)) } } } diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res index a5a0f523..9a7f04db 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Helpers.res @@ -30,21 +30,21 @@ module Prepare = { let twoArgs = (inputs: ts, (arg1: string, arg2: string)): result => switch inputs { | [IEvRecord(map)] => { - let n1 = map->Belt.Map.String.getExn(arg1) - let n2 = map->Belt.Map.String.getExn(arg2) - Ok([n1, n2]) - } + let n1 = map->Belt.Map.String.getExn(arg1) + let n2 = map->Belt.Map.String.getExn(arg2) + Ok([n1, n2]) + } | _ => Error(impossibleErrorString) } let threeArgs = (inputs: ts, (arg1: string, arg2: string, arg3: string)): result => switch inputs { | [IEvRecord(map)] => { - let n1 = map->Belt.Map.String.getExn(arg1) - let n2 = map->Belt.Map.String.getExn(arg2) - let n3 = map->Belt.Map.String.getExn(arg3) - Ok([n1, n2, n3]) - } + let n1 = map->Belt.Map.String.getExn(arg1) + let n2 = map->Belt.Map.String.getExn(arg2) + let n3 = map->Belt.Map.String.getExn(arg3) + Ok([n1, n2, n3]) + } | _ => Error(impossibleErrorString) } } @@ -108,8 +108,10 @@ module Prepare = { } module Record = { - let twoDistOrNumber = (values: ts, labels: (string, string)): result<(frValueDistOrNumber, frValueDistOrNumber), err> => - values->ToValueArray.Record.twoArgs(labels)->E.R.bind(twoDistOrNumber) + let twoDistOrNumber = (values: ts, labels: (string, string)): result< + (frValueDistOrNumber, frValueDistOrNumber), + err, + > => values->ToValueArray.Record.twoArgs(labels)->E.R.bind(twoDistOrNumber) let twoDist = (values: ts, labels: (string, string)): result< (DistributionTypes.genericDist, DistributionTypes.genericDist), From 8477b0c5f74307281ca48aedcf661d369361a3d1 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Fri, 30 Sep 2022 10:36:42 +1000 Subject: [PATCH 44/46] Format Rescript + fix ts error --- .../components/SquiggleViewer/ExpressionViewer.tsx | 2 +- packages/squiggle-lang/src/rescript/FR/FR_Dict.res | 3 ++- .../squiggle-lang/src/rescript/FR/FR_Pointset.res | 3 ++- .../FunctionRegistry/FunctionRegistry_Core.res | 11 ++++------- 4 files changed, 9 insertions(+), 10 deletions(-) diff --git a/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx b/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx index 8bd32292..c2677789 100644 --- a/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx +++ b/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx @@ -298,7 +298,7 @@ export const ExpressionViewer: React.FC = ({ value, width }) => { {() => (
No display for type: {" "} - {value.tag} + {(value as {tag: string}).tag}
)} diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Dict.res b/packages/squiggle-lang/src/rescript/FR/FR_Dict.res index d135717c..77ca49a7 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Dict.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Dict.res @@ -71,7 +71,8 @@ let library = [ ~inputs=[FRTypeArray(FRTypeDict(FRTypeAny))], ~run=(inputs, _, _) => { switch inputs { - | [IEvArray(dicts)] => dicts + | [IEvArray(dicts)] => + dicts ->Belt.Array.map(dictValue => switch dictValue { | IEvRecord(dict) => dict diff --git a/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res b/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res index ee4f7ca8..a12164bd 100644 --- a/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res +++ b/packages/squiggle-lang/src/rescript/FR/FR_Pointset.res @@ -7,7 +7,8 @@ let requiresNamespace = true let inputsToDist = (inputs: array, xyShapeToPointSetDist) => { // TODO - rewrite in more functional/functor-based style switch inputs { - | [IEvArray(items)] => items + | [IEvArray(items)] => + items ->Belt.Array.map(item => switch item { | IEvRecord(map) => { diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res index 5d606bb8..9683147f 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res @@ -83,15 +83,12 @@ module FRType = { | (FRTypeNumeric, IEvNumber(_)) => true | (FRTypeNumeric, IEvDistribution(Symbolic(#Float(_)))) => true | (FRTypeLambda, IEvLambda(_)) => true - | (FRTypeArray(intendedType), IEvArray(elements)) => elements->Belt.Array.every(v => - matchWithValue(intendedType, v) - ) + | (FRTypeArray(intendedType), IEvArray(elements)) => + elements->Belt.Array.every(v => matchWithValue(intendedType, v)) | (FRTypeDict(r), IEvRecord(map)) => map->Belt.Map.String.valuesToArray->Belt.Array.every(v => matchWithValue(r, v)) - | (FRTypeRecord(recordParams), IEvRecord(map)) => recordParams->Belt.Array.every((( - name, - input, - )) => { + | (FRTypeRecord(recordParams), IEvRecord(map)) => + recordParams->Belt.Array.every(((name, input)) => { switch map->Belt.Map.String.get(name) { | Some(v) => matchWithValue(input, v) | None => false From 6cd368ba7dbe3b2d224054eacd917f306a9ac070 Mon Sep 17 00:00:00 2001 From: Sam Nolan Date: Fri, 30 Sep 2022 10:38:48 +1000 Subject: [PATCH 45/46] Format components --- .../src/components/SquiggleViewer/ExpressionViewer.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx b/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx index c2677789..cb40c509 100644 --- a/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx +++ b/packages/components/src/components/SquiggleViewer/ExpressionViewer.tsx @@ -298,7 +298,9 @@ export const ExpressionViewer: React.FC = ({ value, width }) => { {() => (
No display for type: {" "} - {(value as {tag: string}).tag} + + {(value as { tag: string }).tag} +
)} From c47d5b4e624cb600e5bf876736857c6a352a1ec3 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Sun, 2 Oct 2022 14:28:03 +0400 Subject: [PATCH 46/46] remove SquigglePartial story (was broken since 0.4) --- .../src/stories/SquigglePartial.stories.mdx | 51 ------------------- 1 file changed, 51 deletions(-) delete mode 100644 packages/components/src/stories/SquigglePartial.stories.mdx diff --git a/packages/components/src/stories/SquigglePartial.stories.mdx b/packages/components/src/stories/SquigglePartial.stories.mdx deleted file mode 100644 index 3305586b..00000000 --- a/packages/components/src/stories/SquigglePartial.stories.mdx +++ /dev/null @@ -1,51 +0,0 @@ -import { SquigglePartial, SquiggleEditor } from "../components/SquiggleEditor"; -import { useState } from "react"; -import { Canvas, Meta, Story, Props } from "@storybook/addon-docs"; - - - -export const Template = (props) => ; - -# Squiggle Partial - -A Squiggle Partial is an editor that does not return a graph to the user, but -instead returns bindings that can be used by further Squiggle Editors. - - - - {Template.bind({})} - - - - - - {(props) => { - let [bindings, setBindings] = useState({}); - return ( - <> - - - - ); - }} - -