comparison python/ppci/c3/builder.py @ 308:2e7f55319858

Merged analyse into codegenerator
author Windel Bouwman
date Fri, 13 Dec 2013 11:53:29 +0100
parents e609d5296ee9
children 6f4753202b9a
comparison
equal deleted inserted replaced
307:e609d5296ee9 308:2e7f55319858
1 import logging 1 import logging
2 from .lexer import Lexer 2 from .lexer import Lexer
3 from .parser import Parser 3 from .parser import Parser
4 from .codegenerator import CodeGenerator 4 from .codegenerator import CodeGenerator
5 from .analyse import ScopeFiller 5 from .scope import createTopScope, Scope
6 from .scope import createTopScope 6 from .visitor import AstPrinter, Visitor
7 from .visitor import AstPrinter 7 from .astnodes import Package, Function, Identifier, Symbol
8
9
10 class C3Pass:
11 def __init__(self, diag):
12 self.diag = diag
13 self.logger = logging.getLogger('c3')
14 self.visitor = Visitor()
15
16 def error(self, msg, loc=None):
17 self.pkg.ok = False
18 self.diag.error(msg, loc)
19
20 def visit(self, pkg, pre, post):
21 self.visitor.visit(pkg, pre, post)
22
23
24 class ScopeFiller(C3Pass):
25 scoped_types = [Package, Function]
26
27 def __init__(self, diag, topScope, packages):
28 super().__init__(diag)
29 self.topScope = topScope
30 self.packages = packages
31
32 """ Scope is attached to the correct modules. """
33 def addScope(self, pkg):
34 self.logger.info('Adding scoping to package {}'.format(pkg.name))
35 self.pkg = pkg
36 # Prepare top level scope and set scope to all objects:
37 self.scopeStack = [self.topScope]
38 modScope = Scope(self.CurrentScope)
39 self.scopeStack.append(modScope)
40 self.visit(pkg, self.enterScope, self.quitScope)
41 assert len(self.scopeStack) == 2
42
43 self.logger.info('Resolving imports for package {}'.format(pkg.name))
44 # Handle imports:
45 for i in pkg.imports:
46 if i not in self.packages:
47 self.error('Cannot import {}'.format(i))
48 continue
49 pkg.scope.addSymbol(self.packages[i])
50
51 @property
52 def CurrentScope(self):
53 return self.scopeStack[-1]
54
55 def addSymbol(self, sym):
56 if self.CurrentScope.hasSymbol(sym.name):
57 self.error('Redefinition of {0}'.format(sym.name), sym.loc)
58 else:
59 self.CurrentScope.addSymbol(sym)
60
61 def enterScope(self, sym):
62 # Attach scope to references:
63 if type(sym) is Identifier:
64 sym.scope = self.CurrentScope
65
66 # Add symbols to current scope:
67 if isinstance(sym, Symbol):
68 self.addSymbol(sym)
69 sym.scope = self.CurrentScope
70
71 # Create subscope for items creating a scope:
72 if type(sym) in self.scoped_types:
73 newScope = Scope(self.CurrentScope)
74 self.scopeStack.append(newScope)
75 sym.innerScope = self.CurrentScope
76
77 def quitScope(self, sym):
78 # Pop out of scope:
79 if type(sym) in self.scoped_types:
80 self.scopeStack.pop(-1)
8 81
9 82
10 class Builder: 83 class Builder:
11 """ 84 """
12 Generates IR-code from c3 source. 85 Generates IR-code from c3 source.