2022-04-12 05:41:36 +00:00
|
|
|
import * as _ from "lodash";
|
|
|
|
import {
|
|
|
|
samplingParams,
|
2022-04-29 13:50:57 +00:00
|
|
|
evaluateUsingExternalBindings,
|
|
|
|
evaluatePartialUsingExternalBindings,
|
|
|
|
externalBindings,
|
2022-04-12 05:41:36 +00:00
|
|
|
expressionValue,
|
|
|
|
errorValue,
|
|
|
|
} from "../rescript/TypescriptInterface.gen";
|
|
|
|
export {
|
|
|
|
makeSampleSetDist,
|
|
|
|
errorValueToString,
|
|
|
|
distributionErrorToString,
|
|
|
|
} from "../rescript/TypescriptInterface.gen";
|
2022-04-29 19:02:43 +00:00
|
|
|
export type {
|
|
|
|
samplingParams,
|
|
|
|
errorValue,
|
|
|
|
externalBindings as bindings,
|
|
|
|
parameters,
|
|
|
|
};
|
2022-04-29 20:10:39 +00:00
|
|
|
import {
|
|
|
|
jsValueToBinding,
|
|
|
|
jsValue,
|
|
|
|
rescriptExport,
|
|
|
|
squiggleExpression,
|
|
|
|
convertRawToTypescript,
|
|
|
|
} from "./rescript_interop";
|
|
|
|
import { result, resultMap, tag, tagged } from "./types";
|
|
|
|
import { Distribution } from "./distribution";
|
|
|
|
|
|
|
|
export { Distribution, squiggleExpression, result };
|
2022-04-08 18:42:14 +00:00
|
|
|
|
2022-04-11 03:16:31 +00:00
|
|
|
export let defaultSamplingInputs: samplingParams = {
|
2022-04-08 18:42:14 +00:00
|
|
|
sampleCount: 10000,
|
2022-04-12 05:41:36 +00:00
|
|
|
xyPointLength: 10000,
|
2022-04-08 18:42:14 +00:00
|
|
|
};
|
|
|
|
|
2022-04-11 03:16:31 +00:00
|
|
|
export function run(
|
|
|
|
squiggleString: string,
|
2022-04-29 13:50:57 +00:00
|
|
|
bindings?: externalBindings,
|
2022-04-29 18:46:44 +00:00
|
|
|
samplingInputs?: samplingParams,
|
|
|
|
parameters?: parameters
|
2022-04-11 03:16:31 +00:00
|
|
|
): result<squiggleExpression, errorValue> {
|
2022-04-29 19:02:43 +00:00
|
|
|
let b = bindings ? bindings : defaultBindings;
|
|
|
|
let p = parameters ? parameters : defaultParameters;
|
2022-04-11 03:16:31 +00:00
|
|
|
let si: samplingParams = samplingInputs
|
|
|
|
? samplingInputs
|
|
|
|
: defaultSamplingInputs;
|
2022-04-29 13:50:57 +00:00
|
|
|
|
|
|
|
let result: result<expressionValue, errorValue> =
|
2022-04-29 18:46:44 +00:00
|
|
|
evaluateUsingExternalBindings(squiggleString, mergeParameters(b, p));
|
2022-04-12 05:41:36 +00:00
|
|
|
return resultMap(result, (x) => createTsExport(x, si));
|
2022-04-11 03:16:31 +00:00
|
|
|
}
|
|
|
|
|
2022-04-29 13:50:57 +00:00
|
|
|
// Run Partial. A partial is a block of code that doesn't return a value
|
|
|
|
export function runPartial(
|
|
|
|
squiggleString: string,
|
2022-04-29 18:46:44 +00:00
|
|
|
bindings?: externalBindings,
|
|
|
|
_samplingInputs?: samplingParams,
|
|
|
|
parameters?: parameters
|
2022-04-29 13:50:57 +00:00
|
|
|
): result<externalBindings, errorValue> {
|
2022-04-29 19:02:43 +00:00
|
|
|
let b = bindings ? bindings : defaultBindings;
|
|
|
|
let p = parameters ? parameters : defaultParameters;
|
2022-04-29 18:46:44 +00:00
|
|
|
|
|
|
|
return evaluatePartialUsingExternalBindings(
|
|
|
|
squiggleString,
|
|
|
|
mergeParameters(b, p)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function mergeParameters(
|
|
|
|
bindings: externalBindings,
|
|
|
|
parameters: parameters
|
|
|
|
): externalBindings {
|
2022-04-29 20:10:39 +00:00
|
|
|
let transformedParameters = Object.fromEntries(
|
2022-04-29 18:46:44 +00:00
|
|
|
Object.entries(parameters).map(([key, value]) => [
|
|
|
|
"$" + key,
|
|
|
|
jsValueToBinding(value),
|
|
|
|
])
|
|
|
|
);
|
2022-04-29 20:10:39 +00:00
|
|
|
return _.merge(bindings, transformedParameters);
|
2022-04-29 18:46:44 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type parameters = { [key: string]: jsValue };
|
|
|
|
|
2022-04-29 19:02:43 +00:00
|
|
|
export let defaultParameters: parameters = {};
|
|
|
|
export let defaultBindings: externalBindings = {};
|
|
|
|
|
2022-04-28 20:26:40 +00:00
|
|
|
function createTsExport(
|
|
|
|
x: expressionValue,
|
|
|
|
sampEnv: samplingParams
|
|
|
|
): squiggleExpression {
|
|
|
|
switch (x.tag) {
|
|
|
|
case "EvArray":
|
|
|
|
// genType doesn't convert anything more than 2 layers down into {tag: x, value: x}
|
|
|
|
// format, leaving it as the raw values. This converts the raw values
|
|
|
|
// directly into typescript values.
|
|
|
|
//
|
|
|
|
// The casting here is because genType is about the types of the returned
|
|
|
|
// values, claiming they are fully recursive when that's not actually the
|
|
|
|
// case
|
|
|
|
return tag(
|
|
|
|
"array",
|
|
|
|
x.value.map((arrayItem): squiggleExpression => {
|
|
|
|
switch (arrayItem.tag) {
|
|
|
|
case "EvRecord":
|
|
|
|
return tag(
|
|
|
|
"record",
|
|
|
|
_.mapValues(arrayItem.value, (recordValue: unknown) =>
|
|
|
|
convertRawToTypescript(recordValue as rescriptExport, sampEnv)
|
|
|
|
)
|
|
|
|
);
|
|
|
|
case "EvArray":
|
|
|
|
let y = arrayItem.value as unknown as rescriptExport[];
|
|
|
|
return tag(
|
|
|
|
"array",
|
|
|
|
y.map((childArrayItem) =>
|
|
|
|
convertRawToTypescript(childArrayItem, sampEnv)
|
|
|
|
)
|
|
|
|
);
|
|
|
|
default:
|
|
|
|
return createTsExport(arrayItem, sampEnv);
|
|
|
|
}
|
|
|
|
})
|
|
|
|
);
|
|
|
|
case "EvBool":
|
|
|
|
return tag("boolean", x.value);
|
|
|
|
case "EvCall":
|
|
|
|
return tag("call", x.value);
|
|
|
|
case "EvDistribution":
|
|
|
|
return tag("distribution", new Distribution(x.value, sampEnv));
|
|
|
|
case "EvNumber":
|
|
|
|
return tag("number", x.value);
|
|
|
|
case "EvRecord":
|
|
|
|
// genType doesn't support records, so we have to do the raw conversion ourself
|
|
|
|
let result: tagged<"record", { [key: string]: squiggleExpression }> = tag(
|
|
|
|
"record",
|
|
|
|
_.mapValues(x.value, (x: unknown) =>
|
|
|
|
convertRawToTypescript(x as rescriptExport, sampEnv)
|
|
|
|
)
|
|
|
|
);
|
|
|
|
return result;
|
|
|
|
case "EvString":
|
|
|
|
return tag("string", x.value);
|
|
|
|
case "EvSymbol":
|
|
|
|
return tag("symbol", x.value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|