Merge remote-tracking branch 'origin/develop' into log-score-attempt
This commit is contained in:
commit
fd17da83b8
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "@quri/squiggle-components",
|
"name": "@quri/squiggle-components",
|
||||||
"version": "0.2.19",
|
"version": "0.2.20",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@quri/squiggle-lang": "^0.2.8",
|
"@quri/squiggle-lang": "^0.2.8",
|
||||||
|
@ -45,7 +45,7 @@
|
||||||
"web-vitals": "^2.1.4",
|
"web-vitals": "^2.1.4",
|
||||||
"webpack": "^5.72.0",
|
"webpack": "^5.72.0",
|
||||||
"webpack-cli": "^4.9.2",
|
"webpack-cli": "^4.9.2",
|
||||||
"webpack-dev-server": "^4.8.1"
|
"webpack-dev-server": "^4.9.0"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "cross-env REACT_APP_FAST_REFRESH=false && start-storybook -p 6006 -s public",
|
"start": "cross-env REACT_APP_FAST_REFRESH=false && start-storybook -p 6006 -s public",
|
||||||
|
|
|
@ -54,7 +54,7 @@ export const VariableBox: React.FC<VariableBoxProps> = ({
|
||||||
</variableBox.Component>
|
</variableBox.Component>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return <>{children}</>;
|
return <div>{children}</div>;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
"value": 0
|
"value": 0
|
||||||
},
|
},
|
||||||
"fill": {
|
"fill": {
|
||||||
"signal": "{gradient: 'linear', x1: 1, y1: 1, x2: 0, y2: 1, stops: [ {offset: 0.0, color: '#4C78A8'}] }"
|
"value": "#4C78A8"
|
||||||
},
|
},
|
||||||
"interpolate": {
|
"interpolate": {
|
||||||
"value": "monotone"
|
"value": "monotone"
|
||||||
|
|
|
@ -66,4 +66,9 @@ describe("MathJs parse", () => {
|
||||||
describe("comments", () => {
|
describe("comments", () => {
|
||||||
testDescriptionParse("define", "1 # This is a comment", "1")
|
testDescriptionParse("define", "1 # This is a comment", "1")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("ternary operator", () => {
|
||||||
|
testParse("1 ? 2 : 3", "ternary(1, 2, 3)")
|
||||||
|
testParse("1 ? 2 : 3 ? 4 : 5", "ternary(1, 2, ternary(3, 4, 5))")
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -62,7 +62,7 @@ describe("call and bindings", () => {
|
||||||
testEvalToBe("f(x)=x+1; g(x)=f(x)+1; g(2)", "Ok(4)")
|
testEvalToBe("f(x)=x+1; g(x)=f(x)+1; g(2)", "Ok(4)")
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("function trics", () => {
|
describe("function tricks", () => {
|
||||||
testParseToBe(
|
testParseToBe(
|
||||||
"f(x)=f(y)=2; f(2)",
|
"f(x)=f(y)=2; f(2)",
|
||||||
"Ok((:$$block (:$$block (:$let :f (:$$lambda [x] (:$$block (:$let :f (:$$lambda [y] (:$$block 2)))))) (:f 2))))",
|
"Ok((:$$block (:$$block (:$let :f (:$$lambda [x] (:$$block (:$let :f (:$$lambda [y] (:$$block 2)))))) (:f 2))))",
|
||||||
|
|
|
@ -9,3 +9,8 @@ describe("map reduce", () => {
|
||||||
testEvalToBe("arr=[1,2,3]; reverse(arr)", "Ok([3,2,1])")
|
testEvalToBe("arr=[1,2,3]; reverse(arr)", "Ok([3,2,1])")
|
||||||
testEvalToBe("check(x)=(x==2);arr=[1,2,3]; keep(arr,check)", "Ok([2])")
|
testEvalToBe("check(x)=(x==2);arr=[1,2,3]; keep(arr,check)", "Ok([2])")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Skip.describe("map reduce (sam)", () => {
|
||||||
|
testEvalToBe("addone(x)=x+1; map(2, addone)", "Error???")
|
||||||
|
testEvalToBe("addone(x)=x+1; map(2, {x: addone})", "Error???")
|
||||||
|
})
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
open Jest
|
open Jest
|
||||||
open Reducer_TestHelpers
|
open Reducer_TestHelpers
|
||||||
|
|
||||||
Skip.describe("Parse ternary operator", () => {
|
describe("Parse ternary operator", () => {
|
||||||
testParseToBe("true ? 'YES' : 'NO'", "Ok('YES')")
|
testParseToBe("true ? 'YES' : 'NO'", "Ok((:$$block (:$$ternary true 'YES' 'NO')))")
|
||||||
testParseToBe("false ? 'YES' : 'NO'", "Ok('NO')")
|
|
||||||
})
|
})
|
||||||
|
|
||||||
Skip.describe("Evaluate ternary operator", () => {
|
describe("Evaluate ternary operator", () => {
|
||||||
testEvalToBe("true ? 'YES' : 'NO'", "Ok('YES')")
|
testEvalToBe("true ? 'YES' : 'NO'", "Ok('YES')")
|
||||||
testEvalToBe("false ? 'YES' : 'NO'", "Ok('NO')")
|
testEvalToBe("false ? 'YES' : 'NO'", "Ok('NO')")
|
||||||
|
testEvalToBe("2 > 1 ? 'YES' : 'NO'", "Ok('YES')")
|
||||||
|
testEvalToBe("2 <= 1 ? 'YES' : 'NO'", "Ok('NO')")
|
||||||
|
testEvalToBe("1+1 ? 'YES' : 'NO'", "Error(Expected type: Boolean)")
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,11 +1,27 @@
|
||||||
module ErrorValue = Reducer_ErrorValue
|
module ErrorValue = Reducer_ErrorValue
|
||||||
module Expression = Reducer_Expression
|
module Expression = Reducer_Expression
|
||||||
|
module ExpressionValue = ReducerInterface_ExpressionValue
|
||||||
|
module Lambda = Reducer_Expression_Lambda
|
||||||
|
|
||||||
type environment = ReducerInterface_ExpressionValue.environment
|
type environment = ReducerInterface_ExpressionValue.environment
|
||||||
type errorValue = Reducer_ErrorValue.errorValue
|
type errorValue = Reducer_ErrorValue.errorValue
|
||||||
type expressionValue = ReducerInterface_ExpressionValue.expressionValue
|
type expressionValue = ReducerInterface_ExpressionValue.expressionValue
|
||||||
type externalBindings = ReducerInterface_ExpressionValue.externalBindings
|
type externalBindings = ReducerInterface_ExpressionValue.externalBindings
|
||||||
|
type lambdaValue = ExpressionValue.lambdaValue
|
||||||
|
|
||||||
let evaluate = Expression.evaluate
|
let evaluate = Expression.evaluate
|
||||||
let evaluateUsingOptions = Expression.evaluateUsingOptions
|
let evaluateUsingOptions = Expression.evaluateUsingOptions
|
||||||
let evaluatePartialUsingExternalBindings = Expression.evaluatePartialUsingExternalBindings
|
let evaluatePartialUsingExternalBindings = Expression.evaluatePartialUsingExternalBindings
|
||||||
let parse = Expression.parse
|
let parse = Expression.parse
|
||||||
|
|
||||||
|
let foreignFunctionInterface = (
|
||||||
|
lambdaValue: lambdaValue,
|
||||||
|
argArray: array<expressionValue>,
|
||||||
|
environment: ExpressionValue.environment,
|
||||||
|
) => {
|
||||||
|
Lambda.foreignFunctionInterface(lambdaValue, argArray, environment, Expression.reduceExpression)
|
||||||
|
}
|
||||||
|
|
||||||
|
let defaultEnvironment = ExpressionValue.defaultEnvironment
|
||||||
|
|
||||||
|
let defaultExternalBindings = ExpressionValue.defaultExternalBindings
|
||||||
|
|
|
@ -9,6 +9,8 @@ type errorValue = Reducer_ErrorValue.errorValue
|
||||||
type expressionValue = ReducerInterface_ExpressionValue.expressionValue
|
type expressionValue = ReducerInterface_ExpressionValue.expressionValue
|
||||||
@genType
|
@genType
|
||||||
type externalBindings = ReducerInterface_ExpressionValue.externalBindings
|
type externalBindings = ReducerInterface_ExpressionValue.externalBindings
|
||||||
|
@genType
|
||||||
|
type lambdaValue = ReducerInterface_ExpressionValue.lambdaValue
|
||||||
|
|
||||||
@genType
|
@genType
|
||||||
let evaluateUsingOptions: (
|
let evaluateUsingOptions: (
|
||||||
|
@ -26,3 +28,16 @@ let evaluatePartialUsingExternalBindings: (
|
||||||
let evaluate: string => result<expressionValue, errorValue>
|
let evaluate: string => result<expressionValue, errorValue>
|
||||||
|
|
||||||
let parse: string => result<Expression.expression, errorValue>
|
let parse: string => result<Expression.expression, errorValue>
|
||||||
|
|
||||||
|
@genType
|
||||||
|
let foreignFunctionInterface: (
|
||||||
|
QuriSquiggleLang.ReducerInterface_ExpressionValue.lambdaValue,
|
||||||
|
array<QuriSquiggleLang.ReducerInterface_ExpressionValue.expressionValue>,
|
||||||
|
QuriSquiggleLang.ReducerInterface_ExpressionValue.environment,
|
||||||
|
) => result<expressionValue, errorValue>
|
||||||
|
|
||||||
|
@genType
|
||||||
|
let defaultEnvironment: environment
|
||||||
|
|
||||||
|
@genType
|
||||||
|
let defaultExternalBindings: externalBindings
|
||||||
|
|
|
@ -132,6 +132,23 @@ let dispatchMacroCall = (
|
||||||
eLambda(parameters, bindings->Bindings.toExternalBindings, lambdaDefinition),
|
eLambda(parameters, bindings->Bindings.toExternalBindings, lambdaDefinition),
|
||||||
)->Ok
|
)->Ok
|
||||||
|
|
||||||
|
let doTernary = (
|
||||||
|
condition: expression,
|
||||||
|
ifTrue: expression,
|
||||||
|
ifFalse: expression,
|
||||||
|
bindings: ExpressionT.bindings,
|
||||||
|
environment,
|
||||||
|
): result<expressionWithContext, errorValue> => {
|
||||||
|
let rCondition = reduceExpression(condition, bindings, environment)
|
||||||
|
rCondition->Result.flatMap(conditionValue =>
|
||||||
|
switch conditionValue {
|
||||||
|
| ExpressionValue.EvBool(false) => ExpressionWithContext.noContext(ifFalse)->Ok
|
||||||
|
| ExpressionValue.EvBool(true) => ExpressionWithContext.noContext(ifTrue)->Ok
|
||||||
|
| _ => REExpectedType("Boolean")->Error
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
let expandExpressionList = (aList, bindings: ExpressionT.bindings, environment): result<
|
let expandExpressionList = (aList, bindings: ExpressionT.bindings, environment): result<
|
||||||
expressionWithContext,
|
expressionWithContext,
|
||||||
errorValue,
|
errorValue,
|
||||||
|
@ -162,6 +179,8 @@ let dispatchMacroCall = (
|
||||||
lambdaDefinition,
|
lambdaDefinition,
|
||||||
} =>
|
} =>
|
||||||
doLambdaDefinition(bindings, parameters, lambdaDefinition)
|
doLambdaDefinition(bindings, parameters, lambdaDefinition)
|
||||||
|
| list{ExpressionT.EValue(EvCall("$$ternary")), condition, ifTrue, ifFalse} =>
|
||||||
|
doTernary(condition, ifTrue, ifFalse, bindings, environment)
|
||||||
| _ => ExpressionWithContext.noContext(ExpressionT.EList(aList))->Ok
|
| _ => ExpressionWithContext.noContext(ExpressionT.EList(aList))->Ok
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,7 @@ type errorValue =
|
||||||
| RESymbolNotFound(string)
|
| RESymbolNotFound(string)
|
||||||
| RESyntaxError(string)
|
| RESyntaxError(string)
|
||||||
| RETodo(string) // To do
|
| RETodo(string) // To do
|
||||||
|
| REExpectedType(string)
|
||||||
|
|
||||||
type t = errorValue
|
type t = errorValue
|
||||||
|
|
||||||
|
@ -46,4 +47,5 @@ let errorToString = err =>
|
||||||
| RESymbolNotFound(symbolName) => `${symbolName} is not defined`
|
| RESymbolNotFound(symbolName) => `${symbolName} is not defined`
|
||||||
| RESyntaxError(desc) => `Syntax Error: ${desc}`
|
| RESyntaxError(desc) => `Syntax Error: ${desc}`
|
||||||
| RETodo(msg) => `TODO: ${msg}`
|
| RETodo(msg) => `TODO: ${msg}`
|
||||||
|
| REExpectedType(typeName) => `Expected type: ${typeName}`
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,3 +57,13 @@ let applyParametersToLambda = (
|
||||||
|
|
||||||
let doLambdaCall = (lambdaValue: ExpressionValue.lambdaValue, args, environment, reducer) =>
|
let doLambdaCall = (lambdaValue: ExpressionValue.lambdaValue, args, environment, reducer) =>
|
||||||
applyParametersToLambda(lambdaValue, args, environment, reducer)
|
applyParametersToLambda(lambdaValue, args, environment, reducer)
|
||||||
|
|
||||||
|
let foreignFunctionInterface = (
|
||||||
|
lambdaValue: ExpressionValue.lambdaValue,
|
||||||
|
argArray: array<expressionValue>,
|
||||||
|
environment: ExpressionValue.environment,
|
||||||
|
reducer: ExpressionT.reducerFn,
|
||||||
|
): result<expressionValue, 'e> => {
|
||||||
|
let args = argArray->Belt.List.fromArray
|
||||||
|
applyParametersToLambda(lambdaValue, args, environment, reducer)
|
||||||
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ type node = {"type": string, "isNode": bool, "comment": string}
|
||||||
type arrayNode = {...node, "items": array<node>}
|
type arrayNode = {...node, "items": array<node>}
|
||||||
type block = {"node": node}
|
type block = {"node": node}
|
||||||
type blockNode = {...node, "blocks": array<block>}
|
type blockNode = {...node, "blocks": array<block>}
|
||||||
//conditionalNode
|
type conditionalNode = {...node, "condition": node, "trueExpr": node, "falseExpr": node}
|
||||||
type constantNode = {...node, "value": unit}
|
type constantNode = {...node, "value": unit}
|
||||||
type functionAssignmentNode = {...node, "name": string, "params": array<string>, "expr": node}
|
type functionAssignmentNode = {...node, "name": string, "params": array<string>, "expr": node}
|
||||||
type indexNode = {...node, "dimensions": array<node>}
|
type indexNode = {...node, "dimensions": array<node>}
|
||||||
|
@ -31,6 +31,7 @@ external castAssignmentNode: node => assignmentNode = "%identity"
|
||||||
external castAssignmentNodeWAccessor: node => assignmentNodeWAccessor = "%identity"
|
external castAssignmentNodeWAccessor: node => assignmentNodeWAccessor = "%identity"
|
||||||
external castAssignmentNodeWIndex: node => assignmentNodeWIndex = "%identity"
|
external castAssignmentNodeWIndex: node => assignmentNodeWIndex = "%identity"
|
||||||
external castBlockNode: node => blockNode = "%identity"
|
external castBlockNode: node => blockNode = "%identity"
|
||||||
|
external castConditionalNode: node => conditionalNode = "%identity"
|
||||||
external castConstantNode: node => constantNode = "%identity"
|
external castConstantNode: node => constantNode = "%identity"
|
||||||
external castFunctionAssignmentNode: node => functionAssignmentNode = "%identity"
|
external castFunctionAssignmentNode: node => functionAssignmentNode = "%identity"
|
||||||
external castFunctionNode: node => functionNode = "%identity"
|
external castFunctionNode: node => functionNode = "%identity"
|
||||||
|
@ -58,6 +59,7 @@ type mathJsNode =
|
||||||
| MjArrayNode(arrayNode)
|
| MjArrayNode(arrayNode)
|
||||||
| MjAssignmentNode(assignmentNode)
|
| MjAssignmentNode(assignmentNode)
|
||||||
| MjBlockNode(blockNode)
|
| MjBlockNode(blockNode)
|
||||||
|
| MjConditionalNode(conditionalNode)
|
||||||
| MjConstantNode(constantNode)
|
| MjConstantNode(constantNode)
|
||||||
| MjFunctionAssignmentNode(functionAssignmentNode)
|
| MjFunctionAssignmentNode(functionAssignmentNode)
|
||||||
| MjFunctionNode(functionNode)
|
| MjFunctionNode(functionNode)
|
||||||
|
@ -82,6 +84,7 @@ let castNodeType = (node: node) => {
|
||||||
| "ArrayNode" => node->castArrayNode->MjArrayNode->Ok
|
| "ArrayNode" => node->castArrayNode->MjArrayNode->Ok
|
||||||
| "AssignmentNode" => node->decideAssignmentNode
|
| "AssignmentNode" => node->decideAssignmentNode
|
||||||
| "BlockNode" => node->castBlockNode->MjBlockNode->Ok
|
| "BlockNode" => node->castBlockNode->MjBlockNode->Ok
|
||||||
|
| "ConditionalNode" => node->castConditionalNode->MjConditionalNode->Ok
|
||||||
| "ConstantNode" => node->castConstantNode->MjConstantNode->Ok
|
| "ConstantNode" => node->castConstantNode->MjConstantNode->Ok
|
||||||
| "FunctionAssignmentNode" => node->castFunctionAssignmentNode->MjFunctionAssignmentNode->Ok
|
| "FunctionAssignmentNode" => node->castFunctionAssignmentNode->MjFunctionAssignmentNode->Ok
|
||||||
| "FunctionNode" => node->castFunctionNode->MjFunctionNode->Ok
|
| "FunctionNode" => node->castFunctionNode->MjFunctionNode->Ok
|
||||||
|
@ -157,6 +160,10 @@ let rec toString = (mathJsNode: mathJsNode): string => {
|
||||||
| MjAssignmentNode(aNode) =>
|
| MjAssignmentNode(aNode) =>
|
||||||
`${aNode["object"]->toStringSymbolNode} = ${aNode["value"]->toStringMathJsNode}`
|
`${aNode["object"]->toStringSymbolNode} = ${aNode["value"]->toStringMathJsNode}`
|
||||||
| MjBlockNode(bNode) => `{${bNode["blocks"]->toStringBlocks}}`
|
| MjBlockNode(bNode) => `{${bNode["blocks"]->toStringBlocks}}`
|
||||||
|
| MjConditionalNode(cNode) =>
|
||||||
|
`ternary(${toStringMathJsNode(cNode["condition"])}, ${toStringMathJsNode(
|
||||||
|
cNode["trueExpr"],
|
||||||
|
)}, ${toStringMathJsNode(cNode["falseExpr"])})`
|
||||||
| MjConstantNode(cNode) => cNode["value"]->toStringValue
|
| MjConstantNode(cNode) => cNode["value"]->toStringValue
|
||||||
| MjFunctionAssignmentNode(faNode) => faNode->toStringFunctionAssignmentNode
|
| MjFunctionAssignmentNode(faNode) => faNode->toStringFunctionAssignmentNode
|
||||||
| MjFunctionNode(fNode) => fNode->toStringFunctionNode
|
| MjFunctionNode(fNode) => fNode->toStringFunctionNode
|
||||||
|
|
|
@ -113,6 +113,20 @@ let rec fromInnerNode = (mathJsNode: Parse.node): result<expression, errorValue>
|
||||||
aNode["items"]->Belt.List.fromArray->fromNodeList->Result.map(list => ExpressionT.EList(list))
|
aNode["items"]->Belt.List.fromArray->fromNodeList->Result.map(list => ExpressionT.EList(list))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let caseConditionalNode = cndNode => {
|
||||||
|
let rCondition = fromInnerNode(cndNode["condition"])
|
||||||
|
let rTrueExpr = fromInnerNode(cndNode["trueExpr"])
|
||||||
|
let rFalse = fromInnerNode(cndNode["falseExpr"])
|
||||||
|
|
||||||
|
rCondition->Result.flatMap(condition =>
|
||||||
|
rTrueExpr->Result.flatMap(trueExpr =>
|
||||||
|
rFalse->Result.flatMap(falseExpr =>
|
||||||
|
ExpressionBuilder.eFunction("$$ternary", list{condition, trueExpr, falseExpr})->Ok
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
let rFinalExpression: result<expression, errorValue> = switch typedMathJsNode {
|
let rFinalExpression: result<expression, errorValue> = switch typedMathJsNode {
|
||||||
| MjAccessorNode(aNode) => caseAccessorNode(aNode["object"], aNode["index"])
|
| MjAccessorNode(aNode) => caseAccessorNode(aNode["object"], aNode["index"])
|
||||||
| MjArrayNode(aNode) => caseArrayNode(aNode)
|
| MjArrayNode(aNode) => caseArrayNode(aNode)
|
||||||
|
@ -123,6 +137,7 @@ let rec fromInnerNode = (mathJsNode: Parse.node): result<expression, errorValue>
|
||||||
rExpr
|
rExpr
|
||||||
}
|
}
|
||||||
| MjBlockNode(bNode) => bNode["blocks"]->Js.Array2.map(blockToNode)->caseBlock
|
| MjBlockNode(bNode) => bNode["blocks"]->Js.Array2.map(blockToNode)->caseBlock
|
||||||
|
| MjConditionalNode(cndNode) => caseConditionalNode(cndNode)
|
||||||
| MjConstantNode(cNode) =>
|
| MjConstantNode(cNode) =>
|
||||||
cNode["value"]->JavaScript.Gate.jsToEv->Result.flatMap(v => v->ExpressionT.EValue->Ok)
|
cNode["value"]->JavaScript.Gate.jsToEv->Result.flatMap(v => v->ExpressionT.EValue->Ok)
|
||||||
| MjFunctionAssignmentNode(faNode) => caseFunctionAssignmentNode(faNode)
|
| MjFunctionAssignmentNode(faNode) => caseFunctionAssignmentNode(faNode)
|
||||||
|
|
|
@ -12,8 +12,8 @@
|
||||||
"format": "prettier --write ."
|
"format": "prettier --write ."
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@docusaurus/core": "2.0.0-beta.18",
|
"@docusaurus/core": "2.0.0-beta.19",
|
||||||
"@docusaurus/preset-classic": "2.0.0-beta.18",
|
"@docusaurus/preset-classic": "2.0.0-beta.19",
|
||||||
"@quri/squiggle-components": "0.2.9",
|
"@quri/squiggle-components": "0.2.9",
|
||||||
"clsx": "^1.1.1",
|
"clsx": "^1.1.1",
|
||||||
"prism-react-renderer": "^1.2.1",
|
"prism-react-renderer": "^1.2.1",
|
||||||
|
|
Loading…
Reference in New Issue
Block a user