[pypy-svn] r27669 - in pypy/dist/pypy/translator/cli: . src test
antocuni at codespeak.net
antocuni at codespeak.net
Thu May 25 16:42:26 CEST 2006
Author: antocuni
Date: Thu May 25 16:42:15 2006
New Revision: 27669
Modified:
pypy/dist/pypy/translator/cli/cts.py
pypy/dist/pypy/translator/cli/database.py
pypy/dist/pypy/translator/cli/ilgenerator.py
pypy/dist/pypy/translator/cli/record.py
pypy/dist/pypy/translator/cli/src/pypylib.cs
pypy/dist/pypy/translator/cli/test/runtest.py
pypy/dist/pypy/translator/cli/test/test_runtest.py
Log:
- Added support for tuple constants.
- Added support for function that return tuples in runtest.CliTest,
and some methods for compatibility with OORtypeMixin.
Modified: pypy/dist/pypy/translator/cli/cts.py
==============================================================================
--- pypy/dist/pypy/translator/cli/cts.py (original)
+++ pypy/dist/pypy/translator/cli/cts.py Thu May 25 16:42:15 2006
@@ -79,6 +79,8 @@
return 'void' # TODO: is it correct to ignore StaticMethod?
elif isinstance(t, ootype.List):
item_type = self.lltype_to_cts(t._ITEMTYPE)
+ if item_type == 'void': # special case: CLI doesn't allow List of void; use int instead
+ item_type = 'int32'
return self.__class(PYPY_LIST % item_type, include_class)
elif isinstance(t, ootype.Dict):
key_type = self.lltype_to_cts(t._KEYTYPE)
Modified: pypy/dist/pypy/translator/cli/database.py
==============================================================================
--- pypy/dist/pypy/translator/cli/database.py (original)
+++ pypy/dist/pypy/translator/cli/database.py Thu May 25 16:42:15 2006
@@ -68,7 +68,7 @@
return '%s.%s::%s' % (CONST_NAMESPACE, CONST_CLASS, name)
def gen_constants(self, ilasm):
- if not ilasm . show_const ():
+ if not ilasm.show_const():
return
ilasm.begin_namespace(CONST_NAMESPACE)
ilasm.begin_class(CONST_CLASS)
@@ -83,7 +83,7 @@
for const, name in self.consts.iteritems():
const.init(ilasm)
type_ = const.get_type()
- ilasm.set_static_field ( type_, CONST_NAMESPACE, CONST_CLASS, name )
+ ilasm.set_static_field (type_, CONST_NAMESPACE, CONST_CLASS, name)
ilasm.ret()
ilasm.end_function()
@@ -102,10 +102,31 @@
if isinstance(const, ootype._instance):
return InstanceConst(db, const, static_type)
+ elif isinstance(const, ootype._record):
+ return RecordConst(db, const)
else:
assert False, 'Unknown constant: %s' % const
make = staticmethod(make)
-
+
+ def load(db, TYPE, value, ilasm):
+ # TODO: code duplicated from function.py, refactoring needed
+ if TYPE is ootype.Void:
+ pass
+ elif TYPE is ootype.Bool:
+ ilasm.opcode('ldc.i4', str(int(value)))
+ elif TYPE is ootype.Float:
+ ilasm.opcode('ldc.r8', repr(value))
+ elif TYPE in (ootype.Signed, ootype.Unsigned):
+ ilasm.opcode('ldc.i4', str(value))
+ elif TYPE in (ootype.SignedLongLong, ootype.UnsignedLongLong):
+ ilasm.opcode('ldc.i8', str(value))
+ else:
+ cts = CTS(db)
+ name = db.record_const(value)
+ cts_type = cts.lltype_to_cts(TYPE)
+ ilasm.opcode('ldsfld %s %s' % (cts_type, name))
+ load = staticmethod(load)
+
def get_name(self):
pass
@@ -115,6 +136,34 @@
def init(self, ilasm):
pass
+class RecordConst(AbstractConst):
+ def __init__(self, db, record):
+ self.db = db
+ self.cts = CTS(db)
+ self.record = record
+
+ def __hash__(self):
+ return hash(self.record)
+
+ def __eq__(self, other):
+ return self.record == other.record
+
+ def get_name(self):
+ return 'Record'
+
+ def get_type(self):
+ return self.cts.lltype_to_cts(self.record._TYPE)
+
+ def init(self, ilasm):
+ class_name = self.record._TYPE._name
+ ilasm.new('instance void class %s::.ctor()' % class_name)
+ for f_name, (FIELD_TYPE, f_default) in self.record._TYPE._fields.iteritems():
+ f_type = self.cts.lltype_to_cts(FIELD_TYPE)
+ value = self.record._items[f_name]
+ ilasm.opcode('dup')
+ AbstractConst.load(self.db, FIELD_TYPE, value, ilasm)
+ ilasm.set_field((f_type, class_name, f_name))
+
class InstanceConst(AbstractConst):
def __init__(self, db, obj, static_type):
self.cts = CTS(db)
Modified: pypy/dist/pypy/translator/cli/ilgenerator.py
==============================================================================
--- pypy/dist/pypy/translator/cli/ilgenerator.py (original)
+++ pypy/dist/pypy/translator/cli/ilgenerator.py Thu May 25 16:42:15 2006
@@ -143,7 +143,7 @@
def set_field(self, field_data ):
self.opcode('stfld %s %s::%s' % field_data )
- def get_field(self,field_data):
+ def get_field(self, field_data):
self.opcode('ldfld %s %s::%s' % field_data )
def load_set_field(self, cts_type, name):
@@ -158,7 +158,7 @@
def ret(self):
self.opcode('ret')
- def castclass(self,cts_type):
+ def castclass(self, cts_type):
self.opcode('castclass', cts_type)
def load_self(self):
Modified: pypy/dist/pypy/translator/cli/record.py
==============================================================================
--- pypy/dist/pypy/translator/cli/record.py (original)
+++ pypy/dist/pypy/translator/cli/record.py Thu May 25 16:42:15 2006
@@ -11,8 +11,8 @@
trans = string.maketrans('<>(), ', '______')
name = ['Record']
- for f_name, (f_type, f_default) in record._fields.iteritems():
- type_name = f_type._short_name().translate(trans)
+ for f_name, (FIELD_TYPE, f_default) in record._fields.iteritems():
+ type_name = FIELD_TYPE._short_name().translate(trans)
name.append(type_name)
self.name = '__'.join(name)
record._name = self.name
@@ -36,12 +36,13 @@
self.ilasm = ilasm
ilasm.begin_class(self.name, self.get_base_class())
- for f_name, (f_type, f_default) in self.record._fields.iteritems():
- cts_type = self.cts.lltype_to_cts(f_type)
+ for f_name, (FIELD_TYPE, f_default) in self.record._fields.iteritems():
+ cts_type = self.cts.lltype_to_cts(FIELD_TYPE)
if cts_type != 'void':
ilasm.field(f_name, cts_type)
self._ctor()
+ self._toString()
ilasm.end_class()
self.db.record_class(self.record, self.name)
@@ -53,3 +54,25 @@
self.ilasm.opcode('ret')
self.ilasm.end_function()
+ def _toString(self):
+ # only for testing purposes, and only if the Record represents a tuple
+ from pypy.translator.cli.test.runtest import format_object
+
+ for f_name in self.record._fields:
+ if not f_name.startswith('item'):
+ return # it's not a tuple
+
+ self.ilasm.begin_function('ToString', [], 'string', False, 'virtual', 'instance', 'default')
+ self.ilasm.opcode('ldstr', '""')
+ for i in xrange(len(self.record._fields)):
+ f_name = 'item%d' % i
+ FIELD_TYPE, f_default = self.record._fields[f_name]
+ self.ilasm.opcode('ldarg.0')
+ f_type = self.cts.lltype_to_cts(FIELD_TYPE)
+ self.ilasm.get_field((f_type, self.name, f_name))
+ format_object(FIELD_TYPE, self.ilasm)
+ self.ilasm.call('string string::Concat(string, string)')
+ self.ilasm.opcode('ldstr ", "')
+ self.ilasm.call('string string::Concat(string, string)')
+ self.ilasm.opcode('ret')
+ self.ilasm.end_function()
Modified: pypy/dist/pypy/translator/cli/src/pypylib.cs
==============================================================================
--- pypy/dist/pypy/translator/cli/src/pypylib.cs (original)
+++ pypy/dist/pypy/translator/cli/src/pypylib.cs Thu May 25 16:42:15 2006
@@ -9,16 +9,6 @@
public static string ToPython(bool x) { return x.ToString(); }
public static string ToPython(double x) { return x.ToString(); }
public static string ToPython(char x) { return string.Format("'{0}'", x); }
-
- public static string ToPython<T>(pypy.runtime.List<T> lst)
- {
- // TODO: use StringBuilder instead
- string res = "[";
- foreach(T item in lst)
- res += item.ToString() + ","; // XXX: only works for int, bool and double
- res += "]";
- return res;
- }
}
}
@@ -37,6 +27,16 @@
// rpython.ootypesystem.ootype.List.GENERIC_METHODS
public class List<T>: System.Collections.Generic.List<T>
{
+ public override string ToString()
+ {
+ // TODO: use StringBuilder instead
+ string res = "[";
+ foreach(T item in this)
+ res += item.ToString() + ","; // XXX: doesn't work for chars
+ res += "]";
+ return res;
+ }
+
public int ll_length()
{
return this.Count;
Modified: pypy/dist/pypy/translator/cli/test/runtest.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/runtest.py (original)
+++ pypy/dist/pypy/translator/cli/test/runtest.py Thu May 25 16:42:15 2006
@@ -33,6 +33,14 @@
else:
assert res1 == res2
+def format_object(TYPE, ilasm):
+ if isinstance(TYPE, ootype.BuiltinType):
+ ilasm.call_method('string object::ToString()', virtual=True)
+ else:
+ type_ = cts.lltype_to_cts(TYPE)
+ ilasm.call('string class [pypylib]pypy.test.Result::ToPython(%s)' % type_)
+
+
class TestEntryPoint(Node):
"""
This class produces a 'main' method that converts its arguments
@@ -61,22 +69,13 @@
ilasm.call(cts.graph_to_signature(self.graph))
# convert result to a string containing a valid python expression
- var = self.graph.getreturnvar()
- ilasm.call('string class [pypylib]pypy.test.Result::%s' %
- self.__output_method(var.concretetype))
+ TYPE = self.graph.getreturnvar().concretetype
+ format_object(TYPE, ilasm)
ilasm.call('void class [mscorlib]System.Console::WriteLine(string)')
ilasm.opcode('ret')
ilasm.end_function()
self.db.pending_function(self.graph)
- def __output_method(self, TYPE):
- if isinstance(TYPE, ootype.List):
- item_type = cts.lltype_to_cts(TYPE._ITEMTYPE)
- return 'ToPython<%s> (class [pypylib]pypy.runtime.List`1<!!0>)' % item_type
- else:
- type_ = cts.lltype_to_cts(TYPE)
- return 'ToPython(%s)' % type_
-
def __convert_method(self, arg_type):
_conv = {
'int32': 'ToInt32',
@@ -156,17 +155,18 @@
retval = mono.wait()
assert retval == 0, stderr
- return eval(stdout)
-## ret_type, ret_var = cts.llvar_to_cts(self.graph.getreturnvar())
-## if 'int' in ret_type:
-## return int(stdout)
-## elif ret_type == 'float64':
-## return float(stdout)
-## elif ret_type == 'bool':
-## return stdout.strip().lower() == 'true'
-## else:
-## assert False, 'Return type %s is not supported' % ret_type
-
+ res = eval(stdout)
+ if isinstance(res, tuple):
+ res = StructTuple(res) # so tests can access tuple elements with .item0, .item1, etc.
+ return res
+
+class StructTuple(tuple):
+ def __getattr__(self, name):
+ if name.startswith('item'):
+ i = int(name[len('item'):])
+ return self[i]
+ else:
+ raise AttributeError, name
class CliTest(BaseRtypingTest, OORtypeMixin):
def interpret(self, fn, args):
@@ -177,3 +177,11 @@
def interpret_raises(exc, func, args):
py.test.skip("CLI tests don't support interpret_raises")
+ def ll_to_string(self, s):
+ py.test.skip('ll_to_string not supported, yet')
+
+ def ll_to_list(self, l):
+ return l
+
+ def class_name(self, value):
+ py.test.skip('class_name not supported, yet')
Modified: pypy/dist/pypy/translator/cli/test/test_runtest.py
==============================================================================
--- pypy/dist/pypy/translator/cli/test/test_runtest.py (original)
+++ pypy/dist/pypy/translator/cli/test/test_runtest.py Thu May 25 16:42:15 2006
@@ -25,3 +25,8 @@
def fn():
return [1, 2, 3]
assert self.interpret(fn, []) == [1, 2, 3]
+
+ def test_tuple(self):
+ def fn():
+ return 1, 2
+ assert self.interpret(fn, []) == (1, 2)
More information about the Pypy-commit
mailing list