refactor macro definitions
This commit is contained in:
parent
1fa1867470
commit
53c44cdc9d
|
@ -1 +1,2 @@
|
||||||
module Builtin = Reducer_Dispatch_BuiltIn
|
module Builtin = Reducer_Dispatch_BuiltIn
|
||||||
|
module BuiltinMacros = Reducer_Dispatch_BuiltInMacros
|
|
@ -0,0 +1,79 @@
|
||||||
|
module ExpressionValue = ReducerInterface.ExpressionValue
|
||||||
|
module Result = Belt.Result
|
||||||
|
module ExpressionT = Reducer_Expression_T
|
||||||
|
open Reducer_ErrorValue
|
||||||
|
|
||||||
|
type expression = ExpressionT.expression
|
||||||
|
|
||||||
|
let dispatchMacroCall = (list: list<expression>, bindings: ExpressionT.bindings): result<
|
||||||
|
expression,
|
||||||
|
'e,
|
||||||
|
> => {
|
||||||
|
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.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 {
|
||||||
|
| ExpressionT.EList(list{
|
||||||
|
ExpressionT.EValue(EvCall("$let")),
|
||||||
|
ExpressionT.EValue(EvSymbol(aSymbol)),
|
||||||
|
expression,
|
||||||
|
}) => {
|
||||||
|
let rNewExpression = replaceSymbols(expression, bindings)
|
||||||
|
rNewExpression->Result.map(newExpression =>
|
||||||
|
Belt.Map.String.set(bindings, aSymbol, newExpression)->ExpressionT.EBindings
|
||||||
|
)
|
||||||
|
}
|
||||||
|
| _ => REAssignmentExpected->Error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let doBindExpression = (expression: expression, bindings: ExpressionT.bindings) => {
|
||||||
|
switch expression {
|
||||||
|
| ExpressionT.EList(list{ExpressionT.EValue(EvCall("$let")), ..._}) =>
|
||||||
|
REExpressionExpected->Error
|
||||||
|
| _ => replaceSymbols(expression, bindings)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch list {
|
||||||
|
| list{ExpressionT.EValue(EvCall("$$bindings"))} => bindings->ExpressionT.EBindings->Ok
|
||||||
|
|
||||||
|
| list{
|
||||||
|
ExpressionT.EValue(EvCall("$$bindStatement")),
|
||||||
|
ExpressionT.EBindings(bindings),
|
||||||
|
statement,
|
||||||
|
} =>
|
||||||
|
doBindStatement(statement, bindings)
|
||||||
|
| list{
|
||||||
|
ExpressionT.EValue(EvCall("$$bindExpression")),
|
||||||
|
ExpressionT.EBindings(bindings),
|
||||||
|
expression,
|
||||||
|
} =>
|
||||||
|
doBindExpression(expression, bindings)
|
||||||
|
| _ => list->ExpressionT.EList->Ok
|
||||||
|
}
|
||||||
|
}
|
|
@ -59,63 +59,8 @@ let reduceExpression = (expression: t, bindings: T.bindings): result<expressionV
|
||||||
they take expressions as parameters and return a new expression.
|
they take expressions as parameters and return a new expression.
|
||||||
Macros are used to define language building blocks. They are like Lisp macros.
|
Macros are used to define language building blocks. They are like Lisp macros.
|
||||||
*/
|
*/
|
||||||
let doMacroCall = (list: list<t>, bindings: T.bindings): result<t, 'e> => {
|
let doMacroCall = (list: list<t>, bindings: T.bindings): result<t, 'e> =>
|
||||||
let dispatchMacroCall = (list: list<t>, bindings: T.bindings): result<t, 'e> => {
|
list->Reducer_Dispatch_BuiltInMacros.dispatchMacroCall(bindings)
|
||||||
let rec replaceSymbols = (expression: t, bindings: T.bindings): result<t, errorValue> =>
|
|
||||||
switch expression {
|
|
||||||
| T.EValue(EvSymbol(aSymbol)) =>
|
|
||||||
switch bindings->Belt.Map.String.get(aSymbol) {
|
|
||||||
| Some(boundExpression) => boundExpression->Ok
|
|
||||||
| None => RESymbolNotFound(aSymbol)->Error
|
|
||||||
}
|
|
||||||
| T.EValue(_) => expression->Ok
|
|
||||||
| T.EBindings(_) => expression->Ok
|
|
||||||
| T.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->T.EList)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let doBindStatement = (statement: t, bindings: T.bindings) => {
|
|
||||||
switch statement {
|
|
||||||
| T.EList(list{T.EValue(EvCall("$let")), T.EValue(EvSymbol(aSymbol)), expression}) => {
|
|
||||||
let rNewExpression = replaceSymbols(expression, bindings)
|
|
||||||
rNewExpression->Result.map(newExpression =>
|
|
||||||
Belt.Map.String.set(bindings, aSymbol, newExpression)->T.EBindings
|
|
||||||
)
|
|
||||||
}
|
|
||||||
| _ => REAssignmentExpected->Error
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let doBindExpression = (expression: t, bindings: T.bindings) => {
|
|
||||||
switch expression {
|
|
||||||
| T.EList(list{T.EValue(EvCall("$let")), ..._}) => REExpressionExpected->Error
|
|
||||||
| _ => replaceSymbols(expression, bindings)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch list {
|
|
||||||
| list{T.EValue(EvCall("$$bindings"))} => bindings->T.EBindings->Ok
|
|
||||||
|
|
||||||
| list{T.EValue(EvCall("$$bindStatement")), T.EBindings(bindings), statement} =>
|
|
||||||
doBindStatement(statement, bindings)
|
|
||||||
| list{T.EValue(EvCall("$$bindExpression")), T.EBindings(bindings), expression} =>
|
|
||||||
doBindExpression(expression, bindings)
|
|
||||||
| _ => list->T.EList->Ok
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
list->dispatchMacroCall(bindings)
|
|
||||||
}
|
|
||||||
|
|
||||||
let rec seekMacros = (expression: t, bindings: T.bindings): result<t, 'e> =>
|
let rec seekMacros = (expression: t, bindings: T.bindings): result<t, 'e> =>
|
||||||
switch expression {
|
switch expression {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user