Commit 42b34706 authored by Kevin Modzelewski's avatar Kevin Modzelewski

print statement improvements

`print >>None` goes to stdout, and printing to things without write()
functions should throw exceptions.
parent 87d01381
......@@ -2003,7 +2003,7 @@ private:
ConcreteCompilerVariable* dest = NULL;
if (node->dest) {
auto d = evalExpr(node->dest, unw_info);
dest = d->makeConverted(emitter, d->getConcreteType());
dest = d->makeConverted(emitter, d->getBoxType());
d->decvref(emitter);
} else {
llvm::Value* sys_stdout_val = emitter.createCall(unw_info, g.funcs.getSysStdout);
......@@ -2012,63 +2012,22 @@ private:
}
assert(dest);
static BoxedString* write_str = internStringImmortal("write");
static BoxedString* newline_str = internStringImmortal("\n");
static BoxedString* space_str = internStringImmortal(" ");
assert(node->values.size() <= 1);
ConcreteCompilerVariable* converted;
// TODO: why are we inline-generating all this code instead of just emitting a call to some runtime function?
// (=printHelper())
int nvals = node->values.size();
for (int i = 0; i < nvals; i++) {
CompilerVariable* var = evalExpr(node->values[i], unw_info);
ConcreteCompilerVariable* converted = var->makeConverted(emitter, var->getBoxType());
if (node->values.size() == 1) {
CompilerVariable* var = evalExpr(node->values[0], unw_info);
converted = var->makeConverted(emitter, var->getBoxType());
var->decvref(emitter);
// begin code for handling of softspace
bool new_softspace = (i < nvals - 1) || (!node->nl);
llvm::Value* dospace = emitter.createCall(unw_info, g.funcs.softspace,
{ dest->getValue(), getConstantInt(new_softspace, g.i1) });
assert(dospace->getType() == g.i1);
llvm::BasicBlock* ss_block = llvm::BasicBlock::Create(g.context, "softspace", irstate->getLLVMFunction());
llvm::BasicBlock* join_block = llvm::BasicBlock::Create(g.context, "print", irstate->getLLVMFunction());
emitter.getBuilder()->CreateCondBr(dospace, ss_block, join_block);
curblock = ss_block;
emitter.getBuilder()->SetInsertPoint(ss_block);
CallattrFlags flags = {.cls_only = false, .null_on_nonexistent = false, .argspec = ArgPassSpec(1) };
auto r = dest->callattr(emitter, getOpInfoForNode(node, unw_info), write_str, flags, { makeStr(space_str) },
NULL);
r->decvref(emitter);
emitter.getBuilder()->CreateBr(join_block);
curblock = join_block;
emitter.getBuilder()->SetInsertPoint(join_block);
// end code for handling of softspace
llvm::Value* v = emitter.createCall(unw_info, g.funcs.strOrUnicode, converted->getValue());
v = emitter.getBuilder()->CreateBitCast(v, g.llvm_value_type_ptr);
auto s = new ConcreteCompilerVariable(STR, v, true);
r = dest->callattr(emitter, getOpInfoForNode(node, unw_info), write_str, flags, { s }, NULL);
s->decvref(emitter);
r->decvref(emitter);
converted->decvref(emitter);
} else {
converted = new ConcreteCompilerVariable(UNKNOWN, getNullPtr(g.llvm_value_type_ptr), true);
}
if (node->nl) {
CallattrFlags flags = {.cls_only = false, .null_on_nonexistent = false, .argspec = ArgPassSpec(1) };
auto r = dest->callattr(emitter, getOpInfoForNode(node, unw_info), write_str, flags,
{ makeStr(newline_str) }, NULL);
r->decvref(emitter);
if (nvals == 0) {
emitter.createCall(unw_info, g.funcs.softspace, { dest->getValue(), getConstantInt(0, g.i1) });
}
}
emitter.createCall3(unw_info, g.funcs.printHelper, dest->getValue(), converted->getValue(),
getConstantInt(node->nl, g.i1));
dest->decvref(emitter);
converted->decvref(emitter);
}
void doReturn(AST_Return* node, const UnwindInfo& unw_info) {
......
......@@ -240,6 +240,7 @@ void initGlobalFuncs(GlobalState& g) {
GET(assertFailDerefNameDefined);
GET(assertFail);
GET(printExprHelper);
GET(printHelper);
GET(printFloat);
GET(listAppendInternal);
......
......@@ -42,7 +42,7 @@ struct GlobalFuncs {
llvm::Value* unpackIntoArray, *raiseAttributeError, *raiseAttributeErrorStr, *raiseAttributeErrorCapi,
*raiseAttributeErrorStrCapi, *raiseNotIterableError, *raiseIndexErrorStr, *raiseIndexErrorStrCapi,
*assertNameDefined, *assertFail, *assertFailDerefNameDefined, *printExprHelper;
*assertNameDefined, *assertFail, *assertFailDerefNameDefined, *printExprHelper, *printHelper;
llvm::Value* printFloat, *listAppendInternal, *getSysStdout;
ExceptionSwitchable<llvm::Value*> runtimeCall0, runtimeCall1, runtimeCall2, runtimeCall3, runtimeCall, runtimeCallN;
ExceptionSwitchable<llvm::Value*> callattr0, callattr1, callattr2, callattr3, callattr, callattrN;
......
......@@ -113,6 +113,7 @@ void force() {
FORCE(assertFailDerefNameDefined);
FORCE(assertFail);
FORCE(printExprHelper);
FORCE(printHelper);
FORCE(strOrUnicode);
FORCE(printFloat);
......
......@@ -222,6 +222,9 @@ extern "C" void printHelper(Box* dest, Box* var, bool nl) {
static BoxedString* newline_str = internStringImmortal("\n");
static BoxedString* space_str = internStringImmortal(" ");
if (dest == None)
dest = getSysStdout();
if (var) {
// begin code for handling of softspace
bool new_softspace = !nl;
......@@ -229,11 +232,17 @@ extern "C" void printHelper(Box* dest, Box* var, bool nl) {
callattrInternal<CXX>(dest, write_str, CLASS_OR_INST, 0, ArgPassSpec(1), space_str, 0, 0, 0, 0);
Box* str_or_unicode_var = (var->cls == unicode_cls) ? var : str(var);
callattrInternal<CXX>(dest, write_str, CLASS_OR_INST, 0, ArgPassSpec(1), str_or_unicode_var, 0, 0, 0, 0);
Box* write_rtn
= callattrInternal<CXX>(dest, write_str, CLASS_OR_INST, 0, ArgPassSpec(1), str_or_unicode_var, 0, 0, 0, 0);
if (!write_rtn)
raiseAttributeError(dest, write_str->s());
}
if (nl) {
callattrInternal<CXX>(dest, write_str, CLASS_OR_INST, 0, ArgPassSpec(1), newline_str, 0, 0, 0, 0);
Box* write_rtn
= callattrInternal<CXX>(dest, write_str, CLASS_OR_INST, 0, ArgPassSpec(1), newline_str, 0, 0, 0, 0);
if (!write_rtn)
raiseAttributeError(dest, write_str->s());
if (!var)
softspace(dest, false);
}
......
......@@ -54,3 +54,9 @@ try:
assert 0, "expected TypeError was not thrown"
except TypeError:
pass
print >>None, "this should still print"
try:
print >>1, "this should error"
except AttributeError as e:
print e
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