Mercurial > lcfOS
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. |