Actually output PyLong constants

This commit is contained in:
Michael Hansen
2011-09-23 21:46:05 -07:00
parent df8db4da3c
commit 6a93c9f22d
4 changed files with 51 additions and 0 deletions

View File

@@ -243,6 +243,9 @@ void print_const(PycRef<PycObject> obj, PycModule* mod)
case PycObject::TYPE_INT:
printf("%d", obj.cast<PycInt>()->value());
break;
case PycObject::TYPE_LONG:
printf("%s", obj.cast<PycLong>()->repr().c_str());
break;
case PycObject::TYPE_FLOAT:
printf("%s", obj.cast<PycFloat>()->value());
break;

View File

@@ -47,6 +47,48 @@ bool PycLong::isEqual(PycRef<PycObject> obj) const
return true;
}
std::string PycLong::repr() const
{
// Longs are printed as hex, since it's easier (and faster) to convert
// arbitrary-length integers to a power of two than an arbitrary base
if (m_size == 0)
return "0x0L";
// Realign to 32 bits, since Python uses only 15
std::list<unsigned> bits;
std::list<int>::const_iterator bit;
int shift = 0, temp = 0;
for (bit = m_value.begin(); bit != m_value.end(); ++bit) {
temp |= *bit << shift;
shift += 15;
if (shift >= 32) {
bits.push_back(temp);
shift -= 32;
temp = *bit >> (15 - shift);
}
}
if (temp)
bits.push_back(temp);
std::string accum;
accum.resize(3 + (bits.size() * 8) + 2);
char* aptr = &accum[0];
if (m_size < 0)
*aptr++ = '-';
*aptr++ = '0';
*aptr++ = 'x';
std::list<unsigned>::const_reverse_iterator iter = bits.rbegin();
aptr += snprintf(aptr, 9, "%X", *iter++);
while (iter != bits.rend())
aptr += snprintf(aptr, 9, "%08X", *iter++);
*aptr++ = 'L';
*aptr++ = 0;
return accum;
}
/* PycFloat */
void PycFloat::load(PycData* stream, PycModule*)

View File

@@ -3,6 +3,7 @@
#include "object.h"
#include <list>
#include <string>
class PycInt : public PycObject {
public:
@@ -35,6 +36,8 @@ public:
int size() const { return m_size; }
const std::list<int>& value() const { return m_value; }
std::string repr() const;
private:
int m_size;
std::list<int> m_value;

View File

@@ -178,6 +178,9 @@ void output_object(PycRef<PycObject> obj, PycModule* mod, int indent)
case PycObject::TYPE_INT:
iprintf(indent, "%d\n", obj.cast<PycInt>()->value());
break;
case PycObject::TYPE_LONG:
iprintf(indent, "%s\n", obj.cast<PycLong>()->repr().c_str());
break;
case PycObject::TYPE_FLOAT:
iprintf(indent, "%s\n", obj.cast<PycFloat>()->value());
break;