from Compiler.program import Program from .GC import types as GC_types import sys import re, tempfile, os def run(args, options): """ Compile a file and output a Program object. If options.merge_opens is set to True, will attempt to merge any parallelisable open instructions. """ prog = Program(args, options) VARS['program'] = prog if options.binary: VARS['sint'] = GC_types.sbitintvec.get_type(int(options.binary)) VARS['sfix'] = GC_types.sbitfixvec for i in 'cint', 'cfix', 'cgf2n', 'sintbit', 'sgf2n', 'sgf2nint', \ 'sgf2nuint', 'sgf2nuint32', 'sgf2nfloat', 'sfloat', 'cfloat', \ 'squant': del VARS[i] print('Compiling file', prog.infile) f = open(prog.infile, 'rb') changed = False if options.flow_optimization: output = [] if_stack = [] for line in open(prog.infile): if if_stack and not re.match(if_stack[-1][0], line): if_stack.pop() m = re.match( '(\s*)for +([a-zA-Z_]+) +in +range\(([0-9a-zA-Z_]+)\):', line) if m: output.append('%s@for_range_opt(%s)\n' % (m.group(1), m.group(3))) output.append('%sdef _(%s):\n' % (m.group(1), m.group(2))) changed = True continue m = re.match('(\s*)if(\W.*):', line) if m: if_stack.append((m.group(1), len(output))) output.append('%s@if_(%s)\n' % (m.group(1), m.group(2))) output.append('%sdef _():\n' % (m.group(1))) changed = True continue m = re.match('(\s*)elif\s+', line) if m: raise CompilerError('elif not supported') if if_stack: m = re.match('%selse:' % if_stack[-1][0], line) if m: start = if_stack[-1][1] ws = if_stack[-1][0] output[start] = re.sub(r'^%s@if_\(' % ws, r'%s@if_e(' % ws, output[start]) output.append('%s@else_\n' % ws) output.append('%sdef _():\n' % ws) continue output.append(line) if changed: infile = tempfile.NamedTemporaryFile('w+', delete=False) for line in output: infile.write(line) infile.seek(0) else: infile = open(prog.infile) else: infile = open(prog.infile) # make compiler modules directly accessible sys.path.insert(0, 'Compiler') # create the tapes exec(compile(infile.read(), infile.name, 'exec'), VARS) if changed and not options.debug: os.unlink(infile.name) prog.finalize() if prog.req_num: print('Program requires at most:') for x in prog.req_num.pretty(): print(x) if prog.verbose: print('Program requires:', repr(prog.req_num)) print('Cost:', 0 if prog.req_num is None else prog.req_num.cost()) print('Memory size:', dict(prog.allocated_mem)) return prog