Mercurial > lcfOS
diff python/ppci/c3/builder.py @ 300:158068af716c
yafm
author | Windel Bouwman |
---|---|
date | Tue, 03 Dec 2013 18:00:22 +0100 |
parents | python/c3/builder.py@917eab04b8b7 |
children | 6753763d3bec |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/python/ppci/c3/builder.py Tue Dec 03 18:00:22 2013 +0100 @@ -0,0 +1,66 @@ +import logging +import ppci +from .parser import Parser +from .analyse import TypeChecker, Analyzer +from .codegenerator import CodeGenerator +from .analyse import AddScope + + +class Builder: + """ + Generates IR-code from c3 source. + Reports errors to the diagnostics system. + """ + def __init__(self, diag): + self.logger = logging.getLogger('c3') + self.diag = diag + self.parser = Parser(diag) + self.tc = TypeChecker(diag) + self.al = Analyzer(diag) + self.cg = CodeGenerator() + + def checkSource(self, srcs, imps=[]): + """ Performs syntax and type check. """ + iter(srcs) + iter(imps) + + def doParse(srcs): + for src in srcs: + pkg = self.parser.parseSource(src) + if pkg: + yield pkg + else: + self.ok = False + s_pkgs = set(doParse(srcs)) + i_pkgs = set(doParse(imps)) + all_pkgs = s_pkgs | i_pkgs + # Fix scopes: + + def doF(f, pkgs): + for pkg in pkgs: + if f(pkg): + yield pkg + else: + self.ok = False + all_pkgs = set(doF(AddScope(self.diag).addScope, all_pkgs)) + # TODO: fix error handling better + + def doA(pkgs): + packages = {pkg.name: pkg for pkg in pkgs} + for pkg in pkgs: + if self.al.analyzePackage(pkg, packages): + yield pkg + else: + self.ok = False + all_pkgs = set(doA(all_pkgs)) + all_pkgs = set(doF(self.tc.checkPackage, all_pkgs)) + return all_pkgs & s_pkgs + + def build(self, srcs, imps=[]): + """ Create IR-code from sources """ + self.logger.info('Starting build with {}'.format(srcs)) + self.ok = True + for pkg in self.checkSource(srcs, imps): + # Only return ircode when everything is OK + if self.ok: + yield self.cg.gencode(pkg)