diff python/c3/semantics.py @ 150:4ae0e02599de

Added type check start and analyze phase
author Windel Bouwman
date Fri, 01 Mar 2013 16:53:22 +0100
parents 74241ca312cc
children b73bc14a3aa3
line wrap: on
line diff
--- a/python/c3/semantics.py	Fri Mar 01 11:43:52 2013 +0100
+++ b/python/c3/semantics.py	Fri Mar 01 16:53:22 2013 +0100
@@ -1,46 +1,49 @@
 from . import astnodes
-
-class Scope:
-   """ A scope contains all symbols in a scope """
-   def __init__(self, parent=None):
-      self.symbols = {}
-      self.parent = parent
-   def __iter__(self):
-      return iter(self.symbols.values())
-   def getType(self, name):
-      t = self.getSymbol(name)
-      print(t)
-      assert isinstance(t, astnodes.Type)
-      return t
-   def getSymbol(self, name):
-      if name in self.symbols:
-         return self.symbols[name]
-      # Look for symbol:
-      if self.parent:
-         return self.parent.getSymbol(name)
-      raise CompilerException("Symbol {0} not found".format(name), name.loc)
-   def hasSymbol(self, name):
-      if name in self.symbols:
-         return True
-      if self.parent:
-         return self.parent.hasSymbol(name)
-      return False
-      
-   def addSymbol(self, sym):
-      self.symbols[sym.name] = sym
-
-def createBuiltins(scope):
-   scope.addSymbol(astnodes.BaseType('int'))
+from .scope import Scope, topScope
+from ppci.errors import CompilerException
 
 class Semantics:
    """ This class constructs the AST from parser input """
    def __init__(self, diag):
       self.diag = diag
+   def addSymbol(self, s):
+      if self.curScope.hasSymbol(s.name):
+         msg = 'Redefinition of {0}'.format(s.name)
+         self.diag.diag(CompilerException(msg, s.loc))
+      else:
+         self.curScope.addSymbol(s)
    def handlePackage(self, name, loc):
       self.mod = astnodes.Package(name)
       self.mod.loc = loc
-      self.mod.scope = self.curScope = Scope()
-      createBuiltins(self.curScope)
+      self.mod.scope = self.curScope = Scope(topScope)
+   def actOnVarDef(self, name, loc, t, ival):
+      s = astnodes.Variable(name, t)
+      s.loc = loc
+      self.addSymbol(s)
+   def actOnFuncDef1(self, name, loc):
+      self.curFunc = astnodes.Function(name)
+      self.curFunc.loc = loc
+      self.addSymbol(self.curFunc)
+      self.curScope = self.curFunc.scope = Scope(self.curScope)
+   def actOnParameter(self, name, loc, t):
+      p = astnodes.Variable(name, t)
+      p.loc = loc
+      p.parameter = True
+      self.addSymbol(p)
+      return p
+   def actOnFuncDef2(self, parameters, returntype, body):
+      self.curFunc.body = body
+      self.curFunc.typ = astnodes.FunctionType(parameters, returntype)
+      self.curFunc = None
+      self.curScope = self.curScope.parent
+   def actOnType(self, tok):
+      # Try to lookup type, in case of failure return void
+      pass
+   def actOnDesignator(self, tname, loc):
+      d = astnodes.Designator(tname)
+      d.scope = self.curScope
+      d.loc = loc
+      return d
    def actOnBinop(self, lhs, op, rhs, loc):
       bo = astnodes.Binop(lhs, op, rhs)
       bo.loc = loc
@@ -49,21 +52,6 @@
       n = astnodes.Constant(num)
       n.loc = loc
       return n
-   def actOnVarDef(self, name, loc, t, ival):
-      s = astnodes.Variable(name, t)
-      s.loc = loc
-      self.curScope.addSymbol(s)
-   def actOnFuncDef1(self, name, loc):
-      self.curFunc = astnodes.Procedure(name)
-      self.curFunc.loc = loc
-      self.curScope.addSymbol(self.curFunc)
-      self.curScope = self.curFunc.scope = Scope(self.curScope)
-   def actOnFuncDef2(self, parameters, returntype, body):
-      self.curFunc.body = body
-      self.curFunc.typ = astnodes.FunctionType(parameters, returntype)
-      self.curFunc = None
-      self.curScope = self.curScope.parent
-   def actOnType(self, tok):
-      # Try to lookup type, in case of failure return void
-      pass
+   def actOnVariableUse(self, d):
+      return astnodes.VariableUse(d)