def test_jit_example(self): """ Test loading of C code from jit example """ source = io.StringIO(""" int x(int* a, int* b, int count) { int sum = 0; int i; for (i=0; i < count; i++) sum += a[i] * b[i]; return sum; } """) arch = get_current_arch() html_filename = make_filename(self.id()) + '.html' with open(html_filename, 'w') as f, HtmlReportGenerator(f) as reporter: obj = cc(source, arch, debug=True, reporter=reporter) m = load_obj(obj) # print(m.x.argtypes) T = ctypes.c_int * 6 a = T() # TODO: integers in ctypes are 32 bit, they are 64 bit in ppci? a[:] = 1, 0, 2, 0, 3, 0 # ap = ctypes.cast(a, ctypes.POINTER(ctypes.c_long)) b = T() b[:] = 5, 0, 4, 0, 9, 0 # bp = ctypes.cast(b, ctypes.POINTER(ctypes.c_long)) y = m.x(a, b, 3) self.assertEqual(40, y)
def do(self, src, expected_output, lang="c3"): # Compile: bsp_c3_src = """ module bsp; public function void putc(byte c); """ bsp_c3 = io.StringIO(bsp_c3_src) march = get_current_arch() base_filename = make_filename(self.id()) report_filename = base_filename + ".html" with html_reporter(report_filename) as reporter: obj = partial_build(src, lang, bsp_c3, 0, march, reporter) actual_output = [] def bsp_putc(c: int) -> None: # print('bsp_putc:', chr(c)) actual_output.append(chr(c)) # Dynamically load: imports = { "bsp_putc": bsp_putc, } mod = load_obj(obj, imports=imports) # print(dir(mod)) # Invoke! if hasattr(mod, "main"): mod.main() else: mod.main_main() # Check output: actual_output = "".join(actual_output) self.assertEqual(expected_output, actual_output)
def test_jit_example(self): """ Test loading of C code from jit example """ source = io.StringIO(""" int mega_complex_stuff(int* a, int* b, int count) { int sum = 0; int i; for (i=0; i < count; i++) sum += a[i] * b[i]; return sum; } """) arch = get_current_arch() html_filename = make_filename(self.id()) + '.html' with open(html_filename, 'w') as f, HtmlReportGenerator(f) as reporter: obj = cc(source, arch, debug=True, reporter=reporter) m = load_obj(obj) # print(m.x.argtypes) count = 6 T = ctypes.c_int * count a = T() a[:] = 1, 0, 2, 0, 3, 0 b = T() b[:] = 5, 0, 4, 0, 9, 0 y = m.mega_complex_stuff(a, b, count) self.assertEqual(40, y)
def test_c(self): """ Test loading of C code """ source = io.StringIO("int x(int a) { return a + 1 ; }") arch = get_current_arch() obj = cc(source, arch, debug=True) m = load_obj(obj) y = m.x(101) self.assertEqual(102, y)
def test_callback_from_c(self): """ Test calling a python function from C code """ source = io.StringIO(""" int add(int x, int y); int x(int a) { return add(a + 1, 13); } """) arch = get_current_arch() obj = cc(source, arch, debug=True) def my_add(x: int, y: int) -> int: return x + y + 2 imports = {'add': my_add} m = load_obj(obj, imports=imports) y = m.x(101) self.assertEqual(117, y)
def xx_test_compiling(): # Convert Python to wasm wasm_module = python_to_wasm(py3) # Convert wasm to ppci ppci_module = wasm.wasm_to_ir(wasm_module) # Optimizer fails, or makes it slower ;) # optimize(ppci_module, 2) # Compile to native object arch = get_current_arch() ob = ir_to_object([ppci_module], arch, debug=True) # Run in memory native_module = codepage.load_obj(ob) result = native_module.main() assert result == 2741
def to_ir(self, includes=None, march=None, reporter=None): """ Compile C3 to PPCI IR for the given architecture. """ # todo: why would we have to specify an arch here? # circular ref, maybe move get_arch to utils? from ppci.api import get_arch from ppci.api import get_current_arch includes = [] if includes is None else includes march = get_current_arch() if march is None else get_arch(march) logger = logging.getLogger('c3c') if not reporter: # pragma: no cover reporter = DummyReportGenerator() logger.debug('C3 compilation started') reporter.heading(2, 'c3 compilation') sources = [io.StringIO(i) for i in self.items] includes = [get_file(fn) for fn in includes] diag = DiagnosticsManager() c3b = C3Builder(diag, march.info) try: _, ir_modules = c3b.build(sources, includes) for ircode in ir_modules: Verifier().verify(ircode) except CompilerError as ex: diag.error(ex.msg, ex.loc) diag.print_errors() raise TaskError('Compile errors') reporter.message('C3 compilation listings for {}'.format(sources)) for ir_module in ir_modules: reporter.message('{} {}'.format(ir_module, ir_module.stats())) reporter.dump_ir(ir_module) return self._new('ir', ir_modules)
import argparse import io from ppci.api import get_current_arch from ppci.lang.c import CLexer, CParser, COptions, CContext, CSemantics from ppci.lang.c.nodes import types, declarations from ppci.lang.c.preprocessor import prepare_for_parsing parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter) parser.add_argument('source', type=str) args = parser.parse_args() # print('Source:', args.source) # Parse into ast: arch = get_current_arch() coptions = COptions() ccontext = CContext(coptions, arch.info) semantics = CSemantics(ccontext) cparser = CParser(coptions, semantics) clexer = CLexer(COptions()) f = io.StringIO(args.source) tokens = clexer.lex(f, '<snippet>') tokens = prepare_for_parsing(tokens, cparser.keywords) cparser.init_lexer(tokens) semantics.begin() decl = cparser.parse_declarations()[0] # Explain: def explain(x):
if __name__ == '__main__': # Argument handling: arg_parser = argparse.ArgumentParser() arg_parser.add_argument('source', help='C source file') args = arg_parser.parse_args() filename = args.source print("============= [ {} ] ===============".format(args.source)) with open(args.source, 'r') as f: for row, line in enumerate(f, 1): print(row, ':', line.rstrip()) print("====================================") # Parsing: arch_info = get_current_arch().info try: with open(filename, 'r') as f: ast = create_ast(f, arch_info, filename=filename) except CompilerError as ex: ex.print() raise else: print("=== Re-rendered source==============") CPrinter().print(ast) print("====================================") print("================ AST ===============") CAstPrinter().print(ast) print("====================================")