Anonymous avatar Anonymous committed 63d87d9

Refactored classes and added polymorphic callsites

Comments (0)

Files changed (2)

codegen/classes.py

 
         self.branches = [
             (1.0, self.generate_monomorphic),
-#            (),
+            (1.0, self.generate_polymorphic),
         ]
 
     def get_iterable(self, literals):
 
 
     def generate_inline(self, literals):
+        branch = eval_branches(self.rng, self.branches)
+        return branch(literals)
+
+    def generate_class_function(self):
         c = self.create_class()
         self.module.content.insert(0, c)
 
         m = self.create_method(args)
 
         c.content.append(m)
+        return c, m
 
-        branch = eval_branches(self.rng, self.branches)
-        return branch(c, m, literals)
-        
 
+    def generate_monomorphic(self, literals):
+        """Generates a monomorphic callsite"""
+        c, m = self.generate_class_function()
 
-    def generate_monomorphic(self, c, m, literals):
         result = []
 
         class_var = self.next_variable()
         return result
 
 
+    def generate_polymorphic(self, literals, use_duck_typing=True):
+        """Generate a polymorphic callsite"""
+        c, m = self.generate_class_function()
+        c_super, m_super = self.generate_class_function()
+        m_super.name = m.name
 
+        # test duck typing and class polymorphism
+        if not use_duck_typing or self.rng.random() < 0.5:
+            c.super = [c_super.name]
+            if self.rng.random() < 0.5:
+                c.content.remove(m)
 
+        loop_var = self.next_variable()
+        iter = self.get_iterable(literals)
+
+        class_var = self.next_variable()
+        clause = self.rng.choice(list(literals)) + " < " + self.rng.choice(list(literals))
+        i = IfStatement(clause,
+            [Assignment(class_var, '=', [CallStatement(c, [])])],
+            [Assignment(class_var, '=', [CallStatement(c_super, [])])]
+        )
+        result = [i]
+
+        l = ForLoop(loop_var, iter)
+        result.append(l)
+        loop_literals = list(literals) + [loop_var]
+
+        args = [self.rng.choice(loop_literals) for i in m.args]
+        l.content.append(CallStatement(class_var + '.' + m.name, args))
+        return result
+
 from pygen.cgen import *
 from classes import ClassGenerator
 
-class Stats(object):
-    arg_number = 0
-    prog_size = 0
+class TStats(object):
+    def __init__(self):
+        self.arg_number = 0
+        self.func_number = 0
+        self.prog_size = 0
+
+class TModule(object):
+    def __init__(self):
+        self.content = []
 
 class TestClassesGenerator(unittest.TestCase):
 
     def codegen(self, l):
         result = []
         for line in l:
-            result.append(self.cgen.generate(line))
+            result.append(
+                self.cgen.generate(
+                    self.fgen.generate(line)
+                )
+            )
 
         return '\n'.join(result)
 
     def setUp(self):
         self.opts = {}
-        self.module = {}
-        self.stats = Stats()
+        self.module = TModule()
+        self.stats = TStats()
 
         self.gen = ClassGenerator(self.module, self.stats, self.opts)
 
-        self.c = Class('C1')
-        self.m = Method('M', ['a','b'])
-        self.c.content.append(self.m)
-
+        self.fgen = FixGenerator()
         self.cgen = CodeGenerator()
 
     def testMonomorphic(self):
-        result = self.gen.generate_monomorphic(self.c, self.m, ['1','1'])
-        result.insert(0, self.c)
+        result = self.gen.generate_monomorphic(['0', '1'])
+        result.extend(self.module.content)
 
         code = self.codegen(result)
 
         self.assert_('for' in code)
-        self.assert_('.M(' in code)
-        self.assert_('C1()' in code)
+        self.assert_('.func' in code)
+        self.assert_('= class' in code)
 
+    def testPolymorphic(self):
+        result = self.gen.generate_polymorphic(['0', '1'], use_duck_typing=False)
+        result.extend(self.module.content)
+
+        code = self.codegen(result)
+
+        self.assert_('for' in code)
+        self.assert_('.func' in code) # method call
+        self.assert_('= class' in code) # object instantiation
+        self.assert_('(class' in code) # inheritance
+
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.