From 2e8e71bbd0b4198db1a4dba71a6f6e890af1cc12 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 25 Jul 2022 16:34:33 +0200 Subject: [PATCH 01/53] project test remove setResult parse end of outerblock test end of outer block compiles testing bindings tested todo chain bindings topological sort --- .../Reducer_Dispatch_BuiltIn_test.res | 10 +- .../Reducer_Peggy_Parse_test.res | 517 ++++++---- .../Reducer_Peggy_Parse_type_test.res | 36 +- .../Reducer_Peggy_TestHelpers.res | 8 +- ...cer_Peggy_ToExpression_outerBlock_test.res | 23 + .../Reducer_Peggy_ToExpression_test.res | 178 ++-- .../Reducer_Peggy_ToExpression_type_test.res | 52 +- .../Reducer_Peggy_ToExpression_void_test.res | 17 +- .../__tests__/Reducer/Reducer_TestHelpers.res | 27 +- .../Reducer/Reducer_TestMacroHelpers.res | 14 +- .../Reducer_Type_Compile_test.res | 4 +- ...educer_Type_TypeChecker_arguments_test.res | 11 +- .../Reducer_Type_TypeChecker_test.res | 7 +- .../Reducer/Reducer_externalBindings_test.res | 14 - .../Reducer_functionAssignment_test.res | 10 +- .../Reducer/Reducer_functionTricks_test.res | 27 +- .../Reducer/Reducer_ternaryOperator_test.res | 5 +- .../__tests__/Reducer/Reducer_test.res | 2 +- .../ReducerInterface_Distribution_test.res | 32 +- .../ReducerProject/ReducerProject_test.res | 179 ++++ ...leLibrary_FunctionRegistryLibrary_test.res | 10 +- .../FunctionRegistry_Core.res | 24 +- .../FunctionRegistry/Library/FR_Dist.res | 20 +- .../FunctionRegistry/Library/FR_List.res | 72 +- .../FunctionRegistry/Library/FR_Pointset.res | 6 +- .../FunctionRegistry/Library/FR_Sampleset.res | 68 +- .../FunctionRegistry/Library/FR_Scoring.res | 16 +- .../src/rescript/Reducer/Reducer.res | 26 +- .../src/rescript/Reducer/Reducer.resi | 52 +- .../Reducer_Bindings/Reducer_Bindings.res | 1 + .../Reducer_Dispatch_BuiltIn.res | 38 +- .../Reducer_Dispatch_BuiltInMacros.res | 51 +- .../rescript/Reducer/Reducer_ErrorValue.res | 2 +- .../Reducer_Expression/Reducer_Expression.res | 140 ++- .../Reducer_ExpressionWithContext.res | 13 +- .../Reducer_Expression_Lambda.res | 41 +- .../Reducer_Expression_Macro.res | 23 +- .../Reducer_Expression_T.res | 2 + .../Reducer_Peggy_GeneratedParser.peggy | 19 +- .../Reducer_Type/Reducer_Type_Compile.res | 47 +- .../Reducer_Type/Reducer_Type_TypeChecker.res | 6 +- ...ducerInterface_ExternalExpressionValue.res | 12 + .../ReducerInterface_ExternalLibrary.res | 18 +- ...ducerInterface_InternalExpressionValue.res | 6 + .../ReducerInterface_StdLib.res | 3 +- .../ReducerInterface_Value_Continuation.res | 28 + .../ReducerProject/ReducerProject.res | 396 ++++++++ .../ReducerProject_IncludeParser.js | 915 ++++++++++++++++++ .../ReducerProject_IncludeParser.peggy | 41 + .../ReducerProject_ParseIncludes.res | 8 + .../ReducerProject_ProjectAccessors_T.res | 24 + .../ReducerProject_ProjectItem.res | 176 ++++ .../ReducerProject_ProjectItem_T.res | 39 + .../ReducerProject_ReducerFn_T.res | 9 + .../ReducerProject/ReducerProject_T.res | 25 + .../src/rescript/TypescriptInterface.res | 16 +- 56 files changed, 2831 insertions(+), 735 deletions(-) create mode 100644 packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_outerBlock_test.res delete mode 100644 packages/squiggle-lang/__tests__/Reducer/Reducer_externalBindings_test.res create mode 100644 packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res create mode 100644 packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Value/ReducerInterface_Value_Continuation.res create mode 100644 packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res create mode 100644 packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js create mode 100644 packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.peggy create mode 100644 packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ParseIncludes.res create mode 100644 packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectAccessors_T.res create mode 100644 packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res create mode 100644 packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem_T.res create mode 100644 packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ReducerFn_T.res create mode 100644 packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res 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 f3c92f78..4932af3b 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 @@ -1,10 +1,14 @@ -module ExpressionValue = ReducerInterface.ExternalExpressionValue +module ExpressionValue = ReducerInterface.InternalExpressionValue +module Expression = Reducer_Expression open Jest open Expect -let expectEvalToBe = (expr: string, answer: string) => - Reducer.evaluate(expr)->ExpressionValue.toStringResult->expect->toBe(answer) +let expectEvalToBe = (sourceCode: string, answer: string) => + Expression.BackCompatible.evaluateString(sourceCode) + ->ExpressionValue.toStringResult + ->expect + ->toBe(answer) let testEval = (expr, answer) => test(expr, () => expectEvalToBe(expr, answer)) 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 f17fe9aa..80093afb 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,359 +3,464 @@ open Reducer_Peggy_TestHelpers describe("Peggy parse", () => { describe("float", () => { - 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}") + 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)}") }) describe("literals operators parenthesis", () => { // Note that there is always an outer block. Otherwise, external bindings are ignrored at the first statement - 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)}") + 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))}") }) describe("unary", () => { - 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))}") + 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)))}") }) describe("multiplicative", () => { - 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", "{(::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", "{(::$_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 + 3 * 4", + "{(::$_endOfOuterBlock_$ () (::add (::multiply 1 2) (::multiply 3 4)))}", + ) + testParse( + "1 * 2 - 3 * 4", + "{(::$_endOfOuterBlock_$ () (::subtract (::multiply 1 2) (::multiply 3 4)))}", + ) + testParse( + "1 * 2 .+ 3 * 4", + "{(::$_endOfOuterBlock_$ () (::dotAdd (::multiply 1 2) (::multiply 3 4)))}", + ) + testParse( + "1 * 2 .- 3 * 4", + "{(::$_endOfOuterBlock_$ () (::dotSubtract (::multiply 1 2) (::multiply 3 4)))}", + ) + testParse( + "1 * 2 + 3 .* 4", + "{(::$_endOfOuterBlock_$ () (::add (::multiply 1 2) (::dotMultiply 3 4)))}", + ) + testParse( + "1 * 2 + 3 / 4", + "{(::$_endOfOuterBlock_$ () (::add (::multiply 1 2) (::divide 3 4)))}", + ) + testParse( + "1 * 2 + 3 ./ 4", + "{(::$_endOfOuterBlock_$ () (::add (::multiply 1 2) (::dotDivide 3 4)))}", + ) + testParse( + "1 * 2 - 3 .* 4", + "{(::$_endOfOuterBlock_$ () (::subtract (::multiply 1 2) (::dotMultiply 3 4)))}", + ) + testParse( + "1 * 2 - 3 / 4", + "{(::$_endOfOuterBlock_$ () (::subtract (::multiply 1 2) (::divide 3 4)))}", + ) + testParse( + "1 * 2 - 3 ./ 4", + "{(::$_endOfOuterBlock_$ () (::subtract (::multiply 1 2) (::dotDivide 3 4)))}", + ) + testParse( + "1 * 2 - 3 * 4^5", + "{(::$_endOfOuterBlock_$ () (::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)))}", + "{(::$_endOfOuterBlock_$ () (::subtract (::multiply 1 2) (::multiply 3 (::pow (::pow 4 5) 6))))}", + ) + testParse( + "1 * -a[-2]", + "{(::$_endOfOuterBlock_$ () (::multiply 1 (::unaryMinus (::$_atIndex_$ :a (::unaryMinus 2)))))}", ) - testParse("1 * -a[-2]", "{(::multiply 1 (::unaryMinus (::$_atIndex_$ :a (::unaryMinus 2))))}") }) describe("multi-line", () => { - testParse("x=1; 2", "{:x = {1}; 2}") - testParse("x=1; y=2", "{:x = {1}; :y = {2}}") + testParse("x=1; 2", "{:x = {1}; (::$_endOfOuterBlock_$ () 2)}") + testParse("x=1; y=2", "{:x = {1}; :y = {2}; (::$_endOfOuterBlock_$ () ())}") }) describe("variables", () => { - testParse("x = 1", "{:x = {1}}") - testParse("x", "{:x}") - testParse("x = 1; x", "{:x = {1}; :x}") + testParse("x = 1", "{:x = {1}; (::$_endOfOuterBlock_$ () ())}") + testParse("x", "{(::$_endOfOuterBlock_$ () :x)}") + testParse("x = 1; x", "{:x = {1}; (::$_endOfOuterBlock_$ () :x)}") }) describe("functions", () => { - testParse("identity(x) = x", "{:identity = {|:x| {:x}}}") // Function definitions become lambda assignments - testParse("identity(x)", "{(::identity :x)}") + testParse("identity(x) = x", "{:identity = {|:x| {:x}}; (::$_endOfOuterBlock_$ () ())}") // Function definitions become lambda assignments + testParse("identity(x)", "{(::$_endOfOuterBlock_$ () (::identity :x))}") }) describe("arrays", () => { - testParse("[]", "{(::$_constructArray_$ ())}") - testParse("[0, 1, 2]", "{(::$_constructArray_$ (0 1 2))}") - testParse("['hello', 'world']", "{(::$_constructArray_$ ('hello' 'world'))}") - testParse("([0,1,2])[1]", "{(::$_atIndex_$ (::$_constructArray_$ (0 1 2)) 1)}") + testParse("[]", "{(::$_endOfOuterBlock_$ () (::$_constructArray_$ ()))}") + testParse("[0, 1, 2]", "{(::$_endOfOuterBlock_$ () (::$_constructArray_$ (0 1 2)))}") + testParse( + "['hello', 'world']", + "{(::$_endOfOuterBlock_$ () (::$_constructArray_$ ('hello' 'world')))}", + ) + testParse( + "([0,1,2])[1]", + "{(::$_endOfOuterBlock_$ () (::$_atIndex_$ (::$_constructArray_$ (0 1 2)) 1))}", + ) }) describe("records", () => { - testParse("{a: 1, b: 2}", "{(::$_constructRecord_$ ('a': 1 'b': 2))}") - testParse("{1+0: 1, 2+0: 2}", "{(::$_constructRecord_$ ((::add 1 0): 1 (::add 2 0): 2))}") // key can be any expression - testParse("record.property", "{(::$_atIndex_$ :record 'property')}") + testParse( + "{a: 1, b: 2}", + "{(::$_endOfOuterBlock_$ () (::$_constructRecord_$ ('a': 1 'b': 2)))}", + ) + testParse( + "{1+0: 1, 2+0: 2}", + "{(::$_endOfOuterBlock_$ () (::$_constructRecord_$ ((::add 1 0): 1 (::add 2 0): 2)))}", + ) // key can be any expression + testParse("record.property", "{(::$_endOfOuterBlock_$ () (::$_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)", "{(::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(1)", "{(::$_endOfOuterBlock_$ () (::equal :a (::not (::b 1))))}") + testParse("a==!b[1]", "{(::$_endOfOuterBlock_$ () (::equal :a (::not (::$_atIndex_$ :b 1))))}") + testParse( + "a==!b.one", + "{(::$_endOfOuterBlock_$ () (::equal :a (::not (::$_atIndex_$ :b 'one'))))}", + ) }) describe("comments", () => { - 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("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( ` - /* This is - a multi line - comment */ - 1`, - "{1}", + /* This is + a multi line + comment */ + 1`, + "{(::$_endOfOuterBlock_$ () 1)}", ) }) describe("ternary operator", () => { - testParse("true ? 2 : 3", "{(::$$_ternary_$$ true 2 3)}") + testParse("true ? 2 : 3", "{(::$_endOfOuterBlock_$ () (::$$_ternary_$$ true 2 3))}") testParse( "false ? 2 : false ? 4 : 5", - "{(::$$_ternary_$$ false 2 (::$$_ternary_$$ false 4 5))}", + "{(::$_endOfOuterBlock_$ () (::$$_ternary_$$ false 2 (::$$_ternary_$$ false 4 5)))}", ) // nested ternary }) 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", + "{(::$_endOfOuterBlock_$ () (::$$_ternary_$$ true {2} {3}))}", + ) + testParse( + "if false then {2} else {3}", + "{(::$_endOfOuterBlock_$ () (::$$_ternary_$$ false {2} {3}))}", + ) testParse( "if false then {2} else if false then {4} else {5}", - "{(::$$_ternary_$$ false {2} (::$$_ternary_$$ false {4} {5}))}", + "{(::$_endOfOuterBlock_$ () (::$$_ternary_$$ false {2} (::$$_ternary_$$ false {4} {5})))}", ) //nested if }) describe("logical", () => { - 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", "{(::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=c || d", + "{(::$_endOfOuterBlock_$ () (::or (::and :a (::largerEq :b :c)) :d))}", + ) + testParse( + "a && !(b>=c) || d", + "{(::$_endOfOuterBlock_$ () (::or (::and :a (::not (::largerEq :b :c))) :d))}", + ) + testParse( + "a && b<=c || d", + "{(::$_endOfOuterBlock_$ () (::or (::and :a (::smallerEq :b :c)) :d))}", + ) + testParse("a && b>c || d", "{(::$_endOfOuterBlock_$ () (::or (::and :a (::larger :b :c)) :d))}") + testParse( + "a && b { - 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("-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 -> add(2)", "{(::$_endOfOuterBlock_$ () (::add 1 2))}") + testParse("-1 -> add(2)", "{(::$_endOfOuterBlock_$ () (::add (::unaryMinus 1) 2))}") + testParse( + "-a[1] -> add(2)", + "{(::$_endOfOuterBlock_$ () (::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( + "1 -> subtract(2) * 3", + "{(::$_endOfOuterBlock_$ () (::multiply (::subtract 1 2) 3))}", + ) }) describe("elixir pipe", () => { //handled together with -> so there is no need for seperate tests - testParse("1 |> add(2)", "{(::add 1 2)}") + testParse("1 |> add(2)", "{(::$_endOfOuterBlock_$ () (::add 1 2))}") }) 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", "{(::$_endOfOuterBlock_$ () (::credibleIntervalToDistribution 1 2))}") + testParse( + "-1 to -2", + "{(::$_endOfOuterBlock_$ () (::credibleIntervalToDistribution (::unaryMinus 1) (::unaryMinus 2)))}", + ) // lower than unary testParse( "a[1] to a[2]", - "{(::credibleIntervalToDistribution (::$_atIndex_$ :a 1) (::$_atIndex_$ :a 2))}", + "{(::$_endOfOuterBlock_$ () (::credibleIntervalToDistribution (::$_atIndex_$ :a 1) (::$_atIndex_$ :a 2)))}", ) // lower than post testParse( "a.p1 to a.p2", - "{(::credibleIntervalToDistribution (::$_atIndex_$ :a 'p1') (::$_atIndex_$ :a 'p2'))}", + "{(::$_endOfOuterBlock_$ () (::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", + "{(::$_endOfOuterBlock_$ () (::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))}", + "{(::$_endOfOuterBlock_$ () (::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}; :x}") + testParse("x={y=1; y}; x", "{:x = {:y = {1}; :y}; (::$_endOfOuterBlock_$ () :x)}") }) describe("lambda", () => { - 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("{|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( + "f(x)=x ? 1 : 0", + "{:f = {|:x| {(::$$_ternary_$$ :x 1 0)}}; (::$_endOfOuterBlock_$ () ())}", + ) // 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}; :z}", + "{:myadd = {|:x,:y| {(::add :x :y)}}; :z = {:myadd}; (::$_endOfOuterBlock_$ () :z)}", ) testParse( "myadd(x,y)=x+y; z=[myadd]; z", - "{:myadd = {|:x,:y| {(::add :x :y)}}; :z = {(::$_constructArray_$ (:myadd))}; :z}", + "{:myadd = {|:x,:y| {(::add :x :y)}}; :z = {(::$_constructArray_$ (:myadd))}; (::$_endOfOuterBlock_$ () :z)}", ) testParse( "myaddd(x,y)=x+y; z={x: myaddd}; z", - "{:myaddd = {|:x,:y| {(::add :x :y)}}; :z = {(::$_constructRecord_$ ('x': :myaddd))}; :z}", + "{:myaddd = {|:x,:y| {(::add :x :y)}}; :z = {(::$_constructRecord_$ ('x': :myaddd))}; (::$_endOfOuterBlock_$ () :z)}", + ) + testParse("f({|x| x+1})", "{(::$_endOfOuterBlock_$ () (::f {|:x| {(::add :x 1)}}))}") + testParse( + "map(arr, {|x| x+1})", + "{(::$_endOfOuterBlock_$ () (::map :arr {|:x| {(::add :x 1)}}))}", ) - 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 (::$_constructArray_$ (1 2 3)) {|:x| {(::add :x 1)}})}", + "{(::$_endOfOuterBlock_$ () (::map (::$_constructArray_$ (1 2 3)) {|:x| {(::add :x 1)}}))}", ) testParse( "[1,2,3]->map({|x| x+1})", - "{(::map (::$_constructArray_$ (1 2 3)) {|:x| {(::add :x 1)}})}", + "{(::$_endOfOuterBlock_$ () (::map (::$_constructArray_$ (1 2 3)) {|:x| {(::add :x 1)}}))}", ) }) describe("unit", () => { - testParse("1m", "{(::fromUnit_m 1)}") - testParse("1M", "{(::fromUnit_M 1)}") - testParse("1m+2cm", "{(::add (::fromUnit_m 1) (::fromUnit_cm 2))}") + testParse("1m", "{(::$_endOfOuterBlock_$ () (::fromUnit_m 1))}") + testParse("1M", "{(::$_endOfOuterBlock_$ () (::fromUnit_M 1))}") + testParse("1m+2cm", "{(::$_endOfOuterBlock_$ () (::add (::fromUnit_m 1) (::fromUnit_cm 2)))}") }) describe("Module", () => { - testParse("x", "{:x}") - testParse("Math.pi", "{:Math.pi}") + testParse("x", "{(::$_endOfOuterBlock_$ () :x)}") + testParse("Math.pi", "{(::$_endOfOuterBlock_$ () :Math.pi)}") }) }) describe("parsing new line", () => { testParse( ` - a + - b`, - "{(::add :a :b)}", + a + + b`, + "{(::$_endOfOuterBlock_$ () (::add :a :b))}", ) testParse( ` - x= - 1`, - "{:x = {1}}", + x= + 1`, + "{:x = {1}; (::$_endOfOuterBlock_$ () ())}", ) testParse( ` - x=1 - y=2`, - "{:x = {1}; :y = {2}}", + x=1 + y=2`, + "{:x = {1}; :y = {2}; (::$_endOfOuterBlock_$ () ())}", ) testParse( ` - x={ - y=2; - y } - x`, - "{:x = {:y = {2}; :y}; :x}", + x={ + y=2; + y } + x`, + "{:x = {:y = {2}; :y}; (::$_endOfOuterBlock_$ () :x)}", ) testParse( ` - x={ - y=2 - y } - x`, - "{:x = {:y = {2}; :y}; :x}", + x={ + y=2 + y } + x`, + "{:x = {:y = {2}; :y}; (::$_endOfOuterBlock_$ () :x)}", ) testParse( ` - x={ - y=2 - y - } - x`, - "{:x = {:y = {2}; :y}; :x}", + x={ + y=2 + y + } + x`, + "{:x = {:y = {2}; :y}; (::$_endOfOuterBlock_$ () :x)}", ) testParse( ` + x=1 + y=2 + z=3 + `, + "{:x = {1}; :y = {2}; :z = {3}; (::$_endOfOuterBlock_$ () ())}", + ) + testParse( + ` + f={ x=1 y=2 z=3 - `, - "{:x = {1}; :y = {2}; :z = {3}}", + x+y+z + } + `, + "{:f = {:x = {1}; :y = {2}; :z = {3}; (::add (::add :x :y) :z)}; (::$_endOfOuterBlock_$ () ())}", ) testParse( ` - f={ - x=1 - y=2 - z=3 - x+y+z + f={ + x=1 + y=2 + z=3 + x+y+z + } + g=f+4 + g + `, + "{:f = {:x = {1}; :y = {2}; :z = {3}; (::add (::add :x :y) :z)}; :g = {(::add :f 4)}; (::$_endOfOuterBlock_$ () :g)}", + ) + testParse( + ` + f = + { + x=1; //x + y=2 //y + z= + 3 + x+ + y+ + z } - `, - "{:f = {:x = {1}; :y = {2}; :z = {3}; (::add (::add :x :y) :z)}}", + g = + f + + 4 + g -> + h -> + p -> + q + `, + "{:f = {:x = {1}; :y = {2}; :z = {3}; (::add (::add :x :y) :z)}; :g = {(::add :f 4)}; (::$_endOfOuterBlock_$ () (::q (::p (::h :g))))}", ) testParse( ` - f={ - x=1 - y=2 - z=3 - x+y+z - } - g=f+4 - g - `, - "{:f = {:x = {1}; :y = {2}; :z = {3}; (::add (::add :x :y) :z)}; :g = {(::add :f 4)}; :g}", + a |> + b |> + c |> + d + `, + "{(::$_endOfOuterBlock_$ () (::d (::c (::b :a))))}", ) testParse( ` - f = - { - x=1; //x - y=2 //y - z= - 3 - x+ - y+ - z - } - g = - f + - 4 - g -> - h -> - p -> - q - `, - "{:f = {:x = {1}; :y = {2}; :z = {3}; (::add (::add :x :y) :z)}; :g = {(::add :f 4)}; (::q (::p (::h :g)))}", - ) - testParse( - ` - a |> - b |> - c |> - d - `, - "{(::d (::c (::b :a)))}", - ) - testParse( - ` - a |> - b |> - c |> - d + - e - `, - "{(::add (::d (::c (::b :a))) :e)}", + a |> + b |> + c |> + d + + e + `, + "{(::$_endOfOuterBlock_$ () (::add (::d (::c (::b :a))) :e))}", ) }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_Parse_type_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_Parse_type_test.res index 4f7dabdc..010486be 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_Parse_type_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_Parse_type_test.res @@ -3,77 +3,83 @@ open Reducer_Peggy_TestHelpers describe("Peggy parse type", () => { describe("type of", () => { - testParse("p: number", "{(::$_typeOf_$ :p #number)}") + testParse("p: number", "{(::$_typeOf_$ :p #number); (::$_endOfOuterBlock_$ () ())}") }) describe("type alias", () => { - testParse("type index=number", "{(::$_typeAlias_$ #index #number)}") + testParse( + "type index=number", + "{(::$_typeAlias_$ #index #number); (::$_endOfOuterBlock_$ () ())}", + ) }) describe("type or", () => { testParse( "answer: number|string", - "{(::$_typeOf_$ :answer (::$_typeOr_$ (::$_constructArray_$ (#number #string))))}", + "{(::$_typeOf_$ :answer (::$_typeOr_$ (::$_constructArray_$ (#number #string)))); (::$_endOfOuterBlock_$ () ())}", ) }) describe("type function", () => { testParse( "f: number=>number=>number", - "{(::$_typeOf_$ :f (::$_typeFunction_$ (::$_constructArray_$ (#number #number #number))))}", + "{(::$_typeOf_$ :f (::$_typeFunction_$ (::$_constructArray_$ (#number #number #number)))); (::$_endOfOuterBlock_$ () ())}", ) }) describe("high priority contract", () => { testParse( "answer: number<-min<-max(100)|string", - "{(::$_typeOf_$ :answer (::$_typeOr_$ (::$_constructArray_$ ((::$_typeModifier_max_$ (::$_typeModifier_min_$ #number) 100) #string))))}", + "{(::$_typeOf_$ :answer (::$_typeOr_$ (::$_constructArray_$ ((::$_typeModifier_max_$ (::$_typeModifier_min_$ #number) 100) #string)))); (::$_endOfOuterBlock_$ () ())}", ) testParse( "answer: number<-memberOf([1,3,5])", - "{(::$_typeOf_$ :answer (::$_typeModifier_memberOf_$ #number (::$_constructArray_$ (1 3 5))))}", + "{(::$_typeOf_$ :answer (::$_typeModifier_memberOf_$ #number (::$_constructArray_$ (1 3 5)))); (::$_endOfOuterBlock_$ () ())}", ) }) describe("low priority contract", () => { testParse( "answer: number | string $ opaque", - "{(::$_typeOf_$ :answer (::$_typeModifier_opaque_$ (::$_typeOr_$ (::$_constructArray_$ (#number #string)))))}", + "{(::$_typeOf_$ :answer (::$_typeModifier_opaque_$ (::$_typeOr_$ (::$_constructArray_$ (#number #string))))); (::$_endOfOuterBlock_$ () ())}", ) }) describe("type array", () => { - testParse("answer: [number]", "{(::$_typeOf_$ :answer (::$_typeArray_$ #number))}") + testParse( + "answer: [number]", + "{(::$_typeOf_$ :answer (::$_typeArray_$ #number)); (::$_endOfOuterBlock_$ () ())}", + ) }) describe("type record", () => { testParse( "answer: {a: number, b: string}", - "{(::$_typeOf_$ :answer (::$_typeRecord_$ (::$_constructRecord_$ ('a': #number 'b': #string))))}", + "{(::$_typeOf_$ :answer (::$_typeRecord_$ (::$_constructRecord_$ ('a': #number 'b': #string)))); (::$_endOfOuterBlock_$ () ())}", ) }) describe("type constructor", () => { testParse( "answer: Age(number)", - "{(::$_typeOf_$ :answer (::$_typeConstructor_$ #Age (::$_constructArray_$ (#number))))}", + "{(::$_typeOf_$ :answer (::$_typeConstructor_$ #Age (::$_constructArray_$ (#number)))); (::$_endOfOuterBlock_$ () ())}", ) testParse( "answer: Complex(number, number)", - "{(::$_typeOf_$ :answer (::$_typeConstructor_$ #Complex (::$_constructArray_$ (#number #number))))}", + "{(::$_typeOf_$ :answer (::$_typeConstructor_$ #Complex (::$_constructArray_$ (#number #number)))); (::$_endOfOuterBlock_$ () ())}", ) testParse( "answer: Person({age: number, name: string})", - "{(::$_typeOf_$ :answer (::$_typeConstructor_$ #Person (::$_constructArray_$ ((::$_typeRecord_$ (::$_constructRecord_$ ('age': #number 'name': #string)))))))}", + "{(::$_typeOf_$ :answer (::$_typeConstructor_$ #Person (::$_constructArray_$ ((::$_typeRecord_$ (::$_constructRecord_$ ('age': #number 'name': #string))))))); (::$_endOfOuterBlock_$ () ())}", ) testParse( "weekend: Saturday | Sunday", - "{(::$_typeOf_$ :weekend (::$_typeOr_$ (::$_constructArray_$ ((::$_typeConstructor_$ #Saturday (::$_constructArray_$ ())) (::$_typeConstructor_$ #Sunday (::$_constructArray_$ ()))))))}", + "{(::$_typeOf_$ :weekend (::$_typeOr_$ (::$_constructArray_$ ((::$_typeConstructor_$ #Saturday (::$_constructArray_$ ())) (::$_typeConstructor_$ #Sunday (::$_constructArray_$ ())))))); (::$_endOfOuterBlock_$ () ())}", ) }) describe("type parenthesis", () => { //$ is introduced to avoid parenthesis testParse( "answer: (number|string)<-opaque", - "{(::$_typeOf_$ :answer (::$_typeModifier_opaque_$ (::$_typeOr_$ (::$_constructArray_$ (#number #string)))))}", + "{(::$_typeOf_$ :answer (::$_typeModifier_opaque_$ (::$_typeOr_$ (::$_constructArray_$ (#number #string))))); (::$_endOfOuterBlock_$ () ())}", ) }) describe("squiggle expressions in type contracts", () => { testParse( "odds1 = [1,3,5]; odds2 = [7, 9]; type odds = number<-memberOf(concat(odds1, odds2))", - "{:odds1 = {(::$_constructArray_$ (1 3 5))}; :odds2 = {(::$_constructArray_$ (7 9))}; (::$_typeAlias_$ #odds (::$_typeModifier_memberOf_$ #number (::concat :odds1 :odds2)))}", + "{:odds1 = {(::$_constructArray_$ (1 3 5))}; :odds2 = {(::$_constructArray_$ (7 9))}; (::$_typeAlias_$ #odds (::$_typeModifier_memberOf_$ #number (::concat :odds1 :odds2))); (::$_endOfOuterBlock_$ () ())}", ) }) }) 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 b434fdb9..303f66ee 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 @@ -23,13 +23,7 @@ let expectToExpressionToBe = (expr, answer, ~v="_", ()) => { } else { let a2 = rExpr - ->Result.flatMap(expr => - Expression.reduceExpression( - expr, - ReducerInterface_StdLib.internalStdLib, - ExpressionValue.defaultEnvironment, - ) - ) + ->Result.flatMap(expr => Expression.BackCompatible.evaluate(expr)) ->Reducer_Helpers.rRemoveDefaultsInternal ->ExpressionValue.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 new file mode 100644 index 00000000..951005c2 --- /dev/null +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_outerBlock_test.res @@ -0,0 +1,23 @@ +module Bindings = Reducer_Bindings +module InternalExpressionValue = ReducerInterface_InternalExpressionValue + +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( + "x=1; y=2", + "{(:$_let_$ :x {1}); (:$_let_$ :y {2}); (:$_endOfOuterBlock_$ () ())}", + ~v="()", + (), + ) + testToExpression("x=1; 2", "{(:$_let_$ :x {1}); (:$_endOfOuterBlock_$ () 2)}", ~v="2", ()) + testToExpression( + "x={a=1; a}; x", + "{(:$_let_$ :x {(:$_let_$ :a {1}); :a}); (:$_endOfOuterBlock_$ () :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 b8a81f25..3b20fafc 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,101 +7,138 @@ 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", "{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)}", ()) + 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))}", ()) }) describe("unary", () => { - 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))}", ()) + 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)))}", ()) }) describe("multi-line", () => { - testToExpression("x=1; 2", "{(:$_let_$ :x {1}); 2}", ~v="2", ()) - testToExpression("x=1; y=2", "{(:$_let_$ :x {1}); (:$_let_$ :y {2})}", ~v="@{x: 1,y: 2}", ()) + testToExpression("x=1; 2", "{(:$_let_$ :x {1}); (:$_endOfOuterBlock_$ () 2)}", ~v="2", ()) + testToExpression( + "x=1; y=2", + "{(:$_let_$ :x {1}); (:$_let_$ :y {2}); (:$_endOfOuterBlock_$ () ())}", + (), + ) }) describe("variables", () => { - testToExpression("x = 1", "{(:$_let_$ :x {1})}", ~v="@{x: 1}", ()) - testToExpression("x", "{:x}", ~v=":x", ()) //TODO: value should return error - testToExpression("x = 1; x", "{(:$_let_$ :x {1}); :x}", ~v="1", ()) + 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", ()) }) describe("functions", () => { testToExpression( "identity(x) = x", - "{(:$_let_$ :identity (:$$_lambda_$$ [x] {:x}))}", - ~v="@{identity: lambda(x=>internal code)}", + "{(:$_let_$ :identity (:$$_lambda_$$ [x] {:x})); (:$_endOfOuterBlock_$ () ())}", (), ) // Function definitions become lambda assignments - testToExpression("identity(x)", "{(:identity :x)}", ()) // Note value returns error properly + testToExpression("identity(x)", "{(:$_endOfOuterBlock_$ () (: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)})); (:f 3)}", + "{(:$_let_$ :f (:$$_lambda_$$ [x] {(:$$_ternary_$$ (:larger :x 2) 0 1)})); (:$_endOfOuterBlock_$ () (:f 3))}", ~v="0", (), ) }) describe("arrays", () => { - testToExpression("[]", "{(:$_constructArray_$ ())}", ~v="[]", ()) - testToExpression("[0, 1, 2]", "{(:$_constructArray_$ (0 1 2))}", ~v="[0,1,2]", ()) + testToExpression("[]", "{(:$_endOfOuterBlock_$ () (:$_constructArray_$ ()))}", ~v="[]", ()) + testToExpression( + "[0, 1, 2]", + "{(:$_endOfOuterBlock_$ () (:$_constructArray_$ (0 1 2)))}", + ~v="[0,1,2]", + (), + ) testToExpression( "['hello', 'world']", - "{(:$_constructArray_$ ('hello' 'world'))}", + "{(:$_endOfOuterBlock_$ () (:$_constructArray_$ ('hello' 'world')))}", ~v="['hello','world']", (), ) - testToExpression("([0,1,2])[1]", "{(:$_atIndex_$ (:$_constructArray_$ (0 1 2)) 1)}", ~v="1", ()) + testToExpression( + "([0,1,2])[1]", + "{(:$_endOfOuterBlock_$ () (:$_atIndex_$ (:$_constructArray_$ (0 1 2)) 1))}", + ~v="1", + (), + ) }) describe("records", () => { testToExpression( "{a: 1, b: 2}", - "{(:$_constructRecord_$ (('a' 1) ('b' 2)))}", + "{(:$_endOfOuterBlock_$ () (:$_constructRecord_$ (('a' 1) ('b' 2))))}", ~v="{a: 1,b: 2}", (), ) testToExpression( "{1+0: 1, 2+0: 2}", - "{(:$_constructRecord_$ (((:add 1 0) 1) ((:add 2 0) 2)))}", + "{(:$_endOfOuterBlock_$ () (:$_constructRecord_$ (((:add 1 0) 1) ((:add 2 0) 2))))}", (), ) // key can be any expression - testToExpression("record.property", "{(:$_atIndex_$ :record 'property')}", ()) + testToExpression( + "record.property", + "{(:$_endOfOuterBlock_$ () (:$_atIndex_$ :record 'property'))}", + (), + ) testToExpression( "record={property: 1}; record.property", - "{(:$_let_$ :record {(:$_constructRecord_$ (('property' 1)))}); (:$_atIndex_$ :record 'property')}", + "{(:$_let_$ :record {(:$_constructRecord_$ (('property' 1)))}); (:$_endOfOuterBlock_$ () (:$_atIndex_$ :record 'property'))}", ~v="1", (), ) }) 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 line comment", "{(:$_endOfOuterBlock_$ () 1)}", ~v="1", ()) + testToExpression("1 // This is a line comment", "{(:$_endOfOuterBlock_$ () 1)}", ~v="1", ()) + testToExpression( + "1 /* This is a multi line comment */", + "{(:$_endOfOuterBlock_$ () 1)}", + ~v="1", + (), + ) + testToExpression( + "/* This is a multi line comment */ 1", + "{(:$_endOfOuterBlock_$ () 1)}", + ~v="1", + (), + ) }) describe("ternary operator", () => { - testToExpression("true ? 1 : 0", "{(:$$_ternary_$$ true 1 0)}", ~v="1", ()) - testToExpression("false ? 1 : 0", "{(:$$_ternary_$$ false 1 0)}", ~v="0", ()) + testToExpression( + "true ? 1 : 0", + "{(:$_endOfOuterBlock_$ () (:$$_ternary_$$ true 1 0))}", + ~v="1", + (), + ) + testToExpression( + "false ? 1 : 0", + "{(:$_endOfOuterBlock_$ () (:$$_ternary_$$ false 1 0))}", + ~v="0", + (), + ) testToExpression( "true ? 1 : false ? 2 : 0", - "{(:$$_ternary_$$ true 1 (:$$_ternary_$$ false 2 0))}", + "{(:$_endOfOuterBlock_$ () (:$$_ternary_$$ true 1 (:$$_ternary_$$ false 2 0)))}", ~v="1", (), ) // nested ternary testToExpression( "false ? 1 : false ? 2 : 0", - "{(:$$_ternary_$$ false 1 (:$$_ternary_$$ false 2 0))}", + "{(:$_endOfOuterBlock_$ () (:$$_ternary_$$ false 1 (:$$_ternary_$$ false 2 0)))}", ~v="0", (), ) // nested ternary @@ -109,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)})); (:f 6)}", + "{(:$_let_$ :f (:$$_lambda_$$ [a] {(:$$_ternary_$$ (:larger :a 5) 1 0)})); (:$_endOfOuterBlock_$ () (: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)})); (:f 6)}", + "{(:$_let_$ :f (:$$_lambda_$$ [a] {(:$$_ternary_$$ (:larger :a 5) :a 0)})); (:$_endOfOuterBlock_$ () (: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)})); (:f 6)}", + "{(:$_let_$ :f (:$$_lambda_$$ [a] {(:$$_ternary_$$ (:smaller :a 5) 1 :a)})); (:$_endOfOuterBlock_$ () (:f 6))}", ~v="6", (), ) @@ -131,23 +168,41 @@ describe("Peggy to Expression", () => { }) describe("if then else", () => { - testToExpression("if true then 2 else 3", "{(:$$_ternary_$$ true {2} {3})}", ()) - testToExpression("if true then {2} else {3}", "{(:$$_ternary_$$ true {2} {3})}", ()) + testToExpression( + "if true then 2 else 3", + "{(:$_endOfOuterBlock_$ () (:$$_ternary_$$ true {2} {3}))}", + (), + ) + testToExpression( + "if true then {2} else {3}", + "{(:$_endOfOuterBlock_$ () (:$$_ternary_$$ true {2} {3}))}", + (), + ) testToExpression( "if false then {2} else if false then {4} else {5}", - "{(:$$_ternary_$$ false {2} (:$$_ternary_$$ false {4} {5}))}", + "{(:$_endOfOuterBlock_$ () (:$$_ternary_$$ false {2} (:$$_ternary_$$ false {4} {5})))}", (), ) //nested if }) 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)", "{(:$_endOfOuterBlock_$ () (:add 1 2))}", ~v="3", ()) + testToExpression( + "-1 -> add(2)", + "{(:$_endOfOuterBlock_$ () (:add (:unaryMinus 1) 2))}", + ~v="1", + (), + ) // note that unary has higher priority naturally + testToExpression( + "1 -> add(2) * 3", + "{(:$_endOfOuterBlock_$ () (:multiply (:add 1 2) 3))}", + ~v="9", + (), + ) }) describe("elixir pipe", () => { - testToExpression("1 |> add(2)", "{(:add 1 2)}", ~v="3", ()) + testToExpression("1 |> add(2)", "{(:$_endOfOuterBlock_$ () (:add 1 2))}", ~v="3", ()) }) // see testParse for priorities of to and credibleIntervalToDistribution @@ -157,30 +212,31 @@ 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})}", - ~v="@{x: 1,y: 99}", + "{(:$_let_$ :y {99}); (:$_let_$ :x {(:$_let_$ :y {1}); :y}); (:$_endOfOuterBlock_$ () ())}", (), ) }) describe("lambda", () => { - testToExpression("{|x| x}", "{(:$$_lambda_$$ [x] {:x})}", ~v="lambda(x=>internal code)", ()) + testToExpression( + "{|x| x}", + "{(:$_endOfOuterBlock_$ () (:$$_lambda_$$ [x] {:x}))}", + ~v="lambda(x=>internal code)", + (), + ) testToExpression( "f={|x| x}", - "{(:$_let_$ :f {(:$$_lambda_$$ [x] {:x})})}", - ~v="@{f: lambda(x=>internal code)}", + "{(:$_let_$ :f {(:$$_lambda_$$ [x] {:x})}); (:$_endOfOuterBlock_$ () ())}", (), ) testToExpression( "f(x)=x", - "{(:$_let_$ :f (:$$_lambda_$$ [x] {:x}))}", - ~v="@{f: lambda(x=>internal code)}", + "{(:$_let_$ :f (:$$_lambda_$$ [x] {:x})); (:$_endOfOuterBlock_$ () ())}", (), ) // Function definitions are lambda assignments testToExpression( "f(x)=x ? 1 : 0", - "{(:$_let_$ :f (:$$_lambda_$$ [x] {(:$$_ternary_$$ :x 1 0)}))}", - ~v="@{f: lambda(x=>internal code)}", + "{(:$_let_$ :f (:$$_lambda_$$ [x] {(:$$_ternary_$$ :x 1 0)})); (:$_endOfOuterBlock_$ () ())}", (), ) }) @@ -188,12 +244,12 @@ describe("Peggy to Expression", () => { describe("module", () => { // testToExpression("Math.pi", "{:Math.pi}", ~v="3.141592653589793", ()) // Only.test("stdlibrary", () => { - // ReducerInterface_StdLib.internalStdLib - // ->IEvBindings - // ->InternalExpressionValue.toString - // ->expect - // ->toBe("") + // ReducerInterface_StdLib.internalStdLib + // ->IEvBindings + // ->InternalExpressionValue.toString + // ->expect + // ->toBe("") // }) - testToExpression("Math.pi", "{:Math.pi}", ~v="3.141592653589793", ()) + testToExpression("Math.pi", "{(:$_endOfOuterBlock_$ () :Math.pi)}", ~v="3.141592653589793", ()) }) }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_type_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_type_test.res index 9849adb0..b0cfb676 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_type_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Peggy/Reducer_Peggy_ToExpression_type_test.res @@ -5,92 +5,92 @@ describe("Peggy Types to Expression", () => { describe("type of", () => { testToExpression( "p: number", - "{(:$_typeOf_$ :p #number)}", - ~v="@{_typeReferences_: {p: #number}}", + "{(:$_typeOf_$ :p #number); (:$_endOfOuterBlock_$ () ())}", + // ~v="@{_typeReferences_: {p: #number}}", (), ) }) describe("type alias", () => { testToExpression( "type index=number", - "{(:$_typeAlias_$ #index #number)}", - ~v="@{_typeAliases_: {index: #number}}", + "{(:$_typeAlias_$ #index #number); (:$_endOfOuterBlock_$ () ())}", + // ~v="@{_typeAliases_: {index: #number}}", (), ) }) describe("type or", () => { testToExpression( "answer: number|string|distribution", - "{(:$_typeOf_$ :answer (:$_typeOr_$ (:$_constructArray_$ (#number #string #distribution))))}", - ~v="@{_typeReferences_: {answer: {typeOr: [#number,#string,#distribution],typeTag: 'typeOr'}}}", + "{(:$_typeOf_$ :answer (:$_typeOr_$ (:$_constructArray_$ (#number #string #distribution)))); (:$_endOfOuterBlock_$ () ())}", + // ~v="@{_typeReferences_: {answer: {typeOr: [#number,#string,#distribution],typeTag: 'typeOr'}}}", (), ) }) describe("type function", () => { testToExpression( "f: number=>number=>number", - "{(:$_typeOf_$ :f (:$_typeFunction_$ (:$_constructArray_$ (#number #number #number))))}", - ~v="@{_typeReferences_: {f: {inputs: [#number,#number],output: #number,typeTag: 'typeFunction'}}}", + "{(:$_typeOf_$ :f (:$_typeFunction_$ (:$_constructArray_$ (#number #number #number)))); (:$_endOfOuterBlock_$ () ())}", + // ~v="@{_typeReferences_: {f: {inputs: [#number,#number],output: #number,typeTag: 'typeFunction'}}}", (), ) testToExpression( "f: number=>number", - "{(:$_typeOf_$ :f (:$_typeFunction_$ (:$_constructArray_$ (#number #number))))}", - ~v="@{_typeReferences_: {f: {inputs: [#number],output: #number,typeTag: 'typeFunction'}}}", + "{(:$_typeOf_$ :f (:$_typeFunction_$ (:$_constructArray_$ (#number #number)))); (:$_endOfOuterBlock_$ () ())}", + // ~v="@{_typeReferences_: {f: {inputs: [#number],output: #number,typeTag: 'typeFunction'}}}", (), ) }) describe("high priority contract", () => { testToExpression( "answer: number<-min(1)<-max(100)|string", - "{(:$_typeOf_$ :answer (:$_typeOr_$ (:$_constructArray_$ ((:$_typeModifier_max_$ (:$_typeModifier_min_$ #number 1) 100) #string))))}", - ~v="@{_typeReferences_: {answer: {typeOr: [{max: 100,min: 1,typeIdentifier: #number,typeTag: 'typeIdentifier'},#string],typeTag: 'typeOr'}}}", + "{(:$_typeOf_$ :answer (:$_typeOr_$ (:$_constructArray_$ ((:$_typeModifier_max_$ (:$_typeModifier_min_$ #number 1) 100) #string)))); (:$_endOfOuterBlock_$ () ())}", + // ~v="@{_typeReferences_: {answer: {typeOr: [{max: 100,min: 1,typeIdentifier: #number,typeTag: 'typeIdentifier'},#string],typeTag: 'typeOr'}}}", (), ) testToExpression( "answer: number<-memberOf([1,3,5])", - "{(:$_typeOf_$ :answer (:$_typeModifier_memberOf_$ #number (:$_constructArray_$ (1 3 5))))}", - ~v="@{_typeReferences_: {answer: {memberOf: [1,3,5],typeIdentifier: #number,typeTag: 'typeIdentifier'}}}", + "{(:$_typeOf_$ :answer (:$_typeModifier_memberOf_$ #number (:$_constructArray_$ (1 3 5)))); (:$_endOfOuterBlock_$ () ())}", + // ~v="@{_typeReferences_: {answer: {memberOf: [1,3,5],typeIdentifier: #number,typeTag: 'typeIdentifier'}}}", (), ) testToExpression( "answer: number<-min(1)", - "{(:$_typeOf_$ :answer (:$_typeModifier_min_$ #number 1))}", - ~v="@{_typeReferences_: {answer: {min: 1,typeIdentifier: #number,typeTag: 'typeIdentifier'}}}", + "{(:$_typeOf_$ :answer (:$_typeModifier_min_$ #number 1)); (:$_endOfOuterBlock_$ () ())}", + // ~v="@{_typeReferences_: {answer: {min: 1,typeIdentifier: #number,typeTag: 'typeIdentifier'}}}", (), ) testToExpression( "answer: number<-max(10)", - "{(:$_typeOf_$ :answer (:$_typeModifier_max_$ #number 10))}", - ~v="@{_typeReferences_: {answer: {max: 10,typeIdentifier: #number,typeTag: 'typeIdentifier'}}}", + "{(:$_typeOf_$ :answer (:$_typeModifier_max_$ #number 10)); (:$_endOfOuterBlock_$ () ())}", + // ~v="@{_typeReferences_: {answer: {max: 10,typeIdentifier: #number,typeTag: 'typeIdentifier'}}}", (), ) testToExpression( "answer: number<-min(1)<-max(10)", - "{(:$_typeOf_$ :answer (:$_typeModifier_max_$ (:$_typeModifier_min_$ #number 1) 10))}", - ~v="@{_typeReferences_: {answer: {max: 10,min: 1,typeIdentifier: #number,typeTag: 'typeIdentifier'}}}", + "{(:$_typeOf_$ :answer (:$_typeModifier_max_$ (:$_typeModifier_min_$ #number 1) 10)); (:$_endOfOuterBlock_$ () ())}", + // ~v="@{_typeReferences_: {answer: {max: 10,min: 1,typeIdentifier: #number,typeTag: 'typeIdentifier'}}}", (), ) testToExpression( "answer: number<-max(10)<-min(1)", - "{(:$_typeOf_$ :answer (:$_typeModifier_min_$ (:$_typeModifier_max_$ #number 10) 1))}", - ~v="@{_typeReferences_: {answer: {max: 10,min: 1,typeIdentifier: #number,typeTag: 'typeIdentifier'}}}", + "{(:$_typeOf_$ :answer (:$_typeModifier_min_$ (:$_typeModifier_max_$ #number 10) 1)); (:$_endOfOuterBlock_$ () ())}", + // ~v="@{_typeReferences_: {answer: {max: 10,min: 1,typeIdentifier: #number,typeTag: 'typeIdentifier'}}}", (), ) }) describe("low priority contract", () => { testToExpression( "answer: number | string $ opaque", - "{(:$_typeOf_$ :answer (:$_typeModifier_opaque_$ (:$_typeOr_$ (:$_constructArray_$ (#number #string)))))}", - ~v="@{_typeReferences_: {answer: {opaque: true,typeOr: [#number,#string],typeTag: 'typeOr'}}}", + "{(:$_typeOf_$ :answer (:$_typeModifier_opaque_$ (:$_typeOr_$ (:$_constructArray_$ (#number #string))))); (:$_endOfOuterBlock_$ () ())}", + // ~v="@{_typeReferences_: {answer: {opaque: true,typeOr: [#number,#string],typeTag: 'typeOr'}}}", (), ) }) describe("squiggle expressions in type contracts", () => { testToExpression( "odds1 = [1,3,5]; odds2 = [7, 9]; type odds = number<-memberOf(concat(odds1, odds2))", - "{(:$_let_$ :odds1 {(:$_constructArray_$ (1 3 5))}); (:$_let_$ :odds2 {(:$_constructArray_$ (7 9))}); (:$_typeAlias_$ #odds (:$_typeModifier_memberOf_$ #number (:concat :odds1 :odds2)))}", - ~v="@{_typeAliases_: {odds: {memberOf: [1,3,5,7,9],typeIdentifier: #number,typeTag: 'typeIdentifier'}},odds1: [1,3,5],odds2: [7,9]}", + "{(:$_let_$ :odds1 {(:$_constructArray_$ (1 3 5))}); (:$_let_$ :odds2 {(:$_constructArray_$ (7 9))}); (:$_typeAlias_$ #odds (:$_typeModifier_memberOf_$ #number (:concat :odds1 :odds2))); (:$_endOfOuterBlock_$ () ())}", + // ~v="@{_typeAliases_: {odds: {memberOf: [1,3,5,7,9],typeIdentifier: #number,typeTag: 'typeIdentifier'}},odds1: [1,3,5],odds2: [7,9]}", (), ) }) 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 a106a188..f46d387f 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,18 +3,23 @@ open Reducer_Peggy_TestHelpers describe("Peggy void", () => { //literal - testToExpression("()", "{()}", ~v="()", ()) + testToExpression("()", "{(:$_endOfOuterBlock_$ () ())}", ~v="()", ()) testToExpression( "fn()=1", - "{(:$_let_$ :fn (:$$_lambda_$$ [_] {1}))}", - ~v="@{fn: lambda(_=>internal code)}", + "{(:$_let_$ :fn (:$$_lambda_$$ [_] {1})); (:$_endOfOuterBlock_$ () ())}", + // ~v="@{fn: lambda(_=>internal code)}", + (), + ) + testToExpression( + "fn()=1; fn()", + "{(:$_let_$ :fn (:$$_lambda_$$ [_] {1})); (:$_endOfOuterBlock_$ () (:fn ()))}", + ~v="1", (), ) - testToExpression("fn()=1; fn()", "{(:$_let_$ :fn (:$$_lambda_$$ [_] {1})); (:fn ())}", ~v="1", ()) testToExpression( "fn(a)=(); call fn(1)", - "{(:$_let_$ :fn (:$$_lambda_$$ [a] {()})); (:$_let_$ :_ {(:fn 1)})}", - ~v="@{_: (),fn: lambda(a=>internal code)}", + "{(:$_let_$ :fn (:$$_lambda_$$ [a] {()})); (:$_let_$ :_ {(:fn 1)}); (:$_endOfOuterBlock_$ () ())}", + // ~v="@{_: (),fn: lambda(a=>internal code)}", (), ) }) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res index 736c9c2f..d32457e6 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res @@ -1,6 +1,7 @@ +module ErrorValue = Reducer_ErrorValue +module Expression = Reducer_Expression module ExpressionT = Reducer_Expression_T module ExternalExpressionValue = ReducerInterface.ExternalExpressionValue -module ErrorValue = Reducer_ErrorValue open Jest open Expect @@ -13,25 +14,21 @@ let unwrapRecord = rValue => } ) -let expectParseToBe = (expr: string, answer: string) => - Reducer.parse(expr)->ExpressionT.toStringResult->expect->toBe(answer) +let expectParseToBe = (code: string, answer: string) => + Expression.BackCompatible.parse(code)->ExpressionT.toStringResult->expect->toBe(answer) -let expectEvalToBe = (expr: string, answer: string) => - Reducer.evaluate(expr) +let expectEvalToBe = (code: string, answer: string) => + Expression.BackCompatible.evaluateStringAsExternal(code) ->Reducer_Helpers.rRemoveDefaultsExternal ->ExternalExpressionValue.toStringResult ->expect ->toBe(answer) -let expectEvalError = (expr: string) => - Reducer.evaluate(expr)->ExternalExpressionValue.toStringResult->expect->toMatch("Error\(") - -let expectEvalBindingsToBe = (expr: string, bindings: Reducer.externalBindings, answer: string) => - Reducer.evaluateUsingOptions(expr, ~externalBindings=Some(bindings), ~environment=None) - ->Reducer_Helpers.rRemoveDefaultsExternal +let expectEvalError = (code: string) => + Expression.BackCompatible.evaluateStringAsExternal(code) ->ExternalExpressionValue.toStringResult ->expect - ->toBe(answer) + ->toMatch("Error\(") let testParseToBe = (expr, answer) => test(expr, () => expectParseToBe(expr, answer)) let testDescriptionParseToBe = (desc, expr, answer) => @@ -40,18 +37,12 @@ let testDescriptionParseToBe = (desc, expr, answer) => let testEvalError = expr => test(expr, () => expectEvalError(expr)) let testEvalToBe = (expr, answer) => test(expr, () => expectEvalToBe(expr, answer)) let testDescriptionEvalToBe = (desc, expr, answer) => test(desc, () => expectEvalToBe(expr, answer)) -let testEvalBindingsToBe = (expr, bindingsList, answer) => - test(expr, () => expectEvalBindingsToBe(expr, bindingsList->Js.Dict.fromList, answer)) module MySkip = { let testParseToBe = (expr, answer) => Skip.test(expr, () => expectParseToBe(expr, answer)) let testEvalToBe = (expr, answer) => Skip.test(expr, () => expectEvalToBe(expr, answer)) - let testEvalBindingsToBe = (expr, bindingsList, answer) => - Skip.test(expr, () => expectEvalBindingsToBe(expr, bindingsList->Js.Dict.fromList, answer)) } module MyOnly = { let testParseToBe = (expr, answer) => Only.test(expr, () => expectParseToBe(expr, answer)) let testEvalToBe = (expr, answer) => Only.test(expr, () => expectEvalToBe(expr, answer)) - let testEvalBindingsToBe = (expr, bindingsList, answer) => - Only.test(expr, () => expectEvalBindingsToBe(expr, bindingsList->Js.Dict.fromList, answer)) } diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res index ffd5d964..752cc9c7 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestMacroHelpers.res @@ -1,14 +1,14 @@ open Jest open Expect +module Bindings = Reducer_Bindings module BindingsReplacer = Reducer_Expression_BindingsReplacer module Expression = Reducer_Expression -// module ExpressionValue = ReducerInterface.ExpressionValue -module InternalExpressionValue = ReducerInterface.InternalExpressionValue module ExpressionWithContext = Reducer_ExpressionWithContext +module InternalExpressionValue = ReducerInterface.InternalExpressionValue module Macro = Reducer_Expression_Macro +module ProjectAccessorsT = ReducerProject_ProjectAccessors_T module T = Reducer_Expression_T -module Bindings = Reducer_Bindings let testMacro_ = ( tester, @@ -21,8 +21,8 @@ let testMacro_ = ( expr ->Macro.expandMacroCall( bindings, - InternalExpressionValue.defaultEnvironment, - Expression.reduceExpression, + ProjectAccessorsT.identityAccessors, + Expression.reduceExpressionInProject, ) ->ExpressionWithContext.toStringResult ->expect @@ -41,8 +41,8 @@ let testMacroEval_ = ( expr ->Macro.doMacroCall( bindings, - InternalExpressionValue.defaultEnvironment, - Expression.reduceExpression, + ProjectAccessorsT.identityAccessors, + Expression.reduceExpressionInProject, ) ->InternalExpressionValue.toStringResult ->expect 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 71f90373..55ed36bd 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 @@ -8,7 +8,7 @@ open Jest open Expect let myIevEval = (aTypeSourceCode: string) => - TypeCompile.ievFromTypeExpression(aTypeSourceCode, Expression.reduceExpression) + TypeCompile.ievFromTypeExpression(aTypeSourceCode, Expression.reduceExpressionInProject) let myIevEvalToString = (aTypeSourceCode: string) => myIevEval(aTypeSourceCode)->InternalExpressionValue.toStringResult @@ -19,7 +19,7 @@ let myIevTest = (test, aTypeSourceCode, answer) => test(aTypeSourceCode, () => myIevExpectEqual(aTypeSourceCode, answer)) let myTypeEval = (aTypeSourceCode: string) => - TypeCompile.fromTypeExpression(aTypeSourceCode, Expression.reduceExpression) + TypeCompile.fromTypeExpression(aTypeSourceCode, Expression.reduceExpressionInProject) let myTypeEvalToString = (aTypeSourceCode: string) => myTypeEval(aTypeSourceCode)->T.toStringResult let myTypeExpectEqual = (aTypeSourceCode, 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 07da15bb..29fa8249 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,9 @@ +module Bindings = Reducer_Bindings +module ErrorValue = Reducer_ErrorValue module Expression = Reducer_Expression module ExpressionT = Reducer_Expression_T -module ErrorValue = Reducer_ErrorValue module InternalExpressionValue = ReducerInterface_InternalExpressionValue -module Bindings = Reducer_Bindings +module ProjectAccessorsT = ReducerProject_ProjectAccessors_T module T = Reducer_Type_T module TypeChecker = Reducer_Type_TypeChecker @@ -13,10 +14,10 @@ let checkArgumentsSourceCode = (aTypeSourceCode: string, sourceCode: string): re 'v, ErrorValue.t, > => { - let reducerFn = Expression.reduceExpression + let reducerFn = Expression.reduceExpressionInProject let rResult = - Reducer.parse(sourceCode)->Belt.Result.flatMap(expr => - reducerFn(expr, Bindings.emptyBindings, InternalExpressionValue.defaultEnvironment) + Expression.BackCompatible.parse(sourceCode)->Belt.Result.flatMap(expr => + reducerFn(expr, Bindings.emptyBindings, ProjectAccessorsT.identityAccessors) ) rResult->Belt.Result.flatMap(result => switch result { diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Type/Reducer_Type_TypeChecker_test.res index efd9bb18..67de7941 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 @@ -5,6 +5,7 @@ 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 @@ -16,10 +17,10 @@ let isTypeOfSourceCode = (aTypeSourceCode: string, sourceCode: string): result< 'v, ErrorValue.t, > => { - let reducerFn = Expression.reduceExpression + let reducerFn = Expression.reduceExpressionInProject let rResult = - Reducer.parse(sourceCode)->Belt.Result.flatMap(expr => - reducerFn(expr, Bindings.emptyBindings, InternalExpressionValue.defaultEnvironment) + Expression.BackCompatible.parse(sourceCode)->Belt.Result.flatMap(expr => + reducerFn(expr, Bindings.emptyBindings, ProjectAccessorsT.identityAccessors) ) rResult->Belt.Result.flatMap(result => TypeChecker.isTypeOf(aTypeSourceCode, result, reducerFn)) } diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_externalBindings_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_externalBindings_test.res deleted file mode 100644 index bb1a4d35..00000000 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_externalBindings_test.res +++ /dev/null @@ -1,14 +0,0 @@ -open Jest -open Reducer_TestHelpers - -describe("Eval with Bindings", () => { - testEvalBindingsToBe("x", list{("x", ExternalExpressionValue.EvNumber(1.))}, "Ok(1)") - testEvalBindingsToBe("x+1", list{("x", ExternalExpressionValue.EvNumber(1.))}, "Ok(2)") - testParseToBe("y = x+1; y", "Ok({(:$_let_$ :y {(:add :x 1)}); :y})") - testEvalBindingsToBe("y = x+1; y", list{("x", ExternalExpressionValue.EvNumber(1.))}, "Ok(2)") - testEvalBindingsToBe( - "y = x+1", - list{("x", ExternalExpressionValue.EvNumber(1.))}, - "Ok(@{x: 1,y: 2})", - ) -}) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res index 30725cfe..a2abb85d 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionAssignment_test.res @@ -2,8 +2,14 @@ open Jest open Reducer_TestHelpers describe("Parse function assignment", () => { - testParseToBe("f(x)=x", "Ok({(:$_let_$ :f (:$$_lambda_$$ [x] {:x}))})") - testParseToBe("f(x)=2*x", "Ok({(:$_let_$ :f (:$$_lambda_$$ [x] {(:multiply 2 :x)}))})") + testParseToBe( + "f(x)=x", + "Ok({(:$_let_$ :f (:$$_lambda_$$ [x] {:x})); (:$_endOfOuterBlock_$ () ())})", + ) + testParseToBe( + "f(x)=2*x", + "Ok({(:$_let_$ :f (:$$_lambda_$$ [x] {(:multiply 2 :x)})); (:$_endOfOuterBlock_$ () ())})", + ) //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 68614f89..9b111354 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_functionTricks_test.res @@ -39,33 +39,27 @@ describe("symbol not defined", () => { }) describe("call and bindings", () => { - testEvalToBe("f(x)=x+1", "Ok(@{f: lambda(x=>internal code)})") + testEvalToBe("f(x)=x+1; f(0)", "Ok(1)") testEvalToBe("f(x)=x+1; f(1)", "Ok(2)") - testEvalToBe("f=1;y=2", "Ok(@{f: 1,y: 2})") - testEvalToBe("f(x)=x+1; y=f(1)", "Ok(@{f: lambda(x=>internal code),y: 2})") + testEvalToBe("f=1;y=2", "Ok(())") + testEvalToBe("f(x)=x+1; y=f(1); y", "Ok(2)") testEvalToBe("f(x)=x+1; y=f(1); f(1)", "Ok(2)") - testEvalToBe("f(x)=x+1; y=f(1); z=f(1)", "Ok(@{f: lambda(x=>internal code),y: 2,z: 2})") - testEvalToBe( - "f(x)=x+1; g(x)=f(x)+1", - "Ok(@{f: lambda(x=>internal code),g: lambda(x=>internal code)})", - ) + 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({(:$_let_$ :f {99}); (:$_let_$ :g (:$$_lambda_$$ [x] {:f})); (:g 2)})", + "Ok({(:$_let_$ :f {99}); (:$_let_$ :g (:$$_lambda_$$ [x] {:f})); (:$_endOfOuterBlock_$ () (: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)", - "Ok(@{f: lambda(x=>internal code),g: lambda(x=>internal code),y: 4})", - ) + testEvalToBe("f(x)=x+1; g(x)=f(x)+1; y=g(2); y", "Ok(4)") testEvalToBe("f(x)=x+1; g(x)=f(x)+1; g(2)", "Ok(4)") }) describe("function tricks", () => { testEvalError("f(x)=f(y)=2; f(2)") //Error because chain assignment is not allowed testEvalToBe("y=2;g(x)=y+1;g(2)", "Ok(3)") - testEvalToBe("y=2;g(x)=inspect(y)+1", "Ok(@{g: lambda(x=>internal code),y: 2})") + testEvalToBe("y=2;g(x)=inspect(y)+1;y", "Ok(2)") MySkip.testEvalToBe("f(x) = x(x); f(f)", "????") // TODO: Infinite loop. Any solution? Catching proper exception or timeout? MySkip.testEvalToBe("f(x, x)=x+x; f(1,2)", "????") // TODO: Duplicate parameters testEvalToBe("myadd(x,y)=x+y; z=myadd; z", "Ok(lambda(x,y=>internal code))") @@ -73,10 +67,7 @@ describe("function tricks", () => { }) describe("lambda in structures", () => { - testEvalToBe( - "myadd(x,y)=x+y; z=[myadd]", - "Ok(@{myadd: lambda(x,y=>internal code),z: [lambda(x,y=>internal code)]})", - ) + testEvalToBe("myadd(x,y)=x+y; z=[myadd]", "Ok(())") testEvalToBe("myadd(x,y)=x+y; z=[myadd]; z[0]", "Ok(lambda(x,y=>internal code))") testEvalToBe("myadd(x,y)=x+y; z=[myadd]; z[0](3,2)", "Ok(5)") testEvalToBe("myaddd(x,y)=x+y; z={x: myaddd}; z", "Ok({x: lambda(x,y=>internal code)})") diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res index 22fa8328..c86f4bca 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_ternaryOperator_test.res @@ -2,7 +2,10 @@ open Jest open Reducer_TestHelpers describe("Parse ternary operator", () => { - testParseToBe("true ? 'YES' : 'NO'", "Ok({(:$$_ternary_$$ true 'YES' 'NO')})") + testParseToBe( + "true ? 'YES' : 'NO'", + "Ok({(:$_endOfOuterBlock_$ () (:$$_ternary_$$ true 'YES' 'NO'))})", + ) }) describe("Evaluate ternary operator", () => { diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res index dc403e7d..f70aa934 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_test.res @@ -48,7 +48,7 @@ describe("eval", () => { testEvalToBe("x=1; y=x+1; y+1", "Ok(3)") testEvalError("1; x=1") testEvalError("1; 1") - testEvalToBe("x=1; x=1", "Ok(@{x: 1})") + testEvalToBe("x=1; x=1; x", "Ok(1)") }) }) diff --git a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res index 3083b71b..4adb363f 100644 --- a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res +++ b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_Distribution_test.res @@ -118,28 +118,40 @@ 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("3 ^ normal(5,1)", "Ok({(:pow 3 (:normal 5 1))})") - testParse("normal(5,2) ^ 3", "Ok({(:pow (:normal 5 2) 3)})") + testParse( + "normal(5,2) ^ normal(5,1)", + "Ok({(:$_endOfOuterBlock_$ () (: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))})") }) describe("subtraction", () => { - testParse("10 - normal(5,1)", "Ok({(:subtract 10 (:normal 5 1))})") - testParse("normal(5,1) - 10", "Ok({(:subtract (:normal 5 1) 10)})") + testParse("10 - normal(5,1)", "Ok({(:$_endOfOuterBlock_$ () (:subtract 10 (:normal 5 1)))})") + testParse("normal(5,1) - 10", "Ok({(:$_endOfOuterBlock_$ () (: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((:$$_block_$$ (:dotSubtract (:normal 5 2) (:normal 5 1))))", + "Ok((:$_endOfOuterBlock_$ () (:$$_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({(:$_endOfOuterBlock_$ () (:dotMultiply (:normal 5 2) (:normal 5 1)))})", + ) + testParse( + "normal(5,2) ./ normal(5,1)", + "Ok({(:$_endOfOuterBlock_$ () (:dotDivide (:normal 5 2) (:normal 5 1)))})", + ) + testParse( + "normal(5,2) .^ normal(5,1)", + "Ok({(:$_endOfOuterBlock_$ () (:dotPow (:normal 5 2) (:normal 5 1)))})", + ) }) describe("equality", () => { - testParse("5 == normal(5,2)", "Ok({(:equal 5 (:normal 5 2))})") + testParse("5 == normal(5,2)", "Ok({(:$_endOfOuterBlock_$ () (: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_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res new file mode 100644 index 00000000..cea3d777 --- /dev/null +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res @@ -0,0 +1,179 @@ +@@warning("-44") +module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue +module Project = ReducerProject +module Bindings = Reducer_Bindings +module Continuation = ReducerInterface_Value_Continuation + +open Jest +open Expect +open Expect.Operators + +// test("", () => expect(1)->toBe(1)) + +let runFetchResult = (project, sourceId) => { + Project.run(project, sourceId) + Project.getExternalResult(project, sourceId)->ExternalExpressionValue.toStringOptionResult +} + +let runFetchBindings = (project, sourceId) => { + Project.run(project, sourceId) + Project.getExternalBindings(project, sourceId) + ->ExternalExpressionValue.EvModule + ->ExternalExpressionValue.toString +} + +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") + expect(answer)->toBe(sampleBindings) +}) + +test("test result true", () => { + let project = Project.createProject() + Project.setSource(project, "main", "true") + runFetchResult(project, "main")->expect->toBe("Ok(true)") +}) + +test("test result false", () => { + let project = Project.createProject() + Project.setSource(project, "main", "false") + runFetchResult(project, "main")->expect->toBe("Ok(false)") +}) + +test("test library", () => { + let project = Project.createProject() + Project.setSource(project, "main", "x=Math.pi; x") + runFetchResult(project, "main")->expect->toBe("Ok(3.141592653589793)") +}) + +test("test bindings", () => { + let project = Project.createProject() + Project.setSource(project, "variables", "myVariable=666") + runFetchBindings(project, "variables")->expect->toBe("@{myVariable: 666}") +}) + +describe("project1", () => { + let project = Project.createProject() + Project.setSource(project, "first", "x=1") + Project.setSource(project, "main", "x") + Project.setContinues(project, "main", ["first"]) + + test("runOrder", () => { + expect(Project.getRunOrder(project)) == ["first", "main"] + }) + test("dependents first", () => { + expect(Project.getDependents(project, "first")) == ["main"] + }) + test("dependencies first", () => { + expect(Project.getDependencies(project, "first")) == [] + }) + test("dependents main", () => { + expect(Project.getDependents(project, "main")) == [] + }) + test("dependencies main", () => { + expect(Project.getDependencies(project, "main")) == ["first"] + }) + test("test result", () => { + runFetchResult(project, "main")->expect->toBe("Ok(1)") + }) + test("test bindings", () => { + runFetchBindings(project, "main")->expect->toBe("@{x: 1}") + }) +}) + +describe("project2", () => { + let project = Project.createProject() + Project.setContinues(project, "main", ["second"]) + Project.setContinues(project, "second", ["first"]) + Project.setSource(project, "first", "x=1") + Project.setSource(project, "second", "y=2") + Project.setSource(project, "main", "y") + + test("runOrder", () => { + expect(Project.getRunOrder(project)) == ["first", "second", "main"] + }) + test("runOrderFor", () => { + expect(Project.getRunOrderFor(project, "first")) == ["first"] + }) + test("dependencies first", () => { + expect(Project.getDependencies(project, "first")) == [] + }) + test("dependents first", () => { + expect(Project.getDependents(project, "first")) == ["second", "main"] + }) + test("dependents main", () => { + expect(Project.getDependents(project, "main")) == [] + }) + test("dependencies main", () => { + expect(Project.getDependencies(project, "main")) == ["first", "second"] + }) + test("test result", () => { + runFetchResult(project, "main")->expect->toBe("Ok(2)") + }) + test("test bindings", () => { + runFetchBindings(project, "main")->expect->toBe("@{x: 1,y: 2}") + }) +}) + +describe("project with include", () => { + let project = Project.createProject() + Project.setContinues(project, "main", ["second"]) + Project.setContinues(project, "second", ["first"]) + + Project.setSource( + project, + "first", + ` + #include 'common' + x=1`, + ) + Project.parseIncludes(project, "first") + Project.parseIncludes(project, "first") //The only way of setting includes + //Don't forget to parse includes after changing the source + + Project.setSource(project, "common", "common=0") + Project.setSource( + project, + "second", + ` + #include 'common' + y=2`, + ) + Project.parseIncludes(project, "second") //The only way of setting includes + + Project.setSource(project, "main", "y") + + test("runOrder", () => { + expect(Project.getRunOrder(project)) == ["common", "first", "second", "main"] + }) + + test("runOrderFor", () => { + expect(Project.getRunOrderFor(project, "first")) == ["common", "first"] + }) + + test("dependencies first", () => { + expect(Project.getDependencies(project, "first")) == ["common"] + }) + test("dependents first", () => { + expect(Project.getDependents(project, "first")) == ["second", "main"] + }) + test("dependents main", () => { + expect(Project.getDependents(project, "main")) == [] + }) + test("dependencies main", () => { + expect(Project.getDependencies(project, "main")) == ["common", "first", "second"] + }) + test("test result", () => { + runFetchResult(project, "main")->expect->toBe("Ok(2)") + }) + test("test bindings", () => { + runFetchBindings(project, "main")->expect->toBe("@{common: 0,x: 1,y: 2}") + }) +}) + +// test bindings +//TODO: test continues +//TODO: test include diff --git a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res index 2418b4d8..dd23d994 100644 --- a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res +++ b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res @@ -2,8 +2,12 @@ open Jest open Expect open Reducer_TestHelpers -let expectEvalToBeOk = (expr: string) => - Reducer.evaluate(expr)->Reducer_Helpers.rRemoveDefaultsExternal->E.R.isOk->expect->toBe(true) +let expectEvalToBeOk = (code: string) => + Reducer_Expression.BackCompatible.evaluateStringAsExternal(code) + ->Reducer_Helpers.rRemoveDefaultsExternal + ->E.R.isOk + ->expect + ->toBe(true) let registry = FunctionRegistry_Library.registry let examples = E.A.to_list(FunctionRegistry_Core.Registry.allExamples(registry)) @@ -88,7 +92,7 @@ describe("FunctionRegistry Library", () => { ((fn, example)) => { let responseType = example - ->Reducer.evaluate + ->Reducer_Expression.BackCompatible.evaluateStringAsExternal ->E.R2.fmap(ReducerInterface_InternalExpressionValue.externalValueToValueType) let expectedOutputType = fn.output |> E.O.toExn("") expect(responseType)->toEqual(Ok(expectedOutputType)) diff --git a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res index 4b27c221..edce5ac2 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/FunctionRegistry_Core.res @@ -1,3 +1,5 @@ +module ProjectAccessorsT = ReducerProject_ProjectAccessors_T +module ProjectReducerFnT = ReducerProject_ReducerFn_T type internalExpressionValue = ReducerInterface_InternalExpressionValue.t type internalExpressionValueType = ReducerInterface_InternalExpressionValue.internalExpressionValueType @@ -46,8 +48,8 @@ type fnDefinition = { run: ( array, array, - GenericDist.env, - Reducer_Expression_T.reducerFn, + ProjectAccessorsT.t, + ProjectReducerFnT.t, ) => result, } @@ -382,12 +384,12 @@ module FnDefinition = { let run = ( t: t, args: array, - env: GenericDist.env, - reducer: Reducer_Expression_T.reducerFn, + accessors: ProjectAccessorsT.t, + reducer: ProjectReducerFnT.t, ) => { let argValues = FRType.matchWithExpressionValueArray(t.inputs, args) switch argValues { - | Some(values) => t.run(args, values, env, reducer) + | Some(values) => t.run(args, values, accessors, reducer) | None => Error("Incorrect Types") } } @@ -493,8 +495,8 @@ module Registry = { ~registry: registry, ~fnName: string, ~args: array, - ~env: GenericDist.env, - ~reducer: Reducer_Expression_T.reducerFn, + ~accessors: ProjectAccessorsT.t, + ~reducer: ProjectReducerFnT.t, ) => { let relevantFunctions = Js.Dict.get(registry.fnNameDict, fnName) |> E.O.default([]) let modified = {functions: relevantFunctions, fnNameDict: registry.fnNameDict} @@ -512,7 +514,7 @@ module Registry = { switch Matcher.Registry.findMatches(modified, fnName, args) { | Matcher.Match.FullMatch(match) => - match->matchToDef->E.O2.fmap(FnDefinition.run(_, args, env, reducer)) + match->matchToDef->E.O2.fmap(FnDefinition.run(_, args, accessors, reducer)) | SameNameDifferentArguments(m) => Some(Error(showNameMatchDefinitions(m))) | _ => None } @@ -521,10 +523,10 @@ module Registry = { let dispatch = ( registry, (fnName, args): ReducerInterface_InternalExpressionValue.functionCall, - env, - reducer: Reducer_Expression_T.reducerFn, + accessors: ProjectAccessorsT.t, + reducer: ProjectReducerFnT.t, ) => { - _matchAndRun(~registry, ~fnName, ~args, ~env, ~reducer)->E.O2.fmap( + _matchAndRun(~registry, ~fnName, ~args, ~accessors, ~reducer)->E.O2.fmap( E.R2.errMap(_, s => Reducer_ErrorValue.RETodo(s)), ) } 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 9e10577b..23619187 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, env, _) => - inputs->Prepare.ToValueTuple.twoDistOrNumber->process(~fn, ~env), + ~run=(_, inputs, accessors, _) => + inputs->Prepare.ToValueTuple.twoDistOrNumber->process(~fn, ~env=accessors.environment), (), ) } @@ -31,8 +31,10 @@ module DistributionCreation = { FnDefinition.make( ~name, ~inputs=[FRTypeRecord([("p5", FRTypeDistOrNumber), ("p95", FRTypeDistOrNumber)])], - ~run=(_, inputs, env, _) => - inputs->Prepare.ToValueTuple.Record.twoDistOrNumber->process(~fn, ~env), + ~run=(_, inputs, accessors, _) => + inputs + ->Prepare.ToValueTuple.Record.twoDistOrNumber + ->process(~fn, ~env=accessors.environment), (), ) } @@ -41,8 +43,10 @@ module DistributionCreation = { FnDefinition.make( ~name, ~inputs=[FRTypeRecord([("mean", FRTypeDistOrNumber), ("stdev", FRTypeDistOrNumber)])], - ~run=(_, inputs, env, _) => - inputs->Prepare.ToValueTuple.Record.twoDistOrNumber->process(~fn, ~env), + ~run=(_, inputs, accessors, _) => + inputs + ->Prepare.ToValueTuple.Record.twoDistOrNumber + ->process(~fn, ~env=accessors.environment), (), ) } @@ -58,8 +62,8 @@ module DistributionCreation = { FnDefinition.make( ~name, ~inputs=[FRTypeDistOrNumber], - ~run=(_, inputs, env, _) => - inputs->Prepare.ToValueTuple.oneDistOrNumber->process(~fn, ~env), + ~run=(_, inputs, accessors, _) => + inputs->Prepare.ToValueTuple.oneDistOrNumber->process(~fn, ~env=accessors.environment), (), ) } 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 762fe31b..e0b83d18 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_List.res @@ -1,3 +1,6 @@ +// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T +// module ProjectReducerFnT = ReducerProject_ReducerFn_T + open FunctionRegistry_Core open FunctionRegistry_Helpers @@ -24,17 +27,19 @@ module Internals = { Belt.Array.reverse(array), ) - let map = (array: array, environment, eLambdaValue, reducer): result< - ReducerInterface_InternalExpressionValue.t, - Reducer_ErrorValue.errorValue, - > => { + let map = ( + array: array, + accessors: ProjectAccessorsT.t, + eLambdaValue, + reducer: ProjectReducerFnT.t, + ): result => { let rMappedList = array->E.A.reduceReverse(Ok(list{}), (rAcc, elem) => rAcc->E.R.bind(_, acc => { let rNewElem = Reducer_Expression_Lambda.doLambdaCall( eLambdaValue, list{elem}, - environment, - reducer, + (accessors: ProjectAccessorsT.t), + (reducer: ProjectReducerFnT.t), ) rNewElem->E.R2.fmap(newElem => list{newElem, ...acc}) }) @@ -42,29 +47,46 @@ module Internals = { rMappedList->E.R2.fmap(mappedList => mappedList->Belt.List.toArray->Wrappers.evArray) } - let reduce = (aValueArray, initialValue, aLambdaValue, environment, reducer) => { + let reduce = ( + aValueArray, + initialValue, + aLambdaValue, + accessors: ProjectAccessorsT.t, + reducer: ProjectReducerFnT.t, + ) => { aValueArray->E.A.reduce(Ok(initialValue), (rAcc, elem) => rAcc->E.R.bind(_, acc => - Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, environment, reducer) + Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, accessors, reducer) ) ) } - let reduceReverse = (aValueArray, initialValue, aLambdaValue, environment, reducer) => { + let reduceReverse = ( + aValueArray, + initialValue, + aLambdaValue, + accessors: ProjectAccessorsT.t, + reducer: ProjectReducerFnT.t, + ) => { aValueArray->Belt.Array.reduceReverse(Ok(initialValue), (rAcc, elem) => rAcc->Belt.Result.flatMap(acc => - Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, environment, reducer) + Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list{acc, elem}, accessors, reducer) ) ) } - let filter = (aValueArray, aLambdaValue, environment, reducer) => { + let filter = ( + aValueArray, + aLambdaValue, + accessors: ProjectAccessorsT.t, + reducer: ProjectReducerFnT.t, + ) => { let rMappedList = aValueArray->Belt.Array.reduceReverse(Ok(list{}), (rAcc, elem) => rAcc->E.R.bind(_, acc => { let rNewElem = Reducer_Expression_Lambda.doLambdaCall( aLambdaValue, list{elem}, - environment, + accessors, reducer, ) rNewElem->E.R2.fmap(newElem => { @@ -189,10 +211,10 @@ let library = [ FnDefinition.make( ~name="map", ~inputs=[FRTypeArray(FRTypeAny), FRTypeLambda], - ~run=(inputs, _, env, reducer) => + ~run=(inputs, _, accessors: ProjectAccessorsT.t, reducer) => switch inputs { | [IEvArray(array), IEvLambda(lambda)] => - Internals.map(array, env, lambda, reducer)->E.R2.errMap(_ => "Error!") + Internals.map(array, accessors, lambda, reducer)->E.R2.errMap(_ => "Error!") | _ => Error(impossibleError) }, (), @@ -209,10 +231,12 @@ let library = [ FnDefinition.make( ~name="reduce", ~inputs=[FRTypeArray(FRTypeAny), FRTypeAny, FRTypeLambda], - ~run=(inputs, _, env, reducer) => + ~run=(inputs, _, accessors: ProjectAccessorsT.t, reducer) => switch inputs { | [IEvArray(array), initialValue, IEvLambda(lambda)] => - Internals.reduce(array, initialValue, lambda, env, reducer)->E.R2.errMap(_ => "Error!") + Internals.reduce(array, initialValue, lambda, accessors, reducer)->E.R2.errMap(_ => + "Error!" + ) | _ => Error(impossibleError) }, (), @@ -229,12 +253,16 @@ let library = [ FnDefinition.make( ~name="reduceReverse", ~inputs=[FRTypeArray(FRTypeAny), FRTypeAny, FRTypeLambda], - ~run=(inputs, _, env, reducer) => + ~run=(inputs, _, accessors: ProjectAccessorsT.t, reducer: ProjectReducerFnT.t) => switch inputs { | [IEvArray(array), initialValue, IEvLambda(lambda)] => - Internals.reduceReverse(array, initialValue, lambda, env, reducer)->E.R2.errMap(_ => - "Error!" - ) + Internals.reduceReverse( + array, + initialValue, + lambda, + accessors, + reducer, + )->E.R2.errMap(_ => "Error!") | _ => Error(impossibleError) }, (), @@ -251,10 +279,10 @@ let library = [ FnDefinition.make( ~name="filter", ~inputs=[FRTypeArray(FRTypeAny), FRTypeLambda], - ~run=(inputs, _, env, reducer) => + ~run=(inputs, _, accessors: ProjectAccessorsT.t, reducer: ProjectReducerFnT.t) => switch inputs { | [IEvArray(array), IEvLambda(lambda)] => - Internals.filter(array, lambda, env, reducer)->E.R2.errMap(_ => "Error!") + Internals.filter(array, lambda, accessors, reducer)->E.R2.errMap(_ => "Error!") | _ => 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 4f4e1731..441a7450 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Pointset.res @@ -34,13 +34,13 @@ let library = [ FnDefinition.make( ~name="fromDist", ~inputs=[FRTypeDist], - ~run=(_, inputs, env, _) => + ~run=(_, inputs, accessors, _) => switch inputs { | [FRValueDist(dist)] => GenericDist.toPointSet( dist, - ~xyPointLength=env.xyPointLength, - ~sampleCount=env.sampleCount, + ~xyPointLength=accessors.environment.xyPointLength, + ~sampleCount=accessors.environment.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 27b870ee..b42aaa89 100644 --- a/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res +++ b/packages/squiggle-lang/src/rescript/FunctionRegistry/Library/FR_Sampleset.res @@ -1,3 +1,5 @@ +// module ProjectAccessorsT = ReducerProject_ProjectAccessors_T +// module ProjectReducerFnT = ReducerProject_ReducerFn_T open FunctionRegistry_Core open FunctionRegistry_Helpers @@ -6,8 +8,14 @@ let requiresNamespace = true module Internal = { type t = SampleSetDist.t - let doLambdaCall = (aLambdaValue, list, environment, reducer) => - switch Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list, environment, reducer) { + + let doLambdaCall = ( + aLambdaValue, + list, + accessors: ProjectAccessorsT.t, + reducer: ProjectReducerFnT.t, + ) => + switch Reducer_Expression_Lambda.doLambdaCall(aLambdaValue, list, accessors, reducer) { | Ok(IEvNumber(f)) => Ok(f) | _ => Error(Operation.SampleMapNeedsNtoNFunction) } @@ -22,29 +30,26 @@ module Internal = { } //TODO: I don't know why this seems to need at least one input - let fromFn = ( - aLambdaValue, - env: ReducerInterface_InternalExpressionValue.environment, - reducer, - ) => { - let sampleCount = env.sampleCount - let fn = r => doLambdaCall(aLambdaValue, list{IEvNumber(r)}, env, reducer) + let fromFn = (aLambdaValue, accessors: ProjectAccessorsT.t, reducer: ProjectReducerFnT.t) => { + let sampleCount = accessors.environment.sampleCount + let fn = r => doLambdaCall(aLambdaValue, list{IEvNumber(r)}, accessors, reducer) Belt_Array.makeBy(sampleCount, r => fn(r->Js.Int.toFloat))->E.A.R.firstErrorOrOpen } - let map1 = (sampleSetDist: t, aLambdaValue, env, reducer) => { - let fn = r => doLambdaCall(aLambdaValue, list{IEvNumber(r)}, env, reducer) + let map1 = (sampleSetDist: t, aLambdaValue, accessors: ProjectAccessorsT.t, reducer) => { + let fn = r => doLambdaCall(aLambdaValue, list{IEvNumber(r)}, accessors, reducer) SampleSetDist.samplesMap(~fn, sampleSetDist)->toType } - let map2 = (t1: t, t2: t, aLambdaValue, env, reducer) => { - let fn = (a, b) => doLambdaCall(aLambdaValue, list{IEvNumber(a), IEvNumber(b)}, env, reducer) + let map2 = (t1: t, t2: t, aLambdaValue, accessors: ProjectAccessorsT.t, reducer) => { + let fn = (a, b) => + doLambdaCall(aLambdaValue, list{IEvNumber(a), IEvNumber(b)}, accessors, reducer) SampleSetDist.map2(~fn, ~t1, ~t2)->toType } - let map3 = (t1: t, t2: t, t3: t, aLambdaValue, env, reducer) => { + let map3 = (t1: t, t2: t, t3: t, aLambdaValue, accessors: ProjectAccessorsT.t, reducer) => { let fn = (a, b, c) => - doLambdaCall(aLambdaValue, list{IEvNumber(a), IEvNumber(b), IEvNumber(c)}, env, reducer) + doLambdaCall(aLambdaValue, list{IEvNumber(a), IEvNumber(b), IEvNumber(c)}, accessors, reducer) SampleSetDist.map3(~fn, ~t1, ~t2, ~t3)->toType } @@ -59,14 +64,19 @@ module Internal = { E.A.O.openIfAllSome(E.A.fmap(parseSampleSet, arr)) } - let mapN = (aValueArray: array, aLambdaValue, env, reducer) => { + let mapN = ( + aValueArray: array, + aLambdaValue, + accessors: ProjectAccessorsT.t, + reducer, + ) => { switch parseSampleSetArray(aValueArray) { | Some(t1) => let fn = a => doLambdaCall( aLambdaValue, list{IEvArray(E.A.fmap(x => Wrappers.evNumber(x), a))}, - env, + accessors, reducer, ) SampleSetDist.mapN(~fn, ~t1)->toType @@ -86,10 +96,10 @@ let library = [ FnDefinition.make( ~name="fromDist", ~inputs=[FRTypeDist], - ~run=(_, inputs, env, _) => + ~run=(_, inputs, accessors: ProjectAccessorsT.t, _) => switch inputs { | [FRValueDist(dist)] => - GenericDist.toSampleSetDist(dist, env.sampleCount) + GenericDist.toSampleSetDist(dist, accessors.environment.sampleCount) ->E.R2.fmap(Wrappers.sampleSet) ->E.R2.fmap(Wrappers.evDistribution) ->E.R2.errMap(_ => "") @@ -153,10 +163,10 @@ let library = [ FnDefinition.make( ~name="fromFn", ~inputs=[FRTypeLambda], - ~run=(inputs, _, env, reducer) => + ~run=(inputs, _, accessors: ProjectAccessorsT.t, reducer: ProjectReducerFnT.t) => switch inputs { | [IEvLambda(lambda)] => - switch Internal.fromFn(lambda, env, reducer) { + switch Internal.fromFn(lambda, accessors, reducer) { | Ok(r) => Ok(r->Wrappers.sampleSet->Wrappers.evDistribution) | Error(_) => Error("issue") } @@ -177,10 +187,10 @@ let library = [ FnDefinition.make( ~name="map", ~inputs=[FRTypeDist, FRTypeLambda], - ~run=(inputs, _, env, reducer) => + ~run=(inputs, _, accessors: ProjectAccessorsT.t, reducer) => switch inputs { | [IEvDistribution(SampleSet(dist)), IEvLambda(lambda)] => - Internal.map1(dist, lambda, env, reducer)->E.R2.errMap(_ => "") + Internal.map1(dist, lambda, accessors, reducer)->E.R2.errMap(_ => "") | _ => Error(impossibleError) }, (), @@ -200,14 +210,14 @@ let library = [ FnDefinition.make( ~name="map2", ~inputs=[FRTypeDist, FRTypeDist, FRTypeLambda], - ~run=(inputs, _, env, reducer) => { + ~run=(inputs, _, accessors: ProjectAccessorsT.t, reducer) => { switch inputs { | [ IEvDistribution(SampleSet(dist1)), IEvDistribution(SampleSet(dist2)), IEvLambda(lambda), ] => - Internal.map2(dist1, dist2, lambda, env, reducer)->E.R2.errMap(_ => "") + Internal.map2(dist1, dist2, lambda, accessors, reducer)->E.R2.errMap(_ => "") | _ => Error(impossibleError) } }, @@ -228,7 +238,7 @@ let library = [ FnDefinition.make( ~name="map3", ~inputs=[FRTypeDist, FRTypeDist, FRTypeDist, FRTypeLambda], - ~run=(inputs, _, env, reducer) => + ~run=(inputs, _, accessors: ProjectAccessorsT.t, reducer) => switch inputs { | [ IEvDistribution(SampleSet(dist1)), @@ -236,7 +246,7 @@ let library = [ IEvDistribution(SampleSet(dist3)), IEvLambda(lambda), ] => - Internal.map3(dist1, dist2, dist3, lambda, env, reducer)->E.R2.errMap(_ => "") + Internal.map3(dist1, dist2, dist3, lambda, accessors, reducer)->E.R2.errMap(_ => "") | _ => Error(impossibleError) }, (), @@ -256,10 +266,10 @@ let library = [ FnDefinition.make( ~name="mapN", ~inputs=[FRTypeArray(FRTypeDist), FRTypeLambda], - ~run=(inputs, _, env, reducer) => + ~run=(inputs, _, accessors: ProjectAccessorsT.t, reducer) => switch inputs { | [IEvArray(dists), IEvLambda(lambda)] => - Internal.mapN(dists, lambda, env, reducer)->E.R2.errMap(_e => { + Internal.mapN(dists, lambda, accessors, 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 972501e9..d45b1a81 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, env, _) => { + ~run=(_, inputs, accessors, _) => { switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.threeArgs(inputs) { | Ok([FRValueDist(estimate), FRValueDistOrNumber(FRValueDist(d)), FRValueDist(prior)]) => - runScoring(estimate, Score_Dist(d), Some(prior), env) + runScoring(estimate, Score_Dist(d), Some(prior), accessors.environment) | Ok([ FRValueDist(estimate), FRValueDistOrNumber(FRValueNumber(d)), FRValueDist(prior), ]) => - runScoring(estimate, Score_Scalar(d), Some(prior), env) + runScoring(estimate, Score_Scalar(d), Some(prior), accessors.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, env, _) => { + ~run=(_, inputs, accessors, _) => { switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.twoArgs(inputs) { | Ok([FRValueDist(estimate), FRValueDistOrNumber(FRValueDist(d))]) => - runScoring(estimate, Score_Dist(d), None, env) + runScoring(estimate, Score_Dist(d), None, accessors.environment) | Ok([FRValueDist(estimate), FRValueDistOrNumber(FRValueNumber(d))]) => - runScoring(estimate, Score_Scalar(d), None, env) + runScoring(estimate, Score_Scalar(d), None, accessors.environment) | Error(e) => Error(e) | _ => Error(FunctionRegistry_Helpers.impossibleError) } @@ -74,10 +74,10 @@ let library = [ FnDefinition.make( ~name="klDivergence", ~inputs=[FRTypeDist, FRTypeDist], - ~run=(_, inputs, env, _) => { + ~run=(_, inputs, accessors, _) => { switch inputs { | [FRValueDist(estimate), FRValueDist(d)] => - runScoring(estimate, Score_Dist(d), None, env) + runScoring(estimate, Score_Dist(d), None, accessors.environment) | _ => Error(FunctionRegistry_Helpers.impossibleError) } }, diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer.res index bf8c89f9..ca0f63f3 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer.res @@ -1,8 +1,6 @@ module ErrorValue = Reducer_ErrorValue module Expression = Reducer_Expression module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue -module InternalExpressionValue = ReducerInterface_InternalExpressionValue -module Lambda = Reducer_Expression_Lambda type environment = ReducerInterface_InternalExpressionValue.environment type errorValue = Reducer_ErrorValue.errorValue @@ -10,26 +8,10 @@ type expressionValue = ExternalExpressionValue.t type externalBindings = ReducerInterface_ExternalExpressionValue.externalBindings type lambdaValue = ExternalExpressionValue.lambdaValue -let evaluate = Expression.evaluate -let evaluateUsingOptions = Expression.evaluateUsingOptions -let evaluatePartialUsingExternalBindings = Expression.evaluatePartialUsingExternalBindings -let parse = Expression.parse - -let foreignFunctionInterface = ( - lambdaValue: ExternalExpressionValue.lambdaValue, - argArray: array, - environment: ExternalExpressionValue.environment, -) => { - let internallambdaValue = InternalExpressionValue.lambdaValueToInternal(lambdaValue) - let internalArgArray = argArray->Js.Array2.map(InternalExpressionValue.toInternal) - Lambda.foreignFunctionInterface( - internallambdaValue, - internalArgArray, - environment, - Expression.reduceExpression, - )->Belt.Result.map(InternalExpressionValue.toExternal) -} +/* + Use Reducer_Project instead +*/ let defaultEnvironment = ExternalExpressionValue.defaultEnvironment -let defaultExternalBindings = ReducerInterface_StdLib.externalStdLib +// let defaultExternalBindings = ReducerInterface_StdLib.externalStdLib diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi b/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi index bd0c43fb..8ac63abf 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi @@ -1,7 +1,7 @@ module ErrorValue = Reducer_ErrorValue module Expression = Reducer_Expression -@genType +@genType0 type environment = ReducerInterface_ExternalExpressionValue.environment @genType type errorValue = Reducer_ErrorValue.errorValue @@ -12,34 +12,34 @@ type externalBindings = ReducerInterface_ExternalExpressionValue.externalBinding @genType type lambdaValue = ReducerInterface_ExternalExpressionValue.lambdaValue -@genType -let evaluateUsingOptions: ( - ~environment: option, - ~externalBindings: option< - QuriSquiggleLang.ReducerInterface_ExternalExpressionValue.externalBindings, - >, - string, -) => result -@genType -let evaluatePartialUsingExternalBindings: ( - string, - QuriSquiggleLang.ReducerInterface_ExternalExpressionValue.externalBindings, - QuriSquiggleLang.ReducerInterface_ExternalExpressionValue.environment, -) => result -@genType -let evaluate: string => result +// @genType +// let evaluateUsingOptions: ( +// ~environment: option, +// ~externalBindings: option< +// QuriSquiggleLang.ReducerInterface_ExternalExpressionValue.externalBindings, +// >, +// string, +// ) => result +// @genType +// let evaluatePartialUsingExternalBindings: ( +// string, +// QuriSquiggleLang.ReducerInterface_ExternalExpressionValue.externalBindings, +// QuriSquiggleLang.ReducerInterface_ExternalExpressionValue.environment, +// ) => result +// @genType +// let evaluate: string => result -let parse: string => result +// let parse: string => result -@genType -let foreignFunctionInterface: ( - QuriSquiggleLang.ReducerInterface_ExternalExpressionValue.lambdaValue, - array, - QuriSquiggleLang.ReducerInterface_ExternalExpressionValue.environment, -) => result +// @genType +// let foreignFunctionInterface: ( +// QuriSquiggleLang.ReducerInterface_ExternalExpressionValue.lambdaValue, +// array, +// QuriSquiggleLang.ReducerInterface_ExternalExpressionValue.environment, +// ) => result @genType let defaultEnvironment: environment -@genType -let defaultExternalBindings: externalBindings +// @genType +// let defaultExternalBindings: externalBindings 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 28175d7a..3daeb98d 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 @@ -74,6 +74,7 @@ let set = (nameSpace: t, id: string, value): t => { let emptyModule: t = NameSpace(emptyMap) let emptyBindings = emptyModule +let emptyNameSpace = emptyModule let fromTypeScriptBindings = ReducerInterface_InternalExpressionValue.nameSpaceFromTypeScriptBindings let toTypeScriptBindings = ReducerInterface_InternalExpressionValue.nameSpaceToTypeScriptBindings 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 a2ca204a..b1ae2e41 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,11 +1,15 @@ +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 Bindings = Reducer_Bindings +module ProjectAccessorsT = ReducerProject_ProjectAccessors_T +module ProjectReducerFnT = ReducerProject_ReducerFn_T module Result = Belt.Result module TypeBuilder = Reducer_Type_TypeBuilder + open ReducerInterface_InternalExpressionValue open Reducer_ErrorValue @@ -19,10 +23,11 @@ open Reducer_ErrorValue exception TestRescriptException -let callInternal = (call: functionCall, environment, reducer: ExpressionT.reducerFn): result< - 'b, - errorValue, -> => { +let callInternal = ( + call: functionCall, + accessors: ProjectAccessorsT.t, + reducer: ProjectReducerFnT.t, +): result<'b, errorValue> => { let callMathJs = (call: functionCall): result<'b, errorValue> => switch call { | ("javascriptraise", [msg]) => Js.Exn.raiseError(toString(msg)) // For Tests @@ -95,9 +100,17 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce let doExportBindings = (bindings: nameSpace) => bindings->Bindings.toExpressionValue->Ok + let doIdentity = (value: internalExpressionValue) => value->Ok + + let doDumpBindings = (continuation: nameSpace, value: internalExpressionValue) => { + // let _ = Continuation.inspect(continuation, "doDumpBindings") + accessors.continuation = continuation + value->Ok + } + module SampleMap = { let doLambdaCall = (aLambdaValue, list) => - switch Lambda.doLambdaCall(aLambdaValue, list, environment, reducer) { + switch Lambda.doLambdaCall(aLambdaValue, list, accessors, reducer) { | Ok(IEvNumber(f)) => Ok(f) | _ => Error(Operation.SampleMapNeedsNtoNFunction) } @@ -137,12 +150,14 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce | ("$_constructArray_$", [IEvArray(aValueArray)]) => IEvArray(aValueArray)->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)]) => @@ -182,15 +197,16 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce /* Reducer uses Result monad while reducing expressions */ -let dispatch = (call: functionCall, environment, reducer: ExpressionT.reducerFn): result< - internalExpressionValue, - errorValue, -> => +let dispatch = ( + call: functionCall, + accessors: ProjectAccessorsT.t, + reducer: ProjectReducerFnT.t, +): result => try { let (fn, args) = call // There is a bug that prevents string match in patterns // So we have to recreate a copy of the string - ExternalLibrary.dispatch((Js.String.make(fn), args), environment, reducer, callInternal) + ExternalLibrary.dispatch((Js.String.make(fn), args), accessors, reducer, callInternal) } catch { | Js.Exn.Error(obj) => REJavaScriptExn(Js.Exn.message(obj), Js.Exn.name(obj))->Error | _ => RETodo("unhandled rescript exception")->Error 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 c4c76ce3..978ca399 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 @@ -3,17 +3,19 @@ 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 InternalExpressionValue = ReducerInterface_InternalExpressionValue module ExpressionWithContext = Reducer_ExpressionWithContext -module Bindings = Reducer_Bindings +module InternalExpressionValue = ReducerInterface_InternalExpressionValue +module ProjectAccessorsT = ReducerProject_ProjectAccessors_T +module ProjectReducerFnT = ReducerProject_ReducerFn_T module Result = Belt.Result + open Reducer_Expression_ExpressionBuilder -type environment = InternalExpressionValue.environment type errorValue = ErrorValue.errorValue type expression = ExpressionT.expression type expressionWithContext = ExpressionWithContext.expressionWithContext @@ -21,11 +23,11 @@ type expressionWithContext = ExpressionWithContext.expressionWithContext let dispatchMacroCall = ( macroExpression: expression, bindings: ExpressionT.bindings, - environment, - reduceExpression: ExpressionT.reducerFn, + accessors: ProjectAccessorsT.t, + reduceExpression: ProjectReducerFnT.t, ): result => { - let useExpressionToSetBindings = (bindingExpr: expression, environment, statement, newCode) => { - let rExternalBindingsValue = reduceExpression(bindingExpr, bindings, environment) + let useExpressionToSetBindings = (bindingExpr: expression, accessors, statement, newCode) => { + let rExternalBindingsValue = reduceExpression(bindingExpr, bindings, accessors) rExternalBindingsValue->Result.flatMap(nameSpaceValue => { let newBindings = Bindings.fromExpressionValue(nameSpaceValue) @@ -45,16 +47,17 @@ let dispatchMacroCall = ( | "$_let_$" => "$_setBindings_$" | "$_typeOf_$" => "$_setTypeOfBindings_$" | "$_typeAlias_$" => "$_setTypeAliasBindings_$" + | "$_endOfOuterBlock_$" => "$_dumpBindings_$" | _ => "" } - let doBindStatement = (bindingExpr: expression, statement: expression, environment) => { + let doBindStatement = (bindingExpr: expression, statement: expression, accessors) => { let defaultStatement = ErrorValue.REAssignmentExpected->Error switch statement { | ExpressionT.EList(list{ExpressionT.EValue(IEvCall(callName)), symbolExpr, statement}) => { let setBindingsFn = correspondingSetBindingsFn(callName) if setBindingsFn !== "" { - useExpressionToSetBindings(bindingExpr, environment, statement, ( + useExpressionToSetBindings(bindingExpr, accessors, statement, ( newBindingsExpr, boundStatement, ) => eFunction(setBindingsFn, list{newBindingsExpr, symbolExpr, boundStatement})) @@ -66,12 +69,12 @@ let dispatchMacroCall = ( } } - let doBindExpression = (bindingExpr: expression, statement: expression, environment): result< + let doBindExpression = (bindingExpr: expression, statement: expression, accessors): result< expressionWithContext, errorValue, > => { let defaultStatement = () => - useExpressionToSetBindings(bindingExpr, environment, statement, ( + useExpressionToSetBindings(bindingExpr, accessors, statement, ( _newBindingsExpr, boundStatement, ) => boundStatement) @@ -80,13 +83,13 @@ let dispatchMacroCall = ( | ExpressionT.EList(list{ExpressionT.EValue(IEvCall(callName)), symbolExpr, statement}) => { let setBindingsFn = correspondingSetBindingsFn(callName) if setBindingsFn !== "" { - useExpressionToSetBindings(bindingExpr, environment, statement, ( + useExpressionToSetBindings(bindingExpr, accessors, statement, ( newBindingsExpr, boundStatement, ) => eFunction( "$_exportBindings_$", - list{eFunction(setBindingsFn, list{newBindingsExpr, symbolExpr, boundStatement})}, + list{eFunction(setBindingsFn, list{newBindingsExpr, symbolExpr, boundStatement})}, // expression returning bindings ) ) } else { @@ -97,7 +100,7 @@ let dispatchMacroCall = ( } } - let doBlock = (exprs: list, _bindings: ExpressionT.bindings, _environment): result< + let doBlock = (exprs: list, _bindings: ExpressionT.bindings, _accessors): result< expressionWithContext, errorValue, > => { @@ -130,10 +133,10 @@ let dispatchMacroCall = ( ifTrue: expression, ifFalse: expression, bindings: ExpressionT.bindings, - environment, + accessors, ): result => { let blockCondition = ExpressionBuilder.eBlock(list{condition}) - let rCondition = reduceExpression(blockCondition, bindings, environment) + let rCondition = reduceExpression(blockCondition, bindings, accessors) rCondition->Result.flatMap(conditionValue => switch conditionValue { | InternalExpressionValue.IEvBool(false) => { @@ -149,7 +152,7 @@ let dispatchMacroCall = ( ) } - let expandExpressionList = (aList, bindings: ExpressionT.bindings, environment): result< + let expandExpressionList = (aList, bindings: ExpressionT.bindings, accessors): result< expressionWithContext, errorValue, > => @@ -159,21 +162,21 @@ let dispatchMacroCall = ( bindingExpr: ExpressionT.expression, statement, } => - doBindStatement(bindingExpr, statement, environment) + 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, environment) + doBindStatement(eModule(bindings), statement, accessors) | list{ ExpressionT.EValue(IEvCall("$$_bindExpression_$$")), bindingExpr: ExpressionT.expression, expression, } => - doBindExpression(bindingExpr, expression, environment) + 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, environment) + doBindExpression(eModule(bindings), expression, accessors) | list{ExpressionT.EValue(IEvCall("$$_block_$$")), ...exprs} => - doBlock(exprs, bindings, environment) + doBlock(exprs, bindings, accessors) | list{ ExpressionT.EValue(IEvCall("$$_lambda_$$")), ExpressionT.EValue(IEvArrayString(parameters)), @@ -181,12 +184,12 @@ let dispatchMacroCall = ( } => doLambdaDefinition(bindings, parameters, lambdaDefinition) | list{ExpressionT.EValue(IEvCall("$$_ternary_$$")), condition, ifTrue, ifFalse} => - doTernary(condition, ifTrue, ifFalse, bindings, environment) + doTernary(condition, ifTrue, ifFalse, bindings, accessors) | _ => ExpressionWithContext.noContext(ExpressionT.EList(aList))->Ok } switch macroExpression { - | EList(aList) => expandExpressionList(aList, bindings, environment) + | EList(aList) => expandExpressionList(aList, bindings, accessors) | _ => ExpressionWithContext.noContext(macroExpression)->Ok } } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res index 211c9f53..d908bf93 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res @@ -3,7 +3,7 @@ type location @genType type errorValue = - | REArityError(option, int, int) //TODO: Binding a lambda to a variable should record the variable name in lambda for error reporting + | REArityError(option, int, int) | REArrayIndexNotFound(string, int) | REAssignmentExpected | REDistributionError(DistributionTypes.error) 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 6de4f74a..3e476403 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,35 +1,29 @@ +module Bindings = Reducer_Bindings module BindingsReplacer = Reducer_Expression_BindingsReplacer module BuiltIn = Reducer_Dispatch_BuiltIn module ExpressionBuilder = Reducer_Expression_ExpressionBuilder +module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue module Extra = Reducer_Extra module InternalExpressionValue = ReducerInterface_InternalExpressionValue module Lambda = Reducer_Expression_Lambda module Macro = Reducer_Expression_Macro module MathJs = Reducer_MathJs -module Bindings = Reducer_Bindings +module ProjectAccessorsT = ReducerProject_ProjectAccessors_T module Result = Belt.Result module T = Reducer_Expression_T -type environment = InternalExpressionValue.environment type errorValue = Reducer_ErrorValue.errorValue -type expression = T.expression -type internalExpressionValue = InternalExpressionValue.t type externalExpressionValue = ReducerInterface_ExternalExpressionValue.t -type t = expression +type t = T.t /* - Converts a Squigle code to expression + Recursively evaluate/reduce the expression (Lisp AST/Lambda calculus) */ -let parse = (peggyCode: string): result => - peggyCode->Reducer_Peggy_Parse.parse->Result.map(Reducer_Peggy_ToExpression.fromNode) - -/* - Recursively evaluate/reduce the expression (Lisp AST) -*/ -let rec reduceExpression = (expression: t, bindings: T.bindings, environment: environment): result< - internalExpressionValue, - 'e, -> => { +let rec reduceExpressionInProject = ( + expression: t, + continuation: T.bindings, + accessors: ProjectAccessorsT.t, +): result => { // Js.log(`reduce: ${T.toString(expression)} bindings: ${bindings->Bindings.toString}`) switch expression { | T.EValue(value) => value->Ok @@ -38,41 +32,40 @@ let rec reduceExpression = (expression: t, bindings: T.bindings, environment: en | list{EValue(IEvCall(fName)), ..._args} => switch Macro.isMacroName(fName) { // A macro expands then reduces itself - | true => Macro.doMacroCall(expression, bindings, environment, reduceExpression) - | false => reduceExpressionList(list, bindings, environment) + | true => Macro.doMacroCall(expression, continuation, accessors, reduceExpressionInProject) + | false => reduceExpressionList(list, continuation, accessors) } - | _ => reduceExpressionList(list, bindings, environment) + | _ => reduceExpressionList(list, continuation, accessors) } } } - and reduceExpressionList = ( expressions: list, - bindings: T.bindings, - environment: environment, -): result => { + continuation: T.bindings, + accessors: ProjectAccessorsT.t, +): result => { let racc: result< - list, + list, 'e, - > = expressions->Belt.List.reduceReverse(Ok(list{}), (racc, each: expression) => + > = expressions->Belt.List.reduceReverse(Ok(list{}), (racc, each: t) => racc->Result.flatMap(acc => { each - ->reduceExpression(bindings, environment) + ->reduceExpressionInProject(continuation, accessors) ->Result.map(newNode => { acc->Belt.List.add(newNode) }) }) ) - racc->Result.flatMap(acc => acc->reduceValueList(environment)) + racc->Result.flatMap(acc => acc->reduceValueList(accessors)) } /* After reducing each level of expression(Lisp AST), we have a value list to evaluate */ -and reduceValueList = (valueList: list, environment): result< - internalExpressionValue, - 'e, -> => +and reduceValueList = ( + valueList: list, + accessors: ProjectAccessorsT.t, +): result => switch valueList { | list{IEvCall(fName), ...args} => { let rCheckedArgs = switch fName { @@ -81,7 +74,10 @@ and reduceValueList = (valueList: list, environment): r } rCheckedArgs->Result.flatMap(checkedArgs => - (fName, checkedArgs->Belt.List.toArray)->BuiltIn.dispatch(environment, reduceExpression) + (fName, checkedArgs->Belt.List.toArray)->BuiltIn.dispatch( + accessors, + reduceExpressionInProject, + ) ) } | list{IEvLambda(_)} => @@ -91,11 +87,11 @@ and reduceValueList = (valueList: list, environment): r ->Result.flatMap(reducedValueList => reducedValueList->Belt.List.toArray->InternalExpressionValue.IEvArray->Ok ) - | list{IEvLambda(lamdaCall), ...args} => + | list{IEvLambda(lambdaCall), ...args} => args ->Lambda.checkIfReduced ->Result.flatMap(checkedArgs => - Lambda.doLambdaCall(lamdaCall, checkedArgs, environment, reduceExpression) + Lambda.doLambdaCall(lambdaCall, checkedArgs, accessors, reduceExpressionInProject) ) | _ => @@ -106,53 +102,37 @@ and reduceValueList = (valueList: list, environment): r ) } -let evalUsingBindingsExpression_ = (aExpression, bindings, environment): result< - internalExpressionValue, - 'e, -> => reduceExpression(aExpression, bindings, environment) - -let evaluateUsingOptions = ( - ~environment: option, - ~externalBindings: option, - code: string, -): result => { - let anEnvironment = Belt.Option.getWithDefault( - environment, - ReducerInterface_ExternalExpressionValue.defaultEnvironment, - ) - - let mergedBindings: InternalExpressionValue.nameSpace = Bindings.merge( - ReducerInterface_StdLib.internalStdLib, - Belt.Option.map(externalBindings, Bindings.fromTypeScriptBindings)->Belt.Option.getWithDefault( - Bindings.emptyModule, - ), - ) - - parse(code) - ->Result.flatMap(expr => evalUsingBindingsExpression_(expr, mergedBindings, anEnvironment)) - ->Result.map(ReducerInterface_InternalExpressionValue.toExternal) +let reduceReturningBindings = ( + expression: t, + continuation: T.bindings, + accessors: ProjectAccessorsT.t, +): (result, T.bindings) => { + let result = reduceExpressionInProject(expression, continuation, accessors) + (result, accessors.continuation) } -/* - IEvaluates Squiggle code and bindings via Reducer and answers the result -*/ -let evaluate = (code: string): result => { - evaluateUsingOptions(~environment=None, ~externalBindings=None, code) -} -let evaluatePartialUsingExternalBindings = ( - code: string, - externalBindings: ReducerInterface_ExternalExpressionValue.externalBindings, - environment: ReducerInterface_ExternalExpressionValue.environment, -): result => { - let rAnswer = evaluateUsingOptions( - ~environment=Some(environment), - ~externalBindings=Some(externalBindings), - code, - ) - switch rAnswer { - | Ok(EvModule(externalBindings)) => Ok(externalBindings) - | Ok(_) => - Error(Reducer_ErrorValue.RESyntaxError(`Partials must end with an assignment or record`, None)) - | Error(err) => err->Error +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 => + peggyCode->Reducer_Peggy_Parse.parse->Result.map(Reducer_Peggy_ToExpression.fromNode) + + let evaluate = (expression: t): result => { + let accessors = ProjectAccessorsT.identityAccessors + expression->reduceExpressionInProject(accessors.stdLib, accessors) } + + let evaluateString = (peggyCode: string): result => + parse(peggyCode)->Result.flatMap(evaluate) + + let evaluateAsExternal = (expression: t): result => + { + let accessors = ProjectAccessorsT.identityAccessors + expression->reduceExpressionInProject(accessors.stdLib, accessors) + }->Result.map(InternalExpressionValue.toExternal) + + let evaluateStringAsExternal = (peggyCode: string): result< + ExternalExpressionValue.t, + errorValue, + > => parse(peggyCode)->Result.flatMap(evaluateAsExternal) } 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 44059e2b..808a2dcd 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,9 +1,11 @@ +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 type bindings = ExpressionT.bindings type context = bindings @@ -11,7 +13,6 @@ type environment = InternalExpressionValue.environment type errorValue = Reducer_ErrorValue.errorValue type expression = ExpressionT.expression type internalExpressionValue = InternalExpressionValue.t -type reducerFn = ExpressionT.reducerFn type expressionWithContext = | ExpressionWithContext(expression, context) @@ -20,16 +21,16 @@ type expressionWithContext = let callReducer = ( expressionWithContext: expressionWithContext, bindings: bindings, - environment: environment, - reducer: reducerFn, + accessors: ProjectAccessorsT.t, + reducer: ProjectReducerFnT.t, ): result => { switch expressionWithContext { | ExpressionNoContext(expr) => // Js.log(`callReducer: bindings ${Bindings.toString(bindings)} expr ${ExpressionT.toString(expr)}`) - reducer(expr, bindings, environment) + reducer(expr, bindings, accessors) | ExpressionWithContext(expr, context) => // Js.log(`callReducer: context ${Bindings.toString(context)} expr ${ExpressionT.toString(expr)}`) - reducer(expr, context, environment) + reducer(expr, context, accessors) } } 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 59779484..587d80be 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,12 +1,13 @@ +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 Bindings = Reducer_Bindings +module ProjectAccessorsT = ReducerProject_ProjectAccessors_T +module ProjectReducerFnT = ReducerProject_ReducerFn_T module Result = Belt.Result -type environment = ReducerInterface_InternalExpressionValue.environment type expression = ExpressionT.expression type expressionOrFFI = ExpressionT.expressionOrFFI type internalExpressionValue = ReducerInterface_InternalExpressionValue.t @@ -44,7 +45,13 @@ let checkIfReduced = (args: list) => ) ) -let caseNotFFI = (lambdaValue: ExpressionValue.lambdaValue, expr, args, environment, reducer) => { +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, ( @@ -52,39 +59,43 @@ let caseNotFFI = (lambdaValue: ExpressionValue.lambdaValue, expr, args, environm (variable, variableValue), ) => acc->Bindings.set(variable, variableValue)) let newExpression = ExpressionBuilder.eBlock(list{expr}) - reducer(newExpression, bindings, environment) + reducer(newExpression, bindings, accessors) } -let caseFFI = (ffiFn: ExpressionT.ffiFn, args, environment) => { - ffiFn(args->Belt.List.toArray, environment) +let caseFFI = (ffiFn: ExpressionT.ffiFn, args, accessors: ProjectAccessorsT.t) => { + ffiFn(args->Belt.List.toArray, accessors.environment) } let applyParametersToLambda = ( lambdaValue: ExpressionValue.lambdaValue, args, - environment, - reducer: ExpressionT.reducerFn, + accessors: ProjectAccessorsT.t, + reducer: ProjectReducerFnT.t, ): result => { checkArity(lambdaValue, args)->Result.flatMap(args => checkIfReduced(args)->Result.flatMap(args => { let exprOrFFI = castInternalCodeToExpression(lambdaValue.body) switch exprOrFFI { - | NotFFI(expr) => caseNotFFI(lambdaValue, expr, args, environment, reducer) - | FFI(ffiFn) => caseFFI(ffiFn, args, environment) + | NotFFI(expr) => caseNotFFI(lambdaValue, expr, args, accessors, reducer) + | FFI(ffiFn) => caseFFI(ffiFn, args, accessors) } }) ) } -let doLambdaCall = (lambdaValue: ExpressionValue.lambdaValue, args, environment, reducer) => - applyParametersToLambda(lambdaValue, args, environment, reducer) +let doLambdaCall = ( + lambdaValue: ExpressionValue.lambdaValue, + args, + accessors: ProjectAccessorsT.t, + reducer: ProjectReducerFnT.t, +) => applyParametersToLambda(lambdaValue, args, accessors, reducer) let foreignFunctionInterface = ( lambdaValue: ExpressionValue.lambdaValue, argArray: array, - environment: ExpressionValue.environment, - reducer: ExpressionT.reducerFn, + accessors: ProjectAccessorsT.t, + reducer: ProjectReducerFnT.t, ): result => { let args = argArray->Belt.List.fromArray - applyParametersToLambda(lambdaValue, args, environment, reducer) + applyParametersToLambda(lambdaValue, args, accessors, reducer) } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression_Macro.res index 2598a9ed..003d3170 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 @@ -2,6 +2,8 @@ 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 @@ -11,34 +13,29 @@ type expressionWithContext = ExpressionWithContext.expressionWithContext let expandMacroCall = ( macroExpression: expression, bindings: ExpressionT.bindings, - environment: environment, - reduceExpression: ExpressionT.reducerFn, + accessors: ProjectAccessorsT.t, + reduceExpression: ProjectReducerFnT.t, ): result => Reducer_Dispatch_BuiltInMacros.dispatchMacroCall( macroExpression, bindings, - environment, + accessors, reduceExpression, ) let doMacroCall = ( macroExpression: expression, bindings: ExpressionT.bindings, - environment: environment, - reduceExpression: ExpressionT.reducerFn, + accessors: ProjectAccessorsT.t, + reduceExpression: ProjectReducerFnT.t, ): result => expandMacroCall( macroExpression, bindings, - environment, - reduceExpression, + (accessors: ProjectAccessorsT.t), + (reduceExpression: ProjectReducerFnT.t), )->Result.flatMap(expressionWithContext => - ExpressionWithContext.callReducer( - expressionWithContext, - bindings, - environment, - reduceExpression, - ) + ExpressionWithContext.callReducer(expressionWithContext, bindings, accessors, reduceExpression) ) 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 c9739be3..61f723df 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 @@ -17,6 +17,8 @@ type rec expression = | EValue(internalExpressionValue) // Irreducible built-in value. Reducer should not know the internals. External libraries are responsible and bindings = InternalExpressionValue.nameSpace +type t = expression + type reducerFn = ( expression, bindings, 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 15837da4..ec490c42 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,12 +9,25 @@ start zeroOMoreArgumentsBlockOrExpression = innerBlockOrExpression / lambda +// { return h.makeFunctionCall('$_typeOf_$', [identifier, typeExpression])} +// {return [h.nodeVoid()];} outerBlock = statements:array_statements finalExpression: (statementSeparator @expression)? - { if (finalExpression != null) { statements.push(finalExpression) } - return h.nodeBlock(statements) } + { 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 - { return h.nodeBlock([finalExpression])} + { + var newFinalExpression = h.makeFunctionCall('$_endOfOuterBlock_$', [h.nodeVoid(), finalExpression]); + return h.nodeBlock([newFinalExpression])} innerBlockOrExpression = quotedInnerBlock 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 2119ee62..ab0ff74e 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,40 +1,37 @@ +module Bindings = Reducer_Bindings module ErrorValue = Reducer_ErrorValue +module Expression = Reducer_Expression module ExpressionT = Reducer_Expression_T module InternalExpressionValue = ReducerInterface_InternalExpressionValue -module Bindings = Reducer_Bindings +module ProjectAccessorsT = ReducerProject_ProjectAccessors_T +module ProjectReducerFnT = ReducerProject_ReducerFn_T module T = Reducer_Type_T let ievFromTypeExpression = ( typeExpressionSourceCode: string, - reducerFn: ExpressionT.reducerFn, + reducerFn: ProjectReducerFnT.t, ): result => { let sIndex = "compiled" let sourceCode = `type ${sIndex}=${typeExpressionSourceCode}` - Reducer_Expression.parse(sourceCode)->Belt.Result.flatMap(expr => { - let rContext = reducerFn( - expr, - Bindings.emptyBindings, - InternalExpressionValue.defaultEnvironment, - ) - Belt.Result.map(rContext, context => - switch context { - | IEvBindings(nameSpace) => - switch Bindings.getType(nameSpace, sIndex) { - | Some(value) => value - | None => raise(Reducer_Exception.ImpossibleException("Reducer_Type_Compile-none")) - } - | _ => raise(Reducer_Exception.ImpossibleException("Reducer_Type_Compile-raise")) + Reducer_Expression.BackCompatible.parse(sourceCode)->Belt.Result.flatMap(expr => { + let accessors = ProjectAccessorsT.identityAccessors + let result = reducerFn(expr, Bindings.emptyBindings, accessors) + let nameSpace = accessors.continuation + + switch result { + | Ok(_) => + switch Bindings.getType(nameSpace, sIndex) { + | Some(value) => value->Ok + | None => raise(Reducer_Exception.ImpossibleException("Reducer_Type_Compile-none")) } - ) + | err => err + } }) } -let fromTypeExpression = ( - typeExpressionSourceCode: string, - reducerFn: ExpressionT.reducerFn, -): result => { - ievFromTypeExpression( - (typeExpressionSourceCode: string), - (reducerFn: ExpressionT.reducerFn), - )->Belt.Result.map(T.fromIEvValue) +let fromTypeExpression = (typeExpressionSourceCode: string, reducerFn: ProjectReducerFnT.t): result< + T.t, + ErrorValue.t, +> => { + ievFromTypeExpression(typeExpressionSourceCode, reducerFn)->Belt.Result.map(T.fromIEvValue) } 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 e4336df5..42704fd1 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,5 +1,7 @@ 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 @@ -124,7 +126,7 @@ let rec isITypeOf = (anIType: T.iType, aValue): result = let isTypeOf = ( typeExpressionSourceCode: string, aValue: InternalExpressionValue.t, - reducerFn: ExpressionT.reducerFn, + reducerFn: ProjectReducerFnT.t, ): result => { switch typeExpressionSourceCode->Reducer_Type_Compile.fromTypeExpression(reducerFn) { | Ok(anIType) => @@ -152,7 +154,7 @@ let checkITypeArguments = (anIType: T.iType, args: array, - reducerFn: ExpressionT.reducerFn, + reducerFn: ProjectReducerFnT.t, ): result => { switch typeExpressionSourceCode->Reducer_Type_Compile.fromTypeExpression(reducerFn) { | Ok(anIType) => diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalExpressionValue.res index d613ceb8..185fb351 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalExpressionValue.res @@ -92,6 +92,18 @@ let toStringResult = x => | Error(m) => `Error(${ErrorValue.errorToString(m)})` } +let toStringOptionResult = x => + switch x { + | Some(a) => toStringResult(a) + | None => `None` + } + +let toStringOption = x => + switch x { + | Some(a) => toString(a) + | None => `None` + } + @genType type environment = GenericDist.env diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res index 7ae6ace9..89528a32 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalLibrary.res @@ -1,4 +1,6 @@ module InternalExpressionValue = ReducerInterface_InternalExpressionValue +module ProjectAccessorsT = ReducerProject_ProjectAccessors_T +module ProjectReducerFnT = ReducerProject_ReducerFn_T type internalExpressionValue = InternalExpressionValue.t /* @@ -6,17 +8,17 @@ type internalExpressionValue = InternalExpressionValue.t */ let dispatch = ( call: InternalExpressionValue.functionCall, - environment, - reducer: Reducer_Expression_T.reducerFn, + accessors: ProjectAccessorsT.t, + reducer: ProjectReducerFnT.t, 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)) + () => 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)) } /* diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res index 86718b64..b5799067 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res @@ -132,6 +132,12 @@ let toStringResult = x => | Error(m) => `Error(${ErrorValue.errorToString(m)})` } +let toStringOptionResult = x => + switch x { + | Some(a) => `${toStringResult(a)})` + | None => "None" + } + let toStringResultOkless = (codeResult: result): string => switch codeResult { | Ok(a) => toString(a) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res index ec6c4fd4..8beec882 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res @@ -1,7 +1,6 @@ module Bindings = Reducer_Bindings -let internalStdLib = +let internalStdLib: Bindings.t = Bindings.emptyBindings->SquiggleLibrary_Math.makeBindings->SquiggleLibrary_Versions.makeBindings -@genType let externalStdLib = internalStdLib->Bindings.toTypeScriptBindings 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 new file mode 100644 index 00000000..af1c16c9 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_Value/ReducerInterface_Value_Continuation.res @@ -0,0 +1,28 @@ +module InternalExpressionValue = ReducerInterface_InternalExpressionValue + +type t = InternalExpressionValue.nameSpace + +let toValue = nameSpace => InternalExpressionValue.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`) + } + +let minus = (NameSpace(thisContainer): t, NameSpace(thatContainer): t) => { + Belt.Map.String.removeMany( + thisContainer, + Belt.Map.String.keysToArray(thatContainer), + )->InternalExpressionValue.NameSpace +} diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res new file mode 100644 index 00000000..8a78c795 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res @@ -0,0 +1,396 @@ +// TODO: Restore run FFI? +// TODO: Auto clean project based on topology + +module Bindings = Reducer_Bindings +module Continuation = ReducerInterface_Value_Continuation +module ErrorValue = Reducer_ErrorValue +module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue +module InternalExpressionValue = ReducerInterface_InternalExpressionValue +module ProjectAccessorsT = ReducerProject_ProjectAccessors_T +module ProjectItem = ReducerProject_ProjectItem +module T = ReducerProject_T + +@genType.opaque +type project = T.t +type t = T.t + +module Private = { + type internalProject = T.Private.t + type t = T.Private.t + + 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 getImmediateDependencies = (this: t, sourceId: string): ProjectItem.T.includesType => + getItem(this, sourceId)->ProjectItem.getImmediateDependencies + + type topologicalSortState = (Belt.Map.String.t, list) + let rec topologicalSortUtil = ( + this: t, + sourceId: string, + state: topologicalSortState, + ): topologicalSortState => { + let dependencies = getImmediateDependencies(this, sourceId)->Belt.Result.getWithDefault([]) + let (visited, stack) = state + let myVisited = Belt.Map.String.set(visited, sourceId, true) + let (newVisited, newStack) = dependencies->Belt.Array.reduce((myVisited, stack), ( + (currVisited, currStack), + dependency, + ) => { + if !Belt.Map.String.getWithDefault(currVisited, dependency, false) { + topologicalSortUtil(this, dependency, (currVisited, currStack)) + } else { + (currVisited, currStack) + } + }) + (newVisited, list{sourceId, ...newStack}) + } + + let getTopologicalSort = (this: t): array => { + let (_visited, stack) = getSourceIds(this)->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 + } + + let getTopologicalSortFor = (this: t, sourceId) => { + let runOrder = getTopologicalSort(this) + let index = runOrder->Js.Array2.indexOf(sourceId) + let after = Belt.Array.sliceToEnd(runOrder, index + 1) + let before = Js.Array2.slice(runOrder, ~start=0, ~end_=index + 1) + (before, after) + } + + let getRunOrder = getTopologicalSort + + let createProject = () => { + let this: t = { + "items": Belt.Map.String.empty, + "stdLib": ReducerInterface_StdLib.internalStdLib, + "environment": InternalExpressionValue.defaultEnvironment, + } + this + } + + let getRunOrderFor = (this: t, sourceId: string) => { + let (runOrder, _) = getTopologicalSortFor(this, sourceId) + runOrder + } + + let getDependencies = (this: t, sourceId: string): array => { + let runOrder = getRunOrderFor(this, sourceId) + + let _ = Js.Array2.pop(runOrder) + runOrder + } + + let getDependents = (this: t, sourceId: string): array => { + let (_, dependents) = getTopologicalSortFor(this, sourceId) + dependents + } + + let rec touchSource = (this: t, sourceId: string): unit => { + let item = this->getItem(sourceId) + let newItem = ProjectItem.touchSource(item) + Belt.Map.String.set(this["items"], sourceId, newItem)->T.Private.setFieldItems(this, _) + touchDependents(this, sourceId) + } + and touchDependents = (this: t, sourceId: string): unit => { + let _ = getDependents(this, sourceId)->Belt.Array.forEach(_, touchSource(this, _)) + } + + let getSource = (this: t, sourceId: string): option => + Belt.Map.String.get(this["items"], sourceId)->Belt.Option.map(ProjectItem.getSource) + + let setSource = (this: t, sourceId: string, value: string): unit => { + let newItem = this->getItem(sourceId)->ProjectItem.setSource(value) + Belt.Map.String.set(this["items"], sourceId, newItem)->T.Private.setFieldItems(this, _) + touchDependents(this, sourceId) + } + + let clean = (this: t, sourceId: string): unit => { + let newItem = this->getItem(sourceId)->ProjectItem.clean + Belt.Map.String.set(this["items"], sourceId, newItem)->T.Private.setFieldItems(this, _) + } + + let cleanAll = (this: t): unit => + getSourceIds(this)->Belt.Array.forEach(sourceId => clean(this, sourceId)) + + let cleanResults = (this: t, sourceId: string): unit => { + let newItem = this->getItem(sourceId)->ProjectItem.cleanResults + Belt.Map.String.set(this["items"], sourceId, newItem)->T.Private.setFieldItems(this, _) + } + + let cleanAllResults = (this: t): unit => + getSourceIds(this)->Belt.Array.forEach(sourceId => cleanResults(this, sourceId)) + + let getIncludes = (this: t, sourceId: string): ProjectItem.T.includesType => + this->getItem(sourceId)->ProjectItem.getIncludes + + let setContinues = (this: t, sourceId: string, continues: array): unit => { + let newItem = this->getItem(sourceId)->ProjectItem.setContinues(continues) + Belt.Map.String.set(this["items"], sourceId, newItem)->T.Private.setFieldItems(this, _) + touchSource(this, sourceId) + } + let getContinues = (this: t, sourceId: string): array => + ProjectItem.getContinues(this->getItem(sourceId)) + + let removeContinues = (this: t, sourceId: string): unit => { + let newItem = this->getItem(sourceId)->ProjectItem.removeContinues + Belt.Map.String.set(this["items"], sourceId, newItem)->T.Private.setFieldItems(this, _) + touchSource(this, sourceId) + } + + let getContinuation = (this: t, sourceId: string): ProjectItem.T.continuationArgumentType => + this->getItem(sourceId)->ProjectItem.getContinuation + + let setContinuation = ( + this: t, + sourceId: string, + continuation: ProjectItem.T.continuationArgumentType, + ): unit => { + let newItem = this->getItem(sourceId)->ProjectItem.setContinuation(continuation) + Belt.Map.String.set(this["items"], sourceId, newItem)->T.Private.setFieldItems(this, _) + } + + let getResult = (this: t, sourceId: string): ProjectItem.T.resultType => + this->getItem(sourceId)->ProjectItem.getResult + + let setResult = (this: t, sourceId: string, value: ProjectItem.T.resultArgumentType): unit => { + let newItem = this->getItem(sourceId)->ProjectItem.setResult(value) + Belt.Map.String.set(this["items"], sourceId, newItem)->T.Private.setFieldItems(this, _) + } + + let getExternalResult = (this: t, sourceId: string): ProjectItem.T.externalResultType => + this->getItem(sourceId)->ProjectItem.getExternalResult + + let parseIncludes = (this: t, sourceId: string): unit => { + let newItem = this->getItem(sourceId)->ProjectItem.parseIncludes + Belt.Map.String.set(this["items"], sourceId, newItem)->T.Private.setFieldItems(this, _) + } + + let rawParse = (this: t, sourceId): unit => { + let newItem = this->getItem(sourceId)->ProjectItem.rawParse + Belt.Map.String.set(this["items"], sourceId, newItem)->T.Private.setFieldItems(this, _) + } + + let getStdLib = (this: t): Reducer_Bindings.t => this["stdLib"] + let setStdLib = (this: t, value: Reducer_Bindings.t): unit => + T.Private.setFieldStdLib(this, value) + + let getEnvironment = (this: t): InternalExpressionValue.environment => this["environment"] + let setEnvironment = (this: t, value: InternalExpressionValue.environment): unit => + T.Private.setFieldEnvironment(this, value) + + let getExternalBindings = ( + this: t, + sourceId: string, + ): ProjectItem.T.externalBindingsArgumentType => { + let those = this->getContinuation(sourceId) + let these = this->getStdLib + let ofUser = Continuation.minus(those, these) + ofUser->InternalExpressionValue.nameSpaceToTypeScriptBindings + } + + let buildProjectAccessors = (this: t): ProjectAccessorsT.t => { + continuation: Bindings.emptyBindings, + stdLib: getStdLib(this), + environment: getEnvironment(this), + } + + let doRunWithContinuation = ( + this: t, + sourceId: string, + continuation: ProjectItem.T.continuation, + ): unit => { + let accessors = buildProjectAccessors(this) + let newItem = this->getItem(sourceId)->ProjectItem.run(continuation, accessors) + Belt.Map.String.set(this["items"], sourceId, newItem)->T.Private.setFieldItems(this, _) + setContinuation(this, sourceId, accessors.continuation) + } + + type runState = (ProjectItem.T.resultArgumentType, ProjectItem.T.continuation) + + let tryRunWithContinuation = ( + this: t, + sourceId: string, + (rPrevResult: ProjectItem.T.resultArgumentType, continuation: ProjectItem.T.continuation), + ): (ProjectItem.T.resultArgumentType, ProjectItem.T.continuation) => { + switch getResult(this, sourceId) { + | Some(result) => (result, getContinuation(this, sourceId)) // already ran + | None => + switch rPrevResult { + | Error(error) => { + setResult(this, sourceId, Error(error)) + (Error(error), continuation) + } + | Ok(_prevResult) => { + doRunWithContinuation(this, sourceId, continuation) + ( + getResult(this, sourceId)->Belt.Option.getWithDefault(rPrevResult), + getContinuation(this, sourceId), + ) + } + } + } + } + + let runAll = (this: t): unit => { + let runOrder = getTopologicalSort(this) + let initialState = (Ok(InternalExpressionValue.IEvVoid), getStdLib(this)) + let _finalState = Belt.Array.reduce(runOrder, initialState, (currState, currId) => + tryRunWithContinuation(this, currId, currState) + ) + } + + let run = (this: t, sourceId: string): unit => { + let runOrder = getRunOrderFor(this, sourceId) + let initialState = (Ok(InternalExpressionValue.IEvVoid), getStdLib(this)) + let _finalState = Belt.Array.reduce(runOrder, initialState, (currState, currId) => + tryRunWithContinuation(this, currId, currState) + ) + } + + let evaluate = (sourceCode: string) => { + let project = createProject() + setSource(project, "main", sourceCode) + runAll(project) + ( + getResult(project, "main")->Belt.Option.getWithDefault(IEvVoid->Ok), + getContinuation(project, "main"), + ) + } +} + +/* + PUBLIC FUNCTIONS +*/ + +// Create a new this to hold the sources, executables, bindings and other data. +// The this is a mutable object for use in TypeScript. +let createProject = (): t => Private.createProject()->T.Private.castFromInternalProject + +// Answers the array of existing source ids to enumerate over. +let getSourceIds = (this: t): array => + this->T.Private.castToInternalProject->Private.getSourceIds + +// Sets the source for a given source id. +let setSource = (this: t, sourceId: string, value: string): unit => + this->T.Private.castToInternalProject->Private.setSource(sourceId, value) + +// Gets the source for a given source id. +let getSource = (this: t, sourceId: string): option => + this->T.Private.castToInternalProject->Private.getSource(sourceId) + +// Touches the source for a given source id. This forces the dependency graph to be re-evaluated. +// Touching source code clears the includes so that they can be reevaluated. +let touchSource = (this: t, sourceId: string): unit => + this->T.Private.castToInternalProject->Private.touchSource(sourceId) + +// Cleans the compilation artifacts for a given source id. The results stay untouched. +let clean = (this: t, sourceId: string): unit => + this->T.Private.castToInternalProject->Private.clean(sourceId) + +// Cleans all compilation artifacts for all the this. The results stay untouched. +let cleanAll = (this: t): unit => this->T.Private.castToInternalProject->Private.cleanAll + +// Cleans results. Compilation stays untouched to rerun the source. +let cleanResults = (this: t, sourceId: string): unit => + this->T.Private.castToInternalProject->Private.cleanResults(sourceId) + +// Cleans all results. Compilations stays untouched to rerun the source. +let cleanAllResults = (this: t): unit => + this->T.Private.castToInternalProject->Private.cleanAllResults + +let getIncludes = (this: t, sourceId: string): ProjectItem.T.includesType => + this->T.Private.castToInternalProject->Private.getIncludes(sourceId) + +let getContinues = (this: t, sourceId: string): array => + this->T.Private.castToInternalProject->Private.getContinues(sourceId) + +// setContinues acts like an include hidden in the source. It is used to define a continuation. +let setContinues = (this: t, sourceId: string, continues: array): unit => + this->T.Private.castToInternalProject->Private.setContinues(sourceId, continues) + +// This source is not continuing any other source. It is a standalone source. +// Touches this source also. +let removeContinues = (this: t, sourceId: string): unit => + this->T.Private.castToInternalProject->Private.removeContinues(sourceId) + +// Gets includes and continues for a given source id. SourceId is depending on them +let getDependencies = (this: t, sourceId: string): array => + this->T.Private.castToInternalProject->Private.getDependencies(sourceId) + +// Get source ids depending on a given source id. +let getDependents = (this: t, sourceId: string): array => + this->T.Private.castToInternalProject->Private.getDependents(sourceId) + +// Get run order for all sources. It is a topological sort of the dependency graph. +let getRunOrder = (this: t) => this->T.Private.castToInternalProject->Private.getRunOrder + +// Get run order for a given source id. It is a topological sort of the dependency graph. +let getRunOrderFor = (this: t, sourceId: string) => + this->T.Private.castToInternalProject->Private.getRunOrderFor(sourceId) + +// Parse includes so that you can load them before running. Use getIncludes to get the includes. +// It is your responsibility to load the includes before running. +let parseIncludes = (this: t, sourceId: string): unit => + this->T.Private.castToInternalProject->Private.parseIncludes(sourceId) + +// Parse the source code if it is not done already. Use getRawParse to get the parse tree +let rawParse = (this: t, sourceId: string): unit => + this->T.Private.castToInternalProject->Private.rawParse(sourceId) + +// Runs the source code. +// The code is parsed if it is not already done. +// If it continues/includes another source then it will run that source also if is not already done. +let run = (this: t, sourceId: string): unit => + this->T.Private.castToInternalProject->Private.run(sourceId) + +// Runs all the sources. +let runAll = (this: t): unit => this->T.Private.castToInternalProject->Private.runAll + +// WARNING" getExternalBindings will be deprecated. Cyclic directed graph problems +// Get the bindings after running the source code. +let getExternalBindings = (this: t, sourceId: string): ExternalExpressionValue.record => + this->T.Private.castToInternalProject->Private.getExternalBindings(sourceId) + +//WARNING: externalResult will be deprecated. Cyclic directed graph problems +let getExternalResult = (this: t, sourceId: string): option< + result, +> => this->T.Private.castToInternalProject->Private.getExternalResult(sourceId) + +// This is a convenience function to get the result of a single source. +// You cannot use includes +let evaluate = (sourceCode: string): ('r, 'b) => { + let (result, continuation) = Private.evaluate(sourceCode) + ( + result->Belt.Result.map(InternalExpressionValue.toExternal), + continuation->InternalExpressionValue.nameSpaceToTypeScriptBindings, + ) +} + +let foreignFunctionInterface = ( + lambdaValue: ExternalExpressionValue.lambdaValue, + argArray: array, + environment: ExternalExpressionValue.environment, +) => { + let internallambdaValue = InternalExpressionValue.lambdaValueToInternal(lambdaValue) + let internalArgArray = argArray->Js.Array2.map(InternalExpressionValue.toInternal) + let accessors = ProjectAccessorsT.identityAccessorsWithEnvironment(environment) + Reducer_Expression_Lambda.foreignFunctionInterface( + internallambdaValue, + internalArgArray, + accessors, + Reducer_Expression.reduceExpressionInProject, + )->Belt.Result.map(InternalExpressionValue.toExternal) +} diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js new file mode 100644 index 00000000..adc6e598 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js @@ -0,0 +1,915 @@ +// Generated by Peggy 2.0.1. +// +// https://peggyjs.org/ + +"use strict"; + +function peg$subclass(child, parent) { + function C() { this.constructor = child; } + C.prototype = parent.prototype; + child.prototype = new C(); +} + +function peg$SyntaxError(message, expected, found, location) { + var self = Error.call(this, message); + // istanbul ignore next Check is a necessary evil to support older environments + if (Object.setPrototypeOf) { + Object.setPrototypeOf(self, peg$SyntaxError.prototype); + } + self.expected = expected; + self.found = found; + self.location = location; + self.name = "SyntaxError"; + return self; +} + +peg$subclass(peg$SyntaxError, Error); + +function peg$padEnd(str, targetLength, padString) { + padString = padString || " "; + if (str.length > targetLength) { return str; } + targetLength -= str.length; + padString += padString.repeat(targetLength); + return str + padString.slice(0, targetLength); +} + +peg$SyntaxError.prototype.format = function(sources) { + var str = "Error: " + this.message; + if (this.location) { + var src = null; + var k; + for (k = 0; k < sources.length; k++) { + if (sources[k].source === this.location.source) { + src = sources[k].text.split(/\r\n|\n|\r/g); + break; + } + } + var s = this.location.start; + var loc = this.location.source + ":" + s.line + ":" + s.column; + if (src) { + var e = this.location.end; + var filler = peg$padEnd("", s.line.toString().length, ' '); + var line = src[s.line - 1]; + var last = s.line === e.line ? e.column : line.length + 1; + var hatLen = (last - s.column) || 1; + str += "\n --> " + loc + "\n" + + filler + " |\n" + + s.line + " | " + line + "\n" + + filler + " | " + peg$padEnd("", s.column - 1, ' ') + + peg$padEnd("", hatLen, "^"); + } else { + str += "\n at " + loc; + } + } + return str; +}; + +peg$SyntaxError.buildMessage = function(expected, found) { + var DESCRIBE_EXPECTATION_FNS = { + literal: function(expectation) { + return "\"" + literalEscape(expectation.text) + "\""; + }, + + class: function(expectation) { + var escapedParts = expectation.parts.map(function(part) { + return Array.isArray(part) + ? classEscape(part[0]) + "-" + classEscape(part[1]) + : classEscape(part); + }); + + return "[" + (expectation.inverted ? "^" : "") + escapedParts.join("") + "]"; + }, + + any: function() { + return "any character"; + }, + + end: function() { + return "end of input"; + }, + + other: function(expectation) { + return expectation.description; + } + }; + + function hex(ch) { + return ch.charCodeAt(0).toString(16).toUpperCase(); + } + + function literalEscape(s) { + return s + .replace(/\\/g, "\\\\") + .replace(/"/g, "\\\"") + .replace(/\0/g, "\\0") + .replace(/\t/g, "\\t") + .replace(/\n/g, "\\n") + .replace(/\r/g, "\\r") + .replace(/[\x00-\x0F]/g, function(ch) { return "\\x0" + hex(ch); }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return "\\x" + hex(ch); }); + } + + function classEscape(s) { + return s + .replace(/\\/g, "\\\\") + .replace(/\]/g, "\\]") + .replace(/\^/g, "\\^") + .replace(/-/g, "\\-") + .replace(/\0/g, "\\0") + .replace(/\t/g, "\\t") + .replace(/\n/g, "\\n") + .replace(/\r/g, "\\r") + .replace(/[\x00-\x0F]/g, function(ch) { return "\\x0" + hex(ch); }) + .replace(/[\x10-\x1F\x7F-\x9F]/g, function(ch) { return "\\x" + hex(ch); }); + } + + function describeExpectation(expectation) { + return DESCRIBE_EXPECTATION_FNS[expectation.type](expectation); + } + + function describeExpected(expected) { + var descriptions = expected.map(describeExpectation); + var i, j; + + descriptions.sort(); + + if (descriptions.length > 0) { + for (i = 1, j = 1; i < descriptions.length; i++) { + if (descriptions[i - 1] !== descriptions[i]) { + descriptions[j] = descriptions[i]; + j++; + } + } + descriptions.length = j; + } + + switch (descriptions.length) { + case 1: + return descriptions[0]; + + case 2: + return descriptions[0] + " or " + descriptions[1]; + + default: + return descriptions.slice(0, -1).join(", ") + + ", or " + + descriptions[descriptions.length - 1]; + } + } + + function describeFound(found) { + return found ? "\"" + literalEscape(found) + "\"" : "end of input"; + } + + return "Expected " + describeExpected(expected) + " but " + describeFound(found) + " found."; +}; + +function peg$parse(input, options) { + options = options !== undefined ? options : {}; + + var peg$FAILED = {}; + var peg$source = options.grammarSource; + + var peg$startRuleFunctions = { start: peg$parsestart }; + var peg$startRuleFunction = peg$parsestart; + + var peg$c0 = "#include"; + var peg$c1 = "'"; + var peg$c2 = "\""; + var peg$c3 = "//"; + var peg$c4 = "/*"; + var peg$c5 = "*/"; + + var peg$r0 = /^[^']/; + var peg$r1 = /^[^"]/; + var peg$r2 = /^[^*]/; + var peg$r3 = /^[ \t]/; + var peg$r4 = /^[\n\r]/; + var peg$r5 = /^[^\r\n]/; + + var peg$e0 = peg$literalExpectation("#include", false); + var peg$e1 = peg$otherExpectation("string"); + var peg$e2 = peg$literalExpectation("'", false); + var peg$e3 = peg$classExpectation(["'"], true, false); + var peg$e4 = peg$literalExpectation("\"", false); + var peg$e5 = peg$classExpectation(["\""], true, false); + var peg$e6 = peg$literalExpectation("//", false); + var peg$e7 = peg$literalExpectation("/*", false); + var peg$e8 = peg$classExpectation(["*"], true, false); + var peg$e9 = peg$literalExpectation("*/", false); + var peg$e10 = peg$otherExpectation("white space"); + var peg$e11 = peg$classExpectation([" ", "\t"], false, false); + var peg$e12 = peg$otherExpectation("newline"); + var peg$e13 = peg$classExpectation(["\n", "\r"], false, false); + var peg$e14 = peg$classExpectation(["\r", "\n"], true, false); + + var peg$f0 = function(head, tail) {return [head, ...tail].filter( e => e != '');}; + var peg$f1 = function() {return [];}; + var peg$f2 = function(characters) {return characters.join('');}; + var peg$f3 = function(characters) {return characters.join('');}; + var peg$f4 = function() { return '';}; + var peg$f5 = function() { return '';}; + var peg$currPos = 0; + var peg$savedPos = 0; + var peg$posDetailsCache = [{ line: 1, column: 1 }]; + var peg$maxFailPos = 0; + var peg$maxFailExpected = []; + var peg$silentFails = 0; + + var peg$resultsCache = {}; + + var peg$result; + + if ("startRule" in options) { + if (!(options.startRule in peg$startRuleFunctions)) { + throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); + } + + peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; + } + + function text() { + return input.substring(peg$savedPos, peg$currPos); + } + + function offset() { + return peg$savedPos; + } + + function range() { + return { + source: peg$source, + start: peg$savedPos, + end: peg$currPos + }; + } + + function location() { + return peg$computeLocation(peg$savedPos, peg$currPos); + } + + function expected(description, location) { + location = location !== undefined + ? location + : peg$computeLocation(peg$savedPos, peg$currPos); + + throw peg$buildStructuredError( + [peg$otherExpectation(description)], + input.substring(peg$savedPos, peg$currPos), + location + ); + } + + function error(message, location) { + location = location !== undefined + ? location + : peg$computeLocation(peg$savedPos, peg$currPos); + + throw peg$buildSimpleError(message, location); + } + + function peg$literalExpectation(text, ignoreCase) { + return { type: "literal", text: text, ignoreCase: ignoreCase }; + } + + function peg$classExpectation(parts, inverted, ignoreCase) { + return { type: "class", parts: parts, inverted: inverted, ignoreCase: ignoreCase }; + } + + function peg$anyExpectation() { + return { type: "any" }; + } + + function peg$endExpectation() { + return { type: "end" }; + } + + function peg$otherExpectation(description) { + return { type: "other", description: description }; + } + + function peg$computePosDetails(pos) { + var details = peg$posDetailsCache[pos]; + var p; + + if (details) { + return details; + } else { + p = pos - 1; + while (!peg$posDetailsCache[p]) { + p--; + } + + details = peg$posDetailsCache[p]; + details = { + line: details.line, + column: details.column + }; + + while (p < pos) { + if (input.charCodeAt(p) === 10) { + details.line++; + details.column = 1; + } else { + details.column++; + } + + p++; + } + + peg$posDetailsCache[pos] = details; + + return details; + } + } + + function peg$computeLocation(startPos, endPos) { + var startPosDetails = peg$computePosDetails(startPos); + var endPosDetails = peg$computePosDetails(endPos); + + return { + source: peg$source, + start: { + offset: startPos, + line: startPosDetails.line, + column: startPosDetails.column + }, + end: { + offset: endPos, + line: endPosDetails.line, + column: endPosDetails.column + } + }; + } + + function peg$fail(expected) { + if (peg$currPos < peg$maxFailPos) { return; } + + if (peg$currPos > peg$maxFailPos) { + peg$maxFailPos = peg$currPos; + peg$maxFailExpected = []; + } + + peg$maxFailExpected.push(expected); + } + + function peg$buildSimpleError(message, location) { + return new peg$SyntaxError(message, null, null, location); + } + + function peg$buildStructuredError(expected, found, location) { + return new peg$SyntaxError( + peg$SyntaxError.buildMessage(expected, found), + expected, + found, + location + ); + } + + function peg$parsestart() { + var s0, s1, s2, s3; + + var key = peg$currPos * 10 + 0; + var cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseincludes(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$parsenewLine(); + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$parsenewLine(); + } + s3 = peg$parseignore(); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseincludes() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 10 + 1; + var cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + s1 = peg$parseincludeStatement(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$currPos; + s4 = []; + s5 = peg$parsenewLine(); + if (s5 !== peg$FAILED) { + while (s5 !== peg$FAILED) { + s4.push(s5); + s5 = peg$parsenewLine(); + } + } else { + s4 = peg$FAILED; + } + if (s4 !== peg$FAILED) { + s5 = peg$parseincludeStatement(); + if (s5 !== peg$FAILED) { + s3 = s5; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$currPos; + s4 = []; + s5 = peg$parsenewLine(); + if (s5 !== peg$FAILED) { + while (s5 !== peg$FAILED) { + s4.push(s5); + s5 = peg$parsenewLine(); + } + } else { + s4 = peg$FAILED; + } + if (s4 !== peg$FAILED) { + s5 = peg$parseincludeStatement(); + if (s5 !== peg$FAILED) { + s3 = s5; + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } else { + peg$currPos = s3; + s3 = peg$FAILED; + } + } + peg$savedPos = s0; + s0 = peg$f0(s1, s2); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parseignore(); + peg$savedPos = s0; + s1 = peg$f1(); + s0 = s1; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseincludeStatement() { + var s0, s1, s2, s3, s4, s5; + + var key = peg$currPos * 10 + 2; + var cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 8) === peg$c0) { + s1 = peg$c0; + peg$currPos += 8; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e0); } + } + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$parse_(); + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$parse_(); + } + s3 = peg$parsestring(); + if (s3 !== peg$FAILED) { + s4 = []; + s5 = peg$parse_(); + while (s5 !== peg$FAILED) { + s4.push(s5); + s5 = peg$parse_(); + } + s0 = s3; + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + if (s0 === peg$FAILED) { + s0 = peg$parsecomment(); + if (s0 === peg$FAILED) { + s0 = peg$parsedelimitedComment(); + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsestring() { + var s0, s1, s2, s3, s4; + + var key = peg$currPos * 10 + 3; + var cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + peg$silentFails++; + s0 = peg$currPos; + s1 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 39) { + s2 = peg$c1; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e2); } + } + if (s2 !== peg$FAILED) { + s3 = []; + if (peg$r0.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e3); } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$r0.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e3); } + } + } + if (input.charCodeAt(peg$currPos) === 39) { + s4 = peg$c1; + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e2); } + } + if (s4 !== peg$FAILED) { + s1 = s3; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f2(s1); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 34) { + s2 = peg$c2; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e4); } + } + if (s2 !== peg$FAILED) { + s3 = []; + if (peg$r1.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e5); } + } + while (s4 !== peg$FAILED) { + s3.push(s4); + if (peg$r1.test(input.charAt(peg$currPos))) { + s4 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e5); } + } + } + if (input.charCodeAt(peg$currPos) === 34) { + s4 = peg$c2; + peg$currPos++; + } else { + s4 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e4); } + } + if (s4 !== peg$FAILED) { + s1 = s3; + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + } else { + peg$currPos = s1; + s1 = peg$FAILED; + } + if (s1 !== peg$FAILED) { + peg$savedPos = s0; + s1 = peg$f3(s1); + } + s0 = s1; + } + peg$silentFails--; + if (s0 === peg$FAILED) { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e1); } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseignore() { + var s0, s1; + + var key = peg$currPos * 10 + 4; + var cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = []; + s1 = peg$parseany(); + if (s1 === peg$FAILED) { + s1 = peg$parsenewLine(); + if (s1 === peg$FAILED) { + s1 = peg$parse_(); + } + } + while (s1 !== peg$FAILED) { + s0.push(s1); + s1 = peg$parseany(); + if (s1 === peg$FAILED) { + s1 = peg$parsenewLine(); + if (s1 === peg$FAILED) { + s1 = peg$parse_(); + } + } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsecomment() { + var s0, s1, s2, s3; + + var key = peg$currPos * 10 + 5; + var cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 2) === peg$c3) { + s1 = peg$c3; + peg$currPos += 2; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e6); } + } + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$parseany(); + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$parseany(); + } + peg$savedPos = s0; + s0 = peg$f4(); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsedelimitedComment() { + var s0, s1, s2, s3; + + var key = peg$currPos * 10 + 6; + var cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + s0 = peg$currPos; + if (input.substr(peg$currPos, 2) === peg$c4) { + s1 = peg$c4; + peg$currPos += 2; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e7); } + } + if (s1 !== peg$FAILED) { + s2 = []; + if (peg$r2.test(input.charAt(peg$currPos))) { + s3 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e8); } + } + while (s3 !== peg$FAILED) { + s2.push(s3); + if (peg$r2.test(input.charAt(peg$currPos))) { + s3 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e8); } + } + } + if (input.substr(peg$currPos, 2) === peg$c5) { + s3 = peg$c5; + peg$currPos += 2; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e9); } + } + if (s3 !== peg$FAILED) { + peg$savedPos = s0; + s0 = peg$f5(); + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + } else { + peg$currPos = s0; + s0 = peg$FAILED; + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parse_() { + var s0, s1; + + var key = peg$currPos * 10 + 7; + var cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + peg$silentFails++; + if (peg$r3.test(input.charAt(peg$currPos))) { + s0 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e11); } + } + peg$silentFails--; + if (s0 === peg$FAILED) { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e10); } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parsenewLine() { + var s0, s1; + + var key = peg$currPos * 10 + 8; + var cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + peg$silentFails++; + if (peg$r4.test(input.charAt(peg$currPos))) { + s0 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e13); } + } + peg$silentFails--; + if (s0 === peg$FAILED) { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e12); } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + function peg$parseany() { + var s0; + + var key = peg$currPos * 10 + 9; + var cached = peg$resultsCache[key]; + + if (cached) { + peg$currPos = cached.nextPos; + + return cached.result; + } + + if (peg$r5.test(input.charAt(peg$currPos))) { + s0 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e14); } + } + + peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; + + return s0; + } + + peg$result = peg$startRuleFunction(); + + if (peg$result !== peg$FAILED && peg$currPos === input.length) { + return peg$result; + } else { + if (peg$result !== peg$FAILED && peg$currPos < input.length) { + peg$fail(peg$endExpectation()); + } + + throw peg$buildStructuredError( + peg$maxFailExpected, + peg$maxFailPos < input.length ? input.charAt(peg$maxFailPos) : null, + peg$maxFailPos < input.length + ? peg$computeLocation(peg$maxFailPos, peg$maxFailPos + 1) + : peg$computeLocation(peg$maxFailPos, peg$maxFailPos) + ); + } +} + +module.exports = { + SyntaxError: peg$SyntaxError, + parse: peg$parse +}; diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.peggy b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.peggy new file mode 100644 index 00000000..25d69b93 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.peggy @@ -0,0 +1,41 @@ +// Includes are at the start of the file, before any other code. +// There might be some comments before or between the includes. +// #include "string" +// #include "string2" + + +start + = @includes newLine* ignore + +includes + = head:includeStatement tail:(newLine+ @includeStatement)* + {return [head, ...tail].filter( e => e != '');} + / ignore + {return [];} + +includeStatement + = '#include' _* @string _* + / comment + / delimitedComment + +string 'string' + = characters:("'" @([^'])* "'") {return characters.join('');} + / characters:('"' @([^"])* '"') {return characters.join('');} + +ignore = (any / newLine / _)* + +comment += '//'any* +{ return '';} + +delimitedComment += '/*' ([^*]*) '*/' +{ return '';} + +_ "white space" + = [ \t] + +newLine "newline" + = [\n\r] + +any = [^\r\n] diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ParseIncludes.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ParseIncludes.res new file mode 100644 index 00000000..347234a4 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ParseIncludes.res @@ -0,0 +1,8 @@ +@module("./ReducerProject_IncludeParser.js") external parse__: string => array = "parse" + +let parseIncludes = (expr: string): array => + try { + parse__(expr) + } catch { + | Js.Exn.Error(_obj) => [] + } diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectAccessors_T.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectAccessors_T.res new file mode 100644 index 00000000..d3becba9 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectAccessors_T.res @@ -0,0 +1,24 @@ +module ProjectItemT = ReducerProject_ProjectItem_T +module Bindings = Reducer_Bindings +module ExpressionT = Reducer_Expression_T +module InternalExpressionValue = ReducerInterface_InternalExpressionValue + +type projectAccessors = { + stdLib: Reducer_Bindings.t, + environment: ExpressionT.environment, + mutable continuation: ProjectItemT.continuationArgumentType, +} + +type t = projectAccessors + +let identityAccessors: t = { + continuation: Bindings.emptyBindings, + stdLib: ReducerInterface_StdLib.internalStdLib, + environment: InternalExpressionValue.defaultEnvironment, +} + +let identityAccessorsWithEnvironment = (environment): t => { + continuation: Bindings.emptyBindings, + stdLib: ReducerInterface_StdLib.internalStdLib, + environment: environment, +} diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res new file mode 100644 index 00000000..c07cebad --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res @@ -0,0 +1,176 @@ +// 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({ + source: "", + rawParse: None, + expression: None, + continuation: Bindings.emptyBindings, + result: None, + continues: [], + includes: []->Ok, +}) +// source -> rawParse -> includes -> expression -> continuation -> externalBindings -> result -> externalResult + +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 toExternalBindings = continuation => + continuation->InternalExpressionValue.nameSpaceToTypeScriptBindings +let getResult = (T.ProjectItem(r)): T.resultType => r.result +let getExternalResult = (T.ProjectItem(r)): T.externalResultType => + r.result->Belt.Option.map(opt => + opt->Belt.Result.map(value => value->InternalExpressionValue.toExternal) + ) + +let getContinues = (T.ProjectItem(r)): T.continuesType => r.continues +let getIncludes = (T.ProjectItem(r)): T.includesType => r.includes + +let touchSource = (this: t): t => { + let T.ProjectItem(r) = emptyItem + T.ProjectItem({ + ...r, + includes: getIncludes(this), + continues: getContinues(this), + source: getSource(this), + }) +} +let touchRawParse = (this: t): t => { + let T.ProjectItem(r) = emptyItem + T.ProjectItem({ + ...r, + continues: getContinues(this), + source: getSource(this), + rawParse: getRawParse(this), + includes: getIncludes(this), + }) +} +let touchExpression = (this: t): t => { + let T.ProjectItem(r) = emptyItem + T.ProjectItem({ + ...r, + continues: getContinues(this), + source: getSource(this), + rawParse: getRawParse(this), + includes: getIncludes(this), + expression: getExpression(this), + }) +} + +let setSource = (T.ProjectItem(r): t, source: T.sourceArgumentType): t => + T.ProjectItem({...r, source: source})->touchSource + +let setRawParse = (T.ProjectItem(r): t, rawParse: T.rawParseArgumentType): t => + T.ProjectItem({...r, rawParse: Some(rawParse)})->touchRawParse + +let setExpression = (T.ProjectItem(r): t, expression: T.expressionArgumentType): t => + T.ProjectItem({...r, expression: Some(expression)})->touchExpression + +let setContinuation = (T.ProjectItem(r): t, continuation: T.continuationArgumentType): t => { + T.ProjectItem({...r, continuation: continuation}) +} + +let setResult = (T.ProjectItem(r): t, result: T.resultArgumentType): t => T.ProjectItem({ + ...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), + }) +} + +let getImmediateDependencies = (this: t): T.includesType => + getIncludes(this)->Belt.Result.map(Js.Array2.concat(_, 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 setIncludes = (T.ProjectItem(r): t, includes: T.includesType): t => T.ProjectItem({ + ...r, + includes: includes, +}) + +//TODO: forward parse errors to the user +let parseIncludes = (this: t): t => + setIncludes(this, getSource(this)->ReducerProject_ParseIncludes.parseIncludes->Ok) + +let doRawParse = (this: t): T.rawParseArgumentType => this->getSource->Reducer_Peggy_Parse.parse + +let rawParse = (this: t): t => + this->getRawParse->E.O2.defaultFn(() => doRawParse(this))->setRawParse(this, _) + +let doBuildExpression = (this: t): T.expressionType => + this + ->getRawParse + ->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 + | None => + withRawParse + ->doBuildExpression + ->Belt.Option.map(setExpression(withRawParse, _)) + ->E.O2.defaultFn(() => withRawParse) + } +} + +let wrappedReducer = ( + rExpression: T.expressionArgumentType, + aContinuation: T.continuation, + accessors: ProjectAccessorsT.t, +): T.resultArgumentType => { + Belt.Result.flatMap( + rExpression, + Reducer_Expression.reduceExpressionInProject(_, aContinuation, accessors), + ) +} + +let doBuildResult = ( + this: t, + aContinuation: T.continuation, + accessors: ProjectAccessorsT.t, +): T.resultType => + this + ->getExpression + ->Belt.Option.map( + Belt.Result.flatMap( + _, + Reducer_Expression.reduceExpressionInProject(_, aContinuation, accessors), + ), + ) + +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 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 new file mode 100644 index 00000000..5d0846cf --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem_T.res @@ -0,0 +1,39 @@ +module Parse = Reducer_Peggy_Parse +module ExpressionT = Reducer_Expression_T +module InternalExpressionValue = ReducerInterface_InternalExpressionValue +module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue +open Reducer_ErrorValue + +type sourceArgumentType = string +type sourceType = string +type rawParseArgumentType = result +type rawParseType = option +type expressionArgumentType = result +type expressionType = option +type continuation = InternalExpressionValue.nameSpace +type continuationArgumentType = InternalExpressionValue.nameSpace +type continuationType = option +type continuationResultType = option> +type externalBindingsArgumentType = ExternalExpressionValue.record +type externalBindingsType = option +type resultArgumentType = result +type resultType = option +type externalResultArgumentType = result +type externalResultType = option +type continuesArgumentType = array +type continuesType = array +type includesArgumentType = string +type includesType = result, errorValue> + +type projectItem = + | ProjectItem({ + source: sourceType, + rawParse: rawParseType, + expression: expressionType, + continuation: continuationArgumentType, + result: resultType, + continues: continuesType, + includes: includesType, + }) + +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 new file mode 100644 index 00000000..0b401fcb --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ReducerFn_T.res @@ -0,0 +1,9 @@ +module ExpressionT = Reducer_Expression_T +module InternalExpressionValue = ReducerInterface_InternalExpressionValue +module ProjectAccessorsT = ReducerProject_ProjectAccessors_T + +type t = ( + ExpressionT.t, + ExpressionT.bindings, + ProjectAccessorsT.t, +) => result diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res new file mode 100644 index 00000000..9acaa74e --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res @@ -0,0 +1,25 @@ +module ProjectItem = ReducerProject_ProjectItem +module ExpressionT = Reducer_Expression_T +module ProjectAccessorsT = ReducerProject_ProjectAccessors_T + +type project = Object +type t = project + +module Private = { + type internalProject = { + "items": Belt.Map.String.t, + "stdLib": Reducer_Bindings.t, + "environment": ExpressionT.environment, + } + type t = internalProject + + @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 = "stdLib" + + external castFromInternalProject: t => project = "%identity" + external castToInternalProject: project => t = "%identity" +} diff --git a/packages/squiggle-lang/src/rescript/TypescriptInterface.res b/packages/squiggle-lang/src/rescript/TypescriptInterface.res index a1f5afe6..64629731 100644 --- a/packages/squiggle-lang/src/rescript/TypescriptInterface.res +++ b/packages/squiggle-lang/src/rescript/TypescriptInterface.res @@ -34,17 +34,17 @@ type resultString = result @genType let makeSampleSetDist = SampleSetDist.make -@genType -let evaluate = Reducer.evaluate +// @genType +// let evaluate = Reducer.evaluate -@genType -let evaluateUsingOptions = Reducer.evaluateUsingOptions +// @genType +// let evaluateUsingOptions = Reducer.evaluateUsingOptions @genType let parse = Reducer_Peggy_Parse.parse -@genType -let evaluatePartialUsingExternalBindings = Reducer.evaluatePartialUsingExternalBindings +// @genType +// let evaluatePartialUsingExternalBindings = Reducer.evaluatePartialUsingExternalBindings @genType type externalBindings = Reducer.externalBindings @@ -91,8 +91,8 @@ type environment = ReducerInterface_ExternalExpressionValue.environment @genType let defaultEnvironment = ReducerInterface_ExternalExpressionValue.defaultEnvironment -@genType -let foreignFunctionInterface = Reducer.foreignFunctionInterface +// @genType +// let foreignFunctionInterface = Reducer.foreignFunctionInterface @genType type declarationArg = Declaration.arg From f21725d86cd7b418dba6e9cf66b6915881fc1eed Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Wed, 10 Aug 2022 12:09:06 +0200 Subject: [PATCH 02/53] remove TODO --- .../__tests__/ReducerProject/ReducerProject_test.res | 3 --- 1 file changed, 3 deletions(-) diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res index cea3d777..c6605068 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res @@ -174,6 +174,3 @@ describe("project with include", () => { }) }) -// test bindings -//TODO: test continues -//TODO: test include From 0c1c5c94995a667ff5d0f4bee3ea0f9633d01fee Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Sun, 14 Aug 2022 16:14:14 +0200 Subject: [PATCH 03/53] seperate Project Topology Module --- .../ReducerProject/ReducerProject_test.res | 1 - .../ReducerProject/ReducerProject.res | 81 +++---------------- .../ReducerProject/ReducerProject_T.res | 5 ++ .../ReducerProject_Topology.res | 72 +++++++++++++++++ 4 files changed, 86 insertions(+), 73 deletions(-) create mode 100644 packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_Topology.res diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res index c6605068..466a8770 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res @@ -173,4 +173,3 @@ describe("project with include", () => { runFetchBindings(project, "main")->expect->toBe("@{common: 0,x: 1,y: 2}") }) }) - diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res index 8a78c795..11fa62bf 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res @@ -9,6 +9,7 @@ module InternalExpressionValue = ReducerInterface_InternalExpressionValue module ProjectAccessorsT = ReducerProject_ProjectAccessors_T module ProjectItem = ReducerProject_ProjectItem module T = ReducerProject_T +module Topology = ReducerProject_Topology @genType.opaque type project = T.t @@ -18,59 +19,12 @@ module Private = { type internalProject = T.Private.t type t = T.Private.t - 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 getImmediateDependencies = (this: t, sourceId: string): ProjectItem.T.includesType => - getItem(this, sourceId)->ProjectItem.getImmediateDependencies - - type topologicalSortState = (Belt.Map.String.t, list) - let rec topologicalSortUtil = ( - this: t, - sourceId: string, - state: topologicalSortState, - ): topologicalSortState => { - let dependencies = getImmediateDependencies(this, sourceId)->Belt.Result.getWithDefault([]) - let (visited, stack) = state - let myVisited = Belt.Map.String.set(visited, sourceId, true) - let (newVisited, newStack) = dependencies->Belt.Array.reduce((myVisited, stack), ( - (currVisited, currStack), - dependency, - ) => { - if !Belt.Map.String.getWithDefault(currVisited, dependency, false) { - topologicalSortUtil(this, dependency, (currVisited, currStack)) - } else { - (currVisited, currStack) - } - }) - (newVisited, list{sourceId, ...newStack}) - } - - let getTopologicalSort = (this: t): array => { - let (_visited, stack) = getSourceIds(this)->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 - } - - let getTopologicalSortFor = (this: t, sourceId) => { - let runOrder = getTopologicalSort(this) - let index = runOrder->Js.Array2.indexOf(sourceId) - let after = Belt.Array.sliceToEnd(runOrder, index + 1) - let before = Js.Array2.slice(runOrder, ~start=0, ~end_=index + 1) - (before, after) - } - - let getRunOrder = getTopologicalSort + 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 this: t = { @@ -81,23 +35,6 @@ module Private = { this } - let getRunOrderFor = (this: t, sourceId: string) => { - let (runOrder, _) = getTopologicalSortFor(this, sourceId) - runOrder - } - - let getDependencies = (this: t, sourceId: string): array => { - let runOrder = getRunOrderFor(this, sourceId) - - let _ = Js.Array2.pop(runOrder) - runOrder - } - - let getDependents = (this: t, sourceId: string): array => { - let (_, dependents) = getTopologicalSortFor(this, sourceId) - dependents - } - let rec touchSource = (this: t, sourceId: string): unit => { let item = this->getItem(sourceId) let newItem = ProjectItem.touchSource(item) @@ -245,7 +182,7 @@ module Private = { } let runAll = (this: t): unit => { - let runOrder = getTopologicalSort(this) + let runOrder = Topology.getRunOrder(this) let initialState = (Ok(InternalExpressionValue.IEvVoid), getStdLib(this)) let _finalState = Belt.Array.reduce(runOrder, initialState, (currState, currId) => tryRunWithContinuation(this, currId, currState) @@ -253,7 +190,7 @@ module Private = { } let run = (this: t, sourceId: string): unit => { - let runOrder = getRunOrderFor(this, sourceId) + let runOrder = Topology.getRunOrderFor(this, sourceId) let initialState = (Ok(InternalExpressionValue.IEvVoid), getStdLib(this)) let _finalState = Belt.Array.reduce(runOrder, initialState, (currState, currId) => tryRunWithContinuation(this, currId, currState) diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res index 9acaa74e..9e14c70c 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res @@ -22,4 +22,9 @@ module Private = { 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) } diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_Topology.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_Topology.res new file mode 100644 index 00000000..f23c19c1 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_Topology.res @@ -0,0 +1,72 @@ +module ProjectItem = ReducerProject_ProjectItem +module T = ReducerProject_T +type t = T.Private.t + +let getSourceIds = T.Private.getSourceIds +let getItem = T.Private.getItem + +let getImmediateDependencies = (this: t, sourceId: string): ProjectItem.T.includesType => + getItem(this, sourceId)->ProjectItem.getImmediateDependencies + +type topologicalSortState = (Belt.Map.String.t, list) +let rec topologicalSortUtil = ( + this: t, + sourceId: string, + state: topologicalSortState, +): topologicalSortState => { + let dependencies = getImmediateDependencies(this, sourceId)->Belt.Result.getWithDefault([]) + let (visited, stack) = state + let myVisited = Belt.Map.String.set(visited, sourceId, true) + let (newVisited, newStack) = dependencies->Belt.Array.reduce((myVisited, stack), ( + (currVisited, currStack), + dependency, + ) => { + if !Belt.Map.String.getWithDefault(currVisited, dependency, false) { + topologicalSortUtil(this, dependency, (currVisited, currStack)) + } else { + (currVisited, currStack) + } + }) + (newVisited, list{sourceId, ...newStack}) +} + +let getTopologicalSort = (this: t): array => { + let (_visited, stack) = getSourceIds(this)->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 +} + +let getTopologicalSortFor = (this: t, sourceId) => { + let runOrder = getTopologicalSort(this) + let index = runOrder->Js.Array2.indexOf(sourceId) + let after = Belt.Array.sliceToEnd(runOrder, index + 1) + let before = Js.Array2.slice(runOrder, ~start=0, ~end_=index + 1) + (before, after) +} + +let getRunOrder = getTopologicalSort + +let getRunOrderFor = (this: t, sourceId: string) => { + let (runOrder, _) = getTopologicalSortFor(this, sourceId) + runOrder +} + +let getDependencies = (this: t, sourceId: string): array => { + let runOrder = getRunOrderFor(this, sourceId) + + let _ = Js.Array2.pop(runOrder) + runOrder +} + +let getDependents = (this: t, sourceId: string): array => { + let (_, dependents) = getTopologicalSortFor(this, sourceId) + dependents +} From 9075b74536ce7bbb3ffe5e90b0ef063e1c699665 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Sun, 14 Aug 2022 17:34:18 +0200 Subject: [PATCH 04/53] Edit comments --- .../ReducerProject/ReducerProject.res | 126 +++++++++++++----- 1 file changed, 95 insertions(+), 31 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res index 11fa62bf..44cafc0b 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res @@ -1,4 +1,3 @@ -// TODO: Restore run FFI? // TODO: Auto clean project based on topology module Bindings = Reducer_Bindings @@ -212,102 +211,167 @@ module Private = { PUBLIC FUNCTIONS */ -// Create a new this to hold the sources, executables, bindings and other data. -// The this is a mutable object for use in TypeScript. +/* +Creates a new project to hold the sources, executables, bindings, and other data. +The new project runs the sources according to their topological sorting because of the includes and continues. + +Any source can include or continue other sources. "Therefore, the project is a graph data structure." +The difference between including and continuing is that includes are stated inside the source code while continues are stated in the project. + +To run a group of source codes and get results/bindings, the necessary methods are +- setSource +- setContinues +- parseIncludes +- run or runAll +- getExternalBindings +- getExternalResult +*/ let createProject = (): t => Private.createProject()->T.Private.castFromInternalProject -// Answers the array of existing source ids to enumerate over. +/* +Answer all the source ids of all the sources in the project. +*/ let getSourceIds = (this: t): array => this->T.Private.castToInternalProject->Private.getSourceIds -// Sets the source for a given source id. +/* +Sets the source for a given source Id. +*/ let setSource = (this: t, sourceId: string, value: string): unit => this->T.Private.castToInternalProject->Private.setSource(sourceId, value) -// Gets the source for a given source id. +/* +Gets the source for a given source id. +*/ let getSource = (this: t, sourceId: string): option => this->T.Private.castToInternalProject->Private.getSource(sourceId) -// Touches the source for a given source id. This forces the dependency graph to be re-evaluated. -// Touching source code clears the includes so that they can be reevaluated. +/* +Touches the source for a given source id. This and dependent, sources are set to be re-evaluated. +*/ let touchSource = (this: t, sourceId: string): unit => this->T.Private.castToInternalProject->Private.touchSource(sourceId) -// Cleans the compilation artifacts for a given source id. The results stay untouched. +/* +Cleans the compilation artifacts for a given source ID. The results stay untouched, so compilation won't be run again. + +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 +*/ let clean = (this: t, sourceId: string): unit => this->T.Private.castToInternalProject->Private.clean(sourceId) -// Cleans all compilation artifacts for all the this. The results stay untouched. +/* +Cleans all the compilation artifacts in all of the project +*/ let cleanAll = (this: t): unit => this->T.Private.castToInternalProject->Private.cleanAll -// Cleans results. Compilation stays untouched to rerun the source. +/* +Cleans results. Compilation stays untouched to be able to re-run the source. +You would not do this if you were not trying to debug the source code. +*/ let cleanResults = (this: t, sourceId: string): unit => this->T.Private.castToInternalProject->Private.cleanResults(sourceId) -// Cleans all results. Compilations stays untouched to rerun the source. +/* +Cleans all results. Compilations remains untouched to rerun the source. +*/ let cleanAllResults = (this: t): unit => this->T.Private.castToInternalProject->Private.cleanAllResults +/* +To set the includes one first has to call "parseIncludes". The parsed includes or the parser error is returned. +*/ let getIncludes = (this: t, sourceId: string): ProjectItem.T.includesType => this->T.Private.castToInternalProject->Private.getIncludes(sourceId) +/* +Answers the source codes after which this source code is continuing +*/ let getContinues = (this: t, sourceId: string): array => this->T.Private.castToInternalProject->Private.getContinues(sourceId) -// setContinues acts like an include hidden in the source. It is used to define a continuation. +/* + "continues" acts like hidden includes in the source. + It is used to define a continuation that is not visible in the source code. + You can chain source codes on the web interface for example +*/ let setContinues = (this: t, sourceId: string, continues: array): unit => this->T.Private.castToInternalProject->Private.setContinues(sourceId, continues) -// This source is not continuing any other source. It is a standalone source. -// Touches this source also. +/* +Break the continuation chain. This source will become a standalone source. +*/ let removeContinues = (this: t, sourceId: string): unit => this->T.Private.castToInternalProject->Private.removeContinues(sourceId) -// Gets includes and continues for a given source id. SourceId is depending on them +/* +This source depends on the array of sources returned. +*/ let getDependencies = (this: t, sourceId: string): array => this->T.Private.castToInternalProject->Private.getDependencies(sourceId) -// Get source ids depending on a given source id. +/* +The sources returned are dependent on this +*/ let getDependents = (this: t, sourceId: string): array => this->T.Private.castToInternalProject->Private.getDependents(sourceId) -// Get run order for all sources. It is a topological sort of the dependency graph. +/* +Get the run order for the sources in the project. +*/ let getRunOrder = (this: t) => this->T.Private.castToInternalProject->Private.getRunOrder -// Get run order for a given source id. It is a topological sort of the dependency graph. +/* +Get the run order to get the results of this specific source +*/ let getRunOrderFor = (this: t, sourceId: string) => this->T.Private.castToInternalProject->Private.getRunOrderFor(sourceId) -// Parse includes so that you can load them before running. Use getIncludes to get the includes. -// It is your responsibility to load the includes before running. +/* +Parse includes so that you can load them before running. +Load includes by calling getIncludes which returns the includes that have been parsed. +It is your responsibility to load the includes before running. +*/ let parseIncludes = (this: t, sourceId: string): unit => this->T.Private.castToInternalProject->Private.parseIncludes(sourceId) -// Parse the source code if it is not done already. Use getRawParse to get the parse tree +/* +Parse the source code if it is not done already. +Use getRawParse to get the parse tree. +You would need this function if you want to see the parse tree without running the source code. +*/ let rawParse = (this: t, sourceId: string): unit => this->T.Private.castToInternalProject->Private.rawParse(sourceId) -// Runs the source code. -// The code is parsed if it is not already done. -// If it continues/includes another source then it will run that source also if is not already done. +/* +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. +*/ let run = (this: t, sourceId: string): unit => this->T.Private.castToInternalProject->Private.run(sourceId) -// Runs all the sources. +/* +Runs all of the sources in a project. Their results and bindings will be available +*/ let runAll = (this: t): unit => this->T.Private.castToInternalProject->Private.runAll -// WARNING" getExternalBindings will be deprecated. Cyclic directed graph problems -// Get the bindings after running the source code. +/* +Get the bindings after running this source file or the project +*/ let getExternalBindings = (this: t, sourceId: string): ExternalExpressionValue.record => this->T.Private.castToInternalProject->Private.getExternalBindings(sourceId) -//WARNING: externalResult will be deprecated. Cyclic directed graph problems +/* +Get the result after running this source file or the project +*/ let getExternalResult = (this: t, sourceId: string): option< result, > => this->T.Private.castToInternalProject->Private.getExternalResult(sourceId) -// This is a convenience function to get the result of a single source. -// You cannot use includes +/* +This is a convenience function to get the result of a single source without creating a project. +However, without a project, you cannot handle include directives. +The source has to be include free +*/ let evaluate = (sourceCode: string): ('r, 'b) => { let (result, continuation) = Private.evaluate(sourceCode) ( From 66f2f18a004dae56a6c98f9f5f574080bb89ff38 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 15 Aug 2022 14:45:45 +0200 Subject: [PATCH 05/53] fix merging develop --- .../Reducer_Type_switch_replacement_test.res | 26 +++++++++++-------- .../Reducer_Dispatch_ChainPiece.res | 10 ++++--- .../Reducer_Dispatch/Reducer_Dispatch_T.res | 10 ++++--- .../Reducer_Type/Reducer_Type_Compile.res | 2 +- 4 files changed, 29 insertions(+), 19 deletions(-) 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 16f0f118..9dbe08c5 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 @@ -4,8 +4,11 @@ open Expect module DispatchT = Reducer_Dispatch_T module Expression = Reducer_Expression module ExpressionT = Reducer_Expression_T -module TypeCompile = Reducer_Type_Compile +module ProjectAccessorsT = ReducerProject_ProjectAccessors_T +module ProjectReducerFnT = ReducerProject_ReducerFn_T module TypeChecker = Reducer_Type_TypeChecker +module TypeCompile = Reducer_Type_Compile + open ReducerInterface_InternalExpressionValue type errorValue = Reducer_ErrorValue.errorValue @@ -14,13 +17,14 @@ type errorValue = Reducer_ErrorValue.errorValue // 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, environment): option> +// 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: ExpressionT.reducerFn): DispatchT.dispatchChainPiece => { +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) @@ -45,15 +49,15 @@ let makeMyDispatchChainPiece = (reducer: ExpressionT.reducerFn): DispatchT.dispa // Let's bridge the pure implementation to expression values module Bridge = { - let stringConcat: DispatchT.genericIEvFunction = (args, _environment) => { + let stringConcat: DispatchT.genericIEvFunction = (args, _accessors: ProjectAccessorsT.t) => { let (a, b) = extractStringString(args) Implementation.stringConcat(a, b)->IEvString->Ok } - let arrayConcat: DispatchT.genericIEvFunction = (args, _environment) => { + let arrayConcat: DispatchT.genericIEvFunction = (args, _accessors: ProjectAccessorsT.t) => { let (a, b) = extractArrayArray(args) Implementation.arrayConcat(a, b)->IEvArray->Ok } - let plot: DispatchT.genericIEvFunction = (args, _environment) => { + 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 @@ -98,12 +102,12 @@ let makeMyDispatchChainPiece = (reducer: ExpressionT.reducerFn): DispatchT.dispa // Exactly the same as the one used in real life let _dispatch = ( call: functionCall, - environment, - reducer: Reducer_Expression_T.reducerFn, + accessors: ProjectAccessorsT.t, + reducer: ProjectReducerFnT.t, chain, ): result => { let dispatchChainPiece = makeMyDispatchChainPiece(reducer) - dispatchChainPiece(call, environment)->E.O2.defaultFn(() => chain(call, environment, reducer)) + dispatchChainPiece(call, accessors)->E.O2.defaultFn(() => chain(call, accessors, reducer)) } // What is important about this implementation? @@ -112,12 +116,12 @@ let _dispatch = ( // B) Complicated recursive record types are not a problem. describe("Type Dispatch", () => { - let reducerFn = Expression.reduceExpression + let reducerFn = Expression.reduceExpressionInProject let dispatchChainPiece = makeMyDispatchChainPiece(reducerFn) test("stringConcat", () => { let call: functionCall = ("concat", [IEvString("hello"), IEvString("world")]) - let result = dispatchChainPiece(call, defaultEnvironment) + let result = dispatchChainPiece(call, ProjectAccessorsT.identityAccessors) expect(result)->toEqual(Some(Ok(IEvString("helloworld")))) }) }) 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 6cebfef5..310f4879 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,17 +1,21 @@ -module TypeChecker = Reducer_Type_TypeChecker +module ProjectAccessorsT = ReducerProject_ProjectAccessors_T module T = Reducer_Dispatch_T +module TypeChecker = Reducer_Type_TypeChecker open ReducerInterface_InternalExpressionValue type errorValue = Reducer_ErrorValue.errorValue let makeFromTypes = jumpTable => { - let dispatchChainPiece: T.dispatchChainPiece = ((fnName, fnArgs): functionCall, environment) => { + 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, environment)->Some + | Some((_, _, bridgeFn)) => bridgeFn(fnArgs, accessors)->Some | _ => None } } 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 f6234976..68b8f789 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,20 +1,22 @@ module InternalExpressionValue = ReducerInterface_InternalExpressionValue module ExpressionT = Reducer_Expression_T +module ProjectAccessorsT = ReducerProject_ProjectAccessors_T +module ProjectReducerFnT = ReducerProject_ReducerFn_T // Each piece of the dispatch chain computes the result or returns None so that the chain can continue type dispatchChainPiece = ( InternalExpressionValue.functionCall, - InternalExpressionValue.environment, + ProjectAccessorsT.t, ) => option> type dispatchChainPieceWithReducer = ( InternalExpressionValue.functionCall, - InternalExpressionValue.environment, - ExpressionT.reducerFn, + ProjectAccessorsT.t, + ProjectReducerFnT.t, ) => option> // This is a switch statement case implementation: get the arguments and compute the result type genericIEvFunction = ( array, - InternalExpressionValue.environment, + ProjectAccessorsT.t, ) => result 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 25c6c0ee..b091782c 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 @@ -38,7 +38,7 @@ let fromTypeExpression = (typeExpressionSourceCode: string, reducerFn: ProjectRe let fromTypeExpressionExn = ( typeExpressionSourceCode: string, - reducerFn: ExpressionT.reducerFn, + reducerFn: ProjectReducerFnT.t, ): T.t => switch fromTypeExpression(typeExpressionSourceCode, reducerFn) { | Ok(value) => value From 1b69ce3aa16500bbcb32f35027ece16f080409f9 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 15 Aug 2022 15:18:14 +0200 Subject: [PATCH 06/53] compatibility to change environment at runtime There will be changes in develop to change environment at runtime. This fix provides compatibility. So that they can be merged easier. --- .../Reducer_Dispatch_BuiltIn.res | 2 +- .../Reducer_Expression/Reducer_Expression.res | 3 ++- .../Reducer_Type/Reducer_Type_Compile.res | 2 +- .../ReducerProject/ReducerProject.res | 5 +++-- .../ReducerProject_ProjectAccessors_T.res | 22 ++++++++++++++++--- 5 files changed, 26 insertions(+), 8 deletions(-) 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 b1ae2e41..1e8b19d0 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 @@ -104,7 +104,7 @@ let callInternal = ( let doDumpBindings = (continuation: nameSpace, value: internalExpressionValue) => { // let _ = Continuation.inspect(continuation, "doDumpBindings") - accessors.continuation = continuation + accessors.states.continuation = continuation value->Ok } 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 3e476403..b262a327 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 @@ -107,8 +107,9 @@ let reduceReturningBindings = ( continuation: T.bindings, accessors: ProjectAccessorsT.t, ): (result, T.bindings) => { + let states = accessors.states let result = reduceExpressionInProject(expression, continuation, accessors) - (result, accessors.continuation) + (result, states.continuation) } module BackCompatible = { 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 b091782c..79153801 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 @@ -16,7 +16,7 @@ let ievFromTypeExpression = ( Reducer_Expression.BackCompatible.parse(sourceCode)->Belt.Result.flatMap(expr => { let accessors = ProjectAccessorsT.identityAccessors let result = reducerFn(expr, Bindings.emptyBindings, accessors) - let nameSpace = accessors.continuation + let nameSpace = accessors.states.continuation switch result { | Ok(_) => diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res index 44cafc0b..9244c515 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res @@ -138,7 +138,7 @@ module Private = { } let buildProjectAccessors = (this: t): ProjectAccessorsT.t => { - continuation: Bindings.emptyBindings, + states: {continuation: Bindings.emptyBindings}, stdLib: getStdLib(this), environment: getEnvironment(this), } @@ -149,9 +149,10 @@ module Private = { continuation: ProjectItem.T.continuation, ): unit => { let accessors = buildProjectAccessors(this) + let states = accessors.states let newItem = this->getItem(sourceId)->ProjectItem.run(continuation, accessors) Belt.Map.String.set(this["items"], sourceId, newItem)->T.Private.setFieldItems(this, _) - setContinuation(this, sourceId, accessors.continuation) + setContinuation(this, sourceId, states.continuation) } type runState = (ProjectItem.T.resultArgumentType, ProjectItem.T.continuation) 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 d3becba9..9cc06e8f 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectAccessors_T.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectAccessors_T.res @@ -3,22 +3,38 @@ module Bindings = Reducer_Bindings module ExpressionT = Reducer_Expression_T module InternalExpressionValue = ReducerInterface_InternalExpressionValue +type states = {mutable continuation: ProjectItemT.continuationArgumentType} + type projectAccessors = { stdLib: Reducer_Bindings.t, environment: ExpressionT.environment, - mutable continuation: ProjectItemT.continuationArgumentType, + states: states, } type t = projectAccessors let identityAccessors: t = { - continuation: Bindings.emptyBindings, + // 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 identityAccessorsWithEnvironment = (environment): t => { - continuation: Bindings.emptyBindings, + 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, + } +} From ee17bd9e57554c2b8afd189a6c3a7b410dbbd49a Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Tue, 16 Aug 2022 01:51:01 +0200 Subject: [PATCH 07/53] more typescript friendly & remove an unnecessary call --- .../ReducerProject/ReducerProject.res | 45 ++++++++++++++----- .../ReducerProject/ReducerProject_T.res | 3 +- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res index 9244c515..3a990326 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res @@ -10,8 +10,8 @@ module ProjectItem = ReducerProject_ProjectItem module T = ReducerProject_T module Topology = ReducerProject_Topology -@genType.opaque type project = T.t +@genType.opaque type t = T.t module Private = { @@ -27,6 +27,7 @@ module Private = { let createProject = () => { let this: t = { + "tag": "reducerProject", "items": Belt.Map.String.empty, "stdLib": ReducerInterface_StdLib.internalStdLib, "environment": InternalExpressionValue.defaultEnvironment, @@ -226,30 +227,38 @@ To run a group of source codes and get results/bindings, the necessary methods a - run or runAll - getExternalBindings - getExternalResult + +A project has a public field tag with a constant value "reducerProject" +project = {tag: "reducerProject"} */ +@genType let createProject = (): t => Private.createProject()->T.Private.castFromInternalProject /* Answer all the source ids of all the sources in the project. */ +@genType let getSourceIds = (this: t): array => this->T.Private.castToInternalProject->Private.getSourceIds /* Sets the source for a given source Id. */ +@genType let setSource = (this: t, sourceId: string, value: string): unit => this->T.Private.castToInternalProject->Private.setSource(sourceId, value) /* Gets the source for a given source id. */ +@genType let getSource = (this: t, sourceId: string): option => this->T.Private.castToInternalProject->Private.getSource(sourceId) /* Touches the source for a given source id. This and dependent, sources are set to be re-evaluated. */ +@genType let touchSource = (this: t, sourceId: string): unit => this->T.Private.castToInternalProject->Private.touchSource(sourceId) @@ -258,36 +267,44 @@ 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 = (this: t, sourceId: string): unit => this->T.Private.castToInternalProject->Private.clean(sourceId) /* Cleans all the compilation artifacts in all of the project */ +@genType let cleanAll = (this: t): unit => this->T.Private.castToInternalProject->Private.cleanAll /* Cleans results. Compilation stays untouched to be able to re-run the source. You would not do this if you were not trying to debug the source code. */ +@genType let cleanResults = (this: t, sourceId: string): unit => this->T.Private.castToInternalProject->Private.cleanResults(sourceId) /* Cleans all results. Compilations remains untouched to rerun the source. */ +@genType let cleanAllResults = (this: t): unit => this->T.Private.castToInternalProject->Private.cleanAllResults /* To set the includes one first has to call "parseIncludes". The parsed includes or the parser error is returned. */ -let getIncludes = (this: t, sourceId: string): ProjectItem.T.includesType => - this->T.Private.castToInternalProject->Private.getIncludes(sourceId) +@genType +let getIncludes = (this: t, sourceId: string): result< + array, + Reducer_ErrorValue.errorValue, +> => this->T.Private.castToInternalProject->Private.getIncludes(sourceId) /* Answers the source codes after which this source code is continuing */ +@genType let getContinues = (this: t, sourceId: string): array => this->T.Private.castToInternalProject->Private.getContinues(sourceId) @@ -296,35 +313,35 @@ let getContinues = (this: t, sourceId: string): array => It is used to define a continuation that is not visible in the source code. You can chain source codes on the web interface for example */ +@genType let setContinues = (this: t, sourceId: string, continues: array): unit => this->T.Private.castToInternalProject->Private.setContinues(sourceId, continues) -/* -Break the continuation chain. This source will become a standalone source. -*/ -let removeContinues = (this: t, sourceId: string): unit => - this->T.Private.castToInternalProject->Private.removeContinues(sourceId) - /* This source depends on the array of sources returned. */ +@genType let getDependencies = (this: t, sourceId: string): array => this->T.Private.castToInternalProject->Private.getDependencies(sourceId) /* The sources returned are dependent on this */ +@genType let getDependents = (this: t, sourceId: string): array => this->T.Private.castToInternalProject->Private.getDependents(sourceId) /* Get the run order for the sources in the project. */ -let getRunOrder = (this: t) => this->T.Private.castToInternalProject->Private.getRunOrder +@genType +let getRunOrder = (this: t): array => + this->T.Private.castToInternalProject->Private.getRunOrder /* Get the run order to get the results of this specific source */ +@genType let getRunOrderFor = (this: t, sourceId: string) => this->T.Private.castToInternalProject->Private.getRunOrderFor(sourceId) @@ -333,6 +350,7 @@ Parse includes so that you can load them before running. Load includes by calling getIncludes which returns the includes that have been parsed. It is your responsibility to load the includes before running. */ +@genType let parseIncludes = (this: t, sourceId: string): unit => this->T.Private.castToInternalProject->Private.parseIncludes(sourceId) @@ -341,29 +359,34 @@ Parse the source code if it is not done already. Use getRawParse to get the parse tree. You would need this function if you want to see the parse tree without running the source code. */ +@genType let rawParse = (this: t, sourceId: string): unit => this->T.Private.castToInternalProject->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 = (this: t, sourceId: string): unit => this->T.Private.castToInternalProject->Private.run(sourceId) /* Runs all of the sources in a project. Their results and bindings will be available */ +@genType let runAll = (this: t): unit => this->T.Private.castToInternalProject->Private.runAll /* Get the bindings after running this source file or the project */ +@genType let getExternalBindings = (this: t, sourceId: string): ExternalExpressionValue.record => this->T.Private.castToInternalProject->Private.getExternalBindings(sourceId) /* Get the result after running this source file or the project */ +@genType let getExternalResult = (this: t, sourceId: string): option< result, > => this->T.Private.castToInternalProject->Private.getExternalResult(sourceId) @@ -373,6 +396,7 @@ This is a convenience function to get the result of a single source without crea However, without a project, you cannot handle include directives. The source has to be include free */ +@genType let evaluate = (sourceCode: string): ('r, 'b) => { let (result, continuation) = Private.evaluate(sourceCode) ( @@ -381,6 +405,7 @@ let evaluate = (sourceCode: string): ('r, 'b) => { ) } +@genType let foreignFunctionInterface = ( lambdaValue: ExternalExpressionValue.lambdaValue, argArray: array, diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res index 9e14c70c..c7bf968a 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res @@ -2,11 +2,12 @@ module ProjectItem = ReducerProject_ProjectItem module ExpressionT = Reducer_Expression_T module ProjectAccessorsT = ReducerProject_ProjectAccessors_T -type project = Object +type project = {"tag": string} type t = project module Private = { type internalProject = { + "tag": string, "items": Belt.Map.String.t, "stdLib": Reducer_Bindings.t, "environment": ExpressionT.environment, From b3a32b1231b47d993ee84ee82a58c89056227b48 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Tue, 16 Aug 2022 02:14:45 +0200 Subject: [PATCH 08/53] more typescript friendly --- .../ReducerProject/ReducerProject.res | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res index 3a990326..2acbf8db 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res @@ -10,8 +10,8 @@ module ProjectItem = ReducerProject_ProjectItem module T = ReducerProject_T module Topology = ReducerProject_Topology -type project = T.t @genType.opaque +type reducerProject = T.t type t = T.t module Private = { @@ -238,28 +238,28 @@ let createProject = (): t => Private.createProject()->T.Private.castFromInternal Answer all the source ids of all the sources in the project. */ @genType -let getSourceIds = (this: t): array => +let getSourceIds = (this: reducerProject): array => this->T.Private.castToInternalProject->Private.getSourceIds /* Sets the source for a given source Id. */ @genType -let setSource = (this: t, sourceId: string, value: string): unit => +let setSource = (this: reducerProject, sourceId: string, value: string): unit => this->T.Private.castToInternalProject->Private.setSource(sourceId, value) /* Gets the source for a given source id. */ @genType -let getSource = (this: t, sourceId: string): option => +let getSource = (this: reducerProject, sourceId: string): option => this->T.Private.castToInternalProject->Private.getSource(sourceId) /* Touches the source for a given source id. This and dependent, sources are set to be re-evaluated. */ @genType -let touchSource = (this: t, sourceId: string): unit => +let touchSource = (this: reducerProject, sourceId: string): unit => this->T.Private.castToInternalProject->Private.touchSource(sourceId) /* @@ -268,35 +268,35 @@ 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 = (this: t, sourceId: string): unit => +let clean = (this: reducerProject, sourceId: string): unit => this->T.Private.castToInternalProject->Private.clean(sourceId) /* Cleans all the compilation artifacts in all of the project */ @genType -let cleanAll = (this: t): unit => this->T.Private.castToInternalProject->Private.cleanAll +let cleanAll = (this: reducerProject): unit => this->T.Private.castToInternalProject->Private.cleanAll /* Cleans results. Compilation stays untouched to be able to re-run the source. You would not do this if you were not trying to debug the source code. */ @genType -let cleanResults = (this: t, sourceId: string): unit => +let cleanResults = (this: reducerProject, sourceId: string): unit => this->T.Private.castToInternalProject->Private.cleanResults(sourceId) /* Cleans all results. Compilations remains untouched to rerun the source. */ @genType -let cleanAllResults = (this: t): unit => +let cleanAllResults = (this: reducerProject): unit => this->T.Private.castToInternalProject->Private.cleanAllResults /* To set the includes one first has to call "parseIncludes". The parsed includes or the parser error is returned. */ @genType -let getIncludes = (this: t, sourceId: string): result< +let getIncludes = (this: reducerProject, sourceId: string): result< array, Reducer_ErrorValue.errorValue, > => this->T.Private.castToInternalProject->Private.getIncludes(sourceId) @@ -305,7 +305,7 @@ let getIncludes = (this: t, sourceId: string): result< Answers the source codes after which this source code is continuing */ @genType -let getContinues = (this: t, sourceId: string): array => +let getContinues = (this: reducerProject, sourceId: string): array => this->T.Private.castToInternalProject->Private.getContinues(sourceId) /* @@ -314,35 +314,35 @@ let getContinues = (this: t, sourceId: string): array => You can chain source codes on the web interface for example */ @genType -let setContinues = (this: t, sourceId: string, continues: array): unit => +let setContinues = (this: reducerProject, sourceId: string, continues: array): unit => this->T.Private.castToInternalProject->Private.setContinues(sourceId, continues) /* This source depends on the array of sources returned. */ @genType -let getDependencies = (this: t, sourceId: string): array => +let getDependencies = (this: reducerProject, sourceId: string): array => this->T.Private.castToInternalProject->Private.getDependencies(sourceId) /* The sources returned are dependent on this */ @genType -let getDependents = (this: t, sourceId: string): array => +let getDependents = (this: reducerProject, sourceId: string): array => this->T.Private.castToInternalProject->Private.getDependents(sourceId) /* Get the run order for the sources in the project. */ @genType -let getRunOrder = (this: t): array => +let getRunOrder = (this: reducerProject): array => this->T.Private.castToInternalProject->Private.getRunOrder /* Get the run order to get the results of this specific source */ @genType -let getRunOrderFor = (this: t, sourceId: string) => +let getRunOrderFor = (this: reducerProject, sourceId: string) => this->T.Private.castToInternalProject->Private.getRunOrderFor(sourceId) /* @@ -351,7 +351,7 @@ Load includes by calling getIncludes which returns the includes that have been p It is your responsibility to load the includes before running. */ @genType -let parseIncludes = (this: t, sourceId: string): unit => +let parseIncludes = (this: reducerProject, sourceId: string): unit => this->T.Private.castToInternalProject->Private.parseIncludes(sourceId) /* @@ -360,35 +360,35 @@ Use getRawParse to get the parse tree. You would need this function if you want to see the parse tree without running the source code. */ @genType -let rawParse = (this: t, sourceId: string): unit => +let rawParse = (this: reducerProject, sourceId: string): unit => this->T.Private.castToInternalProject->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 = (this: t, sourceId: string): unit => +let run = (this: reducerProject, sourceId: string): unit => this->T.Private.castToInternalProject->Private.run(sourceId) /* Runs all of the sources in a project. Their results and bindings will be available */ @genType -let runAll = (this: t): unit => this->T.Private.castToInternalProject->Private.runAll +let runAll = (this: reducerProject): unit => this->T.Private.castToInternalProject->Private.runAll /* Get the bindings after running this source file or the project */ @genType -let getExternalBindings = (this: t, sourceId: string): ExternalExpressionValue.record => +let getExternalBindings = (this: reducerProject, sourceId: string): ExternalExpressionValue.record => this->T.Private.castToInternalProject->Private.getExternalBindings(sourceId) /* Get the result after running this source file or the project */ @genType -let getExternalResult = (this: t, sourceId: string): option< - result, +let getExternalResult = (this: reducerProject, sourceId: string): option< + result, > => this->T.Private.castToInternalProject->Private.getExternalResult(sourceId) /* @@ -408,7 +408,7 @@ let evaluate = (sourceCode: string): ('r, 'b) => { @genType let foreignFunctionInterface = ( lambdaValue: ExternalExpressionValue.lambdaValue, - argArray: array, + argArray: array, environment: ExternalExpressionValue.environment, ) => { let internallambdaValue = InternalExpressionValue.lambdaValueToInternal(lambdaValue) From dc642774eba4570685f111d04c11579fe718cbb9 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Tue, 16 Aug 2022 02:49:16 +0200 Subject: [PATCH 09/53] reformat --- .../src/rescript/ReducerProject/ReducerProject.res | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res index 2acbf8db..c300e5f8 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res @@ -275,7 +275,8 @@ let clean = (this: reducerProject, sourceId: string): unit => Cleans all the compilation artifacts in all of the project */ @genType -let cleanAll = (this: reducerProject): unit => this->T.Private.castToInternalProject->Private.cleanAll +let cleanAll = (this: reducerProject): unit => + this->T.Private.castToInternalProject->Private.cleanAll /* Cleans results. Compilation stays untouched to be able to re-run the source. @@ -380,7 +381,10 @@ let runAll = (this: reducerProject): unit => this->T.Private.castToInternalProje Get the bindings after running this source file or the project */ @genType -let getExternalBindings = (this: reducerProject, sourceId: string): ExternalExpressionValue.record => +let getExternalBindings = ( + this: reducerProject, + sourceId: string, +): ExternalExpressionValue.record => this->T.Private.castToInternalProject->Private.getExternalBindings(sourceId) /* From 716ec61913f73e7c5e2e350c2654fc4028a74380 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Tue, 16 Aug 2022 16:02:23 +0400 Subject: [PATCH 10/53] fix some gentype errors --- .../Reducer_Expression_Lambda.res | 2 +- ...ducerInterface_InternalExpressionValue.res | 23 +++++++++---------- .../ReducerProject/ReducerProject.res | 2 +- 3 files changed, 13 insertions(+), 14 deletions(-) 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 587d80be..5ab7761d 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 @@ -95,7 +95,7 @@ let foreignFunctionInterface = ( argArray: array, accessors: ProjectAccessorsT.t, reducer: ProjectReducerFnT.t, -): result => { +): result => { let args = argArray->Belt.List.fromArray applyParametersToLambda(lambdaValue, args, accessors, reducer) } diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res index b5799067..a2994baa 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res @@ -1,10 +1,9 @@ module ErrorValue = Reducer_ErrorValue -module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue module Extra_Array = Reducer_Extra_Array -type internalCode = ExternalExpressionValue.internalCode -type environment = ExternalExpressionValue.environment +type internalCode = ReducerInterface_ExternalExpressionValue.internalCode +type environment = ReducerInterface_ExternalExpressionValue.environment -let defaultEnvironment = ExternalExpressionValue.defaultEnvironment +let defaultEnvironment = ReducerInterface_ExternalExpressionValue.defaultEnvironment type rec t = | IEvArray(array) // FIXME: Convert to MapInt @@ -39,19 +38,19 @@ type functionCall = (string, array) module Internal = { module NameSpace = { - external castNameSpaceToHidden: nameSpace => ExternalExpressionValue.hiddenNameSpace = + external castNameSpaceToHidden: nameSpace => ReducerInterface_ExternalExpressionValue.hiddenNameSpace = "%identity" - external castHiddenToNameSpace: ExternalExpressionValue.hiddenNameSpace => nameSpace = + external castHiddenToNameSpace: ReducerInterface_ExternalExpressionValue.hiddenNameSpace => nameSpace = "%identity" } module Lambda = { - let toInternal = (v: ExternalExpressionValue.lambdaValue): lambdaValue => { + let toInternal = (v: ReducerInterface_ExternalExpressionValue.lambdaValue): lambdaValue => { let p = v.parameters let c = v.context->NameSpace.castHiddenToNameSpace let b = v.body {parameters: p, context: c, body: b} } - and toExternal = (v: lambdaValue): ExternalExpressionValue.lambdaValue => { + and toExternal = (v: lambdaValue): ReducerInterface_ExternalExpressionValue.lambdaValue => { let p = v.parameters let c = v.context->NameSpace.castNameSpaceToHidden let b = v.body @@ -146,7 +145,7 @@ let toStringResultOkless = (codeResult: result): strin let toStringResultRecord = x => switch x { - | Ok(a) => `Ok(${ExternalExpressionValue.toStringRecord(a)})` + | Ok(a) => `Ok(${ReducerInterface_ExternalExpressionValue.toStringRecord(a)})` | Error(m) => `Error(${ErrorValue.errorToString(m)})` } @@ -194,7 +193,7 @@ let valueToValueType = value => | IEvVoid => EvtVoid } -let externalValueToValueType = (value: ExternalExpressionValue.t) => +let externalValueToValueType = (value: ReducerInterface_ExternalExpressionValue.t) => switch value { | EvArray(_) => EvtArray | EvArrayString(_) => EvtArrayString @@ -246,7 +245,7 @@ let functionCallSignatureToString = (functionCallSignature: functionCallSignatur `${fn}(${args->Js.Array2.map(valueTypeToString)->Js.Array2.toString})` } -let rec toExternal = (iev: t): ExternalExpressionValue.t => { +let rec toExternal = (iev: t): ReducerInterface_ExternalExpressionValue.t => { switch iev { | IEvArray(v) => v->Belt.Array.map(e => toExternal(e))->EvArray | IEvArrayString(v) => EvArrayString(v) @@ -281,7 +280,7 @@ and nameSpaceToTypeScriptBindings = ( Belt.Map.String.map(container, e => toExternal(e))->Belt.Map.String.toArray->Js.Dict.fromArray } -let rec toInternal = (ev: ExternalExpressionValue.t): t => { +let rec toInternal = (ev: ReducerInterface_ExternalExpressionValue.t): t => { switch ev { | EvArray(v) => v->Belt.Array.map(e => toInternal(e))->IEvArray | EvArrayString(v) => IEvArrayString(v) diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res index c300e5f8..0b9f9385 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res @@ -232,7 +232,7 @@ A project has a public field tag with a constant value "reducerProject" project = {tag: "reducerProject"} */ @genType -let createProject = (): t => Private.createProject()->T.Private.castFromInternalProject +let createProject = (): reducerProject => Private.createProject()->T.Private.castFromInternalProject /* Answer all the source ids of all the sources in the project. From 454a545ef6e3231e5c702975a448459447d16395 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Tue, 16 Aug 2022 17:07:15 +0200 Subject: [PATCH 11/53] tutorial: initial Also missing public API function --- .../ReducerProject/ReducerProject_test.res | 1 - .../ReducerProject_tutorial_test.res | 96 +++++++++++++++++++ .../ReducerProject/ReducerProject.res | 15 ++- 3 files changed, 107 insertions(+), 5 deletions(-) create mode 100644 packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_test.res diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res index 466a8770..b4ede1a4 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res @@ -2,7 +2,6 @@ module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue module Project = ReducerProject module Bindings = Reducer_Bindings -module Continuation = ReducerInterface_Value_Continuation open Jest open Expect diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_test.res new file mode 100644 index 00000000..07f1e973 --- /dev/null +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_test.res @@ -0,0 +1,96 @@ +@@warning("-44") +module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue +module Project = ReducerProject +module Bindings = Reducer_Bindings + +open Jest +open Expect +open Expect.Operators + +describe("ReducerProject Tutorial", () => { + describe("Single source", () => { + /* +Case "Running a single source". +*/ + test("run", () => { + /* 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. + 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") + /* Let's run "main" source. */ + project->Project.run("main") + /* Now you have a result for "main" source. + Running one by one is necessary for UI to navigate among the sources and to see the results by source. + And you're free to run any source you want. + You will look at the results of this source and you don't want to run the others if not required. + */ + + /* However, you could also run the whole project. + If you have all the sources, you can always run the whole project. + Dependencies and recompiling on demand will be taken care of by the project. + */ + project->Project.runAll + + /* Either with run or runAll you executed the project. + You can get the result of a specific source by calling getResult for that source. + You can get the bindings of a specific source by calling getBindings for that source. + If there is any runtime error, getResult will return the error. + + Note that getResult returns None if the source has not been run. + Getting None means you have forgotten to run the source. + */ + let result = project->Project.getExternalResult("main") + let bindings = project->Project.getExternalBindings("main") + + /* Let's display the result and bindings */ + ( + result->ExternalExpressionValue.toStringOptionResult, + bindings->ExternalExpressionValue.EvModule->ExternalExpressionValue.toString, + )->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.getExternalResult(project, "main") + let bindings = Project.getExternalBindings(project, "main") + /* Now you have external bindings and external result. */ + ( + result->ExternalExpressionValue.toStringOptionResult, + bindings->ExternalExpressionValue.EvModule->ExternalExpressionValue.toString, + )->expect == ("Ok(3)", "@{}") + }) + + test("run with an environment", () => { + /* Running the source code like above allows you to set a custom environment */ + let project = Project.createProject() + + /* Optional. Set your custom environment anytime before running */ + Project.setEnvironment(project, ExternalExpressionValue.defaultEnvironment) + + Project.setSource(project, "main", "1 + 2") + Project.runAll(project) + let result = Project.getExternalResult(project, "main") + let _bindings = Project.getExternalBindings(project, "main") + result->ExternalExpressionValue.toStringOptionResult->expect == "Ok(3)" + }) + + test("shortcut", () => { + /* 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->ExternalExpressionValue.toStringResult, + bindings->ExternalExpressionValue.EvModule->ExternalExpressionValue.toString, + )->expect == ("Ok(3)", "@{}") + }) + }) +}) diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res index 0b9f9385..1bba0aff 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res @@ -202,10 +202,11 @@ module Private = { let project = createProject() setSource(project, "main", sourceCode) runAll(project) - ( - getResult(project, "main")->Belt.Option.getWithDefault(IEvVoid->Ok), - getContinuation(project, "main"), - ) + let those = project->getContinuation("main") + let these = project->getStdLib + let ofUser = Continuation.minus(those, these) + + (getResult(project, "main")->Belt.Option.getWithDefault(IEvVoid->Ok), ofUser) } } @@ -409,6 +410,12 @@ let evaluate = (sourceCode: string): ('r, 'b) => { ) } +@genType +let setEnvironment = ( + this: reducerProject, + environment: ExternalExpressionValue.environment, +): unit => this->T.Private.castToInternalProject->Private.setEnvironment(environment) + @genType let foreignFunctionInterface = ( lambdaValue: ExternalExpressionValue.lambdaValue, From c204156b75a8c6499fedc31c4acfbf97f8a5de3e Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Tue, 16 Aug 2022 20:58:47 +0400 Subject: [PATCH 12/53] fix gentype issues with "this" keyword --- .../ReducerProject/ReducerProject.res | 259 +++++++++--------- 1 file changed, 130 insertions(+), 129 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res index 1bba0aff..5ed0858b 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res @@ -26,175 +26,175 @@ module Private = { let getRunOrderFor = Topology.getRunOrderFor let createProject = () => { - let this: t = { + let project: t = { "tag": "reducerProject", "items": Belt.Map.String.empty, "stdLib": ReducerInterface_StdLib.internalStdLib, "environment": InternalExpressionValue.defaultEnvironment, } - this + project } - let rec touchSource = (this: t, sourceId: string): unit => { - let item = this->getItem(sourceId) + let rec touchSource = (project: t, sourceId: string): unit => { + let item = project->getItem(sourceId) let newItem = ProjectItem.touchSource(item) - Belt.Map.String.set(this["items"], sourceId, newItem)->T.Private.setFieldItems(this, _) - touchDependents(this, sourceId) + Belt.Map.String.set(project["items"], sourceId, newItem)->T.Private.setFieldItems(project, _) + touchDependents(project, sourceId) } - and touchDependents = (this: t, sourceId: string): unit => { - let _ = getDependents(this, sourceId)->Belt.Array.forEach(_, touchSource(this, _)) + and touchDependents = (project: t, sourceId: string): unit => { + let _ = getDependents(project, sourceId)->Belt.Array.forEach(_, touchSource(project, _)) } - let getSource = (this: t, sourceId: string): option => - Belt.Map.String.get(this["items"], sourceId)->Belt.Option.map(ProjectItem.getSource) + let getSource = (project: t, sourceId: string): option => + Belt.Map.String.get(project["items"], sourceId)->Belt.Option.map(ProjectItem.getSource) - let setSource = (this: t, sourceId: string, value: string): unit => { - let newItem = this->getItem(sourceId)->ProjectItem.setSource(value) - Belt.Map.String.set(this["items"], sourceId, newItem)->T.Private.setFieldItems(this, _) - touchDependents(this, sourceId) + 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 = (this: t, sourceId: string): unit => { - let newItem = this->getItem(sourceId)->ProjectItem.clean - Belt.Map.String.set(this["items"], sourceId, newItem)->T.Private.setFieldItems(this, _) + 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 = (this: t): unit => - getSourceIds(this)->Belt.Array.forEach(sourceId => clean(this, sourceId)) + let cleanAll = (project: t): unit => + getSourceIds(project)->Belt.Array.forEach(sourceId => clean(project, sourceId)) - let cleanResults = (this: t, sourceId: string): unit => { - let newItem = this->getItem(sourceId)->ProjectItem.cleanResults - Belt.Map.String.set(this["items"], sourceId, newItem)->T.Private.setFieldItems(this, _) + 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 = (this: t): unit => - getSourceIds(this)->Belt.Array.forEach(sourceId => cleanResults(this, sourceId)) + let cleanAllResults = (project: t): unit => + getSourceIds(project)->Belt.Array.forEach(sourceId => cleanResults(project, sourceId)) - let getIncludes = (this: t, sourceId: string): ProjectItem.T.includesType => - this->getItem(sourceId)->ProjectItem.getIncludes + let getIncludes = (project: t, sourceId: string): ProjectItem.T.includesType => + project->getItem(sourceId)->ProjectItem.getIncludes - let setContinues = (this: t, sourceId: string, continues: array): unit => { - let newItem = this->getItem(sourceId)->ProjectItem.setContinues(continues) - Belt.Map.String.set(this["items"], sourceId, newItem)->T.Private.setFieldItems(this, _) - touchSource(this, sourceId) + 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, _) + touchSource(project, sourceId) } - let getContinues = (this: t, sourceId: string): array => - ProjectItem.getContinues(this->getItem(sourceId)) + let getContinues = (project: t, sourceId: string): array => + ProjectItem.getContinues(project->getItem(sourceId)) - let removeContinues = (this: t, sourceId: string): unit => { - let newItem = this->getItem(sourceId)->ProjectItem.removeContinues - Belt.Map.String.set(this["items"], sourceId, newItem)->T.Private.setFieldItems(this, _) - touchSource(this, 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, _) + touchSource(project, sourceId) } - let getContinuation = (this: t, sourceId: string): ProjectItem.T.continuationArgumentType => - this->getItem(sourceId)->ProjectItem.getContinuation + let getContinuation = (project: t, sourceId: string): ProjectItem.T.continuationArgumentType => + project->getItem(sourceId)->ProjectItem.getContinuation let setContinuation = ( - this: t, + project: t, sourceId: string, continuation: ProjectItem.T.continuationArgumentType, ): unit => { - let newItem = this->getItem(sourceId)->ProjectItem.setContinuation(continuation) - Belt.Map.String.set(this["items"], sourceId, newItem)->T.Private.setFieldItems(this, _) + let newItem = project->getItem(sourceId)->ProjectItem.setContinuation(continuation) + Belt.Map.String.set(project["items"], sourceId, newItem)->T.Private.setFieldItems(project, _) } - let getResult = (this: t, sourceId: string): ProjectItem.T.resultType => - this->getItem(sourceId)->ProjectItem.getResult + let getResult = (project: t, sourceId: string): ProjectItem.T.resultType => + project->getItem(sourceId)->ProjectItem.getResult - let setResult = (this: t, sourceId: string, value: ProjectItem.T.resultArgumentType): unit => { - let newItem = this->getItem(sourceId)->ProjectItem.setResult(value) - Belt.Map.String.set(this["items"], sourceId, newItem)->T.Private.setFieldItems(this, _) + 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 getExternalResult = (this: t, sourceId: string): ProjectItem.T.externalResultType => - this->getItem(sourceId)->ProjectItem.getExternalResult + let getExternalResult = (project: t, sourceId: string): ProjectItem.T.externalResultType => + project->getItem(sourceId)->ProjectItem.getExternalResult - let parseIncludes = (this: t, sourceId: string): unit => { - let newItem = this->getItem(sourceId)->ProjectItem.parseIncludes - Belt.Map.String.set(this["items"], sourceId, newItem)->T.Private.setFieldItems(this, _) + 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, _) } - let rawParse = (this: t, sourceId): unit => { - let newItem = this->getItem(sourceId)->ProjectItem.rawParse - Belt.Map.String.set(this["items"], sourceId, newItem)->T.Private.setFieldItems(this, _) + 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 = (this: t): Reducer_Bindings.t => this["stdLib"] - let setStdLib = (this: t, value: Reducer_Bindings.t): unit => - T.Private.setFieldStdLib(this, value) + 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 = (this: t): InternalExpressionValue.environment => this["environment"] - let setEnvironment = (this: t, value: InternalExpressionValue.environment): unit => - T.Private.setFieldEnvironment(this, value) + let getEnvironment = (project: t): InternalExpressionValue.environment => project["environment"] + let setEnvironment = (project: t, value: InternalExpressionValue.environment): unit => + T.Private.setFieldEnvironment(project, value) let getExternalBindings = ( - this: t, + project: t, sourceId: string, ): ProjectItem.T.externalBindingsArgumentType => { - let those = this->getContinuation(sourceId) - let these = this->getStdLib + let those = project->getContinuation(sourceId) + let these = project->getStdLib let ofUser = Continuation.minus(those, these) ofUser->InternalExpressionValue.nameSpaceToTypeScriptBindings } - let buildProjectAccessors = (this: t): ProjectAccessorsT.t => { + let buildProjectAccessors = (project: t): ProjectAccessorsT.t => { states: {continuation: Bindings.emptyBindings}, - stdLib: getStdLib(this), - environment: getEnvironment(this), + stdLib: getStdLib(project), + environment: getEnvironment(project), } let doRunWithContinuation = ( - this: t, + project: t, sourceId: string, continuation: ProjectItem.T.continuation, ): unit => { - let accessors = buildProjectAccessors(this) + let accessors = buildProjectAccessors(project) let states = accessors.states - let newItem = this->getItem(sourceId)->ProjectItem.run(continuation, accessors) - Belt.Map.String.set(this["items"], sourceId, newItem)->T.Private.setFieldItems(this, _) - setContinuation(this, sourceId, states.continuation) + 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) } type runState = (ProjectItem.T.resultArgumentType, ProjectItem.T.continuation) let tryRunWithContinuation = ( - this: t, + project: t, sourceId: string, (rPrevResult: ProjectItem.T.resultArgumentType, continuation: ProjectItem.T.continuation), ): (ProjectItem.T.resultArgumentType, ProjectItem.T.continuation) => { - switch getResult(this, sourceId) { - | Some(result) => (result, getContinuation(this, sourceId)) // already ran + switch getResult(project, sourceId) { + | Some(result) => (result, getContinuation(project, sourceId)) // already ran | None => switch rPrevResult { | Error(error) => { - setResult(this, sourceId, Error(error)) + setResult(project, sourceId, Error(error)) (Error(error), continuation) } | Ok(_prevResult) => { - doRunWithContinuation(this, sourceId, continuation) + doRunWithContinuation(project, sourceId, continuation) ( - getResult(this, sourceId)->Belt.Option.getWithDefault(rPrevResult), - getContinuation(this, sourceId), + getResult(project, sourceId)->Belt.Option.getWithDefault(rPrevResult), + getContinuation(project, sourceId), ) } } } } - let runAll = (this: t): unit => { - let runOrder = Topology.getRunOrder(this) - let initialState = (Ok(InternalExpressionValue.IEvVoid), getStdLib(this)) + let runAll = (project: t): unit => { + let runOrder = Topology.getRunOrder(project) + let initialState = (Ok(InternalExpressionValue.IEvVoid), getStdLib(project)) let _finalState = Belt.Array.reduce(runOrder, initialState, (currState, currId) => - tryRunWithContinuation(this, currId, currState) + tryRunWithContinuation(project, currId, currState) ) } - let run = (this: t, sourceId: string): unit => { - let runOrder = Topology.getRunOrderFor(this, sourceId) - let initialState = (Ok(InternalExpressionValue.IEvVoid), getStdLib(this)) + let run = (project: t, sourceId: string): unit => { + let runOrder = Topology.getRunOrderFor(project, sourceId) + let initialState = (Ok(InternalExpressionValue.IEvVoid), getStdLib(project)) let _finalState = Belt.Array.reduce(runOrder, initialState, (currState, currId) => - tryRunWithContinuation(this, currId, currState) + tryRunWithContinuation(project, currId, currState) ) } @@ -239,29 +239,29 @@ let createProject = (): reducerProject => Private.createProject()->T.Private.cas Answer all the source ids of all the sources in the project. */ @genType -let getSourceIds = (this: reducerProject): array => - this->T.Private.castToInternalProject->Private.getSourceIds +let getSourceIds = (project: reducerProject): array => + project->T.Private.castToInternalProject->Private.getSourceIds /* Sets the source for a given source Id. */ @genType -let setSource = (this: reducerProject, sourceId: string, value: string): unit => - this->T.Private.castToInternalProject->Private.setSource(sourceId, value) +let setSource = (project: reducerProject, sourceId: string, value: string): unit => + project->T.Private.castToInternalProject->Private.setSource(sourceId, value) /* Gets the source for a given source id. */ @genType -let getSource = (this: reducerProject, sourceId: string): option => - this->T.Private.castToInternalProject->Private.getSource(sourceId) +let getSource = (project: reducerProject, sourceId: string): option => + project->T.Private.castToInternalProject->Private.getSource(sourceId) /* Touches the source for a given source id. This and dependent, sources are set to be re-evaluated. */ @genType -let touchSource = (this: reducerProject, sourceId: string): unit => - this->T.Private.castToInternalProject->Private.touchSource(sourceId) +let touchSource = (project: reducerProject, sourceId: string): unit => + project->T.Private.castToInternalProject->Private.touchSource(sourceId) /* Cleans the compilation artifacts for a given source ID. The results stay untouched, so compilation won't be run again. @@ -269,46 +269,46 @@ 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 = (this: reducerProject, sourceId: string): unit => - this->T.Private.castToInternalProject->Private.clean(sourceId) +let clean = (project: reducerProject, sourceId: string): unit => + project->T.Private.castToInternalProject->Private.clean(sourceId) /* Cleans all the compilation artifacts in all of the project */ @genType -let cleanAll = (this: reducerProject): unit => - this->T.Private.castToInternalProject->Private.cleanAll +let cleanAll = (project: reducerProject): unit => + project->T.Private.castToInternalProject->Private.cleanAll /* Cleans results. Compilation stays untouched to be able to re-run the source. You would not do this if you were not trying to debug the source code. */ @genType -let cleanResults = (this: reducerProject, sourceId: string): unit => - this->T.Private.castToInternalProject->Private.cleanResults(sourceId) +let cleanResults = (project: reducerProject, sourceId: string): unit => + project->T.Private.castToInternalProject->Private.cleanResults(sourceId) /* Cleans all results. Compilations remains untouched to rerun the source. */ @genType -let cleanAllResults = (this: reducerProject): unit => - this->T.Private.castToInternalProject->Private.cleanAllResults +let cleanAllResults = (project: reducerProject): unit => + project->T.Private.castToInternalProject->Private.cleanAllResults /* To set the includes one first has to call "parseIncludes". The parsed includes or the parser error is returned. */ @genType -let getIncludes = (this: reducerProject, sourceId: string): result< +let getIncludes = (project: reducerProject, sourceId: string): result< array, Reducer_ErrorValue.errorValue, -> => this->T.Private.castToInternalProject->Private.getIncludes(sourceId) +> => project->T.Private.castToInternalProject->Private.getIncludes(sourceId) /* Answers the source codes after which this source code is continuing */ @genType -let getContinues = (this: reducerProject, sourceId: string): array => - this->T.Private.castToInternalProject->Private.getContinues(sourceId) +let getContinues = (project: reducerProject, sourceId: string): array => + project->T.Private.castToInternalProject->Private.getContinues(sourceId) /* "continues" acts like hidden includes in the source. @@ -316,36 +316,36 @@ let getContinues = (this: reducerProject, sourceId: string): array => You can chain source codes on the web interface for example */ @genType -let setContinues = (this: reducerProject, sourceId: string, continues: array): unit => - this->T.Private.castToInternalProject->Private.setContinues(sourceId, continues) +let setContinues = (project: reducerProject, sourceId: string, continues: array): unit => + project->T.Private.castToInternalProject->Private.setContinues(sourceId, continues) /* This source depends on the array of sources returned. */ @genType -let getDependencies = (this: reducerProject, sourceId: string): array => - this->T.Private.castToInternalProject->Private.getDependencies(sourceId) +let getDependencies = (project: reducerProject, sourceId: string): array => + project->T.Private.castToInternalProject->Private.getDependencies(sourceId) /* The sources returned are dependent on this */ @genType -let getDependents = (this: reducerProject, sourceId: string): array => - this->T.Private.castToInternalProject->Private.getDependents(sourceId) +let getDependents = (project: reducerProject, sourceId: string): array => + project->T.Private.castToInternalProject->Private.getDependents(sourceId) /* Get the run order for the sources in the project. */ @genType -let getRunOrder = (this: reducerProject): array => - this->T.Private.castToInternalProject->Private.getRunOrder +let getRunOrder = (project: reducerProject): array => + project->T.Private.castToInternalProject->Private.getRunOrder /* Get the run order to get the results of this specific source */ @genType -let getRunOrderFor = (this: reducerProject, sourceId: string) => - this->T.Private.castToInternalProject->Private.getRunOrderFor(sourceId) +let getRunOrderFor = (project: reducerProject, sourceId: string) => + project->T.Private.castToInternalProject->Private.getRunOrderFor(sourceId) /* Parse includes so that you can load them before running. @@ -353,8 +353,8 @@ Load includes by calling getIncludes which returns the includes that have been p It is your responsibility to load the includes before running. */ @genType -let parseIncludes = (this: reducerProject, sourceId: string): unit => - this->T.Private.castToInternalProject->Private.parseIncludes(sourceId) +let parseIncludes = (project: reducerProject, sourceId: string): unit => + project->T.Private.castToInternalProject->Private.parseIncludes(sourceId) /* Parse the source code if it is not done already. @@ -362,39 +362,40 @@ Use getRawParse to get the parse tree. You would need this function if you want to see the parse tree without running the source code. */ @genType -let rawParse = (this: reducerProject, sourceId: string): unit => - this->T.Private.castToInternalProject->Private.rawParse(sourceId) +let rawParse = (project: reducerProject, sourceId: string): unit => + project->T.Private.castToInternalProject->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 = (this: reducerProject, sourceId: string): unit => - this->T.Private.castToInternalProject->Private.run(sourceId) +let run = (project: reducerProject, sourceId: string): unit => + project->T.Private.castToInternalProject->Private.run(sourceId) /* Runs all of the sources in a project. Their results and bindings will be available */ @genType -let runAll = (this: reducerProject): unit => this->T.Private.castToInternalProject->Private.runAll +let runAll = (project: reducerProject): unit => + project->T.Private.castToInternalProject->Private.runAll /* Get the bindings after running this source file or the project */ @genType let getExternalBindings = ( - this: reducerProject, + project: reducerProject, sourceId: string, ): ExternalExpressionValue.record => - this->T.Private.castToInternalProject->Private.getExternalBindings(sourceId) + project->T.Private.castToInternalProject->Private.getExternalBindings(sourceId) /* Get the result after running this source file or the project */ @genType -let getExternalResult = (this: reducerProject, sourceId: string): option< +let getExternalResult = (project: reducerProject, sourceId: string): option< result, -> => this->T.Private.castToInternalProject->Private.getExternalResult(sourceId) +> => project->T.Private.castToInternalProject->Private.getExternalResult(sourceId) /* This is a convenience function to get the result of a single source without creating a project. @@ -412,9 +413,9 @@ let evaluate = (sourceCode: string): ('r, 'b) => { @genType let setEnvironment = ( - this: reducerProject, + project: reducerProject, environment: ExternalExpressionValue.environment, -): unit => this->T.Private.castToInternalProject->Private.setEnvironment(environment) +): unit => project->T.Private.castToInternalProject->Private.setEnvironment(environment) @genType let foreignFunctionInterface = ( From 32f3aeba137625ed877cab6cb08079d0e9cd695a Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Tue, 16 Aug 2022 19:01:47 +0200 Subject: [PATCH 13/53] tutorial TODO --- .../ReducerProject_tutorial_test.res | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_test.res index 07f1e973..02089b36 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_test.res @@ -9,7 +9,7 @@ open Expect.Operators describe("ReducerProject Tutorial", () => { describe("Single source", () => { - /* +/* Case "Running a single source". */ test("run", () => { @@ -94,3 +94,16 @@ Case "Running a single source". }) }) }) + +//TODO multiple sources +//TODO multiple sources with includes. Introduction to includes +//TODO multiple sources with multi level includes. Cycle detection +//TODO +//TODO: Implement a runOrder consideration - clean results based on run order. +//TODO: runOrder vs setSource/touchSource +//TODO: Advanced details: (below) +//TODO runOrder. includes vs continues. Run order based reexecution +//TODO: dependents and reexecution +//TODO: dependencies and reexecution +//TODO: cleanAllResults clean +//TODO: cleanAll clean \ No newline at end of file From a8c729762175efe96d9718c605da04d7811275ca Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Wed, 17 Aug 2022 18:57:34 +0200 Subject: [PATCH 14/53] TypeScript experiment --- .../ForTS_InternalValue.res | 33 +++++++++++++++++++ .../ForTS_InternalValue_RecordLike.res | 8 +++++ .../ForTS_InternalValue_String.res | 1 + .../ForTS_InternalValue_Void.res | 3 ++ .../ForTS_InternalValue_tag.tsx | 7 ++++ .../ForTS/ForTS_MyProject.res | 4 +++ .../ForTS_Result_InternalValue.res | 18 ++++++++++ .../ForTS/ForTS_Types.res | 12 +++++++ .../My/My_ErrorValue.res | 10 ++++++ .../MyInterface/MyInterface_InternalValue.res | 9 +++++ .../MyInterface_InternalValue_RecordLike.res | 12 +++++++ .../MyInterface_InternalValue_String.res | 1 + .../MyInterface_InternalValue_Void.res | 1 + .../MyInterface_InternalValue_T.res | 7 ++++ .../Dummy-TypeScriptingRescript/README.md | 1 + 15 files changed, 127 insertions(+) create mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue.res create mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_RecordLike.res create mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_String.res create mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_Void.res create mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_tag.tsx create mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_MyProject.res create mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Result/ForTS_Result_InternalValue.res create mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Types.res create mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/My/My_ErrorValue.res create mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue.res create mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_RecordLike.res create mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_String.res create mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_Void.res create mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue_T.res create mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/README.md diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue.res new file mode 100644 index 00000000..e9e0bfeb --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue.res @@ -0,0 +1,33 @@ +open ForTS_Types + +@module("ForTS_InternalValue_tag") @scope("InternalValueTag") +external ivtVoid_: int = "IvtVoid" +@module("ForTS_InternalValue_tag") @scope("InternalValueTag") +external ivtString_: int = "IvtString" +@module("ForTS_InternalValue_tag") @scope("InternalValueTag") +external ivtRecordLike_: int = "IvtRecordLike" + +let getTag = (variant: internalValue) => + switch variant { + | IvVoid(_) => ivtVoid_ + | IvString(_) => ivtString_ + | IvRecordLike(_) => ivtRecordLike_ + } + +let getVoid = (variant: internalValue): option => + switch variant { + | IvVoid(v) => Some(v) + | _ => None + } + +let getString = (variant: internalValue): option => + switch variant { + | IvString(s) => Some(s) + | _ => None + } + +let getRecordLike = (variant: internalValue): option => + switch variant { + | IvRecordLike(r) => Some(r) + | _ => None + } diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_RecordLike.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_RecordLike.res new file mode 100644 index 00000000..630cd72e --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_RecordLike.res @@ -0,0 +1,8 @@ +open ForTS_Types + +@genType +let toString = (v: recordLike): string => + MyInterface_InternalValue_RecordLike.toString(v, MyInterface_InternalValue.toString) +@genType +let toArray = (v: recordLike): array<(string, internalValue)> => + MyInterface_InternalValue_RecordLike.toArray(v) diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_String.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_String.res new file mode 100644 index 00000000..dffb46e1 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_String.res @@ -0,0 +1 @@ +@genType let toString = (value: string): string => value diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_Void.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_Void.res new file mode 100644 index 00000000..7b5b85e6 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_Void.res @@ -0,0 +1,3 @@ +open ForTS_Types + +@genType let toString = (_value: internalVoid): string => MyInterface_InternalValue_Void.toString diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_tag.tsx b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_tag.tsx new file mode 100644 index 00000000..a8438d1d --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_tag.tsx @@ -0,0 +1,7 @@ +enum InternalValueTag { + IvtVoid, + IvtString, + IvtRecordLike +} + + diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_MyProject.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_MyProject.res new file mode 100644 index 00000000..f677ec42 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_MyProject.res @@ -0,0 +1,4 @@ +open ForTS_Types + +@genType +let getResult = (_p: myProject): option => My_ErrorValue.EError->Error->Some diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Result/ForTS_Result_InternalValue.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Result/ForTS_Result_InternalValue.res new file mode 100644 index 00000000..fd55b6ff --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Result/ForTS_Result_InternalValue.res @@ -0,0 +1,18 @@ +open ForTS_Types + +@genType let isError = (r: result_internalValue): bool => Belt.Result.isError(r) +@genType let isOk = (r: result_internalValue): bool => Belt.Result.isOk(r) + +@genType +let getError = (r: result_internalValue): option => + switch r { + | Ok(_) => None + | Error(e) => Some(e) + } + +@genType +let getValue = (r: result_internalValue): option => + switch r { + | Ok(v) => Some(v) + | Error(_) => None + } diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Types.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Types.res new file mode 100644 index 00000000..4345c405 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Types.res @@ -0,0 +1,12 @@ +/* + Group all opaque types together for TS. + All other modules for TS should use this module +*/ +@genType.opaque type internalValue = MyInterface_InternalValue_T.t +@genType.opaque type recordLike = MyInterface_InternalValue_RecordLike.t +@genType.opaque type internalVoid = int +@genType.opaque type errorValue = My_ErrorValue.t +@genType.opaque type result_internalValue = result // There has to be a type for each result permutation +@genType.opaque type myProject = {name: string} + +//There is no need to map option<> as it becomes nullable diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/My/My_ErrorValue.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/My/My_ErrorValue.res new file mode 100644 index 00000000..a4a2304a --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/My/My_ErrorValue.res @@ -0,0 +1,10 @@ +type errorValue = EError | EErrorString(string) | EErrorNumber(float) +type t = errorValue + +let toString = (e: errorValue): string => { + switch e { + | EError => "Error" + | EErrorString(s) => s + | EErrorNumber(f) => Js.Float.toString(f) + } +} diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue.res new file mode 100644 index 00000000..b4037564 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue.res @@ -0,0 +1,9 @@ +open MyInterface_InternalValue_T + +let rec toString = (v: internalValue): string => { + switch v { + | IvString(s) => MyInterface_InternalValue_String.toString(s) + | IvRecordLike(m) => MyInterface_InternalValue_RecordLike.toString(m, toString) + | IvVoid(_v) => MyInterface_InternalValue_Void.toString + } +} diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_RecordLike.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_RecordLike.res new file mode 100644 index 00000000..ccf7bc45 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_RecordLike.res @@ -0,0 +1,12 @@ +type t = MyInterface_InternalValue_T.recordLike +let toString = (value: t, recToString) => { + let contents = + Belt.Map.String.mapWithKey(value, (key, value) => { + `${key}: ${recToString(value)}` + }) + ->Belt.Map.String.toArray + ->Js.Array2.joinWith(", ") + `{${contents}}` +} + +let toArray = (value: t) => Belt.Map.String.toArray(value) diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_String.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_String.res new file mode 100644 index 00000000..21c261ef --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_String.res @@ -0,0 +1 @@ +let toString = v => v diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_Void.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_Void.res new file mode 100644 index 00000000..b41f0b82 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_Void.res @@ -0,0 +1 @@ +let toString = "Void" diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue_T.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue_T.res new file mode 100644 index 00000000..c37ef95a --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue_T.res @@ -0,0 +1,7 @@ +type rec internalValue = + | IvString(string) + | IvRecordLike(recordLike) + | IvVoid(int) +and recordLike = Belt.Map.String.t + +type t = internalValue diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/README.md b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/README.md new file mode 100644 index 00000000..93dd1be2 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/README.md @@ -0,0 +1 @@ +To be trashed. Experimental code \ No newline at end of file From 55c03ed5204a88d4bdb787ddab063de96b7ed0b9 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Wed, 17 Aug 2022 19:32:11 +0200 Subject: [PATCH 15/53] missing gentype --- .../ForTS/ForTS_InternalValue/ForTS_InternalValue.res | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue.res index e9e0bfeb..c85474da 100644 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue.res +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue.res @@ -7,6 +7,7 @@ external ivtString_: int = "IvtString" @module("ForTS_InternalValue_tag") @scope("InternalValueTag") external ivtRecordLike_: int = "IvtRecordLike" +@genType let getTag = (variant: internalValue) => switch variant { | IvVoid(_) => ivtVoid_ @@ -14,18 +15,21 @@ let getTag = (variant: internalValue) => | IvRecordLike(_) => ivtRecordLike_ } +@genType let getVoid = (variant: internalValue): option => switch variant { | IvVoid(v) => Some(v) | _ => None } +@genType let getString = (variant: internalValue): option => switch variant { | IvString(s) => Some(s) | _ => None } +@genType let getRecordLike = (variant: internalValue): option => switch variant { | IvRecordLike(r) => Some(r) From 868f9f428add3e807cbf48d48b0a17612f4759fc Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Wed, 17 Aug 2022 21:22:10 +0200 Subject: [PATCH 16/53] parametric types for typescript --- .../ReducerProject_tutorial_test.res | 6 +++--- .../ForTS/ForTS_MyProject.res | 3 ++- .../ForTS/ForTS_Result.res | 18 ++++++++++++++++++ .../ForTS_Result_InternalValue.res | 18 ------------------ .../ForTS/ForTS_Types.res | 2 +- 5 files changed, 24 insertions(+), 23 deletions(-) create mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Result.res delete mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Result/ForTS_Result_InternalValue.res diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_test.res index 02089b36..0d2b92f3 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_test.res @@ -9,7 +9,7 @@ open Expect.Operators describe("ReducerProject Tutorial", () => { describe("Single source", () => { -/* + /* Case "Running a single source". */ test("run", () => { @@ -98,7 +98,7 @@ Case "Running a single source". //TODO multiple sources //TODO multiple sources with includes. Introduction to includes //TODO multiple sources with multi level includes. Cycle detection -//TODO +//TODO //TODO: Implement a runOrder consideration - clean results based on run order. //TODO: runOrder vs setSource/touchSource //TODO: Advanced details: (below) @@ -106,4 +106,4 @@ Case "Running a single source". //TODO: dependents and reexecution //TODO: dependencies and reexecution //TODO: cleanAllResults clean -//TODO: cleanAll clean \ No newline at end of file +//TODO: cleanAll clean diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_MyProject.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_MyProject.res index f677ec42..c275b71a 100644 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_MyProject.res +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_MyProject.res @@ -1,4 +1,5 @@ open ForTS_Types @genType -let getResult = (_p: myProject): option => My_ErrorValue.EError->Error->Some +let getResult = (_p: myProject): option> => + My_ErrorValue.EError->Error->Some diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Result.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Result.res new file mode 100644 index 00000000..407c4a2c --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Result.res @@ -0,0 +1,18 @@ +open ForTS_Types + +@genType let isError = (r: result_<'a, 'e>): bool => Belt.Result.isError(r) +@genType let isOk = (r: result_<'a, 'e>): bool => Belt.Result.isOk(r) + +@genType +let getError = (r: result_<'a, 'e>): option<'e> => + switch r { + | Ok(_) => None + | Error(e) => Some(e) + } + +@genType +let getValue = (r: result_<'a, 'e>): option<'a> => + switch r { + | Ok(v) => Some(v) + | Error(_) => None + } diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Result/ForTS_Result_InternalValue.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Result/ForTS_Result_InternalValue.res deleted file mode 100644 index fd55b6ff..00000000 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Result/ForTS_Result_InternalValue.res +++ /dev/null @@ -1,18 +0,0 @@ -open ForTS_Types - -@genType let isError = (r: result_internalValue): bool => Belt.Result.isError(r) -@genType let isOk = (r: result_internalValue): bool => Belt.Result.isOk(r) - -@genType -let getError = (r: result_internalValue): option => - switch r { - | Ok(_) => None - | Error(e) => Some(e) - } - -@genType -let getValue = (r: result_internalValue): option => - switch r { - | Ok(v) => Some(v) - | Error(_) => None - } diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Types.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Types.res index 4345c405..7efcc47d 100644 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Types.res +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Types.res @@ -6,7 +6,7 @@ @genType.opaque type recordLike = MyInterface_InternalValue_RecordLike.t @genType.opaque type internalVoid = int @genType.opaque type errorValue = My_ErrorValue.t -@genType.opaque type result_internalValue = result // There has to be a type for each result permutation +@genType.opaque type result_<'a, 'e> = result<'a, 'e> // There has to be a type for each result permutation @genType.opaque type myProject = {name: string} //There is no need to map option<> as it becomes nullable From fdc7f06f082f3bc2685f53fbc5e5164a0e04bb9a Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Thu, 18 Aug 2022 15:32:26 +0200 Subject: [PATCH 17/53] result --- .../ForTS_InternalValue.res | 2 +- .../ForTS_InternalValue_RecordLike.res | 2 +- .../ForTS_InternalValue_Void.res | 2 +- .../ForTS/ForTS_MyProject.res | 2 +- .../ForTS/ForTS_Result_.res | 18 ++++++++ .../{ForTS_Types.res => ForTS_Types_.res} | 2 +- .../ForTS/ForTS_Reducer_ErrorValue.res | 0 .../ForTS/ForTS_Result.res | 2 +- .../rescript/ForTS/ForTS_SquiggleProject.res | 1 + .../rescript/ForTS/ForTS_SquiggleValue.res | 1 + .../ForTS_SquiggleValue_Array.res | 1 + .../ForTS_SquiggleValue_ArrayString.res | 1 + .../ForTS_SquiggleValue_Date.res | 1 + .../ForTS_SquiggleValue_Declaration.res | 1 + .../ForTS_SquiggleValue_Distribution.res | 1 + .../ForTS_SquiggleValue_Lambda.res | 1 + .../ForTS_SquiggleValue_Record.res | 1 + .../ForTS_SquiggleValue_TimeDuration.res | 1 + .../ForTS_SquiggleValue_Type.res | 1 + .../ForTS_SquiggleValue_Void.res | 1 + .../rescript/ForTS/ForTS_SquiggleValue_tag.ts | 19 +++++++++ .../src/rescript/ForTS/ForTS__Functions.res | 0 .../src/rescript/ForTS/ForTS__Types.res | 20 +++++++++ .../rescript/Reducer/Reducer_ErrorValue.res | 3 +- .../Reducer_Peggy/Reducer_Peggy_Parse.res | 1 - .../ReducerProject/ReducerProject.res | 26 ------------ .../src/rescript/TypescriptInterface.res | 42 ------------------- 27 files changed, 76 insertions(+), 77 deletions(-) create mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Result_.res rename packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/{ForTS_Types.res => ForTS_Types_.res} (80%) create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_Reducer_ErrorValue.res rename packages/squiggle-lang/src/rescript/{Dummy-TypeScriptingRescript => }/ForTS/ForTS_Result.res (95%) create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleProject.res create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue.res create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Array.res create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_ArrayString.res create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Date.res create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Declaration.res create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Distribution.res create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Lambda.res create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Record.res create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_TimeDuration.res create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Type.res create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Void.res create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue_tag.ts create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS__Functions.res create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue.res index c85474da..783f97ec 100644 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue.res +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue.res @@ -1,4 +1,4 @@ -open ForTS_Types +open ForTS_Types_ @module("ForTS_InternalValue_tag") @scope("InternalValueTag") external ivtVoid_: int = "IvtVoid" diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_RecordLike.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_RecordLike.res index 630cd72e..7a28ea75 100644 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_RecordLike.res +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_RecordLike.res @@ -1,4 +1,4 @@ -open ForTS_Types +open ForTS_Types_ @genType let toString = (v: recordLike): string => diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_Void.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_Void.res index 7b5b85e6..7fae9341 100644 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_Void.res +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_Void.res @@ -1,3 +1,3 @@ -open ForTS_Types +open ForTS_Types_ @genType let toString = (_value: internalVoid): string => MyInterface_InternalValue_Void.toString diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_MyProject.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_MyProject.res index c275b71a..23550d16 100644 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_MyProject.res +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_MyProject.res @@ -1,4 +1,4 @@ -open ForTS_Types +open ForTS_Types_ @genType let getResult = (_p: myProject): option> => diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Result_.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Result_.res new file mode 100644 index 00000000..f29b1657 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Result_.res @@ -0,0 +1,18 @@ +open ForTS_Types_ + +@genType let isError = (r: result_<'a, 'e>): bool => Belt.Result.isError(r) +@genType let isOk = (r: result_<'a, 'e>): bool => Belt.Result.isOk(r) + +@genType +let getError = (r: result_<'a, 'e>): option<'e> => + switch r { + | Ok(_) => None + | Error(e) => Some(e) + } + +@genType +let getValue = (r: result_<'a, 'e>): option<'a> => + switch r { + | Ok(v) => Some(v) + | Error(_) => None + } diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Types.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Types_.res similarity index 80% rename from packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Types.res rename to packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Types_.res index 7efcc47d..980c90bd 100644 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Types.res +++ b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Types_.res @@ -6,7 +6,7 @@ @genType.opaque type recordLike = MyInterface_InternalValue_RecordLike.t @genType.opaque type internalVoid = int @genType.opaque type errorValue = My_ErrorValue.t -@genType.opaque type result_<'a, 'e> = result<'a, 'e> // There has to be a type for each result permutation +@genType.opaque type result_<'a, 'e> = result<'a, 'e> @genType.opaque type myProject = {name: string} //There is no need to map option<> as it becomes nullable diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Reducer_ErrorValue.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Reducer_ErrorValue.res new file mode 100644 index 00000000..e69de29b diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Result.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res similarity index 95% rename from packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Result.res rename to packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res index 407c4a2c..19bf6ee0 100644 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Result.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res @@ -1,4 +1,4 @@ -open ForTS_Types +open ForTS__Types @genType let isError = (r: result_<'a, 'e>): bool => Belt.Result.isError(r) @genType let isOk = (r: result_<'a, 'e>): bool => Belt.Result.isOk(r) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleProject.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleProject.res new file mode 100644 index 00000000..80c79902 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleProject.res @@ -0,0 +1 @@ +open ForTS__Types \ No newline at end of file diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue.res new file mode 100644 index 00000000..80c79902 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue.res @@ -0,0 +1 @@ +open ForTS__Types \ No newline at end of file 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 new file mode 100644 index 00000000..80c79902 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Array.res @@ -0,0 +1 @@ +open ForTS__Types \ No newline at end of file diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_ArrayString.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_ArrayString.res new file mode 100644 index 00000000..80c79902 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_ArrayString.res @@ -0,0 +1 @@ +open ForTS__Types \ No newline at end of file diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Date.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Date.res new file mode 100644 index 00000000..80c79902 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Date.res @@ -0,0 +1 @@ +open ForTS__Types \ No newline at end of file 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 new file mode 100644 index 00000000..80c79902 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Declaration.res @@ -0,0 +1 @@ +open ForTS__Types \ No newline at end of file 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 new file mode 100644 index 00000000..80c79902 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Distribution.res @@ -0,0 +1 @@ +open ForTS__Types \ No newline at end of file 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 new file mode 100644 index 00000000..80c79902 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Lambda.res @@ -0,0 +1 @@ +open ForTS__Types \ No newline at end of file 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 new file mode 100644 index 00000000..80c79902 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Record.res @@ -0,0 +1 @@ +open ForTS__Types \ No newline at end of file diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_TimeDuration.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_TimeDuration.res new file mode 100644 index 00000000..80c79902 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_TimeDuration.res @@ -0,0 +1 @@ +open ForTS__Types \ No newline at end of file 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 new file mode 100644 index 00000000..80c79902 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Type.res @@ -0,0 +1 @@ +open ForTS__Types \ No newline at end of file diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Void.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Void.res new file mode 100644 index 00000000..80c79902 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Void.res @@ -0,0 +1 @@ +open ForTS__Types \ No newline at end of file diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue_tag.ts b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue_tag.ts new file mode 100644 index 00000000..afa4a4ba --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue_tag.ts @@ -0,0 +1,19 @@ +enum SquiggleValueTag { + SvtArray, + SvtArrayString, + SvtBool, + SvtCall, + SvtDate, + SvtDeclaration, + SvtDistribution + SvtLambda, + SvtModule, + SvtNumber, + SvtRecord, + SvtString, + SvtSymbol, + SvtTimeDuration, + SvtType, + SvtTypeIdentifier, + SvtVoid, +} \ No newline at end of file diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Functions.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Functions.res new file mode 100644 index 00000000..e69de29b diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res new file mode 100644 index 00000000..71bd56c2 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res @@ -0,0 +1,20 @@ +/* +The reason this is not ExpressionValue is that ExpressionValue is becoming a parametric type +to allow expressions for different domains. +So we rename it right away not cause a compatibility problem +*/ +@genType.opaque type result_<'a, 'e> = result<'a, 'e> + +@genType.opaque type squiggleValue +@genType.opaque type squiggleValue_Array +@genType.opaque type squiggleValue_ArrayString +@genType.opaque type squiggleValue_Date +@genType.opaque type squiggleValue_Declaration +@genType.opaque type squiggleValue_Distribution +@genType.opaque type squiggleValue_Lambda +@genType.opaque type squiggleValue_Record +@genType.opaque type squiggleValue_TimeDuration +@genType.opaque type squiggleValue_Type +@genType.opaque type squiggleValue_Void +@genType.opaque type reducer_errorValue + diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res index d908bf93..de1dd93f 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res @@ -1,7 +1,7 @@ +//FIXME: Move this under ForTS @gentype.import("peggy") @genType.as("LocationRange") type location -@genType type errorValue = | REArityError(option, int, int) | REArrayIndexNotFound(string, int) @@ -23,7 +23,6 @@ type errorValue = type t = errorValue -@genType let errorToString = err => switch err { | REArityError(_oFnName, arity, usedArity) => 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 193cb893..59002761 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 @@ -11,7 +11,6 @@ external castWithLocation: Js.Exn.t => withLocation = "%identity" let syntaxErrorToLocation = (error: Js.Exn.t): Reducer_ErrorValue.location => castWithLocation(error)["location"] -@genType let parse = (expr: string): result => try { Ok(parse__(expr)) diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res index 5ed0858b..ba6e8bb0 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res @@ -10,7 +10,6 @@ module ProjectItem = ReducerProject_ProjectItem module T = ReducerProject_T module Topology = ReducerProject_Topology -@genType.opaque type reducerProject = T.t type t = T.t @@ -232,34 +231,29 @@ To run a group of source codes and get results/bindings, the necessary methods a A project has a public field tag with a constant value "reducerProject" project = {tag: "reducerProject"} */ -@genType let createProject = (): reducerProject => Private.createProject()->T.Private.castFromInternalProject /* Answer all the source ids of all the sources in the project. */ -@genType let getSourceIds = (project: reducerProject): array => project->T.Private.castToInternalProject->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) /* Gets the source for a given source id. */ -@genType let getSource = (project: reducerProject, sourceId: string): option => project->T.Private.castToInternalProject->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) @@ -268,14 +262,12 @@ 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->T.Private.castToInternalProject->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 @@ -283,21 +275,18 @@ let cleanAll = (project: reducerProject): unit => Cleans results. Compilation stays untouched to be able to re-run the source. 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) /* Cleans all results. Compilations remains untouched to rerun the source. */ -@genType let cleanAllResults = (project: reducerProject): unit => project->T.Private.castToInternalProject->Private.cleanAllResults /* To set the includes one first has to call "parseIncludes". The parsed includes or the parser error is returned. */ -@genType let getIncludes = (project: reducerProject, sourceId: string): result< array, Reducer_ErrorValue.errorValue, @@ -306,7 +295,6 @@ let getIncludes = (project: reducerProject, sourceId: string): result< /* 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) @@ -315,35 +303,30 @@ let getContinues = (project: reducerProject, sourceId: string): array => It is used to define a continuation that is not visible in the source code. You can chain source codes on the web interface for example */ -@genType let setContinues = (project: reducerProject, sourceId: string, continues: array): unit => project->T.Private.castToInternalProject->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) /* The sources returned are dependent on this */ -@genType let getDependents = (project: reducerProject, sourceId: string): array => project->T.Private.castToInternalProject->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 /* 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) @@ -352,7 +335,6 @@ Parse includes so that you can load them before running. Load includes by calling getIncludes which returns the includes that have been parsed. 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) @@ -361,28 +343,24 @@ Parse the source code if it is not done already. Use getRawParse to get the parse tree. You would need this function if you want to see the parse tree without running the source code. */ -@genType let rawParse = (project: reducerProject, sourceId: string): unit => project->T.Private.castToInternalProject->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) /* 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 /* Get the bindings after running this source file or the project */ -@genType let getExternalBindings = ( project: reducerProject, sourceId: string, @@ -392,7 +370,6 @@ let getExternalBindings = ( /* Get the result after running this source file or the project */ -@genType let getExternalResult = (project: reducerProject, sourceId: string): option< result, > => project->T.Private.castToInternalProject->Private.getExternalResult(sourceId) @@ -402,7 +379,6 @@ This is a convenience function to get the result of a single source without crea However, without a project, you cannot handle include directives. The source has to be include free */ -@genType let evaluate = (sourceCode: string): ('r, 'b) => { let (result, continuation) = Private.evaluate(sourceCode) ( @@ -411,13 +387,11 @@ let evaluate = (sourceCode: string): ('r, 'b) => { ) } -@genType let setEnvironment = ( project: reducerProject, environment: ExternalExpressionValue.environment, ): unit => project->T.Private.castToInternalProject->Private.setEnvironment(environment) -@genType let foreignFunctionInterface = ( lambdaValue: ExternalExpressionValue.lambdaValue, argArray: array, diff --git a/packages/squiggle-lang/src/rescript/TypescriptInterface.res b/packages/squiggle-lang/src/rescript/TypescriptInterface.res index 64629731..b3d2e827 100644 --- a/packages/squiggle-lang/src/rescript/TypescriptInterface.res +++ b/packages/squiggle-lang/src/rescript/TypescriptInterface.res @@ -34,30 +34,6 @@ type resultString = result @genType let makeSampleSetDist = SampleSetDist.make -// @genType -// let evaluate = Reducer.evaluate - -// @genType -// let evaluateUsingOptions = Reducer.evaluateUsingOptions - -@genType -let parse = Reducer_Peggy_Parse.parse - -// @genType -// let evaluatePartialUsingExternalBindings = Reducer.evaluatePartialUsingExternalBindings - -@genType -type externalBindings = Reducer.externalBindings - -@genType -type expressionValue = ReducerInterface_ExternalExpressionValue.t - -@genType -type recordEV = ReducerInterface_ExternalExpressionValue.record - -@genType -type errorValue = Reducer_ErrorValue.errorValue - @genType let toPointSet = GenericDist.toPointSet @@ -70,30 +46,12 @@ type discreteShape = PointSetTypes.discreteShape @genType type continuousShape = PointSetTypes.continuousShape -@genType -let errorValueToString = Reducer_ErrorValue.errorToString - @genType let distributionErrorToString = DistributionTypes.Error.toString -@genType -type lambdaValue = ReducerInterface_ExternalExpressionValue.lambdaValue - -@genType -type lambdaDeclaration = ReducerInterface_ExternalExpressionValue.lambdaDeclaration - @genType let defaultSamplingEnv = DistributionOperation.defaultEnv -@genType -type environment = ReducerInterface_ExternalExpressionValue.environment - -@genType -let defaultEnvironment = ReducerInterface_ExternalExpressionValue.defaultEnvironment - -// @genType -// let foreignFunctionInterface = Reducer.foreignFunctionInterface - @genType type declarationArg = Declaration.arg From f0ba68f64abfb4f1e263df94bd185699ca739a1e Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 19 Aug 2022 17:13:31 +0200 Subject: [PATCH 18/53] project --- .../ReducerProject/ReducerProject_test.res | 12 +- .../ReducerProject_tutorial_test.res | 32 +- packages/squiggle-lang/src/js/index.ts | 317 +++++++++--------- .../rescript/ForTS/ForTS_ReducerProject.res | 192 +++++++++++ .../ForTS/ForTS_Reducer_ErrorValue.res | 1 + .../rescript/ForTS/ForTS_SquiggleProject.res | 1 - .../rescript/ForTS/ForTS_SquiggleValue.res | 194 ++++++++++- .../ForTS_SquiggleValue_Array.res | 6 +- .../ForTS_SquiggleValue_ArrayString.res | 1 - .../ForTS_SquiggleValue_Date.res | 1 - .../ForTS_SquiggleValue_Declaration.res | 1 - .../ForTS_SquiggleValue_Distribution.res | 1 - .../ForTS_SquiggleValue_Lambda.res | 1 - .../ForTS_SquiggleValue_Module.res | 4 + .../ForTS_SquiggleValue_Record.res | 5 +- .../ForTS_SquiggleValue_TimeDuration.res | 1 - .../ForTS_SquiggleValue_Type.res | 5 +- .../ForTS_SquiggleValue_Void.res | 1 - .../rescript/ForTS/ForTS_SquiggleValue_tag.ts | 2 +- .../src/rescript/ForTS/ForTS__Functions.res | 1 + .../src/rescript/ForTS/ForTS__Types.res | 31 +- ...ducerInterface_ExternalExpressionValue.res | 8 +- ...ducerInterface_InternalExpressionValue.res | 11 + .../ReducerProject/ReducerProject.res | 211 +----------- .../ReducerProject_ProjectItem.res | 8 +- .../ReducerProject_ProjectItem_T.res | 6 +- 26 files changed, 621 insertions(+), 433 deletions(-) create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res delete mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleProject.res delete mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_ArrayString.res delete mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Date.res delete mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Declaration.res delete mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Distribution.res delete mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Lambda.res create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Module.res delete mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_TimeDuration.res delete mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Void.res diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res index b4ede1a4..7b3a75ff 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res @@ -1,6 +1,6 @@ @@warning("-44") -module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue -module Project = ReducerProject +module InternalExpressionValue = ReducerInterface_InternalExpressionValue +module Project = ForTS_ReducerProject module Bindings = Reducer_Bindings open Jest @@ -11,14 +11,14 @@ open Expect.Operators let runFetchResult = (project, sourceId) => { Project.run(project, sourceId) - Project.getExternalResult(project, sourceId)->ExternalExpressionValue.toStringOptionResult + Project.getResult(project, sourceId)->InternalExpressionValue.toStringOptionResult } let runFetchBindings = (project, sourceId) => { Project.run(project, sourceId) - Project.getExternalBindings(project, sourceId) - ->ExternalExpressionValue.EvModule - ->ExternalExpressionValue.toString + Project.getBindings(project, sourceId) + ->InternalExpressionValue.IEvBindings + ->InternalExpressionValue.toString } test("setting continuation", () => { diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_test.res index 0d2b92f3..61dbc11e 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_test.res @@ -1,6 +1,6 @@ @@warning("-44") -module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue -module Project = ReducerProject +module InternalExpressionValue = ReducerInterface_InternalExpressionValue +module Project = ForTS_ReducerProject module Bindings = Reducer_Bindings open Jest @@ -45,13 +45,13 @@ Case "Running a single source". Note that getResult returns None if the source has not been run. Getting None means you have forgotten to run the source. */ - let result = project->Project.getExternalResult("main") - let bindings = project->Project.getExternalBindings("main") + let result = project->Project.getResult("main") + let bindings = project->Project.getBindings("main") /* Let's display the result and bindings */ ( - result->ExternalExpressionValue.toStringOptionResult, - bindings->ExternalExpressionValue.EvModule->ExternalExpressionValue.toString, + result->InternalExpressionValue.toStringOptionResult, + bindings->InternalExpressionValue.IEvBindings->InternalExpressionValue.toString, )->expect == ("Ok(3)", "@{}") /* You've got 3 with empty bindings. */ }) @@ -60,12 +60,12 @@ Case "Running a single source". let project = Project.createProject() Project.setSource(project, "main", "1 + 2") Project.runAll(project) - let result = Project.getExternalResult(project, "main") - let bindings = Project.getExternalBindings(project, "main") + let result = Project.getResult(project, "main") + let bindings = Project.getBindings(project, "main") /* Now you have external bindings and external result. */ ( - result->ExternalExpressionValue.toStringOptionResult, - bindings->ExternalExpressionValue.EvModule->ExternalExpressionValue.toString, + result->InternalExpressionValue.toStringOptionResult, + bindings->InternalExpressionValue.IEvBindings->InternalExpressionValue.toString, )->expect == ("Ok(3)", "@{}") }) @@ -74,13 +74,13 @@ Case "Running a single source". let project = Project.createProject() /* Optional. Set your custom environment anytime before running */ - Project.setEnvironment(project, ExternalExpressionValue.defaultEnvironment) + Project.setEnvironment(project, InternalExpressionValue.defaultEnvironment) Project.setSource(project, "main", "1 + 2") Project.runAll(project) - let result = Project.getExternalResult(project, "main") - let _bindings = Project.getExternalBindings(project, "main") - result->ExternalExpressionValue.toStringOptionResult->expect == "Ok(3)" + let result = Project.getResult(project, "main") + let _bindings = Project.getBindings(project, "main") + result->InternalExpressionValue.toStringOptionResult->expect == "Ok(3)" }) test("shortcut", () => { @@ -88,8 +88,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->ExternalExpressionValue.toStringResult, - bindings->ExternalExpressionValue.EvModule->ExternalExpressionValue.toString, + result->InternalExpressionValue.toStringResult, + bindings->InternalExpressionValue.IEvBindings->InternalExpressionValue.toString, )->expect == ("Ok(3)", "@{}") }) }) diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index acee005c..c27d5058 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -1,19 +1,14 @@ import * as _ from "lodash"; import type { environment, - expressionValue, externalBindings, errorValue, } from "../rescript/TypescriptInterface.gen"; import { defaultEnvironment, - evaluatePartialUsingExternalBindings, - evaluateUsingOptions, - foreignFunctionInterface, } from "../rescript/TypescriptInterface.gen"; export { makeSampleSetDist, - errorValueToString, distributionErrorToString, } from "../rescript/TypescriptInterface.gen"; export type { @@ -23,12 +18,7 @@ export type { } from "../rescript/TypescriptInterface.gen"; export type { errorValue, externalBindings as bindings, jsImports }; import { - jsValueToBinding, - jsValueToExpressionValue, - jsValue, - rescriptExport, squiggleExpression, - convertRawToTypescript, lambdaValue, } from "./rescript_interop"; import { result, resultMap, tag, tagged } from "./types"; @@ -44,162 +34,167 @@ export let defaultSamplingInputs: environment = { xyPointLength: 10000, }; -export function run( - squiggleString: string, - bindings?: externalBindings, - environment?: environment, - imports?: jsImports -): result { - let b = bindings ? bindings : defaultBindings; - let i = imports ? imports : defaultImports; - let e = environment ? environment : defaultEnvironment; - let res: result = evaluateUsingOptions( - { externalBindings: mergeImportsWithBindings(b, i), environment: e }, - squiggleString - ); - return resultMap(res, (x) => createTsExport(x, e)); -} -// Run Partial. A partial is a block of code that doesn't return a value -export function runPartial( - squiggleString: string, - bindings?: externalBindings, - environment?: environment, - imports?: jsImports -): result { - let b = bindings ? bindings : defaultBindings; - let i = imports ? imports : defaultImports; - let e = environment ? environment : defaultEnvironment; +/* + All those functions below are invalid since the introduction of ReducerProject +*/ +// export function run( +// squiggleString: string, +// bindings?: externalBindings, +// environment?: environment, +// imports?: jsImports +// ): result { +// let b = bindings ? bindings : defaultBindings; +// let i = imports ? imports : defaultImports; +// let e = environment ? environment : defaultEnvironment; +// let res: result = evaluateUsingOptions( +// { externalBindings: mergeImportsWithBindings(b, i), environment: e }, +// squiggleString +// ); +// return resultMap(res, (x) => createTsExport(x, e)); +// } - return evaluatePartialUsingExternalBindings( - squiggleString, - mergeImportsWithBindings(b, i), - e - ); -} +// // Run Partial. A partial is a block of code that doesn't return a value +// export function runPartial( +// squiggleString: string, +// bindings?: externalBindings, +// environment?: environment, +// imports?: jsImports +// ): result { +// let b = bindings ? bindings : defaultBindings; +// let i = imports ? imports : defaultImports; +// let e = environment ? environment : defaultEnvironment; -export function runForeign( - fn: lambdaValue, - args: jsValue[], - environment?: environment -): result { - let e = environment ? environment : defaultEnvironment; - let res: result = foreignFunctionInterface( - fn, - args.map(jsValueToExpressionValue), - e - ); - return resultMap(res, (x) => createTsExport(x, e)); -} +// return evaluatePartialUsingExternalBindings( +// squiggleString, +// mergeImportsWithBindings(b, i), +// e +// ); +// } -function mergeImportsWithBindings( - bindings: externalBindings, - imports: jsImports -): externalBindings { - let transformedImports = Object.fromEntries( - Object.entries(imports).map(([key, value]) => [ - "$" + key, - jsValueToBinding(value), - ]) - ); - return _.merge(bindings, transformedImports); -} +// jsValueToExpressionValue is invalid +// export function runForeign( +// fn: lambdaValue, +// args: jsValue[], +// environment?: environment +// ): result { +// let e = environment ? environment : defaultEnvironment; +// let res: result = foreignFunctionInterface( +// fn, +// args.map(jsValueToExpressionValue), +// e +// ); +// return resultMap(res, (x) => createTsExport(x, e)); +// } -type jsImports = { [key: string]: jsValue }; +// function mergeImportsWithBindings( +// bindings: externalBindings, +// imports: jsImports +// ): externalBindings { +// let transformedImports = Object.fromEntries( +// Object.entries(imports).map(([key, value]) => [ +// "$" + key, +// jsValueToBinding(value), +// ]) +// ); +// return _.merge(bindings, transformedImports); +// } -export let defaultImports: jsImports = {}; -export let defaultBindings: externalBindings = {}; +// type jsImports = { [key: string]: jsValue }; -export function mergeBindings( - allBindings: externalBindings[] -): externalBindings { - return allBindings.reduce((acc, x) => ({ ...acc, ...x })); -} +// export let defaultImports: jsImports = {}; +// export let defaultBindings: externalBindings = {}; -function createTsExport( - x: expressionValue, - environment: environment -): squiggleExpression { - switch (x) { - case "EvVoid": - return tag("void", ""); - default: { - switch (x.tag) { - case "EvArray": - // genType doesn't convert anything more than 2 layers down into {tag: x, value: x} - // format, leaving it as the raw values. This converts the raw values - // directly into typescript values. - // - // The casting here is because genType is about the types of the returned - // values, claiming they are fully recursive when that's not actually the - // case - return tag( - "array", - x.value.map( - (arrayItem): squiggleExpression => - convertRawToTypescript( - arrayItem as unknown as rescriptExport, - environment - ) - ) - ); - case "EvArrayString": - return tag("arraystring", x.value); - case "EvBool": - return tag("boolean", x.value); - case "EvCall": - return tag("call", x.value); - case "EvLambda": - return tag("lambda", x.value); - case "EvDistribution": - return tag("distribution", new Distribution(x.value, environment)); - case "EvNumber": - return tag("number", x.value); - case "EvRecord": - // genType doesn't support records, so we have to do the raw conversion ourself - let result: tagged<"record", { [key: string]: squiggleExpression }> = - tag( - "record", - _.mapValues(x.value, (x: unknown) => - convertRawToTypescript(x as rescriptExport, environment) - ) - ); - return result; - case "EvString": - return tag("string", x.value); - case "EvSymbol": - return tag("symbol", x.value); - case "EvDate": - return tag("date", x.value); - case "EvTimeDuration": - return tag("timeDuration", x.value); - case "EvDeclaration": - return tag("lambdaDeclaration", x.value); - case "EvTypeIdentifier": - return tag("typeIdentifier", x.value); - case "EvType": - let typeResult: tagged< - "type", - { [key: string]: squiggleExpression } - > = tag( - "type", - _.mapValues(x.value, (x: unknown) => - convertRawToTypescript(x as rescriptExport, environment) - ) - ); - return typeResult; - case "EvModule": - let moduleResult: tagged< - "module", - { [key: string]: squiggleExpression } - > = tag( - "module", - _.mapValues(x.value, (x: unknown) => - convertRawToTypescript(x as rescriptExport, environment) - ) - ); - return moduleResult; - } - } - } -} +// export function mergeBindings( +// allBindings: externalBindings[] +// ): externalBindings { +// return allBindings.reduce((acc, x) => ({ ...acc, ...x })); +// } + +// function createTsExport( +// x: expressionValue, +// environment: environment +// ): squiggleExpression { +// switch (x) { +// case "EvVoid": +// return tag("void", ""); +// default: { +// switch (x.tag) { +// case "EvArray": +// // genType doesn't convert anything more than 2 layers down into {tag: x, value: x} +// // format, leaving it as the raw values. This converts the raw values +// // directly into typescript values. +// // +// // The casting here is because genType is about the types of the returned +// // values, claiming they are fully recursive when that's not actually the +// // case +// return tag( +// "array", +// x.value.map( +// (arrayItem): squiggleExpression => +// convertRawToTypescript( +// arrayItem as unknown as rescriptExport, +// environment +// ) +// ) +// ); +// case "EvArrayString": +// return tag("arraystring", x.value); +// case "EvBool": +// return tag("boolean", x.value); +// case "EvCall": +// return tag("call", x.value); +// case "EvLambda": +// return tag("lambda", x.value); +// case "EvDistribution": +// return tag("distribution", new Distribution(x.value, environment)); +// case "EvNumber": +// return tag("number", x.value); +// case "EvRecord": +// // genType doesn't support records, so we have to do the raw conversion ourself +// let result: tagged<"record", { [key: string]: squiggleExpression }> = +// tag( +// "record", +// _.mapValues(x.value, (x: unknown) => +// convertRawToTypescript(x as rescriptExport, environment) +// ) +// ); +// return result; +// case "EvString": +// return tag("string", x.value); +// case "EvSymbol": +// return tag("symbol", x.value); +// case "EvDate": +// return tag("date", x.value); +// case "EvTimeDuration": +// return tag("timeDuration", x.value); +// case "EvDeclaration": +// return tag("lambdaDeclaration", x.value); +// case "EvTypeIdentifier": +// return tag("typeIdentifier", x.value); +// case "EvType": +// let typeResult: tagged< +// "type", +// { [key: string]: squiggleExpression } +// > = tag( +// "type", +// _.mapValues(x.value, (x: unknown) => +// convertRawToTypescript(x as rescriptExport, environment) +// ) +// ); +// return typeResult; +// case "EvModule": +// let moduleResult: tagged< +// "module", +// { [key: string]: squiggleExpression } +// > = tag( +// "module", +// _.mapValues(x.value, (x: unknown) => +// convertRawToTypescript(x as rescriptExport, environment) +// ) +// ); +// return moduleResult; +// } +// } +// } +// } diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res new file mode 100644 index 00000000..1dc08768 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res @@ -0,0 +1,192 @@ +open ForTS__Types +// If a module is built for TypeScript then it can only refer to ForTS__Types for other types and modules +// The exception is its implementation and private modules +module T = ReducerProject_T +module Private = ReducerProject.Private + +/* + PUBLIC FUNCTIONS +*/ + +/* +Creates a new project to hold the sources, executables, bindings, and other data. +The new project runs the sources according to their topological sorting because of the includes and continues. + +Any source can include or continue other sources. "Therefore, the project is a graph data structure." +The difference between including and continuing is that includes are stated inside the source code while continues are stated in the project. + +To run a group of source codes and get results/bindings, the necessary methods are +- setSource +- setContinues +- parseIncludes +- run or runAll +- getExternalBindings +- getExternalResult + +A project has a public field tag with a constant value "reducerProject" +project = {tag: "reducerProject"} +*/ +let createProject = (): reducerProject => Private.createProject()->T.Private.castFromInternalProject + +/* +Answer all the source ids of all the sources in the project. +*/ +let getSourceIds = (project: reducerProject): array => + project->T.Private.castToInternalProject->Private.getSourceIds + +/* +Sets the source for a given source Id. +*/ +let setSource = (project: reducerProject, sourceId: string, value: string): unit => + project->T.Private.castToInternalProject->Private.setSource(sourceId, value) + +/* +Gets the source for a given source id. +*/ +let getSource = (project: reducerProject, sourceId: string): option => + project->T.Private.castToInternalProject->Private.getSource(sourceId) + +/* +Touches the source for a given source id. This and dependent, sources are set to be re-evaluated. +*/ +let touchSource = (project: reducerProject, sourceId: string): unit => + project->T.Private.castToInternalProject->Private.touchSource(sourceId) + +/* +Cleans the compilation artifacts for a given source ID. The results stay untouched, so compilation won't be run again. + +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 +*/ +let clean = (project: reducerProject, sourceId: string): unit => + project->T.Private.castToInternalProject->Private.clean(sourceId) + +/* +Cleans all the compilation artifacts in all of the project +*/ +let cleanAll = (project: reducerProject): unit => + project->T.Private.castToInternalProject->Private.cleanAll + +/* +Cleans results. Compilation stays untouched to be able to re-run the source. +You would not do this if you were not trying to debug the source code. +*/ +let cleanResults = (project: reducerProject, sourceId: string): unit => + project->T.Private.castToInternalProject->Private.cleanResults(sourceId) + +/* +Cleans all results. Compilations remains untouched to rerun the source. +*/ +let cleanAllResults = (project: reducerProject): unit => + project->T.Private.castToInternalProject->Private.cleanAllResults + +/* +To set the includes one first has to call "parseIncludes". The parsed includes or the parser error is returned. +*/ +let getIncludes = (project: reducerProject, sourceId: string): result< + array, + Reducer_ErrorValue.errorValue, +> => project->T.Private.castToInternalProject->Private.getIncludes(sourceId) + +/* +Answers the source codes after which this source code is continuing +*/ +let getContinues = (project: reducerProject, sourceId: string): array => + project->T.Private.castToInternalProject->Private.getContinues(sourceId) + +/* + "continues" acts like hidden includes in the source. + It is used to define a continuation that is not visible in the source code. + You can chain source codes on the web interface for example +*/ +let setContinues = (project: reducerProject, sourceId: string, continues: array): unit => + project->T.Private.castToInternalProject->Private.setContinues(sourceId, continues) + +/* +This source depends on the array of sources returned. +*/ +let getDependencies = (project: reducerProject, sourceId: string): array => + project->T.Private.castToInternalProject->Private.getDependencies(sourceId) + +/* +The sources returned are dependent on this +*/ +let getDependents = (project: reducerProject, sourceId: string): array => + project->T.Private.castToInternalProject->Private.getDependents(sourceId) + +/* +Get the run order for the sources in the project. +*/ +let getRunOrder = (project: reducerProject): array => + project->T.Private.castToInternalProject->Private.getRunOrder + +/* +Get the run order to get the results of this specific source +*/ +let getRunOrderFor = (project: reducerProject, sourceId: string) => + project->T.Private.castToInternalProject->Private.getRunOrderFor(sourceId) + +/* +Parse includes so that you can load them before running. +Load includes by calling getIncludes which returns the includes that have been parsed. +It is your responsibility to load the includes before running. +*/module Topology = ReducerProject_Topology + +let parseIncludes = (project: reducerProject, sourceId: string): unit => + project->T.Private.castToInternalProject->Private.parseIncludes(sourceId) + +/* +Parse the source code if it is not done already. +Use getRawParse to get the parse tree. +You would need this function if you want to see the parse tree without running the source code. +*/ +let rawParse = (project: reducerProject, sourceId: string): unit => + project->T.Private.castToInternalProject->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. +*/ +let run = (project: reducerProject, sourceId: string): unit => + project->T.Private.castToInternalProject->Private.run(sourceId) + +/* +Runs all of the sources in a project. Their results and bindings will be available +*/ +let runAll = (project: reducerProject): unit => + project->T.Private.castToInternalProject->Private.runAll + +/* +Get the bindings after running this source file or the project +*/ +let getBindings = (project: reducerProject, sourceId: string): squiggleValue_Module => + project->T.Private.castToInternalProject->Private.getBindings(sourceId) + +/* +Get the result after running this source file or the project +*/ +let getResult = (project: reducerProject, sourceId: string): option< + result_, +> => project->T.Private.castToInternalProject->Private.getResult(sourceId) + +/* +This is a convenience function to get the result of a single source without creating a project. +However, without a project, you cannot handle include directives. +The source has to be include free +*/ +let evaluate = (sourceCode: string): ('r, 'b) => Private.evaluate(sourceCode) + +let setEnvironment = (project: reducerProject, environment: environment): unit => + project->T.Private.castToInternalProject->Private.setEnvironment(environment) + +let foreignFunctionInterface = ( + lambdaValue: squiggleValue_Lambda, + argArray: array, + environment: environment, +): result_ => { + let accessors = ReducerProject_ProjectAccessors_T.identityAccessorsWithEnvironment(environment) + Reducer_Expression_Lambda.foreignFunctionInterface( + lambdaValue, + argArray, + accessors, + Reducer_Expression.reduceExpressionInProject, + ) +} diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Reducer_ErrorValue.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Reducer_ErrorValue.res index e69de29b..8b137891 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Reducer_ErrorValue.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Reducer_ErrorValue.res @@ -0,0 +1 @@ + diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleProject.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleProject.res deleted file mode 100644 index 80c79902..00000000 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleProject.res +++ /dev/null @@ -1 +0,0 @@ -open ForTS__Types \ No newline at end of file diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue.res index 80c79902..12a73d64 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue.res @@ -1 +1,193 @@ -open ForTS__Types \ No newline at end of file +open ForTS__Types + +// Return values as they are if they are JavaScript types. + +@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +external svtArray_: int = "SvtArray" + +@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +external svtArrayString_: int = "SvtArrayString" + +@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +external svtBool_: int = "SvtBool" + +@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +external svtCall_: int = "SvtCall" + +@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +external svtDate_: int = "SvtDate" + +@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +external svtDeclaration_: int = "SvtDeclaration" + +@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +external svtDistribution_: int = "SvtDistribution" + +@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +external svtLambda_: int = "SvtLambda" + +@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +external svtModule_: int = "SvtModule" + +@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +external svtNumber_: int = "SvtNumber" + +@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +external svtRecord_: int = "SvtRecord" + +@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +external svtString_: int = "SvtString" + +@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +external svtSymbol_: int = "SvtSymbol" + +@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +external svtTimeDuration_: int = "SvtTimeDuration" + +@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +external svtType_: int = "SvtType" + +@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +external svtTypeIdentifier_: int = "SvtUndefined" + +@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +external svtVoid_: int = "SvtVoid" + +@genType +let getTag = (variant: squiggleValue) => + switch variant { + | IEvArray(_) => svtArray_ + | IEvArrayString(_) => svtArrayString_ + | IEvBool(_) => svtBool_ + | IEvCall(_) => svtCall_ //Impossible + | IEvDate(_) => svtDate_ + | IEvDeclaration(_) => svtDeclaration_ + | IEvDistribution(_) => svtDistribution_ + | IEvLambda(_) => svtLambda_ + | IEvBindings(_) => svtModule_ //Impossible + | IEvNumber(_) => svtNumber_ + | IEvRecord(_) => svtRecord_ + | IEvString(_) => svtString_ + | IEvSymbol(_) => svtSymbol_ + | IEvTimeDuration(_) => svtTimeDuration_ + | IEvType(_) => svtType_ + | IEvTypeIdentifier(_) => svtTypeIdentifier_ + | IEvVoid => svtVoid_ + } + +@genType +let toString = (variant: squiggleValue) => + ReducerInterface_InternalExpressionValue.toString(variant) + +@genType +let getArray = (variant: squiggleValue): option => + //FIXME: Convert + switch variant { + | IEvArray(arrayLike) => arrayLike->Some + | _ => None + } + +@genType +let getArrayString = (variant: squiggleValue): option> => + switch variant { + | IEvArrayString(value) => value->Some + | _ => None + } + +@genType +let getBool = (variant: squiggleValue): option => + switch variant { + | IEvBool(value) => value->Some + | _ => None + } + +@genType +let getCall = (variant: squiggleValue): option => + switch variant { + | IEvCall(value) => value->Some + | _ => None + } + +@genType +let getDate = (variant: squiggleValue): option => + switch variant { + | IEvDate(value) => value->Some + | _ => None + } + +@genType +let getDeclaration = (variant: squiggleValue): option => + switch variant { + | IEvDeclaration(value) => value->Some + | _ => None + } + +@genType +let getDistribution = (variant: squiggleValue): option => + switch variant { + | IEvDistribution(value) => value->Some + | _ => None + } + +@genType +let getLambda = (variant: squiggleValue): option => + switch variant { + | IEvLambda(value) => value->Some + | _ => None + } + +@genType +let getModule = (variant: squiggleValue): option => + switch variant { + | IEvBindings(value) => value->Some + | _ => None + } + +@genType +let getNumber = (variant: squiggleValue): option => + switch variant { + | IEvNumber(value) => value->Some + | _ => None + } + +@genType +let getRecord = (variant: squiggleValue): option => + switch variant { + | IEvRecord(value) => value->Some + | _ => None + } + +@genType +let getString = (variant: squiggleValue): option => + switch variant { + | IEvString(value) => value->Some + | _ => None + } + +@genType +let getSymbol = (variant: squiggleValue): option => + switch variant { + | IEvSymbol(value) => value->Some + | _ => None + } + +@genType +let getTimeDuration = (variant: squiggleValue): option => + switch variant { + | 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_Array.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Array.res index 80c79902..872a62c1 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 @@ -1 +1,5 @@ -open ForTS__Types \ No newline at end of file +open ForTS__Types +// Note: Internal representation will not be an array in the future. +// Thus we still to have a conversion +let getValues = (v: squiggleValue_Array): array => + ReducerInterface_InternalExpressionValue.arrayToValueArray(v) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_ArrayString.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_ArrayString.res deleted file mode 100644 index 80c79902..00000000 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_ArrayString.res +++ /dev/null @@ -1 +0,0 @@ -open ForTS__Types \ No newline at end of file diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Date.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Date.res deleted file mode 100644 index 80c79902..00000000 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Date.res +++ /dev/null @@ -1 +0,0 @@ -open ForTS__Types \ No newline at end of file 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 deleted file mode 100644 index 80c79902..00000000 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Declaration.res +++ /dev/null @@ -1 +0,0 @@ -open ForTS__Types \ No newline at end of file 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 deleted file mode 100644 index 80c79902..00000000 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Distribution.res +++ /dev/null @@ -1 +0,0 @@ -open ForTS__Types \ No newline at end of file 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 deleted file mode 100644 index 80c79902..00000000 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Lambda.res +++ /dev/null @@ -1 +0,0 @@ -open ForTS__Types \ No newline at end of file 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 new file mode 100644 index 00000000..0539c1d8 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Module.res @@ -0,0 +1,4 @@ +open ForTS__Types + +let getKeyValuePairs = (v: squiggleValue_Module): array<(string, squiggleValue)> => + ReducerInterface_InternalExpressionValue.nameSpaceToKeyValueArray(v) 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 80c79902..dfdd0bea 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 @@ -1 +1,4 @@ -open ForTS__Types \ No newline at end of file +open ForTS__Types + +let getKeyValuePairs = (value: squiggleValue_Record): array<(string, squiggleValue)> => + ReducerInterface_InternalExpressionValue.recordToKeyValuePairs(value) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_TimeDuration.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_TimeDuration.res deleted file mode 100644 index 80c79902..00000000 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_TimeDuration.res +++ /dev/null @@ -1 +0,0 @@ -open ForTS__Types \ No newline at end of file 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 80c79902..427a8fcb 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 @@ -1 +1,4 @@ -open ForTS__Types \ No newline at end of file +open ForTS__Types + +let getKeyValuePairs = (value: squiggleValue_Type): array<(string, squiggleValue)> => + ReducerInterface_InternalExpressionValue.recordToKeyValuePairs(value) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Void.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Void.res deleted file mode 100644 index 80c79902..00000000 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Void.res +++ /dev/null @@ -1 +0,0 @@ -open ForTS__Types \ No newline at end of file diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue_tag.ts b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue_tag.ts index afa4a4ba..9e4b34fd 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue_tag.ts +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue_tag.ts @@ -5,7 +5,7 @@ enum SquiggleValueTag { SvtCall, SvtDate, SvtDeclaration, - SvtDistribution + SvtDistribution, SvtLambda, SvtModule, SvtNumber, diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Functions.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Functions.res index e69de29b..8b137891 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Functions.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Functions.res @@ -0,0 +1 @@ + diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res index 71bd56c2..c7ac9210 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res @@ -1,20 +1,25 @@ -/* +/* The reason this is not ExpressionValue is that ExpressionValue is becoming a parametric type to allow expressions for different domains. So we rename it right away not cause a compatibility problem */ @genType.opaque type result_<'a, 'e> = result<'a, 'e> -@genType.opaque type squiggleValue -@genType.opaque type squiggleValue_Array -@genType.opaque type squiggleValue_ArrayString -@genType.opaque type squiggleValue_Date -@genType.opaque type squiggleValue_Declaration -@genType.opaque type squiggleValue_Distribution -@genType.opaque type squiggleValue_Lambda -@genType.opaque type squiggleValue_Record -@genType.opaque type squiggleValue_TimeDuration -@genType.opaque type squiggleValue_Type -@genType.opaque type squiggleValue_Void -@genType.opaque type reducer_errorValue +@genType.opaque type squiggleValue = ReducerInterface_InternalExpressionValue.t +@genType.opaque type squiggleValue_Array = ReducerInterface_InternalExpressionValue.squiggleArray +@genType.opaque +type squiggleValue_Declaration = ReducerInterface_InternalExpressionValue.lambdaDeclaration +@genType.opaque type squiggleValue_Module = ReducerInterface_InternalExpressionValue.nameSpace +@genType.opaque type squiggleValue_Lambda = ReducerInterface_InternalExpressionValue.lambdaValue +@genType.opaque type squiggleValue_Record = ReducerInterface_InternalExpressionValue.map +@genType.opaque type squiggleValue_Type = ReducerInterface_InternalExpressionValue.map +@genType.opaque type reducerErrorValue = Reducer_ErrorValue.errorValue +@genType.opaque type reducerProject = ReducerProject_T.t + +// From now on one should introduce any new types as opaque types +// Already existing open types we cannot dive in now +@genType type environment = GenericDist.env +@genType type squiggleValue_Distribution = DistributionTypes.genericDist + +//TODO: index.ts should use types from here or vice versa diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalExpressionValue.res index 185fb351..f3ecb0f4 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalExpressionValue.res @@ -16,18 +16,18 @@ type rec externalExpressionValue = | EvArrayString(array) | EvBool(bool) | EvCall(string) // External function call + | EvDate(Js.Date.t) + | EvDeclaration(lambdaDeclaration) | EvDistribution(DistributionTypes.genericDist) | EvLambda(lambdaValue) + | EvModule(record) | EvNumber(float) | EvRecord(record) | EvString(string) | EvSymbol(string) - | EvDate(Js.Date.t) | EvTimeDuration(float) - | EvDeclaration(lambdaDeclaration) - | EvTypeIdentifier(string) - | EvModule(record) | EvType(record) + | EvTypeIdentifier(string) | EvVoid and record = Js.Dict.t and lambdaValue = { diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res index a2994baa..7598be52 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res @@ -23,6 +23,7 @@ type rec t = | IEvType(map) | IEvTypeIdentifier(string) | IEvVoid +and squiggleArray = array and map = Belt.Map.String.t and nameSpace = NameSpace(Belt.Map.String.t) and lambdaValue = { @@ -32,6 +33,7 @@ and lambdaValue = { } and lambdaDeclaration = Declaration.declaration +type squiggleMap = map type internalExpressionValue = t type functionCall = (string, array) @@ -312,3 +314,12 @@ and nameSpaceFromTypeScriptBindings = ( r: ReducerInterface_ExternalExpressionValue.externalBindings, ): nameSpace => r->Js.Dict.entries->Belt.Map.String.fromArray->Belt.Map.String.map(e => toInternal(e))->NameSpace + +let nameSpaceToKeyValueArray = (nameSpace: nameSpace): array<(string, t)> => { + let NameSpace(container) = nameSpace + container->Belt.Map.String.toArray +} + +let arrayToValueArray = (arr: array): array => arr + +let recordToKeyValuePairs = (record: map): array<(string, t)> => record->Belt.Map.String.toArray diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res index ba6e8bb0..b09a44d9 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res @@ -3,14 +3,12 @@ module Bindings = Reducer_Bindings module Continuation = ReducerInterface_Value_Continuation module ErrorValue = Reducer_ErrorValue -module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue module InternalExpressionValue = ReducerInterface_InternalExpressionValue module ProjectAccessorsT = ReducerProject_ProjectAccessors_T module ProjectItem = ReducerProject_ProjectItem module T = ReducerProject_T module Topology = ReducerProject_Topology -type reducerProject = T.t type t = T.t module Private = { @@ -106,9 +104,6 @@ module Private = { Belt.Map.String.set(project["items"], sourceId, newItem)->T.Private.setFieldItems(project, _) } - let getExternalResult = (project: t, sourceId: string): ProjectItem.T.externalResultType => - project->getItem(sourceId)->ProjectItem.getExternalResult - 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, _) @@ -127,14 +122,11 @@ module Private = { let setEnvironment = (project: t, value: InternalExpressionValue.environment): unit => T.Private.setFieldEnvironment(project, value) - let getExternalBindings = ( - project: t, - sourceId: string, - ): ProjectItem.T.externalBindingsArgumentType => { + 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->InternalExpressionValue.nameSpaceToTypeScriptBindings + ofUser } let buildProjectAccessors = (project: t): ProjectAccessorsT.t => { @@ -208,202 +200,3 @@ module Private = { (getResult(project, "main")->Belt.Option.getWithDefault(IEvVoid->Ok), ofUser) } } - -/* - PUBLIC FUNCTIONS -*/ - -/* -Creates a new project to hold the sources, executables, bindings, and other data. -The new project runs the sources according to their topological sorting because of the includes and continues. - -Any source can include or continue other sources. "Therefore, the project is a graph data structure." -The difference between including and continuing is that includes are stated inside the source code while continues are stated in the project. - -To run a group of source codes and get results/bindings, the necessary methods are -- setSource -- setContinues -- parseIncludes -- run or runAll -- getExternalBindings -- getExternalResult - -A project has a public field tag with a constant value "reducerProject" -project = {tag: "reducerProject"} -*/ -let createProject = (): reducerProject => Private.createProject()->T.Private.castFromInternalProject - -/* -Answer all the source ids of all the sources in the project. -*/ -let getSourceIds = (project: reducerProject): array => - project->T.Private.castToInternalProject->Private.getSourceIds - -/* -Sets the source for a given source Id. -*/ -let setSource = (project: reducerProject, sourceId: string, value: string): unit => - project->T.Private.castToInternalProject->Private.setSource(sourceId, value) - -/* -Gets the source for a given source id. -*/ -let getSource = (project: reducerProject, sourceId: string): option => - project->T.Private.castToInternalProject->Private.getSource(sourceId) - -/* -Touches the source for a given source id. This and dependent, sources are set to be re-evaluated. -*/ -let touchSource = (project: reducerProject, sourceId: string): unit => - project->T.Private.castToInternalProject->Private.touchSource(sourceId) - -/* -Cleans the compilation artifacts for a given source ID. The results stay untouched, so compilation won't be run again. - -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 -*/ -let clean = (project: reducerProject, sourceId: string): unit => - project->T.Private.castToInternalProject->Private.clean(sourceId) - -/* -Cleans all the compilation artifacts in all of the project -*/ -let cleanAll = (project: reducerProject): unit => - project->T.Private.castToInternalProject->Private.cleanAll - -/* -Cleans results. Compilation stays untouched to be able to re-run the source. -You would not do this if you were not trying to debug the source code. -*/ -let cleanResults = (project: reducerProject, sourceId: string): unit => - project->T.Private.castToInternalProject->Private.cleanResults(sourceId) - -/* -Cleans all results. Compilations remains untouched to rerun the source. -*/ -let cleanAllResults = (project: reducerProject): unit => - project->T.Private.castToInternalProject->Private.cleanAllResults - -/* -To set the includes one first has to call "parseIncludes". The parsed includes or the parser error is returned. -*/ -let getIncludes = (project: reducerProject, sourceId: string): result< - array, - Reducer_ErrorValue.errorValue, -> => project->T.Private.castToInternalProject->Private.getIncludes(sourceId) - -/* -Answers the source codes after which this source code is continuing -*/ -let getContinues = (project: reducerProject, sourceId: string): array => - project->T.Private.castToInternalProject->Private.getContinues(sourceId) - -/* - "continues" acts like hidden includes in the source. - It is used to define a continuation that is not visible in the source code. - You can chain source codes on the web interface for example -*/ -let setContinues = (project: reducerProject, sourceId: string, continues: array): unit => - project->T.Private.castToInternalProject->Private.setContinues(sourceId, continues) - -/* -This source depends on the array of sources returned. -*/ -let getDependencies = (project: reducerProject, sourceId: string): array => - project->T.Private.castToInternalProject->Private.getDependencies(sourceId) - -/* -The sources returned are dependent on this -*/ -let getDependents = (project: reducerProject, sourceId: string): array => - project->T.Private.castToInternalProject->Private.getDependents(sourceId) - -/* -Get the run order for the sources in the project. -*/ -let getRunOrder = (project: reducerProject): array => - project->T.Private.castToInternalProject->Private.getRunOrder - -/* -Get the run order to get the results of this specific source -*/ -let getRunOrderFor = (project: reducerProject, sourceId: string) => - project->T.Private.castToInternalProject->Private.getRunOrderFor(sourceId) - -/* -Parse includes so that you can load them before running. -Load includes by calling getIncludes which returns the includes that have been parsed. -It is your responsibility to load the includes before running. -*/ -let parseIncludes = (project: reducerProject, sourceId: string): unit => - project->T.Private.castToInternalProject->Private.parseIncludes(sourceId) - -/* -Parse the source code if it is not done already. -Use getRawParse to get the parse tree. -You would need this function if you want to see the parse tree without running the source code. -*/ -let rawParse = (project: reducerProject, sourceId: string): unit => - project->T.Private.castToInternalProject->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. -*/ -let run = (project: reducerProject, sourceId: string): unit => - project->T.Private.castToInternalProject->Private.run(sourceId) - -/* -Runs all of the sources in a project. Their results and bindings will be available -*/ -let runAll = (project: reducerProject): unit => - project->T.Private.castToInternalProject->Private.runAll - -/* -Get the bindings after running this source file or the project -*/ -let getExternalBindings = ( - project: reducerProject, - sourceId: string, -): ExternalExpressionValue.record => - project->T.Private.castToInternalProject->Private.getExternalBindings(sourceId) - -/* -Get the result after running this source file or the project -*/ -let getExternalResult = (project: reducerProject, sourceId: string): option< - result, -> => project->T.Private.castToInternalProject->Private.getExternalResult(sourceId) - -/* -This is a convenience function to get the result of a single source without creating a project. -However, without a project, you cannot handle include directives. -The source has to be include free -*/ -let evaluate = (sourceCode: string): ('r, 'b) => { - let (result, continuation) = Private.evaluate(sourceCode) - ( - result->Belt.Result.map(InternalExpressionValue.toExternal), - continuation->InternalExpressionValue.nameSpaceToTypeScriptBindings, - ) -} - -let setEnvironment = ( - project: reducerProject, - environment: ExternalExpressionValue.environment, -): unit => project->T.Private.castToInternalProject->Private.setEnvironment(environment) - -let foreignFunctionInterface = ( - lambdaValue: ExternalExpressionValue.lambdaValue, - argArray: array, - environment: ExternalExpressionValue.environment, -) => { - let internallambdaValue = InternalExpressionValue.lambdaValueToInternal(lambdaValue) - let internalArgArray = argArray->Js.Array2.map(InternalExpressionValue.toInternal) - let accessors = ProjectAccessorsT.identityAccessorsWithEnvironment(environment) - Reducer_Expression_Lambda.foreignFunctionInterface( - internallambdaValue, - internalArgArray, - accessors, - Reducer_Expression.reduceExpressionInProject, - )->Belt.Result.map(InternalExpressionValue.toExternal) -} diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res index c07cebad..047937f1 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res @@ -20,19 +20,13 @@ let emptyItem = T.ProjectItem({ continues: [], includes: []->Ok, }) -// source -> rawParse -> includes -> expression -> continuation -> externalBindings -> result -> externalResult +// 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 toExternalBindings = continuation => - continuation->InternalExpressionValue.nameSpaceToTypeScriptBindings let getResult = (T.ProjectItem(r)): T.resultType => r.result -let getExternalResult = (T.ProjectItem(r)): T.externalResultType => - r.result->Belt.Option.map(opt => - opt->Belt.Result.map(value => value->InternalExpressionValue.toExternal) - ) let getContinues = (T.ProjectItem(r)): T.continuesType => r.continues let getIncludes = (T.ProjectItem(r)): T.includesType => r.includes 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 5d0846cf..13505fea 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem_T.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem_T.res @@ -14,12 +14,10 @@ type continuation = InternalExpressionValue.nameSpace type continuationArgumentType = InternalExpressionValue.nameSpace type continuationType = option type continuationResultType = option> -type externalBindingsArgumentType = ExternalExpressionValue.record -type externalBindingsType = option +type bindingsArgumentType = InternalExpressionValue.nameSpace +type bindingsType = option type resultArgumentType = result type resultType = option -type externalResultArgumentType = result -type externalResultType = option type continuesArgumentType = array type continuesType = array type includesArgumentType = string From af4070a34f332891aadadd520b4ec4f7a93a2675 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 19 Aug 2022 17:30:29 +0200 Subject: [PATCH 19/53] demolish external expression value --- .../ForTS_InternalValue.res | 37 ------------------- .../ForTS_InternalValue_RecordLike.res | 8 ---- .../ForTS_InternalValue_String.res | 1 - .../ForTS_InternalValue_Void.res | 3 -- .../ForTS_InternalValue_tag.tsx | 7 ---- .../ForTS/ForTS_MyProject.res | 5 --- .../ForTS/ForTS_Result_.res | 18 --------- .../ForTS/ForTS_Types_.res | 12 ------ .../My/My_ErrorValue.res | 10 ----- .../MyInterface/MyInterface_InternalValue.res | 9 ----- .../MyInterface_InternalValue_RecordLike.res | 12 ------ .../MyInterface_InternalValue_String.res | 1 - .../MyInterface_InternalValue_Void.res | 1 - .../MyInterface_InternalValue_T.res | 7 ---- .../Dummy-TypeScriptingRescript/README.md | 1 - .../rescript/ForTS/ForTS_ReducerProject.res | 2 +- .../src/rescript/ForTS/ForTS__Functions.res | 7 +++- .../src/rescript/ForTS/ForTS__Types.res | 7 ++-- 18 files changed, 11 insertions(+), 137 deletions(-) delete mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue.res delete mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_RecordLike.res delete mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_String.res delete mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_Void.res delete mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_tag.tsx delete mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_MyProject.res delete mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Result_.res delete mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Types_.res delete mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/My/My_ErrorValue.res delete mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue.res delete mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_RecordLike.res delete mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_String.res delete mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_Void.res delete mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue_T.res delete mode 100644 packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/README.md diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue.res deleted file mode 100644 index 783f97ec..00000000 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue.res +++ /dev/null @@ -1,37 +0,0 @@ -open ForTS_Types_ - -@module("ForTS_InternalValue_tag") @scope("InternalValueTag") -external ivtVoid_: int = "IvtVoid" -@module("ForTS_InternalValue_tag") @scope("InternalValueTag") -external ivtString_: int = "IvtString" -@module("ForTS_InternalValue_tag") @scope("InternalValueTag") -external ivtRecordLike_: int = "IvtRecordLike" - -@genType -let getTag = (variant: internalValue) => - switch variant { - | IvVoid(_) => ivtVoid_ - | IvString(_) => ivtString_ - | IvRecordLike(_) => ivtRecordLike_ - } - -@genType -let getVoid = (variant: internalValue): option => - switch variant { - | IvVoid(v) => Some(v) - | _ => None - } - -@genType -let getString = (variant: internalValue): option => - switch variant { - | IvString(s) => Some(s) - | _ => None - } - -@genType -let getRecordLike = (variant: internalValue): option => - switch variant { - | IvRecordLike(r) => Some(r) - | _ => None - } diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_RecordLike.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_RecordLike.res deleted file mode 100644 index 7a28ea75..00000000 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_RecordLike.res +++ /dev/null @@ -1,8 +0,0 @@ -open ForTS_Types_ - -@genType -let toString = (v: recordLike): string => - MyInterface_InternalValue_RecordLike.toString(v, MyInterface_InternalValue.toString) -@genType -let toArray = (v: recordLike): array<(string, internalValue)> => - MyInterface_InternalValue_RecordLike.toArray(v) diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_String.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_String.res deleted file mode 100644 index dffb46e1..00000000 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_String.res +++ /dev/null @@ -1 +0,0 @@ -@genType let toString = (value: string): string => value diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_Void.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_Void.res deleted file mode 100644 index 7fae9341..00000000 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_Void.res +++ /dev/null @@ -1,3 +0,0 @@ -open ForTS_Types_ - -@genType let toString = (_value: internalVoid): string => MyInterface_InternalValue_Void.toString diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_tag.tsx b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_tag.tsx deleted file mode 100644 index a8438d1d..00000000 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_InternalValue/ForTS_InternalValue_tag.tsx +++ /dev/null @@ -1,7 +0,0 @@ -enum InternalValueTag { - IvtVoid, - IvtString, - IvtRecordLike -} - - diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_MyProject.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_MyProject.res deleted file mode 100644 index 23550d16..00000000 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_MyProject.res +++ /dev/null @@ -1,5 +0,0 @@ -open ForTS_Types_ - -@genType -let getResult = (_p: myProject): option> => - My_ErrorValue.EError->Error->Some diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Result_.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Result_.res deleted file mode 100644 index f29b1657..00000000 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Result_.res +++ /dev/null @@ -1,18 +0,0 @@ -open ForTS_Types_ - -@genType let isError = (r: result_<'a, 'e>): bool => Belt.Result.isError(r) -@genType let isOk = (r: result_<'a, 'e>): bool => Belt.Result.isOk(r) - -@genType -let getError = (r: result_<'a, 'e>): option<'e> => - switch r { - | Ok(_) => None - | Error(e) => Some(e) - } - -@genType -let getValue = (r: result_<'a, 'e>): option<'a> => - switch r { - | Ok(v) => Some(v) - | Error(_) => None - } diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Types_.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Types_.res deleted file mode 100644 index 980c90bd..00000000 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/ForTS/ForTS_Types_.res +++ /dev/null @@ -1,12 +0,0 @@ -/* - Group all opaque types together for TS. - All other modules for TS should use this module -*/ -@genType.opaque type internalValue = MyInterface_InternalValue_T.t -@genType.opaque type recordLike = MyInterface_InternalValue_RecordLike.t -@genType.opaque type internalVoid = int -@genType.opaque type errorValue = My_ErrorValue.t -@genType.opaque type result_<'a, 'e> = result<'a, 'e> -@genType.opaque type myProject = {name: string} - -//There is no need to map option<> as it becomes nullable diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/My/My_ErrorValue.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/My/My_ErrorValue.res deleted file mode 100644 index a4a2304a..00000000 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/My/My_ErrorValue.res +++ /dev/null @@ -1,10 +0,0 @@ -type errorValue = EError | EErrorString(string) | EErrorNumber(float) -type t = errorValue - -let toString = (e: errorValue): string => { - switch e { - | EError => "Error" - | EErrorString(s) => s - | EErrorNumber(f) => Js.Float.toString(f) - } -} diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue.res deleted file mode 100644 index b4037564..00000000 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue.res +++ /dev/null @@ -1,9 +0,0 @@ -open MyInterface_InternalValue_T - -let rec toString = (v: internalValue): string => { - switch v { - | IvString(s) => MyInterface_InternalValue_String.toString(s) - | IvRecordLike(m) => MyInterface_InternalValue_RecordLike.toString(m, toString) - | IvVoid(_v) => MyInterface_InternalValue_Void.toString - } -} diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_RecordLike.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_RecordLike.res deleted file mode 100644 index ccf7bc45..00000000 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_RecordLike.res +++ /dev/null @@ -1,12 +0,0 @@ -type t = MyInterface_InternalValue_T.recordLike -let toString = (value: t, recToString) => { - let contents = - Belt.Map.String.mapWithKey(value, (key, value) => { - `${key}: ${recToString(value)}` - }) - ->Belt.Map.String.toArray - ->Js.Array2.joinWith(", ") - `{${contents}}` -} - -let toArray = (value: t) => Belt.Map.String.toArray(value) diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_String.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_String.res deleted file mode 100644 index 21c261ef..00000000 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_String.res +++ /dev/null @@ -1 +0,0 @@ -let toString = v => v diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_Void.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_Void.res deleted file mode 100644 index b41f0b82..00000000 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue/MyInterface_InternalValue_Void.res +++ /dev/null @@ -1 +0,0 @@ -let toString = "Void" diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue_T.res b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue_T.res deleted file mode 100644 index c37ef95a..00000000 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/MyInterface/MyInterface_InternalValue_T.res +++ /dev/null @@ -1,7 +0,0 @@ -type rec internalValue = - | IvString(string) - | IvRecordLike(recordLike) - | IvVoid(int) -and recordLike = Belt.Map.String.t - -type t = internalValue diff --git a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/README.md b/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/README.md deleted file mode 100644 index 93dd1be2..00000000 --- a/packages/squiggle-lang/src/rescript/Dummy-TypeScriptingRescript/README.md +++ /dev/null @@ -1 +0,0 @@ -To be trashed. Experimental code \ No newline at end of file diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res index 1dc08768..77d5fbe9 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res @@ -129,7 +129,7 @@ let getRunOrderFor = (project: reducerProject, sourceId: string) => Parse includes so that you can load them before running. Load includes by calling getIncludes which returns the includes that have been parsed. It is your responsibility to load the includes before running. -*/module Topology = ReducerProject_Topology +*/ module Topology = ReducerProject_Topology let parseIncludes = (project: reducerProject, sourceId: string): unit => project->T.Private.castToInternalProject->Private.parseIncludes(sourceId) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Functions.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Functions.res index 8b137891..6a22297a 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Functions.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Functions.res @@ -1 +1,6 @@ - +open ForTS__Types +/* +Global variables, functions, helpers, etc. +*/ +@genType +let defaultEnvironment: environment = DistributionOperation.defaultEnv diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res index c7ac9210..1914e740 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res @@ -1,10 +1,10 @@ +@genType.opaque type result_<'a, 'e> = result<'a, 'e> + /* The reason this is not ExpressionValue is that ExpressionValue is becoming a parametric type to allow expressions for different domains. So we rename it right away not cause a compatibility problem */ -@genType.opaque type result_<'a, 'e> = result<'a, 'e> - @genType.opaque type squiggleValue = ReducerInterface_InternalExpressionValue.t @genType.opaque type squiggleValue_Array = ReducerInterface_InternalExpressionValue.squiggleArray @genType.opaque @@ -17,7 +17,8 @@ type squiggleValue_Declaration = ReducerInterface_InternalExpressionValue.lambda @genType.opaque type reducerProject = ReducerProject_T.t -// From now on one should introduce any new types as opaque types +// From now on one should introduce any new types as opaque types. +// Exception: The intended type is really a JavaScript type or record. Not by coincidence // Already existing open types we cannot dive in now @genType type environment = GenericDist.env @genType type squiggleValue_Distribution = DistributionTypes.genericDist From e9c55fe8025939a11d870c8df012c365de8e8c96 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 19 Aug 2022 17:33:13 +0200 Subject: [PATCH 20/53] demolish FFI --- .../rescript/ForTS/ForTS_ReducerProject.res | 33 +++++++++++-------- 1 file changed, 20 insertions(+), 13 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res index 77d5fbe9..b79012f4 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res @@ -177,16 +177,23 @@ let evaluate = (sourceCode: string): ('r, 'b) => Private.evaluate(sourceCode) let setEnvironment = (project: reducerProject, environment: environment): unit => project->T.Private.castToInternalProject->Private.setEnvironment(environment) -let foreignFunctionInterface = ( - lambdaValue: squiggleValue_Lambda, - argArray: array, - environment: environment, -): result_ => { - let accessors = ReducerProject_ProjectAccessors_T.identityAccessorsWithEnvironment(environment) - Reducer_Expression_Lambda.foreignFunctionInterface( - lambdaValue, - argArray, - accessors, - Reducer_Expression.reduceExpressionInProject, - ) -} +/* +Foreign function interface is intentionally demolished. +There is another way to do that: Umur. +Also there is no more conversion from javascript to squiggle values currently. +If the conversion to the new project is too difficult, I can add it later. +*/ + +// let foreignFunctionInterface = ( +// lambdaValue: squiggleValue_Lambda, +// argArray: array, +// environment: environment, +// ): result_ => { +// let accessors = ReducerProject_ProjectAccessors_T.identityAccessorsWithEnvironment(environment) +// Reducer_Expression_Lambda.foreignFunctionInterface( +// lambdaValue, +// argArray, +// accessors, +// Reducer_Expression.reduceExpressionInProject, +// ) +// } From 975b1ffda8c9ee3e55a986a5060d2ebd2f60f642 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 19 Aug 2022 18:04:24 +0200 Subject: [PATCH 21/53] error value --- .../src/rescript/ForTS/ForTS_Reducer_ErrorValue.res | 10 ++++++++++ .../squiggle-lang/src/rescript/ForTS/ForTS__Types.res | 3 ++- .../src/rescript/Reducer/Reducer_ErrorValue.res | 6 +++--- .../Reducer/Reducer_Peggy/Reducer_Peggy_Parse.res | 4 ++-- 4 files changed, 17 insertions(+), 6 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Reducer_ErrorValue.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Reducer_ErrorValue.res index 8b137891..32541a06 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Reducer_ErrorValue.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Reducer_ErrorValue.res @@ -1 +1,11 @@ +open ForTS__Types +@genType +let toString = (e: reducerErrorValue): string => Reducer_ErrorValue.errorToString(e) + +@genType +let getLocation = (e: reducerErrorValue): option => + switch e { + | RESyntaxError(_, optionalLocation) => optionalLocation + | _ => None + } diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res index 1914e740..c382576d 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res @@ -1,4 +1,6 @@ @genType.opaque type result_<'a, 'e> = result<'a, 'e> +@genType.opaque type reducerErrorValue = Reducer_ErrorValue.errorValue +@genType type syntaxErrorLocation = Reducer_ErrorValue.syntaxErrorLocation /* The reason this is not ExpressionValue is that ExpressionValue is becoming a parametric type @@ -13,7 +15,6 @@ type squiggleValue_Declaration = ReducerInterface_InternalExpressionValue.lambda @genType.opaque type squiggleValue_Lambda = ReducerInterface_InternalExpressionValue.lambdaValue @genType.opaque type squiggleValue_Record = ReducerInterface_InternalExpressionValue.map @genType.opaque type squiggleValue_Type = ReducerInterface_InternalExpressionValue.map -@genType.opaque type reducerErrorValue = Reducer_ErrorValue.errorValue @genType.opaque type reducerProject = ReducerProject_T.t diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res index de1dd93f..3ff122ca 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res @@ -1,6 +1,6 @@ -//FIXME: Move this under ForTS +//TODO: Do not export here but in ForTS__Types @gentype.import("peggy") @genType.as("LocationRange") -type location +type syntaxErrorLocation type errorValue = | REArityError(option, int, int) @@ -17,7 +17,7 @@ type errorValue = | REOperationError(Operation.operationError) | RERecordPropertyNotFound(string, string) | RESymbolNotFound(string) - | RESyntaxError(string, option) + | RESyntaxError(string, option) | RETodo(string) // To do | REUnitNotFound(string) 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 59002761..8ecff48c 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 @@ -5,10 +5,10 @@ type node = {"type": string} @module("./Reducer_Peggy_GeneratedParser.js") external parse__: string => node = "parse" -type withLocation = {"location": Reducer_ErrorValue.location} +type withLocation = {"location": Reducer_ErrorValue.syntaxErrorLocation} external castWithLocation: Js.Exn.t => withLocation = "%identity" -let syntaxErrorToLocation = (error: Js.Exn.t): Reducer_ErrorValue.location => +let syntaxErrorToLocation = (error: Js.Exn.t): Reducer_ErrorValue.syntaxErrorLocation => castWithLocation(error)["location"] let parse = (expr: string): result => From bc7f1317da3232941ba27e0f92d6f03de3e83c64 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 19 Aug 2022 18:27:50 +0200 Subject: [PATCH 22/53] fix project test --- .../ReducerInterface_InternalExpressionValue.res | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res index 7598be52..a715054b 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res @@ -135,7 +135,7 @@ let toStringResult = x => let toStringOptionResult = x => switch x { - | Some(a) => `${toStringResult(a)})` + | Some(a) => toStringResult(a) | None => "None" } From 610fa0227e3fe82fcfc4211353a7427c35bc6304 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 19 Aug 2022 18:28:03 +0200 Subject: [PATCH 23/53] opaque result --- .../squiggle-lang/src/rescript/TypescriptInterface.res | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/TypescriptInterface.res b/packages/squiggle-lang/src/rescript/TypescriptInterface.res index b3d2e827..241b1fa2 100644 --- a/packages/squiggle-lang/src/rescript/TypescriptInterface.res +++ b/packages/squiggle-lang/src/rescript/TypescriptInterface.res @@ -1,3 +1,4 @@ +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 @@ -23,13 +24,13 @@ type symbolicDist = SymbolicDistTypes.symbolicDist type distributionError = DistributionTypes.error @genType -type resultDist = result +type resultDist = result_ @genType -type resultFloat = result +type resultFloat = result_ @genType -type resultString = result +type resultString = result_ @genType let makeSampleSetDist = SampleSetDist.make From 3c1a49e44de8122e60ccd2ee9105177714eeada0 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 19 Aug 2022 18:28:19 +0200 Subject: [PATCH 24/53] index.ts --- packages/squiggle-lang/src/js/index.ts | 29 ++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index c27d5058..15346d67 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -1,14 +1,32 @@ +/* Some of the types have moved to ForTS__Types. +Needs to be reimported here if necessary and distribution related + +We only need distribution related extras for back compatibility. Umur + +Instead of a global function namespace we should use modules under ForTS directly maybe renaming them for ease. + +.e.g. Project.run(project) +.e.g. Distribution.makeSampleSetDist + +*/ + + import * as _ from "lodash"; import type { environment, + expressionValue, externalBindings, errorValue, } from "../rescript/TypescriptInterface.gen"; import { defaultEnvironment, + evaluatePartialUsingExternalBindings, + evaluateUsingOptions, + foreignFunctionInterface, } from "../rescript/TypescriptInterface.gen"; export { makeSampleSetDist, + errorValueToString, distributionErrorToString, } from "../rescript/TypescriptInterface.gen"; export type { @@ -18,7 +36,12 @@ export type { } from "../rescript/TypescriptInterface.gen"; export type { errorValue, externalBindings as bindings, jsImports }; import { + jsValueToBinding, + jsValueToExpressionValue, + jsValue, + rescriptExport, squiggleExpression, + convertRawToTypescript, lambdaValue, } from "./rescript_interop"; import { result, resultMap, tag, tagged } from "./types"; @@ -35,9 +58,8 @@ export let defaultSamplingInputs: environment = { }; -/* - All those functions below are invalid since the introduction of ReducerProject -*/ +/* Umur: All the functions below are invalid. ForTS_Reducer project is the new way to do this. */ + // export function run( // squiggleString: string, // bindings?: externalBindings, @@ -72,7 +94,6 @@ export let defaultSamplingInputs: environment = { // ); // } -// jsValueToExpressionValue is invalid // export function runForeign( // fn: lambdaValue, // args: jsValue[], From 14ceaa2667d1c033e191fc8d421e54099ef08c38 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 19 Aug 2022 19:54:20 +0200 Subject: [PATCH 25/53] missing genType --- .../rescript/ForTS/ForTS_ReducerProject.res | 25 ++++++++++++++++++- .../ForTS_SquiggleValue_Array.res | 2 ++ .../ForTS_SquiggleValue_Module.res | 1 + .../ForTS_SquiggleValue_Record.res | 1 + .../ForTS_SquiggleValue_Type.res | 1 + .../src/rescript/TypescriptInterface.res | 2 +- 6 files changed, 30 insertions(+), 2 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res index b79012f4..47416dbf 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res @@ -26,29 +26,34 @@ To run a group of source codes and get results/bindings, the necessary methods a A project has a public field tag with a constant value "reducerProject" project = {tag: "reducerProject"} */ +@genType let createProject = (): reducerProject => Private.createProject()->T.Private.castFromInternalProject /* Answer all the source ids of all the sources in the project. */ +@genType let getSourceIds = (project: reducerProject): array => project->T.Private.castToInternalProject->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) /* Gets the source for a given source id. */ +@genType let getSource = (project: reducerProject, sourceId: string): option => project->T.Private.castToInternalProject->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) @@ -57,12 +62,14 @@ 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->T.Private.castToInternalProject->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 @@ -70,18 +77,21 @@ let cleanAll = (project: reducerProject): unit => Cleans results. Compilation stays untouched to be able to re-run the source. 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) /* Cleans all results. Compilations remains untouched to rerun the source. */ +@genType let cleanAllResults = (project: reducerProject): unit => project->T.Private.castToInternalProject->Private.cleanAllResults /* To set the includes one first has to call "parseIncludes". The parsed includes or the parser error is returned. */ +@genType let getIncludes = (project: reducerProject, sourceId: string): result< array, Reducer_ErrorValue.errorValue, @@ -90,6 +100,7 @@ let getIncludes = (project: reducerProject, sourceId: string): result< /* 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) @@ -98,30 +109,35 @@ let getContinues = (project: reducerProject, sourceId: string): array => It is used to define a continuation that is not visible in the source code. You can chain source codes on the web interface for example */ +@genType let setContinues = (project: reducerProject, sourceId: string, continues: array): unit => project->T.Private.castToInternalProject->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) /* The sources returned are dependent on this */ +@genType let getDependents = (project: reducerProject, sourceId: string): array => project->T.Private.castToInternalProject->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 /* 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) @@ -131,6 +147,7 @@ Load includes by calling getIncludes which returns the includes that have been p It is your responsibility to load the includes before running. */ module Topology = ReducerProject_Topology +@genType let parseIncludes = (project: reducerProject, sourceId: string): unit => project->T.Private.castToInternalProject->Private.parseIncludes(sourceId) @@ -139,30 +156,35 @@ Parse the source code if it is not done already. Use getRawParse to get the parse tree. You would need this function if you want to see the parse tree without running the source code. */ +@genType let rawParse = (project: reducerProject, sourceId: string): unit => project->T.Private.castToInternalProject->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) /* 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 /* Get the bindings after running this source file or the project */ +@genType let getBindings = (project: reducerProject, sourceId: string): squiggleValue_Module => project->T.Private.castToInternalProject->Private.getBindings(sourceId) /* Get the result after running this source file or the project */ +@genType let getResult = (project: reducerProject, sourceId: string): option< result_, > => project->T.Private.castToInternalProject->Private.getResult(sourceId) @@ -172,8 +194,9 @@ This is a convenience function to get the result of a single source without crea However, without a project, you cannot handle include directives. The source has to be include free */ -let evaluate = (sourceCode: string): ('r, 'b) => Private.evaluate(sourceCode) +@genType let evaluate = (sourceCode: string): ('r, 'b) => Private.evaluate(sourceCode) +@genType let setEnvironment = (project: reducerProject, environment: environment): unit => project->T.Private.castToInternalProject->Private.setEnvironment(environment) 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 872a62c1..e90b493b 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 @@ -1,5 +1,7 @@ open ForTS__Types // Note: Internal representation will not be an array in the future. // Thus we still to have a conversion + +@genType let getValues = (v: squiggleValue_Array): array => ReducerInterface_InternalExpressionValue.arrayToValueArray(v) 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 0539c1d8..0583d676 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 @@ -1,4 +1,5 @@ open ForTS__Types +@genType let getKeyValuePairs = (v: squiggleValue_Module): array<(string, squiggleValue)> => ReducerInterface_InternalExpressionValue.nameSpaceToKeyValueArray(v) 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 dfdd0bea..5fa0da2d 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 @@ -1,4 +1,5 @@ open ForTS__Types +@genType let getKeyValuePairs = (value: squiggleValue_Record): array<(string, squiggleValue)> => ReducerInterface_InternalExpressionValue.recordToKeyValuePairs(value) 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 427a8fcb..b0a91495 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 @@ -1,4 +1,5 @@ open ForTS__Types +@genType let getKeyValuePairs = (value: squiggleValue_Type): array<(string, squiggleValue)> => ReducerInterface_InternalExpressionValue.recordToKeyValuePairs(value) diff --git a/packages/squiggle-lang/src/rescript/TypescriptInterface.res b/packages/squiggle-lang/src/rescript/TypescriptInterface.res index 241b1fa2..35c964ed 100644 --- a/packages/squiggle-lang/src/rescript/TypescriptInterface.res +++ b/packages/squiggle-lang/src/rescript/TypescriptInterface.res @@ -12,7 +12,7 @@ The below few seem to work fine. In the future there's definitely more work to d type samplingParams = GenericDist.env @genType -type genericDist = DistributionTypes.genericDist +type genericDist = squiggleValue_Distribution @genType type sampleSetDist = SampleSetDist.t From 3e3ae504985f0a3a586b810d40bad034955ca4f8 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 19 Aug 2022 20:09:26 +0200 Subject: [PATCH 26/53] fix getIncldues result --- .../squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res index 47416dbf..393f3186 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res @@ -92,7 +92,7 @@ let cleanAllResults = (project: reducerProject): unit => To set the includes one first has to call "parseIncludes". The parsed includes or the parser error is returned. */ @genType -let getIncludes = (project: reducerProject, sourceId: string): result< +let getIncludes = (project: reducerProject, sourceId: string): result_< array, Reducer_ErrorValue.errorValue, > => project->T.Private.castToInternalProject->Private.getIncludes(sourceId) From a9ce3ca40dc325124f4e529e62084512968d1d9e Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 19 Aug 2022 20:11:43 +0200 Subject: [PATCH 27/53] fix errorValue --- .../squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res index 393f3186..a195a046 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res @@ -94,7 +94,7 @@ To set the includes one first has to call "parseIncludes". The parsed includes o @genType let getIncludes = (project: reducerProject, sourceId: string): result_< array, - Reducer_ErrorValue.errorValue, + reducerErrorValue, > => project->T.Private.castToInternalProject->Private.getIncludes(sourceId) /* From decc12637f4b320ed015d188f528b6e6c7aa1832 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 19 Aug 2022 20:23:30 +0200 Subject: [PATCH 28/53] bind common type --- packages/squiggle-lang/src/rescript/TypescriptInterface.res | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/squiggle-lang/src/rescript/TypescriptInterface.res b/packages/squiggle-lang/src/rescript/TypescriptInterface.res index 35c964ed..bcee094a 100644 --- a/packages/squiggle-lang/src/rescript/TypescriptInterface.res +++ b/packages/squiggle-lang/src/rescript/TypescriptInterface.res @@ -9,7 +9,7 @@ The below few seem to work fine. In the future there's definitely more work to d */ @genType -type samplingParams = GenericDist.env +type samplingParams = environment @genType type genericDist = squiggleValue_Distribution From f573c326d25eace4989293943ddc362cb999d0fc Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 19 Aug 2022 20:56:45 +0200 Subject: [PATCH 29/53] demolish ExternalValue --- .../__tests__/Reducer/Reducer_Helpers.res | 4 - .../__tests__/Reducer/Reducer_TestHelpers.res | 16 +-- ...leLibrary_FunctionRegistryLibrary_test.res | 8 +- .../ForTS_SquiggleValue_Module.res | 2 +- .../Reducer_Bindings/Reducer_Bindings.res | 4 +- .../Reducer_Expression/Reducer_Expression.res | 11 -- ...ducerInterface_InternalExpressionValue.res | 116 +++--------------- .../ReducerInterface_StdLib.res | 2 - 8 files changed, 31 insertions(+), 132 deletions(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Helpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Helpers.res index 05eb1b01..91bd5866 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Helpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Helpers.res @@ -15,8 +15,4 @@ let removeDefaultsInternal = (iev: InternalExpressionValue.t) => { } } -let removeDefaultsExternal = (ev: ExternalExpressionValue.t): ExternalExpressionValue.t => - ev->InternalExpressionValue.toInternal->removeDefaultsInternal->InternalExpressionValue.toExternal - let rRemoveDefaultsInternal = r => Belt.Result.map(r, removeDefaultsInternal) -let rRemoveDefaultsExternal = r => Belt.Result.map(r, removeDefaultsExternal) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res index d32457e6..34a21573 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_TestHelpers.res @@ -1,7 +1,7 @@ module ErrorValue = Reducer_ErrorValue module Expression = Reducer_Expression module ExpressionT = Reducer_Expression_T -module ExternalExpressionValue = ReducerInterface.ExternalExpressionValue +module InternalExpressionValue = ReducerInterface.InternalExpressionValue open Jest open Expect @@ -9,8 +9,8 @@ open Expect let unwrapRecord = rValue => rValue->Belt.Result.flatMap(value => switch value { - | ExternalExpressionValue.EvRecord(aRecord) => Ok(aRecord) - | _ => ErrorValue.RETodo("TODO: External bindings must be returned")->Error + | InternalExpressionValue.IEvRecord(aRecord) => Ok(aRecord) + | _ => ErrorValue.RETodo("TODO: Internal bindings must be returned")->Error } ) @@ -18,15 +18,15 @@ let expectParseToBe = (code: string, answer: string) => Expression.BackCompatible.parse(code)->ExpressionT.toStringResult->expect->toBe(answer) let expectEvalToBe = (code: string, answer: string) => - Expression.BackCompatible.evaluateStringAsExternal(code) - ->Reducer_Helpers.rRemoveDefaultsExternal - ->ExternalExpressionValue.toStringResult + Expression.BackCompatible.evaluateString(code) + ->Reducer_Helpers.rRemoveDefaultsInternal + ->InternalExpressionValue.toStringResult ->expect ->toBe(answer) let expectEvalError = (code: string) => - Expression.BackCompatible.evaluateStringAsExternal(code) - ->ExternalExpressionValue.toStringResult + Expression.BackCompatible.evaluateString(code) + ->InternalExpressionValue.toStringResult ->expect ->toMatch("Error\(") diff --git a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res index dd23d994..693dffa5 100644 --- a/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res +++ b/packages/squiggle-lang/__tests__/SquiggleLibrary/SquiggleLibrary_FunctionRegistryLibrary_test.res @@ -3,8 +3,8 @@ open Expect open Reducer_TestHelpers let expectEvalToBeOk = (code: string) => - Reducer_Expression.BackCompatible.evaluateStringAsExternal(code) - ->Reducer_Helpers.rRemoveDefaultsExternal + Reducer_Expression.BackCompatible.evaluateString(code) + ->Reducer_Helpers.rRemoveDefaultsInternal ->E.R.isOk ->expect ->toBe(true) @@ -92,8 +92,8 @@ describe("FunctionRegistry Library", () => { ((fn, example)) => { let responseType = example - ->Reducer_Expression.BackCompatible.evaluateStringAsExternal - ->E.R2.fmap(ReducerInterface_InternalExpressionValue.externalValueToValueType) + ->Reducer_Expression.BackCompatible.evaluateString + ->E.R2.fmap(ReducerInterface_InternalExpressionValue.valueToValueType) let expectedOutputType = fn.output |> E.O.toExn("") expect(responseType)->toEqual(Ok(expectedOutputType)) }, 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 0583d676..2c06b9d7 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 @@ -2,4 +2,4 @@ open ForTS__Types @genType let getKeyValuePairs = (v: squiggleValue_Module): array<(string, squiggleValue)> => - ReducerInterface_InternalExpressionValue.nameSpaceToKeyValueArray(v) + ReducerInterface_InternalExpressionValue.nameSpaceToKeyValuePairs(v) 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 3daeb98d..0f1c2037 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 @@ -76,8 +76,8 @@ let emptyModule: t = NameSpace(emptyMap) let emptyBindings = emptyModule let emptyNameSpace = emptyModule -let fromTypeScriptBindings = ReducerInterface_InternalExpressionValue.nameSpaceFromTypeScriptBindings -let toTypeScriptBindings = ReducerInterface_InternalExpressionValue.nameSpaceToTypeScriptBindings +// let fromTypeScriptBindings = ReducerInterface_InternalExpressionValue.nameSpaceFromTypeScriptBindings +// let toTypeScriptBindings = ReducerInterface_InternalExpressionValue.nameSpaceToTypeScriptBindings let toExpressionValue = (nameSpace: t): internalExpressionValue => IEvBindings(nameSpace) let fromExpressionValue = (aValue: internalExpressionValue): t => 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 b262a327..d350ad74 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 @@ -125,15 +125,4 @@ module BackCompatible = { let evaluateString = (peggyCode: string): result => parse(peggyCode)->Result.flatMap(evaluate) - - let evaluateAsExternal = (expression: t): result => - { - let accessors = ProjectAccessorsT.identityAccessors - expression->reduceExpressionInProject(accessors.stdLib, accessors) - }->Result.map(InternalExpressionValue.toExternal) - - let evaluateStringAsExternal = (peggyCode: string): result< - ExternalExpressionValue.t, - errorValue, - > => parse(peggyCode)->Result.flatMap(evaluateAsExternal) } diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res index a715054b..2f0dd7df 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res @@ -1,9 +1,9 @@ module ErrorValue = Reducer_ErrorValue module Extra_Array = Reducer_Extra_Array -type internalCode = ReducerInterface_ExternalExpressionValue.internalCode -type environment = ReducerInterface_ExternalExpressionValue.environment +type internalCode = Object +type environment = GenericDist.env -let defaultEnvironment = ReducerInterface_ExternalExpressionValue.defaultEnvironment +let defaultEnvironment: environment = DistributionOperation.defaultEnv type rec t = | IEvArray(array) // FIXME: Convert to MapInt @@ -38,29 +38,6 @@ type internalExpressionValue = t type functionCall = (string, array) -module Internal = { - module NameSpace = { - external castNameSpaceToHidden: nameSpace => ReducerInterface_ExternalExpressionValue.hiddenNameSpace = - "%identity" - external castHiddenToNameSpace: ReducerInterface_ExternalExpressionValue.hiddenNameSpace => nameSpace = - "%identity" - } - module Lambda = { - let toInternal = (v: ReducerInterface_ExternalExpressionValue.lambdaValue): lambdaValue => { - let p = v.parameters - let c = v.context->NameSpace.castHiddenToNameSpace - let b = v.body - {parameters: p, context: c, body: b} - } - and toExternal = (v: lambdaValue): ReducerInterface_ExternalExpressionValue.lambdaValue => { - let p = v.parameters - let c = v.context->NameSpace.castNameSpaceToHidden - let b = v.body - {parameters: p, context: c, body: b} - } - } -} - let rec toString = aValue => switch aValue { | IEvArray(anArray) => { @@ -147,7 +124,7 @@ let toStringResultOkless = (codeResult: result): strin let toStringResultRecord = x => switch x { - | Ok(a) => `Ok(${ReducerInterface_ExternalExpressionValue.toStringRecord(a)})` + | Ok(a) => `Ok(${toStringMap(a)})` | Error(m) => `Error(${ErrorValue.errorToString(m)})` } @@ -247,79 +224,18 @@ let functionCallSignatureToString = (functionCallSignature: functionCallSignatur `${fn}(${args->Js.Array2.map(valueTypeToString)->Js.Array2.toString})` } -let rec toExternal = (iev: t): ReducerInterface_ExternalExpressionValue.t => { - switch iev { - | IEvArray(v) => v->Belt.Array.map(e => toExternal(e))->EvArray - | IEvArrayString(v) => EvArrayString(v) - | IEvBool(v) => EvBool(v) - | IEvCall(v) => EvCall(v) - | IEvDeclaration(v) => { - let fn = lambdaValueToExternal(v.fn) - let args = v.args - EvDeclaration({fn: fn, args: args}) - } - | IEvDistribution(v) => EvDistribution(v) - | IEvLambda(v) => EvLambda(lambdaValueToExternal(v)) - | IEvNumber(v) => EvNumber(v) - | IEvRecord(v) => v->mapToExternal->EvRecord - | IEvString(v) => EvString(v) - | IEvSymbol(v) => EvSymbol(v) - | IEvDate(v) => EvDate(v) - | IEvTimeDuration(v) => EvTimeDuration(v) - | IEvType(v) => v->mapToExternal->EvType - | IEvTypeIdentifier(v) => EvTypeIdentifier(v) - | IEvBindings(v) => v->nameSpaceToTypeScriptBindings->EvModule - | IEvVoid => EvVoid - } -} -and mapToExternal = v => - v->Belt.Map.String.map(e => toExternal(e))->Belt.Map.String.toArray->Js.Dict.fromArray -and lambdaValueToExternal = Internal.Lambda.toExternal -and nameSpaceToTypeScriptBindings = ( - nameSpace: nameSpace, -): ReducerInterface_ExternalExpressionValue.externalBindings => { - let NameSpace(container) = nameSpace - Belt.Map.String.map(container, e => toExternal(e))->Belt.Map.String.toArray->Js.Dict.fromArray -} - -let rec toInternal = (ev: ReducerInterface_ExternalExpressionValue.t): t => { - switch ev { - | EvArray(v) => v->Belt.Array.map(e => toInternal(e))->IEvArray - | EvArrayString(v) => IEvArrayString(v) - | EvBool(v) => IEvBool(v) - | EvCall(v) => IEvCall(v) - | EvDate(v) => IEvDate(v) - | EvDeclaration(v) => { - let fn = lambdaValueToInternal(v.fn) - let args = v.args - IEvDeclaration({fn: fn, args: args}) - } - | EvDistribution(v) => IEvDistribution(v) - | EvLambda(v) => IEvLambda(lambdaValueToInternal(v)) - | EvModule(v) => v->nameSpaceFromTypeScriptBindings->IEvBindings - | EvNumber(v) => IEvNumber(v) - | EvRecord(v) => v->recordToInternal->IEvRecord - | EvString(v) => IEvString(v) - | EvSymbol(v) => IEvSymbol(v) - | EvTimeDuration(v) => IEvTimeDuration(v) - | EvType(v) => v->recordToInternal->IEvType - | EvTypeIdentifier(v) => IEvTypeIdentifier(v) - | EvVoid => IEvVoid - } -} -and recordToInternal = v => - v->Js.Dict.entries->Belt.Map.String.fromArray->Belt.Map.String.map(e => toInternal(e)) -and lambdaValueToInternal = Internal.Lambda.toInternal -and nameSpaceFromTypeScriptBindings = ( - r: ReducerInterface_ExternalExpressionValue.externalBindings, -): nameSpace => - r->Js.Dict.entries->Belt.Map.String.fromArray->Belt.Map.String.map(e => toInternal(e))->NameSpace - -let nameSpaceToKeyValueArray = (nameSpace: nameSpace): array<(string, t)> => { - let NameSpace(container) = nameSpace - container->Belt.Map.String.toArray -} - 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 +} diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res index 8beec882..a868eeb5 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_StdLib.res @@ -2,5 +2,3 @@ module Bindings = Reducer_Bindings let internalStdLib: Bindings.t = Bindings.emptyBindings->SquiggleLibrary_Math.makeBindings->SquiggleLibrary_Versions.makeBindings - -let externalStdLib = internalStdLib->Bindings.toTypeScriptBindings From d7ed87556651b54a7db94396d916131171c05252 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 19 Aug 2022 21:12:04 +0200 Subject: [PATCH 30/53] demolish external value --- .../__tests__/Reducer/Reducer_Helpers.res | 1 - .../Reducer_MathJsEval_test.res | 2 +- .../ReducerInterface_ExpressionValue_test.res | 6 +- .../src/rescript/Reducer/Reducer.res | 17 --- .../src/rescript/Reducer/Reducer.resi | 45 ------- .../Reducer_Expression/Reducer_Expression.res | 2 - .../Reducer_Expression_BindingsReplacer.res | 1 - .../ReducerInterface/ReducerInterface.res | 1 - ...ducerInterface_ExternalExpressionValue.res | 111 ------------------ .../ReducerInterface_GenericDistribution.resi | 2 +- ...ducerInterface_InternalExpressionValue.res | 21 ---- .../ReducerProject_ProjectItem_T.res | 1 - 12 files changed, 5 insertions(+), 205 deletions(-) delete mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer.res delete mode 100644 packages/squiggle-lang/src/rescript/Reducer/Reducer.resi delete mode 100644 packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalExpressionValue.res diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Helpers.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Helpers.res index 91bd5866..e915bfc1 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Helpers.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Helpers.res @@ -1,6 +1,5 @@ // Reducer_Helpers module ErrorValue = Reducer_ErrorValue -module ExternalExpressionValue = ReducerInterface.ExternalExpressionValue module InternalExpressionValue = ReducerInterface.InternalExpressionValue module Bindings = Reducer_Bindings 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 index ed00e957..e56c04d7 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsEval_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_MathJs/Reducer_MathJsEval_test.res @@ -1,5 +1,5 @@ module MathJs = Reducer_MathJs -module ErrorValue = Reducer.ErrorValue +module ErrorValue = Reducer_ErrorValue open Jest open ExpectJs diff --git a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_ExpressionValue_test.res b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_ExpressionValue_test.res index b09e20ae..71fd9f61 100644 --- a/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_ExpressionValue_test.res +++ b/packages/squiggle-lang/__tests__/ReducerInterface/ReducerInterface_ExpressionValue_test.res @@ -1,11 +1,11 @@ -open ReducerInterface.ExternalExpressionValue +open ReducerInterface.InternalExpressionValue open Jest open Expect describe("ExpressionValue", () => { - test("argsToString", () => expect([EvNumber(1.), EvString("a")]->argsToString)->toBe("1,'a'")) + test("argsToString", () => expect([IEvNumber(1.), IEvString("a")]->argsToString)->toBe("1,'a'")) test("toStringFunctionCall", () => - expect(("fn", [EvNumber(1.), EvString("a")])->toStringFunctionCall)->toBe("fn(1,'a')") + expect(("fn", [IEvNumber(1.), IEvString("a")])->toStringFunctionCall)->toBe("fn(1,'a')") ) }) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer.res deleted file mode 100644 index ca0f63f3..00000000 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.res +++ /dev/null @@ -1,17 +0,0 @@ -module ErrorValue = Reducer_ErrorValue -module Expression = Reducer_Expression -module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue - -type environment = ReducerInterface_InternalExpressionValue.environment -type errorValue = Reducer_ErrorValue.errorValue -type expressionValue = ExternalExpressionValue.t -type externalBindings = ReducerInterface_ExternalExpressionValue.externalBindings -type lambdaValue = ExternalExpressionValue.lambdaValue - -/* - Use Reducer_Project instead -*/ - -let defaultEnvironment = ExternalExpressionValue.defaultEnvironment - -// let defaultExternalBindings = ReducerInterface_StdLib.externalStdLib diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi b/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi deleted file mode 100644 index 8ac63abf..00000000 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer.resi +++ /dev/null @@ -1,45 +0,0 @@ -module ErrorValue = Reducer_ErrorValue -module Expression = Reducer_Expression - -@genType0 -type environment = ReducerInterface_ExternalExpressionValue.environment -@genType -type errorValue = Reducer_ErrorValue.errorValue -@genType -type expressionValue = ReducerInterface_ExternalExpressionValue.t -@genType -type externalBindings = ReducerInterface_ExternalExpressionValue.externalBindings -@genType -type lambdaValue = ReducerInterface_ExternalExpressionValue.lambdaValue - -// @genType -// let evaluateUsingOptions: ( -// ~environment: option, -// ~externalBindings: option< -// QuriSquiggleLang.ReducerInterface_ExternalExpressionValue.externalBindings, -// >, -// string, -// ) => result -// @genType -// let evaluatePartialUsingExternalBindings: ( -// string, -// QuriSquiggleLang.ReducerInterface_ExternalExpressionValue.externalBindings, -// QuriSquiggleLang.ReducerInterface_ExternalExpressionValue.environment, -// ) => result -// @genType -// let evaluate: string => result - -// let parse: string => result - -// @genType -// let foreignFunctionInterface: ( -// QuriSquiggleLang.ReducerInterface_ExternalExpressionValue.lambdaValue, -// array, -// QuriSquiggleLang.ReducerInterface_ExternalExpressionValue.environment, -// ) => result - -@genType -let defaultEnvironment: environment - -// @genType -// let defaultExternalBindings: externalBindings 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 d350ad74..f2b05036 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 @@ -2,7 +2,6 @@ module Bindings = Reducer_Bindings module BindingsReplacer = Reducer_Expression_BindingsReplacer module BuiltIn = Reducer_Dispatch_BuiltIn module ExpressionBuilder = Reducer_Expression_ExpressionBuilder -module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue module Extra = Reducer_Extra module InternalExpressionValue = ReducerInterface_InternalExpressionValue module Lambda = Reducer_Expression_Lambda @@ -13,7 +12,6 @@ module Result = Belt.Result module T = Reducer_Expression_T type errorValue = Reducer_ErrorValue.errorValue -type externalExpressionValue = ReducerInterface_ExternalExpressionValue.t type t = T.t /* 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 15ecfe58..6e38f833 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 @@ -7,7 +7,6 @@ module Bindings = Reducer_Bindings type errorValue = Reducer_ErrorValue.errorValue type expression = ExpressionT.expression type internalExpressionValue = InternalExpressionValue.t -type externalBindings = ReducerInterface_ExternalExpressionValue.externalBindings let isMacroName = (fName: string): bool => fName->Js.String2.startsWith("$$") diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface.res index ef27130b..d19b93b3 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface.res @@ -1,4 +1,3 @@ -module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue module ExternalLibrary = ReducerInterface_ExternalLibrary module InternalExpressionValue = ReducerInterface_InternalExpressionValue module StdLib = ReducerInterface_StdLib diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalExpressionValue.res deleted file mode 100644 index f3ecb0f4..00000000 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExternalExpressionValue.res +++ /dev/null @@ -1,111 +0,0 @@ -/* - Irreducible values. Reducer does not know about those. Only used for external calls - This is a configuration to to make external calls of those types -*/ -module Extra_Array = Reducer_Extra_Array -module ErrorValue = Reducer_ErrorValue -@genType.opaque -type internalCode = Object - -@genType.opaque -type hiddenNameSpace = Object - -@genType -type rec externalExpressionValue = - | EvArray(array) - | EvArrayString(array) - | EvBool(bool) - | EvCall(string) // External function call - | EvDate(Js.Date.t) - | EvDeclaration(lambdaDeclaration) - | EvDistribution(DistributionTypes.genericDist) - | EvLambda(lambdaValue) - | EvModule(record) - | EvNumber(float) - | EvRecord(record) - | EvString(string) - | EvSymbol(string) - | EvTimeDuration(float) - | EvType(record) - | EvTypeIdentifier(string) - | EvVoid -and record = Js.Dict.t -and lambdaValue = { - parameters: array, - context: hiddenNameSpace, - body: internalCode, -} -and lambdaDeclaration = Declaration.declaration - -@genType -type externalBindings = record - -@genType -type t = externalExpressionValue - -type functionCall = (string, array) - -let rec toString = aValue => - switch aValue { - | EvArray(anArray) => { - let args = anArray->Js.Array2.map(each => toString(each))->Js.Array2.toString - `[${args}]` - } - | EvArrayString(anArray) => { - let args = anArray->Js.Array2.toString - `[${args}]` - } - | EvBool(aBool) => Js.String.make(aBool) - | EvCall(fName) => `:${fName}` - | EvDate(date) => DateTime.Date.toString(date) - | EvDeclaration(d) => Declaration.toString(d, r => toString(EvLambda(r))) - | EvDistribution(dist) => GenericDist.toString(dist) - | EvLambda(lambdaValue) => `lambda(${Js.Array2.toString(lambdaValue.parameters)}=>internal code)` - | EvModule(m) => `@${m->toStringRecord}` - | EvNumber(aNumber) => Js.String.make(aNumber) - | EvRecord(aRecord) => aRecord->toStringRecord - | EvString(aString) => `'${aString}'` - | EvSymbol(aString) => `:${aString}` - | EvTimeDuration(t) => DateTime.Duration.toString(t) - | EvType(t) => `type${t->toStringRecord}` - | EvTypeIdentifier(id) => `#${id}` - | EvVoid => `()` - } -and toStringRecord = aRecord => { - let pairs = - aRecord - ->Js.Dict.entries - ->Js.Array2.map(((eachKey, eachValue)) => `${eachKey}: ${toString(eachValue)}`) - ->Js.Array2.toString - `{${pairs}}` -} - -let argsToString = (args: array): string => { - args->Js.Array2.map(arg => arg->toString)->Js.Array2.toString -} - -let toStringFunctionCall = ((fn, args)): string => `${fn}(${argsToString(args)})` - -let toStringResult = x => - switch x { - | Ok(a) => `Ok(${toString(a)})` - | Error(m) => `Error(${ErrorValue.errorToString(m)})` - } - -let toStringOptionResult = x => - switch x { - | Some(a) => toStringResult(a) - | None => `None` - } - -let toStringOption = x => - switch x { - | Some(a) => toString(a) - | None => `None` - } - -@genType -type environment = GenericDist.env - -@genType -let defaultEnvironment: environment = DistributionOperation.defaultEnv diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi index 6cccdf17..4cf8a17d 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_GenericDistribution.resi @@ -1,4 +1,4 @@ let dispatch: ( ReducerInterface_InternalExpressionValue.functionCall, - ReducerInterface_ExternalExpressionValue.environment, + 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 2f0dd7df..9d47c741 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res @@ -172,27 +172,6 @@ let valueToValueType = value => | IEvVoid => EvtVoid } -let externalValueToValueType = (value: ReducerInterface_ExternalExpressionValue.t) => - switch value { - | EvArray(_) => EvtArray - | EvArrayString(_) => EvtArrayString - | EvBool(_) => EvtBool - | EvCall(_) => EvtCall - | EvDate(_) => EvtDate - | EvDeclaration(_) => EvtDeclaration - | EvDistribution(_) => EvtDistribution - | EvLambda(_) => EvtLambda - | EvModule(_) => EvtModule - | EvNumber(_) => EvtNumber - | EvRecord(_) => EvtRecord - | EvString(_) => EvtString - | EvSymbol(_) => EvtSymbol - | EvTimeDuration(_) => EvtTimeDuration - | EvType(_) => EvtType - | EvTypeIdentifier(_) => EvtTypeIdentifier - | EvVoid => EvtVoid - } - let functionCallToCallSignature = (functionCall: functionCall): functionCallSignature => { let (fn, args) = functionCall CallSignature(fn, args->Js.Array2.map(valueToValueType)) 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 13505fea..6fe251d2 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem_T.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem_T.res @@ -1,7 +1,6 @@ module Parse = Reducer_Peggy_Parse module ExpressionT = Reducer_Expression_T module InternalExpressionValue = ReducerInterface_InternalExpressionValue -module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue open Reducer_ErrorValue type sourceArgumentType = string From 5c75da4736077e72e069db05a91aa369179d6156 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 19 Aug 2022 21:58:06 +0200 Subject: [PATCH 31/53] TypescriptInterface functions --- .../src/rescript/TypescriptInterface.res | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/TypescriptInterface.res b/packages/squiggle-lang/src/rescript/TypescriptInterface.res index bcee094a..f096b233 100644 --- a/packages/squiggle-lang/src/rescript/TypescriptInterface.res +++ b/packages/squiggle-lang/src/rescript/TypescriptInterface.res @@ -32,11 +32,22 @@ type resultFloat = result_ @genType type resultString = result_ +//TODO: ForTS Interface module candid @genType -let makeSampleSetDist = SampleSetDist.make +let makeSampleSetDist: array => result_< + sampleSetDist, + SampleSetDist.sampleSetError, +> = SampleSetDist.make +//TODO: ForTS Interface module candid @genType -let toPointSet = GenericDist.toPointSet +let toPointSet: ( + squiggleValue_Distribution, + ~xyPointLength: int, + ~sampleCount: int, + ~xSelection: DistributionTypes.DistributionOperation.pointsetXSelection=?, + unit, +) => result_ = GenericDist.toPointSet @genType type mixedShape = PointSetTypes.mixedShape From 4bf5f33f25a0d597b8a1e8c554563df91450f95d Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 19 Aug 2022 22:03:55 +0200 Subject: [PATCH 32/53] result tag --- .../src/rescript/ForTS/ForTS_Result.res | 13 +++++++++++++ .../src/rescript/ForTS/ForTS_Result_tag.ts | 4 ++++ 2 files changed, 17 insertions(+) create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_Result_tag.ts diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res index 19bf6ee0..7ace5c9c 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res @@ -16,3 +16,16 @@ let getValue = (r: result_<'a, 'e>): option<'a> => | Ok(v) => Some(v) | Error(_) => None } + +@module("ForTS_Result_tag") @scope("ResultTag") +external rtOk_: int = "RtOk" + +@module("ForTS_Result_tag") @scope("ResultTag") +external rtError_: int = "RtError" + +@genType +let getTag = (r: result_<'a, 'e>): int => + switch r { + | Ok(_) => rtOk_ + | Error(_) => rtError_ + } diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result_tag.ts b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result_tag.ts new file mode 100644 index 00000000..571de93a --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result_tag.ts @@ -0,0 +1,4 @@ +enum ResultTag { + Ok, + Error, +} \ No newline at end of file From 05ce6d2872cf5c51d8411dfc953001fba850b89c Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 19 Aug 2022 23:01:38 +0200 Subject: [PATCH 33/53] Comment opaue type violations --- .../squiggle-lang/src/js/rescript_interop.ts | 281 +++++++++--------- 1 file changed, 142 insertions(+), 139 deletions(-) diff --git a/packages/squiggle-lang/src/js/rescript_interop.ts b/packages/squiggle-lang/src/js/rescript_interop.ts index 3dca8165..0495c5f3 100644 --- a/packages/squiggle-lang/src/js/rescript_interop.ts +++ b/packages/squiggle-lang/src/js/rescript_interop.ts @@ -17,68 +17,69 @@ import { tagged, tag } from "./types"; // This file is here to compensate for genType not fully recursively converting types // Raw rescript types. -export type rescriptExport = - | 0 // EvVoid - | { - TAG: 0; // EvArray - _0: rescriptExport[]; - } - | { - TAG: 1; // EvString - _0: string[]; - } - | { - TAG: 2; // EvBool - _0: boolean; - } - | { - TAG: 3; // EvCall - _0: string; - } - | { - TAG: 4; // EvDistribution - _0: rescriptDist; - } - | { - TAG: 5; // EvLambda - _0: lambdaValue; - } - | { - TAG: 6; // EvNumber - _0: number; - } - | { - TAG: 7; // EvRecord - _0: { [key: string]: rescriptExport }; - } - | { - TAG: 8; // EvString - _0: string; - } - | { - TAG: 9; // EvSymbol - _0: string; - } - | { - TAG: 10; // EvDate - _0: Date; - } - | { - TAG: 11; // EvTimeDuration - _0: number; - } - | { - TAG: 12; // EvDeclaration - _0: rescriptLambdaDeclaration; - } - | { - TAG: 13; // EvTypeIdentifier - _0: string; - } - | { - TAG: 14; // EvModule - _0: { [key: string]: rescriptExport }; - }; +// Umur: Rescript expression values are opaque! +// export type rescriptExport = +// | 0 // EvVoid +// | { +// TAG: 0; // EvArray +// _0: rescriptExport[]; +// } +// | { +// TAG: 1; // EvString +// _0: string[]; +// } +// | { +// TAG: 2; // EvBool +// _0: boolean; +// } +// | { +// TAG: 3; // EvCall +// _0: string; +// } +// | { +// TAG: 4; // EvDistribution +// _0: rescriptDist; +// } +// | { +// TAG: 5; // EvLambda +// _0: lambdaValue; +// } +// | { +// TAG: 6; // EvNumber +// _0: number; +// } +// | { +// TAG: 7; // EvRecord +// _0: { [key: string]: rescriptExport }; +// } +// | { +// TAG: 8; // EvString +// _0: string; +// } +// | { +// TAG: 9; // EvSymbol +// _0: string; +// } +// | { +// TAG: 10; // EvDate +// _0: Date; +// } +// | { +// TAG: 11; // EvTimeDuration +// _0: number; +// } +// | { +// TAG: 12; // EvDeclaration +// _0: rescriptLambdaDeclaration; +// } +// | { +// TAG: 13; // EvTypeIdentifier +// _0: string; +// } +// | { +// TAG: 14; // EvModule +// _0: { [key: string]: rescriptExport }; +// }; type rescriptDist = | { TAG: 0; _0: rescriptPointSetDist } @@ -116,86 +117,88 @@ type rescriptDeclarationArg = max: Date; }; -export type squiggleExpression = - | tagged<"symbol", string> - | tagged<"string", string> - | tagged<"call", string> - | tagged<"lambda", lambdaValue> - | tagged<"array", squiggleExpression[]> - | tagged<"arraystring", string[]> - | tagged<"boolean", boolean> - | tagged<"distribution", Distribution> - | tagged<"number", number> - | tagged<"date", Date> - | tagged<"timeDuration", number> - | tagged<"lambdaDeclaration", lambdaDeclaration> - | tagged<"record", { [key: string]: squiggleExpression }> - | tagged<"type", { [key: string]: squiggleExpression }> - | tagged<"typeIdentifier", string> - | tagged<"module", { [key: string]: squiggleExpression }> - | tagged<"void", string>; +// Umur: Squiggle expressions are opaque! +// export type squiggleExpression = +// | tagged<"symbol", string> +// | tagged<"string", string> +// | tagged<"call", string> +// | tagged<"lambda", lambdaValue> +// | tagged<"array", squiggleExpression[]> +// | tagged<"arraystring", string[]> +// | tagged<"boolean", boolean> +// | tagged<"distribution", Distribution> +// | tagged<"number", number> +// | tagged<"date", Date> +// | tagged<"timeDuration", number> +// | tagged<"lambdaDeclaration", lambdaDeclaration> +// | tagged<"record", { [key: string]: squiggleExpression }> +// | tagged<"type", { [key: string]: squiggleExpression }> +// | tagged<"typeIdentifier", string> +// | tagged<"module", { [key: string]: squiggleExpression }> +// | tagged<"void", string>; export { lambdaValue }; -export function convertRawToTypescript( - result: rescriptExport, - environment: environment -): squiggleExpression { - if (typeof result === "number") { - // EvVoid - return tag("void", ""); - } - switch (result.TAG) { - case 0: // EvArray - return tag( - "array", - result._0.map((x) => convertRawToTypescript(x, environment)) - ); - case 1: // EvArrayString - return tag("arraystring", result._0); - case 2: // EvBool - return tag("boolean", result._0); - case 3: // EvCall - return tag("call", result._0); - case 4: // EvDistribution - return tag( - "distribution", - new Distribution( - convertRawDistributionToGenericDist(result._0), - environment - ) - ); - case 5: // EvDistribution - return tag("lambda", result._0); - case 6: // EvNumber - return tag("number", result._0); - case 7: // EvRecord - return tag( - "record", - _.mapValues(result._0, (x) => convertRawToTypescript(x, environment)) - ); - case 8: // EvString - return tag("string", result._0); - case 9: // EvSymbol - return tag("symbol", result._0); - case 10: // EvDate - return tag("date", result._0); - case 11: // EvTimeDuration - return tag("number", result._0); - case 12: // EvDeclaration - return tag("lambdaDeclaration", { - fn: result._0.fn, - args: result._0.args.map(convertDeclaration), - }); - case 13: // EvSymbol - return tag("typeIdentifier", result._0); - case 14: // EvModule - return tag( - "module", - _.mapValues(result._0, (x) => convertRawToTypescript(x, environment)) - ); - } -} +// Umur: Opaque type no conversion! +// export function convertRawToTypescript( +// result: rescriptExport, +// environment: environment +// ): squiggleExpression { +// if (typeof result === "number") { +// // EvVoid +// return tag("void", ""); +// } +// switch (result.TAG) { +// case 0: // EvArray +// return tag( +// "array", +// result._0.map((x) => convertRawToTypescript(x, environment)) +// ); +// case 1: // EvArrayString +// return tag("arraystring", result._0); +// case 2: // EvBool +// return tag("boolean", result._0); +// case 3: // EvCall +// return tag("call", result._0); +// case 4: // EvDistribution +// return tag( +// "distribution", +// new Distribution( +// convertRawDistributionToGenericDist(result._0), +// environment +// ) +// ); +// case 5: // EvDistribution +// return tag("lambda", result._0); +// case 6: // EvNumber +// return tag("number", result._0); +// case 7: // EvRecord +// return tag( +// "record", +// _.mapValues(result._0, (x) => convertRawToTypescript(x, environment)) +// ); +// case 8: // EvString +// return tag("string", result._0); +// case 9: // EvSymbol +// return tag("symbol", result._0); +// case 10: // EvDate +// return tag("date", result._0); +// case 11: // EvTimeDuration +// return tag("number", result._0); +// case 12: // EvDeclaration +// return tag("lambdaDeclaration", { +// fn: result._0.fn, +// args: result._0.args.map(convertDeclaration), +// }); +// case 13: // EvSymbol +// return tag("typeIdentifier", result._0); +// case 14: // EvModule +// return tag( +// "module", +// _.mapValues(result._0, (x) => convertRawToTypescript(x, environment)) +// ); +// } +// } function convertDeclaration( declarationArg: rescriptDeclarationArg From 7957b89bb4c880629ce9a29fa5e9f98fd35ab6db Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 19 Aug 2022 23:19:30 +0200 Subject: [PATCH 34/53] remove opaque type violations --- .../squiggle-lang/src/js/rescript_interop.ts | 112 +++++++++--------- 1 file changed, 56 insertions(+), 56 deletions(-) diff --git a/packages/squiggle-lang/src/js/rescript_interop.ts b/packages/squiggle-lang/src/js/rescript_interop.ts index 0495c5f3..7b340671 100644 --- a/packages/squiggle-lang/src/js/rescript_interop.ts +++ b/packages/squiggle-lang/src/js/rescript_interop.ts @@ -100,22 +100,22 @@ type rescriptPointSetDist = _0: continuousShape; }; -type rescriptLambdaDeclaration = { - readonly fn: lambdaValue; - readonly args: rescriptDeclarationArg[]; -}; +// type rescriptLambdaDeclaration = { +// readonly fn: lambdaValue; +// readonly args: rescriptDeclarationArg[]; +// }; -type rescriptDeclarationArg = - | { - TAG: 0; // Float - min: number; - max: number; - } - | { - TAG: 1; // Date - min: Date; - max: Date; - }; +// type rescriptDeclarationArg = +// | { +// TAG: 0; // Float +// min: number; +// max: number; +// } +// | { +// TAG: 1; // Date +// min: Date; +// max: Date; +// }; // Umur: Squiggle expressions are opaque! // export type squiggleExpression = @@ -200,16 +200,16 @@ export { lambdaValue }; // } // } -function convertDeclaration( - declarationArg: rescriptDeclarationArg -): declarationArg { - switch (declarationArg.TAG) { - case 0: // Float - return tag("Float", { min: declarationArg.min, max: declarationArg.max }); - case 1: // Date - return tag("Date", { min: declarationArg.min, max: declarationArg.max }); - } -} +// function convertDeclaration( +// declarationArg: rescriptDeclarationArg +// ): declarationArg { +// switch (declarationArg.TAG) { +// case 0: // Float +// return tag("Float", { min: declarationArg.min, max: declarationArg.max }); +// case 1: // Date +// return tag("Date", { min: declarationArg.min, max: declarationArg.max }); +// } +// } function convertRawDistributionToGenericDist( result: rescriptDist @@ -238,35 +238,35 @@ export type jsValue = | { [key: string]: jsValue } | boolean; -export function jsValueToBinding(value: jsValue): rescriptExport { - if (typeof value === "boolean") { - return { TAG: 2, _0: value as boolean }; - } else if (typeof value === "string") { - return { TAG: 8, _0: value as string }; - } else if (typeof value === "number") { - return { TAG: 6, _0: value as number }; - } else if (Array.isArray(value)) { - return { TAG: 0, _0: value.map(jsValueToBinding) }; - } else { - // Record - return { TAG: 7, _0: _.mapValues(value, jsValueToBinding) }; - } -} +// export function jsValueToBinding(value: jsValue): rescriptExport { +// if (typeof value === "boolean") { +// return { TAG: 2, _0: value as boolean }; +// } else if (typeof value === "string") { +// return { TAG: 8, _0: value as string }; +// } else if (typeof value === "number") { +// return { TAG: 6, _0: value as number }; +// } else if (Array.isArray(value)) { +// return { TAG: 0, _0: value.map(jsValueToBinding) }; +// } else { +// // Record +// return { TAG: 7, _0: _.mapValues(value, jsValueToBinding) }; +// } +// } -export function jsValueToExpressionValue(value: jsValue): expressionValue { - if (typeof value === "boolean") { - return { tag: "EvBool", value: value as boolean }; - } else if (typeof value === "string") { - return { tag: "EvString", value: value as string }; - } else if (typeof value === "number") { - return { tag: "EvNumber", value: value as number }; - } else if (Array.isArray(value)) { - return { tag: "EvArray", value: value.map(jsValueToExpressionValue) }; - } else { - // Record - return { - tag: "EvRecord", - value: _.mapValues(value, jsValueToExpressionValue), - }; - } -} +// export function jsValueToExpressionValue(value: jsValue): expressionValue { +// if (typeof value === "boolean") { +// return { tag: "EvBool", value: value as boolean }; +// } else if (typeof value === "string") { +// return { tag: "EvString", value: value as string }; +// } else if (typeof value === "number") { +// return { tag: "EvNumber", value: value as number }; +// } else if (Array.isArray(value)) { +// return { tag: "EvArray", value: value.map(jsValueToExpressionValue) }; +// } else { +// // Record +// return { +// tag: "EvRecord", +// value: _.mapValues(value, jsValueToExpressionValue), +// }; +// } +// } From ddb6d7f9589f9013650e1886a2ad2dc512d1df7f Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Fri, 19 Aug 2022 23:20:45 +0200 Subject: [PATCH 35/53] remove opaque type violations --- packages/squiggle-lang/src/js/rescript_interop.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/squiggle-lang/src/js/rescript_interop.ts b/packages/squiggle-lang/src/js/rescript_interop.ts index 7b340671..b6bcbba0 100644 --- a/packages/squiggle-lang/src/js/rescript_interop.ts +++ b/packages/squiggle-lang/src/js/rescript_interop.ts @@ -137,7 +137,7 @@ type rescriptPointSetDist = // | tagged<"module", { [key: string]: squiggleExpression }> // | tagged<"void", string>; -export { lambdaValue }; +// export { lambdaValue }; // Umur: Opaque type no conversion! // export function convertRawToTypescript( From feb7627ad07a3d1ac2fc09dd67e9c4f3722c2c10 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Sat, 20 Aug 2022 06:47:23 +0200 Subject: [PATCH 36/53] result fmap --- packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res index 7ace5c9c..39aad100 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res @@ -29,3 +29,10 @@ let getTag = (r: result_<'a, 'e>): int => | Ok(_) => rtOk_ | Error(_) => rtError_ } + +@genType +let fmap = (r: result_<'a, 'e>, f: 'a => 'b): result_<'b, 'e> => + switch r { + | Ok(v) => Ok(f(v)) + | Error(e) => Error(e) + } From 347c85324b1df4cf02bc7e7c78113af61cb5308d Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Sat, 20 Aug 2022 07:37:38 +0200 Subject: [PATCH 37/53] opaque distribution type --- .../src/rescript/Distributions/DistributionTypes.res | 2 -- .../squiggle-lang/src/rescript/ForTS/ForTS__Types.res | 6 +++++- .../For_TS_Distributions.res} | 4 +--- .../For_TS_Distributions/For_TS_Distributions_Error.res | 4 ++++ .../squiggle-lang/src/rescript/TypescriptInterface.res | 8 +++----- 5 files changed, 13 insertions(+), 11 deletions(-) rename packages/squiggle-lang/src/rescript/ForTS/{ForTS__Functions.res => For_TS_Distributions/For_TS_Distributions.res} (66%) create mode 100644 packages/squiggle-lang/src/rescript/ForTS/For_TS_Distributions/For_TS_Distributions_Error.res diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res index 0c119ea4..ab272c7f 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res @@ -6,7 +6,6 @@ type genericDist = type asAlgebraicCombinationStrategy = AsDefault | AsSymbolic | AsMonteCarlo | AsConvolution -@genType type error = | NotYetImplemented | Unreachable @@ -27,7 +26,6 @@ module Error = { let fromString = (s: string): t => OtherError(s) - @genType let toString = (err: error): string => switch err { | NotYetImplemented => "Function not yet implemented" diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res index c382576d..f3041750 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res @@ -18,10 +18,14 @@ type squiggleValue_Declaration = ReducerInterface_InternalExpressionValue.lambda @genType.opaque type reducerProject = ReducerProject_T.t +/* Distribution related */ +@genType type environment = GenericDist.env +@genType.opaque +type distributionError = DistributionTypes.error + // From now on one should introduce any new types as opaque types. // Exception: The intended type is really a JavaScript type or record. Not by coincidence // Already existing open types we cannot dive in now -@genType type environment = GenericDist.env @genType type squiggleValue_Distribution = DistributionTypes.genericDist //TODO: index.ts should use types from here or vice versa diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Functions.res b/packages/squiggle-lang/src/rescript/ForTS/For_TS_Distributions/For_TS_Distributions.res similarity index 66% rename from packages/squiggle-lang/src/rescript/ForTS/ForTS__Functions.res rename to packages/squiggle-lang/src/rescript/ForTS/For_TS_Distributions/For_TS_Distributions.res index 6a22297a..9e01f4e1 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Functions.res +++ b/packages/squiggle-lang/src/rescript/ForTS/For_TS_Distributions/For_TS_Distributions.res @@ -1,6 +1,4 @@ open ForTS__Types -/* -Global variables, functions, helpers, etc. -*/ + @genType let defaultEnvironment: environment = DistributionOperation.defaultEnv diff --git a/packages/squiggle-lang/src/rescript/ForTS/For_TS_Distributions/For_TS_Distributions_Error.res b/packages/squiggle-lang/src/rescript/ForTS/For_TS_Distributions/For_TS_Distributions_Error.res new file mode 100644 index 00000000..fff8f232 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/For_TS_Distributions/For_TS_Distributions_Error.res @@ -0,0 +1,4 @@ +open ForTS__Types + +@genType +let toString = (e: distributionError) => DistributionTypes.Error.toString(e) diff --git a/packages/squiggle-lang/src/rescript/TypescriptInterface.res b/packages/squiggle-lang/src/rescript/TypescriptInterface.res index f096b233..60ed0ad6 100644 --- a/packages/squiggle-lang/src/rescript/TypescriptInterface.res +++ b/packages/squiggle-lang/src/rescript/TypescriptInterface.res @@ -20,9 +20,6 @@ type sampleSetDist = SampleSetDist.t @genType type symbolicDist = SymbolicDistTypes.symbolicDist -@genType -type distributionError = DistributionTypes.error - @genType type resultDist = result_ @@ -58,8 +55,9 @@ type discreteShape = PointSetTypes.discreteShape @genType type continuousShape = PointSetTypes.continuousShape -@genType -let distributionErrorToString = DistributionTypes.Error.toString +// ForTS_Distributions_Error.toString +// @genType +// let distributionErrorToString = DistributionTypes.Error.toString @genType let defaultSamplingEnv = DistributionOperation.defaultEnv From c380ee22066a6fb55546a26b074bb103623c6f81 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Sat, 20 Aug 2022 08:11:20 +0200 Subject: [PATCH 38/53] toStringResult for easy testing --- .../src/rescript/ForTS/ForTS_SquiggleValue.res | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue.res index 12a73d64..893c50b3 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue.res @@ -79,6 +79,12 @@ let getTag = (variant: squiggleValue) => let toString = (variant: squiggleValue) => ReducerInterface_InternalExpressionValue.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) + @genType let getArray = (variant: squiggleValue): option => //FIXME: Convert From e6464dbe5c262483209f2ea8e179fc6c33c897ef Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 22 Aug 2022 08:50:59 +0200 Subject: [PATCH 39/53] make ts compatible commit 94803421acd2e5cb3a0f88e10f9244d374fab20b Author: Umur Ozkul Date: Mon Aug 22 08:48:33 2022 +0200 note on old habbits commit 2c47f80fce8fa6c12cb53b97f7150758eaa74b88 Author: Umur Ozkul Date: Mon Aug 22 08:18:16 2022 +0200 getTag returns enum value commit 733b9a820f1d01b618708896451a112d638ee811 Author: Umur Ozkul Date: Mon Aug 22 07:07:30 2022 +0200 result commit 64698f4a930182b3ccf122849824e4b6df251a9f Author: Umur Ozkul Date: Mon Aug 22 06:48:30 2022 +0200 return tags as ts enum commit 8ac802428a7aaac5367f5e8a9aaa592b89e305eb Author: Umur Ozkul Date: Mon Aug 22 06:16:26 2022 +0200 export tags commit 6c843e475a98ca1fcfa893d09d45ac9ad7c633ee Author: Umur Ozkul Date: Mon Aug 22 06:11:00 2022 +0200 distribution tag commit 9a43ec30fcaf967a672475431243949748d00bc7 Author: Umur Ozkul Date: Mon Aug 22 05:46:24 2022 +0200 opaque result commit f89bdd47c41135135baac99b18faf1c418cc4142 Author: Umur Ozkul Date: Mon Aug 22 05:24:18 2022 +0200 make ts compilable commit 6609bb3691b08405639e6f20da0fad309f2f232e Author: Umur Ozkul Date: Mon Aug 22 05:21:34 2022 +0200 compiles commit bace3eca63079de8f285069c65b219601e7310bf Author: Umur Ozkul Date: Mon Aug 22 04:33:34 2022 +0200 rescript compiles commit cd095f605c543902edec08fdcd407600296ec0cb Author: Umur Ozkul Date: Mon Aug 22 02:40:31 2022 +0200 squiggleValue commit 9b78b5d6c8b69287458fe392f142ceb3bca99407 Author: Umur Ozkul Date: Mon Aug 22 02:37:11 2022 +0200 project commit 20c8693b1eb6492f1662bedbb26b469aac11f8ff Author: Umur Ozkul Date: Mon Aug 22 00:59:44 2022 +0200 compiles --- packages/squiggle-lang/src/js/index.ts | 2 - .../squiggle-lang/src/js/rescript_interop.ts | 123 ++++----- .../Distributions/DistributionOperation.res | 1 + .../Distributions/DistributionOperation.resi | 1 + .../Distributions/DistributionTypes.res | 4 +- .../rescript/Distributions/GenericDist.res | 2 + .../rescript/Distributions/GenericDist.resi | 2 + .../PointSetDist/PointSetTypes.res | 2 +- .../ForTS_Distribution/ForTS_Distribution.res | 57 ++++ .../ForTS_Distribution_Environment.res | 1 + .../ForTS_Distribution_Error.res} | 2 +- ...orTS_Distribution_PointSetDistribution.res | 44 ++++ ...S_Distribution_PointSetDistribution_tag.js | 15 ++ ...S_Distribution_PointSetDistribution_tag.ts | 5 + ...rTS_Distribution_SampleSetDistribution.res | 1 + ...orTS_Distribution_SymbolicDistribution.res | 1 + .../ForTS_Distribution_tag.ts | 5 + .../rescript/ForTS/ForTS_ReducerProject.res | 29 ++- .../ForTS/ForTS_Reducer_ErrorValue.res | 3 +- .../src/rescript/ForTS/ForTS_Result.res | 22 +- .../src/rescript/ForTS/ForTS_Result_tag.ts | 8 +- .../ForTS_SquiggleValue.res | 89 ++++--- .../ForTS_SquiggleValue_Array.res | 5 +- .../ForTS_SquiggleValue_Declaration.res | 1 + .../ForTS_SquiggleValue_Distribution.res | 1 + .../ForTS_SquiggleValue_Lambda.res | 1 + .../ForTS_SquiggleValue_Module.res | 3 +- .../ForTS_SquiggleValue_Record.res | 3 +- .../ForTS_SquiggleValue_Type.res | 3 +- .../ForTS_SquiggleValue_tag.ts | 19 ++ .../rescript/ForTS/ForTS_SquiggleValue_tag.ts | 19 -- .../src/rescript/ForTS/ForTS__Types.res | 45 ++-- .../For_TS_Distributions.res | 4 - .../rescript/Reducer/Reducer_ErrorValue.res | 1 + ...ducerInterface_InternalExpressionValue.res | 11 +- .../ReducerProject_IncludeParser.js | 244 ++++++++++++------ .../ReducerProject/ReducerProject_T.res | 3 + .../src/rescript/TypescriptInterface.res | 51 ++-- 38 files changed, 546 insertions(+), 287 deletions(-) create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution.res create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_Environment.res rename packages/squiggle-lang/src/rescript/ForTS/{For_TS_Distributions/For_TS_Distributions_Error.res => ForTS_Distribution/ForTS_Distribution_Error.res} (60%) create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_PointSetDistribution.res create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_PointSetDistribution_tag.js create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_PointSetDistribution_tag.ts create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_SampleSetDistribution.res create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_SymbolicDistribution.res create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_tag.ts rename packages/squiggle-lang/src/rescript/ForTS/{ => ForTS_SquiggleValue}/ForTS_SquiggleValue.res (54%) create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Declaration.res create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Distribution.res create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Lambda.res create mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_tag.ts delete mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue_tag.ts delete mode 100644 packages/squiggle-lang/src/rescript/ForTS/For_TS_Distributions/For_TS_Distributions.res diff --git a/packages/squiggle-lang/src/js/index.ts b/packages/squiggle-lang/src/js/index.ts index 15346d67..c5f66eed 100644 --- a/packages/squiggle-lang/src/js/index.ts +++ b/packages/squiggle-lang/src/js/index.ts @@ -10,7 +10,6 @@ Instead of a global function namespace we should use modules under ForTS directl */ - import * as _ from "lodash"; import type { environment, @@ -57,7 +56,6 @@ export let defaultSamplingInputs: environment = { xyPointLength: 10000, }; - /* Umur: All the functions below are invalid. ForTS_Reducer project is the new way to do this. */ // export function run( diff --git a/packages/squiggle-lang/src/js/rescript_interop.ts b/packages/squiggle-lang/src/js/rescript_interop.ts index b6bcbba0..1031dd3e 100644 --- a/packages/squiggle-lang/src/js/rescript_interop.ts +++ b/packages/squiggle-lang/src/js/rescript_interop.ts @@ -1,19 +1,23 @@ -import * as _ from "lodash"; -import type { - expressionValue, - mixedShape, - sampleSetDist, - genericDist, - environment, - symbolicDist, - discreteShape, - continuousShape, - lambdaValue, - lambdaDeclaration, - declarationArg, -} from "../rescript/TypescriptInterface.gen"; -import { Distribution } from "./distribution"; -import { tagged, tag } from "./types"; +/** + Umur: Delete this file! There is nothing left to see here. +**/ + +// import * as _ from "lodash"; +// import type { +// // expressionValue, +// mixedShape, +// sampleSetDist, +// genericDist, +// // environment, +// symbolicDist, +// discreteShape, +// continuousShape, +// // lambdaValue, +// // lambdaDeclaration, +// // declarationArg, +// } from "../rescript/TypescriptInterface.gen"; +// import { Distribution } from "./distribution"; +// import { tagged, tag } from "./types"; // This file is here to compensate for genType not fully recursively converting types // Raw rescript types. @@ -81,24 +85,26 @@ import { tagged, tag } from "./types"; // _0: { [key: string]: rescriptExport }; // }; -type rescriptDist = - | { TAG: 0; _0: rescriptPointSetDist } - | { TAG: 1; _0: sampleSetDist } - | { TAG: 2; _0: symbolicDist }; +// Umur: opaque type +// type rescriptDist = +// | { TAG: 0; _0: rescriptPointSetDist } +// | { TAG: 1; _0: sampleSetDist } +// | { TAG: 2; _0: symbolicDist }; -type rescriptPointSetDist = - | { - TAG: 0; // Mixed - _0: mixedShape; - } - | { - TAG: 1; // Discrete - _0: discreteShape; - } - | { - TAG: 2; // ContinuousShape - _0: continuousShape; - }; +// Umur: opaque type, no conversion +// type rescriptPointSetDist = +// | { +// TAG: 0; // Mixed +// _0: mixedShape; +// } +// | { +// TAG: 1; // Discrete +// _0: discreteShape; +// } +// | { +// TAG: 2; // ContinuousShape +// _0: continuousShape; +// }; // type rescriptLambdaDeclaration = { // readonly fn: lambdaValue; @@ -211,32 +217,33 @@ type rescriptPointSetDist = // } // } -function convertRawDistributionToGenericDist( - result: rescriptDist -): genericDist { - switch (result.TAG) { - case 0: // Point Set Dist - switch (result._0.TAG) { - case 0: // Mixed - return tag("PointSet", tag("Mixed", result._0._0)); - case 1: // Discrete - return tag("PointSet", tag("Discrete", result._0._0)); - case 2: // Continuous - return tag("PointSet", tag("Continuous", result._0._0)); - } - case 1: // Sample Set Dist - return tag("SampleSet", result._0); - case 2: // Symbolic Dist - return tag("Symbolic", result._0); - } -} +// Umur: opaque type no conversion! +// function convertRawDistributionToGenericDist( +// result: rescriptDist +// ): genericDist { +// switch (result.TAG) { +// case 0: // Point Set Dist +// switch (result._0.TAG) { +// case 0: // Mixed +// return tag("PointSet", tag("Mixed", result._0._0)); +// case 1: // Discrete +// return tag("PointSet", tag("Discrete", result._0._0)); +// case 2: // Continuous +// return tag("PointSet", tag("Continuous", result._0._0)); +// } +// case 1: // Sample Set Dist +// return tag("SampleSet", result._0); +// case 2: // Symbolic Dist +// return tag("Symbolic", result._0); +// } +// } -export type jsValue = - | string - | number - | jsValue[] - | { [key: string]: jsValue } - | boolean; +// export type jsValue = +// | string +// | number +// | jsValue[] +// | { [key: string]: jsValue } +// | boolean; // export function jsValueToBinding(value: jsValue): rescriptExport { // if (typeof value === "boolean") { diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.res index 319535c1..97068765 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.res @@ -1,3 +1,4 @@ +type result<'a, 'e> = ForTS_Result.result<'a, 'e> // Use opaque result type type functionCallInfo = DistributionTypes.DistributionOperation.genericFunctionCallInfo type genericDist = DistributionTypes.genericDist type error = DistributionTypes.error diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.resi b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.resi index 68da9534..7cdc3706 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.resi +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.resi @@ -1,3 +1,4 @@ +type result<'a, 'e> = ForTS_Result.result<'a, 'e> // Use opaque result type @genType let defaultEnv: GenericDist.env diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res index ab272c7f..93f934e1 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionTypes.res @@ -1,4 +1,5 @@ -@genType +//FIXME accessor methods or not opaque? +@genType.opaque type genericDist = | PointSet(PointSetTypes.pointSetDist) | SampleSet(SampleSetDist.t) @@ -6,6 +7,7 @@ type genericDist = type asAlgebraicCombinationStrategy = AsDefault | AsSymbolic | AsMonteCarlo | AsConvolution +@genType.opaque type error = | NotYetImplemented | Unreachable diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist.res b/packages/squiggle-lang/src/rescript/Distributions/GenericDist.res index f536d54d..2db7a05d 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist.res @@ -1,4 +1,6 @@ //TODO: multimodal, add interface, test somehow, track performance, refactor sampleSet, refactor ASTEvaluator.res. +type result<'a, 'e> = ForTS_Result.result<'a, 'e> // Use opaque result type + type t = DistributionTypes.genericDist type error = DistributionTypes.error type toPointSetFn = t => result diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist.resi b/packages/squiggle-lang/src/rescript/Distributions/GenericDist.resi index fd04212a..ba69c1f3 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist.resi +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist.resi @@ -1,3 +1,5 @@ +type result<'a, 'e> = ForTS_Result.result<'a, 'e> // Use opaque result type + type t = DistributionTypes.genericDist type error = DistributionTypes.error type toPointSetFn = t => result diff --git a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/PointSetTypes.res b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/PointSetTypes.res index fcc796ec..76720290 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/PointSetTypes.res +++ b/packages/squiggle-lang/src/rescript/Distributions/PointSetDist/PointSetTypes.res @@ -47,7 +47,7 @@ type pointSetDistMonad<'a, 'b, 'c> = | Discrete('b) | Continuous('c) -@genType +@genType.opaque type pointSetDist = pointSetDistMonad module ShapeMonad = { 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 new file mode 100644 index 00000000..ca4c02ad --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution.res @@ -0,0 +1,57 @@ +// Genetic Distribution happens to be abstract distribution +@genType type distribution = DistributionTypes.genericDist +@genType type pointSetDistribution = ForTS_Distribution_PointSetDistribution.pointSetDistribution +@genType type sampleSetDistribution = ForTS_Distribution_SampleSetDistribution.sampleSetDistribution +@genType type symbolicDistribution = ForTS_Distribution_SymbolicDistribution.symbolicDistribution + +type environment = ForTS_Distribution_Environment.environment //use + +@genType +let defaultEnvironment: environment = DistributionOperation.defaultEnv + +@module("ForTS_Distribution_tag") @scope("distributionTag") +external dtPointSet_: int = "DtPointSet" + +@module("ForTS_Distribution_tag") @scope("distributionTag") +external dtSampleSet_: int = "DtSampleSet" + +@module("ForTS_Distribution_tag") @scope("distributionTag") +external dtSymbolic_: int = "DtSymbolic" + +@genType.import("./ForTS_Distribution_tag") +type distributionTag + +external castEnum: int => distributionTag = "%identity" + +// type genericDist = +// | PointSet(PointSetTypes.pointSetDist) +// | SampleSet(SampleSetDist.t) +// | Symbolic(SymbolicDistTypes.symbolicDist) +@genType +let getTag = (variant: distribution): distributionTag => + switch variant { + | PointSet(_) => dtPointSet_->castEnum + | SampleSet(_) => dtSampleSet_->castEnum + | Symbolic(_) => dtSymbolic_->castEnum + } + +@genType +let getPointSet = (variant: distribution): option => + switch variant { + | PointSet(dist) => dist->Some + | _ => None + } + +@genType +let getSampleSet = (variant: distribution): option => + switch variant { + | SampleSet(dist) => dist->Some + | _ => None + } + +@genType +let getSymbolic = (variant: distribution): option => + switch variant { + | Symbolic(dist) => dist->Some + | _ => None + } diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_Environment.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_Environment.res new file mode 100644 index 00000000..d6f89fb9 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_Environment.res @@ -0,0 +1 @@ +@genType type environment = GenericDist.env //re-export diff --git a/packages/squiggle-lang/src/rescript/ForTS/For_TS_Distributions/For_TS_Distributions_Error.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_Error.res similarity index 60% rename from packages/squiggle-lang/src/rescript/ForTS/For_TS_Distributions/For_TS_Distributions_Error.res rename to packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_Error.res index fff8f232..d228e7b2 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/For_TS_Distributions/For_TS_Distributions_Error.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_Error.res @@ -1,4 +1,4 @@ -open ForTS__Types +@genType type distributionError = DistributionTypes.error @genType let toString = (e: distributionError) => DistributionTypes.Error.toString(e) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_PointSetDistribution.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_PointSetDistribution.res new file mode 100644 index 00000000..59750a15 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_PointSetDistribution.res @@ -0,0 +1,44 @@ +@genType type pointSetDistribution = PointSetTypes.pointSetDist + +@module("ForTS_Distribution_PointSetDistribution_tag") @scope("pointSetDistributionTag") +external pstMixed_: int = "PstMixed" + +@module("ForTS_Distribution_PointSetDistribution_tag") @scope("pointSetDistributionTag") +external pstDiscrete_: int = "PstDiscrete" + +@module("ForTS_Distribution_PointSetDistribution_tag") @scope("pointSetDistributionTag") +external pstContinuous_: int = "PstContinuous" + +@genType.import("./ForTS_Distribution_PointSetDistribution_tag") +type pointSetDistributionTag + +external castEnum: int => pointSetDistributionTag = "%identity" + +@genType +let getTag = (variant: pointSetDistribution): pointSetDistributionTag => + switch variant { + | Mixed(_) => pstMixed_->castEnum + | Discrete(_) => pstDiscrete_->castEnum + | Continuous(_) => pstContinuous_->castEnum + } + +@genType +let getMixed = (variant: pointSetDistribution): 'd => + switch variant { + | Mixed(mixed) => mixed->Some + | _ => None + } + +@genType +let getDiscrete = (variant: pointSetDistribution): 'd => + switch variant { + | Discrete(discrete) => discrete->Some + | _ => None + } + +@genType +let getContinues = (variant: pointSetDistribution): 'd => + switch variant { + | Continuous(continuous) => continuous->Some + | _ => None + } diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_PointSetDistribution_tag.js b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_PointSetDistribution_tag.js new file mode 100644 index 00000000..106c13d2 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_PointSetDistribution_tag.js @@ -0,0 +1,15 @@ +"use strict"; +exports.__esModule = true; +exports.pointSetDistributionTag = void 0; +var pointSetDistributionTag; +(function (pointSetDistributionTag) { + pointSetDistributionTag[(pointSetDistributionTag["PstMixed"] = 0)] = + "PstMixed"; + pointSetDistributionTag[(pointSetDistributionTag["PstDiscrete"] = 1)] = + "PstDiscrete"; + pointSetDistributionTag[(pointSetDistributionTag["PstContinuous"] = 2)] = + "PstContinuous"; +})( + (pointSetDistributionTag = + exports.pointSetDistributionTag || (exports.pointSetDistributionTag = {})) +); diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_PointSetDistribution_tag.ts b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_PointSetDistribution_tag.ts new file mode 100644 index 00000000..e1e16d89 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_PointSetDistribution_tag.ts @@ -0,0 +1,5 @@ +export enum pointSetDistributionTag { + PstMixed, + PstDiscrete, + PstContinuous, +} diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_SampleSetDistribution.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_SampleSetDistribution.res new file mode 100644 index 00000000..29f0c2aa --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_SampleSetDistribution.res @@ -0,0 +1 @@ +@genType type sampleSetDistribution = SampleSetDist.t diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_SymbolicDistribution.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_SymbolicDistribution.res new file mode 100644 index 00000000..32e8614b --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_SymbolicDistribution.res @@ -0,0 +1 @@ +@genType type symbolicDistribution = SymbolicDistTypes.symbolicDist diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_tag.ts b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_tag.ts new file mode 100644 index 00000000..72466c91 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Distribution/ForTS_Distribution_tag.ts @@ -0,0 +1,5 @@ +export enum distributionTag { + DtPointSet, + DtSampleSet, + DtSymbolic, +} diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res index a195a046..d35dd156 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res @@ -1,6 +1,13 @@ -open ForTS__Types -// If a module is built for TypeScript then it can only refer to ForTS__Types for other types and modules -// The exception is its implementation and private modules +@genType type reducerProject = ReducerProject_T.t //re-export + +type result<'a, 'e> = ForTS_Result.result<'a, 'e> // Use opaque result type +type reducerErrorValue = ForTS_Reducer_ErrorValue.reducerErrorValue //use + +type squiggleValue = ForTS_SquiggleValue.squiggleValue //use +type squiggleValue_Module = ForTS_SquiggleValue_Module.squiggleValue_Module //use + +type environment = ForTS_Distribution_Environment.environment //use + module T = ReducerProject_T module Private = ReducerProject.Private @@ -9,6 +16,8 @@ module Private = ReducerProject.Private */ /* +A project links and runs sources that continue or include each other. + Creates a new project to hold the sources, executables, bindings, and other data. The new project runs the sources according to their topological sorting because of the includes and continues. @@ -92,7 +101,7 @@ let cleanAllResults = (project: reducerProject): unit => To set the includes one first has to call "parseIncludes". The parsed includes or the parser error is returned. */ @genType -let getIncludes = (project: reducerProject, sourceId: string): result_< +let getIncludes = (project: reducerProject, sourceId: string): result< array, reducerErrorValue, > => project->T.Private.castToInternalProject->Private.getIncludes(sourceId) @@ -145,7 +154,7 @@ let getRunOrderFor = (project: reducerProject, sourceId: string) => Parse includes so that you can load them before running. Load includes by calling getIncludes which returns the includes that have been parsed. It is your responsibility to load the includes before running. -*/ module Topology = ReducerProject_Topology +*/ @genType let parseIncludes = (project: reducerProject, sourceId: string): unit => @@ -186,7 +195,7 @@ Get the result after running this source file or the project */ @genType let getResult = (project: reducerProject, sourceId: string): option< - result_, + result, > => project->T.Private.castToInternalProject->Private.getResult(sourceId) /* @@ -194,7 +203,11 @@ This is a convenience function to get the result of a single source without crea However, without a project, you cannot handle include directives. The source has to be include free */ -@genType let evaluate = (sourceCode: string): ('r, 'b) => Private.evaluate(sourceCode) +@genType +let evaluate = (sourceCode: string): ( + result, + squiggleValue_Module, +) => Private.evaluate(sourceCode) @genType let setEnvironment = (project: reducerProject, environment: environment): unit => @@ -211,7 +224,7 @@ If the conversion to the new project is too difficult, I can add it later. // lambdaValue: squiggleValue_Lambda, // argArray: array, // environment: environment, -// ): result_ => { +// ): result => { // let accessors = ReducerProject_ProjectAccessors_T.identityAccessorsWithEnvironment(environment) // Reducer_Expression_Lambda.foreignFunctionInterface( // lambdaValue, diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Reducer_ErrorValue.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Reducer_ErrorValue.res index 32541a06..61dc3bac 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Reducer_ErrorValue.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Reducer_ErrorValue.res @@ -1,4 +1,5 @@ -open ForTS__Types +@genType type reducerErrorValue = Reducer_ErrorValue.errorValue //alias +@genType type syntaxErrorLocation = Reducer_ErrorValue.syntaxErrorLocation //alias @genType let toString = (e: reducerErrorValue): string => Reducer_ErrorValue.errorToString(e) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res index 39aad100..6c770dc6 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res @@ -1,4 +1,5 @@ -open ForTS__Types +@genType.opaque type result_<'a, 'e> = result<'a, 'e> +@genType type result<'a, 'e> = result_<'a, 'e> // alias and re-export @genType let isError = (r: result_<'a, 'e>): bool => Belt.Result.isError(r) @genType let isOk = (r: result_<'a, 'e>): bool => Belt.Result.isOk(r) @@ -11,27 +12,32 @@ let getError = (r: result_<'a, 'e>): option<'e> => } @genType -let getValue = (r: result_<'a, 'e>): option<'a> => +let getValue = (r: result<'a, 'e>): option<'a> => switch r { | Ok(v) => Some(v) | Error(_) => None } -@module("ForTS_Result_tag") @scope("ResultTag") +@module("ForTS_Result_tag") @scope("resultTag") external rtOk_: int = "RtOk" -@module("ForTS_Result_tag") @scope("ResultTag") +@module("ForTS_Result_tag") @scope("resultTag") external rtError_: int = "RtError" +@genType.import("./ForTS_Result_tag") +type resultTag + +external castEnum: int => resultTag = "%identity" + @genType -let getTag = (r: result_<'a, 'e>): int => +let getTag = (r: result<'a, 'e>): resultTag => switch r { - | Ok(_) => rtOk_ - | Error(_) => rtError_ + | Ok(_) => rtOk_->castEnum + | Error(_) => rtError_->castEnum } @genType -let fmap = (r: result_<'a, 'e>, f: 'a => 'b): result_<'b, 'e> => +let fmap = (r: result<'a, 'e>, f: 'a => 'b): result<'b, 'e> => switch r { | Ok(v) => Ok(f(v)) | Error(e) => Error(e) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result_tag.ts b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result_tag.ts index 571de93a..da7cd79d 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result_tag.ts +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result_tag.ts @@ -1,4 +1,4 @@ -enum ResultTag { - Ok, - Error, -} \ No newline at end of file +export enum resultTag { + Ok, + Error, +} diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res similarity index 54% rename from packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue.res rename to packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res index 893c50b3..3d7586ff 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue.res @@ -1,78 +1,93 @@ -open ForTS__Types +@genType type squiggleValue = ReducerInterface_InternalExpressionValue.t //re-export +type result_<'a, 'e> = ForTS_Result.result_<'a, 'e> //use +type reducerErrorValue = ForTS_Reducer_ErrorValue.reducerErrorValue //use -// Return values as they are if they are JavaScript types. +@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 +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 -@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +// Return values are kept as they are if they are JavaScript types. + +@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtArray_: int = "SvtArray" -@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtArrayString_: int = "SvtArrayString" -@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtBool_: int = "SvtBool" -@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtCall_: int = "SvtCall" -@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtDate_: int = "SvtDate" -@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtDeclaration_: int = "SvtDeclaration" -@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtDistribution_: int = "SvtDistribution" -@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtLambda_: int = "SvtLambda" -@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtModule_: int = "SvtModule" -@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtNumber_: int = "SvtNumber" -@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtRecord_: int = "SvtRecord" -@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtString_: int = "SvtString" -@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtSymbol_: int = "SvtSymbol" -@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtTimeDuration_: int = "SvtTimeDuration" -@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtType_: int = "SvtType" -@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtTypeIdentifier_: int = "SvtUndefined" -@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag") +@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") external svtVoid_: int = "SvtVoid" +@genType.import("./ForTS_SquiggleValue_tag") +type squiggleValueTag + +external castEnum: int => squiggleValueTag = "%identity" + @genType -let getTag = (variant: squiggleValue) => +let getTag = (variant: squiggleValue): squiggleValueTag => switch variant { - | IEvArray(_) => svtArray_ - | IEvArrayString(_) => svtArrayString_ - | IEvBool(_) => svtBool_ - | IEvCall(_) => svtCall_ //Impossible - | IEvDate(_) => svtDate_ - | IEvDeclaration(_) => svtDeclaration_ - | IEvDistribution(_) => svtDistribution_ - | IEvLambda(_) => svtLambda_ - | IEvBindings(_) => svtModule_ //Impossible - | IEvNumber(_) => svtNumber_ - | IEvRecord(_) => svtRecord_ - | IEvString(_) => svtString_ - | IEvSymbol(_) => svtSymbol_ - | IEvTimeDuration(_) => svtTimeDuration_ - | IEvType(_) => svtType_ - | IEvTypeIdentifier(_) => svtTypeIdentifier_ - | IEvVoid => svtVoid_ + | 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 + | IEvVoid => svtVoid_->castEnum } @genType 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 e90b493b..61b84d74 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 @@ -1,6 +1,5 @@ -open ForTS__Types -// Note: Internal representation will not be an array in the future. -// Thus we still to have a conversion +type squiggleValue = ForTS_SquiggleValue.squiggleValue +@genType type squiggleValue_Array = ForTS_SquiggleValue.squiggleValue_Array //re-export recursive type @genType let getValues = (v: squiggleValue_Array): array => 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 new file mode 100644 index 00000000..b53fb4bf --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Declaration.res @@ -0,0 +1 @@ +@genType type squiggleValue_Declaration = ReducerInterface_InternalExpressionValue.lambdaDeclaration //re-export 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 new file mode 100644 index 00000000..ef20d02f --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Distribution.res @@ -0,0 +1 @@ +@genType type squiggleValue_Distribution = ForTS_Distribution.distribution 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 new file mode 100644 index 00000000..c41a5727 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_Lambda.res @@ -0,0 +1 @@ +@genType type squiggleValue_Lambda = ReducerInterface_InternalExpressionValue.lambdaValue //re-export 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 2c06b9d7..8bb113a2 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 @@ -1,4 +1,5 @@ -open ForTS__Types +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)> => 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 5fa0da2d..bc226f95 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 @@ -1,4 +1,5 @@ -open ForTS__Types +type squiggleValue = ForTS_SquiggleValue.squiggleValue //use +@genType type squiggleValue_Record = ForTS_SquiggleValue.squiggleValue_Record //re-export recursive type @genType let getKeyValuePairs = (value: squiggleValue_Record): array<(string, squiggleValue)> => 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 b0a91495..d9a18bfc 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 @@ -1,4 +1,5 @@ -open ForTS__Types +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)> => 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 new file mode 100644 index 00000000..6393ca60 --- /dev/null +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue/ForTS_SquiggleValue_tag.ts @@ -0,0 +1,19 @@ +export enum squiggleValueTag { + SvtArray, + SvtArrayString, + SvtBool, + SvtCall, + SvtDate, + SvtDeclaration, + SvtDistribution, + SvtLambda, + SvtModule, + SvtNumber, + SvtRecord, + SvtString, + SvtSymbol, + SvtTimeDuration, + SvtType, + SvtTypeIdentifier, + SvtVoid, +} diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue_tag.ts b/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue_tag.ts deleted file mode 100644 index 9e4b34fd..00000000 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_SquiggleValue_tag.ts +++ /dev/null @@ -1,19 +0,0 @@ -enum SquiggleValueTag { - SvtArray, - SvtArrayString, - SvtBool, - SvtCall, - SvtDate, - SvtDeclaration, - SvtDistribution, - SvtLambda, - SvtModule, - SvtNumber, - SvtRecord, - SvtString, - SvtSymbol, - SvtTimeDuration, - SvtType, - SvtTypeIdentifier, - SvtVoid, -} \ No newline at end of file diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res index f3041750..4826324f 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res @@ -1,31 +1,24 @@ -@genType.opaque type result_<'a, 'e> = result<'a, 'e> -@genType.opaque type reducerErrorValue = Reducer_ErrorValue.errorValue -@genType type syntaxErrorLocation = Reducer_ErrorValue.syntaxErrorLocation +@genType type result_<'a, 'e> = ForTS_Result.result_<'a, 'e> //re-export +@genType type result<'a, 'e> = ForTS_Result.result<'a, 'e> //re-export +@genType type reducerErrorValue = ForTS_Reducer_ErrorValue.reducerErrorValue //re-export +@genType type syntaxErrorLocation = ForTS_Reducer_ErrorValue.syntaxErrorLocation //re-export -/* -The reason this is not ExpressionValue is that ExpressionValue is becoming a parametric type -to allow expressions for different domains. -So we rename it right away not cause a compatibility problem -*/ -@genType.opaque type squiggleValue = ReducerInterface_InternalExpressionValue.t -@genType.opaque type squiggleValue_Array = ReducerInterface_InternalExpressionValue.squiggleArray -@genType.opaque -type squiggleValue_Declaration = ReducerInterface_InternalExpressionValue.lambdaDeclaration -@genType.opaque type squiggleValue_Module = ReducerInterface_InternalExpressionValue.nameSpace -@genType.opaque type squiggleValue_Lambda = ReducerInterface_InternalExpressionValue.lambdaValue -@genType.opaque type squiggleValue_Record = ReducerInterface_InternalExpressionValue.map -@genType.opaque type squiggleValue_Type = ReducerInterface_InternalExpressionValue.map - -@genType.opaque type reducerProject = ReducerProject_T.t +@genType type reducerProject = ForTS_ReducerProject.reducerProject //re-export +@genType type squiggleValue = ForTS_SquiggleValue.squiggleValue //re-export +@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 /* Distribution related */ -@genType type environment = GenericDist.env -@genType.opaque -type distributionError = DistributionTypes.error +@genType type squiggleValue_Distribution = ForTS_Distribution.distribution //re-export +@genType type distribution = squiggleValue_Distribution //candid +@genType type distributionError = ForTS_Distribution_Error.distributionError //re-export +@genType type environment = ForTS_Distribution_Environment.environment //re-export -// From now on one should introduce any new types as opaque types. -// Exception: The intended type is really a JavaScript type or record. Not by coincidence -// Already existing open types we cannot dive in now -@genType type squiggleValue_Distribution = DistributionTypes.genericDist +@genType type pointSetDistribution = ForTS_Distribution_PointSetDistribution.pointSetDistribution //re-export +@genType type sampleSetDistribution = ForTS_Distribution_SampleSetDistribution.sampleSetDistribution //re-export +@genType type symbolicDistribution = ForTS_Distribution_SymbolicDistribution.symbolicDistribution //re-export -//TODO: index.ts should use types from here or vice versa diff --git a/packages/squiggle-lang/src/rescript/ForTS/For_TS_Distributions/For_TS_Distributions.res b/packages/squiggle-lang/src/rescript/ForTS/For_TS_Distributions/For_TS_Distributions.res deleted file mode 100644 index 9e01f4e1..00000000 --- a/packages/squiggle-lang/src/rescript/ForTS/For_TS_Distributions/For_TS_Distributions.res +++ /dev/null @@ -1,4 +0,0 @@ -open ForTS__Types - -@genType -let defaultEnvironment: environment = DistributionOperation.defaultEnv diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res index 3ff122ca..a3d1acff 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res @@ -2,6 +2,7 @@ @gentype.import("peggy") @genType.as("LocationRange") type syntaxErrorLocation +@genType.opaque type errorValue = | REArityError(option, int, int) | REArrayIndexNotFound(string, int) diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res index 9d47c741..6a26ecd2 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_InternalExpressionValue.res @@ -5,6 +5,7 @@ type environment = GenericDist.env let defaultEnvironment: environment = DistributionOperation.defaultEnv +@genType.opaque type rec t = | IEvArray(array) // FIXME: Convert to MapInt | IEvArrayString(array) @@ -23,17 +24,17 @@ type rec t = | IEvType(map) | IEvTypeIdentifier(string) | IEvVoid -and squiggleArray = array -and map = Belt.Map.String.t -and nameSpace = NameSpace(Belt.Map.String.t) +@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 lambdaValue = { parameters: array, context: nameSpace, body: internalCode, } -and lambdaDeclaration = Declaration.declaration +@genType.opaque and lambdaDeclaration = Declaration.declaration -type squiggleMap = map type internalExpressionValue = t type functionCall = (string, array) diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js index adc6e598..cb8c66eb 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) { @@ -175,7 +206,7 @@ function peg$parse(input, options) { var peg$c0 = "#include"; var peg$c1 = "'"; - var peg$c2 = "\""; + var peg$c2 = '"'; var peg$c3 = "//"; var peg$c4 = "/*"; var peg$c5 = "*/"; @@ -191,8 +222,8 @@ function peg$parse(input, options) { var peg$e1 = peg$otherExpectation("string"); var peg$e2 = peg$literalExpectation("'", false); var peg$e3 = peg$classExpectation(["'"], true, false); - var peg$e4 = peg$literalExpectation("\"", false); - var peg$e5 = peg$classExpectation(["\""], true, false); + var peg$e4 = peg$literalExpectation('"', false); + var peg$e5 = peg$classExpectation(['"'], true, false); var peg$e6 = peg$literalExpectation("//", false); var peg$e7 = peg$literalExpectation("/*", false); var peg$e8 = peg$classExpectation(["*"], true, false); @@ -203,12 +234,24 @@ function peg$parse(input, options) { var peg$e13 = peg$classExpectation(["\n", "\r"], false, false); var peg$e14 = peg$classExpectation(["\r", "\n"], true, false); - var peg$f0 = function(head, tail) {return [head, ...tail].filter( e => e != '');}; - var peg$f1 = function() {return [];}; - var peg$f2 = function(characters) {return characters.join('');}; - var peg$f3 = function(characters) {return characters.join('');}; - var peg$f4 = function() { return '';}; - var peg$f5 = function() { return '';}; + var peg$f0 = function (head, tail) { + return [head, ...tail].filter((e) => e != ""); + }; + var peg$f1 = function () { + return []; + }; + var peg$f2 = function (characters) { + return characters.join(""); + }; + var peg$f3 = function (characters) { + return characters.join(""); + }; + var peg$f4 = function () { + return ""; + }; + var peg$f5 = function () { + return ""; + }; var peg$currPos = 0; var peg$savedPos = 0; var peg$posDetailsCache = [{ line: 1, column: 1 }]; @@ -222,7 +265,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]; @@ -240,7 +285,7 @@ function peg$parse(input, options) { return { source: peg$source, start: peg$savedPos, - end: peg$currPos + end: peg$currPos, }; } @@ -249,9 +294,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)], @@ -261,9 +307,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); } @@ -273,7 +320,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() { @@ -303,7 +355,7 @@ function peg$parse(input, options) { details = peg$posDetailsCache[p]; details = { line: details.line, - column: details.column + column: details.column, }; while (p < pos) { @@ -332,18 +384,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; @@ -501,7 +555,9 @@ function peg$parse(input, options) { peg$currPos += 8; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e0); } + if (peg$silentFails === 0) { + peg$fail(peg$e0); + } } if (s1 !== peg$FAILED) { s2 = []; @@ -559,7 +615,9 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e2); } + if (peg$silentFails === 0) { + peg$fail(peg$e2); + } } if (s2 !== peg$FAILED) { s3 = []; @@ -568,7 +626,9 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } + if (peg$silentFails === 0) { + peg$fail(peg$e3); + } } while (s4 !== peg$FAILED) { s3.push(s4); @@ -577,7 +637,9 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e3); } + if (peg$silentFails === 0) { + peg$fail(peg$e3); + } } } if (input.charCodeAt(peg$currPos) === 39) { @@ -585,7 +647,9 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e2); } + if (peg$silentFails === 0) { + peg$fail(peg$e2); + } } if (s4 !== peg$FAILED) { s1 = s3; @@ -610,7 +674,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 = []; @@ -619,7 +685,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); @@ -628,7 +696,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) === 34) { @@ -636,7 +706,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; @@ -657,7 +729,9 @@ function peg$parse(input, options) { peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e1); } + if (peg$silentFails === 0) { + peg$fail(peg$e1); + } } peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; @@ -719,7 +793,9 @@ function peg$parse(input, options) { peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e6); } + if (peg$silentFails === 0) { + peg$fail(peg$e6); + } } if (s1 !== peg$FAILED) { s2 = []; @@ -758,7 +834,9 @@ function peg$parse(input, options) { peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e7); } + if (peg$silentFails === 0) { + peg$fail(peg$e7); + } } if (s1 !== peg$FAILED) { s2 = []; @@ -767,7 +845,9 @@ function peg$parse(input, options) { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e8); } + if (peg$silentFails === 0) { + peg$fail(peg$e8); + } } while (s3 !== peg$FAILED) { s2.push(s3); @@ -776,7 +856,9 @@ function peg$parse(input, options) { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e8); } + if (peg$silentFails === 0) { + peg$fail(peg$e8); + } } } if (input.substr(peg$currPos, 2) === peg$c5) { @@ -784,7 +866,9 @@ function peg$parse(input, options) { peg$currPos += 2; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e9); } + if (peg$silentFails === 0) { + peg$fail(peg$e9); + } } if (s3 !== peg$FAILED) { peg$savedPos = s0; @@ -821,12 +905,16 @@ function peg$parse(input, options) { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e11); } + if (peg$silentFails === 0) { + peg$fail(peg$e11); + } } peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e10); } + if (peg$silentFails === 0) { + peg$fail(peg$e10); + } } peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; @@ -852,12 +940,16 @@ function peg$parse(input, options) { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e13); } + if (peg$silentFails === 0) { + peg$fail(peg$e13); + } } peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { peg$fail(peg$e12); } + if (peg$silentFails === 0) { + peg$fail(peg$e12); + } } peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; @@ -882,7 +974,9 @@ 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$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; @@ -911,5 +1005,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_T.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res index c7bf968a..a9411c43 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_T.res @@ -2,7 +2,10 @@ module ProjectItem = ReducerProject_ProjectItem module ExpressionT = Reducer_Expression_T module ProjectAccessorsT = ReducerProject_ProjectAccessors_T +@genType.opaque type project = {"tag": string} +//re-export +@genType type t = project module Private = { diff --git a/packages/squiggle-lang/src/rescript/TypescriptInterface.res b/packages/squiggle-lang/src/rescript/TypescriptInterface.res index 60ed0ad6..16076f52 100644 --- a/packages/squiggle-lang/src/rescript/TypescriptInterface.res +++ b/packages/squiggle-lang/src/rescript/TypescriptInterface.res @@ -8,28 +8,17 @@ would be preferable. The below few seem to work fine. In the future there's definitely more work to do here. */ -@genType -type samplingParams = environment +// 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 -type genericDist = squiggleValue_Distribution - -@genType -type sampleSetDist = SampleSetDist.t - -@genType -type symbolicDist = SymbolicDistTypes.symbolicDist - -@genType -type resultDist = result_ - -@genType -type resultFloat = result_ - -@genType -type resultString = result_ - -//TODO: ForTS Interface module candid @genType let makeSampleSetDist: array => result_< sampleSetDist, @@ -55,15 +44,15 @@ type discreteShape = PointSetTypes.discreteShape @genType type continuousShape = PointSetTypes.continuousShape -// ForTS_Distributions_Error.toString +@genType +let distributionErrorToString = ForTS_Distribution_Error.toString + +@genType +let defaultSamplingEnv = ForTS_Distribution.defaultEnvironment + +// Umur: opaqe types // @genType -// let distributionErrorToString = DistributionTypes.Error.toString +// type declarationArg = Declaration.arg -@genType -let defaultSamplingEnv = DistributionOperation.defaultEnv - -@genType -type declarationArg = Declaration.arg - -@genType -type declaration<'a> = Declaration.declaration<'a> +// @genType +// type declaration<'a> = Declaration.declaration<'a> From 1250e66fb081808f61df9773c3b5b90c58655229 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 22 Aug 2022 17:24:58 +0200 Subject: [PATCH 40/53] fix RT --- packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res | 4 ++-- packages/squiggle-lang/src/rescript/ForTS/ForTS_Result_tag.ts | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res index 6c770dc6..99c4bceb 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res @@ -18,10 +18,10 @@ let getValue = (r: result<'a, 'e>): option<'a> => | Error(_) => None } -@module("ForTS_Result_tag") @scope("resultTag") +@module("./ForTS_Result_tag") @scope("resultTag") external rtOk_: int = "RtOk" -@module("ForTS_Result_tag") @scope("resultTag") +@module("./ForTS_Result_tag") @scope("resultTag") external rtError_: int = "RtError" @genType.import("./ForTS_Result_tag") diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result_tag.ts b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result_tag.ts index da7cd79d..2091415b 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result_tag.ts +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result_tag.ts @@ -1,4 +1,4 @@ export enum resultTag { - Ok, - Error, + RtOk, + RtError, } From f23e26fbbf30a90791c484d8dddb2a5e20660a96 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Tue, 23 Aug 2022 09:20:18 +0200 Subject: [PATCH 41/53] tutorial 1 depending --- ...res => ReducerProject_tutorial_0_test.res} | 0 ...cerProject_tutorial_1_multisource_test.res | 67 +++++++++++++++++++ 2 files changed, 67 insertions(+) rename packages/squiggle-lang/__tests__/ReducerProject/{ReducerProject_tutorial_test.res => ReducerProject_tutorial_0_test.res} (100%) create mode 100644 packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_multisource_test.res diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_0_test.res similarity index 100% rename from packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_test.res rename to packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_0_test.res diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_multisource_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_multisource_test.res new file mode 100644 index 00000000..cc0d45ec --- /dev/null +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_multisource_test.res @@ -0,0 +1,67 @@ +@@warning("-44") +module InternalExpressionValue = ReducerInterface_InternalExpressionValue +module Project = ForTS_ReducerProject +module Bindings = Reducer_Bindings + +open Jest +open Expect +open Expect.Operators + +describe("ReducerProject Tutorial", () => { + describe("Multi source", () => { + /* +Case "Running multiple sources" +*/ + test("Chaining", () => { + let project = Project.createProject() + /* This time let's add 3 sources and chain them together */ + Project.setSource(project, "source1", "x=1") + + Project.setSource(project, "source2", "y=2") + /* To run, source2 depends on source1 */ + Project.setContinues(project, "source2", ["source1"]) + + Project.setSource(project, "source3", "z=3") + /* To run, source3 depends on source2 */ + Project.setContinues(project, "source3", ["source2"]) + + /* Now we can run the project */ + Project.runAll(project) + + /* And let's check the result and bindings of source3 */ + let result3 = Project.getResult(project, "source3") + let bindings3 = Project.getBindings(project, "source3") + + ( + result3->InternalExpressionValue.toStringOptionResult, + bindings3->InternalExpressionValue.IEvBindings->InternalExpressionValue.toString, + )->expect == ("Ok(())", "@{x: 1,y: 2,z: 3}") + }) + + test("Depending", () => { + /* Instead of chaining the sources, we could have a dependency tree */ + /* The point here is that any source can depend on multiple sources */ + 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.setSource(project, "source3", "z=3") + /* To run, source3 depends on source1 and source3 together */ + Project.setContinues(project, "source3", ["source1", "source2"]) + + /* Now we can run the project */ + Project.runAll(project) + + /* And let's check the result and bindings of source3 */ + let result3 = Project.getResult(project, "source3") + let bindings3 = Project.getBindings(project, "source3") + + ( + result3->InternalExpressionValue.toStringOptionResult, + bindings3->InternalExpressionValue.IEvBindings->InternalExpressionValue.toString, + )->expect == ("Ok(())", "@{x: 1,y: 2,z: 3}") + }) + }) +}) From a394e93e062685d7c4150634e8ed872d35c9df69 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Tue, 23 Aug 2022 09:35:29 +0200 Subject: [PATCH 42/53] tutorial intro to includes --- ...cerProject_tutorial_1_multisource_test.res | 49 +++++++++++++++++++ .../src/rescript/ForTS/ForTS__Types.res | 1 - 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_multisource_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_multisource_test.res index cc0d45ec..282f4a78 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_multisource_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_multisource_test.res @@ -63,5 +63,54 @@ Case "Running multiple sources" bindings3->InternalExpressionValue.IEvBindings->InternalExpressionValue.toString, )->expect == ("Ok(())", "@{x: 1,y: 2,z: 3}") }) + + test("Intro to including", () => { + /* Though it would not be practical for a storybook, + let's write the same project above with includes. + You will see that parsing includes is setting the dependencies the same way as before. + */ + 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.setSource( + project, + "source3", + ` + #include "source1" + #include "source2" + z=3`, + ) + /* We need to parse the includes to set the dependencies */ + Project.parseIncludes(project, "source3") + + /* Now we can run the project */ + Project.runAll(project) + + /* 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") + + ( + result3->InternalExpressionValue.toStringOptionResult, + bindings3->InternalExpressionValue.IEvBindings->InternalExpressionValue.toString, + )->expect == ("Ok(())", "@{x: 1,y: 2,z: 3}") + /* + Doing it like this is too verbose for a storybook + But I hope you have seen the relation of setContinues and parseIncludes + */ + /* + Dealing with includes needs more. + - There are parse errors + - There are cyclic includes + - And the depended source1 and source2 is not already there in the project + - If you knew the includes before hand there would not be point of the include directive. + More on those on the next section. + */ + }) }) }) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res index 4826324f..88d22b65 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res @@ -21,4 +21,3 @@ @genType type pointSetDistribution = ForTS_Distribution_PointSetDistribution.pointSetDistribution //re-export @genType type sampleSetDistribution = ForTS_Distribution_SampleSetDistribution.sampleSetDistribution //re-export @genType type symbolicDistribution = ForTS_Distribution_SymbolicDistribution.symbolicDistribution //re-export - From b7ae9804a52f25202f382e604aae07ad2ce3ecf4 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Tue, 23 Aug 2022 09:38:12 +0200 Subject: [PATCH 43/53] format --- ...educerProject_tutorial_1_multisource_test.res | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_multisource_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_multisource_test.res index 282f4a78..b0b44892 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_multisource_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_multisource_test.res @@ -10,8 +10,7 @@ open Expect.Operators describe("ReducerProject Tutorial", () => { describe("Multi source", () => { /* -Case "Running multiple sources" -*/ + Case "Running multiple sources" */ test("Chaining", () => { let project = Project.createProject() /* This time let's add 3 sources and chain them together */ @@ -67,8 +66,7 @@ Case "Running multiple sources" test("Intro to including", () => { /* Though it would not be practical for a storybook, let's write the same project above with includes. - You will see that parsing includes is setting the dependencies the same way as before. - */ + You will see that parsing includes is setting the dependencies the same way as before. */ let project = Project.createProject() /* This time source1 and source2 are not depending on anything */ @@ -99,18 +97,16 @@ Case "Running multiple sources" result3->InternalExpressionValue.toStringOptionResult, bindings3->InternalExpressionValue.IEvBindings->InternalExpressionValue.toString, )->expect == ("Ok(())", "@{x: 1,y: 2,z: 3}") - /* + /* Doing it like this is too verbose for a storybook - But I hope you have seen the relation of setContinues and parseIncludes - */ - /* + But I hope you have seen the relation of setContinues and parseIncludes */ + /* Dealing with includes needs more. - There are parse errors - There are cyclic includes - And the depended source1 and source2 is not already there in the project - If you knew the includes before hand there would not be point of the include directive. - More on those on the next section. - */ + More on those on the next section. */ }) }) }) From 9cf3a93b70e56b789a38e5218dade68934a632ce Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Tue, 23 Aug 2022 11:47:24 +0200 Subject: [PATCH 44/53] fix parseInludes bug --- .../ReducerProject_IncludeParser.js | 328 +++++++----------- .../ReducerProject_IncludeParser.peggy | 5 +- .../ReducerProject_ParseIncludes.res | 13 +- .../ReducerProject_ProjectItem.res | 2 +- 4 files changed, 145 insertions(+), 203 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.js index cb8c66eb..e04b8ba2 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) { @@ -206,7 +175,7 @@ function peg$parse(input, options) { var peg$c0 = "#include"; var peg$c1 = "'"; - var peg$c2 = '"'; + var peg$c2 = "\""; var peg$c3 = "//"; var peg$c4 = "/*"; var peg$c5 = "*/"; @@ -222,8 +191,8 @@ function peg$parse(input, options) { var peg$e1 = peg$otherExpectation("string"); var peg$e2 = peg$literalExpectation("'", false); var peg$e3 = peg$classExpectation(["'"], true, false); - var peg$e4 = peg$literalExpectation('"', false); - var peg$e5 = peg$classExpectation(['"'], true, false); + var peg$e4 = peg$literalExpectation("\"", false); + var peg$e5 = peg$classExpectation(["\""], true, false); var peg$e6 = peg$literalExpectation("//", false); var peg$e7 = peg$literalExpectation("/*", false); var peg$e8 = peg$classExpectation(["*"], true, false); @@ -234,24 +203,12 @@ function peg$parse(input, options) { var peg$e13 = peg$classExpectation(["\n", "\r"], false, false); var peg$e14 = peg$classExpectation(["\r", "\n"], true, false); - var peg$f0 = function (head, tail) { - return [head, ...tail].filter((e) => e != ""); - }; - var peg$f1 = function () { - return []; - }; - var peg$f2 = function (characters) { - return characters.join(""); - }; - var peg$f3 = function (characters) { - return characters.join(""); - }; - var peg$f4 = function () { - return ""; - }; - var peg$f5 = function () { - return ""; - }; + var peg$f0 = function(head, tail) {return [head, ...tail].filter( e => e != '');}; + var peg$f1 = function() {return [];}; + var peg$f2 = function(characters) {return characters.join('');}; + var peg$f3 = function(characters) {return characters.join('');}; + var peg$f4 = function() { return '';}; + var peg$f5 = function() { return '';}; var peg$currPos = 0; var peg$savedPos = 0; var peg$posDetailsCache = [{ line: 1, column: 1 }]; @@ -265,9 +222,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]; @@ -285,7 +240,7 @@ function peg$parse(input, options) { return { source: peg$source, start: peg$savedPos, - end: peg$currPos, + end: peg$currPos }; } @@ -294,10 +249,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)], @@ -307,10 +261,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); } @@ -320,12 +273,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() { @@ -355,7 +303,7 @@ function peg$parse(input, options) { details = peg$posDetailsCache[p]; details = { line: details.line, - column: details.column, + column: details.column }; while (p < pos) { @@ -384,20 +332,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; @@ -421,7 +367,7 @@ function peg$parse(input, options) { } function peg$parsestart() { - var s0, s1, s2, s3; + var s0, s1, s2, s3, s4; var key = peg$currPos * 10 + 0; var cached = peg$resultsCache[key]; @@ -433,16 +379,40 @@ function peg$parse(input, options) { } s0 = peg$currPos; - s1 = peg$parseincludes(); - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$parsenewLine(); - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$parsenewLine(); + s1 = []; + s2 = peg$parsenewLine(); + if (s2 === peg$FAILED) { + s2 = peg$parse_(); + if (s2 === peg$FAILED) { + s2 = peg$parsecomment(); + if (s2 === peg$FAILED) { + s2 = peg$parsedelimitedComment(); + } } - s3 = peg$parseignore(); - s0 = s1; + } + while (s2 !== peg$FAILED) { + s1.push(s2); + s2 = peg$parsenewLine(); + if (s2 === peg$FAILED) { + s2 = peg$parse_(); + if (s2 === peg$FAILED) { + s2 = peg$parsecomment(); + if (s2 === peg$FAILED) { + s2 = peg$parsedelimitedComment(); + } + } + } + } + s2 = peg$parseincludes(); + if (s2 !== peg$FAILED) { + s3 = []; + s4 = peg$parsenewLine(); + while (s4 !== peg$FAILED) { + s3.push(s4); + s4 = peg$parsenewLine(); + } + s4 = peg$parseignore(); + s0 = s2; } else { peg$currPos = s0; s0 = peg$FAILED; @@ -538,7 +508,7 @@ function peg$parse(input, options) { } function peg$parseincludeStatement() { - var s0, s1, s2, s3, s4, s5; + var s0, s1, s2, s3, s4, s5, s6; var key = peg$currPos * 10 + 2; var cached = peg$resultsCache[key]; @@ -550,31 +520,35 @@ function peg$parse(input, options) { } s0 = peg$currPos; + s1 = []; + s2 = peg$parse_(); + while (s2 !== peg$FAILED) { + s1.push(s2); + s2 = peg$parse_(); + } if (input.substr(peg$currPos, 8) === peg$c0) { - s1 = peg$c0; + s2 = peg$c0; peg$currPos += 8; } else { - s1 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e0); - } + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$e0); } } - if (s1 !== peg$FAILED) { - s2 = []; - s3 = peg$parse_(); - while (s3 !== peg$FAILED) { - s2.push(s3); - s3 = peg$parse_(); + if (s2 !== peg$FAILED) { + s3 = []; + s4 = peg$parse_(); + while (s4 !== peg$FAILED) { + s3.push(s4); + s4 = peg$parse_(); } - s3 = peg$parsestring(); - if (s3 !== peg$FAILED) { - s4 = []; - s5 = peg$parse_(); - while (s5 !== peg$FAILED) { - s4.push(s5); - s5 = peg$parse_(); + s4 = peg$parsestring(); + if (s4 !== peg$FAILED) { + s5 = []; + s6 = peg$parse_(); + while (s6 !== peg$FAILED) { + s5.push(s6); + s6 = peg$parse_(); } - s0 = s3; + s0 = s4; } else { peg$currPos = s0; s0 = peg$FAILED; @@ -615,9 +589,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s2 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e2); - } + if (peg$silentFails === 0) { peg$fail(peg$e2); } } if (s2 !== peg$FAILED) { s3 = []; @@ -626,9 +598,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e3); - } + if (peg$silentFails === 0) { peg$fail(peg$e3); } } while (s4 !== peg$FAILED) { s3.push(s4); @@ -637,9 +607,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e3); - } + if (peg$silentFails === 0) { peg$fail(peg$e3); } } } if (input.charCodeAt(peg$currPos) === 39) { @@ -647,9 +615,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s4 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e2); - } + if (peg$silentFails === 0) { peg$fail(peg$e2); } } if (s4 !== peg$FAILED) { s1 = s3; @@ -674,9 +640,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 = []; @@ -685,9 +649,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); @@ -696,9 +658,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) === 34) { @@ -706,9 +666,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; @@ -729,9 +687,7 @@ function peg$parse(input, options) { peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e1); - } + if (peg$silentFails === 0) { peg$fail(peg$e1); } } peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; @@ -793,9 +749,7 @@ function peg$parse(input, options) { peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e6); - } + if (peg$silentFails === 0) { peg$fail(peg$e6); } } if (s1 !== peg$FAILED) { s2 = []; @@ -834,9 +788,7 @@ function peg$parse(input, options) { peg$currPos += 2; } else { s1 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e7); - } + if (peg$silentFails === 0) { peg$fail(peg$e7); } } if (s1 !== peg$FAILED) { s2 = []; @@ -845,9 +797,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e8); - } + if (peg$silentFails === 0) { peg$fail(peg$e8); } } while (s3 !== peg$FAILED) { s2.push(s3); @@ -856,9 +806,7 @@ function peg$parse(input, options) { peg$currPos++; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e8); - } + if (peg$silentFails === 0) { peg$fail(peg$e8); } } } if (input.substr(peg$currPos, 2) === peg$c5) { @@ -866,9 +814,7 @@ function peg$parse(input, options) { peg$currPos += 2; } else { s3 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e9); - } + if (peg$silentFails === 0) { peg$fail(peg$e9); } } if (s3 !== peg$FAILED) { peg$savedPos = s0; @@ -905,16 +851,12 @@ function peg$parse(input, options) { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e11); - } + if (peg$silentFails === 0) { peg$fail(peg$e11); } } peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e10); - } + if (peg$silentFails === 0) { peg$fail(peg$e10); } } peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; @@ -940,16 +882,12 @@ function peg$parse(input, options) { peg$currPos++; } else { s0 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e13); - } + if (peg$silentFails === 0) { peg$fail(peg$e13); } } peg$silentFails--; if (s0 === peg$FAILED) { s1 = peg$FAILED; - if (peg$silentFails === 0) { - peg$fail(peg$e12); - } + if (peg$silentFails === 0) { peg$fail(peg$e12); } } peg$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; @@ -974,9 +912,7 @@ 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$resultsCache[key] = { nextPos: peg$currPos, result: s0 }; @@ -1005,5 +941,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_IncludeParser.peggy b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.peggy index 25d69b93..dc65fac4 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.peggy +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_IncludeParser.peggy @@ -3,9 +3,8 @@ // #include "string" // #include "string2" - start - = @includes newLine* ignore + = (newLine/_/comment/delimitedComment)* @includes newLine* ignore includes = head:includeStatement tail:(newLine+ @includeStatement)* @@ -14,7 +13,7 @@ includes {return [];} includeStatement - = '#include' _* @string _* + = _* '#include' _* @string _* / comment / delimitedComment diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ParseIncludes.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ParseIncludes.res index 347234a4..f6b17901 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ParseIncludes.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ParseIncludes.res @@ -1,8 +1,15 @@ @module("./ReducerProject_IncludeParser.js") external parse__: string => array = "parse" -let parseIncludes = (expr: string): array => +let parseIncludes = (expr: string): result, Reducer_ErrorValue.errorValue> => try { - parse__(expr) + let answer = parse__(expr) + // let logEntry = answer->Js.Array2.joinWith(",") + // `parseIncludes: ${logEntry} for expr: ${expr}`->Js.log + answer->Ok } catch { - | Js.Exn.Error(_obj) => [] + | Js.Exn.Error(obj) => + RESyntaxError( + Belt.Option.getExn(Js.Exn.message(obj)), + Reducer_Peggy_Parse.syntaxErrorToLocation(obj)->Some, + )->Error } diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res index 047937f1..2608e344 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject_ProjectItem.res @@ -106,7 +106,7 @@ let setIncludes = (T.ProjectItem(r): t, includes: T.includesType): t => T.Projec //TODO: forward parse errors to the user let parseIncludes = (this: t): t => - setIncludes(this, getSource(this)->ReducerProject_ParseIncludes.parseIncludes->Ok) + setIncludes(this, getSource(this)->ReducerProject_ParseIncludes.parseIncludes) let doRawParse = (this: t): T.rawParseArgumentType => this->getSource->Reducer_Peggy_Parse.parse From cd205f2eb9c80487b251cf12ccc8a1e6665fa70e Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Tue, 23 Aug 2022 11:48:22 +0200 Subject: [PATCH 45/53] test for parseInclude --- .../ReducerProject_includes_test.res | 33 +++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100644 packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res new file mode 100644 index 00000000..bce7c84b --- /dev/null +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_includes_test.res @@ -0,0 +1,33 @@ +@@warning("-44") +module InternalExpressionValue = ReducerInterface_InternalExpressionValue +module Project = ForTS_ReducerProject +module Bindings = Reducer_Bindings + +open Jest +open Expect +open Expect.Operators + +Only.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) + } + }) +}) From 63cc9353b188813a01f1f4751a94e537de1b0fdb Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Tue, 23 Aug 2022 12:22:35 +0200 Subject: [PATCH 46/53] initial includes tutorial --- ...educerProject_tutorial_2_includes_test.res | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_includes_test.res diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_includes_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_includes_test.res new file mode 100644 index 00000000..4cf12304 --- /dev/null +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_includes_test.res @@ -0,0 +1,60 @@ +@@warning("-44") +module InternalExpressionValue = ReducerInterface_InternalExpressionValue +module Project = ForTS_ReducerProject +module Bindings = Reducer_Bindings + +open Jest +open Expect +open Expect.Operators + +describe("ReducerProject Tutorial", () => { + /* Case: Includes +In the previous tutorial we have set the similarity between setContinues and parseIncludes. +Here we will finally proceed to a real life scenario. */ + + describe("parseIncludes", () => { + /* Here we investigate the details about parseIncludes, before setting up a real life senario in the next section. */ + /* Everything happens inside a project, so let's have a project */ + let project = Project.createProject() + Project.setSource( + project, + "main", + ` + #include "common" + x=1 + `, + ) + /* We need to parse includes after changing the source */ + Project.parseIncludes(project, "main") + test("getDependencies", () => { + /* Parse includes has set the dependencies */ + Project.getDependencies(project, "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 */ + /* getDependencies does not distinguish between setContinues or parseIncludes */ + }) + test("getIncludes", () => { + /* Parse includes has set the includes */ + switch Project.getIncludes(project, "main") { + | Ok(includes) => includes->expect == ["common"] + | Error(err) => err->Reducer_ErrorValue.errorToString->fail + } + /* If the includes cannot be parsed then you get a syntax error. + Otherwise you get the includes. + If there is no syntax error then you can load that file and use setSource to add it to the project. + And so on recursively... */ + }) + test("getDependents", () => { + /* For any reason, you are able to query what other sources + 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 == [] + /* Nothing is depending on or including main */ + }) + + /* Let's look at recursive and possibly cyclic includes */ + /* ... */ + }) +}) From d37f0fe11744c8369114c17afa23720fc56be77e Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Tue, 23 Aug 2022 13:18:56 +0200 Subject: [PATCH 47/53] tutorial includes final --- ...educerProject_tutorial_2_includes_test.res | 100 +++++++++++++++++- 1 file changed, 98 insertions(+), 2 deletions(-) diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_includes_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_includes_test.res index 4cf12304..42673195 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_includes_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_includes_test.res @@ -54,7 +54,103 @@ Here we will finally proceed to a real life scenario. */ /* Nothing is depending on or including main */ }) - /* Let's look at recursive and possibly cyclic includes */ - /* ... */ + describe("Real Like", () => { + /* Now let's look at recursive and possibly cyclic includes */ + /* There is no function provided to load the include files. + Because we have no idea if will it be an ordinary function or will it use promises. + Therefore one has to write a function to load sources recursively and and setSources + while checking for dependencies */ + + /* Let's make a dummy loader */ + let loadSource = (sourceName: string) => + switch sourceName { + | "source1" => "x=1" + | "source2" => ` + #include "source1" + y=2` + | "source3" => ` + #include "source2" + z=3` + | _ => `source ${sourceName} not found`->Js.Exn.raiseError + } + + /* let's recursively load the sources */ + let rec loadIncludesRecursively = (project, sourceName, visited) => { + if Js.Array2.includes(visited, 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's parse the includes and dive into them */ + Project.parseIncludes(project, sourceName) + let rIncludes = Project.getIncludes(project, 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 => { + /* We have got one of the new incldues. + Let's load it and add it to the project */ + let newSource = loadSource(newIncludeName) + Project.setSource(project, 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) + }) + } + } + } + /* As we have a fake source loader and a recursive include handler, + We can not set up a real project */ + + /* * Here starts our real life project! * */ + + let project = Project.createProject() + + /* main includes source3 which includes source2 which includes source1 */ + Project.setSource( + project, + "main", + ` + #include "source3" + x+y+z + `, + ) + /* Setting source requires parsing and loading the includes recursively */ + loadIncludesRecursively(project, "main", []) //No 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, + "doubleX", + ` + #include "source1" + doubleX = x * 2 + `, + ) + loadIncludesRecursively(project, "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"]) + + /* Let's run the project */ + Project.runAll(project) + let result = Project.getResult(project, "main") + let bindings = Project.getBindings(project, "main") + /* And see the result and bindings.. */ + test("recursive includes", () => { + ( + result->InternalExpressionValue.toStringOptionResult, + bindings->InternalExpressionValue.IEvBindings->InternalExpressionValue.toString, + )->expect == ("Ok(6)", "@{doubleX: 2,x: 1,y: 2,z: 3}") + /* Everything as expected */ + }) + }) }) }) From 5bc4395ff6ac113c2055fad5a45b6ac2a2b4e766 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Tue, 23 Aug 2022 13:25:02 +0200 Subject: [PATCH 48/53] spelling --- .../ReducerProject/ReducerProject_tutorial_2_includes_test.res | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_includes_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_includes_test.res index 42673195..ce953ee0 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_includes_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_includes_test.res @@ -91,7 +91,7 @@ Here we will finally proceed to a real life scenario. */ | Ok(includes) => Belt.Array.forEach(includes, newIncludeName => { - /* We have got one of the new incldues. + /* 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) From 22e45d0e7bff76ad5e495c00ffaadd1e00252064 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Tue, 23 Aug 2022 13:39:19 +0200 Subject: [PATCH 49/53] tutorial injecting user values --- ...oject_tutorial_3_injecting_user_values.res | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_3_injecting_user_values.res diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_3_injecting_user_values.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_3_injecting_user_values.res new file mode 100644 index 00000000..f47396b0 --- /dev/null +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_3_injecting_user_values.res @@ -0,0 +1,39 @@ +@@warning("-44") +module InternalExpressionValue = ReducerInterface_InternalExpressionValue +module Project = ForTS_ReducerProject +module Bindings = Reducer_Bindings + +open Jest +open Expect +open Expect.Operators + +describe("ReducerProject Tutorial", () => { + /* Let's build a project that depends on values from the UI */ + let project = Project.createProject() + Project.setSource(project, "main", "x+y+z") + /* x, y and z is not defined in the project but they has to come from the user */ + test("Injecting user values", () => { + /* User has input the values */ + let x = 1 + let y = 2 + let z = 3 + /* Then we construct a source code to define those values */ + let userCode = ` + x = ${x->Js.Int.toString} + y = ${y->Js.Int.toString} + z = ${z->Js.Int.toString} + ` + /* We inject the user code into the project */ + Project.setSource(project, "userCode", userCode) + /* "main" is depending on the user code */ + Project.setContinues(project, "main", ["userCode"]) + /* We can now run the project */ + Project.runAll(project) + let result = Project.getResult(project, "main") + result->InternalExpressionValue.toStringOptionResult->expect == "Ok(6)" + }) +}) + +/* Note that this is not final version of the project */ +/* In the future, for safety, we will provide a way to inject values instead of a source code */ +/* But time is limited for now... */ From 8de8cc3633bb0e6d0616fea98929ba2fe794252b Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Tue, 23 Aug 2022 13:59:18 +0200 Subject: [PATCH 50/53] tutorial calling functions --- ...erProject_tutorial_4_calling_functions.res | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_4_calling_functions.res diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_4_calling_functions.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_4_calling_functions.res new file mode 100644 index 00000000..d595f35a --- /dev/null +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_4_calling_functions.res @@ -0,0 +1,39 @@ +@@warning("-44") +module InternalExpressionValue = ReducerInterface_InternalExpressionValue +module Project = ForTS_ReducerProject +module Bindings = Reducer_Bindings + +open Jest +open Expect +open Expect.Operators + +describe("ReducerProject Tutorial", () => { + /* Let's build a project to provide a function. */ + /* But we will call that function on an array of user input. */ + let project = Project.createProject() + Project.setSource(project, "library", "double(x) = x * 2") + /* userCode is not here yet but its dependency is fixed. So we can set it once and for all */ + Project.setContinues(project, "userCode", ["library"]) + + let userValues = [1, 2, 3, 4, 5] + + let userResults = Belt.Array.map(userValues, aUserValue => { + let userCode = `double(${aUserValue->Js.Int.toString})` + /* Put the constructed source in the project */ + /* We have already set that it depends on "library" */ + Project.setSource(project, "userCode", userCode) + /* Run the project */ + Project.runAll(project) + /* Get the result */ + Project.getResult(project, "userCode") + /* I have to remind you that the "library" is run only once and for all. + The library is not run for each user value. */ + }) + + test("userResults", () => { + let userResultsAsString = Belt.Array.map(userResults, aResult => + aResult->InternalExpressionValue.toStringOptionResult + ) + userResultsAsString->expect == ["Ok(2)", "Ok(4)", "Ok(6)", "Ok(8)", "Ok(10)"] + }) +}) From 1dfc9fe820e117e04f21df2879c2628d2beaf1d3 Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Thu, 25 Aug 2022 10:43:51 +0200 Subject: [PATCH 51/53] RENeedToRun->Error --- .../ReducerProject/ReducerProject_test.res | 2 +- .../ReducerProject_tutorial_0_test.res | 6 +++--- .../ReducerProject_tutorial_1_multisource_test.res | 6 +++--- .../ReducerProject_tutorial_2_includes_test.res | 2 +- ...cerProject_tutorial_3_injecting_user_values.res | 2 +- ...ReducerProject_tutorial_4_calling_functions.res | 2 +- .../src/rescript/ForTS/ForTS_ReducerProject.res | 5 +++-- .../src/rescript/Reducer/Reducer_ErrorValue.res | 2 ++ .../src/rescript/ReducerProject/ReducerProject.res | 14 ++++++++++---- 9 files changed, 25 insertions(+), 16 deletions(-) diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res index 7b3a75ff..d258d71a 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_test.res @@ -11,7 +11,7 @@ open Expect.Operators let runFetchResult = (project, sourceId) => { Project.run(project, sourceId) - Project.getResult(project, sourceId)->InternalExpressionValue.toStringOptionResult + Project.getResult(project, sourceId)->InternalExpressionValue.toStringResult } let runFetchBindings = (project, sourceId) => { diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_0_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_0_test.res index 61dbc11e..d6f43904 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_0_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_0_test.res @@ -50,7 +50,7 @@ Case "Running a single source". /* Let's display the result and bindings */ ( - result->InternalExpressionValue.toStringOptionResult, + result->InternalExpressionValue.toStringResult, bindings->InternalExpressionValue.IEvBindings->InternalExpressionValue.toString, )->expect == ("Ok(3)", "@{}") /* You've got 3 with empty bindings. */ @@ -64,7 +64,7 @@ Case "Running a single source". let bindings = Project.getBindings(project, "main") /* Now you have external bindings and external result. */ ( - result->InternalExpressionValue.toStringOptionResult, + result->InternalExpressionValue.toStringResult, bindings->InternalExpressionValue.IEvBindings->InternalExpressionValue.toString, )->expect == ("Ok(3)", "@{}") }) @@ -80,7 +80,7 @@ Case "Running a single source". Project.runAll(project) let result = Project.getResult(project, "main") let _bindings = Project.getBindings(project, "main") - result->InternalExpressionValue.toStringOptionResult->expect == "Ok(3)" + result->InternalExpressionValue.toStringResult->expect == "Ok(3)" }) test("shortcut", () => { diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_multisource_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_multisource_test.res index b0b44892..4362fcf6 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_multisource_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_1_multisource_test.res @@ -32,7 +32,7 @@ describe("ReducerProject Tutorial", () => { let bindings3 = Project.getBindings(project, "source3") ( - result3->InternalExpressionValue.toStringOptionResult, + result3->InternalExpressionValue.toStringResult, bindings3->InternalExpressionValue.IEvBindings->InternalExpressionValue.toString, )->expect == ("Ok(())", "@{x: 1,y: 2,z: 3}") }) @@ -58,7 +58,7 @@ describe("ReducerProject Tutorial", () => { let bindings3 = Project.getBindings(project, "source3") ( - result3->InternalExpressionValue.toStringOptionResult, + result3->InternalExpressionValue.toStringResult, bindings3->InternalExpressionValue.IEvBindings->InternalExpressionValue.toString, )->expect == ("Ok(())", "@{x: 1,y: 2,z: 3}") }) @@ -94,7 +94,7 @@ describe("ReducerProject Tutorial", () => { let bindings3 = Project.getBindings(project, "source3") ( - result3->InternalExpressionValue.toStringOptionResult, + result3->InternalExpressionValue.toStringResult, bindings3->InternalExpressionValue.IEvBindings->InternalExpressionValue.toString, )->expect == ("Ok(())", "@{x: 1,y: 2,z: 3}") /* diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_includes_test.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_includes_test.res index ce953ee0..a4c2e0a3 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_includes_test.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_2_includes_test.res @@ -146,7 +146,7 @@ Here we will finally proceed to a real life scenario. */ /* And see the result and bindings.. */ test("recursive includes", () => { ( - result->InternalExpressionValue.toStringOptionResult, + result->InternalExpressionValue.toStringResult, bindings->InternalExpressionValue.IEvBindings->InternalExpressionValue.toString, )->expect == ("Ok(6)", "@{doubleX: 2,x: 1,y: 2,z: 3}") /* Everything as expected */ diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_3_injecting_user_values.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_3_injecting_user_values.res index f47396b0..38d655c1 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_3_injecting_user_values.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_3_injecting_user_values.res @@ -30,7 +30,7 @@ describe("ReducerProject Tutorial", () => { /* We can now run the project */ Project.runAll(project) let result = Project.getResult(project, "main") - result->InternalExpressionValue.toStringOptionResult->expect == "Ok(6)" + result->InternalExpressionValue.toStringResult->expect == "Ok(6)" }) }) diff --git a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_4_calling_functions.res b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_4_calling_functions.res index d595f35a..7e2471b5 100644 --- a/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_4_calling_functions.res +++ b/packages/squiggle-lang/__tests__/ReducerProject/ReducerProject_tutorial_4_calling_functions.res @@ -32,7 +32,7 @@ describe("ReducerProject Tutorial", () => { test("userResults", () => { let userResultsAsString = Belt.Array.map(userResults, aResult => - aResult->InternalExpressionValue.toStringOptionResult + aResult->InternalExpressionValue.toStringResult ) userResultsAsString->expect == ["Ok(2)", "Ok(4)", "Ok(6)", "Ok(8)", "Ok(10)"] }) diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res index d35dd156..daf945b9 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res @@ -194,8 +194,9 @@ let getBindings = (project: reducerProject, sourceId: string): squiggleValue_Mod Get the result after running this source file or the project */ @genType -let getResult = (project: reducerProject, sourceId: string): option< - result, +let getResult = (project: reducerProject, sourceId: string): result< + squiggleValue, + reducerErrorValue, > => project->T.Private.castToInternalProject->Private.getResult(sourceId) /* diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res index a3d1acff..55cde709 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res @@ -21,6 +21,7 @@ type errorValue = | RESyntaxError(string, option) | RETodo(string) // To do | REUnitNotFound(string) + | RENeedToRun type t = errorValue @@ -57,4 +58,5 @@ let errorToString = err => | RETodo(msg) => `TODO: ${msg}` | REExpectedType(typeName, valueString) => `Expected type: ${typeName} but got: ${valueString}` | REUnitNotFound(unitName) => `Unit not found: ${unitName}` + | RENeedToRun => "Need to run" } diff --git a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res index b09a44d9..5f2fdce0 100644 --- a/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ReducerProject/ReducerProject.res @@ -96,9 +96,15 @@ module Private = { Belt.Map.String.set(project["items"], sourceId, newItem)->T.Private.setFieldItems(project, _) } - let getResult = (project: t, sourceId: string): ProjectItem.T.resultType => + 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, _) @@ -154,7 +160,7 @@ module Private = { sourceId: string, (rPrevResult: ProjectItem.T.resultArgumentType, continuation: ProjectItem.T.continuation), ): (ProjectItem.T.resultArgumentType, ProjectItem.T.continuation) => { - switch getResult(project, sourceId) { + switch getResultOption(project, sourceId) { | Some(result) => (result, getContinuation(project, sourceId)) // already ran | None => switch rPrevResult { @@ -165,7 +171,7 @@ module Private = { | Ok(_prevResult) => { doRunWithContinuation(project, sourceId, continuation) ( - getResult(project, sourceId)->Belt.Option.getWithDefault(rPrevResult), + getResultOption(project, sourceId)->Belt.Option.getWithDefault(rPrevResult), getContinuation(project, sourceId), ) } @@ -197,6 +203,6 @@ module Private = { let these = project->getStdLib let ofUser = Continuation.minus(those, these) - (getResult(project, "main")->Belt.Option.getWithDefault(IEvVoid->Ok), ofUser) + (getResultOption(project, "main")->Belt.Option.getWithDefault(IEvVoid->Ok), ofUser) } } From 7dd9a5bb7709a883c597d621429d9a6cbb6d58ee Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Thu, 25 Aug 2022 17:47:28 +0400 Subject: [PATCH 52/53] string enum for SquiggleValue tags --- .../ForTS_SquiggleValue.res | 70 +++++++++---------- .../ForTS_SquiggleValue_tag.ts | 34 ++++----- 2 files changed, 52 insertions(+), 52 deletions(-) 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 3d7586ff..30ce6f8c 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 @@ -12,61 +12,61 @@ type squiggleValue_Lambda = ForTS_SquiggleValue_Lambda.squiggleValue_Lambda //us // Return values are kept as they are if they are JavaScript types. -@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -external svtArray_: int = "SvtArray" +@module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") +external svtArray_: string = "SvtArray" -@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -external svtArrayString_: int = "SvtArrayString" +@module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") +external svtArrayString_: string = "SvtArrayString" -@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -external svtBool_: int = "SvtBool" +@module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") +external svtBool_: string = "SvtBool" -@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -external svtCall_: int = "SvtCall" +@module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") +external svtCall_: string = "SvtCall" -@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -external svtDate_: int = "SvtDate" +@module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") +external svtDate_: string = "SvtDate" -@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -external svtDeclaration_: int = "SvtDeclaration" +@module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") +external svtDeclaration_: string = "SvtDeclaration" -@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -external svtDistribution_: int = "SvtDistribution" +@module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") +external svtDistribution_: string = "SvtDistribution" -@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -external svtLambda_: int = "SvtLambda" +@module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") +external svtLambda_: string = "SvtLambda" -@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -external svtModule_: int = "SvtModule" +@module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") +external svtModule_: string = "SvtModule" -@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -external svtNumber_: int = "SvtNumber" +@module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") +external svtNumber_: string = "SvtNumber" -@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -external svtRecord_: int = "SvtRecord" +@module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") +external svtRecord_: string = "SvtRecord" -@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -external svtString_: int = "SvtString" +@module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") +external svtString_: string = "SvtString" -@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -external svtSymbol_: int = "SvtSymbol" +@module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") +external svtSymbol_: string = "SvtSymbol" -@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -external svtTimeDuration_: int = "SvtTimeDuration" +@module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") +external svtTimeDuration_: string = "SvtTimeDuration" -@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -external svtType_: int = "SvtType" +@module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") +external svtType_: string = "SvtType" -@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -external svtTypeIdentifier_: int = "SvtUndefined" +@module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") +external svtTypeIdentifier_: string = "SvtUndefined" -@module("ForTS_SquiggleValue_tag") @scope("squiggleValueTag") -external svtVoid_: int = "SvtVoid" +@module("./ForTS_SquiggleValue_tag") @scope("squiggleValueTag") +external svtVoid_: string = "SvtVoid" @genType.import("./ForTS_SquiggleValue_tag") type squiggleValueTag -external castEnum: int => squiggleValueTag = "%identity" +external castEnum: string => squiggleValueTag = "%identity" @genType let getTag = (variant: squiggleValue): squiggleValueTag => 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 6393ca60..f8b4a9e3 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,19 +1,19 @@ export enum squiggleValueTag { - SvtArray, - SvtArrayString, - SvtBool, - SvtCall, - SvtDate, - SvtDeclaration, - SvtDistribution, - SvtLambda, - SvtModule, - SvtNumber, - SvtRecord, - SvtString, - SvtSymbol, - SvtTimeDuration, - SvtType, - SvtTypeIdentifier, - SvtVoid, + SvtArray = "Array", + SvtArrayString = "ArrayString", + SvtBool = "Bool", + SvtCall = "Call", + SvtDate = "Date", + SvtDeclaration = "Declaration", + SvtDistribution = "Distribution", + SvtLambda = "Lambda", + SvtModule = "Module", + SvtNumber = "Number", + SvtRecord = "Record", + SvtString = "String", + SvtSymbol = "Symbol", + SvtTimeDuration = "TimeDuration", + SvtType = "Type", + SvtTypeIdentifier = "TypeIdentifier", + SvtVoid = "Void", } From 1f22d1f837472cde531354d9bbaff633172c0cb3 Mon Sep 17 00:00:00 2001 From: Vyacheslav Matyukhin Date: Thu, 25 Aug 2022 17:47:41 +0400 Subject: [PATCH 53/53] non-opaque results --- .../Distributions/DistributionOperation.res | 1 - .../Distributions/DistributionOperation.resi | 1 - .../rescript/Distributions/GenericDist.res | 1 - .../rescript/Distributions/GenericDist.resi | 2 - .../rescript/ForTS/ForTS_ReducerProject.res | 1 - .../src/rescript/ForTS/ForTS_Result.res | 44 ------------------- .../src/rescript/ForTS/ForTS_Result_tag.ts | 13 ++++-- .../ForTS_SquiggleValue.res | 3 +- .../src/rescript/ForTS/ForTS__Types.res | 2 - .../src/rescript/TypescriptInterface.res | 10 ++--- 10 files changed, 15 insertions(+), 63 deletions(-) delete mode 100644 packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.res b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.res index 97068765..319535c1 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.res +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.res @@ -1,4 +1,3 @@ -type result<'a, 'e> = ForTS_Result.result<'a, 'e> // Use opaque result type type functionCallInfo = DistributionTypes.DistributionOperation.genericFunctionCallInfo type genericDist = DistributionTypes.genericDist type error = DistributionTypes.error diff --git a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.resi b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.resi index 7cdc3706..68da9534 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.resi +++ b/packages/squiggle-lang/src/rescript/Distributions/DistributionOperation.resi @@ -1,4 +1,3 @@ -type result<'a, 'e> = ForTS_Result.result<'a, 'e> // Use opaque result type @genType let defaultEnv: GenericDist.env diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist.res b/packages/squiggle-lang/src/rescript/Distributions/GenericDist.res index 2db7a05d..c2bdd299 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist.res +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist.res @@ -1,5 +1,4 @@ //TODO: multimodal, add interface, test somehow, track performance, refactor sampleSet, refactor ASTEvaluator.res. -type result<'a, 'e> = ForTS_Result.result<'a, 'e> // Use opaque result type type t = DistributionTypes.genericDist type error = DistributionTypes.error diff --git a/packages/squiggle-lang/src/rescript/Distributions/GenericDist.resi b/packages/squiggle-lang/src/rescript/Distributions/GenericDist.resi index ba69c1f3..fd04212a 100644 --- a/packages/squiggle-lang/src/rescript/Distributions/GenericDist.resi +++ b/packages/squiggle-lang/src/rescript/Distributions/GenericDist.resi @@ -1,5 +1,3 @@ -type result<'a, 'e> = ForTS_Result.result<'a, 'e> // Use opaque result type - type t = DistributionTypes.genericDist type error = DistributionTypes.error type toPointSetFn = t => result diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res index daf945b9..27302313 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_ReducerProject.res @@ -1,6 +1,5 @@ @genType type reducerProject = ReducerProject_T.t //re-export -type result<'a, 'e> = ForTS_Result.result<'a, 'e> // Use opaque result type type reducerErrorValue = ForTS_Reducer_ErrorValue.reducerErrorValue //use type squiggleValue = ForTS_SquiggleValue.squiggleValue //use diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res deleted file mode 100644 index 99c4bceb..00000000 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result.res +++ /dev/null @@ -1,44 +0,0 @@ -@genType.opaque type result_<'a, 'e> = result<'a, 'e> -@genType type result<'a, 'e> = result_<'a, 'e> // alias and re-export - -@genType let isError = (r: result_<'a, 'e>): bool => Belt.Result.isError(r) -@genType let isOk = (r: result_<'a, 'e>): bool => Belt.Result.isOk(r) - -@genType -let getError = (r: result_<'a, 'e>): option<'e> => - switch r { - | Ok(_) => None - | Error(e) => Some(e) - } - -@genType -let getValue = (r: result<'a, 'e>): option<'a> => - switch r { - | Ok(v) => Some(v) - | Error(_) => None - } - -@module("./ForTS_Result_tag") @scope("resultTag") -external rtOk_: int = "RtOk" - -@module("./ForTS_Result_tag") @scope("resultTag") -external rtError_: int = "RtError" - -@genType.import("./ForTS_Result_tag") -type resultTag - -external castEnum: int => resultTag = "%identity" - -@genType -let getTag = (r: result<'a, 'e>): resultTag => - switch r { - | Ok(_) => rtOk_->castEnum - | Error(_) => rtError_->castEnum - } - -@genType -let fmap = (r: result<'a, 'e>, f: 'a => 'b): result<'b, 'e> => - switch r { - | Ok(v) => Ok(f(v)) - | Error(e) => Error(e) - } diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result_tag.ts b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result_tag.ts index 2091415b..73da47b3 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result_tag.ts +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS_Result_tag.ts @@ -1,4 +1,9 @@ -export enum resultTag { - RtOk, - RtError, -} +export type result = + | { + tag: "Ok"; + value: a; + } + | { + tag: "Error"; + value: b; + }; 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 30ce6f8c..df5510d5 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,5 +1,4 @@ @genType type squiggleValue = ReducerInterface_InternalExpressionValue.t //re-export -type result_<'a, 'e> = ForTS_Result.result_<'a, 'e> //use type reducerErrorValue = ForTS_Reducer_ErrorValue.reducerErrorValue //use @genType type squiggleValue_Array = ReducerInterface_InternalExpressionValue.squiggleArray //re-export recursive type @@ -97,7 +96,7 @@ let toString = (variant: squiggleValue) => // This is a useful method for unit tests. // Convert the result along with the error message to a string. @genType -let toStringResult = (variantResult: result_) => +let toStringResult = (variantResult: result) => ReducerInterface_InternalExpressionValue.toStringResult(variantResult) @genType diff --git a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res index 88d22b65..b97c93e0 100644 --- a/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res +++ b/packages/squiggle-lang/src/rescript/ForTS/ForTS__Types.res @@ -1,5 +1,3 @@ -@genType type result_<'a, 'e> = ForTS_Result.result_<'a, 'e> //re-export -@genType type result<'a, 'e> = ForTS_Result.result<'a, 'e> //re-export @genType type reducerErrorValue = ForTS_Reducer_ErrorValue.reducerErrorValue //re-export @genType type syntaxErrorLocation = ForTS_Reducer_ErrorValue.syntaxErrorLocation //re-export diff --git a/packages/squiggle-lang/src/rescript/TypescriptInterface.res b/packages/squiggle-lang/src/rescript/TypescriptInterface.res index 16076f52..428fb0cd 100644 --- a/packages/squiggle-lang/src/rescript/TypescriptInterface.res +++ b/packages/squiggle-lang/src/rescript/TypescriptInterface.res @@ -15,12 +15,12 @@ The below few seem to work fine. In the future there's definitely more work to d @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 type resultDist = result //alternative +@genType type resultFloat = result //alternative +@genType type resultString = result //alternative @genType -let makeSampleSetDist: array => result_< +let makeSampleSetDist: array => result< sampleSetDist, SampleSetDist.sampleSetError, > = SampleSetDist.make @@ -33,7 +33,7 @@ let toPointSet: ( ~sampleCount: int, ~xSelection: DistributionTypes.DistributionOperation.pointsetXSelection=?, unit, -) => result_ = GenericDist.toPointSet +) => result = GenericDist.toPointSet @genType type mixedShape = PointSetTypes.mixedShape