|
|
@ -154,3 +154,95 @@ export async function loadMicroPython(options) { |
|
|
|
} |
|
|
|
|
|
|
|
globalThis.loadMicroPython = loadMicroPython; |
|
|
|
|
|
|
|
async function runCLI() { |
|
|
|
const fs = await import("fs"); |
|
|
|
let heap_size = 128 * 1024; |
|
|
|
let contents = ""; |
|
|
|
let repl = true; |
|
|
|
|
|
|
|
for (let i = 2; i < process.argv.length; i++) { |
|
|
|
if (process.argv[i] === "-X" && i < process.argv.length - 1) { |
|
|
|
if (process.argv[i + 1].includes("heapsize=")) { |
|
|
|
heap_size = parseInt(process.argv[i + 1].split("heapsize=")[1]); |
|
|
|
const suffix = process.argv[i + 1].substr(-1).toLowerCase(); |
|
|
|
if (suffix === "k") { |
|
|
|
heap_size *= 1024; |
|
|
|
} else if (suffix === "m") { |
|
|
|
heap_size *= 1024 * 1024; |
|
|
|
} |
|
|
|
++i; |
|
|
|
} |
|
|
|
} else { |
|
|
|
contents += fs.readFileSync(process.argv[i], "utf8"); |
|
|
|
repl = false; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (process.stdin.isTTY === false) { |
|
|
|
contents = fs.readFileSync(0, "utf8"); |
|
|
|
repl = false; |
|
|
|
} |
|
|
|
|
|
|
|
const mp = await loadMicroPython({ |
|
|
|
heapsize: heap_size, |
|
|
|
stdout: (data) => process.stdout.write(data), |
|
|
|
linebuffer: false, |
|
|
|
}); |
|
|
|
|
|
|
|
if (repl) { |
|
|
|
mp_js_init_repl(); |
|
|
|
process.stdin.setRawMode(true); |
|
|
|
process.stdin.on("data", (data) => { |
|
|
|
for (let i = 0; i < data.length; i++) { |
|
|
|
mp_js_process_char(data[i]).then((result) => { |
|
|
|
if (result) { |
|
|
|
process.exit(); |
|
|
|
} |
|
|
|
}); |
|
|
|
} |
|
|
|
}); |
|
|
|
} else { |
|
|
|
try { |
|
|
|
mp.runPython(contents); |
|
|
|
} catch (error) { |
|
|
|
if (error.name === "PythonError") { |
|
|
|
if (error.type === "SystemExit") { |
|
|
|
// SystemExit, this is a valid exception to successfully end a script.
|
|
|
|
} else { |
|
|
|
// An unhandled Python exception, print in out.
|
|
|
|
console.error(error.message); |
|
|
|
} |
|
|
|
} else { |
|
|
|
// A non-Python exception. Re-raise it.
|
|
|
|
throw error; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
// Check if Node is running (equivalent to ENVIRONMENT_IS_NODE).
|
|
|
|
if ( |
|
|
|
typeof process === "object" && |
|
|
|
typeof process.versions === "object" && |
|
|
|
typeof process.versions.node === "string" |
|
|
|
) { |
|
|
|
// Check if this module is ron from the command line.
|
|
|
|
//
|
|
|
|
// See https://stackoverflow.com/questions/6398196/detect-if-called-through-require-or-directly-by-command-line/66309132#66309132
|
|
|
|
//
|
|
|
|
// Note:
|
|
|
|
// - `resolve()` is used to handle symlinks
|
|
|
|
// - `includes()` is used to handle cases where the file extension was omitted when passed to node
|
|
|
|
|
|
|
|
const path = await import("path"); |
|
|
|
const url = await import("url"); |
|
|
|
|
|
|
|
const pathToThisFile = path.resolve(url.fileURLToPath(import.meta.url)); |
|
|
|
const pathPassedToNode = path.resolve(process.argv[1]); |
|
|
|
const isThisFileBeingRunViaCLI = pathToThisFile.includes(pathPassedToNode); |
|
|
|
|
|
|
|
if (isThisFileBeingRunViaCLI) { |
|
|
|
runCLI(); |
|
|
|
} |
|
|
|
} |
|
|
|