import dis,re,sys,os,string

from bytecodehacks.code_gen import opexfuncread

temphead="""\
# this file is autogenerated by running
# from bytecodehacks.code_gen import write_ops
# write_ops.Main()

from bytecodehacks import opbases
from bytecodehacks.label import Label

_opbases = opbases
_Label = Label

del Label
del opbases

_bytecodes={}

"""

noargtemplate="""\
class %(name)s(_opbases.%(base)s):
    op = %(index)d
    opc = '\\%(index)03o'

    def __init__(self,cs=None,code=None):
        if cs is not None:
            _opbases.%(base)s.__init__(self,cs,code)
    def execute(self,stack):
%(exec_body)s

_bytecodes[%(name)s.opc]=%(name)s

"""

argtemplate="""\
class %(name)s(_opbases.%(base)s):
    op = %(index)d
    opc = '\\%(index)03o'

    def __init__(self,csorarg,code=None):
        if code is not None:
            _opbases.%(base)s.__init__(self,csorarg,code)
        else:
            self.user_init(csorarg)
    def execute(self,stack):
%(exec_body)s

_bytecodes[%(name)s.opc]=%(name)s

"""
jumptemplate="""\
class %(name)s(_opbases.%(base)s):
    op = %(index)d
    opc = '\\%(index)03o'

    def __init__(self,csorarg=None,code=None):
        if csorarg is not None:
            if code is not None:
                _opbases.%(base)s.__init__(self,csorarg,code)
            else:
                self.label = _Label()
                self.user_init(csorarg)
        else:
            self.label = _Label()
    def execute(self,stack):
%(exec_body)s

_bytecodes[%(name)s.opc]=%(name)s

"""

idprog=re.compile('^[_a-zA-Z][_a-zA-Z0-9]*$')
notopprog=re.compile('^<[0-9]+>$')

def main(file=sys.stdout):
    file.write(temphead)
    trans=string.maketrans('+','_')
    for index in range(len(dis.opname)):
        name=string.translate(dis.opname[index],trans)
        
        if notopprog.match(name):
            continue
        if not idprog.match(name):
            name="Opcode_%d"%index

        s = "generating %s ..."%name
        pad = " " * (30-len(s))
        print s,pad,

        base="GenericOneByteCode"

        if index < dis.HAVE_ARGUMENT:
            template = noargtemplate
            base="GenericOneByteCode"
        elif index in dis.hasjrel:
            template = jumptemplate
            base="JRel"
        elif index in dis.hasjabs:
            template = jumptemplate
            base="JAbs"
        elif index in dis.hasname:
            template = argtemplate
            base="NameOpcode"
        elif index in dis.haslocal:
            template = argtemplate
            base="LocalOpcode"
        else:
            template = argtemplate
            base="GenericThreeByteCode"

        exec_body=opexfuncread.exec_funcs[name]

        file.write(template%locals())

        print "done"

def Main():
    from bytecodehacks import __init__
    main(open(os.path.join(os.path.dirname(__init__.__file__),'ops.py'),'w'))
