view python/c3/builder.py @ 281:4496cae24d7f

Improved logview
author Windel Bouwman
date Sat, 02 Nov 2013 11:11:40 +0100
parents e64bae57cda8
children 1c7c1e619be8
line wrap: on
line source

import logging
import ppci
from . import Parser, TypeChecker, Analyzer, CodeGenerator
from . astprinter import AstPrinter
import glob

class Builder:
    """ 
        Generates IR-code from c3 source.
        Reports errors to the diagnostics system
    """
    def __init__(self, diag):
        self.pack_dir = None
        self.logger = logging.getLogger('c3')
        self.diag = diag
        self.parser = Parser(diag)
        self.tc = TypeChecker(diag)
        self.al = Analyzer(diag)
        self.cg = CodeGenerator()
        self.packages = {}

    def getPackage(self, pname):
        """ package provider for use when analyzing """
        if pname in self.packages:
            return self.packages[pname]
        else:
            # Try to lookup package from file
            fns = glob.glob('./**/{}.c3'.format(pname))
            if fns:
                with open(fns[0]) as f:
                    src = f.read()
                self.build(src)
            if self.pack_dir:
                fns = glob.glob('{}/{}.c3'.format(self.pack_dir, pname))
                if fns:
                    with open(fns[0]) as f:
                        src = f.read()
                    self.build(src)
            if pname in self.packages:
                return self.packages[pname]

    def parse(self, src):
        pkg = self.parser.parseSource(src)
        if not pkg:
            return

        # TODO: merge the two below?
        #AstPrinter().printAst(pkg)
        if not self.al.analyzePackage(pkg, self):
            return
        if not self.tc.checkPackage(pkg):
            return

        # Store for later use:
        self.packages[pkg.name] = pkg
        return pkg

    def build(self, src, pack_dir=None):
        """ Create IR-code from sources """
        self.pack_dir = pack_dir
        pkg = self.parse(src)

        # Only return ircode when everything is OK
        if pkg:
            return self.cg.gencode(pkg)