Compare commits

...

4 Commits

Author SHA1 Message Date
Umur Ozkul
fe7fa297e3 fix PR 1116 comment Ozzie 2022-09-12 02:26:32 +02:00
Umur Ozkul
91e59fe3eb rename to System.environment 2022-09-11 22:44:53 +02:00
Umur Ozkul
4b9b071419 Merge branch 'develop' into reducer-squiggle-environment
packages/squiggle-lang/src/rescript/Reducer/Reducer_Dispatch/Reducer_Dispatch_BuiltInMacros.res
packages/squiggle-lang/src/rescript/Reducer/Reducer_Expression/Reducer_Expression.res
2022-09-11 20:37:16 +02:00
Umur Ozkul
1e05507ffe environment access 2022-09-11 20:02:47 +02:00
3 changed files with 105 additions and 3 deletions

View File

@ -0,0 +1,37 @@
open Jest
open Reducer_Peggy_TestHelpers
describe("Environment Accesss", () => {
testToExpression(
"Environment.sampleCount",
"{(:$_endOfOuterBlock_$ () (:$_atIndex_$ (:$$_environment_$$) 'sampleCount'))}",
~v=ReducerInterface_InternalExpressionValue.defaultEnvironment.sampleCount->Js.Int.toString,
(),
)
testToExpression(
"Environment.withSampleCount(100, Environment.sampleCount)",
"{(:$_endOfOuterBlock_$ () (:$$_withEnvironmentSampleCount_$$ 100 (:$_atIndex_$ (:$$_environment_$$) 'sampleCount')))}",
~v="100",
(),
)
testToExpression(
"Environment.withSampleCount(100, 99)",
"{(:$_endOfOuterBlock_$ () (:$$_withEnvironmentSampleCount_$$ 100 99))}",
~v="99",
(),
)
testToExpression(
"f(x) = Environment.withSampleCount(999, Environment.sampleCount+1); f(1)",
"{(:$_let_$ :f (:$$_lambda_$$ [x] {(:$$_withEnvironmentSampleCount_$$ 999 (:add (:$_atIndex_$ (:$$_environment_$$) 'sampleCount') 1))})); (:$_endOfOuterBlock_$ () (:f 1))}",
~v="1000",
(),
)
testToExpression(
"f(x) = Environment.sampleCount+1; Environment.withSampleCount(999, f(1))",
"{(:$_let_$ :f (:$$_lambda_$$ [x] {(:add (:$_atIndex_$ (:$$_environment_$$) 'sampleCount') 1)})); (:$_endOfOuterBlock_$ () (:$$_withEnvironmentSampleCount_$$ 999 (:f 1)))}",
~v="1000",
(),
)
})

View File

@ -131,7 +131,6 @@ let dispatchMacroCall = (
): expressionWithContext => { ): expressionWithContext => {
let blockCondition = ExpressionBuilder.eBlock(list{condition}) let blockCondition = ExpressionBuilder.eBlock(list{condition})
let conditionValue = reduceExpression(blockCondition, bindings, accessors) let conditionValue = reduceExpression(blockCondition, bindings, accessors)
switch conditionValue { switch conditionValue {
| InternalExpressionValue.IEvBool(false) => { | InternalExpressionValue.IEvBool(false) => {
let ifFalseBlock = eBlock(list{ifFalse}) let ifFalseBlock = eBlock(list{ifFalse})
@ -145,6 +144,40 @@ let dispatchMacroCall = (
} }
} }
let doEnvironment = (accessors: ProjectAccessorsT.t): expressionWithContext => {
let environment = accessors.environment
let environmentPairs = [
("sampleCount", environment.sampleCount->Js.Int.toFloat->InternalExpressionValue.IEvNumber),
(
"xyPointLength",
environment.xyPointLength->Js.Int.toFloat->InternalExpressionValue.IEvNumber,
),
]
let environmentMap = Belt.Map.String.fromArray(environmentPairs)
ExpressionWithContext.noContext(ExpressionBuilder.eRecord(environmentMap))
}
let doWithEnvironmentSampleCount = (
sampleCountExpr: expression,
expr: expression,
bindings: ExpressionT.bindings,
accessors: ProjectAccessorsT.t,
): expressionWithContext => {
let blockSampleCount = ExpressionBuilder.eBlock(list{sampleCountExpr})
let sampleCount = reduceExpression(blockSampleCount, bindings, accessors)
switch sampleCount {
| InternalExpressionValue.IEvNumber(sampleCount) => {
let newEnvironment = {...accessors.environment, sampleCount: Js.Math.floor(sampleCount)}
let newAccessors = {...accessors, environment: newEnvironment}
let exprBlock = eBlock(list{expr})
reduceExpression(exprBlock, bindings, newAccessors)
->ExpressionT.EValue
->ExpressionWithContext.noContext
}
| _ => REExpectedType("Number", "")->Reducer_ErrorValue.toException
}
}
let expandExpressionList = ( let expandExpressionList = (
aList, aList,
bindings: ExpressionT.bindings, bindings: ExpressionT.bindings,
@ -179,6 +212,13 @@ let dispatchMacroCall = (
doLambdaDefinition(bindings, parameters, lambdaDefinition) doLambdaDefinition(bindings, parameters, lambdaDefinition)
| list{ExpressionT.EValue(IEvCall("$$_ternary_$$")), condition, ifTrue, ifFalse} => | list{ExpressionT.EValue(IEvCall("$$_ternary_$$")), condition, ifTrue, ifFalse} =>
doTernary(condition, ifTrue, ifFalse, bindings, accessors) doTernary(condition, ifTrue, ifFalse, bindings, accessors)
| list{ExpressionT.EValue(IEvCall("$$_environment_$$"))} => doEnvironment(accessors)
| list{
ExpressionT.EValue(IEvCall("$$_withEnvironmentSampleCount_$$")),
sampleCountExpr,
expr,
} =>
doWithEnvironmentSampleCount(sampleCountExpr, expr, bindings, accessors)
| _ => ExpressionWithContext.noContext(ExpressionT.EList(aList)) | _ => ExpressionWithContext.noContext(ExpressionT.EList(aList))
} }

View File

@ -17,14 +17,39 @@ let rec fromNode = (node: Parse.node): expression => {
ExpressionBuilder.eFunction("$$_lambda_$$", list{args, body}) ExpressionBuilder.eFunction("$$_lambda_$$", list{args, body})
} }
// Convert function calls to macro calls
let caseCallIdentifier = (nodeCallIdentifier: Parse.nodeCallIdentifier): expression => {
let callIdentifier = nodeCallIdentifier["value"]
// `callIdentifier ${callIdentifier}`->Js.log
let callValue = switch callIdentifier {
| "Environment.withSampleCount" => "$$_withEnvironmentSampleCount_$$"
| callName => callName
}
ExpressionBuilder.eCall(callValue)
}
// Convert identifiers to macro calls
let caseIdentifier = (nodeIdentifier: Parse.nodeIdentifier): expression => {
let identifier = nodeIdentifier["value"]
// `caseIdentifier ${identifier}`->Js.log
switch identifier {
| "Environment.sampleCount" =>
"$_atIndex_$"->ExpressionBuilder.eFunction(list{
"$$_environment_$$"->ExpressionBuilder.eFunction(list{}),
ExpressionBuilder.eString("sampleCount"),
})
| symbol => symbol->ExpressionBuilder.eSymbol
}
}
switch Parse.castNodeType(node) { switch Parse.castNodeType(node) {
| PgNodeBlock(nodeBlock) => caseBlock(nodeBlock) | PgNodeBlock(nodeBlock) => caseBlock(nodeBlock)
| PgNodeBoolean(nodeBoolean) => ExpressionBuilder.eBool(nodeBoolean["value"]) | PgNodeBoolean(nodeBoolean) => ExpressionBuilder.eBool(nodeBoolean["value"])
| PgNodeCallIdentifier(nodeCallIdentifier) => ExpressionBuilder.eCall(nodeCallIdentifier["value"]) | PgNodeCallIdentifier(nodeCallIdentifier) => caseCallIdentifier(nodeCallIdentifier)
| PgNodeExpression(nodeExpression) => | PgNodeExpression(nodeExpression) =>
ExpressionT.EList(nodeExpression["nodes"]->Js.Array2.map(fromNode)->Belt.List.fromArray) ExpressionT.EList(nodeExpression["nodes"]->Js.Array2.map(fromNode)->Belt.List.fromArray)
| PgNodeFloat(nodeFloat) => ExpressionBuilder.eNumber(nodeFloat["value"]) | PgNodeFloat(nodeFloat) => ExpressionBuilder.eNumber(nodeFloat["value"])
| PgNodeIdentifier(nodeIdentifier) => ExpressionBuilder.eSymbol(nodeIdentifier["value"]) | PgNodeIdentifier(nodeIdentifier) => caseIdentifier(nodeIdentifier)
| PgNodeInteger(nodeInteger) => ExpressionBuilder.eNumber(Belt.Int.toFloat(nodeInteger["value"])) | PgNodeInteger(nodeInteger) => ExpressionBuilder.eNumber(Belt.Int.toFloat(nodeInteger["value"]))
| PgNodeKeyValue(nodeKeyValue) => | PgNodeKeyValue(nodeKeyValue) =>
ExpressionT.EList(list{fromNode(nodeKeyValue["key"]), fromNode(nodeKeyValue["value"])}) ExpressionT.EList(list{fromNode(nodeKeyValue["key"]), fromNode(nodeKeyValue["value"])})