diff python/c3/typecheck.py @ 220:3f6c30a5d234

Major change in expression parsing to enable pointers and structs
author Windel Bouwman
date Sat, 06 Jul 2013 21:32:20 +0200
parents c1ccb1cb4cef
children 848c4b15fd0b
line wrap: on
line diff
--- a/python/c3/typecheck.py	Sat Jul 06 12:38:09 2013 +0200
+++ b/python/c3/typecheck.py	Sat Jul 06 21:32:20 2013 +0200
@@ -7,28 +7,34 @@
    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
 
 class TypeChecker:
-   def __init__(self, diag):
-      self.diag = diag
-   def error(self, msg, loc):
+    def __init__(self, diag):
+        self.diag = diag
+
+    def error(self, msg, loc):
         """ Wrapper that registers the message and marks the result invalid """
         self.diag.error(msg, loc)
         self.ok = False
-   def checkPackage(self, pkg):
+
+    def checkPackage(self, pkg):
         self.ok = True
         visitor = Visitor()
         visitor.visit(pkg, f_post=self.check2)
         return self.ok
-   def check2(self, sym):
-      if type(sym) is Function:
-         pass
-      elif type(sym) in [IfStatement, WhileStatement]:
+
+    def check2(self, sym):
+      if type(sym) in [IfStatement, WhileStatement]:
          if not equalTypes(sym.condition.typ, boolType):
             self.error('Condition must be of type {0}'.format(boolType), sym.condition.loc)
       elif type(sym) is Assignment:
-         if not equalTypes(sym.lval.typ, sym.rval.typ):
+         if type(sym.lval.typ) is PointerType and sym.rval.typ == intType:
+            print('special case, int to pointer is ok for now')
+            # TODO: add cast instruction?
+         elif not equalTypes(sym.lval.typ, sym.rval.typ):
             self.error('Cannot assign {0} to {1}'.format(sym.rval.typ, sym.lval.typ), sym.loc)
       elif type(sym) is ReturnStatement:
          pass
@@ -62,6 +68,17 @@
             sym.typ = boolType
          else:
             self.error('Unknown literal type', sym.loc)
+      elif type(sym) is Unop:
+            if sym.op == '&':
+                sym.typ = PointerType(sym.a.typ)
+            elif sym.op == '*':
+                # pointer deref
+                if type(sym.a.typ) is PointerType:
+                    sym.typ = sym.a.typ.ptype
+                else:
+                    self.error('Cannot dereference non-pointer type {}'.format(sym.a.typ), sym.loc)
+            else:
+                print('unknown unop', sym.op)
       elif type(sym) is Binop:
          if sym.op in ['+', '-', '*', '/']:
             if equalTypes(sym.a.typ, sym.b.typ):
@@ -94,7 +111,6 @@
       elif type(sym) is Constant:
          if not equalTypes(sym.typ, sym.value.typ):
             self.error('Cannot assign {0} to {1}'.format(sym.value.typ, sym.typ), sym.loc)
-         
       elif type(sym) in [EmptyStatement, CompoundStatement, Package, Function, FunctionType]:
          pass
       else: