From 226525453113e7d2a52502f5d98d86cbb6c89a3c Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Sat, 21 May 2022 17:59:15 +0200 Subject: [PATCH] Filter arguments passed to mathjs calls by type so that error messages are not too weird --- .../Reducer_Dispatch_BuiltIn_test.res | 6 +++ .../Reducer_Dispatch_BuiltIn.res | 3 +- .../rescript/Reducer/Reducer_ErrorValue.res | 2 + .../ReducerInterface_ExpressionValue.res | 49 +++++++++++++++++++ 4 files changed, 59 insertions(+), 1 deletion(-) diff --git a/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res b/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res index 0b4ab55a..535f9e56 100644 --- a/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res +++ b/packages/squiggle-lang/__tests__/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn_test.res @@ -29,3 +29,9 @@ describe("builtin exception", () => { 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 +}) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res index 203d2c37..72d599ca 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltIn.res @@ -149,7 +149,8 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce | ("reduceReverse", [EvArray(aValueArray), initialValue, EvLambda(aLambdaValue)]) => doReduceReverseArray(aValueArray, initialValue, aLambdaValue) | ("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 } } diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res index d36ca5c4..fc2f86f1 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_ErrorValue.res @@ -7,6 +7,7 @@ type errorValue = | REOperationError(Operation.operationError) | REExpressionExpected | REFunctionExpected(string) + | REFunctionNotFound(string) | REJavaScriptExn(option, option) // Javascript Exception | REMacroNotFound(string) | RENotAFunction(string) @@ -29,6 +30,7 @@ let errorToString = err => | REAssignmentExpected => "Assignment expected" | REExpressionExpected => "Expression expected" | REFunctionExpected(msg) => `Function expected: ${msg}` + | REFunctionNotFound(msg) => `Function not found: ${msg}` | REDistributionError(err) => `Distribution Math Error: ${DistributionTypes.Error.toString(err)}` | REOperationError(err) => `Math Error: ${Operation.Error.toString(err)}` | REJavaScriptExn(omsg, oname) => { diff --git a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res index 730cac2a..958b99df 100644 --- a/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res +++ b/packages/squiggle-lang/src/rescript/ReducerInterface/ReducerInterface_ExpressionValue.res @@ -104,3 +104,52 @@ type environment = DistributionOperation.env @genType let defaultEnvironment: environment = DistributionOperation.defaultEnv + +type expresionValueType = + | EvtArray + | EvtArrayString + | EvtBool + | EvtCall + | EvtDistribution + | EvtLambda + | EvtNumber + | EvtRecord + | EvtString + | EvtSymbol + +type functionCallSignature = CallSignature(string, array) +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})`} \ No newline at end of file