refactor passToFunction
This commit is contained in:
parent
d214bddc82
commit
1fb9218a94
|
@ -34,25 +34,25 @@ let rec replaceSymbols = (expression: expression, bindings: ExpressionT.bindings
|
||||||
): ExpressionT.bindings =>
|
): ExpressionT.bindings =>
|
||||||
Belt.Map.String.set(bindings, "$parameters", ExpressionT.EParameters(parameters))
|
Belt.Map.String.set(bindings, "$parameters", ExpressionT.EParameters(parameters))
|
||||||
|
|
||||||
let answerBindingIfNotParameter = (aSymbol, defaultExpression, parameters, bindings) =>
|
let answerBindingIfNotParameter = (aSymbol, defaultExpression, parameters, bindings) =>
|
||||||
switch Js.Array2.some(parameters, a => a == aSymbol) {
|
switch Js.Array2.some(parameters, a => a == aSymbol) {
|
||||||
| true => defaultExpression->Ok // We cannot bind the parameters with global values
|
| true => defaultExpression->Ok // We cannot bind the parameters with global values
|
||||||
| false =>
|
| false =>
|
||||||
switch bindings->Belt.Map.String.get(aSymbol) {
|
switch bindings->Belt.Map.String.get(aSymbol) {
|
||||||
| Some(boundExpression) => boundExpression->Ok
|
| Some(boundExpression) => boundExpression->Ok
|
||||||
| None => RESymbolNotFound(aSymbol)->Error
|
| None => RESymbolNotFound(aSymbol)->Error
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let answerCallBindingIfNotParameter = (aSymbol, defaultExpression, parameters, bindings) =>
|
let answerCallBindingIfNotParameter = (aSymbol, defaultExpression, parameters, bindings) =>
|
||||||
switch Js.Array2.some(parameters, a => a == aSymbol) {
|
switch Js.Array2.some(parameters, a => a == aSymbol) {
|
||||||
| true => defaultExpression->Ok // We cannot bind the parameters with global values
|
| true => defaultExpression->Ok // We cannot bind the parameters with global values
|
||||||
| false =>
|
| false =>
|
||||||
switch bindings->Belt.Map.String.get(aSymbol) {
|
switch bindings->Belt.Map.String.get(aSymbol) {
|
||||||
| Some(boundExpression) => boundExpression->Ok
|
| Some(boundExpression) => boundExpression->Ok
|
||||||
| None => defaultExpression->Ok
|
| None => defaultExpression->Ok
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch expression {
|
switch expression {
|
||||||
| ExpressionT.EValue(EvSymbol(aSymbol)) => {
|
| ExpressionT.EValue(EvSymbol(aSymbol)) => {
|
||||||
|
|
|
@ -12,7 +12,7 @@ type internalCode = ExpressionValue.internalCode
|
||||||
type t = expression
|
type t = expression
|
||||||
|
|
||||||
external castExpressionToInternalCode: expression => internalCode = "%identity"
|
external castExpressionToInternalCode: expression => internalCode = "%identity"
|
||||||
external castInternalCodeToInternalCode: internalCode => expression = "%identity"
|
external castInternalCodeToExpression: internalCode => expression = "%identity"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Shows the expression as text of expression
|
Shows the expression as text of expression
|
||||||
|
@ -64,12 +64,36 @@ let rec reduceExpression = (expression: t, bindings: T.bindings): result<express
|
||||||
let doMacroCall = (list: list<t>, bindings: T.bindings): result<t, 'e> =>
|
let doMacroCall = (list: list<t>, bindings: T.bindings): result<t, 'e> =>
|
||||||
Reducer_Dispatch_BuiltInMacros.dispatchMacroCall(list, bindings, reduceExpression)
|
Reducer_Dispatch_BuiltInMacros.dispatchMacroCall(list, bindings, reduceExpression)
|
||||||
|
|
||||||
|
let applyParametersToLambda = (
|
||||||
|
internal: internalCode,
|
||||||
|
parameters: array<string>,
|
||||||
|
args: list<expressionValue>,
|
||||||
|
): result<expressionValue, 'e> => {
|
||||||
|
let expr = castInternalCodeToExpression(internal)
|
||||||
|
let parameterList = parameters->Belt.List.fromArray
|
||||||
|
let zippedParameterList = parameterList->Belt.List.zip(args)
|
||||||
|
let bindings = Belt.List.reduce(zippedParameterList, defaultBindings, (a, (p, e)) =>
|
||||||
|
a->Belt.Map.String.set(p, e->EValue)
|
||||||
|
)
|
||||||
|
Js.log(`applyParametersToLambda: ${toString(expr)}`)
|
||||||
|
let inspectBindings =
|
||||||
|
bindings
|
||||||
|
->Belt.Map.String.mapWithKey((k, v) => `${k}: ${toString(v)}`)
|
||||||
|
->Belt.Map.String.valuesToArray
|
||||||
|
->Js.Array2.toString
|
||||||
|
Js.log(` inspectBindings: ${inspectBindings}`)
|
||||||
|
reduceExpression(expr, bindings)
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
After reducing each level of expression(Lisp AST), we have a value list to evaluate
|
After reducing each level of expression(Lisp AST), we have a value list to evaluate
|
||||||
*/
|
*/
|
||||||
let reduceValueList = (valueList: list<expressionValue>): result<expressionValue, 'e> =>
|
let reduceValueList = (valueList: list<expressionValue>): result<expressionValue, 'e> =>
|
||||||
switch valueList {
|
switch valueList {
|
||||||
| list{EvCall(fName), ...args} => (fName, args->Belt.List.toArray)->BuiltIn.dispatch
|
| list{EvCall(fName), ...args} => (fName, args->Belt.List.toArray)->BuiltIn.dispatch
|
||||||
|
// "(lambda(x=>internal) param)"
|
||||||
|
| list{EvLambda(parameters, internal), ...args} =>
|
||||||
|
applyParametersToLambda(internal, parameters, args)
|
||||||
| _ => valueList->Belt.List.toArray->ExpressionValue.EvArray->Ok
|
| _ => valueList->Belt.List.toArray->ExpressionValue.EvArray->Ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,11 +121,8 @@ let rec reduceExpression = (expression: t, bindings: T.bindings): result<express
|
||||||
|
|
||||||
let rec reduceExpandedExpression = (expression: t): result<expressionValue, 'e> =>
|
let rec reduceExpandedExpression = (expression: t): result<expressionValue, 'e> =>
|
||||||
switch expression {
|
switch expression {
|
||||||
| T.EList(list{
|
| T.EList(list{T.EValue(EvCall("$lambda")), T.EParameters(parameters), functionDefinition}) =>
|
||||||
T.EValue(EvCall("$lambda")),
|
EvLambda(parameters, functionDefinition->castExpressionToInternalCode)->Ok
|
||||||
T.EParameters(parameters),
|
|
||||||
functionDefinition,
|
|
||||||
}) => EvLambda(parameters, functionDefinition->castExpressionToInternalCode)->Ok
|
|
||||||
| T.EValue(value) => value->Ok
|
| T.EValue(value) => value->Ok
|
||||||
| T.EList(list) => {
|
| T.EList(list) => {
|
||||||
let racc: result<list<expressionValue>, 'e> = list->Belt.List.reduceReverse(Ok(list{}), (
|
let racc: result<list<expressionValue>, 'e> = list->Belt.List.reduceReverse(Ok(list{}), (
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
module ErrorValue = Reducer_ErrorValue
|
||||||
|
module ExpressionT = Reducer_Expression_T
|
||||||
|
module ExpressionValue = ReducerInterface.ExpressionValue
|
||||||
|
module Result = Belt.Result
|
||||||
|
|
||||||
|
type errorValue = ErrorValue.errorValue
|
||||||
|
type expression = ExpressionT.expression
|
||||||
|
|
||||||
|
let passToFunction = (fName: string, lispArgs: list<expression>): expression => {
|
||||||
|
let toEvCallValue = (name: string): expression => name->ExpressionValue.EvCall->ExpressionT.EValue
|
||||||
|
let fn = fName->toEvCallValue
|
||||||
|
list{fn, ...lispArgs}->ExpressionT.EList
|
||||||
|
}
|
||||||
|
|
||||||
|
let toEvSymbolValue = (name: string): expression =>
|
||||||
|
name->ExpressionValue.EvSymbol->ExpressionT.EValue
|
|
@ -1,6 +1,7 @@
|
||||||
|
module Builder = Reducer_Expression_Builder
|
||||||
module ErrorValue = Reducer_ErrorValue
|
module ErrorValue = Reducer_ErrorValue
|
||||||
module ExpressionValue = ReducerInterface.ExpressionValue
|
|
||||||
module ExpressionT = Reducer_Expression_T
|
module ExpressionT = Reducer_Expression_T
|
||||||
|
module ExpressionValue = ReducerInterface.ExpressionValue
|
||||||
module JavaScript = Reducer_Js
|
module JavaScript = Reducer_Js
|
||||||
module Parse = Reducer_MathJs_Parse
|
module Parse = Reducer_MathJs_Parse
|
||||||
module Result = Belt.Result
|
module Result = Belt.Result
|
||||||
|
@ -9,13 +10,6 @@ type expression = ExpressionT.expression
|
||||||
type expressionValue = ExpressionValue.expressionValue
|
type expressionValue = ExpressionValue.expressionValue
|
||||||
type errorValue = ErrorValue.errorValue
|
type errorValue = ErrorValue.errorValue
|
||||||
|
|
||||||
let passToFunction = (fName: string, rLispArgs): result<expression, errorValue> => {
|
|
||||||
let toEvCallValue = (name: string): expression => name->ExpressionValue.EvCall->ExpressionT.EValue
|
|
||||||
|
|
||||||
let fn = fName->toEvCallValue
|
|
||||||
rLispArgs->Result.flatMap(lispArgs => list{fn, ...lispArgs}->ExpressionT.EList->Ok)
|
|
||||||
}
|
|
||||||
|
|
||||||
type blockTag =
|
type blockTag =
|
||||||
| ImportVariablesStatement
|
| ImportVariablesStatement
|
||||||
| ExportVariablesExpression
|
| ExportVariablesExpression
|
||||||
|
@ -34,12 +28,11 @@ let rec fromNode = (mathJsNode: Parse.node): result<expression, errorValue> =>
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
let toEvSymbolValue = (name: string): expression =>
|
|
||||||
name->ExpressionValue.EvSymbol->ExpressionT.EValue
|
|
||||||
|
|
||||||
let caseFunctionNode = fNode => {
|
let caseFunctionNode = fNode => {
|
||||||
let lispArgs = fNode["args"]->Belt.List.fromArray->fromNodeList
|
let rLispArgs = fNode["args"]->Belt.List.fromArray->fromNodeList
|
||||||
passToFunction(fNode->Parse.nameOfFunctionNode, lispArgs)
|
rLispArgs->Result.flatMap(lispArgs =>
|
||||||
|
Builder.passToFunction(fNode->Parse.nameOfFunctionNode, lispArgs)->Ok
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
let caseObjectNode = oNode => {
|
let caseObjectNode = oNode => {
|
||||||
|
@ -60,8 +53,8 @@ let rec fromNode = (mathJsNode: Parse.node): result<expression, errorValue> =>
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
rargs->Result.flatMap(args =>
|
rargs->Result.flatMap(args =>
|
||||||
passToFunction("$constructRecord", list{ExpressionT.EList(args)}->Ok)
|
Builder.passToFunction("$constructRecord", list{ExpressionT.EList(args)})->Ok
|
||||||
) // $consturctRecord gets a single argument: List of key-value paiers
|
) // $constructRecord gets a single argument: List of key-value paiers
|
||||||
}
|
}
|
||||||
|
|
||||||
oNode["properties"]->Js.Dict.entries->Belt.List.fromArray->fromObjectEntries
|
oNode["properties"]->Js.Dict.entries->Belt.List.fromArray->fromObjectEntries
|
||||||
|
@ -85,30 +78,27 @@ let rec fromNode = (mathJsNode: Parse.node): result<expression, errorValue> =>
|
||||||
let caseAccessorNode = (objectNode, indexNode) => {
|
let caseAccessorNode = (objectNode, indexNode) => {
|
||||||
caseIndexNode(indexNode)->Result.flatMap(indexCode => {
|
caseIndexNode(indexNode)->Result.flatMap(indexCode => {
|
||||||
fromNode(objectNode)->Result.flatMap(objectCode =>
|
fromNode(objectNode)->Result.flatMap(objectCode =>
|
||||||
passToFunction("$atIndex", list{objectCode, indexCode}->Ok)
|
Builder.passToFunction("$atIndex", list{objectCode, indexCode})->Ok
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
let caseAssignmentNode = aNode => {
|
let caseAssignmentNode = aNode => {
|
||||||
let symbol = aNode["object"]["name"]->toEvSymbolValue
|
let symbol = aNode["object"]["name"]->Builder.toEvSymbolValue
|
||||||
let rValueExpression = fromNode(aNode["value"])
|
let rValueExpression = fromNode(aNode["value"])
|
||||||
rValueExpression->Result.flatMap(valueExpression => {
|
rValueExpression->Result.flatMap(valueExpression =>
|
||||||
let lispArgs = list{symbol, valueExpression}->Ok
|
Builder.passToFunction("$let", list{symbol, valueExpression})->Ok
|
||||||
passToFunction("$let", lispArgs)
|
)
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let caseFunctionAssignmentNode = faNode => {
|
let caseFunctionAssignmentNode = faNode => {
|
||||||
let symbol = faNode["name"]->toEvSymbolValue
|
let symbol = faNode["name"]->Builder.toEvSymbolValue
|
||||||
let rValueExpression = fromNode(faNode["expr"])
|
let rValueExpression = fromNode(faNode["expr"])
|
||||||
|
|
||||||
rValueExpression->Result.flatMap(valueExpression => {
|
rValueExpression->Result.flatMap(valueExpression => {
|
||||||
let lispParams = faNode["params"]->ExpressionT.EParameters
|
let lispParams = faNode["params"]->ExpressionT.EParameters
|
||||||
let rLambda = passToFunction("$lambda", list{lispParams, valueExpression}->Ok)
|
let lambda = Builder.passToFunction("$lambda", list{lispParams, valueExpression})
|
||||||
rLambda->Result.flatMap(lambda => {
|
Builder.passToFunction("$let", list{symbol, lambda})->Ok
|
||||||
passToFunction("$let", list{symbol, lambda}->Ok)
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +111,7 @@ let rec fromNode = (mathJsNode: Parse.node): result<expression, errorValue> =>
|
||||||
| MjArrayNode(aNode) => caseArrayNode(aNode)
|
| MjArrayNode(aNode) => caseArrayNode(aNode)
|
||||||
| MjAssignmentNode(aNode) => caseAssignmentNode(aNode)
|
| MjAssignmentNode(aNode) => caseAssignmentNode(aNode)
|
||||||
| MjSymbolNode(sNode) => {
|
| MjSymbolNode(sNode) => {
|
||||||
let expr: expression = toEvSymbolValue(sNode["name"])
|
let expr: expression = Builder.toEvSymbolValue(sNode["name"])
|
||||||
let rExpr: result<expression, errorValue> = expr->Ok
|
let rExpr: result<expression, errorValue> = expr->Ok
|
||||||
rExpr
|
rExpr
|
||||||
}
|
}
|
||||||
|
@ -138,7 +128,7 @@ let rec fromNode = (mathJsNode: Parse.node): result<expression, errorValue> =>
|
||||||
rFinalExpression
|
rFinalExpression
|
||||||
})
|
})
|
||||||
and caseTagOrNodes = (tagOrNodes): result<expression, errorValue> => {
|
and caseTagOrNodes = (tagOrNodes): result<expression, errorValue> => {
|
||||||
let initialBindings = passToFunction("$$bindings", list{}->Ok)
|
let initialBindings = Builder.passToFunction("$$bindings", list{})->Ok
|
||||||
let lastIndex = Belt.Array.length(tagOrNodes) - 1
|
let lastIndex = Belt.Array.length(tagOrNodes) - 1
|
||||||
tagOrNodes->Belt.Array.reduceWithIndex(initialBindings, (rPreviousBindings, tagOrNode, i) => {
|
tagOrNodes->Belt.Array.reduceWithIndex(initialBindings, (rPreviousBindings, tagOrNode, i) => {
|
||||||
rPreviousBindings->Result.flatMap(previousBindings => {
|
rPreviousBindings->Result.flatMap(previousBindings => {
|
||||||
|
@ -146,8 +136,10 @@ and caseTagOrNodes = (tagOrNodes): result<expression, errorValue> => {
|
||||||
| BlockNode(node) => fromNode(node)
|
| BlockNode(node) => fromNode(node)
|
||||||
| BlockTag(tag) =>
|
| BlockTag(tag) =>
|
||||||
switch tag {
|
switch tag {
|
||||||
| ImportVariablesStatement => passToFunction("$importVariablesStatement", list{}->Ok)
|
| ImportVariablesStatement =>
|
||||||
| ExportVariablesExpression => passToFunction("$exportVariablesExpression", list{}->Ok)
|
Builder.passToFunction("$importVariablesStatement", list{})->Ok
|
||||||
|
| ExportVariablesExpression =>
|
||||||
|
Builder.passToFunction("$exportVariablesExpression", list{})->Ok
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,8 +150,7 @@ and caseTagOrNodes = (tagOrNodes): result<expression, errorValue> => {
|
||||||
}
|
}
|
||||||
|
|
||||||
rStatement->Result.flatMap((statement: expression) => {
|
rStatement->Result.flatMap((statement: expression) => {
|
||||||
let lispArgs = list{previousBindings, statement}->Ok
|
Builder.passToFunction(bindName, list{previousBindings, statement})->Ok
|
||||||
passToFunction(bindName, lispArgs)
|
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
Loading…
Reference in New Issue
Block a user