more WIP
This commit is contained in:
parent
fea89abff9
commit
6dc1cea045
|
@ -62,7 +62,7 @@ type function = {
|
||||||
isExperimental: bool,
|
isExperimental: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
type fnNameDict = Js.Dict.t<array<function>>
|
type fnNameDict = Js.Dict.t<array<fnDefinition>>
|
||||||
type registry = {functions: array<function>, fnNameDict: fnNameDict}
|
type registry = {functions: array<function>, fnNameDict: fnNameDict}
|
||||||
|
|
||||||
module FRType = {
|
module FRType = {
|
||||||
|
@ -181,188 +181,6 @@ module FRType = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
This module, Matcher, is fairly lengthy. However, only two functions from it
|
|
||||||
are meant to be used outside of it. These are findMatches and matchToDef in Matches.Registry.
|
|
||||||
The rest of it is just called from those two functions.
|
|
||||||
|
|
||||||
Update: This really should be completely re-done sometime, and tested. It works, but it's pretty messy. I'm sure
|
|
||||||
there are internal bugs, but the end functionality works, so I'm not too worried.
|
|
||||||
*/
|
|
||||||
module Matcher = {
|
|
||||||
module MatchSimple = {
|
|
||||||
type t = DifferentName | SameNameDifferentArguments | FullMatch
|
|
||||||
|
|
||||||
let isFullMatch = (match: t) =>
|
|
||||||
switch match {
|
|
||||||
| FullMatch => true
|
|
||||||
| _ => false
|
|
||||||
}
|
|
||||||
|
|
||||||
let isNameMatchOnly = (match: t) =>
|
|
||||||
switch match {
|
|
||||||
| SameNameDifferentArguments => true
|
|
||||||
| _ => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module Match = {
|
|
||||||
type t<'a, 'b> = DifferentName | SameNameDifferentArguments('a) | FullMatch('b)
|
|
||||||
|
|
||||||
let isFullMatch = (match: t<'a, 'b>): bool =>
|
|
||||||
switch match {
|
|
||||||
| FullMatch(_) => true
|
|
||||||
| _ => false
|
|
||||||
}
|
|
||||||
|
|
||||||
let isNameMatchOnly = (match: t<'a, 'b>) =>
|
|
||||||
switch match {
|
|
||||||
| SameNameDifferentArguments(_) => true
|
|
||||||
| _ => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module FnDefinition = {
|
|
||||||
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<internalExpressionValue>) => {
|
|
||||||
if f.name !== fnName {
|
|
||||||
MatchSimple.DifferentName
|
|
||||||
} else {
|
|
||||||
matchAssumingSameName(f, args)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module Function = {
|
|
||||||
type definitionId = int
|
|
||||||
type match = Match.t<array<definitionId>, definitionId>
|
|
||||||
|
|
||||||
let match = (
|
|
||||||
f: function,
|
|
||||||
nameSpace: option<string>,
|
|
||||||
fnName: string,
|
|
||||||
args: array<internalExpressionValue>,
|
|
||||||
): match => {
|
|
||||||
switch nameSpace {
|
|
||||||
| Some(ns) if ns !== f.nameSpace => Match.DifferentName
|
|
||||||
| _ => {
|
|
||||||
let matchedDefinition = () =>
|
|
||||||
E.A.getIndexBy(f.definitions, r =>
|
|
||||||
MatchSimple.isFullMatch(FnDefinition.match(r, fnName, args))
|
|
||||||
) |> E.O.fmap(r => Match.FullMatch(r))
|
|
||||||
let getMatchedNameOnlyDefinition = () => {
|
|
||||||
let nameMatchIndexes =
|
|
||||||
f.definitions
|
|
||||||
->E.A2.fmapi((index, r) =>
|
|
||||||
MatchSimple.isNameMatchOnly(FnDefinition.match(r, fnName, args))
|
|
||||||
? Some(index)
|
|
||||||
: None
|
|
||||||
)
|
|
||||||
->E.A.O.concatSomes
|
|
||||||
switch nameMatchIndexes {
|
|
||||||
| [] => None
|
|
||||||
| elements => Some(Match.SameNameDifferentArguments(elements))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
E.A.O.firstSomeFnWithDefault(
|
|
||||||
[matchedDefinition, getMatchedNameOnlyDefinition],
|
|
||||||
Match.DifferentName,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module RegistryMatch = {
|
|
||||||
type match = {
|
|
||||||
nameSpace: string,
|
|
||||||
fnName: string,
|
|
||||||
inputIndex: int,
|
|
||||||
}
|
|
||||||
let makeMatch = (nameSpace: string, fnName: string, inputIndex: int) => {
|
|
||||||
nameSpace: nameSpace,
|
|
||||||
fnName: fnName,
|
|
||||||
inputIndex: inputIndex,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module Registry = {
|
|
||||||
let _findExactMatches = (
|
|
||||||
r: registry,
|
|
||||||
nameSpace: option<string>,
|
|
||||||
fnName: string,
|
|
||||||
args: array<internalExpressionValue>,
|
|
||||||
) => {
|
|
||||||
let functionMatchPairs =
|
|
||||||
r.functions->E.A2.fmap(l => (l, Function.match(l, nameSpace, fnName, args)))
|
|
||||||
let fullMatch = functionMatchPairs->E.A.getBy(((_, match)) => Match.isFullMatch(match))
|
|
||||||
fullMatch->E.O.bind(((fn, match)) =>
|
|
||||||
switch match {
|
|
||||||
| FullMatch(index) => Some(RegistryMatch.makeMatch(fn.nameSpace, fn.name, index))
|
|
||||||
| _ => None
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
let _findNameMatches = (
|
|
||||||
r: registry,
|
|
||||||
nameSpace: option<string>,
|
|
||||||
fnName: string,
|
|
||||||
args: array<internalExpressionValue>,
|
|
||||||
) => {
|
|
||||||
let functionMatchPairs =
|
|
||||||
r.functions->E.A2.fmap(l => (l, Function.match(l, nameSpace, fnName, args)))
|
|
||||||
let getNameMatches =
|
|
||||||
functionMatchPairs
|
|
||||||
->E.A2.fmap(((fn, match)) => Match.isNameMatchOnly(match) ? Some((fn, match)) : None)
|
|
||||||
->E.A.O.concatSomes
|
|
||||||
let matches =
|
|
||||||
getNameMatches
|
|
||||||
->E.A2.fmap(((fn, match)) =>
|
|
||||||
switch match {
|
|
||||||
| SameNameDifferentArguments(indexes) =>
|
|
||||||
indexes->E.A2.fmap(index => RegistryMatch.makeMatch(fn.nameSpace, fn.name, index))
|
|
||||||
| _ => []
|
|
||||||
}
|
|
||||||
)
|
|
||||||
->Belt.Array.concatMany
|
|
||||||
E.A.toNoneIfEmpty(matches)
|
|
||||||
}
|
|
||||||
|
|
||||||
let findMatches = (r: registry, fnName: string, args: array<internalExpressionValue>) => {
|
|
||||||
let fnNameInParts = Js.String.split(".", fnName)
|
|
||||||
let fnToSearch = E.A.get(fnNameInParts, 1) |> E.O.default(fnNameInParts[0])
|
|
||||||
let nameSpace = E.A.length(fnNameInParts) > 1 ? Some(fnNameInParts[0]) : None
|
|
||||||
|
|
||||||
switch _findExactMatches(r, nameSpace, fnToSearch, args) {
|
|
||||||
| Some(r) => Match.FullMatch(r)
|
|
||||||
| None =>
|
|
||||||
switch _findNameMatches(r, nameSpace, fnToSearch, args) {
|
|
||||||
| Some(r) => Match.SameNameDifferentArguments(r)
|
|
||||||
| None => Match.DifferentName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let matchToDef = (
|
|
||||||
registry: registry,
|
|
||||||
{nameSpace, fnName, inputIndex}: RegistryMatch.match,
|
|
||||||
): option<fnDefinition> =>
|
|
||||||
registry.functions
|
|
||||||
->E.A.getBy(fn => {
|
|
||||||
nameSpace === fn.nameSpace && fnName === fn.name
|
|
||||||
})
|
|
||||||
->E.O.bind(fn => E.A.get(fn.definitions, inputIndex))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module FnDefinition = {
|
module FnDefinition = {
|
||||||
type t = fnDefinition
|
type t = fnDefinition
|
||||||
|
|
||||||
|
@ -440,13 +258,6 @@ module Function = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module NameSpace = {
|
|
||||||
type t = {name: string, functions: array<function>}
|
|
||||||
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 nameToDefinitions = (t: t, name: string) => definitions(t)->E.A2.filter(r => r.name == name)
|
|
||||||
}
|
|
||||||
|
|
||||||
module Registry = {
|
module Registry = {
|
||||||
let toJson = (r: registry) => r.functions->E.A2.fmap(Function.toJson)
|
let toJson = (r: registry) => r.functions->E.A2.fmap(Function.toJson)
|
||||||
let allExamples = (r: registry) => r.functions->E.A2.fmap(r => r.examples)->E.A.concatMany
|
let allExamples = (r: registry) => r.functions->E.A2.fmap(r => r.examples)->E.A.concatMany
|
||||||
|
@ -454,29 +265,24 @@ module Registry = {
|
||||||
r.functions->E.A2.fmap(fn => fn.examples->E.A2.fmap(example => (fn, example)))->E.A.concatMany
|
r.functions->E.A2.fmap(fn => fn.examples->E.A2.fmap(example => (fn, example)))->E.A.concatMany
|
||||||
|
|
||||||
let _buildFnNameDict = (r: array<function>): fnNameDict => {
|
let _buildFnNameDict = (r: array<function>): fnNameDict => {
|
||||||
let allDefinitionsWithFns =
|
// Sorry for the imperative style of this. But it's much easier/less buggy than the previous version.
|
||||||
r
|
let res: fnNameDict = Js.Dict.empty()
|
||||||
->E.A2.fmap(fn => fn.definitions->E.A2.fmap(definitions => (fn, definitions)))
|
r->Js.Array2.forEach(fn =>
|
||||||
->E.A.concatMany
|
fn.definitions->Js.Array2.forEach(def => {
|
||||||
let functionsWithFnNames =
|
|
||||||
allDefinitionsWithFns
|
|
||||||
->E.A2.fmap(((fn, def)) => {
|
|
||||||
let nameWithNamespace = `${fn.nameSpace}.${def.name}`
|
let nameWithNamespace = `${fn.nameSpace}.${def.name}`
|
||||||
let nameWithoutNamespace = def.name
|
let nameWithoutNamespace = def.name
|
||||||
fn.requiresNamespace
|
let names = fn.requiresNamespace ? [nameWithNamespace] : [nameWithNamespace, nameWithoutNamespace]
|
||||||
? [(nameWithNamespace, fn)]
|
names->Js.Array2.forEach(name => {
|
||||||
: [(nameWithNamespace, fn), (nameWithoutNamespace, fn)]
|
switch res->Js.Dict.get(name) {
|
||||||
|
| Some(fns) => {
|
||||||
|
let _ = fns->Js.Array2.push(def)
|
||||||
|
}
|
||||||
|
| None => res->Js.Dict.set(name, [def])
|
||||||
|
}
|
||||||
|
})
|
||||||
})
|
})
|
||||||
->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)
|
res
|
||||||
})
|
|
||||||
cacheAsArray->Js.Dict.fromArray
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let make = (fns: array<function>): registry => {
|
let make = (fns: array<function>): registry => {
|
||||||
|
@ -484,48 +290,33 @@ module Registry = {
|
||||||
{functions: fns, fnNameDict: dict}
|
{functions: fns, fnNameDict: dict}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
let call = (
|
||||||
There's a (potential+minor) bug here: If a function definition is called outside of the calls
|
registry,
|
||||||
to the registry, then it's possible that there could be a match after the registry is
|
fnName: string,
|
||||||
called. However, for now, we could just call the registry last.
|
args: array<internalExpressionValue>,
|
||||||
*/
|
env: Reducer_T.environment,
|
||||||
let _matchAndRun = (
|
reducer: Reducer_T.reducerFn,
|
||||||
~registry: registry,
|
): result<internalExpressionValue, Reducer_ErrorValue.errorValue> => {
|
||||||
~fnName: string,
|
switch Js.Dict.get(registry.fnNameDict, fnName) {
|
||||||
~args: array<internalExpressionValue>,
|
| Some(definitions) => {
|
||||||
~env: Reducer_T.environment,
|
let showNameMatchDefinitions = () => {
|
||||||
~reducer: Reducer_T.reducerFn,
|
let defsString =
|
||||||
) => {
|
definitions
|
||||||
let relevantFunctions = Js.Dict.get(registry.fnNameDict, fnName) |> E.O.default([])
|
|
||||||
let modified = {functions: relevantFunctions, fnNameDict: registry.fnNameDict}
|
|
||||||
let matchToDef = m => Matcher.Registry.matchToDef(registry, m)
|
|
||||||
let showNameMatchDefinitions = matches => {
|
|
||||||
let defs =
|
|
||||||
matches
|
|
||||||
->E.A2.fmap(matchToDef)
|
|
||||||
->E.A.O.concatSomes
|
|
||||||
->E.A2.fmap(FnDefinition.toString)
|
->E.A2.fmap(FnDefinition.toString)
|
||||||
->E.A2.fmap(r => `[${r}]`)
|
->E.A2.fmap(r => `[${r}]`)
|
||||||
->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: ${defsString}`
|
||||||
}
|
}
|
||||||
|
|
||||||
switch Matcher.Registry.findMatches(modified, fnName, args) {
|
let match = definitions->Js.Array2.find(def => def->FnDefinition.isMatch(args))
|
||||||
| Matcher.Match.FullMatch(match) =>
|
switch match {
|
||||||
match->matchToDef->E.O2.fmap(FnDefinition.run(_, args, env, reducer))
|
| Some(def) => def->FnDefinition.run(args, env, reducer)->E.R2.errMap(e => Reducer_ErrorValue.REOther(e))
|
||||||
| SameNameDifferentArguments(m) => Some(Error(showNameMatchDefinitions(m)))
|
| None => {
|
||||||
| _ => None
|
Reducer_ErrorValue.REOther(showNameMatchDefinitions())->Error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
let dispatch = (
|
| None => Reducer_ErrorValue.RESymbolNotFound(fnName)->Error
|
||||||
registry,
|
}
|
||||||
(fnName, args): ReducerInterface_InternalExpressionValue.functionCall,
|
|
||||||
env: Reducer_T.environment,
|
|
||||||
reducer: Reducer_T.reducerFn,
|
|
||||||
) => {
|
|
||||||
_matchAndRun(~registry, ~fnName, ~args, ~env, ~reducer)->E.O2.fmap(
|
|
||||||
E.R2.errMap(_, s => Reducer_ErrorValue.RETodo(s)),
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,4 +12,4 @@ let fnList = Belt.Array.concatMany([
|
||||||
])
|
])
|
||||||
|
|
||||||
let registry = FunctionRegistry_Core.Registry.make(fnList)
|
let registry = FunctionRegistry_Core.Registry.make(fnList)
|
||||||
let dispatch = FunctionRegistry_Core.Registry.dispatch(registry)
|
let call = FunctionRegistry_Core.Registry.call(registry)
|
||||||
|
|
|
@ -45,6 +45,28 @@ let library = [
|
||||||
},
|
},
|
||||||
()
|
()
|
||||||
),
|
),
|
||||||
|
FnDefinition.make(
|
||||||
|
~name="add",
|
||||||
|
~inputs=[FRTypeNumber, FRTypeNumber],
|
||||||
|
~run=(inputs, _, _, _) => {
|
||||||
|
switch inputs {
|
||||||
|
| [IEvNumber(x), IEvNumber(y)] => IEvNumber(x+.y)->Ok
|
||||||
|
| _ => Error(impossibleError)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
()
|
||||||
|
),
|
||||||
|
FnDefinition.make(
|
||||||
|
~name="add",
|
||||||
|
~inputs=[FRTypeNumber, FRTypeNumber],
|
||||||
|
~run=(inputs, _, _, _) => {
|
||||||
|
switch inputs {
|
||||||
|
| [IEvNumber(x), IEvNumber(y)] => IEvNumber(x+.y)->Ok
|
||||||
|
| _ => Error(impossibleError)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
()
|
||||||
|
),
|
||||||
],
|
],
|
||||||
(),
|
(),
|
||||||
),
|
),
|
||||||
|
|
|
@ -264,7 +264,7 @@ lambda
|
||||||
{ statements.push(finalExpression)
|
{ statements.push(finalExpression)
|
||||||
return h.nodeLambda(args, h.nodeBlock(statements)) }
|
return h.nodeLambda(args, h.nodeBlock(statements)) }
|
||||||
/ '{' _nl '|' _nl args:array_parameters _nl '|' _nl finalExpression: expression _nl '}'
|
/ '{' _nl '|' _nl args:array_parameters _nl '|' _nl finalExpression: expression _nl '}'
|
||||||
{ return h.nodeLambda(args, h.nodeBlock([finalExpression])) }
|
{ return h.nodeLambda(args, finalExpression) }
|
||||||
|
|
||||||
arrayConstructor 'array'
|
arrayConstructor 'array'
|
||||||
= '[' _nl ']'
|
= '[' _nl ']'
|
||||||
|
|
|
@ -29,7 +29,7 @@ type nodeIdentifier = {...node, "value": string}
|
||||||
type nodeInteger = {...node, "value": int}
|
type nodeInteger = {...node, "value": int}
|
||||||
type nodeKeyValue = {...node, "key": node, "value": node}
|
type nodeKeyValue = {...node, "key": node, "value": node}
|
||||||
type nodeRecord = {...node, "elements": array<nodeKeyValue>}
|
type nodeRecord = {...node, "elements": array<nodeKeyValue>}
|
||||||
type nodeLambda = {...node, "args": array<nodeIdentifier>, "body": nodeBlock}
|
type nodeLambda = {...node, "args": array<nodeIdentifier>, "body": node}
|
||||||
type nodeLetStatement = {...node, "variable": nodeIdentifier, "value": node}
|
type nodeLetStatement = {...node, "variable": nodeIdentifier, "value": node}
|
||||||
type nodeModuleIdentifier = {...node, "value": string}
|
type nodeModuleIdentifier = {...node, "value": string}
|
||||||
type nodeString = {...node, "value": string}
|
type nodeString = {...node, "value": string}
|
||||||
|
@ -122,7 +122,7 @@ let rec pgToString = (peggyNode: peggyNode): string => {
|
||||||
| PgNodeInteger(node) => node["value"]->Js.String.make
|
| PgNodeInteger(node) => node["value"]->Js.String.make
|
||||||
| PgNodeKeyValue(node) => toString(node["key"]) ++ ": " ++ toString(node["value"])
|
| PgNodeKeyValue(node) => toString(node["key"]) ++ ": " ++ toString(node["value"])
|
||||||
| PgNodeLambda(node) =>
|
| PgNodeLambda(node) =>
|
||||||
"{|" ++ node["args"]->argsToString ++ "| " ++ pgToString(PgNodeBlock(node["body"])) ++ "}"
|
"{|" ++ node["args"]->argsToString ++ "| " ++ node["body"]->toString ++ "}"
|
||||||
| PgNodeLetStatement(node) =>
|
| PgNodeLetStatement(node) =>
|
||||||
pgToString(PgNodeIdentifier(node["variable"])) ++ " = " ++ toString(node["value"])
|
pgToString(PgNodeIdentifier(node["variable"])) ++ " = " ++ toString(node["value"])
|
||||||
| PgNodeModuleIdentifier(node) => `@${node["value"]}`
|
| PgNodeModuleIdentifier(node) => `@${node["value"]}`
|
||||||
|
|
|
@ -15,7 +15,7 @@ let rec fromNode = (node: Parse.node): expression => {
|
||||||
let args =
|
let args =
|
||||||
nodeLambda["args"]
|
nodeLambda["args"]
|
||||||
->Js.Array2.map((argNode: Parse.nodeIdentifier) => argNode["value"])
|
->Js.Array2.map((argNode: Parse.nodeIdentifier) => argNode["value"])
|
||||||
let body = nodeLambda["body"]->caseBlock
|
let body = nodeLambda["body"]->fromNode
|
||||||
|
|
||||||
ExpressionBuilder.eLambda(args, body)
|
ExpressionBuilder.eLambda(args, body)
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ let dispatch = (
|
||||||
() => ReducerInterface_Date.dispatch(call, environment),
|
() => ReducerInterface_Date.dispatch(call, environment),
|
||||||
() => ReducerInterface_Duration.dispatch(call, environment),
|
() => ReducerInterface_Duration.dispatch(call, environment),
|
||||||
() => ReducerInterface_Number.dispatch(call, environment),
|
() => ReducerInterface_Number.dispatch(call, environment),
|
||||||
() => FunctionRegistry_Library.dispatch(call, environment, reducer),
|
// () => FunctionRegistry_Library.dispatch(call, environment, reducer),
|
||||||
])->E.O2.defaultFn(() => chain(call, environment, reducer))
|
])->E.O2.defaultFn(() => chain(call, environment, reducer))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -63,16 +63,11 @@ let internalStdLib: Reducer_Bindings.t = {
|
||||||
(name) => {
|
(name) => {
|
||||||
let _ = res->Reducer_Bindings.set(name, Reducer_Expression_Lambda.makeFFILambda(
|
let _ = res->Reducer_Bindings.set(name, Reducer_Expression_Lambda.makeFFILambda(
|
||||||
(arguments, environment, reducer) => {
|
(arguments, environment, reducer) => {
|
||||||
switch FunctionRegistry_Library.dispatch((name, arguments), environment, reducer) {
|
switch FunctionRegistry_Library.call(name, arguments, environment, reducer) {
|
||||||
| Some(result) => {
|
|
||||||
switch result {
|
|
||||||
| Ok(value) => value
|
| Ok(value) => value
|
||||||
| Error(error) => error->Reducer_ErrorValue.ErrorException->raise
|
| Error(error) => error->Reducer_ErrorValue.ErrorException->raise
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
| None => Reducer_ErrorValue.RESymbolNotFound("Not found in registry")->Reducer_ErrorValue.ErrorException->raise
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)->Reducer_T.IEvLambda)
|
)->Reducer_T.IEvLambda)
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user