changeset 226:240111e0456f

Work on named types
author Windel Bouwman
date Fri, 12 Jul 2013 17:25:31 +0200
parents 1c7364bd74c7
children 82dfe6a32717
files python/c3/analyse.py python/c3/astnodes.py python/c3/builder.py python/c3/parser.py python/c3/typecheck.py
diffstat 5 files changed, 51 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/python/c3/analyse.py	Thu Jul 11 07:42:30 2013 +0200
+++ b/python/c3/analyse.py	Fri Jul 12 17:25:31 2013 +0200
@@ -78,8 +78,13 @@
         if type(t) is PointerType:
             t.ptype = self.resolveType(t.ptype, scope)
             return t
+        elif type(t) is StructureType:
+            for mem in t.mems:
+                mem.typ = self.resolveType(mem.typ, scope)
+            return t
         elif type(t) is Designator:
-            return self.resolveDesignator(t, scope)
+            t = self.resolveDesignator(t, scope)
+            return self.resolveType(t)
         elif isinstance(t, Type):
             # Already resolved??
             return t
@@ -101,6 +106,8 @@
             ft = sym.typ
             ft.returntype = self.resolveType(ft.returntype, sym.scope)
             ft.parametertypes = [self.resolveType(pt, sym.scope) for pt in ft.parametertypes]
+        elif type(sym) is DefinedType:
+            sym.typ = self.resolveType(sym.typ, sym.scope)
 
     def sanity(self, sym):
         if type(sym) is FunctionType:
--- a/python/c3/astnodes.py	Thu Jul 11 07:42:30 2013 +0200
+++ b/python/c3/astnodes.py	Fri Jul 12 17:25:31 2013 +0200
@@ -67,13 +67,15 @@
 class StructureType(Type):
     def __init__(self, mems):
         self.mems = mems
+        for ft, fn in mems:
+            assert type(fn) is str
     def hasField(self, name):
-        for fn, ft in self.mems:
+        for ft, fn in self.mems:
             if name == fn:
                 return True
         return False
     def fieldType(self, name):
-        for fn, ft in self.mems:
+        for ft, fn in self.mems:
             if name == fn:
                 return ft
         raise Exception()
--- a/python/c3/builder.py	Thu Jul 11 07:42:30 2013 +0200
+++ b/python/c3/builder.py	Fri Jul 12 17:25:31 2013 +0200
@@ -8,25 +8,24 @@
         Reports errors to the diagnostics system
     """
     def __init__(self, diag):
-      self.diag = diag
-      self.parser = Parser(diag)
-      self.tc = TypeChecker(diag)
-      self.al = Analyzer(diag)
-      self.cg = CodeGenerator()
+        self.diag = diag
+        self.parser = Parser(diag)
+        self.tc = TypeChecker(diag)
+        self.al = Analyzer(diag)
+        self.cg = CodeGenerator()
     def build(self, src):
-      """ Create IR-code from sources """
-      pkg = self.parser.parseSource(src)
-      if not pkg:
+        """ Create IR-code from sources """
+        pkg = self.parser.parseSource(src)
+        if not pkg:
             return
-      self.pkg = pkg
-      # TODO: merge the two below?
-      #AstPrinter().printAst(pkg)
-      if not self.al.analyzePackage(pkg):
+        self.pkg = pkg
+        # TODO: merge the two below?
+        #AstPrinter().printAst(pkg)
+        if not self.al.analyzePackage(pkg):
             return
-      if not self.tc.checkPackage(pkg):
+        if not self.tc.checkPackage(pkg):
             return
 
-      # Only return ircode when everything is OK
-      ircode = self.cg.gencode(pkg)
-      return ircode
+        # Only return ircode when everything is OK
+        return self.cg.gencode(pkg)
 
--- a/python/c3/parser.py	Thu Jul 11 07:42:30 2013 +0200
+++ b/python/c3/parser.py	Fri Jul 12 17:25:31 2013 +0200
@@ -89,10 +89,10 @@
             mems = []
             while self.Peak != '}':
                 mem_t = self.parseTypeSpec()
-                mem_n = self.Consume('ID')
+                mem_n = self.Consume('ID').val
                 mems.append((mem_t, mem_n))
                 while self.hasConsumed(','):
-                    mem_n = self.Consume('ID')
+                    mem_n = self.Consume('ID').val
                     mems.append((mem_t, mem_n))
                 self.Consume(';')
             self.Consume('}')
--- a/python/c3/typecheck.py	Thu Jul 11 07:42:30 2013 +0200
+++ b/python/c3/typecheck.py	Fri Jul 12 17:25:31 2013 +0200
@@ -3,13 +3,19 @@
 from .visitor import Visitor
 
 def equalTypes(a, b):
-   """ Compare types a and b for equality. Not equal until proven otherwise. """
-   if type(a) is type(b):
-      if type(a) is BaseType:
-         return a.name == b.name
-      elif type(a) is PointerType:
-        return equalTypes(a.ptype, b.ptype)
-   return False
+    """ Compare types a and b for equality. Not equal until proven otherwise. """
+    # Recurse into named types:
+    if type(a) is DefinedType:
+        return equalTypes(a.typ, b)
+    if type(b) is DefinedType:
+        return equalTypes(a, b.typ)
+    # Compare for structural equivalence:
+    if type(a) is type(b):
+        if type(a) is BaseType:
+            return a.name == b.name
+        elif type(a) is PointerType:
+            return equalTypes(a.ptype, b.ptype)
+    return False
 
 def canCast(fromT, toT):
     if isinstance(fromT, PointerType) and isinstance(toT, PointerType):
@@ -89,19 +95,24 @@
             # pointer deref
             sym.lvalue = True
             # check if the to be dereferenced variable is a pointer type:
-            if type(sym.ptr.typ) is PointerType:
-                sym.typ = sym.ptr.typ.ptype
+            ptype = sym.ptr.typ
+            if type(ptype) is DefinedType:
+                ptype = ptype.typ
+            if type(ptype) is PointerType:
+                sym.typ = ptype.ptype
             else:
-                self.error('Cannot dereference non-pointer type {}'.format(sym.ptr.typ), sym.loc)
+                self.error('Cannot dereference non-pointer type {}'.format(ptype), sym.loc)
                 sym.typ = intType
         elif type(sym) is FieldRef:
             basetype = sym.base.typ
             sym.lvalue = True
+            if type(basetype) is DefinedType:
+                basetype = basetype.typ
             if type(basetype) is StructureType:
                 if basetype.hasField(sym.field):
                     sym.typ = basetype.fieldType(sym.field)
                 else:
-                    self.error('{} does not contain field {}'.format(basetype, symfield), sym.loc)
+                    self.error('{} does not contain field {}'.format(basetype, sym.field), sym.loc)
                     sym.typ = intType
             else:
                 self.error('Cannot select field {} of non-structure type {}'.format(sym.field, basetype), sym.loc)