from  compyler.codeObjectAssembler import codeObjectAssembler, debug
from pyasm.x86cpToMemory import CpToMemory
import unittest
import cStringIO
import sys

def setDebugLevel(level):
    import compyler.codeObjectAssembler
    compyler.codeObjectAssembler.debug = level

def setDebugLevelFromArgv():
    argv = sys.argv
    if len(argv) > 1:
        print "SWITCHING DEBUG LEVEL TO => ", argv[1]
        setDebugLevel(int(argv[1]))
        print "!!", debug

def runUnittest():
    setDebugLevelFromArgv()
    unittest.main(argv=sys.argv[0:1] + sys.argv[2:]) # strip debug level

def simpleFunction(*args):
    print args

def simpleKwFunction(*args, **kwargs):
    print args
    print kwargs

def eval_code(code, result, typ = 'single',title=None):
    if not title: title=code
    print "+++++++++++++++ EVALUATING %s +++++++++++++++++++++" % title
    x = codeObjectAssembler()
    co = compile(code,"",typ)
    assem = x.assembleCodeObject(co)

    mem = CpToMemory(assem)
    mem.MakeMemory()
    mem.BindPythonFunctions(globals(),bindFunction=lambda x:xcodeobject(x,0))
        
    results = cStringIO.StringIO();
    _stdout,sys.stdout = sys.stdout,results

    newResult = ""
    try:
        #main()
        
        exec main in globals(),globals() #locals()
        results.seek(0)
        newResult = results.read()
        return newResult == result
    finally:
        sys.stdout = _stdout
        print "------------------DONE EVALUATING -----------------------"
        if newResult != result:
            print "!%s! != !%s!" % (newResult,result)

def eval_raises_code(code, typ = 'single',title=None):
    if not title: title=code
    print "+++++++++++++++ EVALUATING %s +++++++++++++++++++++" % title
    x = codeObjectAssembler()
    co = compile(code,"",typ)
    assem = x.assembleCodeObject(co)
    mem = CpToMemory(assem)
    mem.MakeMemory()
    mem.BindPythonFunctions(globals(),lambda x:xcodeobject(x,0))
    exec main in globals(),globals()
