Skip to content

Commit 9c8a035

Browse files
committed
wip module return stuff
1 parent 310da6b commit 9c8a035

3 files changed

Lines changed: 217 additions & 10 deletions

File tree

src/common/interop/bridge.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/** @satisfies {PyretModule} */
2+
({
3+
requires: [{ "import-type": "builtin", name: "error-display" }],
4+
provides: {},
5+
nativeRequires: [],
6+
theModule: function (runtime, _namespace, _uri, errDisplay) {
7+
"use strict";
8+
9+
/**
10+
* @param {PyretRuntime} foreignRt
11+
* @param {string} modName
12+
*/
13+
function getMod(foreignRt, modName) {
14+
const mod = foreignRt.modules[modName];
15+
if (mod == null) {
16+
runtime.ffi.throwMessageException(`Cannot find foreign module ${modName}`);
17+
}
18+
return foreignRt.getField(mod, "provide-plus-types");
19+
}
20+
21+
/**
22+
* @param {PyretRuntime} foreignRt
23+
* @param {any} srcloc
24+
*/
25+
function translateSrcloc(foreignRt, srcloc) {
26+
const gf = foreignRt.getField;
27+
const srclocM = getMod(foreignRt, "builtin://srcloc");
28+
29+
return foreignRt.ffi.cases(gf(gf(srclocM, "values"), "is-Srcloc"), "Srcloc", srcloc, {
30+
31+
});
32+
33+
console.dir(srclocM, {depth: 3})
34+
runtime.ffi.throwMessageException("TODO");
35+
36+
}
37+
38+
/**
39+
* @param {PyretRuntime} foreignRt
40+
* @param {any} errDisp
41+
*/
42+
function translateErrorDisplay(foreignRt, errDisp) {
43+
const errDispM = getMod(foreignRt, "builtins://error-display");
44+
45+
console.dir(errDispM);
46+
runtime.ffi.throwMessageException("TODO");
47+
}
48+
49+
50+
return runtime.makeJSModuleReturn({
51+
translateSrcloc,
52+
translateErrorDisplay,
53+
});
54+
},
55+
})
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/** @satisfies {PyretModule} */
2+
/*
3+
* This deals with the module return value from the Pyret runtime.
4+
*
5+
* Due to the representation of pyret values, we cannot pass values resulting from
6+
* the repl to the host without first serializing them. The `load-lib` module is
7+
* intended to do this, but doesn't provide very rich error displaying, nor give
8+
* complete raw information about the checks that were run.
9+
*
10+
* All errors will be rendered
11+
*/
12+
({
13+
requires: [
14+
{"import-type": "dependency", protocol: "js-file", args: ["./bridge"]},
15+
],
16+
provides: {
17+
values: {
18+
"extract-check-results": ["arrow", ["Any"], ["List", "Any"]],
19+
},
20+
},
21+
nativeRequires: ["pyret-base/js/exn-stack-parser"],
22+
theModule: function (runtime, _namespace, _uri, bridge, stackLib) {
23+
"use strict";
24+
const EXIT_SUCCESS = 0;
25+
const EXIT_ERROR = 1;
26+
const EXIT_ERROR_RENDERING_ERROR = 2;
27+
const EXIT_ERROR_DISPLAYING_ERROR = 3;
28+
const EXIT_ERROR_CHECK_FAILURES = 4;
29+
const EXIT_ERROR_JS = 5;
30+
const EXIT_ERROR_UNKNOWN = 6;
31+
32+
/** @typedef {{val: { runtime: PyretRuntime; result: any; program: any; realm: any; } }} ModuleReturn */
33+
34+
/**
35+
* @param {ModuleReturn} mr
36+
* @param {string} field
37+
*/
38+
function checkSuccess(mr, field) {
39+
if (!mr.val) {
40+
console.error(mr);
41+
runtime.ffi.throwMessageException(`Tried to get ${field} of non-successful module compilation.`);
42+
}
43+
if (!mr.val.runtime.isSuccessResult(mr.val.result)) {
44+
console.error(mr.val.result);
45+
console.error(mr.val.result.exn);
46+
runtime.ffi.throwMessageException(`Tried to get ${field} of non-successful module execution.`);
47+
}
48+
}
49+
50+
/**
51+
* @param {ModuleReturn} mr
52+
*/
53+
function getModuleResultChecks(mr) {
54+
checkSuccess(mr, "checks");
55+
const checks = mr.val.runtime.getField(mr.val.result.result, "checks");
56+
if (mr.val.runtime.ffi.isList(checks)) {
57+
return checks;
58+
} else {
59+
return mr.val.runtime.ffi.makeList([]);
60+
}
61+
}
62+
63+
/**
64+
* @param {ModuleReturn} mr
65+
*/
66+
function extractCheckResults(mr) {
67+
runtime.checkArity(1, arguments, "extract-check-results", false);
68+
runtime.checkOpaque(/** @type {any} */ (mr));
69+
return runtime.pauseStack(function (restarter) {
70+
const execRt = mr.val.runtime;
71+
const gf = execRt.getField;
72+
const checkerMod = execRt.modules["builtin://checker"];
73+
const checker = gf(checkerMod, "provide-plus-types");
74+
const checkerVals = gf(checker, "values");
75+
const renderCheckResults = gf(checkerVals, "render-check-results-stack");
76+
const realm = runtime.getField(mr.val.realm, "realm").val;
77+
const getStack = execRt.makeFunction((/** @type {any} */ err) => {
78+
const pyretStack = stackLib.convertExceptionToPyretStackTrace(err.val, realm);
79+
const locArray = pyretStack.map(execRt.makeSrcloc);
80+
const locList = execRt.ffi.makeList(locArray);
81+
return locList;
82+
}, "get-stack");
83+
84+
const blockResults = getModuleResultChecks(mr);
85+
86+
// const results = [];
87+
// for (const blockResult of execRt.ffi.toArray(blockResults)) {
88+
// const name = gf(blockResult, "name");
89+
// const loc = gf(blockResult, "loc");
90+
// const kwCheck = gf(blockResult, "keyword-check");
91+
// const testRes = gf(blockResult, "test-results");
92+
// const maybeError = gf(blockResult, "maybe-err");
93+
//
94+
// const bridged = {
95+
// name: name,
96+
// loc: bridge.translateSrcloc(execRt, loc),
97+
//
98+
// }
99+
//
100+
// results.push(bridged)
101+
//
102+
//
103+
// console.log("Block result:");
104+
// console.dir(blockResult)
105+
// console.dir(execRt.toRepr(blockResult));
106+
// }
107+
108+
109+
110+
111+
// edBridge.translateErrorDisplay(execRt, ...)
112+
113+
execRt.runThunk(
114+
function() {return renderCheckResults.app(blockResults, getStack, "json")},
115+
function (/** @type {any} */ renderedCheckResults) {
116+
runtime.console.dir(renderedCheckResults)
117+
const resumeWith = {
118+
message: "Unknown error!",
119+
"exit-code": EXIT_ERROR_UNKNOWN,
120+
};
121+
122+
if (execRt.isSuccessResult(renderedCheckResults)) {
123+
resumeWith.message = execRt.unwrap(
124+
execRt.getField(renderedCheckResults.result, "message")
125+
);
126+
const errs = execRt.getField(renderedCheckResults.result, "errored");
127+
const failed = execRt.getField(renderedCheckResults.result, "failed");
128+
if (errs !== 0 || failed !== 0) {
129+
resumeWith["exit-code"] = EXIT_ERROR_CHECK_FAILURES;
130+
} else {
131+
resumeWith["exit-code"] = EXIT_SUCCESS;
132+
}
133+
} else if (execRt.isFailureResult(renderedCheckResults)) {
134+
console.error(renderedCheckResults.exn);
135+
resumeWith.message = "There was an exception while formatting the check results";
136+
resumeWith["exit-code"] = EXIT_ERROR_RENDERING_ERROR;
137+
}
138+
139+
restarter.resume(
140+
runtime.makeObject({
141+
message: runtime.makeString(resumeWith.message),
142+
"exit-code": runtime.makeNumber(resumeWith["exit-code"]),
143+
})
144+
);
145+
}
146+
);
147+
});
148+
}
149+
return runtime.makeModuleReturn({
150+
"extract-check-results": runtime.makeFunction(extractCheckResults, "extract-check-results"),
151+
}, {});
152+
},
153+
})

src/common/repl-runner.arr

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import require-util as RU
3131
import file("./visitors.arr") as V
3232
import file("./ast.arr") as CA
3333
include js-file("./runtime")
34+
import js-file("./interop/module-return") as MR
3435
include either
3536

3637
include js-file("../tools/debugging")
@@ -92,7 +93,7 @@ fun remove-checks(stx :: A.Program, check-name :: Option<String>) -> A.Program:
9293
stx.visit(V.make-check-filter(pred))
9394
end
9495

95-
#---------------------------run-with-alternate-impl---------------------------#
96+
#--------------------------[run-with-alternate-impl]--------------------------#
9697

9798
data RunAltImplErr:
9899
| ai-cannot-parse-student(err :: CA.ParsePathErr)
@@ -137,7 +138,7 @@ fun replace-fun(
137138
end
138139
end
139140

140-
#--------------------------run-with-alternate-checks--------------------------#
141+
#-------------------------[run-with-alternate-checks]-------------------------#
141142

142143
data RunAltChecksErr:
143144
| ac-cannot-parse-student(err :: CA.ParsePathErr)
@@ -184,7 +185,7 @@ fun add-to-program(stx :: A.Program, expr :: A.Expr):
184185
stx.visit(V.make-program-appender(expr))
185186
end
186187

187-
#----------------------------------run-checks----------------------------------#
188+
#---------------------------------[run-checks]---------------------------------#
188189

189190
data RunChecksErr:
190191
| compile-error(x :: Any, program :: A.Program) # TODO: whats in here?
@@ -218,13 +219,8 @@ fun run(program :: A.Program) -> Either<RunChecksErr, RunChecksResult> block:
218219
| right(val) =>
219220
if LL.is-success-result(val):
220221
val
221-
# ^ identity-print-raw
222-
^ lam(x) block:
223-
# print-module-result(x)
224-
x
225-
end
226-
^ LL.render-check-results(_)
227-
# ^ identity-spy
222+
^ MR.extract-check-results
223+
^ identity-spy
228224
^ _.message
229225
# ^ identity-print-json
230226
^ J.read-json
@@ -238,3 +234,6 @@ fun run(program :: A.Program) -> Either<RunChecksErr, RunChecksResult> block:
238234
end
239235
# ^ identity-spy
240236
end
237+
238+
239+
#----------------------------------run-checks----------------------------------#

0 commit comments

Comments
 (0)