Skip to content

Commit a01baf0

Browse files
committed
feat: execute API
1 parent 8317caf commit a01baf0

File tree

2 files changed

+74
-13
lines changed

2 files changed

+74
-13
lines changed

src/cli.js

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
const fs = require("fs");
22
const version = require("./version");
3-
const { compile } = require("./parser");
3+
const { compile, evalCompiled } = require("./parser");
44
const { render, unrender } = require("./render");
55
const path = require("path");
66
const commander = require("commander");
@@ -38,6 +38,7 @@ program
3838
"--roman [method]",
3939
'Romanize identifiers. The method can be "pinyin", "baxter" or "unicode"'
4040
)
41+
.option("--outputHanzi", "Convert output to hanzi", true)
4142
.option("--log <file>", "Save log to file")
4243
.option("--title <title>", "Override title in rendering")
4344
.helpOption("-h, --help", "Display help");
@@ -192,17 +193,11 @@ function exec() {
192193
);
193194
process.exit(1);
194195
}
195-
if (program.lang === "js") {
196-
eval(getCompiled());
197-
} else if (program.lang === "py") {
198-
var execSync = require("child_process").execSync;
199-
fs.writeFileSync("tmp.py", out);
200-
var ret = execSync(
201-
"which python3; if [ $? == 0 ]; then python3 tmp.py; else python tmp.py; fi; rm tmp.py",
202-
{ encoding: "utf-8" }
203-
);
204-
console.log(ret);
205-
}
196+
197+
evalCompiled(getCompiled(), {
198+
outputHanzi: program.outputHanzi,
199+
lang: program.lang
200+
});
206201
}
207202

208203
function replscope() {

src/parser.js

Lines changed: 67 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
try {
2-
var { hanzi2num, hanzi2numstr, num2hanzi, bool2hanzi } = require("./hanzi2num");
2+
var {
3+
hanzi2num,
4+
hanzi2numstr,
5+
num2hanzi,
6+
bool2hanzi
7+
} = require("./hanzi2num");
38
var hanzi2pinyin = require("./hanzi2pinyin");
49
var STDLIB = require("./stdlib");
510
var { NUMBER_KEYWORDS, KEYWORDS } = require("./keywords");
@@ -753,8 +758,69 @@ function compile(
753758
return targ;
754759
}
755760

761+
function isLangSupportedForEval(lang) {
762+
if (lang !== "js")
763+
throw new Error(
764+
`Executing for target language "${lang}" is not supported in current environment`
765+
);
766+
return true;
767+
}
768+
769+
function hanzinize(value) {
770+
if (typeof value == "number") {
771+
return num2hanzi(value);
772+
} else if (typeof value == "boolean") {
773+
return bool2hanzi(value);
774+
} else if (Array.isArray(value)) {
775+
return value.map(i => hanzinize(i));
776+
} else {
777+
return value;
778+
}
779+
}
780+
781+
function outputHanziWrapper(log) {
782+
return function output(...args) {
783+
log(...args.map(i => hanzinize(i)));
784+
};
785+
}
786+
787+
function evalCompiled(compiledCode, options = {}) {
788+
const { outputHanzi = true, scoped = false, lang = "js" } = options;
789+
790+
isLangSupportedForEval(lang);
791+
792+
let code = compiledCode;
793+
794+
(() => {
795+
const _console_log = console.log;
796+
if (outputHanzi) {
797+
console.log = outputHanziWrapper(_console_log);
798+
}
799+
try {
800+
if (!scoped && "window" in this) {
801+
window.eval(code);
802+
} else {
803+
eval(code);
804+
}
805+
} catch (e) {
806+
throw e;
807+
} finally {
808+
if (outputHanzi) console.log = _console_log;
809+
}
810+
})();
811+
}
812+
813+
function execute(source, options = {}) {
814+
const { lang = "js" } = options;
815+
isLangSupportedForEval(lang);
816+
const compiled = compile(options.lang, source, options);
817+
evalCompiled(compiled, options);
818+
}
819+
756820
var parser = {
757821
compile,
822+
evalCompiled,
823+
execute,
758824
version,
759825
wy2tokens,
760826
tokens2asc,

0 commit comments

Comments
 (0)