Merge pull request #666 from quantified-uncertainty/reducer-modules
Reducer modules
This commit is contained in:
commit
2ced133889
19
packages/squiggle-lang/__tests__/Reducer/Reducer_Helpers.res
Normal file
19
packages/squiggle-lang/__tests__/Reducer/Reducer_Helpers.res
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
module ExpressionT = Reducer_Expression_T
|
||||||
|
module ExpressionValue = ReducerInterface.ExpressionValue
|
||||||
|
module ErrorValue = Reducer_ErrorValue
|
||||||
|
module Bindings = Reducer_Category_Bindings
|
||||||
|
|
||||||
|
let removeDefaults = (ev: ExpressionT.expressionValue): ExpressionT.expressionValue =>
|
||||||
|
switch ev {
|
||||||
|
| EvRecord(extbindings) => {
|
||||||
|
let bindings: Bindings.t = Bindings.fromRecord(extbindings)
|
||||||
|
let keys = Js.Dict.keys(Reducer.defaultExternalBindings)
|
||||||
|
Belt.Map.String.keep(bindings, (key, _value) => {
|
||||||
|
let removeThis = Js.Array2.includes(keys, key)
|
||||||
|
!removeThis
|
||||||
|
})->Bindings.toExpressionValue
|
||||||
|
}
|
||||||
|
| value => value
|
||||||
|
}
|
||||||
|
|
||||||
|
let rRemoveDefaults = r => Belt.Result.map(r, ev => removeDefaults(ev))
|
|
@ -235,6 +235,9 @@ describe("Peggy parse", () => {
|
||||||
testParse("1M", "{(::fromUnit_M 1)}")
|
testParse("1M", "{(::fromUnit_M 1)}")
|
||||||
testParse("1m+2cm", "{(::add (::fromUnit_m 1) (::fromUnit_cm 2))}")
|
testParse("1m+2cm", "{(::add (::fromUnit_m 1) (::fromUnit_cm 2))}")
|
||||||
})
|
})
|
||||||
|
describe("Module", () => {
|
||||||
|
testParse("Math.pi", "{(::$_atIndex_$ @Math 'pi')}")
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("parsing new line", () => {
|
describe("parsing new line", () => {
|
||||||
|
|
|
@ -23,8 +23,13 @@ let expectToExpressionToBe = (expr, answer, ~v="_", ()) => {
|
||||||
let a2 =
|
let a2 =
|
||||||
rExpr
|
rExpr
|
||||||
->Result.flatMap(expr =>
|
->Result.flatMap(expr =>
|
||||||
Expression.reduceExpression(expr, Belt.Map.String.empty, ExpressionValue.defaultEnvironment)
|
Expression.reduceExpression(
|
||||||
|
expr,
|
||||||
|
ReducerInterface_DefaultExternalBindings.defaultInternalBindings,
|
||||||
|
ExpressionValue.defaultEnvironment,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
->Reducer_Helpers.rRemoveDefaults
|
||||||
->ExpressionValue.toStringResultOkless
|
->ExpressionValue.toStringResultOkless
|
||||||
(a1, a2)->expect->toEqual((answer, v))
|
(a1, a2)->expect->toEqual((answer, v))
|
||||||
}
|
}
|
||||||
|
|
|
@ -181,4 +181,8 @@ describe("Peggy to Expression", () => {
|
||||||
(),
|
(),
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("module", () => {
|
||||||
|
testToExpression("Math.pi", "{(:$_atIndex_$ :Math 'pi')}", ~v="3.141592653589793", ())
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
module ExpressionT = Reducer_Expression_T
|
module ExpressionT = Reducer_Expression_T
|
||||||
module ExpressionValue = ReducerInterface.ExpressionValue
|
module ExpressionValue = ReducerInterface.ExpressionValue
|
||||||
module ErrorValue = Reducer_ErrorValue
|
module ErrorValue = Reducer_ErrorValue
|
||||||
|
module Bindings = Reducer_Category_Bindings
|
||||||
|
|
||||||
open Jest
|
open Jest
|
||||||
open Expect
|
open Expect
|
||||||
|
@ -17,7 +18,11 @@ let expectParseToBe = (expr: string, answer: string) =>
|
||||||
Reducer.parse(expr)->ExpressionT.toStringResult->expect->toBe(answer)
|
Reducer.parse(expr)->ExpressionT.toStringResult->expect->toBe(answer)
|
||||||
|
|
||||||
let expectEvalToBe = (expr: string, answer: string) =>
|
let expectEvalToBe = (expr: string, answer: string) =>
|
||||||
Reducer.evaluate(expr)->ExpressionValue.toStringResult->expect->toBe(answer)
|
Reducer.evaluate(expr)
|
||||||
|
->Reducer_Helpers.rRemoveDefaults
|
||||||
|
->ExpressionValue.toStringResult
|
||||||
|
->expect
|
||||||
|
->toBe(answer)
|
||||||
|
|
||||||
let expectEvalError = (expr: string) =>
|
let expectEvalError = (expr: string) =>
|
||||||
Reducer.evaluate(expr)->ExpressionValue.toStringResult->expect->toMatch("Error\(")
|
Reducer.evaluate(expr)->ExpressionValue.toStringResult->expect->toMatch("Error\(")
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
open Jest
|
||||||
|
open Reducer_TestHelpers
|
||||||
|
|
||||||
|
describe("Math Library", () => {
|
||||||
|
testEvalToBe("Math.e", "Ok(2.718281828459045)")
|
||||||
|
testEvalToBe("Math.pi", "Ok(3.141592653589793)")
|
||||||
|
})
|
|
@ -187,5 +187,16 @@ function createTsExport(
|
||||||
return tag("lambdaDeclaration", x.value);
|
return tag("lambdaDeclaration", x.value);
|
||||||
case "EvTypeIdentifier":
|
case "EvTypeIdentifier":
|
||||||
return tag("typeIdentifier", x.value);
|
return tag("typeIdentifier", x.value);
|
||||||
|
case "EvModule":
|
||||||
|
let moduleResult: tagged<
|
||||||
|
"module",
|
||||||
|
{ [key: string]: squiggleExpression }
|
||||||
|
> = tag(
|
||||||
|
"module",
|
||||||
|
_.mapValues(x.value, (x: unknown) =>
|
||||||
|
convertRawToTypescript(x as rescriptExport, environment)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return moduleResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,6 +73,10 @@ export type rescriptExport =
|
||||||
| {
|
| {
|
||||||
TAG: 13; // EvTypeIdentifier
|
TAG: 13; // EvTypeIdentifier
|
||||||
_0: string;
|
_0: string;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
TAG: 14; // EvModule
|
||||||
|
_0: { [key: string]: rescriptExport };
|
||||||
};
|
};
|
||||||
|
|
||||||
type rescriptDist =
|
type rescriptDist =
|
||||||
|
@ -125,7 +129,8 @@ export type squiggleExpression =
|
||||||
| tagged<"timeDuration", number>
|
| tagged<"timeDuration", number>
|
||||||
| tagged<"lambdaDeclaration", lambdaDeclaration>
|
| tagged<"lambdaDeclaration", lambdaDeclaration>
|
||||||
| tagged<"record", { [key: string]: squiggleExpression }>
|
| tagged<"record", { [key: string]: squiggleExpression }>
|
||||||
| tagged<"typeIdentifier", string>;
|
| tagged<"typeIdentifier", string>
|
||||||
|
| tagged<"module", { [key: string]: squiggleExpression }>;
|
||||||
|
|
||||||
export { lambdaValue };
|
export { lambdaValue };
|
||||||
|
|
||||||
|
@ -177,6 +182,11 @@ export function convertRawToTypescript(
|
||||||
});
|
});
|
||||||
case 13: // EvSymbol
|
case 13: // EvSymbol
|
||||||
return tag("typeIdentifier", result._0);
|
return tag("typeIdentifier", result._0);
|
||||||
|
case 14: // EvModule
|
||||||
|
return tag(
|
||||||
|
"module",
|
||||||
|
_.mapValues(result._0, (x) => convertRawToTypescript(x, environment))
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,4 +24,4 @@ let foreignFunctionInterface = (
|
||||||
|
|
||||||
let defaultEnvironment = ExpressionValue.defaultEnvironment
|
let defaultEnvironment = ExpressionValue.defaultEnvironment
|
||||||
|
|
||||||
let defaultExternalBindings = ExpressionValue.defaultExternalBindings
|
let defaultExternalBindings = ReducerInterface_DefaultExternalBindings.defaultExternalBindings
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
include Reducer_Category_Module // Bindings inherit from Module
|
||||||
|
|
||||||
|
open ReducerInterface_ExpressionValue
|
||||||
|
|
||||||
|
let emptyBindings = emptyModule
|
||||||
|
|
||||||
|
let toExpressionValue = (container: t): expressionValue => EvRecord(toRecord(container))
|
||||||
|
let fromExpressionValue = (aValue: expressionValue): t =>
|
||||||
|
switch aValue {
|
||||||
|
| EvRecord(r) => fromRecord(r)
|
||||||
|
| _ => emptyBindings
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
module ExpressionT = Reducer_Expression_T
|
||||||
|
open ReducerInterface_ExpressionValue
|
||||||
|
let expressionValueToString = toString
|
||||||
|
|
||||||
|
type t = ExpressionT.bindings
|
||||||
|
|
||||||
|
let typeAliasesKey = "_typeAliases_"
|
||||||
|
let typeReferencesKey = "_typeReferences_"
|
||||||
|
|
||||||
|
let emptyModule: t = Belt.Map.String.empty
|
||||||
|
|
||||||
|
let cloneRecord = (r: record): record => r->Js.Dict.entries->Js.Dict.fromArray
|
||||||
|
let fromRecord = (r: record): t => Js.Dict.entries(r)->Belt.Map.String.fromArray
|
||||||
|
let toRecord = (container: t): record => Belt.Map.String.toArray(container)->Js.Dict.fromArray
|
||||||
|
|
||||||
|
let toExpressionValue = (container: t): expressionValue => EvModule(toRecord(container))
|
||||||
|
let fromExpressionValue = (aValue: expressionValue): t =>
|
||||||
|
switch aValue {
|
||||||
|
| EvModule(r) => fromRecord(r)
|
||||||
|
| _ => emptyModule
|
||||||
|
}
|
||||||
|
|
||||||
|
let toString = (container: t): string => container->toRecord->EvRecord->expressionValueToString
|
||||||
|
|
||||||
|
// -- Module definition
|
||||||
|
let define = (container: t, identifier: string, ev: expressionValue): t =>
|
||||||
|
Belt.Map.String.set(container, identifier, ev) // TODO build lambda for polymorphic functions here
|
||||||
|
|
||||||
|
let defineNumber = (container: t, identifier: string, value: float): t =>
|
||||||
|
container->define(identifier, EvNumber(value))
|
||||||
|
|
||||||
|
let defineModule = (container: t, identifier: string, value: t): t =>
|
||||||
|
container->define(identifier, toExpressionValue(value))
|
|
@ -256,6 +256,7 @@ let callInternal = (call: functionCall, environment, reducer: ExpressionT.reduce
|
||||||
|
|
||||||
switch call {
|
switch call {
|
||||||
| ("$_atIndex_$", [EvArray(aValueArray), EvNumber(fIndex)]) => arrayAtIndex(aValueArray, fIndex)
|
| ("$_atIndex_$", [EvArray(aValueArray), EvNumber(fIndex)]) => arrayAtIndex(aValueArray, fIndex)
|
||||||
|
| ("$_atIndex_$", [EvModule(dict), EvString(sIndex)]) => recordAtIndex(dict, sIndex)
|
||||||
| ("$_atIndex_$", [EvRecord(dict), EvString(sIndex)]) => recordAtIndex(dict, sIndex)
|
| ("$_atIndex_$", [EvRecord(dict), EvString(sIndex)]) => recordAtIndex(dict, sIndex)
|
||||||
| ("$_constructArray_$", [EvArray(aValueArray)]) => EvArray(aValueArray)->Ok
|
| ("$_constructArray_$", [EvArray(aValueArray)]) => EvArray(aValueArray)->Ok
|
||||||
| ("$_constructRecord_$", [EvArray(arrayOfPairs)]) => constructRecord(arrayOfPairs)
|
| ("$_constructRecord_$", [EvArray(arrayOfPairs)]) => constructRecord(arrayOfPairs)
|
||||||
|
|
|
@ -123,7 +123,7 @@ let evaluateUsingOptions = (
|
||||||
|
|
||||||
let anExternalBindings = switch externalBindings {
|
let anExternalBindings = switch externalBindings {
|
||||||
| Some(bindings) => bindings
|
| Some(bindings) => bindings
|
||||||
| None => ReducerInterface_ExpressionValue.defaultExternalBindings
|
| None => ReducerInterface_DefaultExternalBindings.defaultExternalBindings
|
||||||
}
|
}
|
||||||
|
|
||||||
let bindings = anExternalBindings->Bindings.fromExternalBindings
|
let bindings = anExternalBindings->Bindings.fromExternalBindings
|
||||||
|
|
|
@ -2,77 +2,25 @@ module ErrorValue = Reducer_ErrorValue
|
||||||
module ExpressionT = Reducer_Expression_T
|
module ExpressionT = Reducer_Expression_T
|
||||||
module ExpressionValue = ReducerInterface.ExpressionValue
|
module ExpressionValue = ReducerInterface.ExpressionValue
|
||||||
module Result = Belt.Result
|
module Result = Belt.Result
|
||||||
|
module Bindings = Reducer_Category_Bindings
|
||||||
|
|
||||||
type errorValue = Reducer_ErrorValue.errorValue
|
type errorValue = Reducer_ErrorValue.errorValue
|
||||||
type expression = ExpressionT.expression
|
type expression = ExpressionT.expression
|
||||||
type expressionValue = ExpressionValue.expressionValue
|
type expressionValue = ExpressionValue.expressionValue
|
||||||
type externalBindings = ReducerInterface_ExpressionValue.externalBindings
|
type externalBindings = ReducerInterface_ExpressionValue.externalBindings
|
||||||
|
|
||||||
let defaultBindings: ExpressionT.bindings = Belt.Map.String.empty
|
let emptyBindings = Reducer_Category_Bindings.emptyBindings
|
||||||
|
|
||||||
let typeAliasesKey = "_typeAliases_"
|
let typeAliasesKey = Bindings.typeAliasesKey
|
||||||
let typeReferencesKey = "_typeReferences_"
|
let typeReferencesKey = Bindings.typeReferencesKey
|
||||||
|
|
||||||
let toExternalBindings = (bindings: ExpressionT.bindings): externalBindings => {
|
let toExternalBindings = (bindings: ExpressionT.bindings): externalBindings =>
|
||||||
let keys = Belt.Map.String.keysToArray(bindings)
|
Bindings.toRecord(bindings)
|
||||||
keys->Belt.Array.reduce(Js.Dict.empty(), (acc, key) => {
|
|
||||||
let value = bindings->Belt.Map.String.getExn(key)
|
|
||||||
Js.Dict.set(acc, key, value)
|
|
||||||
acc
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
let fromExternalBindings_ = (externalBindings: externalBindings): ExpressionT.bindings => {
|
let fromExternalBindings = (externalBindings: externalBindings): ExpressionT.bindings =>
|
||||||
let keys = Js.Dict.keys(externalBindings)
|
Bindings.fromRecord(externalBindings)
|
||||||
keys->Belt.Array.reduce(defaultBindings, (acc, key) => {
|
|
||||||
let value = Js.Dict.unsafeGet(externalBindings, key)
|
|
||||||
acc->Belt.Map.String.set(key, value)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
let fromExternalBindings = (externalBindings: externalBindings): ExpressionT.bindings => {
|
let fromValue = (aValue: expressionValue) => Bindings.fromExpressionValue(aValue)
|
||||||
// TODO: This code will be removed in the future when maps are used instead of records. Please don't mind this function for now.
|
|
||||||
|
|
||||||
let internalBindings0 = fromExternalBindings_(externalBindings)
|
|
||||||
|
|
||||||
let oExistingTypeAliases = Belt.Map.String.get(internalBindings0, typeAliasesKey)
|
|
||||||
let internalBindings1 = Belt.Option.mapWithDefault(
|
|
||||||
oExistingTypeAliases,
|
|
||||||
internalBindings0,
|
|
||||||
existingTypeAliases => {
|
|
||||||
let newTypeAliases = switch existingTypeAliases {
|
|
||||||
| EvRecord(actualTypeAliases) =>
|
|
||||||
actualTypeAliases->fromExternalBindings_->toExternalBindings->ExpressionValue.EvRecord
|
|
||||||
| _ => existingTypeAliases
|
|
||||||
}
|
|
||||||
Belt.Map.String.set(internalBindings0, typeAliasesKey, newTypeAliases)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
let oExistingTypeReferences = Belt.Map.String.get(internalBindings1, typeReferencesKey)
|
|
||||||
let internalBindings2 = Belt.Option.mapWithDefault(
|
|
||||||
oExistingTypeReferences,
|
|
||||||
internalBindings1,
|
|
||||||
existingTypeReferences => {
|
|
||||||
let newTypeReferences = switch existingTypeReferences {
|
|
||||||
| EvRecord(actualTypeReferences) =>
|
|
||||||
actualTypeReferences->fromExternalBindings_->toExternalBindings->ExpressionValue.EvRecord
|
|
||||||
| _ => existingTypeReferences
|
|
||||||
}
|
|
||||||
Belt.Map.String.set(internalBindings0, typeReferencesKey, newTypeReferences)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
|
|
||||||
internalBindings2
|
|
||||||
}
|
|
||||||
|
|
||||||
let fromValue = (aValue: expressionValue) =>
|
|
||||||
switch aValue {
|
|
||||||
| EvRecord(externalBindings) => fromExternalBindings(externalBindings)
|
|
||||||
| _ => defaultBindings
|
|
||||||
}
|
|
||||||
|
|
||||||
let externalFromArray = anArray => Js.Dict.fromArray(anArray)
|
|
||||||
|
|
||||||
let isMacroName = (fName: string): bool => fName->Js.String2.startsWith("$$")
|
let isMacroName = (fName: string): bool => fName->Js.String2.startsWith("$$")
|
||||||
|
|
||||||
|
|
|
@ -65,5 +65,7 @@ let eBindExpression = (bindingExpr: expression, expression: expression): express
|
||||||
let eBindExpressionDefault = (expression: expression): expression =>
|
let eBindExpressionDefault = (expression: expression): expression =>
|
||||||
eFunction("$$_bindExpression_$$", list{expression})
|
eFunction("$$_bindExpression_$$", list{expression})
|
||||||
|
|
||||||
|
let eIdentifier = (name: string): expression => name->BExpressionValue.EvSymbol->BExpressionT.EValue
|
||||||
|
|
||||||
let eTypeIdentifier = (name: string): expression =>
|
let eTypeIdentifier = (name: string): expression =>
|
||||||
name->BExpressionValue.EvTypeIdentifier->BExpressionT.EValue
|
name->BExpressionValue.EvTypeIdentifier->BExpressionT.EValue
|
||||||
|
|
|
@ -64,6 +64,7 @@
|
||||||
return {type: 'KeyValue', key: key, value: value}}
|
return {type: 'KeyValue', key: key, value: value}}
|
||||||
function nodeLambda(args, body) {return {type: 'Lambda', args: args, body: body}}
|
function nodeLambda(args, body) {return {type: 'Lambda', args: args, body: body}}
|
||||||
function nodeLetStatment(variable, value) {return {type: 'LetStatement', variable: variable, value: value}}
|
function nodeLetStatment(variable, value) {return {type: 'LetStatement', variable: variable, value: value}}
|
||||||
|
function nodeModuleIdentifier(value) {return {type: 'ModuleIdentifier', value: value}}
|
||||||
function nodeString(value) {return {type: 'String', value: value}}
|
function nodeString(value) {return {type: 'String', value: value}}
|
||||||
function nodeTernary(condition, trueExpression, falseExpression) {return {type: 'Ternary', condition: condition, trueExpression: trueExpression, falseExpression: falseExpression}}
|
function nodeTernary(condition, trueExpression, falseExpression) {return {type: 'Ternary', condition: condition, trueExpression: trueExpression, falseExpression: falseExpression}}
|
||||||
|
|
||||||
|
@ -256,11 +257,11 @@ basicLiteral
|
||||||
|
|
||||||
dollarIdentifierWithModule 'identifier'
|
dollarIdentifierWithModule 'identifier'
|
||||||
= head:moduleIdentifier
|
= head:moduleIdentifier
|
||||||
tail:('.' _nl @moduleIdentifier)* '.' _nl
|
tail:('.' _nl @$moduleIdentifier)* '.' _nl
|
||||||
final:dollarIdentifier
|
final:$dollarIdentifier
|
||||||
{ tail.push(final);
|
{ tail.push(final);
|
||||||
return tail.reduce(function(result, element) {
|
return tail.reduce(function(result, element) {
|
||||||
return makeFunctionCall(postOperatorToFunction['[]'], [result, element])
|
return makeFunctionCall(postOperatorToFunction['[]'], [result, nodeString(element)])
|
||||||
}, head)}
|
}, head)}
|
||||||
|
|
||||||
identifier 'identifier'
|
identifier 'identifier'
|
||||||
|
@ -273,7 +274,7 @@ dollarIdentifier '$identifier'
|
||||||
= ([\$_a-z]+[\$_a-z0-9]i*) {return nodeIdentifier(text())}
|
= ([\$_a-z]+[\$_a-z0-9]i*) {return nodeIdentifier(text())}
|
||||||
|
|
||||||
moduleIdentifier 'identifier'
|
moduleIdentifier 'identifier'
|
||||||
= ([A-Z]+[_a-z0-9]i*) {return nodeIdentifier(text())}
|
= ([A-Z]+[_a-z0-9]i*) {return nodeModuleIdentifier(text())}
|
||||||
|
|
||||||
|
|
||||||
string 'string'
|
string 'string'
|
||||||
|
|
|
@ -22,6 +22,7 @@ type nodeInteger = {...node, "value": int}
|
||||||
type nodeKeyValue = {...node, "key": node, "value": node}
|
type nodeKeyValue = {...node, "key": node, "value": node}
|
||||||
type nodeLambda = {...node, "args": array<nodeIdentifier>, "body": nodeBlock}
|
type nodeLambda = {...node, "args": array<nodeIdentifier>, "body": nodeBlock}
|
||||||
type nodeLetStatement = {...node, "variable": nodeIdentifier, "value": node}
|
type nodeLetStatement = {...node, "variable": nodeIdentifier, "value": node}
|
||||||
|
type nodeModuleIdentifier = {...node, "value": string}
|
||||||
type nodeString = {...node, "value": string}
|
type nodeString = {...node, "value": string}
|
||||||
type nodeTernary = {...node, "condition": node, "trueExpression": node, "falseExpression": node}
|
type nodeTernary = {...node, "condition": node, "trueExpression": node, "falseExpression": node}
|
||||||
type nodeTypeIdentifier = {...node, "value": string}
|
type nodeTypeIdentifier = {...node, "value": string}
|
||||||
|
@ -37,6 +38,7 @@ type peggyNode =
|
||||||
| PgNodeKeyValue(nodeKeyValue)
|
| PgNodeKeyValue(nodeKeyValue)
|
||||||
| PgNodeLambda(nodeLambda)
|
| PgNodeLambda(nodeLambda)
|
||||||
| PgNodeLetStatement(nodeLetStatement)
|
| PgNodeLetStatement(nodeLetStatement)
|
||||||
|
| PgNodeModuleIdentifier(nodeModuleIdentifier)
|
||||||
| PgNodeString(nodeString)
|
| PgNodeString(nodeString)
|
||||||
| PgNodeTernary(nodeTernary)
|
| PgNodeTernary(nodeTernary)
|
||||||
| PgNodeTypeIdentifier(nodeTypeIdentifier)
|
| PgNodeTypeIdentifier(nodeTypeIdentifier)
|
||||||
|
@ -51,6 +53,7 @@ external castNodeInteger: node => nodeInteger = "%identity"
|
||||||
external castNodeKeyValue: node => nodeKeyValue = "%identity"
|
external castNodeKeyValue: node => nodeKeyValue = "%identity"
|
||||||
external castNodeLambda: node => nodeLambda = "%identity"
|
external castNodeLambda: node => nodeLambda = "%identity"
|
||||||
external castNodeLetStatement: node => nodeLetStatement = "%identity"
|
external castNodeLetStatement: node => nodeLetStatement = "%identity"
|
||||||
|
external castNodeModuleIdentifier: node => nodeModuleIdentifier = "%identity"
|
||||||
external castNodeString: node => nodeString = "%identity"
|
external castNodeString: node => nodeString = "%identity"
|
||||||
external castNodeTernary: node => nodeTernary = "%identity"
|
external castNodeTernary: node => nodeTernary = "%identity"
|
||||||
external castNodeTypeIdentifier: node => nodeTypeIdentifier = "%identity"
|
external castNodeTypeIdentifier: node => nodeTypeIdentifier = "%identity"
|
||||||
|
@ -68,6 +71,7 @@ let castNodeType = (node: node) =>
|
||||||
| "KeyValue" => node->castNodeKeyValue->PgNodeKeyValue
|
| "KeyValue" => node->castNodeKeyValue->PgNodeKeyValue
|
||||||
| "Lambda" => node->castNodeLambda->PgNodeLambda
|
| "Lambda" => node->castNodeLambda->PgNodeLambda
|
||||||
| "LetStatement" => node->castNodeLetStatement->PgNodeLetStatement
|
| "LetStatement" => node->castNodeLetStatement->PgNodeLetStatement
|
||||||
|
| "ModuleIdentifier" => node->castNodeModuleIdentifier->PgNodeModuleIdentifier
|
||||||
| "String" => node->castNodeString->PgNodeString
|
| "String" => node->castNodeString->PgNodeString
|
||||||
| "Ternary" => node->castNodeTernary->PgNodeTernary
|
| "Ternary" => node->castNodeTernary->PgNodeTernary
|
||||||
| "TypeIdentifier" => node->castNodeTypeIdentifier->PgNodeTypeIdentifier
|
| "TypeIdentifier" => node->castNodeTypeIdentifier->PgNodeTypeIdentifier
|
||||||
|
@ -94,6 +98,7 @@ let rec pgToString = (peggyNode: peggyNode): string => {
|
||||||
"{|" ++ node["args"]->argsToString ++ "| " ++ pgToString(PgNodeBlock(node["body"])) ++ "}"
|
"{|" ++ node["args"]->argsToString ++ "| " ++ pgToString(PgNodeBlock(node["body"])) ++ "}"
|
||||||
| PgNodeLetStatement(node) =>
|
| PgNodeLetStatement(node) =>
|
||||||
pgToString(PgNodeIdentifier(node["variable"])) ++ " = " ++ toString(node["value"])
|
pgToString(PgNodeIdentifier(node["variable"])) ++ " = " ++ toString(node["value"])
|
||||||
|
| PgNodeModuleIdentifier(node) => `@${node["value"]}`
|
||||||
| PgNodeString(node) => `'${node["value"]->Js.String.make}'`
|
| PgNodeString(node) => `'${node["value"]->Js.String.make}'`
|
||||||
| PgNodeTernary(node) =>
|
| PgNodeTernary(node) =>
|
||||||
"(::$$_ternary_$$ " ++
|
"(::$$_ternary_$$ " ++
|
||||||
|
|
|
@ -34,6 +34,8 @@ let rec fromNode = (node: Parse.node): expression => {
|
||||||
nodeLetStatement["variable"]["value"],
|
nodeLetStatement["variable"]["value"],
|
||||||
fromNode(nodeLetStatement["value"]),
|
fromNode(nodeLetStatement["value"]),
|
||||||
)
|
)
|
||||||
|
| PgNodeModuleIdentifier(nodeModuleIdentifier) =>
|
||||||
|
ExpressionBuilder.eIdentifier(nodeModuleIdentifier["value"])
|
||||||
| PgNodeString(nodeString) => ExpressionBuilder.eString(nodeString["value"])
|
| PgNodeString(nodeString) => ExpressionBuilder.eString(nodeString["value"])
|
||||||
| PgNodeTernary(nodeTernary) =>
|
| PgNodeTernary(nodeTernary) =>
|
||||||
ExpressionBuilder.eFunction(
|
ExpressionBuilder.eFunction(
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
module Bindings = Reducer_Category_Bindings
|
||||||
|
|
||||||
|
let defaultInternalBindings = Bindings.emptyBindings->SquiggleLibrary_Math.makeBindings
|
||||||
|
|
||||||
|
@genType
|
||||||
|
let defaultExternalBindings = defaultInternalBindings->Bindings.toRecord
|
|
@ -4,7 +4,6 @@
|
||||||
*/
|
*/
|
||||||
module Extra_Array = Reducer_Extra_Array
|
module Extra_Array = Reducer_Extra_Array
|
||||||
module ErrorValue = Reducer_ErrorValue
|
module ErrorValue = Reducer_ErrorValue
|
||||||
|
|
||||||
@genType.opaque
|
@genType.opaque
|
||||||
type internalCode = Object
|
type internalCode = Object
|
||||||
|
|
||||||
|
@ -24,6 +23,7 @@ type rec expressionValue =
|
||||||
| EvTimeDuration(float)
|
| EvTimeDuration(float)
|
||||||
| EvDeclaration(lambdaDeclaration)
|
| EvDeclaration(lambdaDeclaration)
|
||||||
| EvTypeIdentifier(string)
|
| EvTypeIdentifier(string)
|
||||||
|
| EvModule(record)
|
||||||
and record = Js.Dict.t<expressionValue>
|
and record = Js.Dict.t<expressionValue>
|
||||||
and externalBindings = record
|
and externalBindings = record
|
||||||
and lambdaValue = {
|
and lambdaValue = {
|
||||||
|
@ -33,9 +33,6 @@ and lambdaValue = {
|
||||||
}
|
}
|
||||||
and lambdaDeclaration = Declaration.declaration<lambdaValue>
|
and lambdaDeclaration = Declaration.declaration<lambdaValue>
|
||||||
|
|
||||||
@genType
|
|
||||||
let defaultExternalBindings: externalBindings = Js.Dict.empty()
|
|
||||||
|
|
||||||
type functionCall = (string, array<expressionValue>)
|
type functionCall = (string, array<expressionValue>)
|
||||||
|
|
||||||
let rec toString = aValue =>
|
let rec toString = aValue =>
|
||||||
|
@ -60,6 +57,7 @@ let rec toString = aValue =>
|
||||||
| EvTimeDuration(t) => DateTime.Duration.toString(t)
|
| EvTimeDuration(t) => DateTime.Duration.toString(t)
|
||||||
| EvDeclaration(d) => Declaration.toString(d, r => toString(EvLambda(r)))
|
| EvDeclaration(d) => Declaration.toString(d, r => toString(EvLambda(r)))
|
||||||
| EvTypeIdentifier(id) => `#${id}`
|
| EvTypeIdentifier(id) => `#${id}`
|
||||||
|
| EvModule(m) => `@${m->toStringRecord}`
|
||||||
}
|
}
|
||||||
and toStringRecord = aRecord => {
|
and toStringRecord = aRecord => {
|
||||||
let pairs =
|
let pairs =
|
||||||
|
@ -86,6 +84,7 @@ let toStringWithType = aValue =>
|
||||||
| EvTimeDuration(_) => `Date::${toString(aValue)}`
|
| EvTimeDuration(_) => `Date::${toString(aValue)}`
|
||||||
| EvDeclaration(_) => `Declaration::${toString(aValue)}`
|
| EvDeclaration(_) => `Declaration::${toString(aValue)}`
|
||||||
| EvTypeIdentifier(_) => `TypeIdentifier::${toString(aValue)}`
|
| EvTypeIdentifier(_) => `TypeIdentifier::${toString(aValue)}`
|
||||||
|
| EvModule(_) => `Module::${toString(aValue)}`
|
||||||
}
|
}
|
||||||
|
|
||||||
let argsToString = (args: array<expressionValue>): string => {
|
let argsToString = (args: array<expressionValue>): string => {
|
||||||
|
@ -133,6 +132,7 @@ type expressionValueType =
|
||||||
| EvtTimeDuration
|
| EvtTimeDuration
|
||||||
| EvtDeclaration
|
| EvtDeclaration
|
||||||
| EvtTypeIdentifier
|
| EvtTypeIdentifier
|
||||||
|
| EvtModule
|
||||||
|
|
||||||
type functionCallSignature = CallSignature(string, array<expressionValueType>)
|
type functionCallSignature = CallSignature(string, array<expressionValueType>)
|
||||||
type functionDefinitionSignature =
|
type functionDefinitionSignature =
|
||||||
|
@ -154,6 +154,7 @@ let valueToValueType = value =>
|
||||||
| EvTimeDuration(_) => EvtTimeDuration
|
| EvTimeDuration(_) => EvtTimeDuration
|
||||||
| EvDeclaration(_) => EvtDeclaration
|
| EvDeclaration(_) => EvtDeclaration
|
||||||
| EvTypeIdentifier(_) => EvtTypeIdentifier
|
| EvTypeIdentifier(_) => EvtTypeIdentifier
|
||||||
|
| EvModule(_) => EvtModule
|
||||||
}
|
}
|
||||||
|
|
||||||
let functionCallToCallSignature = (functionCall: functionCall): functionCallSignature => {
|
let functionCallToCallSignature = (functionCall: functionCall): functionCallSignature => {
|
||||||
|
@ -177,6 +178,7 @@ let valueTypeToString = (valueType: expressionValueType): string =>
|
||||||
| EvtTimeDuration => `Duration`
|
| EvtTimeDuration => `Duration`
|
||||||
| EvtDeclaration => `Declaration`
|
| EvtDeclaration => `Declaration`
|
||||||
| EvtTypeIdentifier => `TypeIdentifier`
|
| EvtTypeIdentifier => `TypeIdentifier`
|
||||||
|
| EvtModule => `Module`
|
||||||
}
|
}
|
||||||
|
|
||||||
let functionCallSignatureToString = (functionCallSignature: functionCallSignature): string => {
|
let functionCallSignatureToString = (functionCallSignature: functionCallSignature): string => {
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
module Bindings = Reducer_Category_Bindings
|
||||||
|
module Module = Reducer_Category_Module
|
||||||
|
|
||||||
|
let m =
|
||||||
|
Module.emptyModule->Module.defineNumber("pi", Js.Math._PI)->Module.defineNumber("e", Js.Math._E)
|
||||||
|
|
||||||
|
let makeBindings = (previousBindings: Bindings.t): Bindings.t =>
|
||||||
|
previousBindings->Bindings.defineModule("Math", m)
|
Loading…
Reference in New Issue
Block a user