view python/ppci/c3/builder.py @ 305:0615b5308710

Updated docs
author Windel Bouwman
date Fri, 06 Dec 2013 13:50:38 +0100
parents 6753763d3bec
children b145f8e6050b
line wrap: on
line source

import logging
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, target):
        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('Building {} source files'.format(len(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)