Simple conversion away from using modules

This commit is contained in:
Ozzie Gooen 2022-07-18 16:10:19 -07:00
parent beb22274d6
commit 30f721eeb6
4 changed files with 73 additions and 86 deletions

View File

@ -529,7 +529,6 @@ export const SquigglePlayground: FC<PlaygroundProps> = ({
const withoutEditor = <div className="mt-3">{tabs}</div>; const withoutEditor = <div className="mt-3">{tabs}</div>;
console.log(vars);
return ( return (
<SquiggleContainer> <SquiggleContainer>
<StyledTab.Group> <StyledTab.Group>

View File

@ -1,7 +1,7 @@
module InternalExpressionValue = ReducerInterface_InternalExpressionValue module InternalExpressionValue = ReducerInterface_InternalExpressionValue
module ExpressionT = Reducer_Expression_T module ExpressionT = Reducer_Expression_T
module Module = Reducer_Module // module Module = Reducer_Module
module Bindings = Reducer_Module // module Bindings = Reducer_Module
module ErrorValue = Reducer_ErrorValue module ErrorValue = Reducer_ErrorValue
open Jest open Jest
@ -50,44 +50,44 @@ module FooImplementation = {
let library = [fn1] let library = [fn1]
} }
let makeBindings = FunctionRegistry_Core.Registry.makeBindings(_, FooImplementation.library) // let makeBindings = FunctionRegistry_Core.Registry.makeBindings(_, FooImplementation.library)
let stdLibWithFoo = Bindings.emptyBindings->makeBindings // let stdLibWithFoo = Bindings.emptyBindings->makeBindings
let evalWithFoo = sourceCode => // let evalWithFoo = sourceCode =>
Reducer_Expression.parse(sourceCode)->Belt.Result.flatMap(expr => // Reducer_Expression.parse(sourceCode)->Belt.Result.flatMap(expr =>
Reducer_Expression.reduceExpression( // Reducer_Expression.reduceExpression(
expr, // expr,
stdLibWithFoo, // stdLibWithFoo,
InternalExpressionValue.defaultEnvironment, // InternalExpressionValue.defaultEnvironment,
) // )
) // )
let evalToStringResultWithFoo = sourceCode => // let evalToStringResultWithFoo = sourceCode =>
evalWithFoo(sourceCode)->InternalExpressionValue.toStringResult // evalWithFoo(sourceCode)->InternalExpressionValue.toStringResult
describe("Module", () => { // describe("Module", () => {
test("add2(1,2)", () => { // test("add2(1,2)", () => {
let result = evalToStringResultWithFoo("Foo.add2(1,2)") // let result = evalToStringResultWithFoo("Foo.add2(1,2)")
expect(result)->toEqual("Ok(3)") // expect(result)->toEqual("Ok(3)")
}) // })
test("add3(1,2,3)", () => { // test("add3(1,2,3)", () => {
let result = evalToStringResultWithFoo("Foo.add3(1,2,3)") // let result = evalToStringResultWithFoo("Foo.add3(1,2,3)")
expect(result)->toEqual("Ok(6)") // expect(result)->toEqual("Ok(6)")
}) // })
}) // })
describe("Fn auto-testing", () => { // describe("Fn auto-testing", () => {
let items = FooImplementation.fn1.examples->E.A.to_list // let items = FooImplementation.fn1.examples->E.A.to_list
testAll("tests of validity", items, r => { // testAll("tests of validity", items, r => {
expect(r->evalWithFoo->E.R.isOk)->toEqual(true) // expect(r->evalWithFoo->E.R.isOk)->toEqual(true)
}) // })
testAll("tests of type", items, r => { // testAll("tests of type", items, r => {
let responseType = // let responseType =
r->evalWithFoo->E.R2.fmap(ReducerInterface_InternalExpressionValue.valueToValueType) // r->evalWithFoo->E.R2.fmap(ReducerInterface_InternalExpressionValue.valueToValueType)
let expectedOutputType = FooImplementation.fn1.output |> E.O.toExn("") // let expectedOutputType = FooImplementation.fn1.output |> E.O.toExn("")
expect(responseType)->toEqual(Ok(expectedOutputType)) // expect(responseType)->toEqual(Ok(expectedOutputType))
}) // })
}) // })

View File

@ -303,10 +303,13 @@ module Matcher = {
} }
let findMatches = (r: registry, fnName: string, args: array<internalExpressionValue>) => { let findMatches = (r: registry, fnName: string, args: array<internalExpressionValue>) => {
switch _findExactMatches(r, fnName, args) { let fnNameInParts = Js.String.split(".", fnName)
let fnToSearch = E.A.get(fnNameInParts, 1) |> E.O.default(fnNameInParts[0])
switch _findExactMatches(r, fnToSearch, args) {
| Some(r) => Match.FullMatch(r) | Some(r) => Match.FullMatch(r)
| None => | None =>
switch _findNameMatches(r, fnName, args) { switch _findNameMatches(r, fnToSearch, args) {
| Some(r) => Match.SameNameDifferentArguments(r) | Some(r) => Match.SameNameDifferentArguments(r)
| None => Match.DifferentName | None => Match.DifferentName
} }
@ -349,9 +352,6 @@ module FnDefinition = {
let toFfiFn = (t: t): Reducer_Expression_T.optionFfiFn => let toFfiFn = (t: t): Reducer_Expression_T.optionFfiFn =>
(args, environment) => run(t, args, environment)->E.R.toOption (args, environment) => run(t, args, environment)->E.R.toOption
let toLambda = (t: t) =>
Reducer_Module.convertOptionToFfiFn(t.name, toFfiFn(t))->Reducer_Module.eLambdaFFIValue
let make = (~name, ~inputs, ~run, ()): t => { let make = (~name, ~inputs, ~run, ()): t => {
name: name, name: name,
inputs: inputs, inputs: inputs,
@ -405,39 +405,40 @@ module NameSpace = {
let definitions = (t: t) => t.functions->E.A2.fmap(f => f.definitions)->E.A.concatMany let definitions = (t: t) => t.functions->E.A2.fmap(f => f.definitions)->E.A.concatMany
let uniqueFnNames = (t: t) => definitions(t)->E.A2.fmap(r => r.name)->E.A.uniq let uniqueFnNames = (t: t) => definitions(t)->E.A2.fmap(r => r.name)->E.A.uniq
let nameToDefinitions = (t: t, name: string) => definitions(t)->E.A2.filter(r => r.name == name) let nameToDefinitions = (t: t, name: string) => definitions(t)->E.A2.filter(r => r.name == name)
//todo: It could be good to set a warning if two definitions are both valid, but I don't expect this often.
let nameFfiFn = (t: t, name: string): Reducer_Expression_T.optionFfiFn => {
(args, environment) => {
let definitions =
nameToDefinitions(t, name)->E.A2.fmap((def, ()) =>
FnDefinition.isMatch(def, args)
? FnDefinition.run(def, args, environment) |> E.R.toOption
: None
)
E.A.O.firstSomeFn(definitions)
}
}
let toModule = (t: t): Reducer_Module.t =>
E.A.reduce(uniqueFnNames(t), Reducer_Module.emptyStdLib, (acc, uniqueName) => {
let relevantDefinitions = nameFfiFn(t, uniqueName)
acc->Reducer_Module.defineFunction(uniqueName, relevantDefinitions)
})
} }
module Registry = { module Registry = {
let toJson = (r: registry) => r->E.A2.fmap(Function.toJson) let toJson = (r: registry) => r->E.A2.fmap(Function.toJson)
let allExamples = (r: registry) => r->E.A2.fmap(r => r.examples)->E.A.concatMany let allExamples = (r: registry) => r->E.A2.fmap(r => r.examples)->E.A.concatMany
let allExamplesWithFns = (r: registry) => let allExamplesWithFns = (r: registry) =>
r->E.A2.fmap(fn => fn.examples->E.A2.fmap(example => (fn, example)))->E.A.concatMany r->E.A2.fmap(fn => fn.examples->E.A2.fmap(example => (fn, example)))->E.A.concatMany
let allDefinitionsWithFns = (r: registry) =>
r->E.A2.fmap(fn => fn.definitions->E.A2.fmap(definitions => (fn, definitions)))->E.A.concatMany
let cache = (r: registry): Js.Dict.t<array<Function.t>> => {
let functionsWithFnNames =
allDefinitionsWithFns(r)
->E.A2.fmap(((fn, def)) => {
let nameWithNamespace = `${fn.nameSpace}.${def.name}`
let nameWithoutNamespace = def.name
fn.requiresNamespace
? [(nameWithNamespace, fn)]
: [(nameWithNamespace, fn), (nameWithoutNamespace, fn)]
})
->E.A.concatMany
let uniqueNames = functionsWithFnNames->E.A2.fmap(((name, _)) => name)->E.A.uniq
let cacheAsArray: array<(string, array<function>)> = uniqueNames->E.A2.fmap(uniqueName => {
let relevantItems =
E.A2.filter(functionsWithFnNames, ((defName, _)) => defName == uniqueName)->E.A2.fmap(
E.Tuple2.second,
)
(uniqueName, relevantItems)
})
cacheAsArray->Js.Dict.fromArray
}
let _exportedSubset = (r: registry): registry => r |> E.A.filter(r => !r.requiresNamespace) let _exportedSubset = (r: registry): registry => r |> E.A.filter(r => !r.requiresNamespace)
let definitionsWithFunctions = (r: registry) =>
r->E.A2.fmap(fn => fn.definitions->E.A2.fmap(def => (def, fn)))->E.A.concatMany
/* /*
There's a (potential+minor) bug here: If a function definition is called outside of the calls There's a (potential+minor) bug here: If a function definition is called outside of the calls
to the registry, then it's possible that there could be a match after the registry is to the registry, then it's possible that there could be a match after the registry is
@ -449,7 +450,10 @@ module Registry = {
~args: array<internalExpressionValue>, ~args: array<internalExpressionValue>,
~env: GenericDist.env, ~env: GenericDist.env,
) => { ) => {
let matchToDef = m => Matcher.Registry.matchToDef(registry, m) let cc = cache(registry)
let relevantFunctions = Js.Dict.get(cc, fnName) |> E.O.default([])
let matchToDef = m => Matcher.Registry.matchToDef(relevantFunctions, m)
let showNameMatchDefinitions = matches => { let showNameMatchDefinitions = matches => {
let defs = let defs =
matches matches
@ -460,7 +464,8 @@ module Registry = {
->E.A2.joinWith("; ") ->E.A2.joinWith("; ")
`There are function matches for ${fnName}(), but with different arguments: ${defs}` `There are function matches for ${fnName}(), but with different arguments: ${defs}`
} }
switch Matcher.Registry.findMatches(registry, fnName, args) {
switch Matcher.Registry.findMatches(relevantFunctions, fnName, args) {
| Matcher.Match.FullMatch(match) => match->matchToDef->E.O2.fmap(FnDefinition.run(_, args, env)) | Matcher.Match.FullMatch(match) => match->matchToDef->E.O2.fmap(FnDefinition.run(_, args, env))
| SameNameDifferentArguments(m) => Some(Error(showNameMatchDefinitions(m))) | SameNameDifferentArguments(m) => Some(Error(showNameMatchDefinitions(m)))
| _ => None | _ => None
@ -476,20 +481,4 @@ module Registry = {
E.R2.errMap(_, s => Reducer_ErrorValue.RETodo(s)), E.R2.errMap(_, s => Reducer_ErrorValue.RETodo(s)),
) )
} }
let allNamespaces = (t: registry) => t->E.A2.fmap(r => r.nameSpace)->E.A.uniq
let makeBindings = (prevBindings: Reducer_Module.t, t: registry): Reducer_Module.t => {
let nameSpaces = allNamespaces(t)
let nameSpaceBindings = nameSpaces->E.A2.fmap(nameSpace => {
let namespaceModule: NameSpace.t = {
name: nameSpace,
functions: t->E.A2.filter(r => r.nameSpace == nameSpace),
}
(nameSpace, NameSpace.toModule(namespaceModule))
})
E.A.reduce(nameSpaceBindings, prevBindings, (acc, (name, fn)) =>
acc->Reducer_Module.defineModule(name, fn)
)
}
} }

View File

@ -1,7 +1,6 @@
module Bindings = Reducer_Bindings module Bindings = Reducer_Bindings
let internalStdLib = Bindings.emptyBindings->SquiggleLibrary_Math.makeBindings let internalStdLib = Bindings.emptyBindings->SquiggleLibrary_Math.makeBindings
->FunctionRegistry_Core.Registry.makeBindings(FunctionRegistry_Library.registry)
@genType @genType
let externalStdLib = internalStdLib->Bindings.toTypeScriptBindings let externalStdLib = internalStdLib->Bindings.toTypeScriptBindings