PR#107 show -> toString

This commit is contained in:
Umur Ozkul 2022-03-30 12:53:36 +02:00
parent 12113cad7e
commit 17ca080ebb
11 changed files with 62 additions and 62 deletions

View File

@ -4,7 +4,7 @@ open Jest
open Expect
let expectEvalToBe = (expr: string, answer: string) =>
Reducer.eval(expr)->ExpressionValue.showResult->expect->toBe(answer)
Reducer.eval(expr)->ExpressionValue.toStringResult->expect->toBe(answer)
describe("builtin", () => {
// All MathJs operators and functions are available for string, number and boolean

View File

@ -5,7 +5,7 @@ open Jest
open Expect
let expectParseToBe = (expr, answer) =>
Parse.parse(expr)->Result.flatMap(Parse.castNodeType)->Parse.showResult->expect->toBe(answer)
Parse.parse(expr)->Result.flatMap(Parse.castNodeType)->Parse.toStringResult->expect->toBe(answer)
describe("MathJs parse", () => {
describe("literals operators paranthesis", () => {

View File

@ -5,10 +5,10 @@ open Jest
open Expect
let expectParseToBe = (expr: string, answer: string) =>
Reducer.parse(expr)->Expression.showResult->expect->toBe(answer)
Reducer.parse(expr)->Expression.toStringResult->expect->toBe(answer)
let expectEvalToBe = (expr: string, answer: string) =>
Reducer.eval(expr)->ExpressionValue.showResult->expect->toBe(answer)
Reducer.eval(expr)->ExpressionValue.toStringResult->expect->toBe(answer)
// Current configuration does not ignore this file so we have to have a test
test("test helpers", () => expect(1)->toBe(1))

View File

@ -3,11 +3,11 @@ open Reducer_TestHelpers
describe("reducer using mathjs parse", () => {
// Test the MathJs parser compatibility
// Those tests show that there is a semantic mapping from MathJs to Expression
// Those tests toString that there is a semantic mapping from MathJs to Expression
// Reducer.parse is called by Reducer.eval
// See https://mathjs.org/docs/expressions/syntax.html
// See https://mathjs.org/docs/reference/functions.html
// Those tests show that we are converting mathjs parse tree to what we need
// Those tests toString that we are converting mathjs parse tree to what we need
describe("expressions", () => {
test("1", () => expectParseToBe("1", "Ok(1)"))

View File

@ -3,9 +3,9 @@ open Jest
open Expect
describe("ExpressionValue", () => {
test("showArgs", () => expect([EvNumber(1.), EvString("a")]->showArgs)->toBe("1, 'a'"))
test("argsToString", () => expect([EvNumber(1.), EvString("a")]->argsToString)->toBe("1, 'a'"))
test("showFunctionCall", () =>
expect(("fn", [EvNumber(1.), EvString("a")])->showFunctionCall)->toBe("fn(1, 'a')")
test("toStringFunctionCall", () =>
expect(("fn", [EvNumber(1.), EvString("a")])->toStringFunctionCall)->toBe("fn(1, 'a')")
)
})

View File

@ -14,16 +14,16 @@ exception TestRescriptException
let callInternal = (call: functionCall): result<'b, errorValue> => {
let callMathJs = (call: functionCall): result<'b, errorValue> =>
switch call {
| ("jsraise", [msg]) => Js.Exn.raiseError(show(msg)) // For Tests
| ("jsraise", [msg]) => Js.Exn.raiseError(toString(msg)) // For Tests
| ("resraise", _) => raise(TestRescriptException) // For Tests
| call => call->showFunctionCall->MathJs.Eval.eval
| call => call->toStringFunctionCall->MathJs.Eval.eval
}
let constructRecord = arrayOfPairs => {
Belt.Array.map(arrayOfPairs, pairValue => {
switch pairValue {
| EvArray([EvString(key), valueValue]) => (key, valueValue)
| _ => ("wrong key type", pairValue->showWithType->EvString)
| _ => ("wrong key type", pairValue->toStringWithType->EvString)
}
})
->Js.Dict.fromArray
@ -52,7 +52,7 @@ let callInternal = (call: functionCall): result<'b, errorValue> => {
arrayAtIndex(aValueArray, fIndex)
| ("$atIndex", [EvRecord(dict), EvArray([EvString(sIndex)])]) => recordAtIndex(dict, sIndex)
| ("$atIndex", [obj, index]) =>
(showWithType(obj) ++ "??~~~~" ++ showWithType(index))->EvString->Ok
(toStringWithType(obj) ++ "??~~~~" ++ toStringWithType(index))->EvString->Ok
| call => callMathJs(call)
}
}

View File

@ -7,7 +7,7 @@ type errorValue =
type t = errorValue
let showError = err =>
let errorToString = err =>
switch err {
| REArrayIndexNotFound(msg, index) => `${msg}: ${Js.String.make(index)}`
| REFunctionExpected(msg) => `Function expected: ${msg}`

View File

@ -13,19 +13,19 @@ type t = expression
/*
Shows the Lisp Code as text lisp code
*/
let rec show = expression =>
let rec toString = expression =>
switch expression {
| T.EList(aList) =>
`(${Belt.List.map(aList, aValue => show(aValue))
`(${Belt.List.map(aList, aValue => toString(aValue))
->Extra.List.interperse(" ")
->Belt.List.toArray
->Js.String.concatMany("")})`
| EValue(aValue) => ExpressionValue.show(aValue)
| EValue(aValue) => ExpressionValue.toString(aValue)
}
let showResult = codeResult =>
let toStringResult = codeResult =>
switch codeResult {
| Ok(a) => `Ok(${show(a)})`
| Ok(a) => `Ok(${toString(a)})`
| Error(m) => `Error(${Js.String.make(m)})`
}

View File

@ -3,8 +3,8 @@ module T = Reducer_Expression_T
type expression = T.expression
type expressionValue = ReducerInterface.ExpressionValue.expressionValue
type t = expression
let show: T.expression => Js.String.t
let showResult: result<T.expression, 'a> => string
let toString: T.expression => Js.String.t
let toStringResult: result<T.expression, 'a> => string
let parse_: (
string,
string => Result.t<'a, Reducer_ErrorValue.t>,

View File

@ -72,52 +72,52 @@ let castNodeType = (node: node) =>
| _ => RETodo(`Argg, unhandled MathJsNode: ${node["type"]}`)->Error
}
let rec show = (mathJsNode: mathJsNode): string => {
let showValue = (a: 'a): string =>
let rec toString = (mathJsNode: mathJsNode): string => {
let toStringValue = (a: 'a): string =>
if Js.typeof(a) == "string" {
`'${Js.String.make(a)}'`
} else {
Js.String.make(a)
}
let showNodeArray = (nodeArray: array<node>): string =>
let toStringNodeArray = (nodeArray: array<node>): string =>
nodeArray
->Belt.Array.map(a => showMathJsNode(a))
->Belt.Array.map(a => toStringMathJsNode(a))
->Extra.Array.interperse(", ")
->Js.String.concatMany("")
let showFunctionNode = (fnode: functionNode): string =>
`${fnode["fn"]}(${fnode["args"]->showNodeArray})`
let toStringFunctionNode = (fnode: functionNode): string =>
`${fnode["fn"]}(${fnode["args"]->toStringNodeArray})`
let showObjectEntry = ((key: string, value: node)): string => `${key}: ${value->showMathJsNode}`
let toStringObjectEntry = ((key: string, value: node)): string => `${key}: ${value->toStringMathJsNode}`
let showObjectNode = (oNode: objectNode): string =>
let toStringObjectNode = (oNode: objectNode): string =>
`{${oNode["properties"]
->Js.Dict.entries
->Belt.Array.map(entry => entry->showObjectEntry)
->Belt.Array.map(entry => entry->toStringObjectEntry)
->Extra.Array.interperse(", ")
->Js.String.concatMany("")}}`
let showIndexNode = (iNode: indexNode): string =>
let toStringIndexNode = (iNode: indexNode): string =>
iNode["dimensions"]
->Belt.Array.map(each => showResult(each->castNodeType))
->Belt.Array.map(each => toStringResult(each->castNodeType))
->Js.String.concatMany("")
switch mathJsNode {
| MjAccessorNode(aNode) => `${aNode["object"]->showMathJsNode}[${aNode["index"]->showIndexNode}]`
| MjArrayNode(aNode) => `[${aNode["items"]->showNodeArray}]`
| MjConstantNode(cNode) => cNode["value"]->showValue
| MjFunctionNode(fNode) => fNode->showFunctionNode
| MjIndexNode(iNode) => iNode->showIndexNode
| MjObjectNode(oNode) => oNode->showObjectNode
| MjOperatorNode(opNode) => opNode->castOperatorNodeToFunctionNode->showFunctionNode
| MjParenthesisNode(pNode) => `(${showMathJsNode(pNode["content"])})`
| MjAccessorNode(aNode) => `${aNode["object"]->toStringMathJsNode}[${aNode["index"]->toStringIndexNode}]`
| MjArrayNode(aNode) => `[${aNode["items"]->toStringNodeArray}]`
| MjConstantNode(cNode) => cNode["value"]->toStringValue
| MjFunctionNode(fNode) => fNode->toStringFunctionNode
| MjIndexNode(iNode) => iNode->toStringIndexNode
| MjObjectNode(oNode) => oNode->toStringObjectNode
| MjOperatorNode(opNode) => opNode->castOperatorNodeToFunctionNode->toStringFunctionNode
| MjParenthesisNode(pNode) => `(${toStringMathJsNode(pNode["content"])})`
| MjSymbolNode(sNode) => sNode["name"]
}
}
and showResult = (rMathJsNode: result<mathJsNode, errorValue>): string =>
and toStringResult = (rMathJsNode: result<mathJsNode, errorValue>): string =>
switch rMathJsNode {
| Error(e) => showError(e)
| Ok(mathJsNode) => show(mathJsNode)
| Error(e) => errorToString(e)
| Ok(mathJsNode) => toString(mathJsNode)
}
and showMathJsNode = node => node->castNodeType->showResult
and toStringMathJsNode = node => node->castNodeType->toStringResult

View File

@ -2,7 +2,7 @@
Irreducible values. Reducer does not know about those. Only used for external calls
This is a configuration to to make external calls of those types
*/
module AE = Reducer_Extra_Array
module Extra_Array = Reducer_Extra_Array
module ErrorValue = Reducer_ErrorValue
type rec expressionValue =
@ -15,7 +15,7 @@ type rec expressionValue =
type functionCall = (string, array<expressionValue>)
let rec show = aValue =>
let rec toString = aValue =>
switch aValue {
| EvBool(aBool) => Js.String.make(aBool)
| EvNumber(aNumber) => Js.String.make(aNumber)
@ -23,38 +23,38 @@ let rec show = aValue =>
| EvSymbol(aString) => `:${aString}`
| EvArray(anArray) => {
let args =
anArray->Belt.Array.map(each => show(each))->AE.interperse(", ")->Js.String.concatMany("")
anArray->Belt.Array.map(each => toString(each))->Extra_Array.interperse(", ")->Js.String.concatMany("")
`[${args}]`
}
| EvRecord(aRecord) => {
let pairs =
aRecord
->Js.Dict.entries
->Belt.Array.map(((eachKey, eachValue)) => `${eachKey}: ${show(eachValue)}`)
->AE.interperse(", ")
->Belt.Array.map(((eachKey, eachValue)) => `${eachKey}: ${toString(eachValue)}`)
->Extra_Array.interperse(", ")
->Js.String.concatMany("")
`{${pairs}}`
}
}
let showWithType = aValue =>
let toStringWithType = aValue =>
switch aValue {
| EvBool(_) => `Bool::${show(aValue)}`
| EvNumber(_) => `Number::${show(aValue)}`
| EvString(_) => `String::${show(aValue)}`
| EvSymbol(_) => `Symbol::${show(aValue)}`
| EvArray(_) => `Array::${show(aValue)}`
| EvRecord(_) => `Record::${show(aValue)}`
| EvBool(_) => `Bool::${toString(aValue)}`
| EvNumber(_) => `Number::${toString(aValue)}`
| EvString(_) => `String::${toString(aValue)}`
| EvSymbol(_) => `Symbol::${toString(aValue)}`
| EvArray(_) => `Array::${toString(aValue)}`
| EvRecord(_) => `Record::${toString(aValue)}`
}
let showArgs = (args: array<expressionValue>): string => {
args->Belt.Array.map(arg => arg->show)->AE.interperse(", ")->Js.String.concatMany("")
let argsToString = (args: array<expressionValue>): string => {
args->Belt.Array.map(arg => arg->toString)->Extra_Array.interperse(", ")->Js.String.concatMany("")
}
let showFunctionCall = ((fn, args)): string => `${fn}(${showArgs(args)})`
let toStringFunctionCall = ((fn, args)): string => `${fn}(${argsToString(args)})`
let showResult = x =>
let toStringResult = x =>
switch x {
| Ok(a) => `Ok(${show(a)})`
| Error(m) => `Error(${ErrorValue.showError(m)})`
| Ok(a) => `Ok(${toString(a)})`
| Error(m) => `Error(${ErrorValue.errorToString(m)})`
}