project
This commit is contained in:
parent
fdc7f06f08
commit
f0ba68f64a
|
@ -1,6 +1,6 @@
|
||||||
@@warning("-44")
|
@@warning("-44")
|
||||||
module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue
|
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
|
||||||
module Project = ReducerProject
|
module Project = ForTS_ReducerProject
|
||||||
module Bindings = Reducer_Bindings
|
module Bindings = Reducer_Bindings
|
||||||
|
|
||||||
open Jest
|
open Jest
|
||||||
|
@ -11,14 +11,14 @@ open Expect.Operators
|
||||||
|
|
||||||
let runFetchResult = (project, sourceId) => {
|
let runFetchResult = (project, sourceId) => {
|
||||||
Project.run(project, sourceId)
|
Project.run(project, sourceId)
|
||||||
Project.getExternalResult(project, sourceId)->ExternalExpressionValue.toStringOptionResult
|
Project.getResult(project, sourceId)->InternalExpressionValue.toStringOptionResult
|
||||||
}
|
}
|
||||||
|
|
||||||
let runFetchBindings = (project, sourceId) => {
|
let runFetchBindings = (project, sourceId) => {
|
||||||
Project.run(project, sourceId)
|
Project.run(project, sourceId)
|
||||||
Project.getExternalBindings(project, sourceId)
|
Project.getBindings(project, sourceId)
|
||||||
->ExternalExpressionValue.EvModule
|
->InternalExpressionValue.IEvBindings
|
||||||
->ExternalExpressionValue.toString
|
->InternalExpressionValue.toString
|
||||||
}
|
}
|
||||||
|
|
||||||
test("setting continuation", () => {
|
test("setting continuation", () => {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
@@warning("-44")
|
@@warning("-44")
|
||||||
module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue
|
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
|
||||||
module Project = ReducerProject
|
module Project = ForTS_ReducerProject
|
||||||
module Bindings = Reducer_Bindings
|
module Bindings = Reducer_Bindings
|
||||||
|
|
||||||
open Jest
|
open Jest
|
||||||
|
@ -45,13 +45,13 @@ Case "Running a single source".
|
||||||
Note that getResult returns None if the source has not been run.
|
Note that getResult returns None if the source has not been run.
|
||||||
Getting None means you have forgotten to run the source.
|
Getting None means you have forgotten to run the source.
|
||||||
*/
|
*/
|
||||||
let result = project->Project.getExternalResult("main")
|
let result = project->Project.getResult("main")
|
||||||
let bindings = project->Project.getExternalBindings("main")
|
let bindings = project->Project.getBindings("main")
|
||||||
|
|
||||||
/* Let's display the result and bindings */
|
/* Let's display the result and bindings */
|
||||||
(
|
(
|
||||||
result->ExternalExpressionValue.toStringOptionResult,
|
result->InternalExpressionValue.toStringOptionResult,
|
||||||
bindings->ExternalExpressionValue.EvModule->ExternalExpressionValue.toString,
|
bindings->InternalExpressionValue.IEvBindings->InternalExpressionValue.toString,
|
||||||
)->expect == ("Ok(3)", "@{}")
|
)->expect == ("Ok(3)", "@{}")
|
||||||
/* You've got 3 with empty bindings. */
|
/* You've got 3 with empty bindings. */
|
||||||
})
|
})
|
||||||
|
@ -60,12 +60,12 @@ Case "Running a single source".
|
||||||
let project = Project.createProject()
|
let project = Project.createProject()
|
||||||
Project.setSource(project, "main", "1 + 2")
|
Project.setSource(project, "main", "1 + 2")
|
||||||
Project.runAll(project)
|
Project.runAll(project)
|
||||||
let result = Project.getExternalResult(project, "main")
|
let result = Project.getResult(project, "main")
|
||||||
let bindings = Project.getExternalBindings(project, "main")
|
let bindings = Project.getBindings(project, "main")
|
||||||
/* Now you have external bindings and external result. */
|
/* Now you have external bindings and external result. */
|
||||||
(
|
(
|
||||||
result->ExternalExpressionValue.toStringOptionResult,
|
result->InternalExpressionValue.toStringOptionResult,
|
||||||
bindings->ExternalExpressionValue.EvModule->ExternalExpressionValue.toString,
|
bindings->InternalExpressionValue.IEvBindings->InternalExpressionValue.toString,
|
||||||
)->expect == ("Ok(3)", "@{}")
|
)->expect == ("Ok(3)", "@{}")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -74,13 +74,13 @@ Case "Running a single source".
|
||||||
let project = Project.createProject()
|
let project = Project.createProject()
|
||||||
|
|
||||||
/* Optional. Set your custom environment anytime before running */
|
/* Optional. Set your custom environment anytime before running */
|
||||||
Project.setEnvironment(project, ExternalExpressionValue.defaultEnvironment)
|
Project.setEnvironment(project, InternalExpressionValue.defaultEnvironment)
|
||||||
|
|
||||||
Project.setSource(project, "main", "1 + 2")
|
Project.setSource(project, "main", "1 + 2")
|
||||||
Project.runAll(project)
|
Project.runAll(project)
|
||||||
let result = Project.getExternalResult(project, "main")
|
let result = Project.getResult(project, "main")
|
||||||
let _bindings = Project.getExternalBindings(project, "main")
|
let _bindings = Project.getBindings(project, "main")
|
||||||
result->ExternalExpressionValue.toStringOptionResult->expect == "Ok(3)"
|
result->InternalExpressionValue.toStringOptionResult->expect == "Ok(3)"
|
||||||
})
|
})
|
||||||
|
|
||||||
test("shortcut", () => {
|
test("shortcut", () => {
|
||||||
|
@ -88,8 +88,8 @@ Case "Running a single source".
|
||||||
/* Examples above was to prepare you for the multi source tutorial. */
|
/* Examples above was to prepare you for the multi source tutorial. */
|
||||||
let (result, bindings) = Project.evaluate("1+2")
|
let (result, bindings) = Project.evaluate("1+2")
|
||||||
(
|
(
|
||||||
result->ExternalExpressionValue.toStringResult,
|
result->InternalExpressionValue.toStringResult,
|
||||||
bindings->ExternalExpressionValue.EvModule->ExternalExpressionValue.toString,
|
bindings->InternalExpressionValue.IEvBindings->InternalExpressionValue.toString,
|
||||||
)->expect == ("Ok(3)", "@{}")
|
)->expect == ("Ok(3)", "@{}")
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,19 +1,14 @@
|
||||||
import * as _ from "lodash";
|
import * as _ from "lodash";
|
||||||
import type {
|
import type {
|
||||||
environment,
|
environment,
|
||||||
expressionValue,
|
|
||||||
externalBindings,
|
externalBindings,
|
||||||
errorValue,
|
errorValue,
|
||||||
} from "../rescript/TypescriptInterface.gen";
|
} from "../rescript/TypescriptInterface.gen";
|
||||||
import {
|
import {
|
||||||
defaultEnvironment,
|
defaultEnvironment,
|
||||||
evaluatePartialUsingExternalBindings,
|
|
||||||
evaluateUsingOptions,
|
|
||||||
foreignFunctionInterface,
|
|
||||||
} from "../rescript/TypescriptInterface.gen";
|
} from "../rescript/TypescriptInterface.gen";
|
||||||
export {
|
export {
|
||||||
makeSampleSetDist,
|
makeSampleSetDist,
|
||||||
errorValueToString,
|
|
||||||
distributionErrorToString,
|
distributionErrorToString,
|
||||||
} from "../rescript/TypescriptInterface.gen";
|
} from "../rescript/TypescriptInterface.gen";
|
||||||
export type {
|
export type {
|
||||||
|
@ -23,12 +18,7 @@ export type {
|
||||||
} from "../rescript/TypescriptInterface.gen";
|
} from "../rescript/TypescriptInterface.gen";
|
||||||
export type { errorValue, externalBindings as bindings, jsImports };
|
export type { errorValue, externalBindings as bindings, jsImports };
|
||||||
import {
|
import {
|
||||||
jsValueToBinding,
|
|
||||||
jsValueToExpressionValue,
|
|
||||||
jsValue,
|
|
||||||
rescriptExport,
|
|
||||||
squiggleExpression,
|
squiggleExpression,
|
||||||
convertRawToTypescript,
|
|
||||||
lambdaValue,
|
lambdaValue,
|
||||||
} from "./rescript_interop";
|
} from "./rescript_interop";
|
||||||
import { result, resultMap, tag, tagged } from "./types";
|
import { result, resultMap, tag, tagged } from "./types";
|
||||||
|
@ -44,162 +34,167 @@ export let defaultSamplingInputs: environment = {
|
||||||
xyPointLength: 10000,
|
xyPointLength: 10000,
|
||||||
};
|
};
|
||||||
|
|
||||||
export function run(
|
|
||||||
squiggleString: string,
|
|
||||||
bindings?: externalBindings,
|
|
||||||
environment?: environment,
|
|
||||||
imports?: jsImports
|
|
||||||
): result<squiggleExpression, errorValue> {
|
|
||||||
let b = bindings ? bindings : defaultBindings;
|
|
||||||
let i = imports ? imports : defaultImports;
|
|
||||||
let e = environment ? environment : defaultEnvironment;
|
|
||||||
let res: result<expressionValue, errorValue> = evaluateUsingOptions(
|
|
||||||
{ externalBindings: mergeImportsWithBindings(b, i), environment: e },
|
|
||||||
squiggleString
|
|
||||||
);
|
|
||||||
return resultMap(res, (x) => createTsExport(x, e));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run Partial. A partial is a block of code that doesn't return a value
|
/*
|
||||||
export function runPartial(
|
All those functions below are invalid since the introduction of ReducerProject
|
||||||
squiggleString: string,
|
*/
|
||||||
bindings?: externalBindings,
|
// export function run(
|
||||||
environment?: environment,
|
// squiggleString: string,
|
||||||
imports?: jsImports
|
// bindings?: externalBindings,
|
||||||
): result<externalBindings, errorValue> {
|
// environment?: environment,
|
||||||
let b = bindings ? bindings : defaultBindings;
|
// imports?: jsImports
|
||||||
let i = imports ? imports : defaultImports;
|
// ): result<squiggleExpression, errorValue> {
|
||||||
let e = environment ? environment : defaultEnvironment;
|
// let b = bindings ? bindings : defaultBindings;
|
||||||
|
// let i = imports ? imports : defaultImports;
|
||||||
|
// let e = environment ? environment : defaultEnvironment;
|
||||||
|
// let res: result<expressionValue, errorValue> = evaluateUsingOptions(
|
||||||
|
// { externalBindings: mergeImportsWithBindings(b, i), environment: e },
|
||||||
|
// squiggleString
|
||||||
|
// );
|
||||||
|
// return resultMap(res, (x) => createTsExport(x, e));
|
||||||
|
// }
|
||||||
|
|
||||||
return evaluatePartialUsingExternalBindings(
|
// // Run Partial. A partial is a block of code that doesn't return a value
|
||||||
squiggleString,
|
// export function runPartial(
|
||||||
mergeImportsWithBindings(b, i),
|
// squiggleString: string,
|
||||||
e
|
// bindings?: externalBindings,
|
||||||
);
|
// environment?: environment,
|
||||||
}
|
// imports?: jsImports
|
||||||
|
// ): result<externalBindings, errorValue> {
|
||||||
|
// let b = bindings ? bindings : defaultBindings;
|
||||||
|
// let i = imports ? imports : defaultImports;
|
||||||
|
// let e = environment ? environment : defaultEnvironment;
|
||||||
|
|
||||||
export function runForeign(
|
// return evaluatePartialUsingExternalBindings(
|
||||||
fn: lambdaValue,
|
// squiggleString,
|
||||||
args: jsValue[],
|
// mergeImportsWithBindings(b, i),
|
||||||
environment?: environment
|
// e
|
||||||
): 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));
|
|
||||||
}
|
|
||||||
|
|
||||||
function mergeImportsWithBindings(
|
// jsValueToExpressionValue is invalid
|
||||||
bindings: externalBindings,
|
// export function runForeign(
|
||||||
imports: jsImports
|
// fn: lambdaValue,
|
||||||
): externalBindings {
|
// args: jsValue[],
|
||||||
let transformedImports = Object.fromEntries(
|
// environment?: environment
|
||||||
Object.entries(imports).map(([key, value]) => [
|
// ): result<squiggleExpression, errorValue> {
|
||||||
"$" + key,
|
// let e = environment ? environment : defaultEnvironment;
|
||||||
jsValueToBinding(value),
|
// let res: result<expressionValue, errorValue> = foreignFunctionInterface(
|
||||||
])
|
// fn,
|
||||||
);
|
// args.map(jsValueToExpressionValue),
|
||||||
return _.merge(bindings, transformedImports);
|
// e
|
||||||
}
|
// );
|
||||||
|
// return resultMap(res, (x) => createTsExport(x, e));
|
||||||
|
// }
|
||||||
|
|
||||||
type jsImports = { [key: string]: jsValue };
|
// function mergeImportsWithBindings(
|
||||||
|
// bindings: externalBindings,
|
||||||
|
// imports: jsImports
|
||||||
|
// ): externalBindings {
|
||||||
|
// let transformedImports = Object.fromEntries(
|
||||||
|
// Object.entries(imports).map(([key, value]) => [
|
||||||
|
// "$" + key,
|
||||||
|
// jsValueToBinding(value),
|
||||||
|
// ])
|
||||||
|
// );
|
||||||
|
// return _.merge(bindings, transformedImports);
|
||||||
|
// }
|
||||||
|
|
||||||
export let defaultImports: jsImports = {};
|
// type jsImports = { [key: string]: jsValue };
|
||||||
export let defaultBindings: externalBindings = {};
|
|
||||||
|
|
||||||
export function mergeBindings(
|
// export let defaultImports: jsImports = {};
|
||||||
allBindings: externalBindings[]
|
// export let defaultBindings: externalBindings = {};
|
||||||
): externalBindings {
|
|
||||||
return allBindings.reduce((acc, x) => ({ ...acc, ...x }));
|
|
||||||
}
|
|
||||||
|
|
||||||
function createTsExport(
|
// export function mergeBindings(
|
||||||
x: expressionValue,
|
// allBindings: externalBindings[]
|
||||||
environment: environment
|
// ): externalBindings {
|
||||||
): squiggleExpression {
|
// return allBindings.reduce((acc, x) => ({ ...acc, ...x }));
|
||||||
switch (x) {
|
// }
|
||||||
case "EvVoid":
|
|
||||||
return tag("void", "");
|
// function createTsExport(
|
||||||
default: {
|
// x: expressionValue,
|
||||||
switch (x.tag) {
|
// environment: environment
|
||||||
case "EvArray":
|
// ): squiggleExpression {
|
||||||
// genType doesn't convert anything more than 2 layers down into {tag: x, value: x}
|
// switch (x) {
|
||||||
// format, leaving it as the raw values. This converts the raw values
|
// case "EvVoid":
|
||||||
// directly into typescript values.
|
// return tag("void", "");
|
||||||
//
|
// default: {
|
||||||
// The casting here is because genType is about the types of the returned
|
// switch (x.tag) {
|
||||||
// values, claiming they are fully recursive when that's not actually the
|
// case "EvArray":
|
||||||
// case
|
// // genType doesn't convert anything more than 2 layers down into {tag: x, value: x}
|
||||||
return tag(
|
// // format, leaving it as the raw values. This converts the raw values
|
||||||
"array",
|
// // directly into typescript values.
|
||||||
x.value.map(
|
// //
|
||||||
(arrayItem): squiggleExpression =>
|
// // The casting here is because genType is about the types of the returned
|
||||||
convertRawToTypescript(
|
// // values, claiming they are fully recursive when that's not actually the
|
||||||
arrayItem as unknown as rescriptExport,
|
// // case
|
||||||
environment
|
// return tag(
|
||||||
)
|
// "array",
|
||||||
)
|
// x.value.map(
|
||||||
);
|
// (arrayItem): squiggleExpression =>
|
||||||
case "EvArrayString":
|
// convertRawToTypescript(
|
||||||
return tag("arraystring", x.value);
|
// arrayItem as unknown as rescriptExport,
|
||||||
case "EvBool":
|
// environment
|
||||||
return tag("boolean", x.value);
|
// )
|
||||||
case "EvCall":
|
// )
|
||||||
return tag("call", x.value);
|
// );
|
||||||
case "EvLambda":
|
// case "EvArrayString":
|
||||||
return tag("lambda", x.value);
|
// return tag("arraystring", x.value);
|
||||||
case "EvDistribution":
|
// case "EvBool":
|
||||||
return tag("distribution", new Distribution(x.value, environment));
|
// return tag("boolean", x.value);
|
||||||
case "EvNumber":
|
// case "EvCall":
|
||||||
return tag("number", x.value);
|
// return tag("call", x.value);
|
||||||
case "EvRecord":
|
// case "EvLambda":
|
||||||
// genType doesn't support records, so we have to do the raw conversion ourself
|
// return tag("lambda", x.value);
|
||||||
let result: tagged<"record", { [key: string]: squiggleExpression }> =
|
// case "EvDistribution":
|
||||||
tag(
|
// return tag("distribution", new Distribution(x.value, environment));
|
||||||
"record",
|
// case "EvNumber":
|
||||||
_.mapValues(x.value, (x: unknown) =>
|
// return tag("number", x.value);
|
||||||
convertRawToTypescript(x as rescriptExport, environment)
|
// case "EvRecord":
|
||||||
)
|
// // genType doesn't support records, so we have to do the raw conversion ourself
|
||||||
);
|
// let result: tagged<"record", { [key: string]: squiggleExpression }> =
|
||||||
return result;
|
// tag(
|
||||||
case "EvString":
|
// "record",
|
||||||
return tag("string", x.value);
|
// _.mapValues(x.value, (x: unknown) =>
|
||||||
case "EvSymbol":
|
// convertRawToTypescript(x as rescriptExport, environment)
|
||||||
return tag("symbol", x.value);
|
// )
|
||||||
case "EvDate":
|
// );
|
||||||
return tag("date", x.value);
|
// return result;
|
||||||
case "EvTimeDuration":
|
// case "EvString":
|
||||||
return tag("timeDuration", x.value);
|
// return tag("string", x.value);
|
||||||
case "EvDeclaration":
|
// case "EvSymbol":
|
||||||
return tag("lambdaDeclaration", x.value);
|
// return tag("symbol", x.value);
|
||||||
case "EvTypeIdentifier":
|
// case "EvDate":
|
||||||
return tag("typeIdentifier", x.value);
|
// return tag("date", x.value);
|
||||||
case "EvType":
|
// case "EvTimeDuration":
|
||||||
let typeResult: tagged<
|
// return tag("timeDuration", x.value);
|
||||||
"type",
|
// case "EvDeclaration":
|
||||||
{ [key: string]: squiggleExpression }
|
// return tag("lambdaDeclaration", x.value);
|
||||||
> = tag(
|
// case "EvTypeIdentifier":
|
||||||
"type",
|
// return tag("typeIdentifier", x.value);
|
||||||
_.mapValues(x.value, (x: unknown) =>
|
// case "EvType":
|
||||||
convertRawToTypescript(x as rescriptExport, environment)
|
// let typeResult: tagged<
|
||||||
)
|
// "type",
|
||||||
);
|
// { [key: string]: squiggleExpression }
|
||||||
return typeResult;
|
// > = tag(
|
||||||
case "EvModule":
|
// "type",
|
||||||
let moduleResult: tagged<
|
// _.mapValues(x.value, (x: unknown) =>
|
||||||
"module",
|
// convertRawToTypescript(x as rescriptExport, environment)
|
||||||
{ [key: string]: squiggleExpression }
|
// )
|
||||||
> = tag(
|
// );
|
||||||
"module",
|
// return typeResult;
|
||||||
_.mapValues(x.value, (x: unknown) =>
|
// case "EvModule":
|
||||||
convertRawToTypescript(x as rescriptExport, environment)
|
// let moduleResult: tagged<
|
||||||
)
|
// "module",
|
||||||
);
|
// { [key: string]: squiggleExpression }
|
||||||
return moduleResult;
|
// > = tag(
|
||||||
}
|
// "module",
|
||||||
}
|
// _.mapValues(x.value, (x: unknown) =>
|
||||||
}
|
// convertRawToTypescript(x as rescriptExport, environment)
|
||||||
}
|
// )
|
||||||
|
// );
|
||||||
|
// return moduleResult;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
|
@ -0,0 +1,192 @@
|
||||||
|
open ForTS__Types
|
||||||
|
// If a module is built for TypeScript then it can only refer to ForTS__Types for other types and modules
|
||||||
|
// The exception is its implementation and private modules
|
||||||
|
module T = ReducerProject_T
|
||||||
|
module Private = ReducerProject.Private
|
||||||
|
|
||||||
|
/*
|
||||||
|
PUBLIC FUNCTIONS
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
Creates a new project to hold the sources, executables, bindings, and other data.
|
||||||
|
The new project runs the sources according to their topological sorting because of the includes and continues.
|
||||||
|
|
||||||
|
Any source can include or continue other sources. "Therefore, the project is a graph data structure."
|
||||||
|
The difference between including and continuing is that includes are stated inside the source code while continues are stated in the project.
|
||||||
|
|
||||||
|
To run a group of source codes and get results/bindings, the necessary methods are
|
||||||
|
- setSource
|
||||||
|
- setContinues
|
||||||
|
- parseIncludes
|
||||||
|
- run or runAll
|
||||||
|
- getExternalBindings
|
||||||
|
- getExternalResult
|
||||||
|
|
||||||
|
A project has a public field tag with a constant value "reducerProject"
|
||||||
|
project = {tag: "reducerProject"}
|
||||||
|
*/
|
||||||
|
let createProject = (): reducerProject => Private.createProject()->T.Private.castFromInternalProject
|
||||||
|
|
||||||
|
/*
|
||||||
|
Answer all the source ids of all the sources in the project.
|
||||||
|
*/
|
||||||
|
let getSourceIds = (project: reducerProject): array<string> =>
|
||||||
|
project->T.Private.castToInternalProject->Private.getSourceIds
|
||||||
|
|
||||||
|
/*
|
||||||
|
Sets the source for a given source Id.
|
||||||
|
*/
|
||||||
|
let setSource = (project: reducerProject, sourceId: string, value: string): unit =>
|
||||||
|
project->T.Private.castToInternalProject->Private.setSource(sourceId, value)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Gets the source for a given source id.
|
||||||
|
*/
|
||||||
|
let getSource = (project: reducerProject, sourceId: string): option<string> =>
|
||||||
|
project->T.Private.castToInternalProject->Private.getSource(sourceId)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Touches the source for a given source id. This and dependent, sources are set to be re-evaluated.
|
||||||
|
*/
|
||||||
|
let touchSource = (project: reducerProject, sourceId: string): unit =>
|
||||||
|
project->T.Private.castToInternalProject->Private.touchSource(sourceId)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Cleans the compilation artifacts for a given source ID. The results stay untouched, so compilation won't be run again.
|
||||||
|
|
||||||
|
Normally, you would never need the compilation artifacts again as the results with the same sources would never change. However, they are needed in case of any debugging reruns
|
||||||
|
*/
|
||||||
|
let clean = (project: reducerProject, sourceId: string): unit =>
|
||||||
|
project->T.Private.castToInternalProject->Private.clean(sourceId)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Cleans all the compilation artifacts in all of the project
|
||||||
|
*/
|
||||||
|
let cleanAll = (project: reducerProject): unit =>
|
||||||
|
project->T.Private.castToInternalProject->Private.cleanAll
|
||||||
|
|
||||||
|
/*
|
||||||
|
Cleans results. Compilation stays untouched to be able to re-run the source.
|
||||||
|
You would not do this if you were not trying to debug the source code.
|
||||||
|
*/
|
||||||
|
let cleanResults = (project: reducerProject, sourceId: string): unit =>
|
||||||
|
project->T.Private.castToInternalProject->Private.cleanResults(sourceId)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Cleans all results. Compilations remains untouched to rerun the source.
|
||||||
|
*/
|
||||||
|
let cleanAllResults = (project: reducerProject): unit =>
|
||||||
|
project->T.Private.castToInternalProject->Private.cleanAllResults
|
||||||
|
|
||||||
|
/*
|
||||||
|
To set the includes one first has to call "parseIncludes". The parsed includes or the parser error is returned.
|
||||||
|
*/
|
||||||
|
let getIncludes = (project: reducerProject, sourceId: string): result<
|
||||||
|
array<string>,
|
||||||
|
Reducer_ErrorValue.errorValue,
|
||||||
|
> => project->T.Private.castToInternalProject->Private.getIncludes(sourceId)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Answers the source codes after which this source code is continuing
|
||||||
|
*/
|
||||||
|
let getContinues = (project: reducerProject, sourceId: string): array<string> =>
|
||||||
|
project->T.Private.castToInternalProject->Private.getContinues(sourceId)
|
||||||
|
|
||||||
|
/*
|
||||||
|
"continues" acts like hidden includes in the source.
|
||||||
|
It is used to define a continuation that is not visible in the source code.
|
||||||
|
You can chain source codes on the web interface for example
|
||||||
|
*/
|
||||||
|
let setContinues = (project: reducerProject, sourceId: string, continues: array<string>): unit =>
|
||||||
|
project->T.Private.castToInternalProject->Private.setContinues(sourceId, continues)
|
||||||
|
|
||||||
|
/*
|
||||||
|
This source depends on the array of sources returned.
|
||||||
|
*/
|
||||||
|
let getDependencies = (project: reducerProject, sourceId: string): array<string> =>
|
||||||
|
project->T.Private.castToInternalProject->Private.getDependencies(sourceId)
|
||||||
|
|
||||||
|
/*
|
||||||
|
The sources returned are dependent on this
|
||||||
|
*/
|
||||||
|
let getDependents = (project: reducerProject, sourceId: string): array<string> =>
|
||||||
|
project->T.Private.castToInternalProject->Private.getDependents(sourceId)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get the run order for the sources in the project.
|
||||||
|
*/
|
||||||
|
let getRunOrder = (project: reducerProject): array<string> =>
|
||||||
|
project->T.Private.castToInternalProject->Private.getRunOrder
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get the run order to get the results of this specific source
|
||||||
|
*/
|
||||||
|
let getRunOrderFor = (project: reducerProject, sourceId: string) =>
|
||||||
|
project->T.Private.castToInternalProject->Private.getRunOrderFor(sourceId)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Parse includes so that you can load them before running.
|
||||||
|
Load includes by calling getIncludes which returns the includes that have been parsed.
|
||||||
|
It is your responsibility to load the includes before running.
|
||||||
|
*/module Topology = ReducerProject_Topology
|
||||||
|
|
||||||
|
let parseIncludes = (project: reducerProject, sourceId: string): unit =>
|
||||||
|
project->T.Private.castToInternalProject->Private.parseIncludes(sourceId)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Parse the source code if it is not done already.
|
||||||
|
Use getRawParse to get the parse tree.
|
||||||
|
You would need this function if you want to see the parse tree without running the source code.
|
||||||
|
*/
|
||||||
|
let rawParse = (project: reducerProject, sourceId: string): unit =>
|
||||||
|
project->T.Private.castToInternalProject->Private.rawParse(sourceId)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Runs a specific source code if it is not done already. The code is parsed if it is not already done. It runs the dependencies if it is not already done.
|
||||||
|
*/
|
||||||
|
let run = (project: reducerProject, sourceId: string): unit =>
|
||||||
|
project->T.Private.castToInternalProject->Private.run(sourceId)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Runs all of the sources in a project. Their results and bindings will be available
|
||||||
|
*/
|
||||||
|
let runAll = (project: reducerProject): unit =>
|
||||||
|
project->T.Private.castToInternalProject->Private.runAll
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get the bindings after running this source file or the project
|
||||||
|
*/
|
||||||
|
let getBindings = (project: reducerProject, sourceId: string): squiggleValue_Module =>
|
||||||
|
project->T.Private.castToInternalProject->Private.getBindings(sourceId)
|
||||||
|
|
||||||
|
/*
|
||||||
|
Get the result after running this source file or the project
|
||||||
|
*/
|
||||||
|
let getResult = (project: reducerProject, sourceId: string): option<
|
||||||
|
result_<squiggleValue, reducerErrorValue>,
|
||||||
|
> => project->T.Private.castToInternalProject->Private.getResult(sourceId)
|
||||||
|
|
||||||
|
/*
|
||||||
|
This is a convenience function to get the result of a single source without creating a project.
|
||||||
|
However, without a project, you cannot handle include directives.
|
||||||
|
The source has to be include free
|
||||||
|
*/
|
||||||
|
let evaluate = (sourceCode: string): ('r, 'b) => Private.evaluate(sourceCode)
|
||||||
|
|
||||||
|
let setEnvironment = (project: reducerProject, environment: environment): unit =>
|
||||||
|
project->T.Private.castToInternalProject->Private.setEnvironment(environment)
|
||||||
|
|
||||||
|
let foreignFunctionInterface = (
|
||||||
|
lambdaValue: squiggleValue_Lambda,
|
||||||
|
argArray: array<squiggleValue>,
|
||||||
|
environment: environment,
|
||||||
|
): result_<squiggleValue, reducerErrorValue> => {
|
||||||
|
let accessors = ReducerProject_ProjectAccessors_T.identityAccessorsWithEnvironment(environment)
|
||||||
|
Reducer_Expression_Lambda.foreignFunctionInterface(
|
||||||
|
lambdaValue,
|
||||||
|
argArray,
|
||||||
|
accessors,
|
||||||
|
Reducer_Expression.reduceExpressionInProject,
|
||||||
|
)
|
||||||
|
}
|
|
@ -1 +0,0 @@
|
||||||
open ForTS__Types
|
|
|
@ -1 +1,193 @@
|
||||||
open ForTS__Types
|
open ForTS__Types
|
||||||
|
|
||||||
|
// Return values as they are if they are JavaScript types.
|
||||||
|
|
||||||
|
@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag")
|
||||||
|
external svtArray_: int = "SvtArray"
|
||||||
|
|
||||||
|
@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag")
|
||||||
|
external svtArrayString_: int = "SvtArrayString"
|
||||||
|
|
||||||
|
@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag")
|
||||||
|
external svtBool_: int = "SvtBool"
|
||||||
|
|
||||||
|
@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag")
|
||||||
|
external svtCall_: int = "SvtCall"
|
||||||
|
|
||||||
|
@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag")
|
||||||
|
external svtDate_: int = "SvtDate"
|
||||||
|
|
||||||
|
@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag")
|
||||||
|
external svtDeclaration_: int = "SvtDeclaration"
|
||||||
|
|
||||||
|
@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag")
|
||||||
|
external svtDistribution_: int = "SvtDistribution"
|
||||||
|
|
||||||
|
@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag")
|
||||||
|
external svtLambda_: int = "SvtLambda"
|
||||||
|
|
||||||
|
@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag")
|
||||||
|
external svtModule_: int = "SvtModule"
|
||||||
|
|
||||||
|
@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag")
|
||||||
|
external svtNumber_: int = "SvtNumber"
|
||||||
|
|
||||||
|
@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag")
|
||||||
|
external svtRecord_: int = "SvtRecord"
|
||||||
|
|
||||||
|
@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag")
|
||||||
|
external svtString_: int = "SvtString"
|
||||||
|
|
||||||
|
@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag")
|
||||||
|
external svtSymbol_: int = "SvtSymbol"
|
||||||
|
|
||||||
|
@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag")
|
||||||
|
external svtTimeDuration_: int = "SvtTimeDuration"
|
||||||
|
|
||||||
|
@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag")
|
||||||
|
external svtType_: int = "SvtType"
|
||||||
|
|
||||||
|
@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag")
|
||||||
|
external svtTypeIdentifier_: int = "SvtUndefined"
|
||||||
|
|
||||||
|
@module("ForTS_SquiggleValue_tag") @scope("SquiggleValueTag")
|
||||||
|
external svtVoid_: int = "SvtVoid"
|
||||||
|
|
||||||
|
@genType
|
||||||
|
let getTag = (variant: squiggleValue) =>
|
||||||
|
switch variant {
|
||||||
|
| IEvArray(_) => svtArray_
|
||||||
|
| IEvArrayString(_) => svtArrayString_
|
||||||
|
| IEvBool(_) => svtBool_
|
||||||
|
| IEvCall(_) => svtCall_ //Impossible
|
||||||
|
| IEvDate(_) => svtDate_
|
||||||
|
| IEvDeclaration(_) => svtDeclaration_
|
||||||
|
| IEvDistribution(_) => svtDistribution_
|
||||||
|
| IEvLambda(_) => svtLambda_
|
||||||
|
| IEvBindings(_) => svtModule_ //Impossible
|
||||||
|
| IEvNumber(_) => svtNumber_
|
||||||
|
| IEvRecord(_) => svtRecord_
|
||||||
|
| IEvString(_) => svtString_
|
||||||
|
| IEvSymbol(_) => svtSymbol_
|
||||||
|
| IEvTimeDuration(_) => svtTimeDuration_
|
||||||
|
| IEvType(_) => svtType_
|
||||||
|
| IEvTypeIdentifier(_) => svtTypeIdentifier_
|
||||||
|
| IEvVoid => svtVoid_
|
||||||
|
}
|
||||||
|
|
||||||
|
@genType
|
||||||
|
let toString = (variant: squiggleValue) =>
|
||||||
|
ReducerInterface_InternalExpressionValue.toString(variant)
|
||||||
|
|
||||||
|
@genType
|
||||||
|
let getArray = (variant: squiggleValue): option<squiggleValue_Array> =>
|
||||||
|
//FIXME: Convert
|
||||||
|
switch variant {
|
||||||
|
| IEvArray(arrayLike) => arrayLike->Some
|
||||||
|
| _ => None
|
||||||
|
}
|
||||||
|
|
||||||
|
@genType
|
||||||
|
let getArrayString = (variant: squiggleValue): option<array<string>> =>
|
||||||
|
switch variant {
|
||||||
|
| IEvArrayString(value) => value->Some
|
||||||
|
| _ => None
|
||||||
|
}
|
||||||
|
|
||||||
|
@genType
|
||||||
|
let getBool = (variant: squiggleValue): option<bool> =>
|
||||||
|
switch variant {
|
||||||
|
| IEvBool(value) => value->Some
|
||||||
|
| _ => None
|
||||||
|
}
|
||||||
|
|
||||||
|
@genType
|
||||||
|
let getCall = (variant: squiggleValue): option<string> =>
|
||||||
|
switch variant {
|
||||||
|
| IEvCall(value) => value->Some
|
||||||
|
| _ => None
|
||||||
|
}
|
||||||
|
|
||||||
|
@genType
|
||||||
|
let getDate = (variant: squiggleValue): option<Js.Date.t> =>
|
||||||
|
switch variant {
|
||||||
|
| IEvDate(value) => value->Some
|
||||||
|
| _ => None
|
||||||
|
}
|
||||||
|
|
||||||
|
@genType
|
||||||
|
let getDeclaration = (variant: squiggleValue): option<squiggleValue_Declaration> =>
|
||||||
|
switch variant {
|
||||||
|
| IEvDeclaration(value) => value->Some
|
||||||
|
| _ => None
|
||||||
|
}
|
||||||
|
|
||||||
|
@genType
|
||||||
|
let getDistribution = (variant: squiggleValue): option<squiggleValue_Distribution> =>
|
||||||
|
switch variant {
|
||||||
|
| IEvDistribution(value) => value->Some
|
||||||
|
| _ => None
|
||||||
|
}
|
||||||
|
|
||||||
|
@genType
|
||||||
|
let getLambda = (variant: squiggleValue): option<squiggleValue_Lambda> =>
|
||||||
|
switch variant {
|
||||||
|
| IEvLambda(value) => value->Some
|
||||||
|
| _ => None
|
||||||
|
}
|
||||||
|
|
||||||
|
@genType
|
||||||
|
let getModule = (variant: squiggleValue): option<squiggleValue_Module> =>
|
||||||
|
switch variant {
|
||||||
|
| IEvBindings(value) => value->Some
|
||||||
|
| _ => None
|
||||||
|
}
|
||||||
|
|
||||||
|
@genType
|
||||||
|
let getNumber = (variant: squiggleValue): option<float> =>
|
||||||
|
switch variant {
|
||||||
|
| IEvNumber(value) => value->Some
|
||||||
|
| _ => None
|
||||||
|
}
|
||||||
|
|
||||||
|
@genType
|
||||||
|
let getRecord = (variant: squiggleValue): option<squiggleValue_Record> =>
|
||||||
|
switch variant {
|
||||||
|
| IEvRecord(value) => value->Some
|
||||||
|
| _ => None
|
||||||
|
}
|
||||||
|
|
||||||
|
@genType
|
||||||
|
let getString = (variant: squiggleValue): option<string> =>
|
||||||
|
switch variant {
|
||||||
|
| IEvString(value) => value->Some
|
||||||
|
| _ => None
|
||||||
|
}
|
||||||
|
|
||||||
|
@genType
|
||||||
|
let getSymbol = (variant: squiggleValue): option<string> =>
|
||||||
|
switch variant {
|
||||||
|
| IEvSymbol(value) => value->Some
|
||||||
|
| _ => None
|
||||||
|
}
|
||||||
|
|
||||||
|
@genType
|
||||||
|
let getTimeDuration = (variant: squiggleValue): option<float> =>
|
||||||
|
switch variant {
|
||||||
|
| IEvTimeDuration(value) => value->Some
|
||||||
|
| _ => None
|
||||||
|
}
|
||||||
|
|
||||||
|
@genType
|
||||||
|
let getType = (variant: squiggleValue): option<squiggleValue_Type> =>
|
||||||
|
switch variant {
|
||||||
|
| IEvType(value) => value->Some
|
||||||
|
| _ => None
|
||||||
|
}
|
||||||
|
|
||||||
|
@genType
|
||||||
|
let getTypeIdentifier = (variant: squiggleValue): option<string> =>
|
||||||
|
switch variant {
|
||||||
|
| IEvTypeIdentifier(value) => value->Some
|
||||||
|
| _ => None
|
||||||
|
}
|
||||||
|
|
|
@ -1 +1,5 @@
|
||||||
open ForTS__Types
|
open ForTS__Types
|
||||||
|
// Note: Internal representation will not be an array in the future.
|
||||||
|
// Thus we still to have a conversion
|
||||||
|
let getValues = (v: squiggleValue_Array): array<squiggleValue> =>
|
||||||
|
ReducerInterface_InternalExpressionValue.arrayToValueArray(v)
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
open ForTS__Types
|
|
|
@ -1 +0,0 @@
|
||||||
open ForTS__Types
|
|
|
@ -1 +0,0 @@
|
||||||
open ForTS__Types
|
|
|
@ -1 +0,0 @@
|
||||||
open ForTS__Types
|
|
|
@ -1 +0,0 @@
|
||||||
open ForTS__Types
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
open ForTS__Types
|
||||||
|
|
||||||
|
let getKeyValuePairs = (v: squiggleValue_Module): array<(string, squiggleValue)> =>
|
||||||
|
ReducerInterface_InternalExpressionValue.nameSpaceToKeyValueArray(v)
|
|
@ -1 +1,4 @@
|
||||||
open ForTS__Types
|
open ForTS__Types
|
||||||
|
|
||||||
|
let getKeyValuePairs = (value: squiggleValue_Record): array<(string, squiggleValue)> =>
|
||||||
|
ReducerInterface_InternalExpressionValue.recordToKeyValuePairs(value)
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
open ForTS__Types
|
|
|
@ -1 +1,4 @@
|
||||||
open ForTS__Types
|
open ForTS__Types
|
||||||
|
|
||||||
|
let getKeyValuePairs = (value: squiggleValue_Type): array<(string, squiggleValue)> =>
|
||||||
|
ReducerInterface_InternalExpressionValue.recordToKeyValuePairs(value)
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
open ForTS__Types
|
|
|
@ -5,7 +5,7 @@ enum SquiggleValueTag {
|
||||||
SvtCall,
|
SvtCall,
|
||||||
SvtDate,
|
SvtDate,
|
||||||
SvtDeclaration,
|
SvtDeclaration,
|
||||||
SvtDistribution
|
SvtDistribution,
|
||||||
SvtLambda,
|
SvtLambda,
|
||||||
SvtModule,
|
SvtModule,
|
||||||
SvtNumber,
|
SvtNumber,
|
||||||
|
|
|
@ -5,16 +5,21 @@ So we rename it right away not cause a compatibility problem
|
||||||
*/
|
*/
|
||||||
@genType.opaque type result_<'a, 'e> = result<'a, 'e>
|
@genType.opaque type result_<'a, 'e> = result<'a, 'e>
|
||||||
|
|
||||||
@genType.opaque type squiggleValue
|
@genType.opaque type squiggleValue = ReducerInterface_InternalExpressionValue.t
|
||||||
@genType.opaque type squiggleValue_Array
|
@genType.opaque type squiggleValue_Array = ReducerInterface_InternalExpressionValue.squiggleArray
|
||||||
@genType.opaque type squiggleValue_ArrayString
|
@genType.opaque
|
||||||
@genType.opaque type squiggleValue_Date
|
type squiggleValue_Declaration = ReducerInterface_InternalExpressionValue.lambdaDeclaration
|
||||||
@genType.opaque type squiggleValue_Declaration
|
@genType.opaque type squiggleValue_Module = ReducerInterface_InternalExpressionValue.nameSpace
|
||||||
@genType.opaque type squiggleValue_Distribution
|
@genType.opaque type squiggleValue_Lambda = ReducerInterface_InternalExpressionValue.lambdaValue
|
||||||
@genType.opaque type squiggleValue_Lambda
|
@genType.opaque type squiggleValue_Record = ReducerInterface_InternalExpressionValue.map
|
||||||
@genType.opaque type squiggleValue_Record
|
@genType.opaque type squiggleValue_Type = ReducerInterface_InternalExpressionValue.map
|
||||||
@genType.opaque type squiggleValue_TimeDuration
|
@genType.opaque type reducerErrorValue = Reducer_ErrorValue.errorValue
|
||||||
@genType.opaque type squiggleValue_Type
|
|
||||||
@genType.opaque type squiggleValue_Void
|
|
||||||
@genType.opaque type reducer_errorValue
|
|
||||||
|
|
||||||
|
@genType.opaque type reducerProject = ReducerProject_T.t
|
||||||
|
|
||||||
|
// From now on one should introduce any new types as opaque types
|
||||||
|
// Already existing open types we cannot dive in now
|
||||||
|
@genType type environment = GenericDist.env
|
||||||
|
@genType type squiggleValue_Distribution = DistributionTypes.genericDist
|
||||||
|
|
||||||
|
//TODO: index.ts should use types from here or vice versa
|
||||||
|
|
|
@ -16,18 +16,18 @@ type rec externalExpressionValue =
|
||||||
| EvArrayString(array<string>)
|
| EvArrayString(array<string>)
|
||||||
| EvBool(bool)
|
| EvBool(bool)
|
||||||
| EvCall(string) // External function call
|
| EvCall(string) // External function call
|
||||||
|
| EvDate(Js.Date.t)
|
||||||
|
| EvDeclaration(lambdaDeclaration)
|
||||||
| EvDistribution(DistributionTypes.genericDist)
|
| EvDistribution(DistributionTypes.genericDist)
|
||||||
| EvLambda(lambdaValue)
|
| EvLambda(lambdaValue)
|
||||||
|
| EvModule(record)
|
||||||
| EvNumber(float)
|
| EvNumber(float)
|
||||||
| EvRecord(record)
|
| EvRecord(record)
|
||||||
| EvString(string)
|
| EvString(string)
|
||||||
| EvSymbol(string)
|
| EvSymbol(string)
|
||||||
| EvDate(Js.Date.t)
|
|
||||||
| EvTimeDuration(float)
|
| EvTimeDuration(float)
|
||||||
| EvDeclaration(lambdaDeclaration)
|
|
||||||
| EvTypeIdentifier(string)
|
|
||||||
| EvModule(record)
|
|
||||||
| EvType(record)
|
| EvType(record)
|
||||||
|
| EvTypeIdentifier(string)
|
||||||
| EvVoid
|
| EvVoid
|
||||||
and record = Js.Dict.t<externalExpressionValue>
|
and record = Js.Dict.t<externalExpressionValue>
|
||||||
and lambdaValue = {
|
and lambdaValue = {
|
||||||
|
|
|
@ -23,6 +23,7 @@ type rec t =
|
||||||
| IEvType(map)
|
| IEvType(map)
|
||||||
| IEvTypeIdentifier(string)
|
| IEvTypeIdentifier(string)
|
||||||
| IEvVoid
|
| IEvVoid
|
||||||
|
and squiggleArray = array<t>
|
||||||
and map = Belt.Map.String.t<t>
|
and map = Belt.Map.String.t<t>
|
||||||
and nameSpace = NameSpace(Belt.Map.String.t<t>)
|
and nameSpace = NameSpace(Belt.Map.String.t<t>)
|
||||||
and lambdaValue = {
|
and lambdaValue = {
|
||||||
|
@ -32,6 +33,7 @@ and lambdaValue = {
|
||||||
}
|
}
|
||||||
and lambdaDeclaration = Declaration.declaration<lambdaValue>
|
and lambdaDeclaration = Declaration.declaration<lambdaValue>
|
||||||
|
|
||||||
|
type squiggleMap = map
|
||||||
type internalExpressionValue = t
|
type internalExpressionValue = t
|
||||||
|
|
||||||
type functionCall = (string, array<t>)
|
type functionCall = (string, array<t>)
|
||||||
|
@ -312,3 +314,12 @@ and nameSpaceFromTypeScriptBindings = (
|
||||||
r: ReducerInterface_ExternalExpressionValue.externalBindings,
|
r: ReducerInterface_ExternalExpressionValue.externalBindings,
|
||||||
): nameSpace =>
|
): nameSpace =>
|
||||||
r->Js.Dict.entries->Belt.Map.String.fromArray->Belt.Map.String.map(e => toInternal(e))->NameSpace
|
r->Js.Dict.entries->Belt.Map.String.fromArray->Belt.Map.String.map(e => toInternal(e))->NameSpace
|
||||||
|
|
||||||
|
let nameSpaceToKeyValueArray = (nameSpace: nameSpace): array<(string, t)> => {
|
||||||
|
let NameSpace(container) = nameSpace
|
||||||
|
container->Belt.Map.String.toArray
|
||||||
|
}
|
||||||
|
|
||||||
|
let arrayToValueArray = (arr: array<t>): array<t> => arr
|
||||||
|
|
||||||
|
let recordToKeyValuePairs = (record: map): array<(string, t)> => record->Belt.Map.String.toArray
|
||||||
|
|
|
@ -3,14 +3,12 @@
|
||||||
module Bindings = Reducer_Bindings
|
module Bindings = Reducer_Bindings
|
||||||
module Continuation = ReducerInterface_Value_Continuation
|
module Continuation = ReducerInterface_Value_Continuation
|
||||||
module ErrorValue = Reducer_ErrorValue
|
module ErrorValue = Reducer_ErrorValue
|
||||||
module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue
|
|
||||||
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
|
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
|
||||||
module ProjectAccessorsT = ReducerProject_ProjectAccessors_T
|
module ProjectAccessorsT = ReducerProject_ProjectAccessors_T
|
||||||
module ProjectItem = ReducerProject_ProjectItem
|
module ProjectItem = ReducerProject_ProjectItem
|
||||||
module T = ReducerProject_T
|
module T = ReducerProject_T
|
||||||
module Topology = ReducerProject_Topology
|
module Topology = ReducerProject_Topology
|
||||||
|
|
||||||
type reducerProject = T.t
|
|
||||||
type t = T.t
|
type t = T.t
|
||||||
|
|
||||||
module Private = {
|
module Private = {
|
||||||
|
@ -106,9 +104,6 @@ module Private = {
|
||||||
Belt.Map.String.set(project["items"], sourceId, newItem)->T.Private.setFieldItems(project, _)
|
Belt.Map.String.set(project["items"], sourceId, newItem)->T.Private.setFieldItems(project, _)
|
||||||
}
|
}
|
||||||
|
|
||||||
let getExternalResult = (project: t, sourceId: string): ProjectItem.T.externalResultType =>
|
|
||||||
project->getItem(sourceId)->ProjectItem.getExternalResult
|
|
||||||
|
|
||||||
let parseIncludes = (project: t, sourceId: string): unit => {
|
let parseIncludes = (project: t, sourceId: string): unit => {
|
||||||
let newItem = project->getItem(sourceId)->ProjectItem.parseIncludes
|
let newItem = project->getItem(sourceId)->ProjectItem.parseIncludes
|
||||||
Belt.Map.String.set(project["items"], sourceId, newItem)->T.Private.setFieldItems(project, _)
|
Belt.Map.String.set(project["items"], sourceId, newItem)->T.Private.setFieldItems(project, _)
|
||||||
|
@ -127,14 +122,11 @@ module Private = {
|
||||||
let setEnvironment = (project: t, value: InternalExpressionValue.environment): unit =>
|
let setEnvironment = (project: t, value: InternalExpressionValue.environment): unit =>
|
||||||
T.Private.setFieldEnvironment(project, value)
|
T.Private.setFieldEnvironment(project, value)
|
||||||
|
|
||||||
let getExternalBindings = (
|
let getBindings = (project: t, sourceId: string): ProjectItem.T.bindingsArgumentType => {
|
||||||
project: t,
|
|
||||||
sourceId: string,
|
|
||||||
): ProjectItem.T.externalBindingsArgumentType => {
|
|
||||||
let those = project->getContinuation(sourceId)
|
let those = project->getContinuation(sourceId)
|
||||||
let these = project->getStdLib
|
let these = project->getStdLib
|
||||||
let ofUser = Continuation.minus(those, these)
|
let ofUser = Continuation.minus(those, these)
|
||||||
ofUser->InternalExpressionValue.nameSpaceToTypeScriptBindings
|
ofUser
|
||||||
}
|
}
|
||||||
|
|
||||||
let buildProjectAccessors = (project: t): ProjectAccessorsT.t => {
|
let buildProjectAccessors = (project: t): ProjectAccessorsT.t => {
|
||||||
|
@ -208,202 +200,3 @@ module Private = {
|
||||||
(getResult(project, "main")->Belt.Option.getWithDefault(IEvVoid->Ok), ofUser)
|
(getResult(project, "main")->Belt.Option.getWithDefault(IEvVoid->Ok), ofUser)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
PUBLIC FUNCTIONS
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
Creates a new project to hold the sources, executables, bindings, and other data.
|
|
||||||
The new project runs the sources according to their topological sorting because of the includes and continues.
|
|
||||||
|
|
||||||
Any source can include or continue other sources. "Therefore, the project is a graph data structure."
|
|
||||||
The difference between including and continuing is that includes are stated inside the source code while continues are stated in the project.
|
|
||||||
|
|
||||||
To run a group of source codes and get results/bindings, the necessary methods are
|
|
||||||
- setSource
|
|
||||||
- setContinues
|
|
||||||
- parseIncludes
|
|
||||||
- run or runAll
|
|
||||||
- getExternalBindings
|
|
||||||
- getExternalResult
|
|
||||||
|
|
||||||
A project has a public field tag with a constant value "reducerProject"
|
|
||||||
project = {tag: "reducerProject"}
|
|
||||||
*/
|
|
||||||
let createProject = (): reducerProject => Private.createProject()->T.Private.castFromInternalProject
|
|
||||||
|
|
||||||
/*
|
|
||||||
Answer all the source ids of all the sources in the project.
|
|
||||||
*/
|
|
||||||
let getSourceIds = (project: reducerProject): array<string> =>
|
|
||||||
project->T.Private.castToInternalProject->Private.getSourceIds
|
|
||||||
|
|
||||||
/*
|
|
||||||
Sets the source for a given source Id.
|
|
||||||
*/
|
|
||||||
let setSource = (project: reducerProject, sourceId: string, value: string): unit =>
|
|
||||||
project->T.Private.castToInternalProject->Private.setSource(sourceId, value)
|
|
||||||
|
|
||||||
/*
|
|
||||||
Gets the source for a given source id.
|
|
||||||
*/
|
|
||||||
let getSource = (project: reducerProject, sourceId: string): option<string> =>
|
|
||||||
project->T.Private.castToInternalProject->Private.getSource(sourceId)
|
|
||||||
|
|
||||||
/*
|
|
||||||
Touches the source for a given source id. This and dependent, sources are set to be re-evaluated.
|
|
||||||
*/
|
|
||||||
let touchSource = (project: reducerProject, sourceId: string): unit =>
|
|
||||||
project->T.Private.castToInternalProject->Private.touchSource(sourceId)
|
|
||||||
|
|
||||||
/*
|
|
||||||
Cleans the compilation artifacts for a given source ID. The results stay untouched, so compilation won't be run again.
|
|
||||||
|
|
||||||
Normally, you would never need the compilation artifacts again as the results with the same sources would never change. However, they are needed in case of any debugging reruns
|
|
||||||
*/
|
|
||||||
let clean = (project: reducerProject, sourceId: string): unit =>
|
|
||||||
project->T.Private.castToInternalProject->Private.clean(sourceId)
|
|
||||||
|
|
||||||
/*
|
|
||||||
Cleans all the compilation artifacts in all of the project
|
|
||||||
*/
|
|
||||||
let cleanAll = (project: reducerProject): unit =>
|
|
||||||
project->T.Private.castToInternalProject->Private.cleanAll
|
|
||||||
|
|
||||||
/*
|
|
||||||
Cleans results. Compilation stays untouched to be able to re-run the source.
|
|
||||||
You would not do this if you were not trying to debug the source code.
|
|
||||||
*/
|
|
||||||
let cleanResults = (project: reducerProject, sourceId: string): unit =>
|
|
||||||
project->T.Private.castToInternalProject->Private.cleanResults(sourceId)
|
|
||||||
|
|
||||||
/*
|
|
||||||
Cleans all results. Compilations remains untouched to rerun the source.
|
|
||||||
*/
|
|
||||||
let cleanAllResults = (project: reducerProject): unit =>
|
|
||||||
project->T.Private.castToInternalProject->Private.cleanAllResults
|
|
||||||
|
|
||||||
/*
|
|
||||||
To set the includes one first has to call "parseIncludes". The parsed includes or the parser error is returned.
|
|
||||||
*/
|
|
||||||
let getIncludes = (project: reducerProject, sourceId: string): result<
|
|
||||||
array<string>,
|
|
||||||
Reducer_ErrorValue.errorValue,
|
|
||||||
> => project->T.Private.castToInternalProject->Private.getIncludes(sourceId)
|
|
||||||
|
|
||||||
/*
|
|
||||||
Answers the source codes after which this source code is continuing
|
|
||||||
*/
|
|
||||||
let getContinues = (project: reducerProject, sourceId: string): array<string> =>
|
|
||||||
project->T.Private.castToInternalProject->Private.getContinues(sourceId)
|
|
||||||
|
|
||||||
/*
|
|
||||||
"continues" acts like hidden includes in the source.
|
|
||||||
It is used to define a continuation that is not visible in the source code.
|
|
||||||
You can chain source codes on the web interface for example
|
|
||||||
*/
|
|
||||||
let setContinues = (project: reducerProject, sourceId: string, continues: array<string>): unit =>
|
|
||||||
project->T.Private.castToInternalProject->Private.setContinues(sourceId, continues)
|
|
||||||
|
|
||||||
/*
|
|
||||||
This source depends on the array of sources returned.
|
|
||||||
*/
|
|
||||||
let getDependencies = (project: reducerProject, sourceId: string): array<string> =>
|
|
||||||
project->T.Private.castToInternalProject->Private.getDependencies(sourceId)
|
|
||||||
|
|
||||||
/*
|
|
||||||
The sources returned are dependent on this
|
|
||||||
*/
|
|
||||||
let getDependents = (project: reducerProject, sourceId: string): array<string> =>
|
|
||||||
project->T.Private.castToInternalProject->Private.getDependents(sourceId)
|
|
||||||
|
|
||||||
/*
|
|
||||||
Get the run order for the sources in the project.
|
|
||||||
*/
|
|
||||||
let getRunOrder = (project: reducerProject): array<string> =>
|
|
||||||
project->T.Private.castToInternalProject->Private.getRunOrder
|
|
||||||
|
|
||||||
/*
|
|
||||||
Get the run order to get the results of this specific source
|
|
||||||
*/
|
|
||||||
let getRunOrderFor = (project: reducerProject, sourceId: string) =>
|
|
||||||
project->T.Private.castToInternalProject->Private.getRunOrderFor(sourceId)
|
|
||||||
|
|
||||||
/*
|
|
||||||
Parse includes so that you can load them before running.
|
|
||||||
Load includes by calling getIncludes which returns the includes that have been parsed.
|
|
||||||
It is your responsibility to load the includes before running.
|
|
||||||
*/
|
|
||||||
let parseIncludes = (project: reducerProject, sourceId: string): unit =>
|
|
||||||
project->T.Private.castToInternalProject->Private.parseIncludes(sourceId)
|
|
||||||
|
|
||||||
/*
|
|
||||||
Parse the source code if it is not done already.
|
|
||||||
Use getRawParse to get the parse tree.
|
|
||||||
You would need this function if you want to see the parse tree without running the source code.
|
|
||||||
*/
|
|
||||||
let rawParse = (project: reducerProject, sourceId: string): unit =>
|
|
||||||
project->T.Private.castToInternalProject->Private.rawParse(sourceId)
|
|
||||||
|
|
||||||
/*
|
|
||||||
Runs a specific source code if it is not done already. The code is parsed if it is not already done. It runs the dependencies if it is not already done.
|
|
||||||
*/
|
|
||||||
let run = (project: reducerProject, sourceId: string): unit =>
|
|
||||||
project->T.Private.castToInternalProject->Private.run(sourceId)
|
|
||||||
|
|
||||||
/*
|
|
||||||
Runs all of the sources in a project. Their results and bindings will be available
|
|
||||||
*/
|
|
||||||
let runAll = (project: reducerProject): unit =>
|
|
||||||
project->T.Private.castToInternalProject->Private.runAll
|
|
||||||
|
|
||||||
/*
|
|
||||||
Get the bindings after running this source file or the project
|
|
||||||
*/
|
|
||||||
let getExternalBindings = (
|
|
||||||
project: reducerProject,
|
|
||||||
sourceId: string,
|
|
||||||
): ExternalExpressionValue.record =>
|
|
||||||
project->T.Private.castToInternalProject->Private.getExternalBindings(sourceId)
|
|
||||||
|
|
||||||
/*
|
|
||||||
Get the result after running this source file or the project
|
|
||||||
*/
|
|
||||||
let getExternalResult = (project: reducerProject, sourceId: string): option<
|
|
||||||
result<ExternalExpressionValue.externalExpressionValue, Reducer_ErrorValue.errorValue>,
|
|
||||||
> => project->T.Private.castToInternalProject->Private.getExternalResult(sourceId)
|
|
||||||
|
|
||||||
/*
|
|
||||||
This is a convenience function to get the result of a single source without creating a project.
|
|
||||||
However, without a project, you cannot handle include directives.
|
|
||||||
The source has to be include free
|
|
||||||
*/
|
|
||||||
let evaluate = (sourceCode: string): ('r, 'b) => {
|
|
||||||
let (result, continuation) = Private.evaluate(sourceCode)
|
|
||||||
(
|
|
||||||
result->Belt.Result.map(InternalExpressionValue.toExternal),
|
|
||||||
continuation->InternalExpressionValue.nameSpaceToTypeScriptBindings,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
let setEnvironment = (
|
|
||||||
project: reducerProject,
|
|
||||||
environment: ExternalExpressionValue.environment,
|
|
||||||
): unit => project->T.Private.castToInternalProject->Private.setEnvironment(environment)
|
|
||||||
|
|
||||||
let foreignFunctionInterface = (
|
|
||||||
lambdaValue: ExternalExpressionValue.lambdaValue,
|
|
||||||
argArray: array<ExternalExpressionValue.externalExpressionValue>,
|
|
||||||
environment: ExternalExpressionValue.environment,
|
|
||||||
) => {
|
|
||||||
let internallambdaValue = InternalExpressionValue.lambdaValueToInternal(lambdaValue)
|
|
||||||
let internalArgArray = argArray->Js.Array2.map(InternalExpressionValue.toInternal)
|
|
||||||
let accessors = ProjectAccessorsT.identityAccessorsWithEnvironment(environment)
|
|
||||||
Reducer_Expression_Lambda.foreignFunctionInterface(
|
|
||||||
internallambdaValue,
|
|
||||||
internalArgArray,
|
|
||||||
accessors,
|
|
||||||
Reducer_Expression.reduceExpressionInProject,
|
|
||||||
)->Belt.Result.map(InternalExpressionValue.toExternal)
|
|
||||||
}
|
|
||||||
|
|
|
@ -20,19 +20,13 @@ let emptyItem = T.ProjectItem({
|
||||||
continues: [],
|
continues: [],
|
||||||
includes: []->Ok,
|
includes: []->Ok,
|
||||||
})
|
})
|
||||||
// source -> rawParse -> includes -> expression -> continuation -> externalBindings -> result -> externalResult
|
// source -> rawParse -> includes -> expression -> continuation -> result
|
||||||
|
|
||||||
let getSource = (T.ProjectItem(r)): T.sourceType => r.source
|
let getSource = (T.ProjectItem(r)): T.sourceType => r.source
|
||||||
let getRawParse = (T.ProjectItem(r)): T.rawParseType => r.rawParse
|
let getRawParse = (T.ProjectItem(r)): T.rawParseType => r.rawParse
|
||||||
let getExpression = (T.ProjectItem(r)): T.expressionType => r.expression
|
let getExpression = (T.ProjectItem(r)): T.expressionType => r.expression
|
||||||
let getContinuation = (T.ProjectItem(r)): T.continuationArgumentType => r.continuation
|
let getContinuation = (T.ProjectItem(r)): T.continuationArgumentType => r.continuation
|
||||||
let toExternalBindings = continuation =>
|
|
||||||
continuation->InternalExpressionValue.nameSpaceToTypeScriptBindings
|
|
||||||
let getResult = (T.ProjectItem(r)): T.resultType => r.result
|
let getResult = (T.ProjectItem(r)): T.resultType => r.result
|
||||||
let getExternalResult = (T.ProjectItem(r)): T.externalResultType =>
|
|
||||||
r.result->Belt.Option.map(opt =>
|
|
||||||
opt->Belt.Result.map(value => value->InternalExpressionValue.toExternal)
|
|
||||||
)
|
|
||||||
|
|
||||||
let getContinues = (T.ProjectItem(r)): T.continuesType => r.continues
|
let getContinues = (T.ProjectItem(r)): T.continuesType => r.continues
|
||||||
let getIncludes = (T.ProjectItem(r)): T.includesType => r.includes
|
let getIncludes = (T.ProjectItem(r)): T.includesType => r.includes
|
||||||
|
|
|
@ -14,12 +14,10 @@ type continuation = InternalExpressionValue.nameSpace
|
||||||
type continuationArgumentType = InternalExpressionValue.nameSpace
|
type continuationArgumentType = InternalExpressionValue.nameSpace
|
||||||
type continuationType = option<continuationArgumentType>
|
type continuationType = option<continuationArgumentType>
|
||||||
type continuationResultType = option<result<continuationArgumentType, errorValue>>
|
type continuationResultType = option<result<continuationArgumentType, errorValue>>
|
||||||
type externalBindingsArgumentType = ExternalExpressionValue.record
|
type bindingsArgumentType = InternalExpressionValue.nameSpace
|
||||||
type externalBindingsType = option<externalBindingsArgumentType>
|
type bindingsType = option<bindingsArgumentType>
|
||||||
type resultArgumentType = result<InternalExpressionValue.t, errorValue>
|
type resultArgumentType = result<InternalExpressionValue.t, errorValue>
|
||||||
type resultType = option<resultArgumentType>
|
type resultType = option<resultArgumentType>
|
||||||
type externalResultArgumentType = result<ExternalExpressionValue.t, errorValue>
|
|
||||||
type externalResultType = option<externalResultArgumentType>
|
|
||||||
type continuesArgumentType = array<string>
|
type continuesArgumentType = array<string>
|
||||||
type continuesType = array<string>
|
type continuesType = array<string>
|
||||||
type includesArgumentType = string
|
type includesArgumentType = string
|
||||||
|
|
Loading…
Reference in New Issue
Block a user