Merge remote-tracking branch 'origin/develop' into scoring-cleanup-three

This commit is contained in:
Quinn Dougherty 2022-06-24 08:48:07 -04:00
commit 3e67180fe1
66 changed files with 1601 additions and 2222 deletions

View File

@ -0,0 +1,4 @@
open Jest
open Expect
test("todo", () => expect("1")->toBe("1"))

View File

@ -19,23 +19,23 @@ describe("bindStatement", () => {
testMacro(
[],
eBindStatement(eBindings([]), exampleStatementY),
"Ok((:$_setBindings_$ {} :y 1) context: {})",
"Ok((:$_setBindings_$ @{} :y 1) context: @{})",
)
// Then it answers the bindings for the next statement when reduced
testMacroEval([], eBindStatement(eBindings([]), exampleStatementY), "Ok({y: 1})")
testMacroEval([], eBindStatement(eBindings([]), exampleStatementY), "Ok(@{y: 1})")
// Now let's feed a binding to see what happens
testMacro(
[],
eBindStatement(eBindings([("x", EvNumber(2.))]), exampleStatementX),
"Ok((:$_setBindings_$ {x: 2} :y 2) context: {x: 2})",
eBindStatement(eBindings([("x", IEvNumber(2.))]), exampleStatementX),
"Ok((:$_setBindings_$ @{x: 2} :y 2) context: @{x: 2})",
)
// An expression does not return a binding, thus error
testMacro([], eBindStatement(eBindings([]), exampleExpression), "Assignment expected")
// When bindings from previous statement are missing the context is injected. This must be the first statement of a block
testMacro(
[("z", EvNumber(99.))],
[("z", IEvNumber(99.))],
eBindStatementDefault(exampleStatementY),
"Ok((:$_setBindings_$ {z: 99} :y 1) context: {z: 99})",
"Ok((:$_setBindings_$ @{z: 99} :y 1) context: @{z: 99})",
)
})
@ -43,26 +43,26 @@ describe("bindExpression", () => {
// x is simply bound in the expression
testMacro(
[],
eBindExpression(eBindings([("x", EvNumber(2.))]), eSymbol("x")),
"Ok(2 context: {x: 2})",
eBindExpression(eBindings([("x", IEvNumber(2.))]), eSymbol("x")),
"Ok(2 context: @{x: 2})",
)
// When an let statement is the end expression then bindings are returned
testMacro(
[],
eBindExpression(eBindings([("x", EvNumber(2.))]), exampleStatementY),
"Ok((:$_exportBindings_$ (:$_setBindings_$ {x: 2} :y 1)) context: {x: 2})",
eBindExpression(eBindings([("x", IEvNumber(2.))]), exampleStatementY),
"Ok((:$_exportBindings_$ (:$_setBindings_$ @{x: 2} :y 1)) context: @{x: 2})",
)
// Now let's reduce that expression
testMacroEval(
[],
eBindExpression(eBindings([("x", EvNumber(2.))]), exampleStatementY),
"Ok({x: 2,y: 1})",
eBindExpression(eBindings([("x", IEvNumber(2.))]), exampleStatementY),
"Ok(@{x: 2,y: 1})",
)
// When bindings are missing the context is injected. This must be the first and last statement of a block
testMacroEval(
[("z", EvNumber(99.))],
[("z", IEvNumber(99.))],
eBindExpressionDefault(exampleStatementY),
"Ok({y: 1,z: 99})",
"Ok(@{y: 1,z: 99})",
)
})
@ -72,7 +72,7 @@ describe("block", () => {
testMacroEval([], eBlock(list{exampleExpression}), "Ok(1)")
// Block with a single statement
testMacro([], eBlock(list{exampleStatementY}), "Ok((:$$_bindExpression_$$ (:$_let_$ :y 1)))")
testMacroEval([], eBlock(list{exampleStatementY}), "Ok({y: 1})")
testMacroEval([], eBlock(list{exampleStatementY}), "Ok(@{y: 1})")
// Block with a statement and an expression
testMacro(
[],
@ -86,7 +86,7 @@ describe("block", () => {
eBlock(list{exampleStatementY, exampleStatementZ}),
"Ok((:$$_bindExpression_$$ (:$$_bindStatement_$$ (:$_let_$ :y 1)) (:$_let_$ :z :y)))",
)
testMacroEval([], eBlock(list{exampleStatementY, exampleStatementZ}), "Ok({y: 1,z: 1})")
testMacroEval([], eBlock(list{exampleStatementY, exampleStatementZ}), "Ok(@{y: 1,z: 1})")
// Block inside a block
testMacro([], eBlock(list{eBlock(list{exampleExpression})}), "Ok((:$$_bindExpression_$$ {1}))")
testMacroEval([], eBlock(list{eBlock(list{exampleExpression})}), "Ok(1)")
@ -99,7 +99,7 @@ describe("block", () => {
testMacroEval(
[],
eBlock(list{eLetStatement("z", eBlock(list{eBlock(list{exampleExpressionY})}))}),
"Ok({z: :y})",
"Ok(@{z: :y})",
)
// Empty block
testMacro([], eBlock(list{}), "Ok(:undefined block)") //TODO: should be an error
@ -115,7 +115,7 @@ describe("block", () => {
"Ok((:$$_bindExpression_$$ {(:$_let_$ :y (:add :x 1)); :y}))",
)
testMacroEval(
[("x", EvNumber(1.))],
[("x", IEvNumber(1.))],
eBlock(list{
eBlock(list{
eLetStatement("y", eFunction("add", list{eSymbol("x"), eNumber(1.)})),
@ -135,12 +135,12 @@ describe("lambda", () => {
testMacro([], callLambdaExpression, "Ok(((:$$_lambda_$$ [y] :y) 1))")
testMacroEval([], callLambdaExpression, "Ok(1)")
// Parameters shadow the outer scope
testMacroEval([("y", EvNumber(666.))], callLambdaExpression, "Ok(1)")
testMacroEval([("y", IEvNumber(666.))], callLambdaExpression, "Ok(1)")
// When not shadowed by the parameters, the outer scope variables are available
let lambdaExpression = eFunction(
"$$_lambda_$$",
list{eArrayString(["z"]), eFunction("add", list{eSymbol("y"), eSymbol("z")})},
)
let callLambdaExpression = eList(list{lambdaExpression, eNumber(1.)})
testMacroEval([("y", EvNumber(666.))], callLambdaExpression, "Ok(667)")
testMacroEval([("y", IEvNumber(666.))], callLambdaExpression, "Ok(667)")
})

View File

@ -1,4 +1,4 @@
module ExpressionValue = ReducerInterface.ExpressionValue
module ExpressionValue = ReducerInterface.ExternalExpressionValue
open Jest
open Expect

View File

@ -1,19 +1,22 @@
module ExpressionT = Reducer_Expression_T
module ExpressionValue = ReducerInterface.ExpressionValue
// Reducer_Helpers
module ErrorValue = Reducer_ErrorValue
module Bindings = Reducer_Category_Bindings
module ExternalExpressionValue = ReducerInterface.ExternalExpressionValue
module InternalExpressionValue = ReducerInterface.InternalExpressionValue
module Module = Reducer_Category_Module
let removeDefaults = (ev: ExpressionT.expressionValue): ExpressionT.expressionValue =>
switch ev {
| EvRecord(extbindings) => {
let bindings: Bindings.t = Bindings.fromRecord(extbindings)
let keys = Js.Dict.keys(Reducer.defaultExternalBindings)
Belt.Map.String.keep(bindings, (key, _value) => {
let removeThis = Js.Array2.includes(keys, key)
!removeThis
})->Bindings.toExpressionValue
}
let removeDefaultsInternal = (iev: InternalExpressionValue.t) => {
switch iev {
| InternalExpressionValue.IEvModule(nameSpace) =>
Module.removeOther(
nameSpace,
ReducerInterface.StdLib.internalStdLib,
)->InternalExpressionValue.IEvModule
| value => value
}
}
let rRemoveDefaults = r => Belt.Result.map(r, ev => removeDefaults(ev))
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)

View File

@ -1,4 +1,3 @@
open ReducerInterface.ExpressionValue
module MathJs = Reducer_MathJs
module ErrorValue = Reducer.ErrorValue
@ -6,14 +5,14 @@ open Jest
open ExpectJs
describe("eval", () => {
test("Number", () => expect(MathJs.Eval.eval("1"))->toEqual(Ok(EvNumber(1.))))
test("Number expr", () => expect(MathJs.Eval.eval("1-1"))->toEqual(Ok(EvNumber(0.))))
test("String", () => expect(MathJs.Eval.eval("'hello'"))->toEqual(Ok(EvString("hello"))))
test("Number", () => expect(MathJs.Eval.eval("1"))->toEqual(Ok(IEvNumber(1.))))
test("Number expr", () => expect(MathJs.Eval.eval("1-1"))->toEqual(Ok(IEvNumber(0.))))
test("String", () => expect(MathJs.Eval.eval("'hello'"))->toEqual(Ok(IEvString("hello"))))
test("String expr", () =>
expect(MathJs.Eval.eval("concat('hello ','world')"))->toEqual(Ok(EvString("hello world")))
expect(MathJs.Eval.eval("concat('hello ','world')"))->toEqual(Ok(IEvString("hello world")))
)
test("Boolean", () => expect(MathJs.Eval.eval("true"))->toEqual(Ok(EvBool(true))))
test("Boolean expr", () => expect(MathJs.Eval.eval("2>1"))->toEqual(Ok(EvBool(true))))
test("Boolean", () => expect(MathJs.Eval.eval("true"))->toEqual(Ok(IEvBool(true))))
test("Boolean expr", () => expect(MathJs.Eval.eval("2>1"))->toEqual(Ok(IEvBool(true))))
})
describe("errors", () => {

View File

@ -1,6 +1,6 @@
module Expression = Reducer_Expression
module ExpressionT = Reducer_Expression_T
module ExpressionValue = ReducerInterface_ExpressionValue
module ExpressionValue = ReducerInterface.InternalExpressionValue
module Parse = Reducer_Peggy_Parse
module Result = Belt.Result
module ToExpression = Reducer_Peggy_ToExpression
@ -29,7 +29,7 @@ let expectToExpressionToBe = (expr, answer, ~v="_", ()) => {
ExpressionValue.defaultEnvironment,
)
)
->Reducer_Helpers.rRemoveDefaults
->Reducer_Helpers.rRemoveDefaultsInternal
->ExpressionValue.toStringResultOkless
(a1, a2)->expect->toEqual((answer, v))
}

View File

@ -22,11 +22,11 @@ describe("Peggy to Expression", () => {
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; y=2", "{(:$_let_$ :x {1}); (:$_let_$ :y {2})}", ~v="@{x: 1,y: 2}", ())
})
describe("variables", () => {
testToExpression("x = 1", "{(:$_let_$ :x {1})}", ~v="{x: 1}", ())
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", ())
})
@ -35,7 +35,7 @@ describe("Peggy to Expression", () => {
testToExpression(
"identity(x) = x",
"{(:$_let_$ :identity (:$$_lambda_$$ [x] {:x}))}",
~v="{identity: lambda(x=>internal code)}",
~v="@{identity: lambda(x=>internal code)}",
(),
) // Function definitions become lambda assignments
testToExpression("identity(x)", "{(:identity :x)}", ()) // Note value returns error properly
@ -155,7 +155,7 @@ describe("Peggy to Expression", () => {
testToExpression(
"y=99; x={y=1; y}",
"{(:$_let_$ :y {99}); (:$_let_$ :x {(:$_let_$ :y {1}); :y})}",
~v="{x: 1,y: 99}",
~v="@{x: 1,y: 99}",
(),
)
})
@ -165,19 +165,19 @@ describe("Peggy to Expression", () => {
testToExpression(
"f={|x| x}",
"{(:$_let_$ :f {(:$$_lambda_$$ [x] {:x})})}",
~v="{f: lambda(x=>internal code)}",
~v="@{f: lambda(x=>internal code)}",
(),
)
testToExpression(
"f(x)=x",
"{(:$_let_$ :f (:$$_lambda_$$ [x] {:x}))}",
~v="{f: lambda(x=>internal code)}",
~v="@{f: lambda(x=>internal code)}",
(),
) // 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)}",
~v="@{f: lambda(x=>internal code)}",
(),
)
})

View File

@ -6,7 +6,7 @@ describe("Peggy Types to Expression", () => {
testToExpression(
"p: number",
"{(:$_typeOf_$ :p #number)}",
~v="{_typeReferences_: {p: #number}}",
~v="@{_typeReferences_: {p: #number}}",
(),
)
})
@ -14,7 +14,7 @@ describe("Peggy Types to Expression", () => {
testToExpression(
"type index=number",
"{(:$_typeAlias_$ #index #number)}",
~v="{_typeAliases_: {index: #number}}",
~v="@{_typeAliases_: {index: #number}}",
(),
)
})
@ -22,7 +22,7 @@ describe("Peggy Types to Expression", () => {
testToExpression(
"answer: number|string|distribution",
"{(:$_typeOf_$ :answer (:$_typeOr_$ (:$_constructArray_$ (#number #string #distribution))))}",
~v="{_typeReferences_: {answer: {typeTag: 'typeOr',typeOr: [#number,#string,#distribution]}}}",
~v="@{_typeReferences_: {answer: {typeOr: [#number,#string,#distribution],typeTag: 'typeOr'}}}",
(),
)
})
@ -30,13 +30,13 @@ describe("Peggy Types to Expression", () => {
testToExpression(
"f: number=>number=>number",
"{(:$_typeOf_$ :f (:$_typeFunction_$ (:$_constructArray_$ (#number #number #number))))}",
~v="{_typeReferences_: {f: {typeTag: 'typeFunction',inputs: [#number,#number],output: #number}}}",
~v="@{_typeReferences_: {f: {inputs: [#number,#number],output: #number,typeTag: 'typeFunction'}}}",
(),
)
testToExpression(
"f: number=>number",
"{(:$_typeOf_$ :f (:$_typeFunction_$ (:$_constructArray_$ (#number #number))))}",
~v="{_typeReferences_: {f: {typeTag: 'typeFunction',inputs: [#number],output: #number}}}",
~v="@{_typeReferences_: {f: {inputs: [#number],output: #number,typeTag: 'typeFunction'}}}",
(),
)
})
@ -44,37 +44,37 @@ describe("Peggy Types to Expression", () => {
testToExpression(
"answer: number<-min(1)<-max(100)|string",
"{(:$_typeOf_$ :answer (:$_typeOr_$ (:$_constructArray_$ ((:$_typeModifier_max_$ (:$_typeModifier_min_$ #number 1) 100) #string))))}",
~v="{_typeReferences_: {answer: {typeTag: 'typeOr',typeOr: [{typeTag: 'typeIdentifier',typeIdentifier: #number,min: 1,max: 100},#string]}}}",
~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: {typeTag: 'typeIdentifier',typeIdentifier: #number,memberOf: [1,3,5]}}}",
~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: {typeTag: 'typeIdentifier',typeIdentifier: #number,min: 1}}}",
~v="@{_typeReferences_: {answer: {min: 1,typeIdentifier: #number,typeTag: 'typeIdentifier'}}}",
(),
)
testToExpression(
"answer: number<-max(10)",
"{(:$_typeOf_$ :answer (:$_typeModifier_max_$ #number 10))}",
~v="{_typeReferences_: {answer: {typeTag: 'typeIdentifier',typeIdentifier: #number,max: 10}}}",
~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: {typeTag: 'typeIdentifier',typeIdentifier: #number,min: 1,max: 10}}}",
~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: {typeTag: 'typeIdentifier',typeIdentifier: #number,max: 10,min: 1}}}",
~v="@{_typeReferences_: {answer: {max: 10,min: 1,typeIdentifier: #number,typeTag: 'typeIdentifier'}}}",
(),
)
})
@ -82,7 +82,7 @@ describe("Peggy Types to Expression", () => {
testToExpression(
"answer: number | string $ opaque",
"{(:$_typeOf_$ :answer (:$_typeModifier_opaque_$ (:$_typeOr_$ (:$_constructArray_$ (#number #string)))))}",
~v="{_typeReferences_: {answer: {typeTag: 'typeOr',typeOr: [#number,#string],opaque: true}}}",
~v="@{_typeReferences_: {answer: {opaque: true,typeOr: [#number,#string],typeTag: 'typeOr'}}}",
(),
)
})
@ -90,7 +90,7 @@ describe("Peggy Types to Expression", () => {
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: {typeTag: 'typeIdentifier',typeIdentifier: #number,memberOf: [1,3,5,7,9]}},odds1: [1,3,5],odds2: [7,9]}",
~v="@{_typeAliases_: {odds: {memberOf: [1,3,5,7,9],typeIdentifier: #number,typeTag: 'typeIdentifier'}},odds1: [1,3,5],odds2: [7,9]}",
(),
)
})

View File

@ -1,7 +1,6 @@
module ExpressionT = Reducer_Expression_T
module ExpressionValue = ReducerInterface.ExpressionValue
module ExternalExpressionValue = ReducerInterface.ExternalExpressionValue
module ErrorValue = Reducer_ErrorValue
module Bindings = Reducer_Category_Bindings
open Jest
open Expect
@ -9,7 +8,7 @@ open Expect
let unwrapRecord = rValue =>
rValue->Belt.Result.flatMap(value =>
switch value {
| ExpressionValue.EvRecord(aRecord) => Ok(aRecord)
| ExternalExpressionValue.EvRecord(aRecord) => Ok(aRecord)
| _ => ErrorValue.RETodo("TODO: External bindings must be returned")->Error
}
)
@ -19,18 +18,18 @@ let expectParseToBe = (expr: string, answer: string) =>
let expectEvalToBe = (expr: string, answer: string) =>
Reducer.evaluate(expr)
->Reducer_Helpers.rRemoveDefaults
->ExpressionValue.toStringResult
->Reducer_Helpers.rRemoveDefaultsExternal
->ExternalExpressionValue.toStringResult
->expect
->toBe(answer)
let expectEvalError = (expr: string) =>
Reducer.evaluate(expr)->ExpressionValue.toStringResult->expect->toMatch("Error\(")
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.rRemoveDefaults
->ExpressionValue.toStringResult
->Reducer_Helpers.rRemoveDefaultsExternal
->ExternalExpressionValue.toStringResult
->expect
->toBe(answer)

View File

@ -1,25 +1,27 @@
open Jest
open Expect
module Bindings = Reducer_Expression_Bindings
module BindingsReplacer = Reducer_Expression_BindingsReplacer
module Expression = Reducer_Expression
module ExpressionValue = ReducerInterface_ExpressionValue
// module ExpressionValue = ReducerInterface.ExpressionValue
module InternalExpressionValue = ReducerInterface.InternalExpressionValue
module ExpressionWithContext = Reducer_ExpressionWithContext
module Macro = Reducer_Expression_Macro
module T = Reducer_Expression_T
module Module = Reducer_Category_Module
let testMacro_ = (
tester,
bindArray: array<(string, ExpressionValue.expressionValue)>,
bindArray: array<(string, InternalExpressionValue.t)>,
expr: T.expression,
expectedCode: string,
) => {
let bindings = Belt.Map.String.fromArray(bindArray)
let bindings = Module.fromArray(bindArray)
tester(expr->T.toString, () =>
expr
->Macro.expandMacroCall(
bindings,
ExpressionValue.defaultEnvironment,
InternalExpressionValue.defaultEnvironment,
Expression.reduceExpression,
)
->ExpressionWithContext.toStringResult
@ -30,39 +32,43 @@ let testMacro_ = (
let testMacroEval_ = (
tester,
bindArray: array<(string, ExpressionValue.expressionValue)>,
bindArray: array<(string, InternalExpressionValue.t)>,
expr: T.expression,
expectedValue: string,
) => {
let bindings = Belt.Map.String.fromArray(bindArray)
let bindings = Module.fromArray(bindArray)
tester(expr->T.toString, () =>
expr
->Macro.doMacroCall(bindings, ExpressionValue.defaultEnvironment, Expression.reduceExpression)
->ExpressionValue.toStringResult
->Macro.doMacroCall(
bindings,
InternalExpressionValue.defaultEnvironment,
Expression.reduceExpression,
)
->InternalExpressionValue.toStringResult
->expect
->toEqual(expectedValue)
)
}
let testMacro = (
bindArray: array<(string, ExpressionValue.expressionValue)>,
bindArray: array<(string, InternalExpressionValue.t)>,
expr: T.expression,
expectedExpr: string,
) => testMacro_(test, bindArray, expr, expectedExpr)
let testMacroEval = (
bindArray: array<(string, ExpressionValue.expressionValue)>,
bindArray: array<(string, InternalExpressionValue.t)>,
expr: T.expression,
expectedValue: string,
) => testMacroEval_(test, bindArray, expr, expectedValue)
module MySkip = {
let testMacro = (
bindArray: array<(string, ExpressionValue.expressionValue)>,
bindArray: array<(string, InternalExpressionValue.t)>,
expr: T.expression,
expectedExpr: string,
) => testMacro_(Skip.test, bindArray, expr, expectedExpr)
let testMacroEval = (
bindArray: array<(string, ExpressionValue.expressionValue)>,
bindArray: array<(string, InternalExpressionValue.t)>,
expr: T.expression,
expectedValue: string,
) => testMacroEval_(Skip.test, bindArray, expr, expectedValue)
@ -70,12 +76,12 @@ module MySkip = {
module MyOnly = {
let testMacro = (
bindArray: array<(string, ExpressionValue.expressionValue)>,
bindArray: array<(string, InternalExpressionValue.t)>,
expr: T.expression,
expectedExpr: string,
) => testMacro_(Only.test, bindArray, expr, expectedExpr)
let testMacroEval = (
bindArray: array<(string, ExpressionValue.expressionValue)>,
bindArray: array<(string, InternalExpressionValue.t)>,
expr: T.expression,
expectedValue: string,
) => testMacroEval_(Only.test, bindArray, expr, expectedValue)

View File

@ -1,11 +1,14 @@
// TODO: Reimplement with usual parse
open Jest
open Reducer_TestHelpers
describe("Eval with Bindings", () => {
testEvalBindingsToBe("x", list{("x", ExpressionValue.EvNumber(1.))}, "Ok(1)")
testEvalBindingsToBe("x+1", list{("x", ExpressionValue.EvNumber(1.))}, "Ok(2)")
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", ExpressionValue.EvNumber(1.))}, "Ok(2)")
testEvalBindingsToBe("y = x+1", list{("x", ExpressionValue.EvNumber(1.))}, "Ok({x: 1,y: 2})")
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})",
)
})

View File

@ -39,15 +39,15 @@ describe("symbol not defined", () => {
})
describe("call and bindings", () => {
testEvalToBe("f(x)=x+1", "Ok({f: lambda(x=>internal code)})")
testEvalToBe("f(x)=x+1", "Ok(@{f: lambda(x=>internal code)})")
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(@{f: 1,y: 2})")
testEvalToBe("f(x)=x+1; y=f(1)", "Ok(@{f: lambda(x=>internal code),y: 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; 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)})",
"Ok(@{f: lambda(x=>internal code),g: lambda(x=>internal code)})",
)
testParseToBe(
"f=99; g(x)=f; g(2)",
@ -57,7 +57,7 @@ describe("call and bindings", () => {
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})",
"Ok(@{f: lambda(x=>internal code),g: lambda(x=>internal code),y: 4})",
)
testEvalToBe("f(x)=x+1; g(x)=f(x)+1; g(2)", "Ok(4)")
})
@ -65,7 +65,7 @@ describe("call and bindings", () => {
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", "Ok(@{g: lambda(x=>internal code),y: 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))")
@ -75,7 +75,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)]})",
"Ok(@{myadd: lambda(x,y=>internal code),z: [lambda(x,y=>internal code)]})",
)
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)")

View File

@ -39,7 +39,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", "Ok(@{x: 1})")
})
})

View File

@ -1,4 +1,4 @@
open ReducerInterface.ExpressionValue
open ReducerInterface.ExternalExpressionValue
open Jest
open Expect

View File

@ -31,6 +31,7 @@
"basic": false
}
},
"external-stdlib": "@rescript/std",
"refmt": 3,
"warnings": {
"number": "+A-42-48-9-30-4"

View File

@ -5,6 +5,7 @@
"license": "MIT",
"scripts": {
"peggy": "peggy --cache",
"rescript": "rescript",
"build": "yarn build:peggy && yarn build:rescript && yarn build:typescript",
"build:peggy": "find . -type f -name *.peggy -exec yarn peggy {} \\;",
"build:rescript": "rescript build -with-deps",
@ -36,12 +37,12 @@
],
"author": "Quantified Uncertainty Research Institute",
"dependencies": {
"@rescript/std": "^9.1.4",
"@stdlib/stats": "^0.0.13",
"jstat": "^1.9.5",
"lodash": "^4.17.21",
"mathjs": "^10.6.0",
"pdfast": "^0.2.0",
"rescript": "^9.1.4"
"pdfast": "^0.2.0"
},
"devDependencies": {
"@glennsl/rescript-jest": "^0.9.0",
@ -59,6 +60,7 @@
"peggy": "^2.0.1",
"prettier": "^2.7.1",
"reanalyze": "^2.23.0",
"rescript": "^9.1.4",
"rescript-fast-check": "^1.1.1",
"ts-jest": "^27.1.4",
"ts-loader": "^9.3.0",

View File

@ -10,6 +10,7 @@ import {
evaluatePartialUsingExternalBindings,
evaluateUsingOptions,
foreignFunctionInterface,
parse as parseRescript,
} from "../rescript/TypescriptInterface.gen";
export {
makeSampleSetDist,
@ -31,7 +32,7 @@ import {
convertRawToTypescript,
lambdaValue,
} from "./rescript_interop";
import { result, resultMap, tag, tagged } from "./types";
import { Ok, result, resultMap, tag, tagged } from "./types";
import { Distribution, shape } from "./distribution";
export { Distribution, resultMap, defaultEnvironment };
@ -58,6 +59,23 @@ export function run(
return resultMap(res, (x) => createTsExport(x, e));
}
export function parse(
squiggleString: string
): result<null, Extract<errorValue, { tag: "RESyntaxError" }>> {
const maybeExpression = parseRescript(squiggleString);
if (maybeExpression.tag === "Ok") {
return Ok(null); // TODO - return AST
} else {
if (
typeof maybeExpression.value !== "object" ||
maybeExpression.value.tag !== "RESyntaxError"
) {
throw new Error("Expected syntax error");
}
return { tag: "Error", value: maybeExpression.value };
}
}
// Run Partial. A partial is a block of code that doesn't return a value
export function runPartial(
squiggleString: string,
@ -129,30 +147,13 @@ function createTsExport(
// case
return tag(
"array",
x.value.map((arrayItem): squiggleExpression => {
switch (arrayItem.tag) {
case "EvRecord":
return tag(
"record",
_.mapValues(arrayItem.value, (recordValue: unknown) =>
convertRawToTypescript(
recordValue as rescriptExport,
environment
)
)
);
case "EvArray":
let y = arrayItem.value as unknown as rescriptExport[];
return tag(
"array",
y.map((childArrayItem) =>
convertRawToTypescript(childArrayItem, environment)
)
);
default:
return createTsExport(arrayItem, environment);
}
})
x.value.map(
(arrayItem): squiggleExpression =>
convertRawToTypescript(
arrayItem as unknown as rescriptExport,
environment
)
)
);
case "EvArrayString":
return tag("arraystring", x.value);

View File

@ -1,3 +1,4 @@
@@warning("-27") //TODO: Remove and fix the warning
open Distributions
type t = PointSetTypes.discreteShape

View File

@ -1,3 +1,5 @@
@@warning("-27") //TODO: Remove and fix the warning
@@warning("-32") //TODO: Remove and fix the warning
open Distributions
type t = PointSetTypes.mixedShape

View File

@ -1,4 +1,4 @@
type expressionValue = ReducerInterface_ExpressionValue.expressionValue
type internalExpressionValue = ReducerInterface_InternalExpressionValue.t
/*
Function Registry "Type". A type, without any other information.
@ -28,7 +28,7 @@ type rec frValue =
| FRValueArray(array<frValue>)
| FRValueDistOrNumber(frValueDistOrNumber)
| FRValueRecord(frValueRecord)
| FRValueLambda(ReducerInterface_ExpressionValue.lambdaValue)
| FRValueLambda(ReducerInterface_InternalExpressionValue.lambdaValue)
| FRValueString(string)
| FRValueVariant(string)
| FRValueAny(frValue)
@ -41,7 +41,7 @@ and frValueDistOrNumber = FRValueNumber(float) | FRValueDist(DistributionTypes.g
type fnDefinition = {
name: string,
inputs: array<frType>,
run: (array<frValue>, DistributionOperation.env) => result<expressionValue, string>,
run: (array<frValue>, DistributionOperation.env) => result<internalExpressionValue, string>,
}
type function = {
@ -73,47 +73,47 @@ module FRType = {
| FRTypeAny => `any`
}
let rec toFrValue = (r: expressionValue): option<frValue> =>
let rec toFrValue = (r: internalExpressionValue): option<frValue> =>
switch r {
| EvNumber(f) => Some(FRValueNumber(f))
| EvString(f) => Some(FRValueString(f))
| EvDistribution(f) => Some(FRValueDistOrNumber(FRValueDist(f)))
| EvLambda(f) => Some(FRValueLambda(f))
| EvArray(elements) =>
| IEvNumber(f) => Some(FRValueNumber(f))
| IEvString(f) => Some(FRValueString(f))
| IEvDistribution(f) => Some(FRValueDistOrNumber(FRValueDist(f)))
| IEvLambda(f) => Some(FRValueLambda(f))
| IEvArray(elements) =>
elements->E.A2.fmap(toFrValue)->E.A.O.openIfAllSome->E.O2.fmap(r => FRValueArray(r))
| EvRecord(record) =>
Js.Dict.entries(record)
| IEvRecord(map) =>
Belt.Map.String.toArray(map)
->E.A2.fmap(((key, item)) => item->toFrValue->E.O2.fmap(o => (key, o)))
->E.A.O.openIfAllSome
->E.O2.fmap(r => FRValueRecord(r))
| _ => None
}
let rec matchWithExpressionValue = (t: t, r: expressionValue): option<frValue> =>
let rec matchWithExpressionValue = (t: t, r: internalExpressionValue): option<frValue> =>
switch (t, r) {
| (FRTypeAny, f) => toFrValue(f)
| (FRTypeString, EvString(f)) => Some(FRValueString(f))
| (FRTypeNumber, EvNumber(f)) => Some(FRValueNumber(f))
| (FRTypeDistOrNumber, EvNumber(f)) => Some(FRValueDistOrNumber(FRValueNumber(f)))
| (FRTypeDistOrNumber, EvDistribution(Symbolic(#Float(f)))) =>
| (FRTypeString, IEvString(f)) => Some(FRValueString(f))
| (FRTypeNumber, IEvNumber(f)) => Some(FRValueNumber(f))
| (FRTypeDistOrNumber, IEvNumber(f)) => Some(FRValueDistOrNumber(FRValueNumber(f)))
| (FRTypeDistOrNumber, IEvDistribution(Symbolic(#Float(f)))) =>
Some(FRValueDistOrNumber(FRValueNumber(f)))
| (FRTypeDistOrNumber, EvDistribution(f)) => Some(FRValueDistOrNumber(FRValueDist(f)))
| (FRTypeNumeric, EvNumber(f)) => Some(FRValueNumber(f))
| (FRTypeNumeric, EvDistribution(Symbolic(#Float(f)))) => Some(FRValueNumber(f))
| (FRTypeLambda, EvLambda(f)) => Some(FRValueLambda(f))
| (FRTypeArray(intendedType), EvArray(elements)) => {
| (FRTypeDistOrNumber, IEvDistribution(f)) => Some(FRValueDistOrNumber(FRValueDist(f)))
| (FRTypeNumeric, IEvNumber(f)) => Some(FRValueNumber(f))
| (FRTypeNumeric, IEvDistribution(Symbolic(#Float(f)))) => Some(FRValueNumber(f))
| (FRTypeLambda, IEvLambda(f)) => Some(FRValueLambda(f))
| (FRTypeArray(intendedType), IEvArray(elements)) => {
let el = elements->E.A2.fmap(matchWithExpressionValue(intendedType))
E.A.O.openIfAllSome(el)->E.O2.fmap(r => FRValueArray(r))
}
| (FRTypeDict(r), EvRecord(record)) =>
record
->Js.Dict.entries
| (FRTypeDict(r), IEvRecord(map)) =>
map
->Belt.Map.String.toArray
->E.A2.fmap(((key, item)) => matchWithExpressionValue(r, item)->E.O2.fmap(o => (key, o)))
->E.A.O.openIfAllSome
->E.O2.fmap(r => FRValueDict(Js.Dict.fromArray(r)))
| (FRTypeRecord(recordParams), EvRecord(record)) => {
| (FRTypeRecord(recordParams), IEvRecord(map)) => {
let getAndMatch = (name, input) =>
E.Dict.get(record, name)->E.O.bind(matchWithExpressionValue(input))
Belt.Map.String.get(map, name)->E.O.bind(matchWithExpressionValue(input))
//All names in the type must be present. If any are missing, the corresponding
//value will be None, and this function would return None.
let namesAndValues: array<option<(Js.Dict.key, frValue)>> =
@ -125,35 +125,38 @@ module FRType = {
| _ => None
}
let rec matchReverse = (e: frValue): expressionValue =>
let rec matchReverse = (e: frValue): internalExpressionValue =>
switch e {
| FRValueNumber(f) => EvNumber(f)
| FRValueDistOrNumber(FRValueNumber(n)) => EvNumber(n)
| FRValueDistOrNumber(FRValueDist(n)) => EvDistribution(n)
| FRValueDist(dist) => EvDistribution(dist)
| FRValueArray(elements) => EvArray(elements->E.A2.fmap(matchReverse))
| FRValueNumber(f) => IEvNumber(f)
| FRValueDistOrNumber(FRValueNumber(n)) => IEvNumber(n)
| FRValueDistOrNumber(FRValueDist(n)) => IEvDistribution(n)
| FRValueDist(dist) => IEvDistribution(dist)
| FRValueArray(elements) => IEvArray(elements->E.A2.fmap(matchReverse))
| FRValueRecord(frValueRecord) => {
let record =
frValueRecord->E.A2.fmap(((name, value)) => (name, matchReverse(value)))->E.Dict.fromArray
EvRecord(record)
let map =
frValueRecord
->E.A2.fmap(((name, value)) => (name, matchReverse(value)))
->Belt.Map.String.fromArray
IEvRecord(map)
}
| FRValueDict(frValueRecord) => {
let record =
let map =
frValueRecord
->Js.Dict.entries
->E.A2.fmap(((name, value)) => (name, matchReverse(value)))
->E.Dict.fromArray
EvRecord(record)
->Belt.Map.String.fromArray
IEvRecord(map)
}
| FRValueLambda(l) => EvLambda(l)
| FRValueString(string) => EvString(string)
| FRValueVariant(string) => EvString(string)
| FRValueLambda(l) => IEvLambda(l)
| FRValueString(string) => IEvString(string)
| FRValueVariant(string) => IEvString(string)
| FRValueAny(f) => matchReverse(f)
}
let matchWithExpressionValueArray = (inputs: array<t>, args: array<expressionValue>): option<
array<frValue>,
> => {
let matchWithExpressionValueArray = (
inputs: array<t>,
args: array<internalExpressionValue>,
): option<array<frValue>> => {
let isSameLength = E.A.length(inputs) == E.A.length(args)
if !isSameLength {
None
@ -204,14 +207,14 @@ module Matcher = {
}
module FnDefinition = {
let matchAssumingSameName = (f: fnDefinition, args: array<expressionValue>) => {
let matchAssumingSameName = (f: fnDefinition, args: array<internalExpressionValue>) => {
switch FRType.matchWithExpressionValueArray(f.inputs, args) {
| Some(_) => MatchSimple.FullMatch
| None => MatchSimple.SameNameDifferentArguments
}
}
let match = (f: fnDefinition, fnName: string, args: array<expressionValue>) => {
let match = (f: fnDefinition, fnName: string, args: array<internalExpressionValue>) => {
if f.name !== fnName {
MatchSimple.DifferentName
} else {
@ -224,7 +227,7 @@ module Matcher = {
type definitionId = int
type match = Match.t<array<definitionId>, definitionId>
let match = (f: function, fnName: string, args: array<expressionValue>): match => {
let match = (f: function, fnName: string, args: array<internalExpressionValue>): match => {
let matchedDefinition = () =>
E.A.getIndexBy(f.definitions, r =>
MatchSimple.isFullMatch(FnDefinition.match(r, fnName, args))
@ -258,7 +261,7 @@ module Matcher = {
}
module Registry = {
let _findExactMatches = (r: registry, fnName: string, args: array<expressionValue>) => {
let _findExactMatches = (r: registry, fnName: string, args: array<internalExpressionValue>) => {
let functionMatchPairs = r->E.A2.fmap(l => (l, Function.match(l, fnName, args)))
let fullMatch = functionMatchPairs->E.A.getBy(((_, match)) => Match.isFullMatch(match))
fullMatch->E.O.bind(((fn, match)) =>
@ -269,7 +272,7 @@ module Matcher = {
)
}
let _findNameMatches = (r: registry, fnName: string, args: array<expressionValue>) => {
let _findNameMatches = (r: registry, fnName: string, args: array<internalExpressionValue>) => {
let functionMatchPairs = r->E.A2.fmap(l => (l, Function.match(l, fnName, args)))
let getNameMatches =
functionMatchPairs
@ -288,7 +291,7 @@ module Matcher = {
E.A.toNoneIfEmpty(matches)
}
let findMatches = (r: registry, fnName: string, args: array<expressionValue>) => {
let findMatches = (r: registry, fnName: string, args: array<internalExpressionValue>) => {
switch _findExactMatches(r, fnName, args) {
| Some(r) => Match.FullMatch(r)
| None =>
@ -316,7 +319,7 @@ module FnDefinition = {
t.name ++ `(${inputs})`
}
let run = (t: t, args: array<expressionValue>, env: DistributionOperation.env) => {
let run = (t: t, args: array<internalExpressionValue>, env: DistributionOperation.env) => {
let argValues = FRType.matchWithExpressionValueArray(t.inputs, args)
switch argValues {
| Some(values) => t.run(values, env)
@ -370,7 +373,7 @@ module Registry = {
let matchAndRun = (
~registry: registry,
~fnName: string,
~args: array<expressionValue>,
~args: array<internalExpressionValue>,
~env: DistributionOperation.env,
) => {
let matchToDef = m => Matcher.Registry.matchToDef(registry, m)

View File

@ -4,11 +4,11 @@ let impossibleError = "Wrong inputs / Logically impossible"
module Wrappers = {
let symbolic = r => DistributionTypes.Symbolic(r)
let evDistribution = r => ReducerInterface_ExpressionValue.EvDistribution(r)
let evNumber = r => ReducerInterface_ExpressionValue.EvNumber(r)
let evArray = r => ReducerInterface_ExpressionValue.EvArray(r)
let evRecord = r => ReducerInterface_ExpressionValue.EvRecord(r)
let evString = r => ReducerInterface_ExpressionValue.EvString(r)
let evDistribution = r => ReducerInterface_InternalExpressionValue.IEvDistribution(r)
let evNumber = r => ReducerInterface_InternalExpressionValue.IEvNumber(r)
let evArray = r => ReducerInterface_InternalExpressionValue.IEvArray(r)
let evRecord = r => ReducerInterface_InternalExpressionValue.IEvRecord(r)
let evString = r => ReducerInterface_InternalExpressionValue.IEvString(r)
let symbolicEvDistribution = r => r->DistributionTypes.Symbolic->evDistribution
}

View File

@ -9,7 +9,7 @@ module Declaration = {
("inputs", FRTypeArray(FRTypeRecord([("min", FRTypeNumber), ("max", FRTypeNumber)]))),
])
let fromExpressionValue = (e: frValue): result<expressionValue, string> => {
let fromExpressionValue = (e: frValue): result<internalExpressionValue, string> => {
switch FunctionRegistry_Helpers.Prepare.ToValueArray.Record.twoArgs([e]) {
| Ok([FRValueLambda(lambda), FRValueArray(inputs)]) => {
open FunctionRegistry_Helpers.Prepare
@ -20,7 +20,7 @@ module Declaration = {
inputs
->E.A2.fmap(getMinMax)
->E.A.R.firstErrorOrOpen
->E.R2.fmap(args => ReducerInterface_ExpressionValue.EvDeclaration(
->E.R2.fmap(args => ReducerInterface_InternalExpressionValue.IEvDeclaration(
Declaration.make(lambda, args),
))
}
@ -43,7 +43,9 @@ let inputsTodist = (inputs: array<FunctionRegistry_Core.frValue>, makeDist) => {
let expressionValue =
xyCoords
->E.R.bind(r => r->XYShape.T.makeFromZipped->E.R2.errMap(XYShape.Error.toString))
->E.R2.fmap(r => ReducerInterface_ExpressionValue.EvDistribution(PointSet(makeDist(r))))
->E.R2.fmap(r => ReducerInterface_InternalExpressionValue.IEvDistribution(
PointSet(makeDist(r)),
))
expressionValue
}
@ -369,7 +371,7 @@ to(5,10)
E.Dict.concat(d1, d2) |> Js.Dict.map((. r) =>
FunctionRegistry_Core.FRType.matchReverse(r)
)
newDict->Wrappers.evRecord->Ok
newDict->Js.Dict.entries->Belt.Map.String.fromArray->Wrappers.evRecord->Ok
}
| _ => Error(impossibleError)
}
@ -390,6 +392,7 @@ to(5,10)
->Prepare.ToTypedArray.dicts
->E.R2.fmap(E.Dict.concatMany)
->E.R2.fmap(Js.Dict.map((. r) => FunctionRegistry_Core.FRType.matchReverse(r)))
->E.R2.fmap(r => r->Js.Dict.entries->Belt.Map.String.fromArray)
->E.R2.fmap(Wrappers.evRecord)
),
],
@ -462,7 +465,7 @@ to(5,10)
}
})
->E.A.R.firstErrorOrOpen
->E.R2.fmap(Js.Dict.fromArray)
->E.R2.fmap(Belt.Map.String.fromArray)
->E.R2.fmap(Wrappers.evRecord)
inputs->getOrError(0)->E.R.bind(Prepare.ToValueArray.Array.arrayOfArrays)
|> E.R2.bind(convertInternalItems)

View File

@ -1,13 +1,14 @@
module ErrorValue = Reducer_ErrorValue
module Expression = Reducer_Expression
module ExpressionValue = ReducerInterface_ExpressionValue
module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
module Lambda = Reducer_Expression_Lambda
type environment = ReducerInterface_ExpressionValue.environment
type environment = ReducerInterface_InternalExpressionValue.environment
type errorValue = Reducer_ErrorValue.errorValue
type expressionValue = ReducerInterface_ExpressionValue.expressionValue
type externalBindings = ReducerInterface_ExpressionValue.externalBindings
type lambdaValue = ExpressionValue.lambdaValue
type expressionValue = ExternalExpressionValue.t
type externalBindings = ReducerInterface_ExternalExpressionValue.externalBindings
type lambdaValue = ExternalExpressionValue.lambdaValue
let evaluate = Expression.evaluate
let evaluateUsingOptions = Expression.evaluateUsingOptions
@ -15,13 +16,20 @@ let evaluatePartialUsingExternalBindings = Expression.evaluatePartialUsingExtern
let parse = Expression.parse
let foreignFunctionInterface = (
lambdaValue: lambdaValue,
lambdaValue: ExternalExpressionValue.lambdaValue,
argArray: array<expressionValue>,
environment: ExpressionValue.environment,
environment: ExternalExpressionValue.environment,
) => {
Lambda.foreignFunctionInterface(lambdaValue, argArray, environment, Expression.reduceExpression)
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)
}
let defaultEnvironment = ExpressionValue.defaultEnvironment
let defaultEnvironment = ExternalExpressionValue.defaultEnvironment
let defaultExternalBindings = ReducerInterface_StdLib.externalStdLib

View File

@ -2,27 +2,29 @@ module ErrorValue = Reducer_ErrorValue
module Expression = Reducer_Expression
@genType
type environment = ReducerInterface_ExpressionValue.environment
type environment = ReducerInterface_ExternalExpressionValue.environment
@genType
type errorValue = Reducer_ErrorValue.errorValue
@genType
type expressionValue = ReducerInterface_ExpressionValue.expressionValue
type expressionValue = ReducerInterface_ExternalExpressionValue.t
@genType
type externalBindings = ReducerInterface_ExpressionValue.externalBindings
type externalBindings = ReducerInterface_ExternalExpressionValue.externalBindings
@genType
type lambdaValue = ReducerInterface_ExpressionValue.lambdaValue
type lambdaValue = ReducerInterface_ExternalExpressionValue.lambdaValue
@genType
let evaluateUsingOptions: (
~environment: option<QuriSquiggleLang.ReducerInterface_ExpressionValue.environment>,
~externalBindings: option<QuriSquiggleLang.ReducerInterface_ExpressionValue.externalBindings>,
~environment: option<QuriSquiggleLang.ReducerInterface_ExternalExpressionValue.environment>,
~externalBindings: option<
QuriSquiggleLang.ReducerInterface_ExternalExpressionValue.externalBindings,
>,
string,
) => result<expressionValue, errorValue>
@genType
let evaluatePartialUsingExternalBindings: (
string,
QuriSquiggleLang.ReducerInterface_ExpressionValue.externalBindings,
QuriSquiggleLang.ReducerInterface_ExpressionValue.environment,
QuriSquiggleLang.ReducerInterface_ExternalExpressionValue.externalBindings,
QuriSquiggleLang.ReducerInterface_ExternalExpressionValue.environment,
) => result<externalBindings, errorValue>
@genType
let evaluate: string => result<expressionValue, errorValue>
@ -31,9 +33,9 @@ let parse: string => result<Expression.expression, errorValue>
@genType
let foreignFunctionInterface: (
QuriSquiggleLang.ReducerInterface_ExpressionValue.lambdaValue,
array<QuriSquiggleLang.ReducerInterface_ExpressionValue.expressionValue>,
QuriSquiggleLang.ReducerInterface_ExpressionValue.environment,
QuriSquiggleLang.ReducerInterface_ExternalExpressionValue.lambdaValue,
array<QuriSquiggleLang.ReducerInterface_ExternalExpressionValue.t>,
QuriSquiggleLang.ReducerInterface_ExternalExpressionValue.environment,
) => result<expressionValue, errorValue>
@genType

View File

@ -1,12 +0,0 @@
include Reducer_Category_Module // Bindings inherit from Module
open ReducerInterface_ExpressionValue
let emptyBindings = emptyModule
let toExpressionValue = (container: t): expressionValue => EvRecord(toRecord(container))
let fromExpressionValue = (aValue: expressionValue): t =>
switch aValue {
| EvRecord(r) => fromRecord(r)
| _ => emptyBindings
}

View File

@ -1,33 +1,112 @@
module ExpressionT = Reducer_Expression_T
open ReducerInterface_ExpressionValue
open ReducerInterface_InternalExpressionValue
let expressionValueToString = toString
type t = ExpressionT.bindings
type t = ReducerInterface_InternalExpressionValue.nameSpace
let typeAliasesKey = "_typeAliases_"
let typeReferencesKey = "_typeReferences_"
let emptyModule: t = Belt.Map.String.empty
let getType = (nameSpace: t, id: string) => {
let NameSpace(container) = nameSpace
Belt.Map.String.get(container, typeAliasesKey)->Belt.Option.flatMap(aliases =>
switch aliases {
| IEvRecord(r) => Belt.Map.String.get(r, id)
| _ => None
}
)
}
let cloneRecord = (r: record): record => r->Js.Dict.entries->Js.Dict.fromArray
let fromRecord = (r: record): t => Js.Dict.entries(r)->Belt.Map.String.fromArray
let toRecord = (container: t): record => Belt.Map.String.toArray(container)->Js.Dict.fromArray
let getTypeOf = (nameSpace: t, id: string) => {
let NameSpace(container) = nameSpace
Belt.Map.String.get(container, typeReferencesKey)->Belt.Option.flatMap(defs =>
switch defs {
| IEvRecord(r) => Belt.Map.String.get(r, id)
| _ => None
}
)
}
let toExpressionValue = (container: t): expressionValue => EvModule(toRecord(container))
let fromExpressionValue = (aValue: expressionValue): t =>
let getWithDefault = (nameSpace: t, id: string, default) => {
let NameSpace(container) = nameSpace
Belt.Map.String.getWithDefault(container, id, default)
}
let get = (nameSpace: t, id: string) => {
let NameSpace(container) = nameSpace
Belt.Map.String.get(container, id)
}
let emptyMap: map = Belt.Map.String.empty
let setTypeAlias = (nameSpace: t, id: string, value): t => {
let NameSpace(container) = nameSpace
let rValue = Belt.Map.String.getWithDefault(container, typeAliasesKey, IEvRecord(emptyMap))
let r = switch rValue {
| IEvRecord(r) => r
| _ => emptyMap
}
let r2 = Belt.Map.String.set(r, id, value)->IEvRecord
Belt.Map.String.set(container, typeAliasesKey, r2)->NameSpace
}
let setTypeOf = (nameSpace: t, id: string, value): t => {
let NameSpace(container) = nameSpace
let rValue = Belt.Map.String.getWithDefault(container, typeReferencesKey, IEvRecord(emptyMap))
let r = switch rValue {
| IEvRecord(r) => r
| _ => emptyMap
}
let r2 = Belt.Map.String.set(r, id, value)->IEvRecord
Belt.Map.String.set(container, typeReferencesKey, r2)->NameSpace
}
let set = (nameSpace: t, id: string, value): t => {
let NameSpace(container) = nameSpace
Belt.Map.String.set(container, id, value)->NameSpace
}
let emptyModule: t = NameSpace(Belt.Map.String.empty)
let fromTypeScriptBindings = ReducerInterface_InternalExpressionValue.nameSpaceFromTypeScriptBindings
let toTypeScriptBindings = ReducerInterface_InternalExpressionValue.nameSpaceToTypeScriptBindings
let toExpressionValue = (nameSpace: t): internalExpressionValue => IEvModule(nameSpace)
let fromExpressionValue = (aValue: internalExpressionValue): t =>
switch aValue {
| EvModule(r) => fromRecord(r)
| IEvModule(nameSpace) => nameSpace
| _ => emptyModule
}
let toString = (container: t): string => container->toRecord->EvRecord->expressionValueToString
let fromArray = a => Belt.Map.String.fromArray(a)->NameSpace
let merge = (nameSpace: t, other: t): t => {
let NameSpace(container) = nameSpace
let NameSpace(otherContainer) = other
otherContainer
->Belt.Map.String.reduce(container, (container, key, value) =>
Belt.Map.String.set(container, key, value)
)
->NameSpace
}
let removeOther = (nameSpace: t, other: t): t => {
let NameSpace(container) = nameSpace
let NameSpace(otherContainer) = other
let keys = Belt.Map.String.keysToArray(otherContainer)
Belt.Map.String.keep(container, (key, _value) => {
let removeThis = Js.Array2.includes(keys, key)
!removeThis
})->NameSpace
}
// -- Module definition
let define = (container: t, identifier: string, ev: expressionValue): t =>
Belt.Map.String.set(container, identifier, ev) // TODO build lambda for polymorphic functions here
let define = (nameSpace: t, identifier: string, ev: internalExpressionValue): t => {
let NameSpace(container) = nameSpace
Belt.Map.String.set(container, identifier, ev)->NameSpace // TODO build lambda for polymorphic functions here
}
let defineNumber = (nameSpace: t, identifier: string, value: float): t =>
nameSpace->define(identifier, IEvNumber(value))
let defineNumber = (container: t, identifier: string, value: float): t =>
container->define(identifier, EvNumber(value))
let defineModule = (container: t, identifier: string, value: t): t =>
container->define(identifier, toExpressionValue(value))
let defineModule = (nameSpace: t, identifier: string, value: t): t =>
nameSpace->define(identifier, toExpressionValue(value))

View File

@ -0,0 +1,16 @@
module ExpressionValue = ReducerInterface_InternalExpressionValue
module ExpressionT = Reducer_Expression_T
open ExpressionValue
let isOfResolvedType = (aType, aValue) => {
let caseTypeIdentifier = (aTypeIdentifier0, aValue) => {
let valueType = aValue->valueToValueType->valueTypeToString->Js.String2.toLowerCase
let aTypeIdentifier = aTypeIdentifier0->Js.String2.toLowerCase
aTypeIdentifier === valueType
}
switch aType {
| IEvTypeIdentifier(aTypeIdentifier) => caseTypeIdentifier(aTypeIdentifier, aValue)
| _ => false
}
}

View File

@ -1,10 +1,11 @@
module Bindings = Reducer_Expression_Bindings
module BindingsReplacer = Reducer_Expression_BindingsReplacer
module ExpressionT = Reducer_Expression_T
module ExternalLibrary = ReducerInterface.ExternalLibrary
module Lambda = Reducer_Expression_Lambda
module MathJs = Reducer_MathJs
module Module = Reducer_Category_Module
module Result = Belt.Result
open ReducerInterface.ExpressionValue
open ReducerInterface_InternalExpressionValue
open Reducer_ErrorValue
/*
@ -31,23 +32,29 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce
let constructRecord = arrayOfPairs => {
Belt.Array.map(arrayOfPairs, pairValue =>
switch pairValue {
| EvArray([EvString(key), valueValue]) => (key, valueValue)
| _ => ("wrong key type", pairValue->toStringWithType->EvString)
| IEvArray([IEvString(key), valueValue]) => (key, valueValue)
| _ => ("wrong key type", pairValue->toStringWithType->IEvString)
}
)
->Js.Dict.fromArray
->EvRecord
->Belt.Map.String.fromArray
->IEvRecord
->Ok
}
let arrayAtIndex = (aValueArray: array<expressionValue>, fIndex: float) =>
let arrayAtIndex = (aValueArray: array<internalExpressionValue>, fIndex: float) =>
switch Belt.Array.get(aValueArray, Belt.Int.fromFloat(fIndex)) {
| Some(value) => value->Ok
| None => REArrayIndexNotFound("Array index not found", Belt.Int.fromFloat(fIndex))->Error
}
let recordAtIndex = (dict: Js.Dict.t<expressionValue>, sIndex) =>
switch Js.Dict.get(dict, sIndex) {
let moduleAtIndex = (nameSpace: nameSpace, sIndex) =>
switch Module.get(nameSpace, sIndex) {
| Some(value) => value->Ok
| None => RERecordPropertyNotFound("Module property not found", sIndex)->Error
}
let recordAtIndex = (dict: Belt.Map.String.t<internalExpressionValue>, sIndex) =>
switch Belt.Map.String.get(dict, sIndex) {
| Some(value) => value->Ok
| None => RERecordPropertyNotFound("Record property not found", sIndex)->Error
}
@ -55,70 +62,37 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce
let doAddArray = (originalA, b) => {
let a = originalA->Js.Array2.copy
let _ = Js.Array2.pushMany(a, b)
a->EvArray->Ok
a->IEvArray->Ok
}
let doAddString = (a, b) => {
let answer = Js.String2.concat(a, b)
answer->EvString->Ok
answer->IEvString->Ok
}
let inspect = (value: expressionValue) => {
let inspect = (value: internalExpressionValue) => {
Js.log(value->toString)
value->Ok
}
let inspectLabel = (value: expressionValue, label: string) => {
let inspectLabel = (value: internalExpressionValue, label: string) => {
Js.log(`${label}: ${value->toString}`)
value->Ok
}
let doSetBindings = (
externalBindings: externalBindings,
symbol: string,
value: expressionValue,
) => {
Bindings.fromExternalBindings(externalBindings)
->Belt.Map.String.set(symbol, value)
->Bindings.toExternalBindings
->EvRecord
->Ok
}
let doSetBindingsInNamespace = (
externalBindings: externalBindings,
symbol: string,
value: expressionValue,
namespace: string,
) => {
let bindings = Bindings.fromExternalBindings(externalBindings)
let evAliases = bindings->Belt.Map.String.getWithDefault(namespace, EvRecord(Js.Dict.empty()))
let newEvAliases = switch evAliases {
| EvRecord(dict) => {
Js.Dict.set(dict, symbol, value)
dict->EvRecord
}
| _ => Js.Dict.empty()->EvRecord
}
bindings
->Belt.Map.String.set(namespace, newEvAliases)
->Bindings.toExternalBindings
->EvRecord
->Ok
let doSetBindings = (bindings: nameSpace, symbol: string, value: internalExpressionValue) => {
Module.set(bindings, symbol, value)->IEvModule->Ok
}
let doSetTypeAliasBindings = (
externalBindings: externalBindings,
bindings: nameSpace,
symbol: string,
value: expressionValue,
) => doSetBindingsInNamespace(externalBindings, symbol, value, Bindings.typeAliasesKey)
value: internalExpressionValue,
) => Module.setTypeAlias(bindings, symbol, value)->IEvModule->Ok
let doSetTypeOfBindings = (
externalBindings: externalBindings,
symbol: string,
value: expressionValue,
) => doSetBindingsInNamespace(externalBindings, symbol, value, Bindings.typeReferencesKey)
let doSetTypeOfBindings = (bindings: nameSpace, symbol: string, value: internalExpressionValue) =>
Module.setTypeOf(bindings, symbol, value)->IEvModule->Ok
let doExportBindings = (externalBindings: externalBindings) => EvRecord(externalBindings)->Ok
let doExportBindings = (bindings: nameSpace) => bindings->Module.toExpressionValue->Ok
let doKeepArray = (aValueArray, aLambdaValue) => {
let rMappedList = aValueArray->Belt.Array.reduceReverse(Ok(list{}), (rAcc, elem) =>
@ -126,13 +100,13 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce
let rNewElem = Lambda.doLambdaCall(aLambdaValue, list{elem}, environment, reducer)
rNewElem->Result.map(newElem =>
switch newElem {
| EvBool(true) => list{elem, ...acc}
| IEvBool(true) => list{elem, ...acc}
| _ => acc
}
)
})
)
rMappedList->Result.map(mappedList => mappedList->Belt.List.toArray->EvArray)
rMappedList->Result.map(mappedList => mappedList->Belt.List.toArray->IEvArray)
}
let doMapArray = (aValueArray, aLambdaValue) => {
@ -142,35 +116,36 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce
rNewElem->Result.map(newElem => list{newElem, ...acc})
})
)
rMappedList->Result.map(mappedList => mappedList->Belt.List.toArray->EvArray)
rMappedList->Result.map(mappedList => mappedList->Belt.List.toArray->IEvArray)
}
module SampleMap = {
type t = SampleSetDist.t
let doLambdaCall = (aLambdaValue, list) =>
switch Lambda.doLambdaCall(aLambdaValue, list, environment, reducer) {
| Ok(EvNumber(f)) => Ok(f)
| Ok(IEvNumber(f)) => Ok(f)
| _ => Error(Operation.SampleMapNeedsNtoNFunction)
}
let toType = r =>
switch r {
| Ok(r) => Ok(EvDistribution(SampleSet(r)))
| Ok(r) => Ok(IEvDistribution(SampleSet(r)))
| Error(r) => Error(REDistributionError(SampleSetError(r)))
}
let map1 = (sampleSetDist: t, aLambdaValue) => {
let fn = r => doLambdaCall(aLambdaValue, list{EvNumber(r)})
let fn = r => doLambdaCall(aLambdaValue, list{IEvNumber(r)})
toType(SampleSetDist.samplesMap(~fn, sampleSetDist))
}
let map2 = (t1: t, t2: t, aLambdaValue) => {
let fn = (a, b) => doLambdaCall(aLambdaValue, list{EvNumber(a), EvNumber(b)})
let fn = (a, b) => doLambdaCall(aLambdaValue, list{IEvNumber(a), IEvNumber(b)})
SampleSetDist.map2(~fn, ~t1, ~t2)->toType
}
let map3 = (t1: t, t2: t, t3: t, aLambdaValue) => {
let fn = (a, b, c) => doLambdaCall(aLambdaValue, list{EvNumber(a), EvNumber(b), EvNumber(c)})
let fn = (a, b, c) =>
doLambdaCall(aLambdaValue, list{IEvNumber(a), IEvNumber(b), IEvNumber(c)})
SampleSetDist.map3(~fn, ~t1, ~t2, ~t3)->toType
}
}
@ -192,132 +167,128 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce
}
let typeModifier_memberOf = (aType, anArray) => {
let newRecord = Js.Dict.fromArray([
("typeTag", EvString("typeIdentifier")),
let newRecord = Belt.Map.String.fromArray([
("typeTag", IEvString("typeIdentifier")),
("typeIdentifier", aType),
])
newRecord->Js.Dict.set("memberOf", anArray)
newRecord->EvRecord->Ok
newRecord->Belt.Map.String.set("memberOf", anArray)->IEvRecord->Ok
}
let typeModifier_memberOf_update = (aRecord, anArray) => {
let newRecord = aRecord->Js.Dict.entries->Js.Dict.fromArray
newRecord->Js.Dict.set("memberOf", anArray)
newRecord->EvRecord->Ok
aRecord->Belt.Map.String.set("memberOf", anArray)->IEvRecord->Ok
}
let typeModifier_min = (aType, value) => {
let newRecord = Js.Dict.fromArray([
("typeTag", EvString("typeIdentifier")),
let newRecord = Belt.Map.String.fromArray([
("typeTag", IEvString("typeIdentifier")),
("typeIdentifier", aType),
])
newRecord->Js.Dict.set("min", value)
newRecord->EvRecord->Ok
newRecord->Belt.Map.String.set("min", value)->IEvRecord->Ok
}
let typeModifier_min_update = (aRecord, value) => {
let newRecord = aRecord->Js.Dict.entries->Js.Dict.fromArray
newRecord->Js.Dict.set("min", value)
newRecord->EvRecord->Ok
aRecord->Belt.Map.String.set("min", value)->IEvRecord->Ok
}
let typeModifier_max = (aType, value) => {
let newRecord = Js.Dict.fromArray([
("typeTag", EvString("typeIdentifier")),
let newRecord = Belt.Map.String.fromArray([
("typeTag", IEvString("typeIdentifier")),
("typeIdentifier", aType),
])
newRecord->Js.Dict.set("max", value)
newRecord->EvRecord->Ok
}
let typeModifier_max_update = (aRecord, value) => {
let newRecord = aRecord->Js.Dict.entries->Js.Dict.fromArray
newRecord->Js.Dict.set("max", value)
newRecord->EvRecord->Ok
newRecord->Belt.Map.String.set("max", value)->IEvRecord->Ok
}
let typeModifier_max_update = (aRecord, value) =>
aRecord->Belt.Map.String.set("max", value)->IEvRecord->Ok
let typeModifier_opaque_update = aRecord => {
let newRecord = aRecord->Js.Dict.entries->Js.Dict.fromArray
newRecord->Js.Dict.set("opaque", EvBool(true))
newRecord->EvRecord->Ok
}
let typeModifier_opaque_update = aRecord =>
aRecord->Belt.Map.String.set("opaque", IEvBool(true))->IEvRecord->Ok
let typeOr = evArray => {
let newRecord = Js.Dict.fromArray([("typeTag", EvString("typeOr")), ("typeOr", evArray)])
newRecord->EvRecord->Ok
let newRecord = Belt.Map.String.fromArray([
("typeTag", IEvString("typeOr")),
("typeOr", evArray),
])
newRecord->IEvRecord->Ok
}
let typeFunction = anArray => {
let output = Belt.Array.getUnsafe(anArray, Js.Array2.length(anArray) - 1)
let inputs = Js.Array2.slice(anArray, ~start=0, ~end_=-1)
let newRecord = Js.Dict.fromArray([
("typeTag", EvString("typeFunction")),
("inputs", EvArray(inputs)),
let newRecord = Belt.Map.String.fromArray([
("typeTag", IEvString("typeFunction")),
("inputs", IEvArray(inputs)),
("output", output),
])
newRecord->EvRecord->Ok
newRecord->IEvRecord->Ok
}
switch call {
| ("$_atIndex_$", [EvArray(aValueArray), EvNumber(fIndex)]) => arrayAtIndex(aValueArray, fIndex)
| ("$_atIndex_$", [EvModule(dict), EvString(sIndex)]) => recordAtIndex(dict, sIndex)
| ("$_atIndex_$", [EvRecord(dict), EvString(sIndex)]) => recordAtIndex(dict, sIndex)
| ("$_constructArray_$", [EvArray(aValueArray)]) => EvArray(aValueArray)->Ok
| ("$_constructRecord_$", [EvArray(arrayOfPairs)]) => constructRecord(arrayOfPairs)
| ("$_exportBindings_$", [EvRecord(externalBindings)]) => doExportBindings(externalBindings)
| ("$_setBindings_$", [EvRecord(externalBindings), EvSymbol(symbol), value]) =>
doSetBindings(externalBindings, symbol, value)
| ("$_setTypeAliasBindings_$", [EvRecord(externalBindings), EvTypeIdentifier(symbol), value]) =>
doSetTypeAliasBindings(externalBindings, symbol, value)
| ("$_setTypeOfBindings_$", [EvRecord(externalBindings), EvSymbol(symbol), value]) =>
doSetTypeOfBindings(externalBindings, symbol, value)
| ("$_typeModifier_memberOf_$", [EvTypeIdentifier(typeIdentifier), EvArray(arr)]) =>
typeModifier_memberOf(EvTypeIdentifier(typeIdentifier), EvArray(arr))
| ("$_typeModifier_memberOf_$", [EvRecord(typeRecord), EvArray(arr)]) =>
typeModifier_memberOf_update(typeRecord, EvArray(arr))
| ("$_typeModifier_min_$", [EvTypeIdentifier(typeIdentifier), value]) =>
typeModifier_min(EvTypeIdentifier(typeIdentifier), value)
| ("$_typeModifier_min_$", [EvRecord(typeRecord), value]) =>
| ("$_atIndex_$", [IEvArray(aValueArray), IEvNumber(fIndex)]) => arrayAtIndex(aValueArray, fIndex)
| ("$_atIndex_$", [IEvModule(dict), IEvString(sIndex)]) => moduleAtIndex(dict, sIndex)
| ("$_atIndex_$", [IEvRecord(dict), IEvString(sIndex)]) => recordAtIndex(dict, sIndex)
| ("$_constructArray_$", [IEvArray(aValueArray)]) => IEvArray(aValueArray)->Ok
| ("$_constructRecord_$", [IEvArray(arrayOfPairs)]) => constructRecord(arrayOfPairs)
| ("$_exportBindings_$", [IEvModule(nameSpace)]) => doExportBindings(nameSpace)
| ("$_setBindings_$", [IEvModule(nameSpace), IEvSymbol(symbol), value]) =>
doSetBindings(nameSpace, symbol, value)
| ("$_setTypeAliasBindings_$", [IEvModule(nameSpace), IEvTypeIdentifier(symbol), value]) =>
doSetTypeAliasBindings(nameSpace, symbol, value)
| ("$_setTypeOfBindings_$", [IEvModule(nameSpace), IEvSymbol(symbol), value]) =>
doSetTypeOfBindings(nameSpace, symbol, value)
| ("$_typeModifier_memberOf_$", [IEvTypeIdentifier(typeIdentifier), IEvArray(arr)]) =>
typeModifier_memberOf(IEvTypeIdentifier(typeIdentifier), IEvArray(arr))
| ("$_typeModifier_memberOf_$", [IEvRecord(typeRecord), IEvArray(arr)]) =>
typeModifier_memberOf_update(typeRecord, IEvArray(arr))
| ("$_typeModifier_min_$", [IEvTypeIdentifier(typeIdentifier), value]) =>
typeModifier_min(IEvTypeIdentifier(typeIdentifier), value)
| ("$_typeModifier_min_$", [IEvRecord(typeRecord), value]) =>
typeModifier_min_update(typeRecord, value)
| ("$_typeModifier_max_$", [EvTypeIdentifier(typeIdentifier), value]) =>
typeModifier_max(EvTypeIdentifier(typeIdentifier), value)
| ("$_typeModifier_max_$", [EvRecord(typeRecord), value]) =>
| ("$_typeModifier_max_$", [IEvTypeIdentifier(typeIdentifier), value]) =>
typeModifier_max(IEvTypeIdentifier(typeIdentifier), value)
| ("$_typeModifier_max_$", [IEvRecord(typeRecord), value]) =>
typeModifier_max_update(typeRecord, value)
| ("$_typeModifier_opaque_$", [EvRecord(typeRecord)]) => typeModifier_opaque_update(typeRecord)
| ("$_typeOr_$", [EvArray(arr)]) => typeOr(EvArray(arr))
| ("$_typeFunction_$", [EvArray(arr)]) => typeFunction(arr)
| ("concat", [EvArray(aValueArray), EvArray(bValueArray)]) => doAddArray(aValueArray, bValueArray)
| ("concat", [EvString(aValueString), EvString(bValueString)]) =>
| ("$_typeModifier_opaque_$", [IEvRecord(typeRecord)]) => typeModifier_opaque_update(typeRecord)
| ("$_typeOr_$", [IEvArray(arr)]) => typeOr(IEvArray(arr))
| ("$_typeFunction_$", [IEvArray(arr)]) => typeFunction(arr)
| ("concat", [IEvArray(aValueArray), IEvArray(bValueArray)]) =>
doAddArray(aValueArray, bValueArray)
| ("concat", [IEvString(aValueString), IEvString(bValueString)]) =>
doAddString(aValueString, bValueString)
| ("inspect", [value, EvString(label)]) => inspectLabel(value, label)
| ("inspect", [value, IEvString(label)]) => inspectLabel(value, label)
| ("inspect", [value]) => inspect(value)
| ("filter", [EvArray(aValueArray), EvLambda(aLambdaValue)]) =>
| ("filter", [IEvArray(aValueArray), IEvLambda(aLambdaValue)]) =>
doKeepArray(aValueArray, aLambdaValue)
| ("map", [EvArray(aValueArray), EvLambda(aLambdaValue)]) => doMapArray(aValueArray, aLambdaValue)
| ("mapSamples", [EvDistribution(SampleSet(dist)), EvLambda(aLambdaValue)]) =>
| ("map", [IEvArray(aValueArray), IEvLambda(aLambdaValue)]) =>
doMapArray(aValueArray, aLambdaValue)
| ("mapSamples", [IEvDistribution(SampleSet(dist)), IEvLambda(aLambdaValue)]) =>
SampleMap.map1(dist, aLambdaValue)
| (
"mapSamples2",
[EvDistribution(SampleSet(dist1)), EvDistribution(SampleSet(dist2)), EvLambda(aLambdaValue)],
[
IEvDistribution(SampleSet(dist1)),
IEvDistribution(SampleSet(dist2)),
IEvLambda(aLambdaValue),
],
) =>
SampleMap.map2(dist1, dist2, aLambdaValue)
| (
"mapSamples3",
[
EvDistribution(SampleSet(dist1)),
EvDistribution(SampleSet(dist2)),
EvDistribution(SampleSet(dist3)),
EvLambda(aLambdaValue),
IEvDistribution(SampleSet(dist1)),
IEvDistribution(SampleSet(dist2)),
IEvDistribution(SampleSet(dist3)),
IEvLambda(aLambdaValue),
],
) =>
SampleMap.map3(dist1, dist2, dist3, aLambdaValue)
| ("reduce", [EvArray(aValueArray), initialValue, EvLambda(aLambdaValue)]) =>
| ("reduce", [IEvArray(aValueArray), initialValue, IEvLambda(aLambdaValue)]) =>
doReduceArray(aValueArray, initialValue, aLambdaValue)
| ("reduceReverse", [EvArray(aValueArray), initialValue, EvLambda(aLambdaValue)]) =>
| ("reduceReverse", [IEvArray(aValueArray), initialValue, IEvLambda(aLambdaValue)]) =>
doReduceReverseArray(aValueArray, initialValue, aLambdaValue)
| ("reverse", [EvArray(aValueArray)]) => aValueArray->Belt.Array.reverse->EvArray->Ok
| (_, [EvBool(_)])
| (_, [EvNumber(_)])
| (_, [EvString(_)])
| (_, [EvBool(_), EvBool(_)])
| (_, [EvNumber(_), EvNumber(_)])
| (_, [EvString(_), EvString(_)]) =>
| ("reverse", [IEvArray(aValueArray)]) => aValueArray->Belt.Array.reverse->IEvArray->Ok
| (_, [IEvBool(_)])
| (_, [IEvNumber(_)])
| (_, [IEvString(_)])
| (_, [IEvBool(_), IEvBool(_)])
| (_, [IEvNumber(_), IEvNumber(_)])
| (_, [IEvString(_), IEvString(_)]) =>
callMathJs(call)
| call =>
Error(REFunctionNotFound(call->functionCallToCallSignature->functionCallSignatureToString)) // Report full type signature as error
@ -328,7 +299,7 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce
Reducer uses Result monad while reducing expressions
*/
let dispatch = (call: functionCall, environment, reducer: ExpressionT.reducerFn): result<
expressionValue,
internalExpressionValue,
errorValue,
> =>
try {

View File

@ -3,19 +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_Expression_Bindings
module BindingsReplacer = Reducer_Expression_BindingsReplacer
module ErrorValue = Reducer_ErrorValue
module ExpressionBuilder = Reducer_Expression_ExpressionBuilder
module ExpressionT = Reducer_Expression_T
module ExpressionValue = ReducerInterface.ExpressionValue
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
module ExpressionWithContext = Reducer_ExpressionWithContext
module Module = Reducer_Category_Module
module Result = Belt.Result
open Reducer_Expression_ExpressionBuilder
type environment = ExpressionValue.environment
type environment = InternalExpressionValue.environment
type errorValue = ErrorValue.errorValue
type expression = ExpressionT.expression
type expressionValue = ExpressionValue.expressionValue
type expressionWithContext = ExpressionWithContext.expressionWithContext
let dispatchMacroCall = (
@ -27,13 +27,13 @@ let dispatchMacroCall = (
let useExpressionToSetBindings = (bindingExpr: expression, environment, statement, newCode) => {
let rExternalBindingsValue = reduceExpression(bindingExpr, bindings, environment)
rExternalBindingsValue->Result.flatMap(externalBindingsValue => {
let newBindings = Bindings.fromValue(externalBindingsValue)
rExternalBindingsValue->Result.flatMap(nameSpaceValue => {
let newBindings = Module.fromExpressionValue(nameSpaceValue)
let rNewStatement = Bindings.replaceSymbols(newBindings, statement)
let rNewStatement = BindingsReplacer.replaceSymbols(newBindings, statement)
rNewStatement->Result.map(boundStatement =>
ExpressionWithContext.withContext(
newCode(newBindings->Bindings.toExternalBindings->eRecord, boundStatement),
newCode(newBindings->eModule, boundStatement),
newBindings,
)
)
@ -51,7 +51,7 @@ let dispatchMacroCall = (
let doBindStatement = (bindingExpr: expression, statement: expression, environment) => {
let defaultStatement = ErrorValue.REAssignmentExpected->Error
switch statement {
| ExpressionT.EList(list{ExpressionT.EValue(EvCall(callName)), symbolExpr, statement}) => {
| ExpressionT.EList(list{ExpressionT.EValue(IEvCall(callName)), symbolExpr, statement}) => {
let setBindingsFn = correspondingSetBindingsFn(callName)
if setBindingsFn !== "" {
useExpressionToSetBindings(bindingExpr, environment, statement, (
@ -77,7 +77,7 @@ let dispatchMacroCall = (
) => boundStatement)
switch statement {
| ExpressionT.EList(list{ExpressionT.EValue(EvCall(callName)), symbolExpr, statement}) => {
| ExpressionT.EList(list{ExpressionT.EValue(IEvCall(callName)), symbolExpr, statement}) => {
let setBindingsFn = correspondingSetBindingsFn(callName)
if setBindingsFn !== "" {
useExpressionToSetBindings(bindingExpr, environment, statement, (
@ -123,10 +123,7 @@ let dispatchMacroCall = (
bindings: ExpressionT.bindings,
parameters: array<string>,
lambdaDefinition: ExpressionT.expression,
) =>
ExpressionWithContext.noContext(
eLambda(parameters, bindings->Bindings.toExternalBindings, lambdaDefinition),
)->Ok
) => ExpressionWithContext.noContext(eLambda(parameters, bindings, lambdaDefinition))->Ok
let doTernary = (
condition: expression,
@ -139,11 +136,11 @@ let dispatchMacroCall = (
let rCondition = reduceExpression(blockCondition, bindings, environment)
rCondition->Result.flatMap(conditionValue =>
switch conditionValue {
| ExpressionValue.EvBool(false) => {
| InternalExpressionValue.IEvBool(false) => {
let ifFalseBlock = eBlock(list{ifFalse})
ExpressionWithContext.withContext(ifFalseBlock, bindings)->Ok
}
| ExpressionValue.EvBool(true) => {
| InternalExpressionValue.IEvBool(true) => {
let ifTrueBlock = eBlock(list{ifTrue})
ExpressionWithContext.withContext(ifTrueBlock, bindings)->Ok
}
@ -158,32 +155,32 @@ let dispatchMacroCall = (
> =>
switch aList {
| list{
ExpressionT.EValue(EvCall("$$_bindStatement_$$")),
ExpressionT.EValue(IEvCall("$$_bindStatement_$$")),
bindingExpr: ExpressionT.expression,
statement,
} =>
doBindStatement(bindingExpr, statement, environment)
| list{ExpressionT.EValue(EvCall("$$_bindStatement_$$")), statement} =>
| list{ExpressionT.EValue(IEvCall("$$_bindStatement_$$")), statement} =>
// bindings of the context are used when there is no binding expression
doBindStatement(eRecord(Bindings.toExternalBindings(bindings)), statement, environment)
doBindStatement(eModule(bindings), statement, environment)
| list{
ExpressionT.EValue(EvCall("$$_bindExpression_$$")),
ExpressionT.EValue(IEvCall("$$_bindExpression_$$")),
bindingExpr: ExpressionT.expression,
expression,
} =>
doBindExpression(bindingExpr, expression, environment)
| list{ExpressionT.EValue(EvCall("$$_bindExpression_$$")), expression} =>
| list{ExpressionT.EValue(IEvCall("$$_bindExpression_$$")), expression} =>
// bindings of the context are used when there is no binding expression
doBindExpression(eRecord(Bindings.toExternalBindings(bindings)), expression, environment)
| list{ExpressionT.EValue(EvCall("$$_block_$$")), ...exprs} =>
doBindExpression(eModule(bindings), expression, environment)
| list{ExpressionT.EValue(IEvCall("$$_block_$$")), ...exprs} =>
doBlock(exprs, bindings, environment)
| list{
ExpressionT.EValue(EvCall("$$_lambda_$$")),
ExpressionT.EValue(EvArrayString(parameters)),
ExpressionT.EValue(IEvCall("$$_lambda_$$")),
ExpressionT.EValue(IEvArrayString(parameters)),
lambdaDefinition,
} =>
doLambdaDefinition(bindings, parameters, lambdaDefinition)
| list{ExpressionT.EValue(EvCall("$$_ternary_$$")), condition, ifTrue, ifFalse} =>
| list{ExpressionT.EValue(IEvCall("$$_ternary_$$")), condition, ifTrue, ifFalse} =>
doTernary(condition, ifTrue, ifFalse, bindings, environment)
| _ => ExpressionWithContext.noContext(ExpressionT.EList(aList))->Ok
}

View File

@ -1,3 +1,6 @@
@gentype.import("peggy") @genType.as("LocationRange")
type location
@genType
type errorValue =
| REArityError(option<string>, int, int) //TODO: Binding a lambda to a variable should record the variable name in lambda for error reporting
@ -14,7 +17,7 @@ type errorValue =
| REOperationError(Operation.operationError)
| RERecordPropertyNotFound(string, string)
| RESymbolNotFound(string)
| RESyntaxError(string)
| RESyntaxError(string, option<location>)
| RETodo(string) // To do
| REUnitNotFound(string)
@ -50,7 +53,7 @@ let errorToString = err =>
| RENotAFunction(valueString) => `${valueString} is not a function`
| RERecordPropertyNotFound(msg, index) => `${msg}: ${index}`
| RESymbolNotFound(symbolName) => `${symbolName} is not defined`
| RESyntaxError(desc) => `Syntax Error: ${desc}`
| RESyntaxError(desc, _) => `Syntax Error: ${desc}`
| RETodo(msg) => `TODO: ${msg}`
| REExpectedType(typeName) => `Expected type: ${typeName}`
| REUnitNotFound(unitName) => `Unit not found: ${unitName}`

View File

@ -1,20 +1,20 @@
module Bindings = Reducer_Expression_Bindings
module BindingsReplacer = Reducer_Expression_BindingsReplacer
module BuiltIn = Reducer_Dispatch_BuiltIn
module ExpressionBuilder = Reducer_Expression_ExpressionBuilder
module ExpressionValue = ReducerInterface.ExpressionValue
module Extra = Reducer_Extra
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
module Lambda = Reducer_Expression_Lambda
module Macro = Reducer_Expression_Macro
module MathJs = Reducer_MathJs
module Module = Reducer_Category_Module
module Result = Belt.Result
module T = Reducer_Expression_T
type environment = ReducerInterface_ExpressionValue.environment
type environment = InternalExpressionValue.environment
type errorValue = Reducer_ErrorValue.errorValue
type expression = T.expression
type expressionValue = ReducerInterface_ExpressionValue.expressionValue
type externalBindings = ReducerInterface_ExpressionValue.externalBindings
type internalCode = ReducerInterface_ExpressionValue.internalCode
type internalExpressionValue = InternalExpressionValue.t
type externalExpressionValue = ReducerInterface_ExternalExpressionValue.t
type t = expression
/*
@ -27,7 +27,7 @@ let parse = (peggyCode: string): result<t, errorValue> =>
Recursively evaluate/reduce the expression (Lisp AST)
*/
let rec reduceExpression = (expression: t, bindings: T.bindings, environment: environment): result<
expressionValue,
internalExpressionValue,
'e,
> => {
// Js.log(`reduce: ${T.toString(expression)} bindings: ${bindings->Bindings.toString}`)
@ -35,7 +35,7 @@ let rec reduceExpression = (expression: t, bindings: T.bindings, environment: en
| T.EValue(value) => value->Ok
| T.EList(list) =>
switch list {
| list{EValue(EvCall(fName)), ..._args} =>
| list{EValue(IEvCall(fName)), ..._args} =>
switch Macro.isMacroName(fName) {
// A macro expands then reduces itself
| true => Macro.doMacroCall(expression, bindings, environment, reduceExpression)
@ -50,11 +50,11 @@ and reduceExpressionList = (
expressions: list<t>,
bindings: T.bindings,
environment: environment,
): result<expressionValue, 'e> => {
let racc: result<list<expressionValue>, 'e> = expressions->Belt.List.reduceReverse(Ok(list{}), (
racc,
each: expression,
) =>
): result<internalExpressionValue, 'e> => {
let racc: result<
list<internalExpressionValue>,
'e,
> = expressions->Belt.List.reduceReverse(Ok(list{}), (racc, each: expression) =>
racc->Result.flatMap(acc => {
each
->reduceExpression(bindings, environment)
@ -69,12 +69,12 @@ and reduceExpressionList = (
/*
After reducing each level of expression(Lisp AST), we have a value list to evaluate
*/
and reduceValueList = (valueList: list<expressionValue>, environment): result<
expressionValue,
and reduceValueList = (valueList: list<internalExpressionValue>, environment): result<
internalExpressionValue,
'e,
> =>
switch valueList {
| list{EvCall(fName), ...args} => {
| list{IEvCall(fName), ...args} => {
let rCheckedArgs = switch fName {
| "$_setBindings_$" | "$_setTypeOfBindings_$" | "$_setTypeAliasBindings_$" => args->Ok
| _ => args->Lambda.checkIfReduced
@ -84,14 +84,14 @@ and reduceValueList = (valueList: list<expressionValue>, environment): result<
(fName, checkedArgs->Belt.List.toArray)->BuiltIn.dispatch(environment, reduceExpression)
)
}
| list{EvLambda(_)} =>
| list{IEvLambda(_)} =>
// TODO: remove on solving issue#558
valueList
->Lambda.checkIfReduced
->Result.flatMap(reducedValueList =>
reducedValueList->Belt.List.toArray->ExpressionValue.EvArray->Ok
reducedValueList->Belt.List.toArray->InternalExpressionValue.IEvArray->Ok
)
| list{EvLambda(lamdaCall), ...args} =>
| list{IEvLambda(lamdaCall), ...args} =>
args
->Lambda.checkIfReduced
->Result.flatMap(checkedArgs =>
@ -102,62 +102,57 @@ and reduceValueList = (valueList: list<expressionValue>, environment): result<
valueList
->Lambda.checkIfReduced
->Result.flatMap(reducedValueList =>
reducedValueList->Belt.List.toArray->ExpressionValue.EvArray->Ok
reducedValueList->Belt.List.toArray->InternalExpressionValue.IEvArray->Ok
)
}
let evalUsingBindingsExpression_ = (aExpression, bindings, environment): result<
expressionValue,
internalExpressionValue,
'e,
> => reduceExpression(aExpression, bindings, environment)
let evaluateUsingOptions = (
~environment: option<ReducerInterface_ExpressionValue.environment>,
~externalBindings: option<ReducerInterface_ExpressionValue.externalBindings>,
~environment: option<ReducerInterface_ExternalExpressionValue.environment>,
~externalBindings: option<ReducerInterface_ExternalExpressionValue.externalBindings>,
code: string,
): result<expressionValue, errorValue> => {
): result<externalExpressionValue, errorValue> => {
let anEnvironment = Belt.Option.getWithDefault(
environment,
ReducerInterface_ExpressionValue.defaultEnvironment,
ReducerInterface_ExternalExpressionValue.defaultEnvironment,
)
let anExternalBindings = switch externalBindings {
| Some(bindings) => {
let cloneLib = ReducerInterface_StdLib.externalStdLib->Reducer_Category_Bindings.cloneRecord
Js.Dict.entries(bindings)->Js.Array2.reduce((acc, (key, value)) => {
acc->Js.Dict.set(key, value)
acc
}, cloneLib)
}
| None => ReducerInterface_StdLib.externalStdLib
}
let mergedBindings: InternalExpressionValue.nameSpace = Module.merge(
ReducerInterface_StdLib.internalStdLib,
Belt.Option.map(externalBindings, Module.fromTypeScriptBindings)->Belt.Option.getWithDefault(
Module.emptyModule,
),
)
let bindings = anExternalBindings->Bindings.fromExternalBindings
parse(code)->Result.flatMap(expr => evalUsingBindingsExpression_(expr, bindings, anEnvironment))
parse(code)
->Result.flatMap(expr => evalUsingBindingsExpression_(expr, mergedBindings, anEnvironment))
->Result.map(ReducerInterface_InternalExpressionValue.toExternal)
}
/*
Evaluates Squiggle code and bindings via Reducer and answers the result
IEvaluates Squiggle code and bindings via Reducer and answers the result
*/
let evaluate = (code: string): result<expressionValue, errorValue> => {
let evaluate = (code: string): result<externalExpressionValue, errorValue> => {
evaluateUsingOptions(~environment=None, ~externalBindings=None, code)
}
let eval = evaluate
let evaluatePartialUsingExternalBindings = (
code: string,
externalBindings: ReducerInterface_ExpressionValue.externalBindings,
environment: ReducerInterface_ExpressionValue.environment,
): result<externalBindings, errorValue> => {
externalBindings: ReducerInterface_ExternalExpressionValue.externalBindings,
environment: ReducerInterface_ExternalExpressionValue.environment,
): result<ReducerInterface_ExternalExpressionValue.externalBindings, errorValue> => {
let rAnswer = evaluateUsingOptions(
~environment=Some(environment),
~externalBindings=Some(externalBindings),
code,
)
switch rAnswer {
| Ok(EvRecord(externalBindings)) => Ok(externalBindings)
| Ok(EvModule(externalBindings)) => Ok(externalBindings)
| Ok(_) =>
Error(Reducer_ErrorValue.RESyntaxError(`Partials must end with an assignment or record`))
Error(Reducer_ErrorValue.RESyntaxError(`Partials must end with an assignment or record`, None))
| Error(err) => err->Error
}
}

View File

@ -1,16 +1,16 @@
module Bindings = Reducer_Expression_Bindings
module BindingsReplacer = Reducer_Expression_BindingsReplacer
module ErrorValue = Reducer_ErrorValue
module ExpressionT = Reducer_Expression_T
module ExpressionValue = ReducerInterface.ExpressionValue
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
module Result = Belt.Result
module Module = Reducer_Category_Module
type bindings = ExpressionT.bindings
type context = bindings
type environment = ExpressionValue.environment
type environment = InternalExpressionValue.environment
type errorValue = Reducer_ErrorValue.errorValue
type expression = ExpressionT.expression
type expressionValue = ExpressionValue.expressionValue
type externalBindings = ReducerInterface_ExpressionValue.externalBindings
type internalExpressionValue = InternalExpressionValue.t
type reducerFn = ExpressionT.reducerFn
type expressionWithContext =
@ -22,7 +22,7 @@ let callReducer = (
bindings: bindings,
environment: environment,
reducer: reducerFn,
): result<expressionValue, errorValue> => {
): result<internalExpressionValue, errorValue> => {
switch expressionWithContext {
| ExpressionNoContext(expr) =>
// Js.log(`callReducer: bindings ${Bindings.toString(bindings)} expr ${ExpressionT.toString(expr)}`)
@ -40,7 +40,9 @@ let toString = expressionWithContext =>
switch expressionWithContext {
| ExpressionNoContext(expr) => ExpressionT.toString(expr)
| ExpressionWithContext(expr, context) =>
`${ExpressionT.toString(expr)} context: ${Bindings.toString(context)}`
`${ExpressionT.toString(expr)} context: ${context
->Module.toExpressionValue
->InternalExpressionValue.toString}`
}
let toStringResult = rExpressionWithContext =>

View File

@ -1,72 +0,0 @@
module ErrorValue = Reducer_ErrorValue
module ExpressionT = Reducer_Expression_T
module ExpressionValue = ReducerInterface.ExpressionValue
module Result = Belt.Result
module Bindings = Reducer_Category_Bindings
type errorValue = Reducer_ErrorValue.errorValue
type expression = ExpressionT.expression
type expressionValue = ExpressionValue.expressionValue
type externalBindings = ReducerInterface_ExpressionValue.externalBindings
let emptyBindings = Reducer_Category_Bindings.emptyBindings
let typeAliasesKey = Bindings.typeAliasesKey
let typeReferencesKey = Bindings.typeReferencesKey
let toExternalBindings = (bindings: ExpressionT.bindings): externalBindings =>
Bindings.toRecord(bindings)
let fromExternalBindings = (externalBindings: externalBindings): ExpressionT.bindings =>
Bindings.fromRecord(externalBindings)
let fromValue = (aValue: expressionValue) => Bindings.fromExpressionValue(aValue)
let isMacroName = (fName: string): bool => fName->Js.String2.startsWith("$$")
let rec replaceSymbols = (bindings: ExpressionT.bindings, expression: expression): result<
expression,
errorValue,
> =>
switch expression {
| ExpressionT.EValue(value) =>
replaceSymbolOnValue(bindings, value)->Result.map(evValue => evValue->ExpressionT.EValue)
| ExpressionT.EList(list) =>
switch list {
| list{EValue(EvCall(fName)), ..._args} =>
switch isMacroName(fName) {
// A macro reduces itself so we dont dive in it
| true => expression->Ok
| false => replaceSymbolsOnExpressionList(bindings, list)
}
| _ => replaceSymbolsOnExpressionList(bindings, list)
}
}
and replaceSymbolsOnExpressionList = (bindings, list) => {
let racc = list->Belt.List.reduceReverse(Ok(list{}), (racc, each: expression) =>
racc->Result.flatMap(acc => {
replaceSymbols(bindings, each)->Result.flatMap(newNode => {
acc->Belt.List.add(newNode)->Ok
})
})
)
racc->Result.map(acc => acc->ExpressionT.EList)
}
and replaceSymbolOnValue = (bindings, evValue: expressionValue) =>
switch evValue {
| EvSymbol(symbol) => Belt.Map.String.getWithDefault(bindings, symbol, evValue)->Ok
| EvCall(symbol) => Belt.Map.String.getWithDefault(bindings, symbol, evValue)->checkIfCallable
| _ => evValue->Ok
}
and checkIfCallable = (evValue: expressionValue) =>
switch evValue {
| EvCall(_) | EvLambda(_) => evValue->Ok
| _ => ErrorValue.RENotAFunction(ExpressionValue.toString(evValue))->Error
}
let toString = (bindings: ExpressionT.bindings) =>
bindings->toExternalBindings->ExpressionValue.EvRecord->ExpressionValue.toString
let externalBindingsToString = (externalBindings: externalBindings) =>
externalBindings->ExpressionValue.EvRecord->ExpressionValue.toString

View File

@ -0,0 +1,53 @@
module ErrorValue = Reducer_ErrorValue
module ExpressionT = Reducer_Expression_T
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
module Result = Belt.Result
module Module = Reducer_Category_Module
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("$$")
let rec replaceSymbols = (bindings: ExpressionT.bindings, expression: expression): result<
expression,
errorValue,
> =>
switch expression {
| ExpressionT.EValue(value) =>
replaceSymbolOnValue(bindings, value)->Result.map(evValue => evValue->ExpressionT.EValue)
| ExpressionT.EList(list) =>
switch list {
| list{EValue(IEvCall(fName)), ..._args} =>
switch isMacroName(fName) {
// A macro reduces itself so we dont dive in it
| true => expression->Ok
| false => replaceSymbolsOnExpressionList(bindings, list)
}
| _ => replaceSymbolsOnExpressionList(bindings, list)
}
}
and replaceSymbolsOnExpressionList = (bindings, list) => {
let racc = list->Belt.List.reduceReverse(Ok(list{}), (racc, each: expression) =>
racc->Result.flatMap(acc => {
replaceSymbols(bindings, each)->Result.flatMap(newNode => {
acc->Belt.List.add(newNode)->Ok
})
})
)
racc->Result.map(acc => acc->ExpressionT.EList)
}
and replaceSymbolOnValue = (bindings, evValue: internalExpressionValue) =>
switch evValue {
| IEvSymbol(symbol) => Module.getWithDefault(bindings, symbol, evValue)->Ok
| IEvCall(symbol) => Module.getWithDefault(bindings, symbol, evValue)->checkIfCallable
| _ => evValue->Ok
}
and checkIfCallable = (evValue: internalExpressionValue) =>
switch evValue {
| IEvCall(_) | IEvLambda(_) => evValue->Ok
| _ => ErrorValue.RENotAFunction(InternalExpressionValue.toString(evValue))->Error
}

View File

@ -1,24 +1,28 @@
module BBindings = Reducer_Expression_Bindings
module BBindingsReplacer = Reducer_Expression_BindingsReplacer
module BErrorValue = Reducer_ErrorValue
module BExpressionT = Reducer_Expression_T
module BExpressionValue = ReducerInterface.ExpressionValue
module BInternalExpressionValue = ReducerInterface_InternalExpressionValue
module BModule = Reducer_Category_Module
type errorValue = BErrorValue.errorValue
type expression = BExpressionT.expression
type internalCode = ReducerInterface_ExpressionValue.internalCode
type expressionOrFFI = BExpressionT.expressionOrFFI
type ffiFn = BExpressionT.ffiFn
type internalCode = ReducerInterface_InternalExpressionValue.internalCode
external castExpressionToInternalCode: expression => internalCode = "%identity"
external castExpressionToInternalCode: expressionOrFFI => internalCode = "%identity"
let eArray = anArray => anArray->BExpressionValue.EvArray->BExpressionT.EValue
let eArray = anArray => anArray->BInternalExpressionValue.IEvArray->BExpressionT.EValue
let eArrayString = anArray => anArray->BExpressionValue.EvArrayString->BExpressionT.EValue
let eArrayString = anArray => anArray->BInternalExpressionValue.IEvArrayString->BExpressionT.EValue
let eBindings = (anArray: array<(string, BExpressionValue.expressionValue)>) =>
anArray->Js.Dict.fromArray->BExpressionValue.EvRecord->BExpressionT.EValue
let eBindings = (anArray: array<(string, BInternalExpressionValue.t)>) =>
anArray->BModule.fromArray->BModule.toExpressionValue->BExpressionT.EValue
let eBool = aBool => aBool->BExpressionValue.EvBool->BExpressionT.EValue
let eBool = aBool => aBool->BInternalExpressionValue.IEvBool->BExpressionT.EValue
let eCall = (name: string): expression => name->BExpressionValue.EvCall->BExpressionT.EValue
let eCall = (name: string): expression =>
name->BInternalExpressionValue.IEvCall->BExpressionT.EValue
let eFunction = (fName: string, lispArgs: list<expression>): expression => {
let fn = fName->eCall
@ -27,29 +31,41 @@ let eFunction = (fName: string, lispArgs: list<expression>): expression => {
let eLambda = (
parameters: array<string>,
context: BExpressionValue.externalBindings,
context: BInternalExpressionValue.nameSpace,
expr: expression,
) => {
// Js.log(`eLambda context ${BBindings.externalBindingsToString(context)}`)
BExpressionValue.EvLambda({
BInternalExpressionValue.IEvLambda({
parameters: parameters,
context: context,
body: expr->castExpressionToInternalCode,
body: NotFFI(expr)->castExpressionToInternalCode,
})->BExpressionT.EValue
}
let eNumber = aNumber => aNumber->BExpressionValue.EvNumber->BExpressionT.EValue
let eLambdaFFI = (parameters: array<string>, ffiFn: ffiFn) => {
let context = BModule.emptyModule
BInternalExpressionValue.IEvLambda({
parameters: parameters,
context: context,
body: FFI(ffiFn)->castExpressionToInternalCode,
})->BExpressionT.EValue
}
let eRecord = aRecord => aRecord->BExpressionValue.EvRecord->BExpressionT.EValue
let eNumber = aNumber => aNumber->BInternalExpressionValue.IEvNumber->BExpressionT.EValue
let eString = aString => aString->BExpressionValue.EvString->BExpressionT.EValue
let eRecord = aMap => aMap->BInternalExpressionValue.IEvRecord->BExpressionT.EValue
let eSymbol = (name: string): expression => name->BExpressionValue.EvSymbol->BExpressionT.EValue
let eString = aString => aString->BInternalExpressionValue.IEvString->BExpressionT.EValue
let eSymbol = (name: string): expression =>
name->BInternalExpressionValue.IEvSymbol->BExpressionT.EValue
let eList = (list: list<expression>): expression => list->BExpressionT.EList
let eBlock = (exprs: list<expression>): expression => eFunction("$$_block_$$", exprs)
let eModule = (nameSpace: BInternalExpressionValue.nameSpace): expression =>
nameSpace->BInternalExpressionValue.IEvModule->BExpressionT.EValue
let eLetStatement = (symbol: string, valueExpression: expression): expression =>
eFunction("$_let_$", list{eSymbol(symbol), valueExpression})
@ -65,7 +81,8 @@ let eBindExpression = (bindingExpr: expression, expression: expression): express
let eBindExpressionDefault = (expression: expression): expression =>
eFunction("$$_bindExpression_$$", list{expression})
let eIdentifier = (name: string): expression => name->BExpressionValue.EvSymbol->BExpressionT.EValue
let eIdentifier = (name: string): expression =>
name->BInternalExpressionValue.IEvSymbol->BExpressionT.EValue
let eTypeIdentifier = (name: string): expression =>
name->BExpressionValue.EvTypeIdentifier->BExpressionT.EValue
name->BInternalExpressionValue.IEvTypeIdentifier->BExpressionT.EValue

View File

@ -1,19 +1,24 @@
module Bindings = Reducer_Expression_Bindings
module BindingsReplacer = Reducer_Expression_BindingsReplacer
module ErrorValue = Reducer_ErrorValue
module ExpressionBuilder = Reducer_Expression_ExpressionBuilder
module ExpressionT = Reducer_Expression_T
module ExpressionValue = ReducerInterface.ExpressionValue
module ExpressionValue = ReducerInterface_InternalExpressionValue
module Module = Reducer_Category_Module
module Result = Belt.Result
type environment = ReducerInterface_ExpressionValue.environment
type environment = ReducerInterface_InternalExpressionValue.environment
type expression = ExpressionT.expression
type expressionValue = ReducerInterface_ExpressionValue.expressionValue
type externalBindings = ReducerInterface_ExpressionValue.externalBindings
type internalCode = ReducerInterface_ExpressionValue.internalCode
type expressionOrFFI = ExpressionT.expressionOrFFI
type internalExpressionValue = ReducerInterface_InternalExpressionValue.t
// type tmpExternalBindings = ReducerInterface_InternalExpressionValue.tmpExternalBindings
type internalCode = ReducerInterface_InternalExpressionValue.internalCode
external castInternalCodeToExpression: internalCode => expression = "%identity"
external castInternalCodeToExpression: internalCode => expressionOrFFI = "%identity"
let checkArity = (lambdaValue: ExpressionValue.lambdaValue, args: list<expressionValue>) => {
let checkArity = (
lambdaValue: ExpressionValue.lambdaValue,
args: list<internalExpressionValue>,
) => {
let argsLength = Belt.List.length(args)
let parametersLength = Js.Array2.length(lambdaValue.parameters)
if argsLength !== parametersLength {
@ -23,34 +28,44 @@ let checkArity = (lambdaValue: ExpressionValue.lambdaValue, args: list<expressio
}
}
let checkIfReduced = (args: list<expressionValue>) =>
let checkIfReduced = (args: list<internalExpressionValue>) =>
args->Belt.List.reduceReverse(Ok(list{}), (rAcc, arg) =>
rAcc->Result.flatMap(acc =>
switch arg {
| EvSymbol(symbol) => ErrorValue.RESymbolNotFound(symbol)->Error
| IEvSymbol(symbol) => ErrorValue.RESymbolNotFound(symbol)->Error
| _ => list{arg, ...acc}->Ok
}
)
)
let caseNotFFI = (lambdaValue: ExpressionValue.lambdaValue, expr, args, environment, reducer) => {
let parameterList = lambdaValue.parameters->Belt.List.fromArray
let zippedParameterList = parameterList->Belt.List.zip(args)
let bindings = Belt.List.reduce(zippedParameterList, lambdaValue.context, (
acc,
(variable, variableValue),
) => acc->Module.set(variable, variableValue))
let newExpression = ExpressionBuilder.eBlock(list{expr})
reducer(newExpression, bindings, environment)
}
let caseFFI = (ffiFn: ExpressionT.ffiFn, args, environment) => {
ffiFn(args->Belt.List.toArray, environment)
}
let applyParametersToLambda = (
lambdaValue: ExpressionValue.lambdaValue,
args,
environment,
reducer: ExpressionT.reducerFn,
): result<expressionValue, 'e> => {
): result<internalExpressionValue, 'e> => {
checkArity(lambdaValue, args)->Result.flatMap(args =>
checkIfReduced(args)->Result.flatMap(args => {
let expr = castInternalCodeToExpression(lambdaValue.body)
let parameterList = lambdaValue.parameters->Belt.List.fromArray
let zippedParameterList = parameterList->Belt.List.zip(args)
let bindings = Belt.List.reduce(
zippedParameterList,
lambdaValue.context->Bindings.fromExternalBindings,
(acc, (variable, variableValue)) => acc->Belt.Map.String.set(variable, variableValue),
)
let newExpression = ExpressionBuilder.eBlock(list{expr})
reducer(newExpression, bindings, environment)
let exprOrFFI = castInternalCodeToExpression(lambdaValue.body)
switch exprOrFFI {
| NotFFI(expr) => caseNotFFI(lambdaValue, expr, args, environment, reducer)
| FFI(ffiFn) => caseFFI(ffiFn, args, environment)
}
})
)
}
@ -60,10 +75,10 @@ let doLambdaCall = (lambdaValue: ExpressionValue.lambdaValue, args, environment,
let foreignFunctionInterface = (
lambdaValue: ExpressionValue.lambdaValue,
argArray: array<expressionValue>,
argArray: array<internalExpressionValue>,
environment: ExpressionValue.environment,
reducer: ExpressionT.reducerFn,
): result<expressionValue, 'e> => {
): result<internalExpressionValue, 'e> => {
let args = argArray->Belt.List.fromArray
applyParametersToLambda(lambdaValue, args, environment, reducer)
}

View File

@ -1,11 +1,11 @@
module ExpressionT = Reducer_Expression_T
module ExpressionValue = ReducerInterface.ExpressionValue
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
module ExpressionWithContext = Reducer_ExpressionWithContext
module Result = Belt.Result
type environment = ExpressionValue.environment
type environment = InternalExpressionValue.environment
type expression = ExpressionT.expression
type expressionValue = ExpressionValue.expressionValue
type internalExpressionValue = InternalExpressionValue.t
type expressionWithContext = ExpressionWithContext.expressionWithContext
let expandMacroCall = (
@ -26,7 +26,7 @@ let doMacroCall = (
bindings: ExpressionT.bindings,
environment: environment,
reduceExpression: ExpressionT.reducerFn,
): result<expressionValue, 'e> =>
): result<internalExpressionValue, 'e> =>
expandMacroCall(
macroExpression,
bindings,

View File

@ -7,28 +7,28 @@
The act of defining the semantics of a functional language is to write it in terms of Lisp AST.
*/
module Extra = Reducer_Extra
module ExpressionValue = ReducerInterface.ExpressionValue
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
type expressionValue = ExpressionValue.expressionValue
type environment = ExpressionValue.environment
type internalExpressionValue = InternalExpressionValue.t
type environment = ReducerInterface_InternalExpressionValue.environment
type rec expression =
| EList(list<expression>) // A list to map-reduce
| EValue(expressionValue) // Irreducible built-in value. Reducer should not know the internals. External libraries are responsible
and bindings = Belt.Map.String.t<expressionValue>
| EValue(internalExpressionValue) // Irreducible built-in value. Reducer should not know the internals. External libraries are responsible
and bindings = InternalExpressionValue.nameSpace
type reducerFn = (
expression,
bindings,
environment,
) => result<expressionValue, Reducer_ErrorValue.errorValue>
) => result<internalExpressionValue, Reducer_ErrorValue.errorValue>
/*
Converts the expression to String
*/
let rec toString = expression =>
switch expression {
| EList(list{EValue(EvCall("$$_block_$$")), ...statements}) =>
| EList(list{EValue(IEvCall("$$_block_$$")), ...statements}) =>
`{${Belt.List.map(statements, aValue => toString(aValue))
->Extra.List.interperse("; ")
->Belt.List.toArray
@ -38,7 +38,7 @@ let rec toString = expression =>
->Extra.List.interperse(" ")
->Belt.List.toArray
->Js.String.concatMany("")})`
| EValue(aValue) => ExpressionValue.toString(aValue)
| EValue(aValue) => InternalExpressionValue.toString(aValue)
}
let toStringResult = codeResult =>
@ -65,3 +65,12 @@ let inspectResult = (r: result<expression, Reducer_ErrorValue.errorValue>): resu
Js.log(toStringResult(r))
r
}
type ffiFn = (
array<internalExpressionValue>,
environment,
) => result<internalExpressionValue, Reducer_ErrorValue.errorValue>
type expressionOrFFI =
| NotFFI(expression)
| FFI(ffiFn)

View File

@ -1,4 +1,4 @@
open ReducerInterface.ExpressionValue
open ReducerInterface_InternalExpressionValue
open Reducer_ErrorValue
external castBool: unit => bool = "%identity"
@ -8,10 +8,10 @@ external castString: unit => string = "%identity"
/*
As JavaScript returns us any type, we need to type check and cast type propertype before using it
*/
let jsToEv = (jsValue): result<expressionValue, errorValue> =>
let jsToIEv = (jsValue): result<internalExpressionValue, errorValue> =>
switch Js.typeof(jsValue) {
| "boolean" => jsValue->castBool->EvBool->Ok
| "number" => jsValue->castNumber->EvNumber->Ok
| "string" => jsValue->castString->EvString->Ok
| "boolean" => jsValue->castBool->IEvBool->Ok
| "number" => jsValue->castNumber->IEvNumber->Ok
| "string" => jsValue->castString->IEvString->Ok
| other => RETodo(`Unhandled MathJs literal type: ${Js.String.make(other)}`)->Error
}

View File

@ -1,5 +1,5 @@
module JavaScript = Reducer_Js
open ReducerInterface.ExpressionValue
open ReducerInterface_InternalExpressionValue
open Reducer_ErrorValue
@module("mathjs") external dummy_: string => unit = "evaluate"
@ -17,10 +17,10 @@ let eval__: string => 'a = %raw(`function (expr) { return {value: Mathjs.evaluat
/*
Call MathJs evaluate and return as a variant
*/
let eval = (expr: string): result<expressionValue, errorValue> => {
let eval = (expr: string): result<internalExpressionValue, errorValue> => {
try {
let answer = eval__(expr)
answer["value"]->JavaScript.Gate.jsToEv
answer["value"]->JavaScript.Gate.jsToIEv
} catch {
| Js.Exn.Error(obj) => REJavaScriptExn(Js.Exn.message(obj), Js.Exn.name(obj))->Error
}

View File

@ -5,11 +5,15 @@ type node = {"type": string}
@module("./Reducer_Peggy_GeneratedParser.js") external parse__: string => node = "parse"
let syntaxErrorToLocation: Js.Exn.t => Reducer_ErrorValue.location = error => %raw(`error.location`)
@genType
let parse = (expr: string): result<node, errorValue> =>
try {
Ok(parse__(expr))
} catch {
| Js.Exn.Error(obj) => REJavaScriptExn(Js.Exn.message(obj), Js.Exn.name(obj))->Error
| Js.Exn.Error(obj) =>
RESyntaxError(Belt.Option.getExn(Js.Exn.message(obj)), syntaxErrorToLocation(obj)->Some)->Error
}
type nodeBlock = {...node, "statements": array<node>}

View File

@ -1,2 +1,4 @@
module ExpressionValue = ReducerInterface_ExpressionValue
module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue
module ExternalLibrary = ReducerInterface_ExternalLibrary
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
module StdLib = ReducerInterface_StdLib

View File

@ -1,27 +1,27 @@
module EV = ReducerInterface_ExpressionValue
type expressionValue = EV.expressionValue
module IEV = ReducerInterface_InternalExpressionValue
type internalExpressionValue = IEV.t
let dispatch = (call: EV.functionCall, _: DistributionOperation.env): option<
result<expressionValue, QuriSquiggleLang.Reducer_ErrorValue.errorValue>,
let dispatch = (call: IEV.functionCall, _: DistributionOperation.env): option<
result<internalExpressionValue, QuriSquiggleLang.Reducer_ErrorValue.errorValue>,
> => {
switch call {
| ("toString", [EvDate(t)]) => EV.EvString(DateTime.Date.toString(t))->Ok->Some
| ("makeDateFromYear", [EvNumber(year)]) =>
| ("toString", [IEvDate(t)]) => IEV.IEvString(DateTime.Date.toString(t))->Ok->Some
| ("makeDateFromYear", [IEvNumber(year)]) =>
switch DateTime.Date.makeFromYear(year) {
| Ok(t) => EV.EvDate(t)->Ok->Some
| Ok(t) => IEV.IEvDate(t)->Ok->Some
| Error(e) => Reducer_ErrorValue.RETodo(e)->Error->Some
}
| ("dateFromNumber", [EvNumber(f)]) => EV.EvDate(DateTime.Date.fromFloat(f))->Ok->Some
| ("toNumber", [EvDate(f)]) => EV.EvNumber(DateTime.Date.toFloat(f))->Ok->Some
| ("subtract", [EvDate(d1), EvDate(d2)]) =>
| ("dateFromNumber", [IEvNumber(f)]) => IEV.IEvDate(DateTime.Date.fromFloat(f))->Ok->Some
| ("toNumber", [IEvDate(f)]) => IEV.IEvNumber(DateTime.Date.toFloat(f))->Ok->Some
| ("subtract", [IEvDate(d1), IEvDate(d2)]) =>
switch DateTime.Date.subtract(d1, d2) {
| Ok(d) => EV.EvTimeDuration(d)->Ok
| Ok(d) => IEV.IEvTimeDuration(d)->Ok
| Error(e) => Error(RETodo(e))
}->Some
| ("subtract", [EvDate(d1), EvTimeDuration(d2)]) =>
EV.EvDate(DateTime.Date.subtractDuration(d1, d2))->Ok->Some
| ("add", [EvDate(d1), EvTimeDuration(d2)]) =>
EV.EvDate(DateTime.Date.addDuration(d1, d2))->Ok->Some
| ("subtract", [IEvDate(d1), IEvTimeDuration(d2)]) =>
IEV.IEvDate(DateTime.Date.subtractDuration(d1, d2))->Ok->Some
| ("add", [IEvDate(d1), IEvTimeDuration(d2)]) =>
IEV.IEvDate(DateTime.Date.addDuration(d1, d2))->Ok->Some
| _ => None
}
}

View File

@ -1,33 +1,36 @@
module EV = ReducerInterface_ExpressionValue
type expressionValue = EV.expressionValue
module IEV = ReducerInterface_InternalExpressionValue
type internalExpressionValue = IEV.t
let dispatch = (call: EV.functionCall, _: DistributionOperation.env): option<
result<expressionValue, QuriSquiggleLang.Reducer_ErrorValue.errorValue>,
let dispatch = (call: IEV.functionCall, _: DistributionOperation.env): option<
result<internalExpressionValue, QuriSquiggleLang.Reducer_ErrorValue.errorValue>,
> => {
switch call {
| ("toString", [EvTimeDuration(t)]) => EV.EvString(DateTime.Duration.toString(t))->Ok->Some
| ("minutes", [EvNumber(f)]) => EV.EvTimeDuration(DateTime.Duration.fromMinutes(f))->Ok->Some
| ("fromUnit_minutes", [EvNumber(f)]) =>
EV.EvTimeDuration(DateTime.Duration.fromMinutes(f))->Ok->Some
| ("hours", [EvNumber(f)]) => EV.EvTimeDuration(DateTime.Duration.fromHours(f))->Ok->Some
| ("fromUnit_hours", [EvNumber(f)]) => EV.EvTimeDuration(DateTime.Duration.fromHours(f))->Ok->Some
| ("days", [EvNumber(f)]) => EV.EvTimeDuration(DateTime.Duration.fromDays(f))->Ok->Some
| ("fromUnit_days", [EvNumber(f)]) => EV.EvTimeDuration(DateTime.Duration.fromDays(f))->Ok->Some
| ("years", [EvNumber(f)]) => EV.EvTimeDuration(DateTime.Duration.fromYears(f))->Ok->Some
| ("fromUnit_years", [EvNumber(f)]) => EV.EvTimeDuration(DateTime.Duration.fromYears(f))->Ok->Some
| ("toHours", [EvTimeDuration(f)]) => EV.EvNumber(DateTime.Duration.toHours(f))->Ok->Some
| ("toMinutes", [EvTimeDuration(f)]) => EV.EvNumber(DateTime.Duration.toMinutes(f))->Ok->Some
| ("toDays", [EvTimeDuration(f)]) => EV.EvNumber(DateTime.Duration.toDays(f))->Ok->Some
| ("toYears", [EvTimeDuration(f)]) => EV.EvNumber(DateTime.Duration.toYears(f))->Ok->Some
| ("add", [EvTimeDuration(d1), EvTimeDuration(d2)]) =>
EV.EvTimeDuration(DateTime.Duration.add(d1, d2))->Ok->Some
| ("subtract", [EvTimeDuration(d1), EvTimeDuration(d2)]) =>
EV.EvTimeDuration(DateTime.Duration.subtract(d1, d2))->Ok->Some
| ("multiply", [EvTimeDuration(d1), EvNumber(d2)]) =>
EV.EvTimeDuration(DateTime.Duration.multiply(d1, d2))->Ok->Some
| ("divide", [EvTimeDuration(d1), EvNumber(d2)]) =>
EV.EvTimeDuration(DateTime.Duration.divide(d1, d2))->Ok->Some
| ("divide", [EvTimeDuration(d1), EvTimeDuration(d2)]) => EV.EvNumber(d1 /. d2)->Ok->Some
| ("toString", [IEvTimeDuration(t)]) => IEV.IEvString(DateTime.Duration.toString(t))->Ok->Some
| ("minutes", [IEvNumber(f)]) => IEV.IEvTimeDuration(DateTime.Duration.fromMinutes(f))->Ok->Some
| ("fromUnit_minutes", [IEvNumber(f)]) =>
IEV.IEvTimeDuration(DateTime.Duration.fromMinutes(f))->Ok->Some
| ("hours", [IEvNumber(f)]) => IEV.IEvTimeDuration(DateTime.Duration.fromHours(f))->Ok->Some
| ("fromUnit_hours", [IEvNumber(f)]) =>
IEV.IEvTimeDuration(DateTime.Duration.fromHours(f))->Ok->Some
| ("days", [IEvNumber(f)]) => IEV.IEvTimeDuration(DateTime.Duration.fromDays(f))->Ok->Some
| ("fromUnit_days", [IEvNumber(f)]) =>
IEV.IEvTimeDuration(DateTime.Duration.fromDays(f))->Ok->Some
| ("years", [IEvNumber(f)]) => IEV.IEvTimeDuration(DateTime.Duration.fromYears(f))->Ok->Some
| ("fromUnit_years", [IEvNumber(f)]) =>
IEV.IEvTimeDuration(DateTime.Duration.fromYears(f))->Ok->Some
| ("toHours", [IEvTimeDuration(f)]) => IEV.IEvNumber(DateTime.Duration.toHours(f))->Ok->Some
| ("toMinutes", [IEvTimeDuration(f)]) => IEV.IEvNumber(DateTime.Duration.toMinutes(f))->Ok->Some
| ("toDays", [IEvTimeDuration(f)]) => IEV.IEvNumber(DateTime.Duration.toDays(f))->Ok->Some
| ("toYears", [IEvTimeDuration(f)]) => IEV.IEvNumber(DateTime.Duration.toYears(f))->Ok->Some
| ("add", [IEvTimeDuration(d1), IEvTimeDuration(d2)]) =>
IEV.IEvTimeDuration(DateTime.Duration.add(d1, d2))->Ok->Some
| ("subtract", [IEvTimeDuration(d1), IEvTimeDuration(d2)]) =>
IEV.IEvTimeDuration(DateTime.Duration.subtract(d1, d2))->Ok->Some
| ("multiply", [IEvTimeDuration(d1), IEvNumber(d2)]) =>
IEV.IEvTimeDuration(DateTime.Duration.multiply(d1, d2))->Ok->Some
| ("divide", [IEvTimeDuration(d1), IEvNumber(d2)]) =>
IEV.IEvTimeDuration(DateTime.Duration.divide(d1, d2))->Ok->Some
| ("divide", [IEvTimeDuration(d1), IEvTimeDuration(d2)]) => IEV.IEvNumber(d1 /. d2)->Ok->Some
| _ => None
}
}

View File

@ -8,8 +8,8 @@ module ErrorValue = Reducer_ErrorValue
type internalCode = Object
@genType
type rec expressionValue =
| EvArray(array<expressionValue>)
type rec externalExpressionValue =
| EvArray(array<externalExpressionValue>)
| EvArrayString(array<string>)
| EvBool(bool)
| EvCall(string) // External function call
@ -24,7 +24,7 @@ type rec expressionValue =
| EvDeclaration(lambdaDeclaration)
| EvTypeIdentifier(string)
| EvModule(record)
and record = Js.Dict.t<expressionValue>
and record = Js.Dict.t<externalExpressionValue>
and externalBindings = record
and lambdaValue = {
parameters: array<string>,
@ -33,7 +33,10 @@ and lambdaValue = {
}
and lambdaDeclaration = Declaration.declaration<lambdaValue>
type functionCall = (string, array<expressionValue>)
@genType
type t = externalExpressionValue
type functionCall = (string, array<externalExpressionValue>)
let rec toString = aValue =>
switch aValue {
@ -68,26 +71,7 @@ and toStringRecord = aRecord => {
`{${pairs}}`
}
let toStringWithType = aValue =>
switch aValue {
| EvArray(_) => `Array::${toString(aValue)}`
| EvArrayString(_) => `ArrayString::${toString(aValue)}`
| EvBool(_) => `Bool::${toString(aValue)}`
| EvCall(_) => `Call::${toString(aValue)}`
| EvDistribution(_) => `Distribution::${toString(aValue)}`
| EvLambda(_) => `Lambda::${toString(aValue)}`
| EvNumber(_) => `Number::${toString(aValue)}`
| EvRecord(_) => `Record::${toString(aValue)}`
| EvString(_) => `String::${toString(aValue)}`
| EvSymbol(_) => `Symbol::${toString(aValue)}`
| EvDate(_) => `Date::${toString(aValue)}`
| EvTimeDuration(_) => `Date::${toString(aValue)}`
| EvDeclaration(_) => `Declaration::${toString(aValue)}`
| EvTypeIdentifier(_) => `TypeIdentifier::${toString(aValue)}`
| EvModule(_) => `Module::${toString(aValue)}`
}
let argsToString = (args: array<expressionValue>): string => {
let argsToString = (args: array<externalExpressionValue>): string => {
args->Js.Array2.map(arg => arg->toString)->Js.Array2.toString
}
@ -99,18 +83,6 @@ let toStringResult = x =>
| Error(m) => `Error(${ErrorValue.errorToString(m)})`
}
let toStringResultOkless = (codeResult: result<expressionValue, ErrorValue.errorValue>): string =>
switch codeResult {
| Ok(a) => toString(a)
| Error(m) => `Error(${ErrorValue.errorToString(m)})`
}
let toStringResultRecord = x =>
switch x {
| Ok(a) => `Ok(${toStringRecord(a)})`
| Error(m) => `Error(${ErrorValue.errorToString(m)})`
}
@genType
type environment = DistributionOperation.env
@ -141,14 +113,14 @@ type functionDefinitionSignature =
let valueToValueType = value =>
switch value {
| EvArray(_) => EvtArray
| EvArrayString(_) => EvtArray
| EvArrayString(_) => EvtArrayString
| EvBool(_) => EvtBool
| EvCall(_) => EvtCall
| EvDistribution(_) => EvtDistribution
| EvLambda(_) => EvtLambda
| EvNumber(_) => EvtNumber
| EvRecord(_) => EvtRecord
| EvString(_) => EvtArray
| EvString(_) => EvtString
| EvSymbol(_) => EvtSymbol
| EvDate(_) => EvtDate
| EvTimeDuration(_) => EvtTimeDuration

View File

@ -1,6 +1,6 @@
module ExpressionValue = ReducerInterface_ExpressionValue
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
type expressionValue = ExpressionValue.expressionValue
type internalExpressionValue = InternalExpressionValue.t
// module Sample = {
// // In real life real libraries should be somewhere else
@ -17,14 +17,14 @@ type expressionValue = ExpressionValue.expressionValue
// I expect that it's important to build this first, so it doesn't get recalculated for each tryRegistry() call.
let registry = FunctionRegistry_Library.registry
let tryRegistry = ((fnName, args): ExpressionValue.functionCall, env) => {
let tryRegistry = ((fnName, args): InternalExpressionValue.functionCall, env) => {
FunctionRegistry_Core.Registry.matchAndRun(~registry, ~fnName, ~args, ~env)->E.O2.fmap(
E.R2.errMap(_, s => Reducer_ErrorValue.RETodo(s)),
)
}
let dispatch = (call: ExpressionValue.functionCall, environment, chain): result<
expressionValue,
let dispatch = (call: InternalExpressionValue.functionCall, environment, chain): result<
internalExpressionValue,
'e,
> => {
E.A.O.firstSomeFn([

View File

@ -1,5 +1,5 @@
module ExpressionValue = ReducerInterface_ExpressionValue
type expressionValue = ExpressionValue.expressionValue
module IEV = ReducerInterface_InternalExpressionValue
type internalExpressionValue = IEV.t
module Helpers = {
let arithmeticMap = r =>
@ -18,14 +18,14 @@ module Helpers = {
| _ => #Multiply
}
let catchAndConvertTwoArgsToDists = (args: array<expressionValue>): option<(
let catchAndConvertTwoArgsToDists = (args: array<internalExpressionValue>): option<(
DistributionTypes.genericDist,
DistributionTypes.genericDist,
)> =>
switch args {
| [EvDistribution(a), EvDistribution(b)] => Some((a, b))
| [EvNumber(a), EvDistribution(b)] => Some((GenericDist.fromFloat(a), b))
| [EvDistribution(a), EvNumber(b)] => Some((a, GenericDist.fromFloat(b)))
| [IEvDistribution(a), IEvDistribution(b)] => Some((a, b))
| [IEvNumber(a), IEvDistribution(b)] => Some((GenericDist.fromFloat(a), b))
| [IEvDistribution(a), IEvNumber(b)] => Some((a, GenericDist.fromFloat(b)))
| _ => None
}
@ -80,23 +80,28 @@ module Helpers = {
)->DistributionOperation.run(~env)
}
let parseNumber = (args: expressionValue): Belt.Result.t<float, string> =>
let parseNumber = (args: internalExpressionValue): Belt.Result.t<float, string> =>
switch args {
| EvNumber(x) => Ok(x)
| IEvNumber(x) => Ok(x)
| _ => Error("Not a number")
}
let parseNumberArray = (ags: array<expressionValue>): Belt.Result.t<array<float>, string> =>
E.A.fmap(parseNumber, ags) |> E.A.R.firstErrorOrOpen
let parseNumberArray = (ags: array<internalExpressionValue>): Belt.Result.t<
array<float>,
string,
> => E.A.fmap(parseNumber, ags) |> E.A.R.firstErrorOrOpen
let parseDist = (args: expressionValue): Belt.Result.t<DistributionTypes.genericDist, string> =>
let parseDist = (args: internalExpressionValue): Belt.Result.t<
DistributionTypes.genericDist,
string,
> =>
switch args {
| EvDistribution(x) => Ok(x)
| EvNumber(x) => Ok(GenericDist.fromFloat(x))
| IEvDistribution(x) => Ok(x)
| IEvNumber(x) => Ok(GenericDist.fromFloat(x))
| _ => Error("Not a distribution")
}
let parseDistributionArray = (ags: array<expressionValue>): Belt.Result.t<
let parseDistributionArray = (ags: array<internalExpressionValue>): Belt.Result.t<
array<DistributionTypes.genericDist>,
string,
> => E.A.fmap(parseDist, ags) |> E.A.R.firstErrorOrOpen
@ -122,18 +127,18 @@ module Helpers = {
}
let mixture = (
args: array<expressionValue>,
args: array<internalExpressionValue>,
~env: DistributionOperation.env,
): DistributionOperation.outputType => {
let error = (err: string): DistributionOperation.outputType =>
err->DistributionTypes.ArgumentError->GenDistError
switch args {
| [EvArray(distributions)] =>
| [IEvArray(distributions)] =>
switch parseDistributionArray(distributions) {
| Ok(distrs) => mixtureWithDefaultWeights(distrs, ~env)
| Error(err) => error(err)
}
| [EvArray(distributions), EvArray(weights)] =>
| [IEvArray(distributions), IEvArray(weights)] =>
switch (parseDistributionArray(distributions), parseNumberArray(weights)) {
| (Ok(distrs), Ok(wghts)) => mixtureWithGivenWeights(distrs, wghts, ~env)
| (Error(err), Ok(_)) => error(err)
@ -142,7 +147,7 @@ module Helpers = {
}
| _ =>
switch E.A.last(args) {
| Some(EvArray(b)) => {
| Some(IEvArray(b)) => {
let weights = parseNumberArray(b)
let distributions = parseDistributionArray(
Belt.Array.slice(args, ~offset=0, ~len=E.A.length(args) - 1),
@ -152,8 +157,8 @@ module Helpers = {
| Error(err) => error(err)
}
}
| Some(EvNumber(_))
| Some(EvDistribution(_)) =>
| Some(IEvNumber(_))
| Some(IEvDistribution(_)) =>
switch parseDistributionArray(args) {
| Ok(distributions) => mixtureWithDefaultWeights(distributions, ~env)
| Error(err) => error(err)
@ -180,20 +185,19 @@ module SymbolicConstructors = {
}
}
let dispatchToGenericOutput = (
call: ExpressionValue.functionCall,
env: DistributionOperation.env,
): option<DistributionOperation.outputType> => {
let dispatchToGenericOutput = (call: IEV.functionCall, env: DistributionOperation.env): option<
DistributionOperation.outputType,
> => {
let (fnName, args) = call
switch (fnName, args) {
| ("triangular" as fnName, [EvNumber(f1), EvNumber(f2), EvNumber(f3)]) =>
| ("triangular" as fnName, [IEvNumber(f1), IEvNumber(f2), IEvNumber(f3)]) =>
SymbolicConstructors.threeFloat(fnName)
->E.R.bind(r => r(f1, f2, f3))
->SymbolicConstructors.symbolicResultToOutput
| ("sample", [EvDistribution(dist)]) => Helpers.toFloatFn(#Sample, dist, ~env)
| ("sampleN", [EvDistribution(dist), EvNumber(n)]) =>
| ("sample", [IEvDistribution(dist)]) => Helpers.toFloatFn(#Sample, dist, ~env)
| ("sampleN", [IEvDistribution(dist), IEvNumber(n)]) =>
Some(FloatArray(GenericDist.sampleN(dist, Belt.Int.fromFloat(n))))
| (("mean" | "stdev" | "variance" | "min" | "max" | "mode") as op, [EvDistribution(dist)]) => {
| (("mean" | "stdev" | "variance" | "min" | "max" | "mode") as op, [IEvDistribution(dist)]) => {
let fn = switch op {
| "mean" => #Mean
| "stdev" => #Stdev
@ -205,13 +209,13 @@ let dispatchToGenericOutput = (
}
Helpers.toFloatFn(fn, dist, ~env)
}
| ("integralSum", [EvDistribution(dist)]) => Helpers.toFloatFn(#IntegralSum, dist, ~env)
| ("toString", [EvDistribution(dist)]) => Helpers.toStringFn(ToString, dist, ~env)
| ("sparkline", [EvDistribution(dist)]) =>
| ("integralSum", [IEvDistribution(dist)]) => Helpers.toFloatFn(#IntegralSum, dist, ~env)
| ("toString", [IEvDistribution(dist)]) => Helpers.toStringFn(ToString, dist, ~env)
| ("sparkline", [IEvDistribution(dist)]) =>
Helpers.toStringFn(ToSparkline(MagicNumbers.Environment.sparklineLength), dist, ~env)
| ("sparkline", [EvDistribution(dist), EvNumber(n)]) =>
| ("sparkline", [IEvDistribution(dist), IEvNumber(n)]) =>
Helpers.toStringFn(ToSparkline(Belt.Float.toInt(n)), dist, ~env)
| ("exp", [EvDistribution(a)]) =>
| ("exp", [IEvDistribution(a)]) =>
// https://mathjs.org/docs/reference/functions/exp.html
Helpers.twoDiststoDistFn(
Algebraic(AsDefault),
@ -220,47 +224,66 @@ let dispatchToGenericOutput = (
a,
~env,
)->Some
| ("normalize", [EvDistribution(dist)]) => Helpers.toDistFn(Normalize, dist, ~env)
| ("klDivergence", [EvDistribution(estimate), EvDistribution(answer)]) =>
Some(
DistributionOperation.run(
FromDist(ToScore(LogScore(Score_Dist(answer), None)), estimate),
~env,
),
)
| ("klDivergence", [EvDistribution(estimate), EvDistribution(answer), EvDistribution(prior)]) =>
Some(
DistributionOperation.run(
FromDist(ToScore(LogScore(Score_Dist(answer), Some(Score_Dist(prior)))), estimate),
~env,
),
)
| ("isNormalized", [EvDistribution(dist)]) => Helpers.toBoolFn(IsNormalized, dist, ~env)
| ("toPointSet", [EvDistribution(dist)]) => Helpers.toDistFn(ToPointSet, dist, ~env)
| ("scaleLog", [EvDistribution(dist)]) =>
| ("normalize", [IEvDistribution(dist)]) => Helpers.toDistFn(Normalize, dist, ~env)
| ("klDivergence", [IEvDistribution(prediction), IEvDistribution(answer)]) =>
Some(DistributionOperation.run(FromDist(ToScore(LogScore(Score_Dist(answer), None), prediction), ~env))
| (
"klDivergence",
[IEvDistribution(prediction), IEvDistribution(answer), IEvDistribution(prior)],
) =>
Some(
DistributionOperation.run(
FromDist(ToScore(LogScore(Score_Dist(answer), Some(Score_Dist(prior)))), estimate), ~env
)
)
| (
"logScoreWithPointAnswer",
[IEvDistribution(prediction), IEvNumber(answer), IEvDistribution(prior)],
)
| (
"logScoreWithPointAnswer",
[
IEvDistribution(prediction),
IEvDistribution(Symbolic(#Float(answer))),
IEvDistribution(prior),
],
) =>
DistributionOperation.run(
FromDist(ToScore(LogScore(answer, prior->Some)), prediction),
~env,
)->Some
| ("logScoreWithPointAnswer", [IEvDistribution(prediction), IEvNumber(answer)])
| (
"logScoreWithPointAnswer",
[IEvDistribution(prediction), IEvDistribution(Symbolic(#Float(answer)))],
) =>
DistributionOperation.run(FromDist(ToScore(LogScore(answer, None)), prediction), ~env)->Some
| ("isNormalized", [IEvDistribution(dist)]) => Helpers.toBoolFn(IsNormalized, dist, ~env)
| ("toPointSet", [IEvDistribution(dist)]) => Helpers.toDistFn(ToPointSet, dist, ~env)
| ("scaleLog", [IEvDistribution(dist)]) =>
Helpers.toDistFn(Scale(#Logarithm, MagicNumbers.Math.e), dist, ~env)
| ("scaleLog10", [EvDistribution(dist)]) => Helpers.toDistFn(Scale(#Logarithm, 10.0), dist, ~env)
| ("scaleLog", [EvDistribution(dist), EvNumber(float)]) =>
| ("scaleLog10", [IEvDistribution(dist)]) => Helpers.toDistFn(Scale(#Logarithm, 10.0), dist, ~env)
| ("scaleLog", [IEvDistribution(dist), IEvNumber(float)]) =>
Helpers.toDistFn(Scale(#Logarithm, float), dist, ~env)
| ("scaleLogWithThreshold", [EvDistribution(dist), EvNumber(base), EvNumber(eps)]) =>
| ("scaleLogWithThreshold", [IEvDistribution(dist), IEvNumber(base), IEvNumber(eps)]) =>
Helpers.toDistFn(Scale(#LogarithmWithThreshold(eps), base), dist, ~env)
| ("scaleMultiply", [EvDistribution(dist), EvNumber(float)]) =>
| ("scaleMultiply", [IEvDistribution(dist), IEvNumber(float)]) =>
Helpers.toDistFn(Scale(#Multiply, float), dist, ~env)
| ("scalePow", [EvDistribution(dist), EvNumber(float)]) =>
| ("scalePow", [IEvDistribution(dist), IEvNumber(float)]) =>
Helpers.toDistFn(Scale(#Power, float), dist, ~env)
| ("scaleExp", [EvDistribution(dist)]) =>
| ("scaleExp", [IEvDistribution(dist)]) =>
Helpers.toDistFn(Scale(#Power, MagicNumbers.Math.e), dist, ~env)
| ("cdf", [EvDistribution(dist), EvNumber(float)]) => Helpers.toFloatFn(#Cdf(float), dist, ~env)
| ("pdf", [EvDistribution(dist), EvNumber(float)]) => Helpers.toFloatFn(#Pdf(float), dist, ~env)
| ("inv", [EvDistribution(dist), EvNumber(float)]) => Helpers.toFloatFn(#Inv(float), dist, ~env)
| ("quantile", [EvDistribution(dist), EvNumber(float)]) =>
| ("cdf", [IEvDistribution(dist), IEvNumber(float)]) => Helpers.toFloatFn(#Cdf(float), dist, ~env)
| ("pdf", [IEvDistribution(dist), IEvNumber(float)]) => Helpers.toFloatFn(#Pdf(float), dist, ~env)
| ("inv", [IEvDistribution(dist), IEvNumber(float)]) => Helpers.toFloatFn(#Inv(float), dist, ~env)
| ("quantile", [IEvDistribution(dist), IEvNumber(float)]) =>
Helpers.toFloatFn(#Inv(float), dist, ~env)
| ("toSampleSet", [EvDistribution(dist), EvNumber(float)]) =>
| ("toSampleSet", [IEvDistribution(dist), IEvNumber(float)]) =>
Helpers.toDistFn(ToSampleSet(Belt.Int.fromFloat(float)), dist, ~env)
| ("toSampleSet", [EvDistribution(dist)]) =>
| ("toSampleSet", [IEvDistribution(dist)]) =>
Helpers.toDistFn(ToSampleSet(env.sampleCount), dist, ~env)
| ("toList", [EvDistribution(SampleSet(dist))]) => Some(FloatArray(SampleSetDist.T.get(dist)))
| ("fromSamples", [EvArray(inputArray)]) => {
| ("toList", [IEvDistribution(SampleSet(dist))]) => Some(FloatArray(SampleSetDist.T.get(dist)))
| ("fromSamples", [IEvArray(inputArray)]) => {
let _wrapInputErrors = x => SampleSetDist.NonNumericInput(x)
let parsedArray = Helpers.parseNumberArray(inputArray)->E.R2.errMap(_wrapInputErrors)
switch parsedArray {
@ -268,15 +291,15 @@ let dispatchToGenericOutput = (
| Error(e) => GenDistError(SampleSetError(e))
}->Some
}
| ("inspect", [EvDistribution(dist)]) => Helpers.toDistFn(Inspect, dist, ~env)
| ("truncateLeft", [EvDistribution(dist), EvNumber(float)]) =>
| ("inspect", [IEvDistribution(dist)]) => Helpers.toDistFn(Inspect, dist, ~env)
| ("truncateLeft", [IEvDistribution(dist), IEvNumber(float)]) =>
Helpers.toDistFn(Truncate(Some(float), None), dist, ~env)
| ("truncateRight", [EvDistribution(dist), EvNumber(float)]) =>
| ("truncateRight", [IEvDistribution(dist), IEvNumber(float)]) =>
Helpers.toDistFn(Truncate(None, Some(float)), dist, ~env)
| ("truncate", [EvDistribution(dist), EvNumber(float1), EvNumber(float2)]) =>
| ("truncate", [IEvDistribution(dist), IEvNumber(float1), IEvNumber(float2)]) =>
Helpers.toDistFn(Truncate(Some(float1), Some(float2)), dist, ~env)
| ("mx" | "mixture", args) => Helpers.mixture(args, ~env)->Some
| ("log", [EvDistribution(a)]) =>
| ("log", [IEvDistribution(a)]) =>
Helpers.twoDiststoDistFn(
Algebraic(AsDefault),
"log",
@ -284,7 +307,7 @@ let dispatchToGenericOutput = (
GenericDist.fromFloat(MagicNumbers.Math.e),
~env,
)->Some
| ("log10", [EvDistribution(a)]) =>
| ("log10", [IEvDistribution(a)]) =>
Helpers.twoDiststoDistFn(
Algebraic(AsDefault),
"log",
@ -292,7 +315,7 @@ let dispatchToGenericOutput = (
GenericDist.fromFloat(10.0),
~env,
)->Some
| ("unaryMinus", [EvDistribution(a)]) =>
| ("unaryMinus", [IEvDistribution(a)]) =>
Helpers.twoDiststoDistFn(
Algebraic(AsDefault),
"multiply",
@ -315,7 +338,7 @@ let dispatchToGenericOutput = (
Helpers.catchAndConvertTwoArgsToDists(args)->E.O2.fmap(((fst, snd)) =>
Helpers.twoDiststoDistFn(Pointwise, arithmetic, fst, snd, ~env)
)
| ("dotExp", [EvDistribution(a)]) =>
| ("dotExp", [IEvDistribution(a)]) =>
Helpers.twoDiststoDistFn(
Pointwise,
"dotPow",
@ -328,17 +351,18 @@ let dispatchToGenericOutput = (
}
let genericOutputToReducerValue = (o: DistributionOperation.outputType): result<
expressionValue,
internalExpressionValue,
Reducer_ErrorValue.errorValue,
> =>
switch o {
| Dist(d) => Ok(ReducerInterface_ExpressionValue.EvDistribution(d))
| Float(d) => Ok(EvNumber(d))
| String(d) => Ok(EvString(d))
| Bool(d) => Ok(EvBool(d))
| FloatArray(d) => Ok(EvArray(d |> E.A.fmap(r => ReducerInterface_ExpressionValue.EvNumber(r))))
| Dist(d) => Ok(ReducerInterface_InternalExpressionValue.IEvDistribution(d))
| Float(d) => Ok(IEvNumber(d))
| String(d) => Ok(IEvString(d))
| Bool(d) => Ok(IEvBool(d))
| FloatArray(d) =>
Ok(IEvArray(d |> E.A.fmap(r => ReducerInterface_InternalExpressionValue.IEvNumber(r))))
| GenDistError(err) => Error(REDistributionError(err))
}
let dispatch = (call: ExpressionValue.functionCall, environment) =>
let dispatch = (call: IEV.functionCall, environment) =>
dispatchToGenericOutput(call, environment)->E.O2.fmap(genericOutputToReducerValue)

View File

@ -1,4 +1,4 @@
let dispatch: (
ReducerInterface_ExpressionValue.functionCall,
ReducerInterface_ExpressionValue.environment,
) => option<result<ReducerInterface_ExpressionValue.expressionValue, Reducer_ErrorValue.errorValue>>
ReducerInterface_InternalExpressionValue.functionCall,
ReducerInterface_ExternalExpressionValue.environment,
) => option<result<ReducerInterface_InternalExpressionValue.t, Reducer_ErrorValue.errorValue>>

View File

@ -0,0 +1,259 @@
module ErrorValue = Reducer_ErrorValue
module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue
module Extra_Array = Reducer_Extra_Array
type internalCode = ExternalExpressionValue.internalCode
type environment = ExternalExpressionValue.environment
let defaultEnvironment = ExternalExpressionValue.defaultEnvironment
type rec t =
| IEvArray(array<t>) // FIXME: Convert
| IEvArrayString(array<string>) // FIXME: Convert
| IEvBool(bool)
| IEvCall(string) // External function call
| IEvDate(Js.Date.t)
| IEvDeclaration(lambdaDeclaration)
| IEvDistribution(DistributionTypes.genericDist)
| IEvLambda(lambdaValue)
| IEvModule(nameSpace)
| IEvNumber(float)
| IEvRecord(map)
| IEvString(string)
| IEvSymbol(string)
| IEvTimeDuration(float)
| IEvTypeIdentifier(string)
and map = Belt.Map.String.t<t>
and nameSpace = NameSpace(Belt.Map.String.t<t>)
and lambdaValue = {
parameters: array<string>,
context: nameSpace,
body: internalCode,
}
and lambdaDeclaration = Declaration.declaration<lambdaValue>
type internalExpressionValue = t
type functionCall = (string, array<t>)
let rec toString = aValue =>
switch aValue {
| IEvArray(anArray) => {
let args = anArray->Js.Array2.map(each => toString(each))->Js.Array2.toString
`[${args}]`
}
| IEvArrayString(anArray) => {
let args = anArray->Js.Array2.toString
`[${args}]`
}
| IEvBool(aBool) => Js.String.make(aBool)
| IEvCall(fName) => `:${fName}`
| IEvDate(date) => DateTime.Date.toString(date)
| IEvDeclaration(d) => Declaration.toString(d, r => toString(IEvLambda(r)))
| IEvDistribution(dist) => GenericDist.toString(dist)
| IEvLambda(lambdaValue) => `lambda(${Js.Array2.toString(lambdaValue.parameters)}=>internal code)`
| IEvModule(m) => `@${m->toStringNameSpace}`
| IEvNumber(aNumber) => Js.String.make(aNumber)
| IEvRecord(aMap) => aMap->toStringMap
| IEvString(aString) => `'${aString}'`
| IEvSymbol(aString) => `:${aString}`
| IEvTimeDuration(t) => DateTime.Duration.toString(t)
| IEvTypeIdentifier(id) => `#${id}`
}
and toStringMap = aMap => {
let pairs =
aMap
->Belt.Map.String.toArray
->Js.Array2.map(((eachKey, eachValue)) => `${eachKey}: ${toString(eachValue)}`)
->Js.Array2.toString
`{${pairs}}`
}
and toStringNameSpace = nameSpace => {
let NameSpace(container) = nameSpace
container->toStringMap
}
let toStringWithType = aValue =>
switch aValue {
| IEvArray(_) => `Array::${toString(aValue)}`
| IEvArrayString(_) => `ArrayString::${toString(aValue)}`
| IEvBool(_) => `Bool::${toString(aValue)}`
| IEvCall(_) => `Call::${toString(aValue)}`
| IEvDistribution(_) => `Distribution::${toString(aValue)}`
| IEvLambda(_) => `Lambda::${toString(aValue)}`
| IEvNumber(_) => `Number::${toString(aValue)}`
| IEvRecord(_) => `Record::${toString(aValue)}`
| IEvString(_) => `String::${toString(aValue)}`
| IEvSymbol(_) => `Symbol::${toString(aValue)}`
| IEvDate(_) => `Date::${toString(aValue)}`
| IEvTimeDuration(_) => `Date::${toString(aValue)}`
| IEvDeclaration(_) => `Declaration::${toString(aValue)}`
| IEvTypeIdentifier(_) => `TypeIdentifier::${toString(aValue)}`
| IEvModule(_) => `Module::${toString(aValue)}`
}
let argsToString = (args: array<t>): 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 toStringResultOkless = (codeResult: result<t, ErrorValue.errorValue>): string =>
switch codeResult {
| Ok(a) => toString(a)
| Error(m) => `Error(${ErrorValue.errorToString(m)})`
}
let toStringResultRecord = x =>
switch x {
| Ok(a) => `Ok(${ExternalExpressionValue.toStringRecord(a)})`
| Error(m) => `Error(${ErrorValue.errorToString(m)})`
}
type internalExpressionValueType =
| EvtArray
| EvtArrayString
| EvtBool
| EvtCall
| EvtDistribution
| EvtLambda
| EvtNumber
| EvtRecord
| EvtString
| EvtSymbol
| EvtDate
| EvtTimeDuration
| EvtDeclaration
| EvtTypeIdentifier
| EvtModule
type functionCallSignature = CallSignature(string, array<internalExpressionValueType>)
type functionDefinitionSignature =
FunctionDefinitionSignature(functionCallSignature, internalExpressionValueType)
let valueToValueType = value =>
switch value {
| IEvArray(_) => EvtArray
| IEvArrayString(_) => EvtArrayString
| IEvBool(_) => EvtBool
| IEvCall(_) => EvtCall
| IEvDistribution(_) => EvtDistribution
| IEvLambda(_) => EvtLambda
| IEvNumber(_) => EvtNumber
| IEvRecord(_) => EvtRecord
| IEvString(_) => EvtString
| IEvSymbol(_) => EvtSymbol
| IEvDate(_) => EvtDate
| IEvTimeDuration(_) => EvtTimeDuration
| IEvDeclaration(_) => EvtDeclaration
| IEvTypeIdentifier(_) => EvtTypeIdentifier
| IEvModule(_) => EvtModule
}
let functionCallToCallSignature = (functionCall: functionCall): functionCallSignature => {
let (fn, args) = functionCall
CallSignature(fn, args->Js.Array2.map(valueToValueType))
}
let valueTypeToString = (valueType: internalExpressionValueType): string =>
switch valueType {
| EvtArray => `Array`
| EvtArrayString => `ArrayString`
| EvtBool => `Bool`
| EvtCall => `Call`
| EvtDistribution => `Distribution`
| EvtLambda => `Lambda`
| EvtNumber => `Number`
| EvtRecord => `Record`
| EvtString => `String`
| EvtSymbol => `Symbol`
| EvtDate => `Date`
| EvtTimeDuration => `Duration`
| EvtDeclaration => `Declaration`
| EvtTypeIdentifier => `TypeIdentifier`
| EvtModule => `Module`
}
let functionCallSignatureToString = (functionCallSignature: functionCallSignature): string => {
let CallSignature(fn, args) = functionCallSignature
`${fn}(${args->Js.Array2.map(valueTypeToString)->Js.Array2.toString})`
}
let rec toExternal = (iev: t): 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)
| 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)
| IEvDeclaration(v) => {
let fn = lambdaValueToExternal(v.fn)
let args = v.args
EvDeclaration({fn: fn, args: args})
}
| IEvTypeIdentifier(v) => EvTypeIdentifier(v)
| IEvModule(v) => v->nameSpaceToTypeScriptBindings->EvModule
}
}
and mapToExternal = v =>
v->Belt.Map.String.map(e => toExternal(e))->Belt.Map.String.toArray->Js.Dict.fromArray
and lambdaValueToExternal = v => {
let p = v.parameters
let c = v.context->nameSpaceToTypeScriptBindings
let b = v.body
{parameters: p, context: c, body: b}
}
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: 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)
| EvDistribution(v) => IEvDistribution(v)
| EvLambda(v) => IEvLambda(lambdaValueToInternal(v))
| EvNumber(v) => IEvNumber(v)
| EvRecord(v) => v->recordToInternal->IEvRecord
| EvString(v) => IEvString(v)
| EvSymbol(v) => IEvSymbol(v)
| EvDate(v) => IEvDate(v)
| EvTimeDuration(v) => IEvTimeDuration(v)
| EvDeclaration(v) => {
let fn = lambdaValueToInternal(v.fn)
let args = v.args
IEvDeclaration({fn: fn, args: args})
}
| EvTypeIdentifier(v) => IEvTypeIdentifier(v)
| EvModule(v) => v->nameSpaceFromTypeScriptBindings->IEvModule
}
}
and recordToInternal = v =>
v->Js.Dict.entries->Belt.Map.String.fromArray->Belt.Map.String.map(e => toInternal(e))
and lambdaValueToInternal = v => {
let p = v.parameters
let c = v.context->nameSpaceFromTypeScriptBindings
let b = v.body
{parameters: p, context: c, body: b}
}
and nameSpaceFromTypeScriptBindings = (
r: ReducerInterface_ExternalExpressionValue.externalBindings,
): nameSpace =>
r->Js.Dict.entries->Belt.Map.String.fromArray->Belt.Map.String.map(e => toInternal(e))->NameSpace

View File

@ -1,5 +1,5 @@
module EV = ReducerInterface_ExpressionValue
type expressionValue = EV.expressionValue
module IEV = ReducerInterface_InternalExpressionValue
type internalExpressionValue = IEV.t
module ScientificUnit = {
let nameToMultiplier = str =>
@ -24,8 +24,8 @@ module ScientificUnit = {
}
}
let dispatch = (call: EV.functionCall, _: DistributionOperation.env): option<
result<expressionValue, QuriSquiggleLang.Reducer_ErrorValue.errorValue>,
let dispatch = (call: IEV.functionCall, _: DistributionOperation.env): option<
result<internalExpressionValue, QuriSquiggleLang.Reducer_ErrorValue.errorValue>,
> => {
switch call {
| (
@ -37,9 +37,9 @@ let dispatch = (call: EV.functionCall, _: DistributionOperation.env): option<
| "fromUnit_G"
| "fromUnit_T"
| "fromUnit_P") as op,
[EvNumber(f)],
[IEvNumber(f)],
) =>
op->ScientificUnit.getMultiplier->E.O2.fmap(multiplier => EV.EvNumber(f *. multiplier)->Ok)
op->ScientificUnit.getMultiplier->E.O2.fmap(multiplier => IEV.IEvNumber(f *. multiplier)->Ok)
| _ => None
}
}

View File

@ -1,6 +1,6 @@
module Bindings = Reducer_Category_Bindings
module Module = Reducer_Category_Module
let internalStdLib = Bindings.emptyBindings->SquiggleLibrary_Math.makeBindings
let internalStdLib = Module.emptyModule->SquiggleLibrary_Math.makeBindings
@genType
let externalStdLib = internalStdLib->Bindings.toRecord
let externalStdLib = internalStdLib->Module.toTypeScriptBindings

View File

@ -1,4 +1,4 @@
module Bindings = Reducer_Category_Bindings
module Bindings = Reducer_Category_Module
module Module = Reducer_Category_Module
let availableNumbers: array<(string, float)> = [
@ -14,10 +14,10 @@ let availableNumbers: array<(string, float)> = [
("tau", 6.283185307179586),
]
let mathBindings: Bindings.ExpressionT.bindings =
let mathBindings: Bindings.t =
availableNumbers
->E.A2.fmap(((name, v)) => (name, ReducerInterface_ExpressionValue.EvNumber(v)))
->Belt.Map.String.fromArray
->E.A2.fmap(((name, v)) => (name, ReducerInterface_InternalExpressionValue.IEvNumber(v)))
->Bindings.fromArray
let makeBindings = (previousBindings: Bindings.t): Bindings.t =>
previousBindings->Bindings.defineModule("Math", mathBindings)

View File

@ -40,6 +40,9 @@ let evaluate = Reducer.evaluate
@genType
let evaluateUsingOptions = Reducer.evaluateUsingOptions
@genType
let parse = Reducer_Peggy_Parse.parse
@genType
let evaluatePartialUsingExternalBindings = Reducer.evaluatePartialUsingExternalBindings
@ -47,10 +50,10 @@ let evaluatePartialUsingExternalBindings = Reducer.evaluatePartialUsingExternalB
type externalBindings = Reducer.externalBindings
@genType
type expressionValue = ReducerInterface_ExpressionValue.expressionValue
type expressionValue = ReducerInterface_ExternalExpressionValue.t
@genType
type recordEV = ReducerInterface_ExpressionValue.record
type recordEV = ReducerInterface_ExternalExpressionValue.record
@genType
type errorValue = Reducer_ErrorValue.errorValue
@ -74,19 +77,19 @@ let errorValueToString = Reducer_ErrorValue.errorToString
let distributionErrorToString = DistributionTypes.Error.toString
@genType
type lambdaValue = ReducerInterface_ExpressionValue.lambdaValue
type lambdaValue = ReducerInterface_ExternalExpressionValue.lambdaValue
@genType
type lambdaDeclaration = ReducerInterface_ExpressionValue.lambdaDeclaration
type lambdaDeclaration = ReducerInterface_ExternalExpressionValue.lambdaDeclaration
@genType
let defaultSamplingEnv = DistributionOperation.defaultEnv
@genType
type environment = ReducerInterface_ExpressionValue.environment
type environment = ReducerInterface_ExternalExpressionValue.environment
@genType
let defaultEnvironment = ReducerInterface_ExpressionValue.defaultEnvironment
let defaultEnvironment = ReducerInterface_ExternalExpressionValue.defaultEnvironment
@genType
let foreignFunctionInterface = Reducer.foreignFunctionInterface

View File

@ -1,4 +1,5 @@
/media/vendor
/out
/client/out
/server/out
/*.vsix
/syntaxes/*.json

View File

@ -0,0 +1,60 @@
import * as path from "path";
import * as vscode from "vscode";
import {
LanguageClient,
LanguageClientOptions,
ServerOptions,
TransportKind,
} from "vscode-languageclient/node";
let client: LanguageClient;
export const startClient = (context: vscode.ExtensionContext) => {
// The server is implemented in node
let serverModule = context.asAbsolutePath(
path.join("server", "out", "server.js")
);
// The debug options for the server
// --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging
let debugOptions = { execArgv: ["--nolazy" /*"--inspect=6009"*/] };
// If the extension is launched in debug mode then the debug server options are used
// Otherwise the run options are used
let serverOptions: ServerOptions = {
run: { module: serverModule, transport: TransportKind.ipc },
debug: {
module: serverModule,
transport: TransportKind.ipc,
options: debugOptions,
},
};
// Options to control the language client
let clientOptions: LanguageClientOptions = {
// Register the server for plain text documents
documentSelector: [{ scheme: "file", language: "squiggle" }],
synchronize: {
// Notify the server about file changes to '.clientrc files contained in the workspace
fileEvents: vscode.workspace.createFileSystemWatcher("**/.clientrc"),
},
};
// Create the language client and start the client.
client = new LanguageClient(
"squiggleServer",
"Squiggle Server",
serverOptions,
clientOptions
);
// Start the client. This will also launch the server
client.start();
};
export const stopClient = () => {
if (!client) {
return undefined;
}
return client.stop();
};

View File

@ -1,6 +1,7 @@
// The module 'vscode' contains the VS Code extensibility API
// Import the module and reference it with the alias vscode in your code below
import * as vscode from "vscode";
import { startClient, stopClient } from "./client";
import { SquiggleEditorProvider } from "./editor";
import { registerPreviewCommand } from "./preview";
@ -11,7 +12,11 @@ export function activate(context: vscode.ExtensionContext) {
context.subscriptions.push(SquiggleEditorProvider.register(context));
registerPreviewCommand(context);
startClient(context);
}
// this method is called when your extension is deactivated
export function deactivate() {}
export function deactivate() {
stopClient();
}

View File

@ -0,0 +1,12 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2020",
"lib": ["ES2020", "dom"],
"outDir": "out",
"rootDir": "src",
"sourceMap": true
},
"include": ["src"],
"exclude": ["node_modules", ".vscode-test"]
}

View File

@ -3,7 +3,7 @@
"displayName": "Squiggle",
"description": "Squiggle language support",
"license": "MIT",
"version": "0.1.2",
"version": "0.2.0",
"publisher": "QURI",
"repository": {
"type": "git",
@ -18,10 +18,11 @@
"Visualization"
],
"activationEvents": [
"onLanguage:squiggle",
"onCustomEditor:squiggle.wysiwyg",
"onCommand:squiggle.preview"
],
"main": "./out/extension.js",
"main": "./client/out/extension.js",
"contributes": {
"languages": [
{
@ -124,14 +125,15 @@
},
"scripts": {
"vscode:prepublish": "yarn run compile",
"compile:tsc": "tsc -p ./",
"compile:tsc": "tsc -b",
"compile:grammar": "js-yaml syntaxes/squiggle.tmLanguage.yaml >syntaxes/squiggle.tmLanguage.json",
"compile:vendor": "(cd ../squiggle-lang && yarn run build) && (cd ../components && yarn run bundle && yarn run build:css) && mkdir -p media/vendor && cp ../components/dist/bundle.js media/vendor/components.js && cp ../components/dist/main.css media/vendor/components.css && cp ../../node_modules/react/umd/react.production.min.js media/vendor/react.js && cp ../../node_modules/react-dom/umd/react-dom.production.min.js media/vendor/react-dom.js && cp ../website/static/img/quri-logo.png media/vendor/icon.png",
"compile": "yarn run compile:tsc && yarn run compile:grammar && yarn run compile:vendor",
"watch": "tsc -watch -p ./",
"compile": "yarn run compile:vendor && yarn run compile:grammar && yarn run compile:tsc",
"watch": "tsc -b -watch",
"pretest": "yarn run compile && yarn run lint",
"lint": "eslint src --ext ts",
"format": "eslint src --ext ts --fix"
"lint": "eslint client/src server/src --ext ts",
"format": "eslint client/src server/src --ext ts --fix",
"package": "npx vsce package --yarn"
},
"devDependencies": {
"@types/glob": "^7.2.0",
@ -142,6 +144,13 @@
"eslint": "^8.18.0",
"glob": "^8.0.3",
"js-yaml": "^4.1.0",
"typescript": "^4.7.4"
"typescript": "^4.7.4",
"vsce-yarn-patch": "^1.66.2"
},
"dependencies": {
"vscode-languageclient": "^8.0.1",
"vscode-languageserver": "^7.0.0",
"vscode-languageserver-textdocument": "^1.0.5",
"@quri/squiggle-lang": "^0.2.11"
}
}

View File

@ -0,0 +1,80 @@
import {
createConnection,
TextDocuments,
Diagnostic,
DiagnosticSeverity,
ProposedFeatures,
InitializeParams,
TextDocumentSyncKind,
InitializeResult,
} from "vscode-languageserver/node";
import { parse } from "@quri/squiggle-lang";
import { TextDocument } from "vscode-languageserver-textdocument";
// Create a connection for the server, using Node's IPC as a transport.
// Also include all preview / proposed LSP features.
let connection = createConnection(ProposedFeatures.all);
const documents: TextDocuments<TextDocument> = new TextDocuments(TextDocument);
documents.onDidChangeContent((change) => {
validateSquiggleDocument(change.document);
});
let hasDiagnosticRelatedInformationCapability = false;
connection.onInitialize((params: InitializeParams) => {
const capabilities = params.capabilities;
hasDiagnosticRelatedInformationCapability = !!(
capabilities.textDocument &&
capabilities.textDocument.publishDiagnostics &&
capabilities.textDocument.publishDiagnostics.relatedInformation
);
const result: InitializeResult = {
capabilities: {
textDocumentSync: TextDocumentSyncKind.Incremental,
},
};
return result;
});
async function validateSquiggleDocument(
textDocument: TextDocument
): Promise<void> {
const text = textDocument.getText();
const diagnostics: Diagnostic[] = [];
const parseResult = parse(text);
if (parseResult.tag === "Error") {
const location = parseResult.value.value[1];
diagnostics.push({
severity: DiagnosticSeverity.Error,
range: {
start: {
line: location.start.line - 1,
character: location.start.column - 1,
},
end: {
line: location.end.line - 1,
character: location.end.column - 1,
},
},
message: parseResult.value.value[0],
});
}
// Send the computed diagnostics to VSCode.
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
}
// Make the text document manager listen on the connection
// for open, change and close text document events
documents.listen(connection);
// Listen on the connection
connection.listen();

View File

@ -0,0 +1,12 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2020",
"lib": ["ES2020", "dom"],
"outDir": "out",
"rootDir": "src",
"sourceMap": true
},
"include": ["src"],
"exclude": ["node_modules"]
}

View File

@ -1,15 +1,13 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "ES2020",
"target": "es2020",
"lib": ["es2020", "dom"],
"outDir": "out",
"lib": ["ES2020", "dom"],
"sourceMap": true,
"rootDir": "src",
"strict": true /* enable all strict type-checking options */
/* Additional Checks */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */
}
"sourceMap": true
},
"include": ["src"],
"exclude": ["node_modules", ".vscode-test"],
"references": [{ "path": "./client" }, { "path": "./server" }]
}

File diff suppressed because it is too large Load Diff

250
yarn.lock
View File

@ -2336,6 +2336,11 @@
"@react-hook/passive-layout-effect" "^1.2.0"
"@react-hook/resize-observer" "^1.2.1"
"@rescript/std@^9.1.4":
version "9.1.4"
resolved "https://registry.yarnpkg.com/@rescript/std/-/std-9.1.4.tgz#94971cb504b10d36d470618fa1c6f0a2d03a6b9b"
integrity sha512-OHBORysVe6vmyllL24S2sXiwLGrpVRbZW5k2FverbjY3QF81VoyCRYL6kMOSNMEn9GseO/oDubK8+nvVzCSVMA==
"@rollup/plugin-babel@^5.2.0":
version "5.3.1"
resolved "https://registry.yarnpkg.com/@rollup/plugin-babel/-/plugin-babel-5.3.1.tgz#04bc0608f4aa4b2e4b1aebf284344d0f68fda283"
@ -5497,6 +5502,16 @@ axobject-query@^2.2.0:
resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-2.2.0.tgz#943d47e10c0b704aa42275e20edf3722648989be"
integrity sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==
azure-devops-node-api@^7.2.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/azure-devops-node-api/-/azure-devops-node-api-7.2.0.tgz#131d4e01cf12ebc6e45569b5e0c5c249e4114d6d"
integrity sha512-pMfGJ6gAQ7LRKTHgiRF+8iaUUeGAI0c8puLaqHLc7B8AR7W6GJLozK9RFeUHFjEGybC9/EB3r67WPd7e46zQ8w==
dependencies:
os "0.1.1"
tunnel "0.0.4"
typed-rest-client "1.2.0"
underscore "1.8.3"
babel-code-frame@^6.26.0:
version "6.26.0"
resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b"
@ -6073,6 +6088,11 @@ bser@2.1.1:
dependencies:
node-int64 "^0.4.0"
buffer-crc32@~0.2.3:
version "0.2.13"
resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242"
integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==
buffer-from@^1.0.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
@ -6310,7 +6330,7 @@ chalk@^1.1.3:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
chalk@^2.0.0, chalk@^2.4.1:
chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2:
version "2.4.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
@ -6387,7 +6407,7 @@ cheerio-select@^2.1.0:
domhandler "^5.0.3"
domutils "^3.0.1"
cheerio@^1.0.0-rc.11:
cheerio@^1.0.0-rc.1, cheerio@^1.0.0-rc.11:
version "1.0.0-rc.11"
resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.11.tgz#1be84be1a126958366bcc57a11648cd9b30a60c2"
integrity sha512-bQwNaDIBKID5ts/DsdhxrjqFXYfLw4ste+wMKqWA8DyKcS4qwsPP4Bk8ZNaTJjvpiX/qW3BT4sU7d6Bh5i+dag==
@ -6669,7 +6689,7 @@ comma-separated-tokens@^1.0.0:
resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea"
integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==
commander@2, commander@^2.19.0, commander@^2.20.0:
commander@2, commander@^2.19.0, commander@^2.20.0, commander@^2.8.1:
version "2.20.3"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
@ -7647,6 +7667,11 @@ delegates@^1.0.0:
resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a"
integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==
denodeify@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/denodeify/-/denodeify-1.2.1.tgz#3a36287f5034e699e7577901052c2e6c94251631"
integrity sha512-KNTihKNmQENUZeKu5fzfpzRqR5S2VMp4gl9RFHiWzj9DfvYQPMJ6XHKNaQxaGCXwPk6y9yme3aUoaiAe+KX+vg==
depd@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df"
@ -7729,7 +7754,7 @@ detective@^5.2.1:
defined "^1.0.0"
minimist "^1.2.6"
didyoumean@^1.2.2:
didyoumean@^1.2.1, didyoumean@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/didyoumean/-/didyoumean-1.2.2.tgz#989346ffe9e839b4555ecf5666edea0d3e8ad037"
integrity sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==
@ -8081,6 +8106,11 @@ entities@^4.2.0, entities@^4.3.0:
resolved "https://registry.yarnpkg.com/entities/-/entities-4.3.0.tgz#62915f08d67353bb4eb67e3d62641a4059aec656"
integrity sha512-/iP1rZrSEJ0DTlPiX+jbzlA3eVkY/e8L8SozroF395fIqE3TYF/Nz7YOMAawta+vLmyJ/hkGNNPcSbMADCCXbg==
entities@~1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
envinfo@^7.7.3:
version "7.8.1"
resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.8.1.tgz#06377e3e5f4d379fea7ac592d5ad8927e0c4d475"
@ -8813,6 +8843,13 @@ fbjs@^3.0.0, fbjs@^3.0.1:
setimmediate "^1.0.5"
ua-parser-js "^0.7.30"
fd-slicer@~1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/fd-slicer/-/fd-slicer-1.1.0.tgz#25c7c89cb1f9077f8891bbe61d8f390eae256f1e"
integrity sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==
dependencies:
pend "~1.2.0"
feed@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/feed/-/feed-4.2.2.tgz#865783ef6ed12579e2c44bbef3c9113bc4956a7e"
@ -9308,7 +9345,7 @@ glob-to-regexp@^0.4.1:
resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e"
integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==
glob@^7.0.0, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
glob@^7.0.0, glob@^7.0.6, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6:
version "7.2.3"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b"
integrity sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==
@ -11598,6 +11635,13 @@ lines-and-columns@^1.1.6:
resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
linkify-it@^2.0.0:
version "2.2.0"
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.2.0.tgz#e3b54697e78bf915c70a38acd78fd09e0058b1cf"
integrity sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==
dependencies:
uc.micro "^1.0.1"
load-json-file@^1.0.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0"
@ -11727,7 +11771,7 @@ lodash.uniq@4.5.0, lodash.uniq@^4.5.0:
resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773"
integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==
lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0:
lodash@^4.17.10, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4, lodash@^4.7.0:
version "4.17.21"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
@ -11859,6 +11903,17 @@ markdown-escapes@^1.0.0:
resolved "https://registry.yarnpkg.com/markdown-escapes/-/markdown-escapes-1.0.4.tgz#c95415ef451499d7602b91095f3c8e8975f78535"
integrity sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==
markdown-it@^8.3.1:
version "8.4.2"
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.2.tgz#386f98998dc15a37722aa7722084f4020bdd9b54"
integrity sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==
dependencies:
argparse "^1.0.7"
entities "~1.1.1"
linkify-it "^2.0.0"
mdurl "^1.0.1"
uc.micro "^1.0.5"
mathjs@^10.6.0:
version "10.6.1"
resolved "https://registry.yarnpkg.com/mathjs/-/mathjs-10.6.1.tgz#95b34178eed65cbf7a63d35c468ad3ac912f7ddf"
@ -11931,7 +11986,7 @@ mdn-data@2.0.4:
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b"
integrity sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==
mdurl@^1.0.0:
mdurl@^1.0.0, mdurl@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
integrity sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==
@ -12079,7 +12134,7 @@ mime-types@^2.1.12, mime-types@^2.1.27, mime-types@^2.1.30, mime-types@^2.1.31,
dependencies:
mime-db "1.52.0"
mime@1.6.0:
mime@1.6.0, mime@^1.3.4:
version "1.6.0"
resolved "https://registry.yarnpkg.com/mime/-/mime-1.6.0.tgz#32cd9e5c64553bd58d19a568af452acff04981b1"
integrity sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==
@ -12148,7 +12203,7 @@ minimatch@3.0.4:
dependencies:
brace-expansion "^1.1.7"
minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2:
minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
@ -12292,6 +12347,11 @@ multicast-dns@^7.2.5:
dns-packet "^5.2.2"
thunky "^1.0.2"
mute-stream@~0.0.4:
version "0.0.8"
resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.8.tgz#1630c42b2251ff81e2a283de96a5497ea92e5e0d"
integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==
nan@^2.12.1:
version "2.16.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.16.0.tgz#664f43e45460fb98faf00edca0bb0d7b8dce7916"
@ -12763,6 +12823,24 @@ os-homedir@^1.0.0:
resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3"
integrity sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==
os-tmpdir@^1.0.0, os-tmpdir@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274"
integrity sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==
os@0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/os/-/os-0.1.1.tgz#208845e89e193ad4d971474b93947736a56d13f3"
integrity sha512-jg06S2xr5De63mLjZVJDf3/k37tpjppr2LR7MUOsxv8XuUCVpCnvbCksXCBcB5gQqQf/K0+87WGTRlAj5q7r1A==
osenv@^0.1.3:
version "0.1.5"
resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410"
integrity sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==
dependencies:
os-homedir "^1.0.0"
os-tmpdir "^1.0.0"
p-all@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/p-all/-/p-all-2.1.0.tgz#91419be56b7dee8fe4c5db875d55e0da084244a0"
@ -12991,6 +13069,13 @@ parse-numeric-range@^1.3.0:
resolved "https://registry.yarnpkg.com/parse-numeric-range/-/parse-numeric-range-1.3.0.tgz#7c63b61190d61e4d53a1197f0c83c47bb670ffa3"
integrity sha512-twN+njEipszzlMJd4ONUYgSfZPDxgHhT9Ahed5uTigpQn90FggW4SA/AIPq/6a149fTbE9qBEcSwE3FAEp6wQQ==
parse-semver@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/parse-semver/-/parse-semver-1.1.1.tgz#9a4afd6df063dc4826f93fba4a99cf223f666cb8"
integrity sha512-Eg1OuNntBMH0ojvEKSrvDSnwLmvVuUOSdylH/pSCPNMIspLlweJyIWXCE+k/5hm3cj/EBUYwmWkjhBALNP4LXQ==
dependencies:
semver "^5.1.0"
parse5-htmlparser2-tree-adapter@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz#23c2cc233bcf09bb7beba8b8a69d46b08c62c2f1"
@ -13153,6 +13238,11 @@ peggy@^2.0.1:
commander "^9.3.0"
source-map-generator "0.8.0"
pend@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/pend/-/pend-1.2.0.tgz#7a57eb550a6783f9115331fcf4663d5c8e007a50"
integrity sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
@ -14685,6 +14775,13 @@ read-pkg@^5.2.0:
parse-json "^5.0.0"
type-fest "^0.6.0"
read@^1.0.7:
version "1.0.7"
resolved "https://registry.yarnpkg.com/read/-/read-1.0.7.tgz#b3da19bd052431a97671d44a42634adf710b40c4"
integrity sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==
dependencies:
mute-stream "~0.0.4"
"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.1.4, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.6, readable-stream@~2.3.6:
version "2.3.7"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57"
@ -15428,7 +15525,7 @@ semver-diff@^3.1.1:
dependencies:
semver "^6.3.0"
"semver@2 || 3 || 4 || 5", semver@^5.4.1, semver@^5.5.0, semver@^5.6.0:
"semver@2 || 3 || 4 || 5", semver@^5.1.0, semver@^5.4.1, semver@^5.5.0, semver@^5.6.0:
version "5.7.1"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
@ -16598,6 +16695,13 @@ tiny-warning@^1.0.0, tiny-warning@^1.0.3:
resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754"
integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==
tmp@0.0.29:
version "0.0.29"
resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.29.tgz#f25125ff0dd9da3ccb0c2dd371ee1288bb9128c0"
integrity sha512-89PTqMWGDva+GqClOqBV9s3SMh7MA3Mq0pJUdAoHuF65YoE7O0LermaZkVfT5/Ngfo18H4eYiyG7zKOtnEbxsw==
dependencies:
os-tmpdir "~1.0.1"
tmpl@1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.5.tgz#8683e0b902bb9c20c4f726e3c0b69f36518c07cc"
@ -16839,6 +16943,11 @@ tty-browserify@0.0.0:
resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6"
integrity sha512-JVa5ijo+j/sOoHGjw0sxw734b1LhBkQ3bvUGNdxnVXDCX81Yx7TFgnZygxrIIWn23hbfTaMYLwRmAxFyDuFmIw==
tunnel@0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/tunnel/-/tunnel-0.0.4.tgz#2d3785a158c174c9a16dc2c046ec5fc5f1742213"
integrity sha512-o9QYRJN5WgS8oCtqvwzzcfnzaTnDPr7HpUsQdSXscTyzXbjvl4wSHPTUKOKzEaDeQvOuyRtt3ui+ujM7x7TReQ==
type-check@^0.4.0, type-check@~0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.4.0.tgz#07b8203bfa7056c0657050e3ccd2c37730bab8f1"
@ -16901,6 +17010,14 @@ typed-function@^2.1.0:
resolved "https://registry.yarnpkg.com/typed-function/-/typed-function-2.1.0.tgz#ded6f8a442ba8749ff3fe75bc41419c8d46ccc3f"
integrity sha512-bctQIOqx2iVbWGDGPWwIm18QScpu2XRmkC19D8rQGFsjKSgteq/o1hTZvIG/wuDq8fanpBDrLkLq+aEN/6y5XQ==
typed-rest-client@1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/typed-rest-client/-/typed-rest-client-1.2.0.tgz#723085d203f38d7d147271e5ed3a75488eb44a02"
integrity sha512-FrUshzZ1yxH8YwGR29PWWnfksLEILbWJydU7zfIRkyH7kAEzB62uMAl2WY6EyolWpLpVHeJGgQm45/MaruaHpw==
dependencies:
tunnel "0.0.4"
underscore "1.8.3"
typedarray-to-buffer@^3.1.5:
version "3.1.5"
resolved "https://registry.yarnpkg.com/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz#a97ee7a9ff42691b9f783ff1bc5112fe3fca9080"
@ -16923,6 +17040,11 @@ ua-parser-js@^0.7.30:
resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.31.tgz#649a656b191dffab4f21d5e053e27ca17cbff5c6"
integrity sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==
uc.micro@^1.0.1, uc.micro@^1.0.5:
version "1.0.6"
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.6.tgz#9c411a802a409a91fc6cf74081baba34b24499ac"
integrity sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==
uglify-js@^3.1.4:
version "3.16.1"
resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.16.1.tgz#0e7ec928b3d0b1e1d952bce634c384fd56377317"
@ -16938,6 +17060,11 @@ unbox-primitive@^1.0.2:
has-symbols "^1.0.3"
which-boxed-primitive "^1.0.2"
underscore@1.8.3:
version "1.8.3"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022"
integrity sha512-5WsVTFcH1ut/kkhAaHf4PVgI8c7++GiVcpCGxPouI6ZVjsqPnSDf8h/8HtVqc0t4fzRXwnMK70EcZeAs3PIddg==
unfetch@^4.2.0:
version "4.2.0"
resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be"
@ -17185,6 +17312,11 @@ urix@^0.1.0:
resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72"
integrity sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==
url-join@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/url-join/-/url-join-1.1.0.tgz#741c6c2f4596c4830d6718460920d0c92202dc78"
integrity sha512-zz1wZk4Lb5PTVwZ3HWDmm8XnlPvmOof6/fjdDPA5yBrUcbtV64U6bV832Zf1BtU2WkBBWaUT46wCs+l0HP5nhg==
url-loader@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.1.tgz#28505e905cae158cf07c92ca622d7f237e70a4e2"
@ -17746,6 +17878,89 @@ vm-browserify@^1.0.1:
resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0"
integrity sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==
vsce-yarn-patch@^1.66.2:
version "1.66.2"
resolved "https://registry.yarnpkg.com/vsce-yarn-patch/-/vsce-yarn-patch-1.66.2.tgz#b217a9d73ee715ad41ec44393a5d78ed0955ab44"
integrity sha512-IJjBF/WQWQvEIikI93qDEhiugjVFDgibqsBa2roawp5abeovPZ9/bzLt0b9AylBtP60q2qSMWsGtf1hZBAs7fw==
dependencies:
azure-devops-node-api "^7.2.0"
chalk "^2.4.2"
cheerio "^1.0.0-rc.1"
commander "^2.8.1"
denodeify "^1.2.1"
didyoumean "^1.2.1"
glob "^7.0.6"
lodash "^4.17.10"
markdown-it "^8.3.1"
mime "^1.3.4"
minimatch "^3.0.3"
osenv "^0.1.3"
parse-semver "^1.1.1"
read "^1.0.7"
semver "^5.1.0"
tmp "0.0.29"
typed-rest-client "1.2.0"
url-join "^1.1.0"
yauzl "^2.3.1"
yazl "^2.2.2"
vscode-jsonrpc@6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-6.0.0.tgz#108bdb09b4400705176b957ceca9e0880e9b6d4e"
integrity sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==
vscode-jsonrpc@8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-8.0.1.tgz#f30b0625ebafa0fb3bc53e934ca47b706445e57e"
integrity sha512-N/WKvghIajmEvXpatSzvTvOIz61ZSmOSa4BRA4pTLi+1+jozquQKP/MkaylP9iB68k73Oua1feLQvH3xQuigiQ==
vscode-languageclient@^8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-8.0.1.tgz#bf5535c4463a78daeaca0bcb4f5868aec86bb301"
integrity sha512-9XoE+HJfaWvu7Y75H3VmLo5WLCtsbxEgEhrLPqwt7eyoR49lUIyyrjb98Yfa50JCMqF2cePJAEVI6oe2o1sIhw==
dependencies:
minimatch "^3.0.4"
semver "^7.3.5"
vscode-languageserver-protocol "3.17.1"
vscode-languageserver-protocol@3.16.0:
version "3.16.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.16.0.tgz#34135b61a9091db972188a07d337406a3cdbe821"
integrity sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==
dependencies:
vscode-jsonrpc "6.0.0"
vscode-languageserver-types "3.16.0"
vscode-languageserver-protocol@3.17.1:
version "3.17.1"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.1.tgz#e801762c304f740208b6c804a0cf21f2c87509ed"
integrity sha512-BNlAYgQoYwlSgDLJhSG+DeA8G1JyECqRzM2YO6tMmMji3Ad9Mw6AW7vnZMti90qlAKb0LqAlJfSVGEdqMMNzKg==
dependencies:
vscode-jsonrpc "8.0.1"
vscode-languageserver-types "3.17.1"
vscode-languageserver-textdocument@^1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.5.tgz#838769940ece626176ec5d5a2aa2d0aa69f5095c"
integrity sha512-1ah7zyQjKBudnMiHbZmxz5bYNM9KKZYz+5VQLj+yr8l+9w3g+WAhCkUkWbhMEdC5u0ub4Ndiye/fDyS8ghIKQg==
vscode-languageserver-types@3.16.0:
version "3.16.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.16.0.tgz#ecf393fc121ec6974b2da3efb3155644c514e247"
integrity sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==
vscode-languageserver-types@3.17.1:
version "3.17.1"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.1.tgz#c2d87fa7784f8cac389deb3ff1e2d9a7bef07e16"
integrity sha512-K3HqVRPElLZVVPtMeKlsyL9aK0GxGQpvtAUTfX4k7+iJ4mc1M+JM+zQwkgGy2LzY0f0IAafe8MKqIkJrxfGGjQ==
vscode-languageserver@^7.0.0:
version "7.0.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-7.0.0.tgz#49b068c87cfcca93a356969d20f5d9bdd501c6b0"
integrity sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==
dependencies:
vscode-languageserver-protocol "3.16.0"
vscode-uri@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.3.tgz#a95c1ce2e6f41b7549f86279d19f47951e4f4d84"
@ -18580,6 +18795,21 @@ yargs@~17.2.1:
y18n "^5.0.5"
yargs-parser "^20.2.2"
yauzl@^2.3.1:
version "2.10.0"
resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9"
integrity sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==
dependencies:
buffer-crc32 "~0.2.3"
fd-slicer "~1.1.0"
yazl@^2.2.2:
version "2.5.1"
resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.5.1.tgz#a3d65d3dd659a5b0937850e8609f22fffa2b5c35"
integrity sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==
dependencies:
buffer-crc32 "~0.2.3"
yn@3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"