# PigletC: a tiny C-like language compiler for PigletVM, # see https://github.com/vkazanov/bytecode-interpreters-post # Author: Peter Sovietov import os import sys from src.main import compile if len(sys.argv) == 2 and os.path.isfile(sys.argv[1]): path = sys.argv[1] with open(path) as f: src = f.read() c = compile(path, src) with open("%s.pvm" % path, "w") as f: f.write(c.asm) else: print("usage: pigletc.py file.c")
def test(path, running_aggregate_tests=False): global ok global skipped global output_index index = tests[path] passed = False output = [f"{B}> TEST {index}/{n}:{E} {path}"] try: try: expected_error = Path(path.replace('.px', '.err')).read_text() except FileNotFoundError: expected_error = None error = True exe_filename = True try: if running_aggregate_tests: exe_filename = f'./{aggregate_exe_filename}' else: exe_filename = compile( path, args.cpp_compiler, args.opt_level, mode=('executable' if args.separate else 'cpp')) error = False except NotSupportedError as e: skipped += 1 output.append(f"{Y}{e}{E}") except PyxellError as e: error_message = str(e) if expected_error: if error_message.strip().endswith(expected_error): output.append(f"{G}{error_message}{E}") passed = True else: output.append( f"{R}{error_message}\n---\n> {expected_error}{E}") else: output.append(f"{R}{error_message}{E}") except subprocess.CalledProcessError as e: output.append(f"{R}{e.output.decode()}{E}") except Exception: output.append(f"{R}{traceback.format_exc()}{E}") if not error: if expected_error: output.append( f"{R}Program compiled successfully, but error expected.\n---\n> {expected_error}{E}" ) elif not args.separate and not running_aggregate_tests: aggregate_cpp_code.extend([ f'namespace test{index} {{', re.sub('^', INDENT, Path(path.replace('.px', '.cpp')).read_text(), flags=re.MULTILINE), '}\n', ]) tests_to_compile.add(path) # The function will be run again with running_aggregate_tests=True. return elif exe_filename is None: output.append(f"{G}OK{E}") passed = True else: with open(path.replace('.px', '.tmp'), 'w') as tmpfile: t1 = timer() command = [exe_filename] if running_aggregate_tests: command.append(path) try: with open(path.replace('.px', '.in'), 'r') as infile: subprocess.call(command, stdin=infile, stdout=tmpfile) except FileNotFoundError: subprocess.call(command, stdout=tmpfile) t2 = timer() try: subprocess.check_output([ 'diff', '--strip-trailing-cr', '--text', path.replace('.px', '.tmp'), path.replace('.px', '.out') ], stderr=subprocess.STDOUT) except subprocess.CalledProcessError as e: if e.returncode == 2: output.append(f"{Y}{e.output.decode()}{E}") else: output.append(f"{R}WA: {e.output.decode()}{E}") else: output.append(f"{G}OK{E} ({t2-t1:.3f}s)") passed = True except Exception: output.append(f"{R}{traceback.format_exc()}{E}") # Print the output of tests in the right order. output_dict[index] = '\n'.join( output) if not passed or args.verbose else '' with lock: while output_index in output_dict: if output_dict[output_index]: print(output_dict[output_index]) output_index += 1 if passed: ok += 1 if not args.verbose: os.remove(path.replace('.px', '.tmp')) if not error: os.remove(path.replace('.px', '.cpp')) os.remove(path.replace('.px', '.exe'))
# PigletC, a tiny C-like language compiler for PigletVM, # see https://github.com/vkazanov/bytecode-interpreters-post # Author: Peter Sovietov import sys from src.main import Compiler, compile if len(sys.argv) == 2: path = sys.argv[1] with open(path) as f: src = f.read() c = Compiler(path, src) compile(c) with open("%s.pvm" % path, "w") as f: f.write(c.asm) else: print("usage: pigletc.py file.c")