Mercurial > lcfOS
view python/zcc.py @ 329:8f6f3ace4e78
Added build tasks
author | Windel Bouwman |
---|---|
date | Wed, 05 Feb 2014 21:29:31 +0100 |
parents | e9fe6988497c |
children | a78b41ff6ad2 |
line wrap: on
line source
#!/usr/bin/env python import sys import argparse import logging from ppci.c3 import AstPrinter from ppci.buildtasks import Compile from ppci.tasks import TaskRunner import outstream from utils import HexFile import target from target.target_list import target_list from ppci import irutils import io logformat='%(asctime)s|%(levelname)s|%(name)s|%(message)s' def logLevel(s): """ Converts a string to a valid logging level """ numeric_level = getattr(logging, s.upper(), None) if not isinstance(numeric_level, int): raise ValueError('Invalid log level: {}'.format(s)) return numeric_level class RstFormatter(logging.Formatter): """ Formatter that tries to create an rst document """ def __init__(self): super().__init__(fmt=logformat) def format(self, record): s = super().format(record) s += '\n' if hasattr(record, 'c3_ast'): f = io.StringIO() print('', file=f) print('', file=f) print('.. code::', file=f) print('', file=f) AstPrinter().printAst(record.c3_ast, f) print('', file=f) s += '\n' + f.getvalue() if hasattr(record, 'ircode'): f = io.StringIO() print('', file=f) print('', file=f) print('.. code::', file=f) print('', file=f) Writer(' ').write(record.ircode, f) print('', file=f) s += '\n' + f.getvalue() if hasattr(record, 'irfunc'): f = io.StringIO() print('', file=f) print('', file=f) print('.. code::', file=f) print('', file=f) Writer(' ').write_function(record.irfunc, f) print('', file=f) s += '\n' + f.getvalue() if hasattr(record, 'ppci_frame'): f = io.StringIO() frame = record.ppci_frame print('', file=f) print('.. code::', file=f) print('', file=f) print(' {}'.format(frame.name), file=f) for i in frame.instructions: print(' {}'.format(i),file=f) print('', file=f) s += '\n' + f.getvalue() if hasattr(record, 'ra_cfg'): f = io.StringIO() print('', file=f) print('', file=f) print('.. graphviz::', file=f) print('', file=f) print(' digraph G {', file=f) print(' size="8,80";', file=f) cfg = record.ra_cfg cfg.to_dot(f) print(' }', file=f) print('', file=f) s += '\n' + f.getvalue() if hasattr(record, 'ra_ig'): f = io.StringIO() print('', file=f) print('', file=f) print('.. graphviz::', file=f) print('', file=f) print(' digraph G {', file=f) print(' ratio="compress";', file=f) print(' size="8,80";', file=f) ig = record.ra_ig ig.to_dot(f) print(' }', file=f) print('', file=f) s += '\n' + f.getvalue() if hasattr(record, 'zcc_outs'): f = io.StringIO() print('', file=f) print('', file=f) print('.. code::', file=f) print('', file=f) outstream.OutputStreamWriter(' ').dump(record.zcc_outs, f) print('', file=f) s += '\n' + f.getvalue() return s targets = {t.name: t for t in target_list} targetnames = list(targets.keys()) # Parse arguments: parser = argparse.ArgumentParser(description='lcfos Compiler') parser.add_argument('source', type=argparse.FileType('r'), \ help='the source file to build', nargs="+") parser.add_argument('-i', '--imp', type=argparse.FileType('r'), \ help='Possible import module', action='append', default=[]) #sub_parsers = parser.add_subparsers() #recipe = sub_parsers.add_parser('recipe') parser.add_argument('--optimize', action='store_true', help="Optimize") parser.add_argument('--target', help="Backend selection", choices=targetnames, required=True) parser.add_argument('-o', '--output', help='Output file', metavar='filename') parser.add_argument('--log', help='Log level (INFO,DEBUG,[WARN])', type=logLevel, default='WARN') parser.add_argument('--report', help='Specify a file to write the compile report to', type=argparse.FileType('w')) def main(args): # Configure some logging: logging.getLogger().setLevel(logging.DEBUG) ch = logging.StreamHandler() ch.setFormatter(logging.Formatter(logformat)) ch.setLevel(args.log) logging.getLogger().addHandler(ch) if args.report: fh = logging.StreamHandler(stream=args.report) fh.setFormatter(RstFormatter()) logging.getLogger().addHandler(fh) tg = targets[args.target] outs = outstream.TextOutputStream() tr = TaskRunner() tr.add_task(Compile(args.source, args.imp, tg, outs)) res = tr.run_tasks() if res > 0: return 1 logging.info('Assembly created', extra={'zcc_outs':outs}) code_bytes = outs.sections['code'].to_bytes() if args.output: output_filename = args.output with open(output_filename, 'wb') as f: f.write(code_bytes) if args.report: logging.getLogger().removeHandler(fh) logging.getLogger().removeHandler(ch) return 0 if __name__ == '__main__': arguments = parser.parse_args() sys.exit(main(arguments))