Commit ec1b3848 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Implement execfile() (1-arg version)

Also required adding some string functions so that
we could use os.path.
parent 59e195aa
...@@ -452,7 +452,8 @@ static_assert(sizeof(pyston::BoxedClass) == sizeof(struct _typeobject), ""); ...@@ -452,7 +452,8 @@ static_assert(sizeof(pyston::BoxedClass) == sizeof(struct _typeobject), "");
// TODO these shouldn't be here // TODO these shouldn't be here
void setupRuntime(); void setupRuntime();
void teardownRuntime(); void teardownRuntime();
BoxedModule* createModule(const std::string& name, const std::string& fn); BoxedModule* compileAndRunModule(const std::string& name, const std::string& fn, bool add_to_sys_modules);
BoxedModule* createModule(const std::string& name, const std::string& fn, bool add_to_sys_modules = true);
std::string getPythonFuncAt(void* ip, void* sp); std::string getPythonFuncAt(void* ip, void* sp);
......
...@@ -83,11 +83,17 @@ Timer::~Timer() { ...@@ -83,11 +83,17 @@ Timer::~Timer() {
} }
bool startswith(const std::string& s, const std::string& pattern) { bool startswith(const std::string& s, const std::string& pattern) {
if (s.size() == 0) if (pattern.size() > s.size())
return pattern.size() == 0; return false;
return s.compare(0, pattern.size(), pattern) == 0; return s.compare(0, pattern.size(), pattern) == 0;
} }
bool endswith(const std::string& s, const std::string& pattern) {
if (pattern.size() > s.size())
return false;
return s.compare(s.size() - pattern.size(), pattern.size(), pattern) == 0;
}
void removeDirectoryIfExists(const std::string& path) { void removeDirectoryIfExists(const std::string& path) {
llvm::error_code code; llvm::error_code code;
......
...@@ -48,6 +48,7 @@ public: ...@@ -48,6 +48,7 @@ public:
}; };
bool startswith(const std::string& s, const std::string& pattern); bool startswith(const std::string& s, const std::string& pattern);
bool endswith(const std::string& s, const std::string& pattern);
void removeDirectoryIfExists(const std::string& path); void removeDirectoryIfExists(const std::string& path);
......
...@@ -127,8 +127,6 @@ int main(int argc, char** argv) { ...@@ -127,8 +127,6 @@ int main(int argc, char** argv) {
_t.split("to run"); _t.split("to run");
BoxedModule* main_module = NULL; BoxedModule* main_module = NULL;
if (fn != NULL) { if (fn != NULL) {
main_module = createModule("__main__", fn);
llvm::SmallString<128> path; llvm::SmallString<128> path;
if (!llvm::sys::path::is_absolute(fn)) { if (!llvm::sys::path::is_absolute(fn)) {
...@@ -147,20 +145,8 @@ int main(int argc, char** argv) { ...@@ -147,20 +145,8 @@ int main(int argc, char** argv) {
num_iterations = 1000; num_iterations = 1000;
for (int i = 0; i < num_iterations; i++) { for (int i = 0; i < num_iterations; i++) {
AST_Module* m;
if (caching)
m = caching_parse(fn);
else
m = parse(fn);
if (VERBOSITY() >= 1) {
printf("Parsed code; ast:\n");
print_ast(m);
printf("==============\n");
}
try { try {
compileAndRunModule(m, main_module); main_module = compileAndRunModule("__main__", fn, true);
} catch (Box* b) { } catch (Box* b) {
std::string msg = formatException(b); std::string msg = formatException(b);
printLastTraceback(); printLastTraceback();
...@@ -173,7 +159,7 @@ int main(int argc, char** argv) { ...@@ -173,7 +159,7 @@ int main(int argc, char** argv) {
if (repl && BENCH) { if (repl && BENCH) {
if (!main_module) { if (!main_module) {
main_module = createModule("__main__", "<bench>"); main_module = createModule("__main__", "<bench>", true);
} else { } else {
main_module->fn = "<bench>"; main_module->fn = "<bench>";
} }
...@@ -211,7 +197,7 @@ int main(int argc, char** argv) { ...@@ -211,7 +197,7 @@ int main(int argc, char** argv) {
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);
if (!main_module) { if (!main_module) {
main_module = createModule("__main__", "<stdin>"); main_module = createModule("__main__", "<stdin>", true);
} else { } else {
main_module->fn = "<stdin>"; main_module->fn = "<stdin>";
} }
......
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#include <cstddef> #include <cstddef>
#include <err.h> #include <err.h>
#include "llvm/Support/FileSystem.h"
#include "codegen/compvars.h" #include "codegen/compvars.h"
#include "core/ast.h" #include "core/ast.h"
#include "core/types.h" #include "core/types.h"
...@@ -524,6 +526,29 @@ Box* divmod(Box* lhs, Box* rhs) { ...@@ -524,6 +526,29 @@ Box* divmod(Box* lhs, Box* rhs) {
return binopInternal(lhs, rhs, AST_TYPE::DivMod, false, NULL); return binopInternal(lhs, rhs, AST_TYPE::DivMod, false, NULL);
} }
Box* execfile(Box* _fn) {
// The "globals" and "locals" arguments aren't implemented for now
if (!isSubclass(_fn->cls, str_cls)) {
raiseExcHelper(TypeError, "must be string, not %s", getTypeName(_fn)->c_str());
}
BoxedString* fn = static_cast<BoxedString*>(_fn);
bool exists;
llvm::error_code code = llvm::sys::fs::exists(fn->s, exists);
#if LLVMREV < 210072
ASSERT(code == 0, "%s: %s", code.message().c_str(), fn->s.c_str());
#else
assert(!code);
#endif
if (!exists)
raiseExcHelper(IOError, "No such file or directory: '%s'", fn->s.c_str());
compileAndRunModule("aoeu", fn->s, false);
return None;
}
void setupBuiltins() { void setupBuiltins() {
builtins_module = createModule("__builtin__", "__builtin__"); builtins_module = createModule("__builtin__", "__builtin__");
...@@ -649,6 +674,8 @@ void setupBuiltins() { ...@@ -649,6 +674,8 @@ void setupBuiltins() {
builtins_module->giveAttr("divmod", new BoxedFunction(boxRTFunction((void*)divmod, UNKNOWN, 2))); builtins_module->giveAttr("divmod", new BoxedFunction(boxRTFunction((void*)divmod, UNKNOWN, 2)));
builtins_module->giveAttr("execfile", new BoxedFunction(boxRTFunction((void*)execfile, UNKNOWN, 1)));
builtins_module->giveAttr("map", new BoxedFunction(boxRTFunction((void*)map2, LIST, 2))); builtins_module->giveAttr("map", new BoxedFunction(boxRTFunction((void*)map2, LIST, 2)));
builtins_module->giveAttr("filter", new BoxedFunction(boxRTFunction((void*)filter2, LIST, 2))); builtins_module->giveAttr("filter", new BoxedFunction(boxRTFunction((void*)filter2, LIST, 2)));
builtins_module->giveAttr("zip", new BoxedFunction(boxRTFunction((void*)zip2, LIST, 2))); builtins_module->giveAttr("zip", new BoxedFunction(boxRTFunction((void*)zip2, LIST, 2)));
......
...@@ -3487,6 +3487,14 @@ extern "C" Box* getGlobal(BoxedModule* m, std::string* name) { ...@@ -3487,6 +3487,14 @@ extern "C" Box* getGlobal(BoxedModule* m, std::string* name) {
raiseExcHelper(NameError, "global name '%s' is not defined", name->c_str()); raiseExcHelper(NameError, "global name '%s' is not defined", name->c_str());
} }
BoxedModule* compileAndRunModule(const std::string& name, const std::string& fn, bool add_to_sys_modules) {
BoxedModule* module = createModule(name, fn, add_to_sys_modules);
AST_Module* ast = caching_parse(fn.c_str());
compileAndRunModule(ast, module);
return module;
}
// TODO I feel like importing should go somewhere else; it's more closely tied to codegen // TODO I feel like importing should go somewhere else; it's more closely tied to codegen
// than to the object model. // than to the object model.
extern "C" Box* import(const std::string* name) { extern "C" Box* import(const std::string* name) {
...@@ -3533,9 +3541,7 @@ extern "C" Box* import(const std::string* name) { ...@@ -3533,9 +3541,7 @@ extern "C" Box* import(const std::string* name) {
printf("Importing %s from %s\n", name->c_str(), fn.c_str()); printf("Importing %s from %s\n", name->c_str(), fn.c_str());
// TODO duplication with jit.cpp: // TODO duplication with jit.cpp:
BoxedModule* module = createModule(*name, fn); BoxedModule* module = compileAndRunModule(*name, fn, true);
AST_Module* ast = caching_parse(fn.c_str());
compileAndRunModule(ast, module);
return module; return module;
} }
......
...@@ -23,6 +23,7 @@ ...@@ -23,6 +23,7 @@
#include "codegen/compvars.h" #include "codegen/compvars.h"
#include "core/common.h" #include "core/common.h"
#include "core/types.h" #include "core/types.h"
#include "core/util.h"
#include "gc/collector.h" #include "gc/collector.h"
#include "runtime/objmodel.h" #include "runtime/objmodel.h"
#include "runtime/types.h" #include "runtime/types.h"
...@@ -694,6 +695,64 @@ Box* strContains(BoxedString* self, Box* elt) { ...@@ -694,6 +695,64 @@ Box* strContains(BoxedString* self, Box* elt) {
return True; return True;
} }
Box* strStartswith(BoxedString* self, Box* elt) {
if (self->cls != str_cls)
raiseExcHelper(TypeError, "descriptor 'startswith' requires a 'str' object but received a '%s'",
getTypeName(elt)->c_str());
if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object");
BoxedString* sub = static_cast<BoxedString*>(elt);
return boxBool(startswith(self->s, sub->s));
}
Box* strEndswith(BoxedString* self, Box* elt) {
if (self->cls != str_cls)
raiseExcHelper(TypeError, "descriptor 'endswith' requires a 'str' object but received a '%s'",
getTypeName(elt)->c_str());
if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object");
BoxedString* sub = static_cast<BoxedString*>(elt);
return boxBool(endswith(self->s, sub->s));
}
Box* strFind(BoxedString* self, Box* elt) {
if (self->cls != str_cls)
raiseExcHelper(TypeError, "descriptor 'find' requires a 'str' object but received a '%s'",
getTypeName(elt)->c_str());
if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object");
BoxedString* sub = static_cast<BoxedString*>(elt);
size_t r = self->s.find(sub->s);
if (r == std::string::npos)
return boxInt(-1);
return boxInt(r);
}
Box* strRfind(BoxedString* self, Box* elt) {
if (self->cls != str_cls)
raiseExcHelper(TypeError, "descriptor 'rfind' requires a 'str' object but received a '%s'",
getTypeName(elt)->c_str());
if (elt->cls != str_cls)
raiseExcHelper(TypeError, "expected a character buffer object");
BoxedString* sub = static_cast<BoxedString*>(elt);
size_t r = self->s.rfind(sub->s);
if (r == std::string::npos)
return boxInt(-1);
return boxInt(r);
}
extern "C" Box* strGetitem(BoxedString* self, Box* slice) { extern "C" Box* strGetitem(BoxedString* self, Box* slice) {
assert(self->cls == str_cls); assert(self->cls == str_cls);
...@@ -851,9 +910,7 @@ void setupStr() { ...@@ -851,9 +910,7 @@ void setupStr() {
str_cls->giveAttr("upper", new BoxedFunction(boxRTFunction((void*)strUpper, STR, 1))); str_cls->giveAttr("upper", new BoxedFunction(boxRTFunction((void*)strUpper, STR, 1)));
str_cls->giveAttr("strip", new BoxedFunction(boxRTFunction((void*)strStrip, STR, 2, 1, false, false), { None })); str_cls->giveAttr("strip", new BoxedFunction(boxRTFunction((void*)strStrip, STR, 2, 1, false, false), { None }));
str_cls->giveAttr("lstrip", new BoxedFunction(boxRTFunction((void*)strLStrip, STR, 2, 1, false, false), { None })); str_cls->giveAttr("lstrip", new BoxedFunction(boxRTFunction((void*)strLStrip, STR, 2, 1, false, false), { None }));
str_cls->giveAttr("rstrip", new BoxedFunction(boxRTFunction((void*)strRStrip, STR, 2, 1, false, false), { None })); str_cls->giveAttr("rstrip", new BoxedFunction(boxRTFunction((void*)strRStrip, STR, 2, 1, false, false), { None }));
str_cls->giveAttr("capitalize", new BoxedFunction(boxRTFunction((void*)strCapitalize, STR, 1))); str_cls->giveAttr("capitalize", new BoxedFunction(boxRTFunction((void*)strCapitalize, STR, 1)));
...@@ -861,6 +918,12 @@ void setupStr() { ...@@ -861,6 +918,12 @@ void setupStr() {
str_cls->giveAttr("__contains__", new BoxedFunction(boxRTFunction((void*)strContains, BOXED_BOOL, 2))); str_cls->giveAttr("__contains__", new BoxedFunction(boxRTFunction((void*)strContains, BOXED_BOOL, 2)));
str_cls->giveAttr("startswith", new BoxedFunction(boxRTFunction((void*)strStartswith, BOXED_BOOL, 2)));
str_cls->giveAttr("endswith", new BoxedFunction(boxRTFunction((void*)strEndswith, BOXED_BOOL, 2)));
str_cls->giveAttr("find", new BoxedFunction(boxRTFunction((void*)strFind, BOXED_INT, 2)));
str_cls->giveAttr("rfind", new BoxedFunction(boxRTFunction((void*)strRfind, BOXED_INT, 2)));
str_cls->giveAttr("__add__", new BoxedFunction(boxRTFunction((void*)strAdd, UNKNOWN, 2))); str_cls->giveAttr("__add__", new BoxedFunction(boxRTFunction((void*)strAdd, UNKNOWN, 2)));
str_cls->giveAttr("__mod__", new BoxedFunction(boxRTFunction((void*)strMod, STR, 2))); str_cls->giveAttr("__mod__", new BoxedFunction(boxRTFunction((void*)strMod, STR, 2)));
str_cls->giveAttr("__mul__", new BoxedFunction(boxRTFunction((void*)strMul, UNKNOWN, 2))); str_cls->giveAttr("__mul__", new BoxedFunction(boxRTFunction((void*)strMul, UNKNOWN, 2)));
......
...@@ -805,14 +805,16 @@ void setupRuntime() { ...@@ -805,14 +805,16 @@ void setupRuntime() {
TRACK_ALLOCATIONS = true; TRACK_ALLOCATIONS = true;
} }
BoxedModule* createModule(const std::string& name, const std::string& fn) { BoxedModule* createModule(const std::string& name, const std::string& fn, bool add_to_sys_modules) {
assert(fn.size() && "probably wanted to set the fn to <stdin>?"); assert(fn.size() && "probably wanted to set the fn to <stdin>?");
BoxedModule* module = new BoxedModule(name, fn); BoxedModule* module = new BoxedModule(name, fn);
if (add_to_sys_modules) {
BoxedDict* d = getSysModulesDict(); BoxedDict* d = getSysModulesDict();
Box* b_name = boxStringPtr(&name); Box* b_name = boxStringPtr(&name);
assert(d->d.count(b_name) == 0); assert(d->d.count(b_name) == 0);
d->d[b_name] = module; d->d[b_name] = module;
}
module->giveAttr("__doc__", None); module->giveAttr("__doc__", None);
return module; return module;
......
# expected: fail # expected: fail
# execfile() not implemented yet # execfile() not implemented yet
execfile("execfile_target.py") try:
execfile("doesnt_exist.py")
except IOError, e:
print e
import os
fn = os.path.join(os.path.dirname(__file__), 'execfile_target.py')
execfile(fn)
print "done with first execfile" print "done with first execfile"
execfile("execfile_target.py") execfile(fn)
...@@ -56,3 +56,7 @@ print sorted([str(i) for i in xrange(25)]) ...@@ -56,3 +56,7 @@ print sorted([str(i) for i in xrange(25)])
for i in xrange(-3, 5): for i in xrange(-3, 5):
print i, "bananananananananana".split("an", i) print i, "bananananananananana".split("an", i)
for i in ["", "a", "ab", "aa"]:
for j in ["", "b", "a", "ab", "aa"]:
print i, j, i.startswith(j), j.startswith(i), i.endswith(j), j.endswith(i), i.find(j), j.find(i), i.rfind(j), j.rfind(i)
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