annotate python/ppci/c3/builder.py @ 366:39bf68bf1891

Fix sample tests and deterministic build
author Windel Bouwman
date Fri, 21 Mar 2014 09:43:01 +0100
parents 5477e499b039
children fb3c1f029b30
rev   line source
254
bd26dc13f270 Added logger
Windel Bouwman
parents: 251
diff changeset
1 import logging
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
2 from .lexer import Lexer
300
Windel Bouwman
parents: 295
diff changeset
3 from .parser import Parser
Windel Bouwman
parents: 295
diff changeset
4 from .codegenerator import CodeGenerator
308
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
5 from .scope import createTopScope, Scope
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
6 from .visitor import AstPrinter, Visitor
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
7 from .astnodes import Package, Function, Identifier, Symbol
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
8
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
9
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
10 class C3Pass:
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
11 def __init__(self, diag):
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
12 self.diag = diag
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
13 self.logger = logging.getLogger('c3')
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
14 self.visitor = Visitor()
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
15
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
16 def error(self, msg, loc=None):
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
17 self.pkg.ok = False
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
18 self.diag.error(msg, loc)
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
19
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
20 def visit(self, pkg, pre, post):
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
21 self.visitor.visit(pkg, pre, post)
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
22
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
23
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
24 class ScopeFiller(C3Pass):
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
25 scoped_types = [Package, Function]
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
26
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
27 def __init__(self, diag, topScope, packages):
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
28 super().__init__(diag)
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
29 self.topScope = topScope
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
30 self.packages = packages
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
31
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
32 """ Scope is attached to the correct modules. """
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
33 def addScope(self, pkg):
334
6f4753202b9a Added more recipes
Windel Bouwman
parents: 308
diff changeset
34 self.logger.debug('Adding scoping to package {}'.format(pkg.name))
308
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
35 self.pkg = pkg
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
36 # Prepare top level scope and set scope to all objects:
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
37 self.scopeStack = [self.topScope]
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
38 modScope = Scope(self.CurrentScope)
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
39 self.scopeStack.append(modScope)
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
40 self.visit(pkg, self.enterScope, self.quitScope)
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
41 assert len(self.scopeStack) == 2
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
42
334
6f4753202b9a Added more recipes
Windel Bouwman
parents: 308
diff changeset
43 self.logger.debug('Resolving imports for package {}'.format(pkg.name))
308
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
44 # Handle imports:
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
45 for i in pkg.imports:
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
46 if i not in self.packages:
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
47 self.error('Cannot import {}'.format(i))
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
48 continue
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
49 pkg.scope.addSymbol(self.packages[i])
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
50
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
51 @property
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
52 def CurrentScope(self):
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
53 return self.scopeStack[-1]
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
54
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
55 def addSymbol(self, sym):
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
56 if self.CurrentScope.hasSymbol(sym.name):
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
57 self.error('Redefinition of {0}'.format(sym.name), sym.loc)
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
58 else:
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
59 self.CurrentScope.addSymbol(sym)
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
60
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
61 def enterScope(self, sym):
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
62 # Attach scope to references:
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
63 if type(sym) is Identifier:
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
64 sym.scope = self.CurrentScope
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
65
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
66 # Add symbols to current scope:
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
67 if isinstance(sym, Symbol):
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
68 self.addSymbol(sym)
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
69 sym.scope = self.CurrentScope
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
70
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
71 # Create subscope for items creating a scope:
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
72 if type(sym) in self.scoped_types:
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
73 newScope = Scope(self.CurrentScope)
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
74 self.scopeStack.append(newScope)
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
75 sym.innerScope = self.CurrentScope
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
76
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
77 def quitScope(self, sym):
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
78 # Pop out of scope:
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
79 if type(sym) in self.scoped_types:
2e7f55319858 Merged analyse into codegenerator
Windel Bouwman
parents: 307
diff changeset
80 self.scopeStack.pop(-1)
165
598d3888a11c Added front class and fided AST view
Windel Bouwman
parents:
diff changeset
81
287
1c7c1e619be8 File movage
Windel Bouwman
parents: 272
diff changeset
82
165
598d3888a11c Added front class and fided AST view
Windel Bouwman
parents:
diff changeset
83 class Builder:
288
a747a45dcd78 Various styling work
Windel Bouwman
parents: 287
diff changeset
84 """
186
46d62dadd61b Improved testsuite
Windel Bouwman
parents: 168
diff changeset
85 Generates IR-code from c3 source.
300
Windel Bouwman
parents: 295
diff changeset
86 Reports errors to the diagnostics system.
186
46d62dadd61b Improved testsuite
Windel Bouwman
parents: 168
diff changeset
87 """
301
6753763d3bec merge codegen into ppci package
Windel Bouwman
parents: 300
diff changeset
88 def __init__(self, diag, target):
254
bd26dc13f270 Added logger
Windel Bouwman
parents: 251
diff changeset
89 self.logger = logging.getLogger('c3')
226
240111e0456f Work on named types
Windel Bouwman
parents: 225
diff changeset
90 self.diag = diag
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
91 self.lexer = Lexer(diag)
226
240111e0456f Work on named types
Windel Bouwman
parents: 225
diff changeset
92 self.parser = Parser(diag)
307
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents: 306
diff changeset
93 self.cg = CodeGenerator(diag)
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
94 self.topScope = createTopScope(target) # Scope with built in types
194
b01429a5d695 Fixed test
Windel Bouwman
parents: 186
diff changeset
95
287
1c7c1e619be8 File movage
Windel Bouwman
parents: 272
diff changeset
96 def build(self, srcs, imps=[]):
251
6ed3d3a82a63 Added another c3 example. First import attempt
Windel Bouwman
parents: 226
diff changeset
97 """ Create IR-code from sources """
334
6f4753202b9a Added more recipes
Windel Bouwman
parents: 308
diff changeset
98 self.logger.debug('Building {} source files'.format(len(srcs)))
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
99 iter(srcs) # Check if srcs are iterable
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
100 iter(imps)
288
a747a45dcd78 Various styling work
Windel Bouwman
parents: 287
diff changeset
101 self.ok = True
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
102 self.pkgs = {}
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
103
307
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents: 306
diff changeset
104 # Parsing stage (phase 1)
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
105 def doParse(src):
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
106 tokens = self.lexer.lex(src)
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
107 return self.parser.parseSource(tokens)
366
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
108 s_pkgs = list(map(doParse, srcs))
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
109 i_pkgs = list(map(doParse, imps))
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
110 all_pkgs = s_pkgs + i_pkgs
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
111 if not all(all_pkgs):
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
112 self.ok = False
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
113 return
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
114
307
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents: 306
diff changeset
115 # Fix scopes and package refs (phase 1.5)
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
116 packages = {pkg.name: pkg for pkg in all_pkgs}
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
117 self.pkgs = packages
307
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents: 306
diff changeset
118
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents: 306
diff changeset
119 scopeFiller = ScopeFiller(self.diag, self.topScope, packages)
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
120 # Fix scopes:
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
121 for pkg in all_pkgs:
307
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents: 306
diff changeset
122 scopeFiller.addScope(pkg)
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
123 if not all(pkg.ok for pkg in all_pkgs):
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
124 self.ok = False
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
125 return
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
126
307
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents: 306
diff changeset
127 # Generate intermediate code (phase 2)
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents: 306
diff changeset
128 # Only return ircode when everything is OK
366
39bf68bf1891 Fix sample tests and deterministic build
Windel Bouwman
parents: 354
diff changeset
129 for pkg in s_pkgs:
307
e609d5296ee9 Massive rewrite of codegenerator
Windel Bouwman
parents: 306
diff changeset
130 yield self.cg.gencode(pkg)
306
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
131 if not all(pkg.ok for pkg in all_pkgs):
b145f8e6050b Start on c3 rewrite
Windel Bouwman
parents: 305
diff changeset
132 self.ok = False