Filter arguments passed to mathjs calls by type so that error messages are not too weird

This commit is contained in:
Umur Ozkul 2022-05-21 17:59:15 +02:00
parent feb0284a89
commit 2265254531
4 changed files with 59 additions and 1 deletions

View File

@ -29,3 +29,9 @@ describe("builtin exception", () => {
expectEvalToBe("testZadanga(1)", "Error(JS Exception: Error: Undefined function testZadanga)") expectEvalToBe("testZadanga(1)", "Error(JS Exception: Error: Undefined function testZadanga)")
) )
}) })
Skip.describe("error reporting from collection functions", () => {
testEval("arr = [normal(3,2)]; map(arr, zarathsuzaWasHere)", "")
// FIXME: returns "Error(Function not found: map(Array,Symbol))"
// Actually this error is correct but not informative
})

View File

@ -149,7 +149,8 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce
| ("reduceReverse", [EvArray(aValueArray), initialValue, EvLambda(aLambdaValue)]) => | ("reduceReverse", [EvArray(aValueArray), initialValue, EvLambda(aLambdaValue)]) =>
doReduceReverseArray(aValueArray, initialValue, aLambdaValue) doReduceReverseArray(aValueArray, initialValue, aLambdaValue)
| ("reverse", [EvArray(aValueArray)]) => aValueArray->Belt.Array.reverse->EvArray->Ok | ("reverse", [EvArray(aValueArray)]) => aValueArray->Belt.Array.reverse->EvArray->Ok
| call => callMathJs(call) | (_, [EvBool(_)]) | (_, [EvNumber(_)]) | (_, [EvString(_)]) | (_, [EvBool(_), EvBool(_)]) | (_, [EvNumber(_), EvNumber(_)]) | (_, [EvString(_), EvString(_)]) => callMathJs(call)
| call => Error(REFunctionNotFound(call->functionCallToCallSignature->functionCallSignatureToString)) // Report full type signature as error
} }
} }

View File

@ -7,6 +7,7 @@ type errorValue =
| REOperationError(Operation.operationError) | REOperationError(Operation.operationError)
| REExpressionExpected | REExpressionExpected
| REFunctionExpected(string) | REFunctionExpected(string)
| REFunctionNotFound(string)
| REJavaScriptExn(option<string>, option<string>) // Javascript Exception | REJavaScriptExn(option<string>, option<string>) // Javascript Exception
| REMacroNotFound(string) | REMacroNotFound(string)
| RENotAFunction(string) | RENotAFunction(string)
@ -29,6 +30,7 @@ let errorToString = err =>
| REAssignmentExpected => "Assignment expected" | REAssignmentExpected => "Assignment expected"
| REExpressionExpected => "Expression expected" | REExpressionExpected => "Expression expected"
| REFunctionExpected(msg) => `Function expected: ${msg}` | REFunctionExpected(msg) => `Function expected: ${msg}`
| REFunctionNotFound(msg) => `Function not found: ${msg}`
| REDistributionError(err) => `Distribution Math Error: ${DistributionTypes.Error.toString(err)}` | REDistributionError(err) => `Distribution Math Error: ${DistributionTypes.Error.toString(err)}`
| REOperationError(err) => `Math Error: ${Operation.Error.toString(err)}` | REOperationError(err) => `Math Error: ${Operation.Error.toString(err)}`
| REJavaScriptExn(omsg, oname) => { | REJavaScriptExn(omsg, oname) => {

View File

@ -104,3 +104,52 @@ type environment = DistributionOperation.env
@genType @genType
let defaultEnvironment: environment = DistributionOperation.defaultEnv let defaultEnvironment: environment = DistributionOperation.defaultEnv
type expresionValueType =
| EvtArray
| EvtArrayString
| EvtBool
| EvtCall
| EvtDistribution
| EvtLambda
| EvtNumber
| EvtRecord
| EvtString
| EvtSymbol
type functionCallSignature = CallSignature(string, array<expresionValueType>)
type functionDefinitionSignature = FunctionDefinitionSignature(functionCallSignature, expresionValueType)
let valueToValueType = (value) => switch value {
| EvArray(_) => EvtArray
| EvArrayString(_) => EvtArray
| EvBool(_) => EvtBool
| EvCall(_) => EvtCall
| EvDistribution(_) => EvtDistribution
| EvLambda(_) => EvtLambda
| EvNumber(_) => EvtNumber
| EvRecord(_) => EvtRecord
| EvString(_) => EvtArray
| EvSymbol(_) => EvtSymbol}
let functionCallToCallSignature = (functionCall: functionCall): functionCallSignature => {
let (fn, args) = functionCall
CallSignature(fn, args->Js.Array2.map(valueToValueType))}
let valueTypeToString = (valueType: expresionValueType): string =>
switch valueType {
| EvtArray => `Array`
| EvtArrayString => `ArrayString`
| EvtBool => `Bool`
| EvtCall => `Call`
| EvtDistribution => `Distribution`
| EvtLambda => `Lambda`
| EvtNumber => `Number`
| EvtRecord => `Record`
| EvtString => `String`
| EvtSymbol => `Symbol`
}
let functionCallSignatureToString = (functionCallSignature: functionCallSignature): string => {
let CallSignature(fn, args) = functionCallSignature
`${fn}(${args->Js.Array2.map(valueTypeToString)->Js.Array2.toString})`}