Mercurial > lcfOS
comparison python/ppci/c3/builder.py @ 307:e609d5296ee9
Massive rewrite of codegenerator
author | Windel Bouwman |
---|---|
date | Thu, 12 Dec 2013 20:42:56 +0100 |
parents | b145f8e6050b |
children | 2e7f55319858 |
comparison
equal
deleted
inserted
replaced
306:b145f8e6050b | 307:e609d5296ee9 |
---|---|
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 .analyse import TypeChecker, Analyzer | |
5 from .codegenerator import CodeGenerator | 4 from .codegenerator import CodeGenerator |
6 from .analyse import AddScope | 5 from .analyse import ScopeFiller |
7 from .scope import createTopScope | 6 from .scope import createTopScope |
8 from .visitor import AstPrinter | 7 from .visitor import AstPrinter |
9 | 8 |
10 | 9 |
11 class Builder: | 10 class Builder: |
16 def __init__(self, diag, target): | 15 def __init__(self, diag, target): |
17 self.logger = logging.getLogger('c3') | 16 self.logger = logging.getLogger('c3') |
18 self.diag = diag | 17 self.diag = diag |
19 self.lexer = Lexer(diag) | 18 self.lexer = Lexer(diag) |
20 self.parser = Parser(diag) | 19 self.parser = Parser(diag) |
21 self.tc = TypeChecker(diag) | 20 self.cg = CodeGenerator(diag) |
22 self.al = Analyzer(diag) | |
23 self.cg = CodeGenerator() | |
24 self.topScope = createTopScope(target) # Scope with built in types | 21 self.topScope = createTopScope(target) # Scope with built in types |
25 | 22 |
26 def build(self, srcs, imps=[]): | 23 def build(self, srcs, imps=[]): |
27 """ Create IR-code from sources """ | 24 """ Create IR-code from sources """ |
28 self.logger.info('Building {} source files'.format(len(srcs))) | 25 self.logger.info('Building {} source files'.format(len(srcs))) |
29 iter(srcs) # Check if srcs are iterable | 26 iter(srcs) # Check if srcs are iterable |
30 iter(imps) | 27 iter(imps) |
31 self.ok = True | 28 self.ok = True |
32 self.pkgs = {} | 29 self.pkgs = {} |
33 | 30 |
31 # Parsing stage (phase 1) | |
34 def doParse(src): | 32 def doParse(src): |
35 tokens = self.lexer.lex(src) | 33 tokens = self.lexer.lex(src) |
36 return self.parser.parseSource(tokens) | 34 return self.parser.parseSource(tokens) |
37 s_pkgs = set(map(doParse, srcs)) | 35 s_pkgs = set(map(doParse, srcs)) |
38 i_pkgs = set(map(doParse, imps)) | 36 i_pkgs = set(map(doParse, imps)) |
39 all_pkgs = s_pkgs | i_pkgs | 37 all_pkgs = s_pkgs | i_pkgs |
40 if not all(all_pkgs): | 38 if not all(all_pkgs): |
41 self.ok = False | 39 self.ok = False |
42 return | 40 return |
43 | 41 |
44 #for pkg in all_pkgs: | 42 # Fix scopes and package refs (phase 1.5) |
45 # AstPrinter().printAst(pkg) | |
46 | |
47 packages = {pkg.name: pkg for pkg in all_pkgs} | 43 packages = {pkg.name: pkg for pkg in all_pkgs} |
48 self.pkgs = packages | 44 self.pkgs = packages |
45 | |
46 scopeFiller = ScopeFiller(self.diag, self.topScope, packages) | |
49 # Fix scopes: | 47 # Fix scopes: |
50 for pkg in all_pkgs: | 48 for pkg in all_pkgs: |
51 AddScope(self.diag, self.topScope).addScope(pkg) | 49 scopeFiller.addScope(pkg) |
52 if not all(pkg.ok for pkg in all_pkgs): | 50 if not all(pkg.ok for pkg in all_pkgs): |
53 self.ok = False | 51 self.ok = False |
54 return | 52 return |
55 | 53 |
56 for pkg in all_pkgs: | 54 # Generate intermediate code (phase 2) |
57 self.al.analyzePackage(pkg, packages) | 55 # Only return ircode when everything is OK |
56 for pkg in all_pkgs & s_pkgs: | |
57 yield self.cg.gencode(pkg) | |
58 if not all(pkg.ok for pkg in all_pkgs): | 58 if not all(pkg.ok for pkg in all_pkgs): |
59 self.ok = False | 59 self.ok = False |
60 return | 60 return |
61 | |
62 for pkg in all_pkgs: | |
63 self.tc.checkPackage(pkg) | |
64 if not all(pkg.ok for pkg in all_pkgs): | |
65 self.ok = False | |
66 return | |
67 | |
68 # Only return ircode when everything is OK | |
69 for pkg in all_pkgs & s_pkgs: | |
70 yield self.cg.gencode(pkg) |