Merge branch 'reducer-typecheck' of github.com:quantified-uncertainty/squiggle into reducer-typecheck

* 'reducer-typecheck' of github.com:quantified-uncertainty/squiggle:
  type modifiers -> type contracts
  simplified modules
  before math library
This commit is contained in:
Ozzie Gooen 2022-07-18 09:34:52 -07:00
commit e0f97d8af0
28 changed files with 118 additions and 229 deletions

View File

@ -2,15 +2,15 @@
module ErrorValue = Reducer_ErrorValue
module ExternalExpressionValue = ReducerInterface.ExternalExpressionValue
module InternalExpressionValue = ReducerInterface.InternalExpressionValue
module Module = Reducer_Module
module Bindings = Reducer_Bindings
let removeDefaultsInternal = (iev: InternalExpressionValue.t) => {
switch iev {
| InternalExpressionValue.IEvModule(nameSpace) =>
Module.removeOther(
| InternalExpressionValue.IEvBindings(nameSpace) =>
Bindings.removeOther(
nameSpace,
ReducerInterface.StdLib.internalStdLib,
)->InternalExpressionValue.IEvModule
)->InternalExpressionValue.IEvBindings
| value => value
}
}

View File

@ -1,119 +0,0 @@
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
module ExpressionT = Reducer_Expression_T
module Module = Reducer_Module
module Bindings = Reducer_Module
module ErrorValue = Reducer_ErrorValue
open Jest
open Expect
// ----------------------
// --- Start of Module File
// ----------------------
module FooImplementation = {
// As this is a Rescript module, functions can use other functions in this module
// and in other stdLib modules implemented this way.
// Embedding function definitions in to switch statements is a bad practice
// - to reduce line count or to
let fooNumber = 0.0
let fooString = "Foo String"
let fooBool = true
let makeFoo = (a: string, b: string, _environment): string => `I am ${a}-foo and I am ${b}-foo`
let makeBar = (a: float, b: float, _environment): string =>
`I am ${a->Js.Float.toString}-bar and I am ${b->Js.Float.toString}-bar`
// You can also define functions that has their internal errors
let makeReturningError = (_a: float, _b: float, _environment): result<float, ErrorValue.t> =>
if false {
0.->Ok
} else {
ErrorValue.RETodo("test error")->Error
}
}
// There is a potential for type modules to define lift functions
// for their own type to get rid of switch statements.
module FooFFI = {
let makeFoo: ExpressionT.optionFfiFn = (args: array<InternalExpressionValue.t>, environment) => {
switch args {
| [IEvString(a), IEvString(b)] => FooImplementation.makeFoo(a, b, environment)->IEvString->Some
| _ => None
}
}
let makeBar: ExpressionT.optionFfiFn = (args: array<InternalExpressionValue.t>, environment) =>
switch args {
| [IEvNumber(a), IEvNumber(b)] => FooImplementation.makeBar(a, b, environment)->IEvString->Some
| _ => None
}
let makeReturningError: ExpressionT.optionFfiFnReturningResult = (
args: array<InternalExpressionValue.t>,
environment,
) =>
switch args {
| [IEvNumber(a), IEvNumber(b)] =>
FooImplementation.makeReturningError(a, b, environment)
->Belt.Result.map(v => v->InternalExpressionValue.IEvNumber)
->Some
| _ => None
}
}
let fooModule: Module.t =
Module.emptyStdLib
->Module.defineNumber("fooNumber", FooImplementation.fooNumber)
->Module.defineString("fooString", FooImplementation.fooString)
->Module.defineBool("fooBool", FooImplementation.fooBool)
->Module.defineFunction("makeFoo", FooFFI.makeFoo)
->Module.defineFunction("makeBar", FooFFI.makeBar)
->Module.defineFunctionReturningResult("makeReturningError", FooFFI.makeReturningError)
let makeBindings = (prevBindings: Bindings.t): Bindings.t =>
prevBindings->Module.defineModule("Foo", fooModule)
// ----------------------
// --- End of Module File
// ----------------------
let stdLibWithFoo = Bindings.emptyBindings->makeBindings
let evalWithFoo = sourceCode =>
Reducer_Expression.parse(sourceCode)->Belt.Result.flatMap(expr =>
Reducer_Expression.reduceExpression(
expr,
stdLibWithFoo,
InternalExpressionValue.defaultEnvironment,
)
)
let evalToStringResultWithFoo = sourceCode =>
evalWithFoo(sourceCode)->InternalExpressionValue.toStringResult
describe("Module", () => {
test("fooNumber", () => {
let result = evalToStringResultWithFoo("Foo.fooNumber")
expect(result)->toEqual("Ok(0)")
})
test("fooString", () => {
let result = evalToStringResultWithFoo("Foo.fooString")
expect(result)->toEqual("Ok('Foo String')")
})
test("fooBool", () => {
let result = evalToStringResultWithFoo("Foo.fooBool")
expect(result)->toEqual("Ok(true)")
})
test("fooBool", () => {
let result = evalToStringResultWithFoo("Foo.fooBool")
expect(result)->toEqual("Ok(true)")
})
test("makeFoo", () => {
let result = evalToStringResultWithFoo("Foo.makeFoo('a', 'b')")
expect(result)->toEqual("Ok('I am a-foo and I am b-foo')")
})
test("makeFoo wrong arguments", () => {
let result = evalToStringResultWithFoo("Foo.makeFoo(1, 2)")
// Notice the error with types
expect(result)->toEqual("Error(Function not found: makeFoo(Number,Number))")
})
test("makeBar", () => {
let result = evalToStringResultWithFoo("Foo.makeBar(1, 2)")
expect(result)->toEqual("Ok('I am 1-bar and I am 2-bar')")
})
})

View File

@ -236,7 +236,8 @@ describe("Peggy parse", () => {
testParse("1m+2cm", "{(::add (::fromUnit_m 1) (::fromUnit_cm 2))}")
})
describe("Module", () => {
testParse("Math.pi", "{(::$_atIndex_$ @Math 'pi')}")
testParse("x", "{:x}")
testParse("Math.pi", "{:Math.pi}")
})
})

View File

@ -20,7 +20,7 @@ describe("Peggy parse type", () => {
"{(::$_typeOf_$ :f (::$_typeFunction_$ (::$_constructArray_$ (#number #number #number))))}",
)
})
describe("high priority modifier", () => {
describe("high priority contract", () => {
testParse(
"answer: number<-min<-max(100)|string",
"{(::$_typeOf_$ :answer (::$_typeOr_$ (::$_constructArray_$ ((::$_typeModifier_max_$ (::$_typeModifier_min_$ #number) 100) #string))))}",
@ -30,7 +30,7 @@ describe("Peggy parse type", () => {
"{(::$_typeOf_$ :answer (::$_typeModifier_memberOf_$ #number (::$_constructArray_$ (1 3 5))))}",
)
})
describe("low priority modifier", () => {
describe("low priority contract", () => {
testParse(
"answer: number | string $ opaque",
"{(::$_typeOf_$ :answer (::$_typeModifier_opaque_$ (::$_typeOr_$ (::$_constructArray_$ (#number #string)))))}",
@ -70,7 +70,7 @@ describe("Peggy parse type", () => {
"{(::$_typeOf_$ :answer (::$_typeModifier_opaque_$ (::$_typeOr_$ (::$_constructArray_$ (#number #string)))))}",
)
})
describe("squiggle expressions in type modifiers", () => {
describe("squiggle expressions in type contracts", () => {
testParse(
"odds1 = [1,3,5]; odds2 = [7, 9]; type odds = number<-memberOf(concat(odds1, odds2))",
"{:odds1 = {(::$_constructArray_$ (1 3 5))}; :odds2 = {(::$_constructArray_$ (7 9))}; (::$_typeAlias_$ #odds (::$_typeModifier_memberOf_$ #number (::concat :odds1 :odds2)))}",

View File

@ -4,6 +4,7 @@ module ExpressionValue = ReducerInterface.InternalExpressionValue
module Parse = Reducer_Peggy_Parse
module Result = Belt.Result
module ToExpression = Reducer_Peggy_ToExpression
module Bindings = Reducer_Bindings
open Jest
open Expect

View File

@ -1,3 +1,6 @@
module Bindings = Reducer_Bindings
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
open Jest
open Reducer_Peggy_TestHelpers
@ -183,6 +186,14 @@ describe("Peggy to Expression", () => {
})
describe("module", () => {
testToExpression("Math.pi", "{(:$_atIndex_$ :Math 'pi')}", ~v="3.141592653589793", ())
// testToExpression("Math.pi", "{:Math.pi}", ~v="3.141592653589793", ())
// Only.test("stdlibrary", () => {
// ReducerInterface_StdLib.internalStdLib
// ->IEvBindings
// ->InternalExpressionValue.toString
// ->expect
// ->toBe("")
// })
testToExpression("Math.pi", "{:Math.pi}", ~v="3.141592653589793", ())
})
})

View File

@ -40,7 +40,7 @@ describe("Peggy Types to Expression", () => {
(),
)
})
describe("high priority modifier", () => {
describe("high priority contract", () => {
testToExpression(
"answer: number<-min(1)<-max(100)|string",
"{(:$_typeOf_$ :answer (:$_typeOr_$ (:$_constructArray_$ ((:$_typeModifier_max_$ (:$_typeModifier_min_$ #number 1) 100) #string))))}",
@ -78,7 +78,7 @@ describe("Peggy Types to Expression", () => {
(),
)
})
describe("low priority modifier", () => {
describe("low priority contract", () => {
testToExpression(
"answer: number | string $ opaque",
"{(:$_typeOf_$ :answer (:$_typeModifier_opaque_$ (:$_typeOr_$ (:$_constructArray_$ (#number #string)))))}",
@ -86,7 +86,7 @@ describe("Peggy Types to Expression", () => {
(),
)
})
describe("squiggle expressions in type modifiers", () => {
describe("squiggle expressions in type contracts", () => {
testToExpression(
"odds1 = [1,3,5]; odds2 = [7, 9]; type odds = number<-memberOf(concat(odds1, odds2))",
"{(:$_let_$ :odds1 {(:$_constructArray_$ (1 3 5))}); (:$_let_$ :odds2 {(:$_constructArray_$ (7 9))}); (:$_typeAlias_$ #odds (:$_typeModifier_memberOf_$ #number (:concat :odds1 :odds2)))}",

View File

@ -8,7 +8,7 @@ module InternalExpressionValue = ReducerInterface.InternalExpressionValue
module ExpressionWithContext = Reducer_ExpressionWithContext
module Macro = Reducer_Expression_Macro
module T = Reducer_Expression_T
module Module = Reducer_Module
module Bindings = Reducer_Bindings
let testMacro_ = (
tester,
@ -16,7 +16,7 @@ let testMacro_ = (
expr: T.expression,
expectedCode: string,
) => {
let bindings = Module.fromArray(bindArray)
let bindings = Bindings.fromArray(bindArray)
tester(expr->T.toString, () =>
expr
->Macro.expandMacroCall(
@ -36,7 +36,7 @@ let testMacroEval_ = (
expr: T.expression,
expectedValue: string,
) => {
let bindings = Module.fromArray(bindArray)
let bindings = Bindings.fromArray(bindArray)
tester(expr->T.toString, () =>
expr
->Macro.doMacroCall(

View File

@ -1,6 +1,6 @@
module Expression = Reducer_Expression
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
module Module = Reducer_Module
module Bindings = Reducer_Bindings
module T = Reducer_Type_T
module TypeCompile = Reducer_Type_Compile

View File

@ -2,7 +2,7 @@ module Expression = Reducer_Expression
module ExpressionT = Reducer_Expression_T
module ErrorValue = Reducer_ErrorValue
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
module Module = Reducer_Module
module Bindings = Reducer_Bindings
module T = Reducer_Type_T
module TypeChecker = Reducer_Type_TypeChecker
@ -16,7 +16,7 @@ let checkArgumentsSourceCode = (aTypeSourceCode: string, sourceCode: string): re
let reducerFn = Expression.reduceExpression
let rResult =
Reducer.parse(sourceCode)->Belt.Result.flatMap(expr =>
reducerFn(expr, Module.emptyBindings, InternalExpressionValue.defaultEnvironment)
reducerFn(expr, Bindings.emptyBindings, InternalExpressionValue.defaultEnvironment)
)
rResult->Belt.Result.flatMap(result =>
switch result {

View File

@ -2,7 +2,7 @@ module Expression = Reducer_Expression
module ExpressionT = Reducer_Expression_T
module ErrorValue = Reducer_ErrorValue
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
module Module = Reducer_Module
module Bindings = Reducer_Bindings
module T = Reducer_Type_T
module TypeChecker = Reducer_Type_TypeChecker
@ -19,7 +19,7 @@ let isTypeOfSourceCode = (aTypeSourceCode: string, sourceCode: string): result<
let reducerFn = Expression.reduceExpression
let rResult =
Reducer.parse(sourceCode)->Belt.Result.flatMap(expr =>
reducerFn(expr, Module.emptyBindings, InternalExpressionValue.defaultEnvironment)
reducerFn(expr, Bindings.emptyBindings, InternalExpressionValue.defaultEnvironment)
)
rResult->Belt.Result.flatMap(result => TypeChecker.isTypeOf(aTypeSourceCode, result, reducerFn))
}

View File

@ -1,3 +1,6 @@
// Only Bindings as the global module is supported
// Other module operations such as import export will be prepreocessed jobs
module ExpressionT = Reducer_Expression_T
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
open Reducer_ErrorValue
@ -75,10 +78,10 @@ let emptyBindings = emptyModule
let fromTypeScriptBindings = ReducerInterface_InternalExpressionValue.nameSpaceFromTypeScriptBindings
let toTypeScriptBindings = ReducerInterface_InternalExpressionValue.nameSpaceToTypeScriptBindings
let toExpressionValue = (nameSpace: t): internalExpressionValue => IEvModule(nameSpace)
let toExpressionValue = (nameSpace: t): internalExpressionValue => IEvBindings(nameSpace)
let fromExpressionValue = (aValue: internalExpressionValue): t =>
switch aValue {
| IEvModule(nameSpace) => nameSpace
| IEvBindings(nameSpace) => nameSpace
| _ => emptyModule
}

View File

@ -3,7 +3,7 @@ module ExpressionT = Reducer_Expression_T
module ExternalLibrary = ReducerInterface.ExternalLibrary
module Lambda = Reducer_Expression_Lambda
module MathJs = Reducer_MathJs
module Module = Reducer_Module
module Bindings = Reducer_Bindings
module Result = Belt.Result
module TypeBuilder = Reducer_Type_TypeBuilder
open ReducerInterface_InternalExpressionValue
@ -49,9 +49,9 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce
}
let moduleAtIndex = (nameSpace: nameSpace, sIndex) =>
switch Module.get(nameSpace, sIndex) {
switch Bindings.get(nameSpace, sIndex) {
| Some(value) => value->Ok
| None => RERecordPropertyNotFound("Module property not found", sIndex)->Error
| None => RERecordPropertyNotFound("Bindings property not found", sIndex)->Error
}
let recordAtIndex = (dict: Belt.Map.String.t<internalExpressionValue>, sIndex) =>
@ -81,19 +81,19 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce
}
let doSetBindings = (bindings: nameSpace, symbol: string, value: internalExpressionValue) => {
Module.set(bindings, symbol, value)->IEvModule->Ok
Bindings.set(bindings, symbol, value)->IEvBindings->Ok
}
let doSetTypeAliasBindings = (
bindings: nameSpace,
symbol: string,
value: internalExpressionValue,
) => Module.setTypeAlias(bindings, symbol, value)->IEvModule->Ok
) => Bindings.setTypeAlias(bindings, symbol, value)->IEvBindings->Ok
let doSetTypeOfBindings = (bindings: nameSpace, symbol: string, value: internalExpressionValue) =>
Module.setTypeOf(bindings, symbol, value)->IEvModule->Ok
Bindings.setTypeOf(bindings, symbol, value)->IEvBindings->Ok
let doExportBindings = (bindings: nameSpace) => bindings->Module.toExpressionValue->Ok
let doExportBindings = (bindings: nameSpace) => bindings->Bindings.toExpressionValue->Ok
let doKeepArray = (aValueArray, aLambdaValue) => {
let rMappedList = aValueArray->Belt.Array.reduceReverse(Ok(list{}), (rAcc, elem) =>
@ -169,16 +169,16 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce
switch call {
| ("$_atIndex_$", [IEvArray(aValueArray), IEvNumber(fIndex)]) => arrayAtIndex(aValueArray, fIndex)
| ("$_atIndex_$", [IEvModule(dict), IEvString(sIndex)]) => moduleAtIndex(dict, sIndex)
| ("$_atIndex_$", [IEvBindings(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]) =>
| ("$_exportBindings_$", [IEvBindings(nameSpace)]) => doExportBindings(nameSpace)
| ("$_setBindings_$", [IEvBindings(nameSpace), IEvSymbol(symbol), value]) =>
doSetBindings(nameSpace, symbol, value)
| ("$_setTypeAliasBindings_$", [IEvModule(nameSpace), IEvTypeIdentifier(symbol), value]) =>
| ("$_setTypeAliasBindings_$", [IEvBindings(nameSpace), IEvTypeIdentifier(symbol), value]) =>
doSetTypeAliasBindings(nameSpace, symbol, value)
| ("$_setTypeOfBindings_$", [IEvModule(nameSpace), IEvSymbol(symbol), value]) =>
| ("$_setTypeOfBindings_$", [IEvBindings(nameSpace), IEvSymbol(symbol), value]) =>
doSetTypeOfBindings(nameSpace, symbol, value)
| ("$_typeModifier_memberOf_$", [IEvTypeIdentifier(typeIdentifier), IEvArray(arr)]) =>
TypeBuilder.typeModifier_memberOf(IEvTypeIdentifier(typeIdentifier), IEvArray(arr))

View File

@ -9,7 +9,7 @@ module ExpressionBuilder = Reducer_Expression_ExpressionBuilder
module ExpressionT = Reducer_Expression_T
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
module ExpressionWithContext = Reducer_ExpressionWithContext
module Module = Reducer_Module
module Bindings = Reducer_Bindings
module Result = Belt.Result
open Reducer_Expression_ExpressionBuilder
@ -28,7 +28,7 @@ let dispatchMacroCall = (
let rExternalBindingsValue = reduceExpression(bindingExpr, bindings, environment)
rExternalBindingsValue->Result.flatMap(nameSpaceValue => {
let newBindings = Module.fromExpressionValue(nameSpaceValue)
let newBindings = Bindings.fromExpressionValue(nameSpaceValue)
let rNewStatement = BindingsReplacer.replaceSymbols(newBindings, statement)
rNewStatement->Result.map(boundStatement =>

View File

@ -6,7 +6,7 @@ module InternalExpressionValue = ReducerInterface_InternalExpressionValue
module Lambda = Reducer_Expression_Lambda
module Macro = Reducer_Expression_Macro
module MathJs = Reducer_MathJs
module Module = Reducer_Module
module Bindings = Reducer_Bindings
module Result = Belt.Result
module T = Reducer_Expression_T
@ -121,10 +121,10 @@ let evaluateUsingOptions = (
ReducerInterface_ExternalExpressionValue.defaultEnvironment,
)
let mergedBindings: InternalExpressionValue.nameSpace = Module.merge(
let mergedBindings: InternalExpressionValue.nameSpace = Bindings.merge(
ReducerInterface_StdLib.internalStdLib,
Belt.Option.map(externalBindings, Module.fromTypeScriptBindings)->Belt.Option.getWithDefault(
Module.emptyModule,
Belt.Option.map(externalBindings, Bindings.fromTypeScriptBindings)->Belt.Option.getWithDefault(
Bindings.emptyModule,
),
)

View File

@ -3,7 +3,7 @@ module ErrorValue = Reducer_ErrorValue
module ExpressionT = Reducer_Expression_T
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
module Result = Belt.Result
module Module = Reducer_Module
module Bindings = Reducer_Bindings
type bindings = ExpressionT.bindings
type context = bindings
@ -41,7 +41,7 @@ let toString = expressionWithContext =>
| ExpressionNoContext(expr) => ExpressionT.toString(expr)
| ExpressionWithContext(expr, context) =>
`${ExpressionT.toString(expr)} context: ${context
->Module.toExpressionValue
->Bindings.toExpressionValue
->InternalExpressionValue.toString}`
}

View File

@ -2,7 +2,7 @@ module ErrorValue = Reducer_ErrorValue
module ExpressionT = Reducer_Expression_T
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
module Result = Belt.Result
module Module = Reducer_Module
module Bindings = Reducer_Bindings
type errorValue = Reducer_ErrorValue.errorValue
type expression = ExpressionT.expression
@ -42,8 +42,8 @@ and replaceSymbolsOnExpressionList = (bindings, list) => {
}
and replaceSymbolOnValue = (bindings, evValue: internalExpressionValue) =>
switch evValue {
| IEvSymbol(symbol) => Module.getWithDefault(bindings, symbol, evValue)->Ok
| IEvCall(symbol) => Module.getWithDefault(bindings, symbol, evValue)->checkIfCallable
| IEvSymbol(symbol) => Bindings.getWithDefault(bindings, symbol, evValue)->Ok
| IEvCall(symbol) => Bindings.getWithDefault(bindings, symbol, evValue)->checkIfCallable
| _ => evValue->Ok
}
and checkIfCallable = (evValue: internalExpressionValue) =>

View File

@ -2,7 +2,7 @@ module BBindingsReplacer = Reducer_Expression_BindingsReplacer
module BErrorValue = Reducer_ErrorValue
module BExpressionT = Reducer_Expression_T
module BInternalExpressionValue = ReducerInterface_InternalExpressionValue
module BModule = Reducer_Module
module BBindings = Reducer_Bindings
type errorValue = BErrorValue.errorValue
type expression = BExpressionT.expression
@ -15,7 +15,7 @@ let eArray = anArray => anArray->BInternalExpressionValue.IEvArray->BExpressionT
let eArrayString = anArray => anArray->BInternalExpressionValue.IEvArrayString->BExpressionT.EValue
let eBindings = (anArray: array<(string, BInternalExpressionValue.t)>) =>
anArray->BModule.fromArray->BModule.toExpressionValue->BExpressionT.EValue
anArray->BBindings.fromArray->BBindings.toExpressionValue->BExpressionT.EValue
let eBool = aBool => aBool->BInternalExpressionValue.IEvBool->BExpressionT.EValue
@ -35,12 +35,12 @@ let eLambda = (
BInternalExpressionValue.IEvLambda({
parameters: parameters,
context: context,
body: NotFFI(expr)->BModule.castExpressionToInternalCode,
body: NotFFI(expr)->BBindings.castExpressionToInternalCode,
})->BExpressionT.EValue
}
let eLambdaFFI = (ffiFn: ffiFn) => {
ffiFn->BModule.eLambdaFFIValue->BExpressionT.EValue
ffiFn->BBindings.eLambdaFFIValue->BExpressionT.EValue
}
let eNumber = aNumber => aNumber->BInternalExpressionValue.IEvNumber->BExpressionT.EValue
@ -57,7 +57,7 @@ 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
nameSpace->BInternalExpressionValue.IEvBindings->BExpressionT.EValue
let eLetStatement = (symbol: string, valueExpression: expression): expression =>
eFunction("$_let_$", list{eSymbol(symbol), valueExpression})

View File

@ -3,7 +3,7 @@ module ErrorValue = Reducer_ErrorValue
module ExpressionBuilder = Reducer_Expression_ExpressionBuilder
module ExpressionT = Reducer_Expression_T
module ExpressionValue = ReducerInterface_InternalExpressionValue
module Module = Reducer_Module
module Bindings = Reducer_Bindings
module Result = Belt.Result
type environment = ReducerInterface_InternalExpressionValue.environment
@ -50,7 +50,7 @@ let caseNotFFI = (lambdaValue: ExpressionValue.lambdaValue, expr, args, environm
let bindings = Belt.List.reduce(zippedParameterList, lambdaValue.context, (
acc,
(variable, variableValue),
) => acc->Module.set(variable, variableValue))
) => acc->Bindings.set(variable, variableValue))
let newExpression = ExpressionBuilder.eBlock(list{expr})
reducer(newExpression, bindings, environment)
}

View File

@ -1,14 +0,0 @@
module ExpressionBuilder = Reducer_Expression_ExpressionBuilder
module ExpressionT = Reducer_Expression_T
type expression = ExpressionT.expression
let defaultCaseFFI = (functionName: string): expression => {
ExpressionBuilder.eLambdaFFI(Reducer_Module.functionNotFoundErrorFFIFn(functionName))
}
let addGuard = (
guard: expression,
expression: expression,
previousExpression: expression,
): expression => ExpressionBuilder.eTernary(guard, expression, previousExpression)

View File

@ -187,13 +187,16 @@ basicLiteral
/ dollarIdentifier
dollarIdentifierWithModule 'identifier'
= head:moduleIdentifier
= head:$moduleIdentifier
tail:('.' _nl @$moduleIdentifier)* '.' _nl
final:$dollarIdentifier
{ tail.push(final);
return tail.reduce(function(result, element) {
return h.makeFunctionCall(h.postOperatorToFunction['[]'], [result, h.nodeString(element)])
}, head)}
{
let modifiers = [...tail]
modifiers.unshift(head)
modifiers.push(final)
let modifiedIdentifier = modifiers.join('.')
return h.nodeIdentifier(modifiedIdentifier)
}
identifier 'identifier'
= ([_a-z]+[_a-z0-9]i*) {return h.nodeIdentifier(text(), location())}

View File

@ -1,7 +1,7 @@
module ErrorValue = Reducer_ErrorValue
module ExpressionT = Reducer_Expression_T
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
module Module = Reducer_Module
module Bindings = Reducer_Bindings
module T = Reducer_Type_T
let ievFromTypeExpression = (
@ -11,11 +11,15 @@ let ievFromTypeExpression = (
let sIndex = "compiled"
let sourceCode = `type ${sIndex}=${typeExpressionSourceCode}`
Reducer_Expression.parse(sourceCode)->Belt.Result.flatMap(expr => {
let rContext = reducerFn(expr, Module.emptyBindings, InternalExpressionValue.defaultEnvironment)
let rContext = reducerFn(
expr,
Bindings.emptyBindings,
InternalExpressionValue.defaultEnvironment,
)
Belt.Result.map(rContext, context =>
switch context {
| IEvModule(nameSpace) =>
switch Module.getType(nameSpace, sIndex) {
| IEvBindings(nameSpace) =>
switch Bindings.getType(nameSpace, sIndex) {
| Some(value) => value
| None => raise(Reducer_Exception.ImpossibleException("Reducer_Type_Compile-none"))
}

View File

@ -41,10 +41,10 @@ let checkModifier = (
}
let checkModifiers = (
modifiers: Belt.Map.String.t<InternalExpressionValue.t>,
contracts: Belt.Map.String.t<InternalExpressionValue.t>,
aValue: InternalExpressionValue.t,
): bool => {
modifiers->Belt.Map.String.reduce(true, (acc, key, modifierArg) =>
contracts->Belt.Map.String.reduce(true, (acc, key, modifierArg) =>
switch acc {
| true => checkModifier(key, modifierArg, aValue)
| _ => acc

View File

@ -3,7 +3,7 @@ open InternalExpressionValue
type rec iType =
| ItTypeIdentifier(string)
| ItModifiedType({modifiedType: iType, modifiers: Belt.Map.String.t<InternalExpressionValue.t>})
| ItModifiedType({modifiedType: iType, contracts: Belt.Map.String.t<InternalExpressionValue.t>})
| ItTypeOr({typeOr: array<iType>})
| ItTypeFunction({inputs: array<iType>, output: iType})
| ItTypeArray({element: iType})
@ -16,8 +16,8 @@ type typeErrorValue = TypeMismatch(t, InternalExpressionValue.t)
let rec toString = (t: t): string => {
switch t {
| ItTypeIdentifier(s) => s
| ItModifiedType({modifiedType, modifiers}) =>
`${toString(modifiedType)}${modifiers->Belt.Map.String.reduce("", (acc, k, v) =>
| ItModifiedType({modifiedType, contracts}) =>
`${toString(modifiedType)}${contracts->Belt.Map.String.reduce("", (acc, k, v) =>
Js.String2.concatMany(acc, ["<-", k, "(", InternalExpressionValue.toString(v), ")"])
)}`
| ItTypeOr({typeOr}) => `(${Js.Array2.map(typeOr, toString)->Js.Array2.joinWith(" | ")})`
@ -82,7 +82,7 @@ let rec fromTypeMap = typeMap => {
default,
)
let modifiers =
let contracts =
typeMap->Belt.Map.String.keep((k, _v) => ["min", "max", "memberOf"]->Js.Array2.includes(k))
let makeIt = switch evTypeTag {
@ -96,9 +96,9 @@ let rec fromTypeMap = typeMap => {
| _ => raise(Reducer_Exception.ImpossibleException("Reducer_Type_T-evTypeTag"))
}
Belt.Map.String.isEmpty(modifiers)
Belt.Map.String.isEmpty(contracts)
? makeIt
: ItModifiedType({modifiedType: makeIt, modifiers: modifiers})
: ItModifiedType({modifiedType: makeIt, contracts: contracts})
}
and fromIEvValue = (ievValue: InternalExpressionValue.t): iType =>

View File

@ -1,7 +1,7 @@
module ExpressionT = Reducer_Expression_T
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
module T = Reducer_Type_T
module TypeModifiers = Reducer_Type_Modifiers
module TypeContracts = Reducer_Type_Contracts
open InternalExpressionValue
let rec isITypeOf = (anIType: T.iType, aValue): result<bool, T.typeErrorValue> => {
@ -92,11 +92,11 @@ let rec isITypeOf = (anIType: T.iType, aValue): result<bool, T.typeErrorValue> =
let caseModifiedType = (
anIType: T.iType,
modifiedType: T.iType,
modifiers: Belt.Map.String.t<InternalExpressionValue.t>,
contracts: Belt.Map.String.t<InternalExpressionValue.t>,
aValue: InternalExpressionValue.t,
) => {
isITypeOf(modifiedType, aValue)->Belt.Result.flatMap(_result => {
if TypeModifiers.checkModifiers(modifiers, aValue) {
if TypeContracts.checkModifiers(contracts, aValue) {
Ok(true)
} else {
T.TypeMismatch(anIType, aValue)->Error
@ -106,8 +106,8 @@ let rec isITypeOf = (anIType: T.iType, aValue): result<bool, T.typeErrorValue> =
switch anIType {
| ItTypeIdentifier(name) => caseTypeIdentifier(name, aValue)
| ItModifiedType({modifiedType, modifiers}) =>
caseModifiedType(anIType, modifiedType, modifiers, aValue) //{modifiedType: iType, modifiers: Belt.Map.String.t<InternalExpressionValue.t>}
| ItModifiedType({modifiedType, contracts}) =>
caseModifiedType(anIType, modifiedType, contracts, aValue) //{modifiedType: iType, contracts: Belt.Map.String.t<InternalExpressionValue.t>}
| ItTypeOr({typeOr}) => caseOr(anIType, typeOr, aValue)
| ItTypeFunction(_) =>
raise(

View File

@ -15,7 +15,7 @@ type rec t =
| IEvDeclaration(lambdaDeclaration)
| IEvDistribution(DistributionTypes.genericDist)
| IEvLambda(lambdaValue)
| IEvModule(nameSpace)
| IEvBindings(nameSpace)
| IEvNumber(float)
| IEvRecord(map)
| IEvString(string)
@ -52,7 +52,7 @@ let rec toString = aValue =>
| 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}`
| IEvBindings(m) => `@${m->toStringNameSpace}`
| IEvNumber(aNumber) => Js.String.make(aNumber)
| IEvRecord(aMap) => aMap->toStringMap
| IEvString(aString) => `'${aString}'`
@ -84,7 +84,7 @@ let toStringWithType = aValue =>
| IEvDeclaration(_) => `Declaration::${toString(aValue)}`
| IEvDistribution(_) => `Distribution::${toString(aValue)}`
| IEvLambda(_) => `Lambda::${toString(aValue)}`
| IEvModule(_) => `Module::${toString(aValue)}`
| IEvBindings(_) => `Bindings::${toString(aValue)}`
| IEvNumber(_) => `Number::${toString(aValue)}`
| IEvRecord(_) => `Record::${toString(aValue)}`
| IEvString(_) => `String::${toString(aValue)}`
@ -150,7 +150,7 @@ let valueToValueType = value =>
| IEvDeclaration(_) => EvtDeclaration
| IEvDistribution(_) => EvtDistribution
| IEvLambda(_) => EvtLambda
| IEvModule(_) => EvtModule
| IEvBindings(_) => EvtModule
| IEvNumber(_) => EvtNumber
| IEvRecord(_) => EvtRecord
| IEvString(_) => EvtString
@ -211,7 +211,7 @@ let rec toExternal = (iev: t): ExternalExpressionValue.t => {
| IEvTimeDuration(v) => EvTimeDuration(v)
| IEvType(v) => v->mapToExternal->EvType
| IEvTypeIdentifier(v) => EvTypeIdentifier(v)
| IEvModule(v) => v->nameSpaceToTypeScriptBindings->EvModule
| IEvBindings(v) => v->nameSpaceToTypeScriptBindings->EvModule
}
}
and mapToExternal = v =>
@ -243,7 +243,7 @@ let rec toInternal = (ev: ExternalExpressionValue.t): t => {
}
| EvDistribution(v) => IEvDistribution(v)
| EvLambda(v) => IEvLambda(lambdaValueToInternal(v))
| EvModule(v) => v->nameSpaceFromTypeScriptBindings->IEvModule
| EvModule(v) => v->nameSpaceFromTypeScriptBindings->IEvBindings
| EvNumber(v) => IEvNumber(v)
| EvRecord(v) => v->recordToInternal->IEvRecord
| EvString(v) => IEvString(v)

View File

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

View File

@ -1,17 +1,16 @@
module Bindings = Reducer_Module
module Module = Reducer_Module
module Bindings = Reducer_Bindings
let availableNumbers: array<(string, float)> = [
("pi", Js.Math._PI),
("e", Js.Math._E),
("ln2", Js.Math._LN2),
("ln10", Js.Math._LN10),
("log2e", Js.Math._LOG2E),
("log10e", Js.Math._LOG10E),
("sqrt2", Js.Math._SQRT2),
("sqrt1_2", Js.Math._SQRT1_2),
("phi", 1.618033988749895),
("tau", 6.283185307179586),
("Math.pi", Js.Math._PI),
("Math.e", Js.Math._E),
("Math.ln2", Js.Math._LN2),
("Math.ln10", Js.Math._LN10),
("Math.log2e", Js.Math._LOG2E),
("Math.log10e", Js.Math._LOG10E),
("Math.sqrt2", Js.Math._SQRT2),
("Math.sqrt1_2", Js.Math._SQRT1_2),
("Math.phi", 1.618033988749895),
("Math.tau", 6.283185307179586),
]
let mathBindings: Bindings.t =
@ -20,4 +19,4 @@ let mathBindings: Bindings.t =
->Bindings.fromArray
let makeBindings = (previousBindings: Bindings.t): Bindings.t =>
previousBindings->Bindings.defineModule("Math", mathBindings)
previousBindings->Bindings.merge(mathBindings)