function definition parse (tested)
This commit is contained in:
parent
a915e68049
commit
88b6d49ad3
|
@ -0,0 +1,12 @@
|
|||
open Jest
|
||||
open Reducer_TestHelpers
|
||||
|
||||
describe("Parse function assignment", () => {
|
||||
testParseToBe("f(x)=x", "Ok((:$let :f (:$lambda (x) :x)))")
|
||||
testParseToBe("f(x)=2*x", "Ok((:$let :f (:$lambda (x) (:multiply 2 :x))))")
|
||||
//MathJs does not allow blocks in function definitions
|
||||
})
|
||||
|
||||
Skip.describe("Evaluate function assignment", () => {
|
||||
testParseToBe("f(x)=x; f(1)", "Ok(1)")
|
||||
})
|
|
@ -33,6 +33,7 @@ let dispatchMacroCall = (
|
|||
}
|
||||
| ExpressionT.EValue(_) => expression->Ok
|
||||
| ExpressionT.EBindings(_) => expression->Ok
|
||||
| ExpressionT.EParameters(_) => expression->Ok
|
||||
| ExpressionT.EList(list) => {
|
||||
let racc = list->Belt.List.reduceReverse(Ok(list{}), (racc, each: expression) =>
|
||||
racc->Result.flatMap(acc => {
|
||||
|
|
|
@ -16,6 +16,7 @@ type t = expression
|
|||
let rec toString = expression =>
|
||||
switch expression {
|
||||
| T.EBindings(_) => "$$bound"
|
||||
| T.EParameters(params) => `(${Js.Array2.toString(params->Belt.List.toArray)})`
|
||||
| T.EList(aList) =>
|
||||
`(${Belt.List.map(aList, aValue => toString(aValue))
|
||||
->Extra.List.interperse(" ")
|
||||
|
@ -72,6 +73,7 @@ let rec reduceExpression = (expression: t, bindings: T.bindings): result<express
|
|||
switch expression {
|
||||
| T.EValue(_value) => expression->Ok
|
||||
| T.EBindings(_value) => expression->Ok
|
||||
| T.EParameters(_value) => expression->Ok
|
||||
| T.EList(list) => {
|
||||
let racc: result<list<t>, 'e> = list->Belt.List.reduceReverse(Ok(list{}), (
|
||||
racc,
|
||||
|
@ -108,6 +110,7 @@ let rec reduceExpression = (expression: t, bindings: T.bindings): result<express
|
|||
racc->Result.flatMap(acc => acc->reduceValueList)
|
||||
}
|
||||
| EBindings(_bindings) => RETodo("Error: Bindings cannot be reduced to values")->Error
|
||||
| EParameters(_parameters) => RETodo("Error: Lambda Parameters cannot be reduced to values")->Error
|
||||
}
|
||||
|
||||
let rExpandedExpression: result<t, 'e> = expression->seekMacros(bindings)
|
||||
|
|
|
@ -11,5 +11,6 @@ open ReducerInterface.ExpressionValue
|
|||
type rec expression =
|
||||
| EList(list<expression>) // A list to map-reduce
|
||||
| EValue(expressionValue) // Irreducible built-in value. Reducer should not know the internals. External libraries are responsible
|
||||
| EBindings(bindings) // let/def kind of statements return bindings
|
||||
| EBindings(bindings) // $let kind of statements return bindings; for internal use only
|
||||
| EParameters(list<string>) // for $defun; for internal use only
|
||||
and bindings = Belt.Map.String.t<expression>
|
||||
|
|
|
@ -99,6 +99,19 @@ let rec fromNode = (mathJsNode: Parse.node): result<expression, errorValue> =>
|
|||
})
|
||||
}
|
||||
|
||||
let caseFunctionAssignmentNode = faNode => {
|
||||
let symbol = faNode["name"]->toEvSymbolValue
|
||||
let rValueExpression = fromNode(faNode["expr"])
|
||||
|
||||
rValueExpression->Result.flatMap(valueExpression => {
|
||||
let lispParams = faNode["params"]->Belt.List.fromArray->ExpressionT.EParameters
|
||||
let rLambda = passToFunction("$lambda", list{lispParams, valueExpression}->Ok)
|
||||
rLambda -> Result.flatMap( lambda => {
|
||||
passToFunction("$let", list{symbol, lambda}->Ok)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
let caseArrayNode = aNode => {
|
||||
aNode["items"]->Belt.List.fromArray->fromNodeList->Result.map(list => ExpressionT.EList(list))
|
||||
}
|
||||
|
@ -115,6 +128,7 @@ let rec fromNode = (mathJsNode: Parse.node): result<expression, errorValue> =>
|
|||
| MjBlockNode(bNode) => bNode["blocks"]->Belt.Array.map(toTagOrNode)->caseTagOrNodes
|
||||
| MjConstantNode(cNode) =>
|
||||
cNode["value"]->JavaScript.Gate.jsToEv->Result.flatMap(v => v->ExpressionT.EValue->Ok)
|
||||
| MjFunctionAssignmentNode(faNode) => caseFunctionAssignmentNode(faNode)
|
||||
| MjFunctionNode(fNode) => fNode->caseFunctionNode
|
||||
| MjIndexNode(iNode) => caseIndexNode(iNode)
|
||||
| MjObjectNode(oNode) => caseObjectNode(oNode)
|
||||
|
|
Loading…
Reference in New Issue
Block a user