comparison 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
comparison
equal deleted inserted replaced
149:74241ca312cc 150:4ae0e02599de
1 from . import astnodes 1 from . import astnodes
2 2 from .scope import Scope, topScope
3 class Scope: 3 from ppci.errors import CompilerException
4 """ A scope contains all symbols in a scope """
5 def __init__(self, parent=None):
6 self.symbols = {}
7 self.parent = parent
8 def __iter__(self):
9 return iter(self.symbols.values())
10 def getType(self, name):
11 t = self.getSymbol(name)
12 print(t)
13 assert isinstance(t, astnodes.Type)
14 return t
15 def getSymbol(self, name):
16 if name in self.symbols:
17 return self.symbols[name]
18 # Look for symbol:
19 if self.parent:
20 return self.parent.getSymbol(name)
21 raise CompilerException("Symbol {0} not found".format(name), name.loc)
22 def hasSymbol(self, name):
23 if name in self.symbols:
24 return True
25 if self.parent:
26 return self.parent.hasSymbol(name)
27 return False
28
29 def addSymbol(self, sym):
30 self.symbols[sym.name] = sym
31
32 def createBuiltins(scope):
33 scope.addSymbol(astnodes.BaseType('int'))
34 4
35 class Semantics: 5 class Semantics:
36 """ This class constructs the AST from parser input """ 6 """ This class constructs the AST from parser input """
37 def __init__(self, diag): 7 def __init__(self, diag):
38 self.diag = diag 8 self.diag = diag
9 def addSymbol(self, s):
10 if self.curScope.hasSymbol(s.name):
11 msg = 'Redefinition of {0}'.format(s.name)
12 self.diag.diag(CompilerException(msg, s.loc))
13 else:
14 self.curScope.addSymbol(s)
39 def handlePackage(self, name, loc): 15 def handlePackage(self, name, loc):
40 self.mod = astnodes.Package(name) 16 self.mod = astnodes.Package(name)
41 self.mod.loc = loc 17 self.mod.loc = loc
42 self.mod.scope = self.curScope = Scope() 18 self.mod.scope = self.curScope = Scope(topScope)
43 createBuiltins(self.curScope) 19 def actOnVarDef(self, name, loc, t, ival):
20 s = astnodes.Variable(name, t)
21 s.loc = loc
22 self.addSymbol(s)
23 def actOnFuncDef1(self, name, loc):
24 self.curFunc = astnodes.Function(name)
25 self.curFunc.loc = loc
26 self.addSymbol(self.curFunc)
27 self.curScope = self.curFunc.scope = Scope(self.curScope)
28 def actOnParameter(self, name, loc, t):
29 p = astnodes.Variable(name, t)
30 p.loc = loc
31 p.parameter = True
32 self.addSymbol(p)
33 return p
34 def actOnFuncDef2(self, parameters, returntype, body):
35 self.curFunc.body = body
36 self.curFunc.typ = astnodes.FunctionType(parameters, returntype)
37 self.curFunc = None
38 self.curScope = self.curScope.parent
39 def actOnType(self, tok):
40 # Try to lookup type, in case of failure return void
41 pass
42 def actOnDesignator(self, tname, loc):
43 d = astnodes.Designator(tname)
44 d.scope = self.curScope
45 d.loc = loc
46 return d
44 def actOnBinop(self, lhs, op, rhs, loc): 47 def actOnBinop(self, lhs, op, rhs, loc):
45 bo = astnodes.Binop(lhs, op, rhs) 48 bo = astnodes.Binop(lhs, op, rhs)
46 bo.loc = loc 49 bo.loc = loc
47 return bo 50 return bo
48 def actOnNumber(self, num, loc): 51 def actOnNumber(self, num, loc):
49 n = astnodes.Constant(num) 52 n = astnodes.Constant(num)
50 n.loc = loc 53 n.loc = loc
51 return n 54 return n
52 def actOnVarDef(self, name, loc, t, ival): 55 def actOnVariableUse(self, d):
53 s = astnodes.Variable(name, t) 56 return astnodes.VariableUse(d)
54 s.loc = loc
55 self.curScope.addSymbol(s)
56 def actOnFuncDef1(self, name, loc):
57 self.curFunc = astnodes.Procedure(name)
58 self.curFunc.loc = loc
59 self.curScope.addSymbol(self.curFunc)
60 self.curScope = self.curFunc.scope = Scope(self.curScope)
61 def actOnFuncDef2(self, parameters, returntype, body):
62 self.curFunc.body = body
63 self.curFunc.typ = astnodes.FunctionType(parameters, returntype)
64 self.curFunc = None
65 self.curScope = self.curScope.parent
66 def actOnType(self, tok):
67 # Try to lookup type, in case of failure return void
68 pass
69 57