xcbgen-parser: support switch-case
authorChristian Linhart <chris@demorecorder.com>
Tue, 19 Aug 2014 13:55:33 +0000 (15:55 +0200)
committerPeter Harris <pharris@opentext.com>
Mon, 25 Aug 2014 23:39:31 +0000 (19:39 -0400)
"case" is implemented as a variation of "bitcase" as follows:

The old class "BitCaseType" became the abstract class
"CaseOrBitcaseType" with two derived classes
"CaseType" and "BitcaseType".
(Therefore BitcaseType keeps the old semantic which may
be important for some generators)

There are two additional flags in class Type:
* is_case
* is_case_or_bitcase
The latter is for convenience because case and bitcase
have to be treated the same way in many cases.

The list of cases and bitcases in a SwitchType object
is still called "bitcases".
Reasons:
* Renaming that list would break generators based on the parser.
* Creating an extra list for cases would make other code more
  complicated because you usually want to iterate over all
  case and bitcase members of a switch.

Reviewed-by: Ran Benita <ran234@gmail.com>
xcbgen/expr.py
xcbgen/xtypes.py

index f9d5179..e4fb06e 100644 (file)
@@ -120,7 +120,7 @@ class Expression(object):
             for p in reversed(parents): 
                 fields = dict([(f.field_name, f) for f in p.fields])
                 if self.lenfield_name in fields.keys():
-                    if p.is_bitcase:
+                    if p.is_case_or_bitcase:
                         # switch is the anchestor 
                         self.lenfield_parent = p.parents[-1]
                     else:
index 3cd9032..45d7568 100644 (file)
@@ -33,7 +33,9 @@ class Type(object):
         self.is_union = False
         self.is_pad = False
         self.is_switch = False
+        self.is_case_or_bitcase = False
         self.is_bitcase = False
+        self.is_case = False
 
     def resolve(self, module):
         '''
@@ -405,16 +407,20 @@ class SwitchType(ComplexType):
 
         # Resolve all of our field datatypes.
         for index, child in enumerate(list(self.elt)):
-            if child.tag == 'bitcase':
+            if child.tag == 'bitcase' or child.tag == 'case':
                 field_name = child.get('name')
                 if field_name is None:
-                    field_type = self.name + ('bitcase%d' % index,)
+                    field_type = self.name + ('%s%d' % ( child.tag, index ),)
                 else:
                     field_type = self.name + (field_name,)
 
                 # use self.parent to indicate anchestor, 
                 # as switch does not contain named fields itself
-                type = BitcaseType(index, field_type, child, *parents)
+                if child.tag == 'bitcase':
+                    type = BitcaseType(index, field_type, child, *parents)
+                else:
+                    type = CaseType(index, field_type, child, *parents)
+
                 # construct the switch type name from the parent type and the field name
                 if field_name is None:
                     type.has_name = False
@@ -497,9 +503,9 @@ class Union(ComplexType):
     out = __main__.output['union']
 
 
-class BitcaseType(ComplexType):
+class CaseOrBitcaseType(ComplexType):
     '''
-    Derived class representing a struct data type.
+    Derived class representing a case or bitcase.
     '''
     def __init__(self, index, name, elt, *parent):
         elts = list(elt)
@@ -515,7 +521,7 @@ class BitcaseType(ComplexType):
         self.index = 1
         self.lenfield_parent = list(parent) + [self]
         self.parents = list(parent)
-        self.is_bitcase = True
+        self.is_case_or_bitcase = True
 
     def make_member_of(self, module, switch_type, field_type, field_name, visible, wire, auto, enum=None):
         '''
@@ -546,6 +552,23 @@ class BitcaseType(ComplexType):
         ComplexType.resolve(self, module)
 
 
+class BitcaseType(CaseOrBitcaseType):
+    '''
+    Derived class representing a bitcase.
+    '''
+    def __init__(self, index, name, elt, *parent):
+        CaseOrBitcaseType.__init__(self, index, name, elt, *parent)
+        self.is_bitcase = True
+
+class CaseType(CaseOrBitcaseType):
+    '''
+    Derived class representing a case.
+    '''
+    def __init__(self, index, name, elt, *parent):
+        CaseOrBitcaseType.__init__(self, index, name, elt, *parent)
+        self.is_case = True
+
+
 class Reply(ComplexType):
     '''
     Derived class representing a reply.  Only found as a field of Request.