view python/c3/builder.py @ 293:6aa721e7b10b

Try to improve build sequence
author Windel Bouwman
date Thu, 28 Nov 2013 20:39:37 +0100
parents bd2593de3ff8
children 917eab04b8b7
line wrap: on
line source

import logging
import ppci
from . import Parser, TypeChecker, Analyzer, 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))
        print(s_pkgs)
        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.ok = True
        for pkg in self.checkSource(srcs, imps):
            # Only return ircode when everything is OK
            if self.ok:
                yield self.cg.gencode(pkg)