2022-04-12 05:41:36 +00:00
|
|
|
import * as _ from "lodash";
|
|
|
|
import {
|
2022-04-29 18:41:30 +00:00
|
|
|
environment,
|
2022-04-29 22:51:00 +00:00
|
|
|
defaultEnvironment,
|
2022-04-29 13:50:57 +00:00
|
|
|
evaluatePartialUsingExternalBindings,
|
2022-04-29 19:02:24 +00:00
|
|
|
evaluateUsingOptions,
|
2022-04-29 13:50:57 +00:00
|
|
|
externalBindings,
|
2022-04-12 05:41:36 +00:00
|
|
|
expressionValue,
|
|
|
|
errorValue,
|
2022-05-10 15:52:13 +00:00
|
|
|
foreignFunctionInterface,
|
2022-04-12 05:41:36 +00:00
|
|
|
} from "../rescript/TypescriptInterface.gen";
|
|
|
|
export {
|
|
|
|
makeSampleSetDist,
|
|
|
|
errorValueToString,
|
|
|
|
distributionErrorToString,
|
2022-05-02 19:04:16 +00:00
|
|
|
distributionError,
|
2022-05-25 23:27:15 +00:00
|
|
|
declarationArg,
|
|
|
|
declaration,
|
2022-04-12 05:41:36 +00:00
|
|
|
} from "../rescript/TypescriptInterface.gen";
|
2022-05-10 15:52:13 +00:00
|
|
|
export type { errorValue, externalBindings as bindings, jsImports };
|
2022-04-08 19:55:04 +00:00
|
|
|
import {
|
2022-04-29 20:10:39 +00:00
|
|
|
jsValueToBinding,
|
2022-05-10 15:52:13 +00:00
|
|
|
jsValueToExpressionValue,
|
2022-04-29 20:10:39 +00:00
|
|
|
jsValue,
|
|
|
|
rescriptExport,
|
|
|
|
squiggleExpression,
|
|
|
|
convertRawToTypescript,
|
2022-05-10 15:52:13 +00:00
|
|
|
lambdaValue,
|
2022-04-29 20:10:39 +00:00
|
|
|
} from "./rescript_interop";
|
|
|
|
import { result, resultMap, tag, tagged } from "./types";
|
2022-05-02 18:29:59 +00:00
|
|
|
import { Distribution, shape } from "./distribution";
|
2022-04-11 03:16:31 +00:00
|
|
|
|
2022-05-10 15:52:13 +00:00
|
|
|
export {
|
|
|
|
Distribution,
|
|
|
|
squiggleExpression,
|
|
|
|
result,
|
|
|
|
resultMap,
|
|
|
|
shape,
|
|
|
|
lambdaValue,
|
|
|
|
environment,
|
2022-05-10 16:24:08 +00:00
|
|
|
defaultEnvironment,
|
2022-05-10 15:52:13 +00:00
|
|
|
};
|
2022-04-28 18:59:15 +00:00
|
|
|
|
2022-05-10 15:52:13 +00:00
|
|
|
export let defaultSamplingInputs: environment = {
|
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 22:51:00 +00:00
|
|
|
environment?: environment,
|
2022-04-29 20:29:42 +00:00
|
|
|
imports?: jsImports
|
2022-04-11 03:16:31 +00:00
|
|
|
): result<squiggleExpression, errorValue> {
|
2022-04-29 19:02:43 +00:00
|
|
|
let b = bindings ? bindings : defaultBindings;
|
2022-04-29 20:29:42 +00:00
|
|
|
let i = imports ? imports : defaultImports;
|
2022-04-29 22:51:00 +00:00
|
|
|
let e = environment ? environment : defaultEnvironment;
|
2022-04-29 19:02:24 +00:00
|
|
|
let res: result<expressionValue, errorValue> = evaluateUsingOptions(
|
2022-05-09 14:18:50 +00:00
|
|
|
{ externalBindings: mergeImportsWithBindings(b, i), environment: e },
|
2022-04-29 19:02:24 +00:00
|
|
|
squiggleString
|
2022-04-29 22:51:00 +00:00
|
|
|
);
|
|
|
|
return resultMap(res, (x) => createTsExport(x, e));
|
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,
|
2022-04-29 22:51:00 +00:00
|
|
|
environment?: environment,
|
2022-04-29 20:29:42 +00:00
|
|
|
imports?: jsImports
|
2022-04-29 13:50:57 +00:00
|
|
|
): result<externalBindings, errorValue> {
|
2022-04-29 19:02:43 +00:00
|
|
|
let b = bindings ? bindings : defaultBindings;
|
2022-04-29 20:29:42 +00:00
|
|
|
let i = imports ? imports : defaultImports;
|
2022-04-29 22:51:00 +00:00
|
|
|
let e = environment ? environment : defaultEnvironment;
|
2022-04-29 18:46:44 +00:00
|
|
|
|
2022-04-29 18:41:30 +00:00
|
|
|
return evaluatePartialUsingExternalBindings(
|
|
|
|
squiggleString,
|
2022-05-09 14:18:50 +00:00
|
|
|
mergeImportsWithBindings(b, i),
|
2022-04-29 22:51:00 +00:00
|
|
|
e
|
2022-04-29 18:46:44 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-05-10 15:52:13 +00:00
|
|
|
export function runForeign(
|
|
|
|
fn: lambdaValue,
|
|
|
|
args: jsValue[],
|
|
|
|
environment?: environment
|
|
|
|
): result<squiggleExpression, errorValue> {
|
|
|
|
let e = environment ? environment : defaultEnvironment;
|
|
|
|
let res: result<expressionValue, errorValue> = foreignFunctionInterface(
|
|
|
|
fn,
|
|
|
|
args.map(jsValueToExpressionValue),
|
|
|
|
e
|
|
|
|
);
|
|
|
|
return resultMap(res, (x) => createTsExport(x, e));
|
|
|
|
}
|
|
|
|
|
2022-05-09 14:18:50 +00:00
|
|
|
function mergeImportsWithBindings(
|
2022-04-29 18:46:44 +00:00
|
|
|
bindings: externalBindings,
|
2022-04-29 20:29:42 +00:00
|
|
|
imports: jsImports
|
2022-04-29 18:46:44 +00:00
|
|
|
): externalBindings {
|
2022-04-29 20:29:42 +00:00
|
|
|
let transformedImports = Object.fromEntries(
|
|
|
|
Object.entries(imports).map(([key, value]) => [
|
2022-04-29 18:46:44 +00:00
|
|
|
"$" + key,
|
|
|
|
jsValueToBinding(value),
|
|
|
|
])
|
2022-04-29 18:41:30 +00:00
|
|
|
);
|
2022-04-29 20:29:42 +00:00
|
|
|
return _.merge(bindings, transformedImports);
|
2022-04-29 13:50:57 +00:00
|
|
|
}
|
|
|
|
|
2022-04-29 20:29:42 +00:00
|
|
|
type jsImports = { [key: string]: jsValue };
|
2022-04-29 18:46:44 +00:00
|
|
|
|
2022-04-29 20:29:42 +00:00
|
|
|
export let defaultImports: jsImports = {};
|
2022-04-29 19:02:43 +00:00
|
|
|
export let defaultBindings: externalBindings = {};
|
|
|
|
|
2022-05-09 14:18:50 +00:00
|
|
|
export function mergeBindings(
|
|
|
|
allBindings: externalBindings[]
|
|
|
|
): externalBindings {
|
|
|
|
return allBindings.reduce((acc, x) => ({ ...acc, ...x }));
|
|
|
|
}
|
|
|
|
|
2022-04-12 05:41:36 +00:00
|
|
|
function createTsExport(
|
|
|
|
x: expressionValue,
|
2022-04-29 22:51:00 +00:00
|
|
|
environment: environment
|
2022-04-12 05:41:36 +00:00
|
|
|
): squiggleExpression {
|
2022-04-11 03:16:31 +00:00
|
|
|
switch (x.tag) {
|
|
|
|
case "EvArray":
|
2022-04-28 20:26:40 +00:00
|
|
|
// 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
|
2022-04-12 05:41:36 +00:00
|
|
|
return tag(
|
|
|
|
"array",
|
2022-04-28 20:26:40 +00:00
|
|
|
x.value.map((arrayItem): squiggleExpression => {
|
|
|
|
switch (arrayItem.tag) {
|
|
|
|
case "EvRecord":
|
|
|
|
return tag(
|
|
|
|
"record",
|
|
|
|
_.mapValues(arrayItem.value, (recordValue: unknown) =>
|
2022-04-29 22:51:00 +00:00
|
|
|
convertRawToTypescript(
|
|
|
|
recordValue as rescriptExport,
|
|
|
|
environment
|
|
|
|
)
|
2022-04-28 20:26:40 +00:00
|
|
|
)
|
|
|
|
);
|
|
|
|
case "EvArray":
|
|
|
|
let y = arrayItem.value as unknown as rescriptExport[];
|
|
|
|
return tag(
|
|
|
|
"array",
|
|
|
|
y.map((childArrayItem) =>
|
2022-04-29 22:51:00 +00:00
|
|
|
convertRawToTypescript(childArrayItem, environment)
|
2022-04-28 20:26:40 +00:00
|
|
|
)
|
|
|
|
);
|
|
|
|
default:
|
2022-04-29 22:51:00 +00:00
|
|
|
return createTsExport(arrayItem, environment);
|
2022-04-28 20:26:40 +00:00
|
|
|
}
|
|
|
|
})
|
2022-04-12 05:41:36 +00:00
|
|
|
);
|
2022-04-29 18:41:30 +00:00
|
|
|
case "EvArrayString":
|
2022-04-29 22:51:00 +00:00
|
|
|
return tag("arraystring", x.value);
|
2022-04-11 03:16:31 +00:00
|
|
|
case "EvBool":
|
|
|
|
return tag("boolean", x.value);
|
2022-04-12 15:12:19 +00:00
|
|
|
case "EvCall":
|
|
|
|
return tag("call", x.value);
|
2022-04-25 07:20:27 +00:00
|
|
|
case "EvLambda":
|
|
|
|
return tag("lambda", x.value);
|
2022-04-11 03:16:31 +00:00
|
|
|
case "EvDistribution":
|
2022-04-29 22:51:00 +00:00
|
|
|
return tag("distribution", new Distribution(x.value, environment));
|
2022-04-11 03:16:31 +00:00
|
|
|
case "EvNumber":
|
|
|
|
return tag("number", x.value);
|
|
|
|
case "EvRecord":
|
2022-04-28 20:26:40 +00:00
|
|
|
// genType doesn't support records, so we have to do the raw conversion ourself
|
|
|
|
let result: tagged<"record", { [key: string]: squiggleExpression }> = tag(
|
2022-04-12 05:41:36 +00:00
|
|
|
"record",
|
2022-04-28 20:26:40 +00:00
|
|
|
_.mapValues(x.value, (x: unknown) =>
|
2022-04-29 22:51:00 +00:00
|
|
|
convertRawToTypescript(x as rescriptExport, environment)
|
2022-04-28 20:26:40 +00:00
|
|
|
)
|
2022-04-12 05:41:36 +00:00
|
|
|
);
|
2022-04-28 20:26:40 +00:00
|
|
|
return result;
|
2022-04-12 05:41:36 +00:00
|
|
|
case "EvString":
|
|
|
|
return tag("string", x.value);
|
|
|
|
case "EvSymbol":
|
|
|
|
return tag("symbol", x.value);
|
2022-05-22 22:37:07 +00:00
|
|
|
case "EvDate":
|
|
|
|
return tag("date", x.value);
|
|
|
|
case "EvTimeDuration":
|
|
|
|
return tag("timeDuration", x.value);
|
2022-05-24 21:23:37 +00:00
|
|
|
case "EvDeclaration":
|
|
|
|
return tag("lambdaDeclaration", x.value);
|
2022-05-26 09:09:08 +00:00
|
|
|
case "EvTypeIdentifier":
|
|
|
|
return tag("typeIdentifier", x.value);
|
2022-04-11 03:16:31 +00:00
|
|
|
}
|
|
|
|
}
|