Compare commits
9 Commits
develop
...
project-se
Author | SHA1 | Date | |
---|---|---|---|
|
e8aa541fc9 | ||
|
fb5fd8edf8 | ||
|
534b7a45d3 | ||
|
17cc2a42cc | ||
|
de73a98735 | ||
|
5076427d03 | ||
|
7829efab25 | ||
|
565694ea00 | ||
|
f489d0bcfe |
|
@ -199,3 +199,42 @@ describe("project with independent sources", () => {
|
|||
expect(Project.getRunOrderFor(project, "second")) == ["second"]
|
||||
})
|
||||
})
|
||||
|
||||
describe("project serialization", () => {
|
||||
let project = Project.createProject()
|
||||
Project.setSource(project, "first", "x = 1")
|
||||
Project.setSource(project, "second", "y = 1")
|
||||
Project.setSource(project, "main", "x + y")
|
||||
Project.setContinues(project, "main", ["first", "second"])
|
||||
let expectedJson: Project.reducerProjectJson = {
|
||||
environment: {
|
||||
sampleCount: 10000,
|
||||
xyPointLength: 1000,
|
||||
},
|
||||
items: [
|
||||
{
|
||||
continues: [],
|
||||
id: "first",
|
||||
source: "x = 1",
|
||||
},
|
||||
{
|
||||
continues: ["first", "second"],
|
||||
id: "main",
|
||||
source: "x + y",
|
||||
},
|
||||
{
|
||||
continues: [],
|
||||
id: "second",
|
||||
source: "y = 1",
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
test("serializes correctly", () => {
|
||||
expect(Project.toJson(project)) == expectedJson
|
||||
})
|
||||
|
||||
test("serializes reflexive", () => {
|
||||
expect(Project.toJson(Project.fromJson(Project.toJson(project)))) == Project.toJson(project)
|
||||
})
|
||||
})
|
||||
|
|
|
@ -22,20 +22,28 @@ export const run = (src, { output, sampleCount } = {}) => {
|
|||
});
|
||||
}
|
||||
project.setSource("main", src);
|
||||
const time = measure(() => project.run("main"));
|
||||
|
||||
const bindings = project.getBindings("main");
|
||||
const result = project.getResult("main");
|
||||
|
||||
if (output) {
|
||||
console.log("Result:", result.tag, result.value.toString());
|
||||
console.log("Bindings:", bindings.toString());
|
||||
}
|
||||
|
||||
console.log(
|
||||
"Time:",
|
||||
String(time),
|
||||
result.tag === "Error" ? red(result.tag) : green(result.tag),
|
||||
result.tag === "Error" ? result.value.toStringWithFrameStack() : ""
|
||||
);
|
||||
runProject(project, output);
|
||||
};
|
||||
|
||||
export const runProject = (project, { output }) => {
|
||||
const time = measure(() => project.runAll());
|
||||
console.log("Time: ", time);
|
||||
|
||||
const ids = project.getSourceIds();
|
||||
|
||||
ids.forEach((id) => {
|
||||
const result = project.getResult(id);
|
||||
const bindings = project.getBindings(id);
|
||||
|
||||
console.log(id + ":");
|
||||
if (output) {
|
||||
console.log("Result:", result.tag, result.value.toString());
|
||||
console.log("Bindings:", bindings.toString());
|
||||
}
|
||||
|
||||
console.log(
|
||||
result.tag === "Error" ? red(result.tag) : green(result.tag),
|
||||
result.tag === "Error" ? result.value.toString() : ""
|
||||
);
|
||||
});
|
||||
};
|
||||
|
|
28
packages/squiggle-lang/scripts/run-project.mjs
Executable file
28
packages/squiggle-lang/scripts/run-project.mjs
Executable file
|
@ -0,0 +1,28 @@
|
|||
#!/usr/bin/env node
|
||||
import fs from "fs";
|
||||
|
||||
import { Command } from "commander";
|
||||
|
||||
import { SqProject } from "@quri/squiggle-lang";
|
||||
import { runProject } from "./lib.mjs";
|
||||
|
||||
const program = new Command();
|
||||
|
||||
program.option("-o, --output");
|
||||
program.arguments("<string>");
|
||||
|
||||
const options = program.parse(process.argv);
|
||||
|
||||
const sampleCount = process.env.SAMPLE_COUNT;
|
||||
console.log(sampleCount);
|
||||
|
||||
const src = fs.readFileSync(program.args[0], "utf-8");
|
||||
if (!src) {
|
||||
throw new Error("Expected src");
|
||||
}
|
||||
|
||||
const projectJson = JSON.parse(src);
|
||||
|
||||
const project = SqProject.fromJson(projectJson);
|
||||
|
||||
runProject(project, options);
|
|
@ -119,4 +119,12 @@ export class SqProject {
|
|||
getEnvironment(): environment {
|
||||
return RSProject.getEnvironment(this._value);
|
||||
}
|
||||
|
||||
toJSON(): RSProject.reducerProjectJson {
|
||||
return RSProject.toJson(this._value);
|
||||
}
|
||||
|
||||
static fromJson(projectJson: RSProject.reducerProjectJson): SqProject {
|
||||
return new SqProject(RSProject.fromJson(projectJson));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
@genType type reducerProject = ReducerProject_T.project //re-export
|
||||
@genType type reducerProjectJson = ReducerProject_T.projectJson //re-export
|
||||
|
||||
type error = SqError.t //use
|
||||
type errorMessage = SqError.Message.t //use
|
||||
|
@ -215,3 +216,30 @@ let setEnvironment = (project: reducerProject, environment: environment): unit =
|
|||
|
||||
@genType
|
||||
let getEnvironment = (project: reducerProject): environment => project->Private.getEnvironment
|
||||
|
||||
@genType
|
||||
let toJson = (project: reducerProject): reducerProjectJson => project->Private.toJson
|
||||
|
||||
@genType
|
||||
let fromJson = (project: reducerProjectJson): reducerProject => project->Private.fromJson
|
||||
|
||||
/*
|
||||
Foreign function interface is intentionally demolished.
|
||||
There is another way to do that: Umur.
|
||||
Also there is no more conversion from javascript to squiggle values currently.
|
||||
If the conversion to the new project is too difficult, I can add it later.
|
||||
*/
|
||||
|
||||
// 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,3 +1,4 @@
|
|||
@genType
|
||||
type environment = GenericDist.env
|
||||
|
||||
@genType.opaque
|
||||
|
|
|
@ -150,6 +150,28 @@ let setEnvironment = (project: t, value: Reducer_T.environment): unit => {
|
|||
project.environment = value
|
||||
}
|
||||
|
||||
let toJson = (project: t): T.projectJson => {
|
||||
items: Belt.Array.map(Belt.MutableMap.String.toArray(project.items), ((id, projectItem)) => {
|
||||
let projectItem: T.projectItemJson = {
|
||||
id: id,
|
||||
source: ProjectItem.getSource(projectItem),
|
||||
continues: ProjectItem.getContinues(projectItem),
|
||||
}
|
||||
projectItem
|
||||
}),
|
||||
environment: getEnvironment(project),
|
||||
}
|
||||
|
||||
let fromJson = (json: T.projectJson): t => {
|
||||
let project = createProject()
|
||||
setEnvironment(project, json.environment)
|
||||
Belt.Array.forEach(json.items, item => {
|
||||
setSource(project, item.id, item.source)
|
||||
setContinues(project, item.id, item.continues)
|
||||
})
|
||||
project
|
||||
}
|
||||
|
||||
let getBindings = (project: t, sourceId: string): Reducer_T.namespace => {
|
||||
project->getItem(sourceId)->ProjectItem.getContinuation
|
||||
}
|
||||
|
|
|
@ -7,8 +7,22 @@ type project = {
|
|||
mutable environment: Reducer_T.environment,
|
||||
mutable previousRunOrder: array<string>,
|
||||
}
|
||||
|
||||
type t = project
|
||||
|
||||
@genType
|
||||
type projectItemJson = {
|
||||
id: string,
|
||||
source: string,
|
||||
continues: array<string>,
|
||||
}
|
||||
|
||||
@genType
|
||||
type projectJson = {
|
||||
items: array<projectItemJson>,
|
||||
environment: Reducer_T.environment,
|
||||
}
|
||||
|
||||
// these functions are used in ReducerProject_Topology, so they are defined here to avoid circular dependencies
|
||||
let getSourceIds = (project: t): array<string> => Belt.MutableMap.String.keysToArray(project.items)
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user