88 lines
2.5 KiB
Python
Executable File
88 lines
2.5 KiB
Python
Executable File
#!/usr/bin/env python
|
|
|
|
import os
|
|
import sys
|
|
import argparse
|
|
import tempfile
|
|
from subprocess import *
|
|
import re
|
|
|
|
import parser
|
|
from Compiler import Compiler
|
|
|
|
def main(argv):
|
|
parser = argparse.ArgumentParser(prog = 'jtlc',
|
|
description = "Josh's Toy Language Compiler")
|
|
parser.add_argument('-E', action = 'store_true',
|
|
help = 'Translate only; do not compile, assemble, or link')
|
|
parser.add_argument('-c', action = 'store_true',
|
|
help = 'Translate, compile, and assemble, but do not link')
|
|
parser.add_argument('-o', metavar = 'file', dest = 'output_file',
|
|
help = 'Output File')
|
|
parser.add_argument('sources', metavar = 'source',
|
|
nargs = '*', help = 'Input Source File')
|
|
args = parser.parse_args(argv[1:])
|
|
|
|
if len(args.sources) < 1:
|
|
sys.stderr.write(argv[0] + ': no input files\n')
|
|
return 1
|
|
|
|
success = True
|
|
ofiles = []
|
|
for s in args.sources:
|
|
tf = tempfile.NamedTemporaryFile(suffix = '.c', delete = False)
|
|
tfname = tf.name
|
|
success = translate(args, s, tf)
|
|
tf.close()
|
|
if success:
|
|
suffix = '.c' if args.E else '.o'
|
|
m = re.match('(.*)\.jtl', s)
|
|
if m is not None:
|
|
ofname = m.group(1) + suffix
|
|
else:
|
|
ofname = s + suffix
|
|
if args.E:
|
|
f = open(tfname, 'r')
|
|
content = f.read()
|
|
f.close()
|
|
if args.output_file is not None:
|
|
ofname = args.output_file
|
|
f = open(ofname, 'w')
|
|
f.write(content)
|
|
f.close()
|
|
return 0
|
|
else:
|
|
success = do_compile(args, tfname, ofname)
|
|
ofiles.append(ofname)
|
|
os.unlink(tfname)
|
|
|
|
if success and not args.c:
|
|
success = do_link(args, ofiles)
|
|
|
|
return 0 if success else 2
|
|
|
|
def translate(args, source, dest):
|
|
f = open(source, 'r')
|
|
contents = f.read()
|
|
f.close()
|
|
result = parser.parse(contents)
|
|
if result is None:
|
|
return False
|
|
return Compiler(result).compile(dest)
|
|
|
|
def do_compile(args, source_fname, ofname):
|
|
Popen(['grep', '-n', '.', source_fname]).wait()
|
|
rc = Popen(['gcc', '-o', ofname, '-c', source_fname]).wait()
|
|
return rc == 0
|
|
|
|
def do_link(args, ofiles):
|
|
cmd = ['gcc']
|
|
if args.output_file is not None:
|
|
cmd += ['-o', args.output_file]
|
|
cmd += ofiles
|
|
rc = Popen(cmd).wait()
|
|
return rc == 0
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main(sys.argv))
|