# Path: prolog/jittest/test_00_model.py
# class BaseTestPyrologC(object):
#     def setup_class(cls):
#         if not executable.check():
#             py.test.skip("missing pyrolog-c at %s" % (executable.dirpath(), ))
#         cls.tmpdir = udir.join('test-pyrolog-jit')
#         cls.tmpdir.ensure(dir=True)
# 
#     def setup_method(self, meth):
#         self.filepath = self.tmpdir.join(meth.im_func.func_name + '.pl')
# 
#     def run(self, src, call, **jitopts):
#         jitopts.setdefault('threshold', 200)
#         # write the snippet
#         with self.filepath.open("w") as f:
#             # we don't want to see the small bridges created
#             # by the checkinterval reaching the limit
#             f.write(str(src) + "\n")
#         #
#         # run a child pyrolog-c with logging enabled
#         logfile = self.filepath.new(ext='.log')
#         #
#         cmdline = [strexecutable]
#         cmdline.append(str(self.filepath))
#         #
#         print cmdline, logfile
#         env={'PYPYLOG': 'jit-log-opt,jit-summary:' + str(logfile)}
#         #env={'PYPYLOG': ':' + str(logfile)}
#         pipe = subprocess.Popen(cmdline,
#                                 env=env,
#                                 stdin=subprocess.PIPE,
#                                 stdout=subprocess.PIPE,
#                                 stderr=subprocess.PIPE)
#         pipe.stdin.write(call + "\n")
#         stdout, stderr = pipe.communicate()
#         if stderr.startswith('SKIP:'):
#             py.test.skip(stderr)
#         if stderr.startswith('debug_alloc.h:'):   # lldebug builds
#             stderr = ''
#         assert not stderr
#         #
#         # parse the JIT log
#         rawlog = logparser.parse_log_file(str(logfile))
#         rawtraces = logparser.extract_category(rawlog, 'jit-log-opt-')
#         log = Log(rawtraces)
#         log.result = stdout
#         if "ParseError" in log.result or "ERROR" in log.result:
#             assert 0, log.result
#         #
#         summaries  = logparser.extract_category(rawlog, 'jit-summary')
#         if len(summaries) > 0:
#             log.jit_summary = parse_prof(summaries[-1])
#         else:
#             log.jit_summary = None
#         #
#         return log
# 
#     def run_and_check(self, src, args=[], **jitopts):
#         log1 = self.run(src, args, threshold=-1, function_threshold=-1)  # without the JIT
#         log2 = self.run(src, args, **jitopts)     # with the JIT
#         assert log1.result == log2.result
#         # check that the JIT actually ran
#         assert len(log2.filter_loops()) > 0
#         return log2


from prolog.jittest.test_00_model import BaseTestPyrologC
        py.test.skip("fix me later")
        code = """
            g(X, Y, Out) :- Out is X - Y.
            g(X, Y, Out) :- Y > 0, Y0 is Y - 1, g(X, Y0, Out).
            iterate_failure(X) :- g(X, X, A), fail.
            iterate_failure(_).
        """
        log = self.run_and_check(code, "iterate_failure(10000).")
        loop, = log.filter_loops("g")
        assert loop.match("""
            i6 = int_sub_ovf(i2, 1)
            guard_no_overflow(descr=<Guard2>)
            guard_not_invalidated(descr=<Guard3>)
            i9 = int_eq(i6, 0)
            guard_false(i9, descr=<Guard4>)
            jump(p0, p1, i6, p3, p4, descr=<Loop0>)
        """)

    def test_ifthenelse(self):
        code = """
            equal(0, 0). equal(X, X).
            iterate_if(X) :- equal(X, 0) -> true ;
                             Y is X - 1, iterate_if(Y).
        """
        log = self.run_and_check(code, "iterate_if(10000).")
        loop, = log.filter_loops("iterate_if")
        assert loop.match("""
            guard_not_invalidated(descr=...)
            i5 = int_eq(i2, 0)
            guard_false(i5, descr=...)

# Path: prolog/jittest/test_00_model.py
# class BaseTestPyrologC(object):
#     def setup_class(cls):
#         if not executable.check():
#             py.test.skip("missing pyrolog-c at %s" % (executable.dirpath(), ))
#         cls.tmpdir = udir.join('test-pyrolog-jit')
#         cls.tmpdir.ensure(dir=True)
# 
#     def setup_method(self, meth):
#         self.filepath = self.tmpdir.join(meth.im_func.func_name + '.pl')
# 
#     def run(self, src, call, **jitopts):
#         jitopts.setdefault('threshold', 200)
#         # write the snippet
#         with self.filepath.open("w") as f:
#             # we don't want to see the small bridges created
#             # by the checkinterval reaching the limit
#             f.write(str(src) + "\n")
#         #
#         # run a child pyrolog-c with logging enabled
#         logfile = self.filepath.new(ext='.log')
#         #
#         cmdline = [strexecutable]
#         cmdline.append(str(self.filepath))
#         #
#         print cmdline, logfile
#         env={'PYPYLOG': 'jit-log-opt,jit-summary:' + str(logfile)}
#         #env={'PYPYLOG': ':' + str(logfile)}
#         pipe = subprocess.Popen(cmdline,
#                                 env=env,
#                                 stdin=subprocess.PIPE,
#                                 stdout=subprocess.PIPE,
#                                 stderr=subprocess.PIPE)
#         pipe.stdin.write(call + "\n")
#         stdout, stderr = pipe.communicate()
#         if stderr.startswith('SKIP:'):
#             py.test.skip(stderr)
#         if stderr.startswith('debug_alloc.h:'):   # lldebug builds
#             stderr = ''
#         assert not stderr
#         #
#         # parse the JIT log
#         rawlog = logparser.parse_log_file(str(logfile))
#         rawtraces = logparser.extract_category(rawlog, 'jit-log-opt-')
#         log = Log(rawtraces)
#         log.result = stdout
#         if "ParseError" in log.result or "ERROR" in log.result:
#             assert 0, log.result
#         #
#         summaries  = logparser.extract_category(rawlog, 'jit-summary')
#         if len(summaries) > 0:
#             log.jit_summary = parse_prof(summaries[-1])
#         else:
#             log.jit_summary = None
#         #
#         return log
# 
#     def run_and_check(self, src, args=[], **jitopts):
#         log1 = self.run(src, args, threshold=-1, function_threshold=-1)  # without the JIT
#         log2 = self.run(src, args, **jitopts)     # with the JIT
#         assert log1.result == log2.result
#         # check that the JIT actually ran
#         assert len(log2.filter_loops()) > 0
#         return log2


# Path: prolog/jittest/test_iterate.py
from prolog.jittest.test_00_model import BaseTestPyrologC

        py.test.skip("fix me later")
        code = """
            g(X, Y, Out) :- Out is X - Y.
            g(X, Y, Out) :- Y > 0, Y0 is Y - 1, g(X, Y0, Out).
            iterate_failure(X) :- g(X, X, A), fail.
            iterate_failure(_).
        """
        log = self.run_and_check(code, "iterate_failure(10000).")
        loop, = log.filter_loops("g")
        assert loop.match("""
            i6 = int_sub_ovf(i2, 1)
            guard_no_overflow(descr=<Guard2>)
            guard_not_invalidated(descr=<Guard3>)
            i9 = int_eq(i6, 0)
            guard_false(i9, descr=<Guard4>)
            jump(p0, p1, i6, p3, p4, descr=<Loop0>)
        """)

    def test_ifthenelse(self):
        code = """
            equal(0, 0). equal(X, X).
            iterate_if(X) :- equal(X, 0) -> true ;
                             Y is X - 1, iterate_if(Y).
        """
        log = self.run_and_check(code, "iterate_if(10000).")
        loop, = log.filter_loops("iterate_if")
        assert loop.match("""
            guard_not_invalidated(descr=...)
            i5 = int_eq(i2, 0)
            guard_false(i5, descr=...)

            i7 = int_sub_ovf(i2, 1)