project
This commit is contained in:
parent
fdc7f06f08
commit
f0ba68f64a
|
@ -1,6 +1,6 @@
|
|||
@@warning("-44")
|
||||
module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue
|
||||
module Project = ReducerProject
|
||||
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
|
||||
module Project = ForTS_ReducerProject
|
||||
module Bindings = Reducer_Bindings
|
||||
|
||||
open Jest
|
||||
|
@ -11,14 +11,14 @@ open Expect.Operators
|
|||
|
||||
let runFetchResult = (project, sourceId) => {
|
||||
Project.run(project, sourceId)
|
||||
Project.getExternalResult(project, sourceId)->ExternalExpressionValue.toStringOptionResult
|
||||
Project.getResult(project, sourceId)->InternalExpressionValue.toStringOptionResult
|
||||
}
|
||||
|
||||
let runFetchBindings = (project, sourceId) => {
|
||||
Project.run(project, sourceId)
|
||||
Project.getExternalBindings(project, sourceId)
|
||||
->ExternalExpressionValue.EvModule
|
||||
->ExternalExpressionValue.toString
|
||||
Project.getBindings(project, sourceId)
|
||||
->InternalExpressionValue.IEvBindings
|
||||
->InternalExpressionValue.toString
|
||||
}
|
||||
|
||||
test("setting continuation", () => {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
@@warning("-44")
|
||||
module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue
|
||||
module Project = ReducerProject
|
||||
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
|
||||
module Project = ForTS_ReducerProject
|
||||
module Bindings = Reducer_Bindings
|
||||
|
||||
open Jest
|
||||
|
@ -45,13 +45,13 @@ Case "Running a single source".
|
|||
Note that getResult returns None if the source has not been run.
|
||||
Getting None means you have forgotten to run the source.
|
||||
*/
|
||||
let result = project->Project.getExternalResult("main")
|
||||
let bindings = project->Project.getExternalBindings("main")
|
||||
let result = project->Project.getResult("main")
|
||||
let bindings = project->Project.getBindings("main")
|
||||
|
||||
/* Let's display the result and bindings */
|
||||
(
|
||||
result->ExternalExpressionValue.toStringOptionResult,
|
||||
bindings->ExternalExpressionValue.EvModule->ExternalExpressionValue.toString,
|
||||
result->InternalExpressionValue.toStringOptionResult,
|
||||
bindings->InternalExpressionValue.IEvBindings->InternalExpressionValue.toString,
|
||||
)->expect == ("Ok(3)", "@{}")
|
||||
/* You've got 3 with empty bindings. */
|
||||
})
|
||||
|
@ -60,12 +60,12 @@ Case "Running a single source".
|
|||
let project = Project.createProject()
|
||||
Project.setSource(project, "main", "1 + 2")
|
||||
Project.runAll(project)
|
||||
let result = Project.getExternalResult(project, "main")
|
||||
let bindings = Project.getExternalBindings(project, "main")
|
||||
let result = Project.getResult(project, "main")
|
||||
let bindings = Project.getBindings(project, "main")
|
||||
/* Now you have external bindings and external result. */
|
||||
(
|
||||
result->ExternalExpressionValue.toStringOptionResult,
|
||||
bindings->ExternalExpressionValue.EvModule->ExternalExpressionValue.toString,
|
||||
result->InternalExpressionValue.toStringOptionResult,
|
||||
bindings->InternalExpressionValue.IEvBindings->InternalExpressionValue.toString,
|
||||
)->expect == ("Ok(3)", "@{}")
|
||||
})
|
||||
|
||||
|
@ -74,13 +74,13 @@ Case "Running a single source".
|
|||
let project = Project.createProject()
|
||||
|
||||
/* 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.runAll(project)
|
||||
let result = Project.getExternalResult(project, "main")
|
||||
let _bindings = Project.getExternalBindings(project, "main")
|
||||
result->ExternalExpressionValue.toStringOptionResult->expect == "Ok(3)"
|
||||
let result = Project.getResult(project, "main")
|
||||
let _bindings = Project.getBindings(project, "main")
|
||||
result->InternalExpressionValue.toStringOptionResult->expect == "Ok(3)"
|
||||
})
|
||||
|
||||
test("shortcut", () => {
|
||||
|
@ -88,8 +88,8 @@ Case "Running a single source".
|
|||
/* Examples above was to prepare you for the multi source tutorial. */
|
||||
let (result, bindings) = Project.evaluate("1+2")
|
||||
(
|
||||
result->ExternalExpressionValue.toStringResult,
|
||||
bindings->ExternalExpressionValue.EvModule->ExternalExpressionValue.toString,
|
||||
result->InternalExpressionValue.toStringResult,
|
||||
bindings->InternalExpressionValue.IEvBindings->InternalExpressionValue.toString,
|
||||
)->expect == ("Ok(3)", "@{}")
|
||||
})
|
||||
})
|
||||
|
|
|
@ -1,19 +1,14 @@
|
|||
import * as _ from "lodash";
|
||||
import type {
|
||||
environment,
|
||||
expressionValue,
|
||||
externalBindings,
|
||||
errorValue,
|
||||
} from "../rescript/TypescriptInterface.gen";
|
||||
import {
|
||||
defaultEnvironment,
|
||||
evaluatePartialUsingExternalBindings,
|
||||
evaluateUsingOptions,
|
||||
foreignFunctionInterface,
|
||||
} from "../rescript/TypescriptInterface.gen";
|
||||
export {
|
||||
makeSampleSetDist,
|
||||
errorValueToString,
|
||||
distributionErrorToString,
|
||||
} from "../rescript/TypescriptInterface.gen";
|
||||
export type {
|
||||
|
@ -23,12 +18,7 @@ export type {
|
|||
} from "../rescript/TypescriptInterface.gen";
|
||||
export type { errorValue, externalBindings as bindings, jsImports };
|
||||
import {
|
||||
jsValueToBinding,
|
||||
jsValueToExpressionValue,
|
||||
jsValue,
|
||||
rescriptExport,
|
||||
squiggleExpression,
|
||||
convertRawToTypescript,
|
||||
lambdaValue,
|
||||
} from "./rescript_interop";
|
||||
import { result, resultMap, tag, tagged } from "./types";
|
||||
|
@ -44,162 +34,167 @@ export let defaultSamplingInputs: environment = {
|
|||
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(
|
||||
squiggleString: string,
|
||||
bindings?: externalBindings,
|
||||
environment?: environment,
|
||||
imports?: jsImports
|
||||
): result<externalBindings, errorValue> {
|
||||
let b = bindings ? bindings : defaultBindings;
|
||||
let i = imports ? imports : defaultImports;
|
||||
let e = environment ? environment : defaultEnvironment;
|
||||
/*
|
||||
All those functions below are invalid since the introduction of ReducerProject
|
||||
*/
|
||||
// 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));
|
||||
// }
|
||||
|
||||
return evaluatePartialUsingExternalBindings(
|
||||
squiggleString,
|
||||
mergeImportsWithBindings(b, i),
|
||||
e
|
||||
);
|
||||
}
|
||||
// // Run Partial. A partial is a block of code that doesn't return a value
|
||||
// export function runPartial(
|
||||
// squiggleString: string,
|
||||
// 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(
|
||||
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));
|
||||
}
|
||||
// return evaluatePartialUsingExternalBindings(
|
||||
// squiggleString,
|
||||
// mergeImportsWithBindings(b, i),
|
||||
// e
|
||||
// );
|
||||
// }
|
||||
|
||||
function mergeImportsWithBindings(
|
||||
bindings: externalBindings,
|
||||
imports: jsImports
|
||||
): externalBindings {
|
||||
let transformedImports = Object.fromEntries(
|
||||
Object.entries(imports).map(([key, value]) => [
|
||||
"$" + key,
|
||||
jsValueToBinding(value),
|
||||
])
|
||||
);
|
||||
return _.merge(bindings, transformedImports);
|
||||
}
|
||||
// jsValueToExpressionValue is invalid
|
||||
// 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));
|
||||
// }
|
||||
|
||||
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 = {};
|
||||
export let defaultBindings: externalBindings = {};
|
||||
// type jsImports = { [key: string]: jsValue };
|
||||
|
||||
export function mergeBindings(
|
||||
allBindings: externalBindings[]
|
||||
): externalBindings {
|
||||
return allBindings.reduce((acc, x) => ({ ...acc, ...x }));
|
||||
}
|
||||
// export let defaultImports: jsImports = {};
|
||||
// export let defaultBindings: externalBindings = {};
|
||||
|
||||
function createTsExport(
|
||||
x: expressionValue,
|
||||
environment: environment
|
||||
): squiggleExpression {
|
||||
switch (x) {
|
||||
case "EvVoid":
|
||||
return tag("void", "");
|
||||
default: {
|
||||
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 =>
|
||||
convertRawToTypescript(
|
||||
arrayItem as unknown as rescriptExport,
|
||||
environment
|
||||
)
|
||||
)
|
||||
);
|
||||
case "EvArrayString":
|
||||
return tag("arraystring", x.value);
|
||||
case "EvBool":
|
||||
return tag("boolean", x.value);
|
||||
case "EvCall":
|
||||
return tag("call", x.value);
|
||||
case "EvLambda":
|
||||
return tag("lambda", x.value);
|
||||
case "EvDistribution":
|
||||
return tag("distribution", new Distribution(x.value, environment));
|
||||
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, environment)
|
||||
)
|
||||
);
|
||||
return result;
|
||||
case "EvString":
|
||||
return tag("string", x.value);
|
||||
case "EvSymbol":
|
||||
return tag("symbol", x.value);
|
||||
case "EvDate":
|
||||
return tag("date", x.value);
|
||||
case "EvTimeDuration":
|
||||
return tag("timeDuration", x.value);
|
||||
case "EvDeclaration":
|
||||
return tag("lambdaDeclaration", x.value);
|
||||
case "EvTypeIdentifier":
|
||||
return tag("typeIdentifier", x.value);
|
||||
case "EvType":
|
||||
let typeResult: tagged<
|
||||
"type",
|
||||
{ [key: string]: squiggleExpression }
|
||||
> = tag(
|
||||
"type",
|
||||
_.mapValues(x.value, (x: unknown) =>
|
||||
convertRawToTypescript(x as rescriptExport, environment)
|
||||
)
|
||||
);
|
||||
return typeResult;
|
||||
case "EvModule":
|
||||
let moduleResult: tagged<
|
||||
"module",
|
||||
{ [key: string]: squiggleExpression }
|
||||
> = tag(
|
||||
"module",
|
||||
_.mapValues(x.value, (x: unknown) =>
|
||||
convertRawToTypescript(x as rescriptExport, environment)
|
||||
)
|
||||
);
|
||||
return moduleResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// export function mergeBindings(
|
||||
// allBindings: externalBindings[]
|
||||
// ): externalBindings {
|
||||
// return allBindings.reduce((acc, x) => ({ ...acc, ...x }));
|
||||
// }
|
||||
|
||||
// function createTsExport(
|
||||
// x: expressionValue,
|
||||
// environment: environment
|
||||
// ): squiggleExpression {
|
||||
// switch (x) {
|
||||
// case "EvVoid":
|
||||
// return tag("void", "");
|
||||
// default: {
|
||||
// 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 =>
|
||||
// convertRawToTypescript(
|
||||
// arrayItem as unknown as rescriptExport,
|
||||
// environment
|
||||
// )
|
||||
// )
|
||||
// );
|
||||
// case "EvArrayString":
|
||||
// return tag("arraystring", x.value);
|
||||
// case "EvBool":
|
||||
// return tag("boolean", x.value);
|
||||
// case "EvCall":
|
||||
// return tag("call", x.value);
|
||||
// case "EvLambda":
|
||||
// return tag("lambda", x.value);
|
||||
// case "EvDistribution":
|
||||
// return tag("distribution", new Distribution(x.value, environment));
|
||||
// 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, environment)
|
||||
// )
|
||||
// );
|
||||
// return result;
|
||||
// case "EvString":
|
||||
// return tag("string", x.value);
|
||||
// case "EvSymbol":
|
||||
// return tag("symbol", x.value);
|
||||
// case "EvDate":
|
||||
// return tag("date", x.value);
|
||||
// case "EvTimeDuration":
|
||||
// return tag("timeDuration", x.value);
|
||||
// case "EvDeclaration":
|
||||
// return tag("lambdaDeclaration", x.value);
|
||||
// case "EvTypeIdentifier":
|
||||
// return tag("typeIdentifier", x.value);
|
||||
// case "EvType":
|
||||
// let typeResult: tagged<
|
||||
// "type",
|
||||
// { [key: string]: squiggleExpression }
|
||||
// > = tag(
|
||||
// "type",
|
||||
// _.mapValues(x.value, (x: unknown) =>
|
||||
// convertRawToTypescript(x as rescriptExport, environment)
|
||||
// )
|
||||
// );
|
||||
// return typeResult;
|
||||
// case "EvModule":
|
||||
// let moduleResult: tagged<
|
||||
// "module",
|
||||
// { [key: string]: squiggleExpression }
|
||||
// > = 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,
|
||||
SvtDate,
|
||||
SvtDeclaration,
|
||||
SvtDistribution
|
||||
SvtDistribution,
|
||||
SvtLambda,
|
||||
SvtModule,
|
||||
SvtNumber,
|
||||
|
|
|
@ -1,20 +1,25 @@
|
|||
/*
|
||||
/*
|
||||
The reason this is not ExpressionValue is that ExpressionValue is becoming a parametric type
|
||||
to allow expressions for different domains.
|
||||
So we rename it right away not cause a compatibility problem
|
||||
*/
|
||||
@genType.opaque type result_<'a, 'e> = result<'a, 'e>
|
||||
|
||||
@genType.opaque type squiggleValue
|
||||
@genType.opaque type squiggleValue_Array
|
||||
@genType.opaque type squiggleValue_ArrayString
|
||||
@genType.opaque type squiggleValue_Date
|
||||
@genType.opaque type squiggleValue_Declaration
|
||||
@genType.opaque type squiggleValue_Distribution
|
||||
@genType.opaque type squiggleValue_Lambda
|
||||
@genType.opaque type squiggleValue_Record
|
||||
@genType.opaque type squiggleValue_TimeDuration
|
||||
@genType.opaque type squiggleValue_Type
|
||||
@genType.opaque type squiggleValue_Void
|
||||
@genType.opaque type reducer_errorValue
|
||||
@genType.opaque type squiggleValue = ReducerInterface_InternalExpressionValue.t
|
||||
@genType.opaque type squiggleValue_Array = ReducerInterface_InternalExpressionValue.squiggleArray
|
||||
@genType.opaque
|
||||
type squiggleValue_Declaration = ReducerInterface_InternalExpressionValue.lambdaDeclaration
|
||||
@genType.opaque type squiggleValue_Module = ReducerInterface_InternalExpressionValue.nameSpace
|
||||
@genType.opaque type squiggleValue_Lambda = ReducerInterface_InternalExpressionValue.lambdaValue
|
||||
@genType.opaque type squiggleValue_Record = ReducerInterface_InternalExpressionValue.map
|
||||
@genType.opaque type squiggleValue_Type = ReducerInterface_InternalExpressionValue.map
|
||||
@genType.opaque type reducerErrorValue = Reducer_ErrorValue.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>)
|
||||
| EvBool(bool)
|
||||
| EvCall(string) // External function call
|
||||
| EvDate(Js.Date.t)
|
||||
| EvDeclaration(lambdaDeclaration)
|
||||
| EvDistribution(DistributionTypes.genericDist)
|
||||
| EvLambda(lambdaValue)
|
||||
| EvModule(record)
|
||||
| EvNumber(float)
|
||||
| EvRecord(record)
|
||||
| EvString(string)
|
||||
| EvSymbol(string)
|
||||
| EvDate(Js.Date.t)
|
||||
| EvTimeDuration(float)
|
||||
| EvDeclaration(lambdaDeclaration)
|
||||
| EvTypeIdentifier(string)
|
||||
| EvModule(record)
|
||||
| EvType(record)
|
||||
| EvTypeIdentifier(string)
|
||||
| EvVoid
|
||||
and record = Js.Dict.t<externalExpressionValue>
|
||||
and lambdaValue = {
|
||||
|
|
|
@ -23,6 +23,7 @@ type rec t =
|
|||
| IEvType(map)
|
||||
| IEvTypeIdentifier(string)
|
||||
| IEvVoid
|
||||
and squiggleArray = array<t>
|
||||
and map = Belt.Map.String.t<t>
|
||||
and nameSpace = NameSpace(Belt.Map.String.t<t>)
|
||||
and lambdaValue = {
|
||||
|
@ -32,6 +33,7 @@ and lambdaValue = {
|
|||
}
|
||||
and lambdaDeclaration = Declaration.declaration<lambdaValue>
|
||||
|
||||
type squiggleMap = map
|
||||
type internalExpressionValue = t
|
||||
|
||||
type functionCall = (string, array<t>)
|
||||
|
@ -312,3 +314,12 @@ and nameSpaceFromTypeScriptBindings = (
|
|||
r: ReducerInterface_ExternalExpressionValue.externalBindings,
|
||||
): 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 Continuation = ReducerInterface_Value_Continuation
|
||||
module ErrorValue = Reducer_ErrorValue
|
||||
module ExternalExpressionValue = ReducerInterface_ExternalExpressionValue
|
||||
module InternalExpressionValue = ReducerInterface_InternalExpressionValue
|
||||
module ProjectAccessorsT = ReducerProject_ProjectAccessors_T
|
||||
module ProjectItem = ReducerProject_ProjectItem
|
||||
module T = ReducerProject_T
|
||||
module Topology = ReducerProject_Topology
|
||||
|
||||
type reducerProject = T.t
|
||||
type t = T.t
|
||||
|
||||
module Private = {
|
||||
|
@ -106,9 +104,6 @@ module Private = {
|
|||
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 newItem = project->getItem(sourceId)->ProjectItem.parseIncludes
|
||||
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 =>
|
||||
T.Private.setFieldEnvironment(project, value)
|
||||
|
||||
let getExternalBindings = (
|
||||
project: t,
|
||||
sourceId: string,
|
||||
): ProjectItem.T.externalBindingsArgumentType => {
|
||||
let getBindings = (project: t, sourceId: string): ProjectItem.T.bindingsArgumentType => {
|
||||
let those = project->getContinuation(sourceId)
|
||||
let these = project->getStdLib
|
||||
let ofUser = Continuation.minus(those, these)
|
||||
ofUser->InternalExpressionValue.nameSpaceToTypeScriptBindings
|
||||
ofUser
|
||||
}
|
||||
|
||||
let buildProjectAccessors = (project: t): ProjectAccessorsT.t => {
|
||||
|
@ -208,202 +200,3 @@ module Private = {
|
|||
(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: [],
|
||||
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 getRawParse = (T.ProjectItem(r)): T.rawParseType => r.rawParse
|
||||
let getExpression = (T.ProjectItem(r)): T.expressionType => r.expression
|
||||
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 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 getIncludes = (T.ProjectItem(r)): T.includesType => r.includes
|
||||
|
|
|
@ -14,12 +14,10 @@ type continuation = InternalExpressionValue.nameSpace
|
|||
type continuationArgumentType = InternalExpressionValue.nameSpace
|
||||
type continuationType = option<continuationArgumentType>
|
||||
type continuationResultType = option<result<continuationArgumentType, errorValue>>
|
||||
type externalBindingsArgumentType = ExternalExpressionValue.record
|
||||
type externalBindingsType = option<externalBindingsArgumentType>
|
||||
type bindingsArgumentType = InternalExpressionValue.nameSpace
|
||||
type bindingsType = option<bindingsArgumentType>
|
||||
type resultArgumentType = result<InternalExpressionValue.t, errorValue>
|
||||
type resultType = option<resultArgumentType>
|
||||
type externalResultArgumentType = result<ExternalExpressionValue.t, errorValue>
|
||||
type externalResultType = option<externalResultArgumentType>
|
||||
type continuesArgumentType = array<string>
|
||||
type continuesType = array<string>
|
||||
type includesArgumentType = string
|
||||
|
|
Loading…
Reference in New Issue
Block a user