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)