squiggle/packages/squiggle-lang/src/rescript/Reducer/Reducer_Bindings/Reducer_Bindings.res

188 lines
6.0 KiB
Plaintext
Raw Normal View History

2022-07-18 16:16:49 +00:00
// Only Bindings as the global module is supported
// Other module operations such as import export will be prepreocessed jobs
module ExpressionT = Reducer_Expression_T
2022-07-05 02:30:08 +00:00
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
open Reducer_ErrorValue
open ReducerInterface_InternalExpressionValue
2022-06-27 00:40:31 +00:00
let expressionValueToString = toString
type t = ReducerInterface_InternalExpressionValue.nameSpace
let typeAliasesKey = "_typeAliases_"
let typeReferencesKey = "_typeReferences_"
let getType = (nameSpace: t, id: string) => {
let NameSpace(container) = nameSpace
Belt.Map.String.get(container, typeAliasesKey)->Belt.Option.flatMap(aliases =>
switch aliases {
2022-06-23 18:38:07 +00:00
| IEvRecord(r) => Belt.Map.String.get(r, id)
| _ => None
}
)
}
let getTypeOf = (nameSpace: t, id: string) => {
let NameSpace(container) = nameSpace
Belt.Map.String.get(container, typeReferencesKey)->Belt.Option.flatMap(defs =>
switch defs {
2022-06-23 18:38:07 +00:00
| IEvRecord(r) => Belt.Map.String.get(r, id)
| _ => None
}
)
}
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
2022-06-23 18:38:07 +00:00
let rValue = Belt.Map.String.getWithDefault(container, typeAliasesKey, IEvRecord(emptyMap))
let r = switch rValue {
2022-06-23 18:38:07 +00:00
| IEvRecord(r) => r
| _ => emptyMap
}
2022-06-23 18:38:07 +00:00
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
2022-06-23 18:38:07 +00:00
let rValue = Belt.Map.String.getWithDefault(container, typeReferencesKey, IEvRecord(emptyMap))
let r = switch rValue {
2022-06-23 18:38:07 +00:00
| IEvRecord(r) => r
| _ => emptyMap
}
2022-06-23 18:38:07 +00:00
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
}
2022-06-27 00:40:31 +00:00
let emptyModule: t = NameSpace(emptyMap)
2022-07-05 02:30:08 +00:00
let emptyBindings = emptyModule
let fromTypeScriptBindings = ReducerInterface_InternalExpressionValue.nameSpaceFromTypeScriptBindings
let toTypeScriptBindings = ReducerInterface_InternalExpressionValue.nameSpaceToTypeScriptBindings
let toExpressionValue = (nameSpace: t): internalExpressionValue => IEvBindings(nameSpace)
2022-06-24 10:15:38 +00:00
let fromExpressionValue = (aValue: internalExpressionValue): t =>
switch aValue {
| IEvBindings(nameSpace) => nameSpace
| _ => emptyModule
}
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
}
2022-06-27 00:40:31 +00:00
external castExpressionToInternalCode: ExpressionT.expressionOrFFI => internalCode = "%identity"
let eLambdaFFIValue = (ffiFn: ExpressionT.ffiFn) => {
IEvLambda({
parameters: [],
context: emptyModule,
body: FFI(ffiFn)->castExpressionToInternalCode,
})
}
2022-07-05 02:30:08 +00:00
let functionNotFoundError = (call: functionCall) =>
REFunctionNotFound(call->functionCallToCallSignature->functionCallSignatureToString)->Error
let functionNotFoundErrorFFIFn = (functionName: string): ExpressionT.ffiFn => {
(args: array<internalExpressionValue>, _environment: environment): result<
internalExpressionValue,
errorValue,
> => {
let call = (functionName, args)
functionNotFoundError(call)
}
}
2022-07-11 15:45:26 +00:00
let convertOptionToFfiFnReturningResult = (
myFunctionName: string,
myFunction: ExpressionT.optionFfiFnReturningResult,
): ExpressionT.ffiFn => {
(args: array<InternalExpressionValue.t>, environment) => {
myFunction(args, environment)->Belt.Option.getWithDefault(
functionNotFoundErrorFFIFn(myFunctionName)(args, environment),
)
}
}
2022-07-05 02:30:08 +00:00
let convertOptionToFfiFn = (
myFunctionName: string,
myFunction: ExpressionT.optionFfiFn,
): ExpressionT.ffiFn => {
(args: array<InternalExpressionValue.t>, environment) => {
myFunction(args, environment)
->Belt.Option.map(v => v->Ok)
->Belt.Option.getWithDefault(functionNotFoundErrorFFIFn(myFunctionName)(args, environment))
}
}
// -- Module definition
2022-06-24 10:15:38 +00:00
let define = (nameSpace: t, identifier: string, ev: internalExpressionValue): t => {
let NameSpace(container) = nameSpace
2022-06-27 00:40:31 +00:00
Belt.Map.String.set(container, identifier, ev)->NameSpace
}
2022-07-05 02:30:08 +00:00
let defineNumber = (nameSpace: t, identifier: string, value: float): t =>
2022-06-23 18:38:07 +00:00
nameSpace->define(identifier, IEvNumber(value))
2022-07-05 02:30:08 +00:00
let defineString = (nameSpace: t, identifier: string, value: string): t =>
nameSpace->define(identifier, IEvString(value))
let defineBool = (nameSpace: t, identifier: string, value: bool): t =>
nameSpace->define(identifier, IEvBool(value))
let defineModule = (nameSpace: t, identifier: string, value: t): t =>
nameSpace->define(identifier, toExpressionValue(value))
2022-06-27 00:40:31 +00:00
2022-07-05 02:30:08 +00:00
let defineFunction = (nameSpace: t, identifier: string, value: ExpressionT.optionFfiFn): t => {
nameSpace->define(identifier, convertOptionToFfiFn(identifier, value)->eLambdaFFIValue)
}
2022-07-11 15:45:26 +00:00
let defineFunctionReturningResult = (
nameSpace: t,
identifier: string,
value: ExpressionT.optionFfiFnReturningResult,
): t => {
nameSpace->define(
identifier,
convertOptionToFfiFnReturningResult(identifier, value)->eLambdaFFIValue,
)
}
let emptyStdLib: t = emptyModule->defineBool("_standardLibrary", true)