Commit 6c340adf authored by Kevin Modzelewski's avatar Kevin Modzelewski

Support print as a function

parent 47ef853a
...@@ -27,7 +27,7 @@ const std::map<std::string, FutureOption> future_options ...@@ -27,7 +27,7 @@ const std::map<std::string, FutureOption> future_options
{ "division", { version_hex(2, 2, 0), version_hex(3, 0, 0), FF_DIVISION } }, { "division", { version_hex(2, 2, 0), version_hex(3, 0, 0), FF_DIVISION } },
{ "generators", { version_hex(2, 2, 0), version_hex(3, 0, 0), FF_GENERATOR } }, { "generators", { version_hex(2, 2, 0), version_hex(3, 0, 0), FF_GENERATOR } },
{ "unicode_literals", { version_hex(2, 6, 0), version_hex(3, 0, 0), FF_UNICODE_LITERALS } }, { "unicode_literals", { version_hex(2, 6, 0), version_hex(3, 0, 0), FF_UNICODE_LITERALS } },
{ "print_functions", { version_hex(2, 6, 0), version_hex(3, 0, 0), FF_PRINT_FUNCTIONS } }, { "print_function", { version_hex(2, 6, 0), version_hex(3, 0, 0), FF_PRINT_FUNCTION } },
{ "nested_scopes", { version_hex(2, 1, 0), version_hex(2, 2, 0), FF_NESTED_SCOPES } }, { "nested_scopes", { version_hex(2, 1, 0), version_hex(2, 2, 0), FF_NESTED_SCOPES } },
{ "with_statement", { version_hex(2, 5, 0), version_hex(3, 6, 0), FF_WITH_STATEMENT } } }; { "with_statement", { version_hex(2, 5, 0), version_hex(3, 6, 0), FF_WITH_STATEMENT } } };
......
...@@ -27,7 +27,7 @@ namespace pyston { ...@@ -27,7 +27,7 @@ namespace pyston {
#define FF_DIVISION 0x02 #define FF_DIVISION 0x02
#define FF_GENERATOR 0x04 #define FF_GENERATOR 0x04
#define FF_UNICODE_LITERALS 0x08 #define FF_UNICODE_LITERALS 0x08
#define FF_PRINT_FUNCTIONS 0x10 #define FF_PRINT_FUNCTION 0x10
#define FF_NESTED_SCOPES 0x20 #define FF_NESTED_SCOPES 0x20
#define FF_WITH_STATEMENT 0x40 #define FF_WITH_STATEMENT 0x40
......
...@@ -188,7 +188,6 @@ void initGlobalFuncs(GlobalState& g) { ...@@ -188,7 +188,6 @@ void initGlobalFuncs(GlobalState& g) {
GET(compare); GET(compare);
GET(augbinop); GET(augbinop);
GET(nonzero); GET(nonzero);
GET(print);
GET(unboxedLen); GET(unboxedLen);
GET(getclsattr); GET(getclsattr);
GET(unaryop); GET(unaryop);
......
...@@ -35,9 +35,9 @@ struct GlobalFuncs { ...@@ -35,9 +35,9 @@ struct GlobalFuncs {
llvm::Value* boxInt, *unboxInt, *boxFloat, *unboxFloat, *boxStringPtr, *boxCLFunction, *unboxCLFunction, llvm::Value* boxInt, *unboxInt, *boxFloat, *unboxFloat, *boxStringPtr, *boxCLFunction, *unboxCLFunction,
*boxInstanceMethod, *boxBool, *unboxBool, *createTuple, *createDict, *createList, *createSlice, *boxInstanceMethod, *boxBool, *unboxBool, *createTuple, *createDict, *createList, *createSlice,
*createUserClass, *createClosure, *createGenerator, *createLong, *createSet, *createPureImaginary; *createUserClass, *createClosure, *createGenerator, *createLong, *createSet, *createPureImaginary;
llvm::Value* getattr, *setattr, *delattr, *delitem, *delGlobal, *print, *nonzero, *binop, *compare, *augbinop, llvm::Value* getattr, *setattr, *delattr, *delitem, *delGlobal, *nonzero, *binop, *compare, *augbinop, *unboxedLen,
*unboxedLen, *getitem, *getclsattr, *getGlobal, *setitem, *unaryop, *import, *importFrom, *importStar, *repr, *getitem, *getclsattr, *getGlobal, *setitem, *unaryop, *import, *importFrom, *importStar, *repr, *str,
*str, *isinstance, *yield, *getiter; *isinstance, *yield, *getiter;
llvm::Value* unpackIntoArray, *raiseAttributeError, *raiseAttributeErrorStr, *raiseNotIterableError, llvm::Value* unpackIntoArray, *raiseAttributeError, *raiseAttributeErrorStr, *raiseNotIterableError,
*assertNameDefined, *assertFail; *assertNameDefined, *assertFail;
......
...@@ -603,11 +603,62 @@ Box* execfile(Box* _fn) { ...@@ -603,11 +603,62 @@ Box* execfile(Box* _fn) {
return None; return None;
} }
Box* print(BoxedTuple* args, BoxedDict* kwargs) {
assert(args->cls == tuple_cls);
assert(kwargs->cls == dict_cls);
Box* dest, *end;
auto it = kwargs->d.find(new BoxedString("file"));
if (it != kwargs->d.end()) {
dest = it->second;
kwargs->d.erase(it);
} else {
dest = getSysStdout();
}
it = kwargs->d.find(new BoxedString("end"));
if (it != kwargs->d.end()) {
end = it->second;
kwargs->d.erase(it);
} else {
end = new BoxedString("\n");
}
RELEASE_ASSERT(kwargs->d.size() == 0, "print() got unexpected keyword arguments");
static const std::string write_str("write");
Box* space_box = new BoxedString(" ");
// TODO softspace handling?
bool first = true;
for (auto e : args->elts) {
BoxedString* s = str(e);
if (!first) {
Box* r = callattr(dest, &write_str, false, ArgPassSpec(1), space_box, NULL, NULL, NULL, NULL);
RELEASE_ASSERT(r, "");
}
first = false;
Box* r = callattr(dest, &write_str, false, ArgPassSpec(1), s, NULL, NULL, NULL, NULL);
RELEASE_ASSERT(r, "");
}
Box* r = callattr(dest, &write_str, false, ArgPassSpec(1), end, NULL, NULL, NULL, NULL);
RELEASE_ASSERT(r, "");
return None;
}
void setupBuiltins() { void setupBuiltins() {
builtins_module = createModule("__builtin__", "__builtin__"); builtins_module = createModule("__builtin__", "__builtin__");
builtins_module->giveAttr("None", None); builtins_module->giveAttr("None", None);
builtins_module->giveAttr("print", new BoxedFunction(boxRTFunction((void*)print, NONE, 0, 0, true, true)));
notimplemented_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(Box), false); notimplemented_cls = new BoxedClass(type_cls, object_cls, NULL, 0, sizeof(Box), false);
notimplemented_cls->giveAttr("__name__", boxStrConstant("NotImplementedType")); notimplemented_cls->giveAttr("__name__", boxStrConstant("NotImplementedType"));
notimplemented_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)notimplementedRepr, STR, 1))); notimplemented_cls->giveAttr("__repr__", new BoxedFunction(boxRTFunction((void*)notimplementedRepr, STR, 1)));
......
...@@ -71,7 +71,6 @@ void force() { ...@@ -71,7 +71,6 @@ void force() {
FORCE(getattr); FORCE(getattr);
FORCE(setattr); FORCE(setattr);
FORCE(delattr); FORCE(delattr);
FORCE(print);
FORCE(nonzero); FORCE(nonzero);
FORCE(binop); FORCE(binop);
FORCE(compare); FORCE(compare);
......
...@@ -1782,14 +1782,6 @@ extern "C" i64 unboxedLen(Box* obj) { ...@@ -1782,14 +1782,6 @@ extern "C" i64 unboxedLen(Box* obj) {
return rtn; return rtn;
} }
extern "C" void print(Box* obj) {
static StatCounter slowpath_print("slowpath_print");
slowpath_print.log();
BoxedString* strd = str(obj);
printf("%s", strd->s.c_str());
}
extern "C" void dump(void* p) { extern "C" void dump(void* p) {
printf("\n"); printf("\n");
bool is_gc = (gc::global_heap.getAllocationFromInteriorPointer(p) != NULL); bool is_gc = (gc::global_heap.getAllocationFromInteriorPointer(p) != NULL);
......
...@@ -61,7 +61,6 @@ Box* open(Box* arg1, Box* arg2); ...@@ -61,7 +61,6 @@ Box* open(Box* arg1, Box* arg2);
// extern "C" Box* chr(Box* arg); // extern "C" Box* chr(Box* arg);
extern "C" Box* compare(Box*, Box*, int); extern "C" Box* compare(Box*, Box*, int);
extern "C" BoxedInt* len(Box* obj); extern "C" BoxedInt* len(Box* obj);
extern "C" void print(Box* obj);
// extern "C" Box* trap(); // extern "C" Box* trap();
extern "C" i64 unboxedLen(Box* obj); extern "C" i64 unboxedLen(Box* obj);
extern "C" Box* binop(Box* lhs, Box* rhs, int op_type); extern "C" Box* binop(Box* lhs, Box* rhs, int op_type);
......
# This is the same as print_function.py, but using print as a statement
def f(o, msg): def f(o, msg):
print msg print msg
return o return o
......
# This is the same as print.py, but using print as a function
# I guess print() as a function doesn't use the softspace technique.
from __future__ import print_function
def f(o, msg):
print(msg)
return o
class C(object):
def write(self, s):
print("class write", repr(s))
c = C()
c2 = C()
def write2(s):
print("instance write", repr(s))
c.write = write2
l = [c, c2]
print(f(1, "evaluating argument"), file=f(l[0], "evaluating dest"))
print(f(2, "evaluating second argument"), file=l[0])
print(hasattr(c, "softspace"))
print(hasattr(c2, "softspace"))
print(f(3, 3), file=l[1])
print(hasattr(c2, "softspace"))
print(f(4, 4), file=l[0])
print(hasattr(c, "softspace"))
import sys
ss_1 = sys.stdout.softspace
print(1, end="")
ss_2 = sys.stdout.softspace
print()
ss_3 = sys.stdout.softspace
print(ss_1, ss_2, ss_3)
print(hasattr(c, "softspace"), file=c)
print()
class D(object):
def __str__(self):
return 1
try:
print(D(), file=c)
assert 0, "expected TypeError was not thrown"
except TypeError:
pass
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