comparison python/ppci/c3/builder.py @ 306:b145f8e6050b

Start on c3 rewrite
author Windel Bouwman
date Mon, 09 Dec 2013 19:00:21 +0100
parents 0615b5308710
children e609d5296ee9
comparison
equal deleted inserted replaced
305:0615b5308710 306:b145f8e6050b
1 import logging 1 import logging
2 from .lexer import Lexer
2 from .parser import Parser 3 from .parser import Parser
3 from .analyse import TypeChecker, Analyzer 4 from .analyse import TypeChecker, Analyzer
4 from .codegenerator import CodeGenerator 5 from .codegenerator import CodeGenerator
5 from .analyse import AddScope 6 from .analyse import AddScope
7 from .scope import createTopScope
8 from .visitor import AstPrinter
6 9
7 10
8 class Builder: 11 class Builder:
9 """ 12 """
10 Generates IR-code from c3 source. 13 Generates IR-code from c3 source.
11 Reports errors to the diagnostics system. 14 Reports errors to the diagnostics system.
12 """ 15 """
13 def __init__(self, diag, target): 16 def __init__(self, diag, target):
14 self.logger = logging.getLogger('c3') 17 self.logger = logging.getLogger('c3')
15 self.diag = diag 18 self.diag = diag
19 self.lexer = Lexer(diag)
16 self.parser = Parser(diag) 20 self.parser = Parser(diag)
17 self.tc = TypeChecker(diag) 21 self.tc = TypeChecker(diag)
18 self.al = Analyzer(diag) 22 self.al = Analyzer(diag)
19 self.cg = CodeGenerator() 23 self.cg = CodeGenerator()
20 24 self.topScope = createTopScope(target) # Scope with built in types
21 def checkSource(self, srcs, imps=[]):
22 """ Performs syntax and type check. """
23 iter(srcs)
24 iter(imps)
25
26 def doParse(srcs):
27 for src in srcs:
28 pkg = self.parser.parseSource(src)
29 if pkg:
30 yield pkg
31 else:
32 self.ok = False
33 s_pkgs = set(doParse(srcs))
34 i_pkgs = set(doParse(imps))
35 all_pkgs = s_pkgs | i_pkgs
36 # Fix scopes:
37
38 def doF(f, pkgs):
39 for pkg in pkgs:
40 if f(pkg):
41 yield pkg
42 else:
43 self.ok = False
44 all_pkgs = set(doF(AddScope(self.diag).addScope, all_pkgs))
45 # TODO: fix error handling better
46
47 def doA(pkgs):
48 packages = {pkg.name: pkg for pkg in pkgs}
49 for pkg in pkgs:
50 if self.al.analyzePackage(pkg, packages):
51 yield pkg
52 else:
53 self.ok = False
54 all_pkgs = set(doA(all_pkgs))
55 all_pkgs = set(doF(self.tc.checkPackage, all_pkgs))
56 return all_pkgs & s_pkgs
57 25
58 def build(self, srcs, imps=[]): 26 def build(self, srcs, imps=[]):
59 """ Create IR-code from sources """ 27 """ Create IR-code from sources """
60 self.logger.info('Building {} source files'.format(len(srcs))) 28 self.logger.info('Building {} source files'.format(len(srcs)))
29 iter(srcs) # Check if srcs are iterable
30 iter(imps)
61 self.ok = True 31 self.ok = True
62 for pkg in self.checkSource(srcs, imps): 32 self.pkgs = {}
63 # Only return ircode when everything is OK 33
64 if self.ok: 34 def doParse(src):
65 yield self.cg.gencode(pkg) 35 tokens = self.lexer.lex(src)
36 return self.parser.parseSource(tokens)
37 s_pkgs = set(map(doParse, srcs))
38 i_pkgs = set(map(doParse, imps))
39 all_pkgs = s_pkgs | i_pkgs
40 if not all(all_pkgs):
41 self.ok = False
42 return
43
44 #for pkg in all_pkgs:
45 # AstPrinter().printAst(pkg)
46
47 packages = {pkg.name: pkg for pkg in all_pkgs}
48 self.pkgs = packages
49 # Fix scopes:
50 for pkg in all_pkgs:
51 AddScope(self.diag, self.topScope).addScope(pkg)
52 if not all(pkg.ok for pkg in all_pkgs):
53 self.ok = False
54 return
55
56 for pkg in all_pkgs:
57 self.al.analyzePackage(pkg, packages)
58 if not all(pkg.ok for pkg in all_pkgs):
59 self.ok = False
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)