Commit a1be8bf1 authored by Michael Arntzenius's avatar Michael Arntzenius

implement `pyston -c command`

parent 978d853b
...@@ -47,6 +47,20 @@ ...@@ -47,6 +47,20 @@
using namespace pyston; using namespace pyston;
// returns true iff we got a request to exit, i.e. SystemExit, placing the
// return code in `*retcode`. does not touch `*retcode* if it returns false.
static bool handle_toplevel_exn(const ExcInfo& e, int* retcode) {
if (e.matches(SystemExit)) {
Box* code = e.value->getattr("code");
*retcode = 1;
if (code && isSubclass(code->cls, pyston::int_cls))
*retcode = static_cast<BoxedInt*>(code)->n;
return true;
}
e.printExcAndTraceback();
return false;
}
int main(int argc, char** argv) { int main(int argc, char** argv) {
Timer _t("for jit startup"); Timer _t("for jit startup");
// llvm::sys::PrintStackTraceOnErrorSignal(); // llvm::sys::PrintStackTraceOnErrorSignal();
...@@ -55,9 +69,9 @@ int main(int argc, char** argv) { ...@@ -55,9 +69,9 @@ int main(int argc, char** argv) {
int code; int code;
bool force_repl = false; bool force_repl = false;
bool repl = true;
bool stats = false; bool stats = false;
while ((code = getopt(argc, argv, "+OqcdIibpjtrsvnx")) != -1) { const char* command = NULL;
while ((code = getopt(argc, argv, "+OqdIibpjtrsvnxc:")) != -1) {
if (code == 'O') if (code == 'O')
FORCE_OPTIMIZE = true; FORCE_OPTIMIZE = true;
else if (code == 't') else if (code == 't')
...@@ -86,7 +100,11 @@ int main(int argc, char** argv) { ...@@ -86,7 +100,11 @@ int main(int argc, char** argv) {
USE_REGALLOC_BASIC = false; USE_REGALLOC_BASIC = false;
} else if (code == 'x') { } else if (code == 'x') {
ENABLE_PYPA_PARSER = true; ENABLE_PYPA_PARSER = true;
} else if (code == '?') } else if (code == 'c') {
command = optarg;
// no more option parsing; the rest of our arguments go into sys.argv.
break;
} else
abort(); abort();
} }
...@@ -100,18 +118,23 @@ int main(int argc, char** argv) { ...@@ -100,18 +118,23 @@ int main(int argc, char** argv) {
initCodegen(); initCodegen();
} }
if (optind != argc) { // Arguments left over after option parsing are of the form:
fn = argv[optind]; // [ script | - ] [ arguments... ]
if (strcmp("-", fn) == 0) // unless we've been already parsed a `-c command` option, in which case only:
fn = NULL; // [ arguments...]
else if (!force_repl) // are parsed.
repl = false; if (command)
addToSysArgv("-c");
for (int i = optind; i < argc; i++) { else if (optind != argc) {
addToSysArgv(argv[i]); addToSysArgv(argv[optind]);
} if (strcmp("-", argv[optind]) != 0)
} else { fn = argv[optind];
++optind;
} else
addToSysArgv(""); addToSysArgv("");
for (int i = optind; i < argc; i++) {
addToSysArgv(argv[i]);
} }
std::string self_path = llvm::sys::fs::getMainExecutable(argv[0], (void*)main); std::string self_path = llvm::sys::fs::getMainExecutable(argv[0], (void*)main);
...@@ -133,6 +156,20 @@ int main(int argc, char** argv) { ...@@ -133,6 +156,20 @@ int main(int argc, char** argv) {
_t.split("to run"); _t.split("to run");
BoxedModule* main_module = NULL; BoxedModule* main_module = NULL;
// if the user invoked `pyston -c command`
if (command != NULL) {
main_module = createModule("__main__", "<string>");
AST_Module* m = parse_string(command);
try {
compileAndRunModule(m, main_module);
} catch (ExcInfo e) {
int retcode = 1;
(void)handle_toplevel_exn(e, &retcode);
return retcode;
}
}
if (fn != NULL) { if (fn != NULL) {
llvm::SmallString<128> path; llvm::SmallString<128> path;
...@@ -150,20 +187,13 @@ int main(int argc, char** argv) { ...@@ -150,20 +187,13 @@ int main(int argc, char** argv) {
try { try {
main_module = createAndRunModule("__main__", fn); main_module = createAndRunModule("__main__", fn);
} catch (ExcInfo e) { } catch (ExcInfo e) {
if (e.matches(SystemExit)) { int retcode = 1;
Box* code = e.value->getattr("code"); (void)handle_toplevel_exn(e, &retcode);
int rtncode = 1; return retcode;
if (code && isSubclass(code->cls, pyston::int_cls))
rtncode = static_cast<BoxedInt*>(code)->n;
return rtncode;
} else {
e.printExcAndTraceback();
return 1;
}
} }
} }
if (repl) { if (force_repl || !(command || fn)) {
printf("Pyston v%d.%d (rev " STRINGIFY(GITREV) ")", PYSTON_VERSION_MAJOR, PYSTON_VERSION_MINOR); printf("Pyston v%d.%d (rev " STRINGIFY(GITREV) ")", PYSTON_VERSION_MAJOR, PYSTON_VERSION_MINOR);
printf(", targeting Python %d.%d.%d\n", PYTHON_VERSION_MAJOR, PYTHON_VERSION_MINOR, PYTHON_VERSION_MICRO); printf(", targeting Python %d.%d.%d\n", PYTHON_VERSION_MAJOR, PYTHON_VERSION_MINOR, PYTHON_VERSION_MICRO);
...@@ -173,49 +203,41 @@ int main(int argc, char** argv) { ...@@ -173,49 +203,41 @@ int main(int argc, char** argv) {
main_module->fn = "<stdin>"; main_module->fn = "<stdin>";
} }
while (repl) { for (;;) {
char* line = readline(">> "); char* line = readline(">> ");
if (!line)
break;
add_history(line);
AST_Module* m = parse_string(line);
Timer _t("repl");
if (m->body.size() > 0 && m->body[0]->type == AST_TYPE::Expr) {
AST_Expr* e = ast_cast<AST_Expr>(m->body[0]);
AST_Call* c = new AST_Call();
AST_Name* r = new AST_Name(m->interned_strings->get("repr"), AST_TYPE::Load, 0);
c->func = r;
c->starargs = NULL;
c->kwargs = NULL;
c->args.push_back(e->value);
c->lineno = 0;
AST_Print* p = new AST_Print();
p->dest = NULL;
p->nl = true;
p->values.push_back(c);
p->lineno = 0;
m->body[0] = p;
}
if (!line) { try {
repl = false; compileAndRunModule(m, main_module);
} else { } catch (ExcInfo e) {
add_history(line); int retcode = 0xdeadbeef; // should never be seen
if (handle_toplevel_exn(e, &retcode))
AST_Module* m = parse_string(line); return retcode;
Timer _t("repl");
if (m->body.size() > 0 && m->body[0]->type == AST_TYPE::Expr) {
AST_Expr* e = ast_cast<AST_Expr>(m->body[0]);
AST_Call* c = new AST_Call();
AST_Name* r = new AST_Name(m->interned_strings->get("repr"), AST_TYPE::Load, 0);
c->func = r;
c->starargs = NULL;
c->kwargs = NULL;
c->args.push_back(e->value);
c->lineno = 0;
AST_Print* p = new AST_Print();
p->dest = NULL;
p->nl = true;
p->values.push_back(c);
p->lineno = 0;
m->body[0] = p;
}
try {
compileAndRunModule(m, main_module);
} catch (ExcInfo e) {
if (e.matches(SystemExit)) {
Box* code = e.value->getattr("code");
int rtncode = 1;
if (code && isSubclass(code->cls, pyston::int_cls))
rtncode = static_cast<BoxedInt*>(code)->n;
return rtncode;
} else {
e.printExcAndTraceback();
}
}
} }
} }
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment