Lichen

lplc

468:b46f0224a6c4
2017-01-12 Paul Boddie Extended NotImplementedError, raising it within setattr.
     1 #!/usr/bin/env python     2      3 from errors import *     4 from os import rename     5 from os.path import abspath, exists, join, split     6 from pyparser import error     7 from subprocess import Popen, PIPE     8 from time import time     9 import importer, deducer, optimiser, generator, translator    10 import sys    11     12 libdirs = [    13     join(split(__file__)[0], "lib"),    14     "/usr/share/lichen/lib"    15     ]    16     17 def load_module(filename, module_name):    18     for libdir in libdirs:    19         path = join(libdir, filename)    20         if exists(path):    21             return i.load_from_file(path, module_name)    22     return None    23     24 def show_missing(missing):    25     missing = list(missing)    26     missing.sort()    27     for module_name, name in missing:    28         print >>sys.stderr, "Module %s references an unknown object: %s" % (module_name, name)    29     30 def show_syntax_error(exc):    31     print >>sys.stderr, "Syntax error at column %d on line %d in file %s:" % (exc.offset, exc.lineno, exc.filename)    32     print >>sys.stderr    33     print >>sys.stderr, exc.text.rstrip()    34     print >>sys.stderr, " " * exc.offset + "^"    35     36 def stopwatch(activity, now):    37     print >>sys.stderr, "%s took %.2f seconds" % (activity, time() - now)    38     return time()    39     40 def call(tokens, verbose=False):    41     out = not verbose and PIPE or None    42     cmd = Popen(tokens, stdout=out, stderr=out)    43     stdout, stderr = cmd.communicate()    44     return cmd.wait()    45     46 # Main program.    47     48 if __name__ == "__main__":    49     args = sys.argv[1:]    50     path = libdirs + sys.path[:]    51     52     # Determine the options and arguments.    53     54     verbose = False    55     reset = False    56     debug = False    57     make = True    58     make_verbose = True    59     60     filenames = []    61     outputs = []    62     63     # Obtain program filenames by default.    64     65     l = filenames    66     67     for arg in args:    68         if arg == "-v": verbose = True    69         elif arg == "-r": reset = True    70         elif arg == "-g": debug = True    71         elif arg == "-c": make = False    72         elif arg == "-q": make_verbose = False    73         elif arg == "-o": l = outputs    74         else:    75             l.append(arg)    76     77             # Revert to collecting program filenames after obtaining the output    78             # executable filename.    79     80             if l is outputs: l = filenames    81     82     # Obtain the program filename.    83     84     if len(filenames) > 1:    85         print >>sys.stderr, "Only one main program file can be specified."    86         sys.exit(1)    87     88     filename = abspath(filenames[0])    89     path.append(split(filename)[0])    90     91     # Obtain the output filename.    92     93     output = outputs and outputs[0] or "_main"    94     95     # Define the output data directories.    96     97     datadir = "_lplc"    98     cache_dir = join(datadir, "_cache")    99     deduced_dir = join(datadir, "_deduced")   100     output_dir = join(datadir, "_output")   101     generated_dir = join(datadir, "_generated")   102    103     # Load the program.   104    105     try:   106         start = now = time()   107    108         i = importer.Importer(path, cache_dir, verbose)   109         m = i.initialise(filename, reset)   110         success = i.finalise()   111    112         now = stopwatch("Inspection", now)   113    114         # Check for success, indicating missing references otherwise.   115    116         if not success:   117             show_missing(i.missing)   118             sys.exit(1)   119    120         d = deducer.Deducer(i, deduced_dir)   121         d.to_output()   122    123         now = stopwatch("Deduction", now)   124    125         o = optimiser.Optimiser(i, d, output_dir)   126         o.to_output()   127    128         now = stopwatch("Optimisation", now)   129    130         g = generator.Generator(i, o, generated_dir)   131         g.to_output(debug)   132    133         now = stopwatch("Generation", now)   134    135         t = translator.Translator(i, d, o, generated_dir)   136         t.to_output()   137    138         now = stopwatch("Translation", now)   139    140         # Compile the program unless otherwise indicated.   141    142         if make:   143             make_clean_cmd = ["make", "-C", generated_dir, "clean"]   144             make_cmd = make_clean_cmd[:-1]   145    146             retval = call(make_clean_cmd, make_verbose)   147             if not retval:   148                 retval = call(make_cmd, make_verbose)   149    150             if not retval:   151                 stopwatch("Compilation", now)   152             else:   153                 sys.exit(retval)   154    155             # Move the executable into the current directory.   156    157             rename(join(generated_dir, "main"), output)   158    159     # Report any errors.   160    161     except error.SyntaxError, exc:   162         show_syntax_error(exc)   163         if "-tb" in args:   164             raise   165         sys.exit(1)   166    167     except ProcessingError, exc:   168         print exc   169         if "-tb" in args:   170             raise   171         sys.exit(1)   172    173     else:   174         sys.exit(0)   175    176 # vim: tabstop=4 expandtab shiftwidth=4