From 1f989de11c4fcfd87cbec1a96339ce870b4efb1c Mon Sep 17 00:00:00 2001 From: Umur Ozkul Date: Mon, 25 Apr 2022 01:53:37 +0200 Subject: [PATCH] lambda binding --- .../Reducer_Dispatch_BuiltInMacros.res | 88 +++++++++++++------ .../Reducer_Expression/Reducer_Expression.res | 3 + 2 files changed, 65 insertions(+), 26 deletions(-) diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res index 7da85124..a17036de 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res @@ -16,37 +16,73 @@ type reducerFn = ( ExpressionT.bindings, ) => result +let rec replaceSymbols = (expression: expression, bindings: ExpressionT.bindings): result< + expression, + errorValue, +> => { + let getParameters = (bindings: ExpressionT.bindings): list => { + let eParameters = Belt.Map.String.getWithDefault(bindings, "$parameters", EParameters(list{})) + switch eParameters { + | EParameters(parameters) => parameters + | _ => list{} + } + } + + let putParameters = ( + bindings: ExpressionT.bindings, + parameters: list, + ): ExpressionT.bindings => + Belt.Map.String.set(bindings, "$parameters", ExpressionT.EParameters(parameters)) + switch expression { + | ExpressionT.EValue(EvSymbol(aSymbol)) => { + let parameters = getParameters(bindings) + switch Belt.List.has(parameters, aSymbol, (a, b) => a == b) { + | true => expression->Ok // We cannot bind the parameters with global values + | false => + switch bindings->Belt.Map.String.get(aSymbol) { + | Some(boundExpression) => boundExpression->Ok + | None => RESymbolNotFound(aSymbol)->Error + } + } + } + | ExpressionT.EValue(_) => expression->Ok + | ExpressionT.EBindings(_) => expression->Ok + | ExpressionT.EParameters(_) => expression->Ok + | ExpressionT.EList(list{ + ExpressionT.EValue(EvCall("$lambda")), + ExpressionT.EParameters(parameters), + expr, + }) => { + let oldParameters = getParameters(bindings) + let newParameters = oldParameters->Belt.List.concat(parameters) + let newBindings = putParameters(bindings, newParameters) + let rNewExpr = replaceSymbols(expr, newBindings) + rNewExpr -> Result.flatMap(newExpr => ExpressionT.EList(list{ + ExpressionT.EValue(EvCall("$lambda")), + ExpressionT.EParameters(parameters), + newExpr + })->Ok) + } + | ExpressionT.EList(list) => { + let racc = list->Belt.List.reduceReverse(Ok(list{}), (racc, each: expression) => + racc->Result.flatMap(acc => { + each + ->replaceSymbols(bindings) + ->Result.flatMap(newNode => { + acc->Belt.List.add(newNode)->Ok + }) + }) + ) + racc->Result.map(acc => acc->ExpressionT.EList) + } + } +} + let dispatchMacroCall = ( list: list, bindings: ExpressionT.bindings, reduceExpression: reducerFn, ): result => { - let rec replaceSymbols = (expression: expression, bindings: ExpressionT.bindings): result< - expression, - errorValue, - > => - switch expression { - | ExpressionT.EValue(EvSymbol(aSymbol)) => - switch bindings->Belt.Map.String.get(aSymbol) { - | Some(boundExpression) => boundExpression->Ok - | None => RESymbolNotFound(aSymbol)->Error - } - | 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 => { - each - ->replaceSymbols(bindings) - ->Result.flatMap(newNode => { - acc->Belt.List.add(newNode)->Ok - }) - }) - ) - racc->Result.map(acc => acc->ExpressionT.EList) - } - } let doBindStatement = (statement: expression, bindings: ExpressionT.bindings) => { switch statement { diff --git a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res index 30f8d96c..1153491b 100644 --- a/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res +++ b/packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res @@ -93,6 +93,9 @@ let rec reduceExpression = (expression: t, bindings: T.bindings): result => switch expression { + // | T.EList(list{T.EValue(EvCall("$lambda")), T.EParameters(parameters), functionDefinition}) => { + // let lambda = T.ELambda(parameters, functionDefinition) + // lambda->Ok} | T.EValue(value) => value->Ok | T.EList(list) => { let racc: result, 'e> = list->Belt.List.reduceReverse(Ok(list{}), (