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