format
Merge branch 'Umur-reducer-dev' into reducer-dev
This commit is contained in:
commit
e4d1a8eef3
|
@ -6,7 +6,8 @@ open Jest
|
|||
open Expect
|
||||
|
||||
let unwrapRecord = rValue =>
|
||||
rValue->Belt.Result.flatMap(value => switch value {
|
||||
rValue->Belt.Result.flatMap(value =>
|
||||
switch value {
|
||||
| ExpressionValue.EvRecord(aRecord) => Ok(aRecord)
|
||||
| _ => ErrorValue.RETodo("TODO: External bindings must be returned")->Error
|
||||
}
|
||||
|
@ -25,7 +26,12 @@ let expectEvalToBe = (expr: string, answer: string) =>
|
|||
Reducer.evaluate(expr)->ExpressionValue.toStringResult->expect->toBe(answer)
|
||||
|
||||
let expectEvalBindingsToBe = (expr: string, bindings: Reducer.externalBindings, answer: string) =>
|
||||
Reducer.evaluateUsingOptions(expr, ~externalBindings=Some(bindings), ~isPartial=None, ~environment=None)
|
||||
Reducer.evaluateUsingOptions(
|
||||
expr,
|
||||
~externalBindings=Some(bindings),
|
||||
~isPartial=None,
|
||||
~environment=None,
|
||||
)
|
||||
->ExpressionValue.toStringResult
|
||||
->expect
|
||||
->toBe(answer)
|
||||
|
@ -35,7 +41,12 @@ let expectEvalPartialBindingsToBe = (
|
|||
bindings: Reducer.externalBindings,
|
||||
answer: string,
|
||||
) =>
|
||||
Reducer.evaluateUsingOptions(expr, ~externalBindings=Some(bindings), ~isPartial=Some(true), ~environment=None)
|
||||
Reducer.evaluateUsingOptions(
|
||||
expr,
|
||||
~externalBindings=Some(bindings),
|
||||
~isPartial=Some(true),
|
||||
~environment=None,
|
||||
)
|
||||
->unwrapRecord
|
||||
->ExpressionValue.toStringResultRecord
|
||||
->expect
|
||||
|
|
|
@ -16,12 +16,8 @@ type externalBindings = ReducerInterface_ExpressionValue.externalBindings
|
|||
|
||||
@genType
|
||||
let evaluateUsingOptions: (
|
||||
~environment: option<
|
||||
QuriSquiggleLang.ReducerInterface_ExpressionValue.environment,
|
||||
>,
|
||||
~externalBindings: option<
|
||||
QuriSquiggleLang.ReducerInterface_ExpressionValue.externalBindings,
|
||||
>,
|
||||
~environment: option<QuriSquiggleLang.ReducerInterface_ExpressionValue.environment>,
|
||||
~externalBindings: option<QuriSquiggleLang.ReducerInterface_ExpressionValue.externalBindings>,
|
||||
~isPartial: option<bool>,
|
||||
string,
|
||||
) => result<expressionValue, errorValue>
|
||||
|
|
|
@ -60,20 +60,26 @@ let defaultBindings: T.bindings = Belt.Map.String.empty
|
|||
/*
|
||||
Recursively evaluate/reduce the expression (Lisp AST)
|
||||
*/
|
||||
let rec reduceExpression = (expression: t, bindings: T.bindings, environment: environment): result<expressionValue, 'e> => {
|
||||
let rec reduceExpression = (expression: t, bindings: T.bindings, environment: environment): result<
|
||||
expressionValue,
|
||||
'e,
|
||||
> => {
|
||||
/*
|
||||
Macros are like functions but instead of taking values as parameters,
|
||||
they take expressions as parameters and return a new expression.
|
||||
Macros are used to define language building blocks. They are like Lisp macros.
|
||||
*/
|
||||
let doMacroCall = (list: list<t>, bindings: T.bindings, environment: environment): result<t, 'e> =>
|
||||
let doMacroCall = (list: list<t>, bindings: T.bindings, environment: environment): result<
|
||||
t,
|
||||
'e,
|
||||
> =>
|
||||
Reducer_Dispatch_BuiltInMacros.dispatchMacroCall(list, bindings, environment, reduceExpression)
|
||||
|
||||
let applyParametersToLambda = (
|
||||
internal: internalCode,
|
||||
parameters: array<string>,
|
||||
args: list<expressionValue>,
|
||||
environment
|
||||
environment,
|
||||
): result<expressionValue, 'e> => {
|
||||
let expr = castInternalCodeToExpression(internal)
|
||||
let parameterList = parameters->Belt.List.fromArray
|
||||
|
@ -91,9 +97,13 @@ let rec reduceExpression = (expression: t, bindings: T.bindings, environment: en
|
|||
/*
|
||||
After reducing each level of expression(Lisp AST), we have a value list to evaluate
|
||||
*/
|
||||
let reduceValueList = (valueList: list<expressionValue>, environment): result<expressionValue, 'e> =>
|
||||
let reduceValueList = (valueList: list<expressionValue>, environment): result<
|
||||
expressionValue,
|
||||
'e,
|
||||
> =>
|
||||
switch valueList {
|
||||
| list{EvCall(fName), ...args} => (fName, args->Belt.List.toArray)->BuiltIn.dispatch(environment)
|
||||
| list{EvCall(fName), ...args} =>
|
||||
(fName, args->Belt.List.toArray)->BuiltIn.dispatch(environment)
|
||||
// "(lambda(x=>internal) param)"
|
||||
| list{EvLambda((parameters, internal)), ...args} =>
|
||||
applyParametersToLambda(internal, parameters, args, environment)
|
||||
|
@ -153,8 +163,10 @@ let rec reduceExpression = (expression: t, bindings: T.bindings, environment: en
|
|||
)
|
||||
}
|
||||
|
||||
let evalUsingExternalBindingsExpression_ = (aExpression, bindings, environment): result<expressionValue, 'e> =>
|
||||
reduceExpression(aExpression, bindings, environment)
|
||||
let evalUsingExternalBindingsExpression_ = (aExpression, bindings, environment): result<
|
||||
expressionValue,
|
||||
'e,
|
||||
> => reduceExpression(aExpression, bindings, environment)
|
||||
|
||||
/*
|
||||
Evaluates MathJs code via Reducer using bindings and answers the result.
|
||||
|
@ -190,8 +202,8 @@ let evaluateUsingOptions = (
|
|||
~environment: option<ReducerInterface_ExpressionValue.environment>,
|
||||
~externalBindings: option<ReducerInterface_ExpressionValue.externalBindings>,
|
||||
~isPartial: option<bool>,
|
||||
code: string): result<expressionValue, errorValue> => {
|
||||
|
||||
code: string,
|
||||
): result<expressionValue, errorValue> => {
|
||||
let anEnvironment = switch environment {
|
||||
| Some(env) => env
|
||||
| None => ReducerInterface_ExpressionValue.defaultEnvironment
|
||||
|
|
|
@ -25,7 +25,6 @@ type externalBindings = Js.Dict.t<expressionValue>
|
|||
@genType
|
||||
let defaultExternalBindings: externalBindings = Js.Dict.empty()
|
||||
|
||||
|
||||
type functionCall = (string, array<expressionValue>)
|
||||
|
||||
let rec toString = aValue =>
|
||||
|
|
|
@ -14,8 +14,13 @@ type expressionValue = ExpressionValue.expressionValue
|
|||
Map external calls of Reducer
|
||||
*/
|
||||
|
||||
let dispatch = (call: ExpressionValue.functionCall, environment, chain): result<expressionValue, 'e> =>
|
||||
ReducerInterface_GenericDistribution.dispatch(call, environment) |> E.O.default(chain(call, environment))
|
||||
let dispatch = (call: ExpressionValue.functionCall, environment, chain): result<
|
||||
expressionValue,
|
||||
'e,
|
||||
> =>
|
||||
ReducerInterface_GenericDistribution.dispatch(call, environment) |> E.O.default(
|
||||
chain(call, environment),
|
||||
)
|
||||
/*
|
||||
If your dispatch is too big you can divide it into smaller dispatches and pass the call so that it gets called finally.
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
let dispatch: (ReducerInterface_ExpressionValue.functionCall, ReducerInterface_ExpressionValue.environment) => option<
|
||||
result<ReducerInterface_ExpressionValue.expressionValue, Reducer_ErrorValue.errorValue>,
|
||||
>
|
||||
let dispatch: (
|
||||
ReducerInterface_ExpressionValue.functionCall,
|
||||
ReducerInterface_ExpressionValue.environment,
|
||||
) => option<result<ReducerInterface_ExpressionValue.expressionValue, Reducer_ErrorValue.errorValue>>
|
||||
|
|
Loading…
Reference in New Issue
Block a user