"""

Emit Table Unit Tests
---------------------

Currently these tests only test the construction of the emit table
decision trees.  They do not test the application of those decision
trees to actual Operation objects.  This should be fixed.

"""


import unittest
import path
import sys
from cStringIO import StringIO

from pynto import emittable, lowir, log

M = lowir.argflags.MEM|lowir.argflags.SOFTSTACK
R = lowir.argflags.REG|lowir.argflags.SOFTREG|lowir.argflags.TEMP
C = lowir.argflags.CONST
LC = lowir.argflags.LARGECONST

class TestEmitTable (unittest.TestCase):

    def _runTable (self, table, outpath):
        out = outpath.open ('w') # open now so we delete any existing file
        logger = log.Log (sys.stderr)
        #logger.set_level (log.MINUTIA)
        et = emittable.EmitTable (logger, table)
        et.dump (out)
        out.close ()
        return

    def testMove (self):
        outpath = path.path ("move.out")
        refpath = path.path ("move.ref")
        self._runTable ({ 'MOVE': ( ( (M,), (R,), "store" ),
                                    ( (R,), (M,), "load" ),
                                    ( (R,), (R,), "reg_move" ),
                                    ( (R,), (C,), "load_constant" ),
                                    ( (R,), (LC,),"load_large_constant"))},
                        outpath)
        self.assertEqual (outpath.bytes(), refpath.bytes(), "out != ref")
        pass

    def testLongList (self):
        outpath = path.path ("longlist.out")
        refpath = path.path ("longlist.ref")
        self._runTable ({'CALL':    ( ( (R,R,R,R,R,R,R,R,R,R),
                                        (R,R,R,R,R,R,R,R,R,R),
                                        "prefix(emit_br, 1)" ), ),
                         
                         'CALLPTR': ( ( (R,R,R,R,R,R,R,R,R,R),
                                        (R,R,R,R,R,R,R,R,R,R,R),
                                        "emit_callptr" ), ), },
                        outpath)
        self.assertEqual (outpath.bytes(), refpath.bytes(), "out != ref")
        return
    
    pass

def add_tests (suite):
    for testname in dir (TestEmitTable):
        if testname.startswith ('test'):
            suite.addTest (TestEmitTable(testname))
            pass
        pass
    return

if __name__ == "__main__":
    
    unittest.main ()
    pass

