Commit fd8cc825 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Misc things to get chaos.py working

reduce(), some float precision issues, string interpolation improvements
parent 3263a159
......@@ -1424,14 +1424,16 @@ public:
// Ugly, but for now special-case the set of type-pairs that we know will always work
if (exp_type == BinOp
&& ((cls == int_cls && rhs_cls == int_cls) || (cls == float_cls && rhs_cls == float_cls)
|| (cls == list_cls && rhs_cls == int_cls))) {
|| (cls == list_cls && rhs_cls == int_cls) || (cls == str_cls))) {
const std::string& left_side_name = getOpName(op_type);
ConcreteCompilerVariable* called_constant = tryCallattrConstant(
emitter, info, var, &left_side_name, true, ArgPassSpec(1, 0, 0, 0), { converted_rhs }, NULL, false);
if (called_constant)
if (called_constant) {
converted_rhs->decvref(emitter);
return called_constant;
}
}
}
......@@ -1588,7 +1590,7 @@ public:
CompilerVariable* binexp(IREmitter& emitter, const OpInfo& info, VAR* var, CompilerVariable* rhs,
AST_TYPE::AST_TYPE op_type, BinExpType exp_type) override {
ConcreteCompilerVariable* converted = var->makeConverted(emitter, UNKNOWN);
ConcreteCompilerVariable* converted = var->makeConverted(emitter, STR);
CompilerVariable* rtn = converted->binexp(emitter, info, rhs, op_type, exp_type);
converted->decvref(emitter);
return rtn;
......
......@@ -378,6 +378,25 @@ Box* map2(Box* f, Box* container) {
return rtn;
}
Box* reduce(Box* f, Box* container, Box* initial) {
Box* current = initial;
for (Box* e : container->pyElements()) {
assert(e);
if (current == NULL) {
current = e;
} else {
current = runtimeCall(f, ArgPassSpec(2), current, e, NULL, NULL, NULL);
}
}
if (current == NULL) {
raiseExcHelper(TypeError, "reduce() of empty sequence with no initial value");
}
return current;
}
Box* filter2(Box* f, Box* container) {
// If the filter-function argument is None, filter() works by only returning
// the elements that are truthy. This is equivalent to using the bool() constructor.
......@@ -720,6 +739,8 @@ void setupBuiltins() {
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("reduce",
new BoxedFunction(boxRTFunction((void*)reduce, UNKNOWN, 3, 1, false, false), { NULL }));
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("dir", new BoxedFunction(boxRTFunction((void*)dir, LIST, 1, 1, false, false), { NULL }));
......
......@@ -654,12 +654,20 @@ extern "C" int PyNumber_Check(PyObject*) {
Py_FatalError("unimplemented");
}
extern "C" PyObject* PyNumber_Add(PyObject*, PyObject*) {
Py_FatalError("unimplemented");
extern "C" PyObject* PyNumber_Add(PyObject* lhs, PyObject* rhs) {
try {
return binop(lhs, rhs, AST_TYPE::Add);
} catch (Box* b) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyNumber_Subtract(PyObject*, PyObject*) {
Py_FatalError("unimplemented");
extern "C" PyObject* PyNumber_Subtract(PyObject* lhs, PyObject* rhs) {
try {
return binop(lhs, rhs, AST_TYPE::Sub);
} catch (Box* b) {
Py_FatalError("unimplemented");
}
}
extern "C" PyObject* PyNumber_Multiply(PyObject* lhs, PyObject* rhs) {
......
......@@ -154,7 +154,7 @@ extern "C" Box* complexDivInt(BoxedComplex* lhs, BoxedInt* rhs) {
if (rhs->n == 0) {
raiseDivZeroExc();
}
return boxComplex(lhs->real / (float)rhs->n, lhs->imag / (float)rhs->n);
return boxComplex(lhs->real / (double)rhs->n, lhs->imag / (double)rhs->n);
}
extern "C" Box* complexDiv(BoxedComplex* lhs, Box* rhs) {
......
......@@ -331,7 +331,7 @@ extern "C" Box* intTruedivInt(BoxedInt* lhs, BoxedInt* rhs) {
if (rhs->n == 0) {
raiseExcHelper(ZeroDivisionError, "division by zero");
}
return boxFloat(lhs->n / (float)rhs->n);
return boxFloat(lhs->n / (double)rhs->n);
}
extern "C" Box* intTruedivFloat(BoxedInt* lhs, BoxedFloat* rhs) {
......@@ -731,7 +731,7 @@ void setupInt() {
_addFuncIntFloatUnknown("__sub__", (void*)intSubInt, (void*)intSubFloat, (void*)intSub);
_addFuncIntFloatUnknown("__div__", (void*)intDivInt, (void*)intDivFloat, (void*)intDiv);
_addFuncIntFloatUnknown("__floordiv__", (void*)intFloordivInt, (void*)intFloordivFloat, (void*)intFloordiv);
_addFuncIntFloatUnknown("__truediv__", (void*)intTruedivInt, (void*)intDivFloat, (void*)intTruediv);
_addFuncIntFloatUnknown("__truediv__", (void*)intTruedivInt, (void*)intTruedivFloat, (void*)intTruediv);
_addFuncIntFloatUnknown("__mul__", (void*)intMulInt, (void*)intMulFloat, (void*)intMul);
_addFuncIntUnknown("__mod__", BOXED_INT, (void*)intModInt, (void*)intMod);
_addFuncIntFloatUnknown("__pow__", (void*)intPowInt, (void*)intPowFloat, (void*)intPow);
......
......@@ -147,7 +147,26 @@ extern "C" Box* strMod(BoxedString* lhs, Box* rhs) {
BoxedString* s = str(val_to_use);
os << s->s;
break;
} else if (c == 'd') {
} else if (c == 'c') {
if (!val_to_use) {
RELEASE_ASSERT(elt_num < num_elts, "insufficient number of arguments for format string");
val_to_use = (*elts)[elt_num];
elt_num++;
}
RELEASE_ASSERT(val_to_use->cls == int_cls, "unsupported");
RELEASE_ASSERT(nspace == 0, "unsupported");
RELEASE_ASSERT(ndot == 0, "unsupported");
RELEASE_ASSERT(nzero == 0, "unsupported");
int64_t n = static_cast<BoxedInt*>(val_to_use)->n;
if (n < 0)
raiseExcHelper(OverflowError, "unsigned byte integer is less than minimum");
if (n >= 256)
raiseExcHelper(OverflowError, "unsigned byte integer is greater than maximum");
os << (char)n;
break;
} else if (c == 'd' || c == 'i') {
if (!val_to_use) {
RELEASE_ASSERT(elt_num < num_elts, "insufficient number of arguments for format string");
val_to_use = (*elts)[elt_num];
......
import operator
print reduce(operator.add, range(50))
print reduce(operator.add, range(40), 0)
print reduce(operator.add, "hello world")
print reduce(operator.add, "", 0)
def f(a, b):
print "f", a, b
return b
print reduce(f, "abc", 0)
print reduce(f, "abc")
try:
print reduce(f, [])
except TypeError, e:
print e
# expected: fail
# - can't pass exceptions through C API yet
# (TODO fold this into reduce.py once it works)
import operator
try:
print reduce(operator.add, "hello world", 0)
except TypeError, e:
print e
......@@ -8,3 +8,17 @@ print "%(a(b))s" % {'a(b)': 1}
# I'm not sure if this is a feature or a bug, but both CPython and PyPy will accept it:
print "%s %(a)s" % {'a': 1}
print "%c" % ord('A')
print repr("%c" % 255)
print repr("%c" % 0)
try:
print repr("%c" % -1)
except OverflowError, e:
print e
try:
print repr("%c" % 256)
except OverflowError, 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