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)