from pypy.interpreter.pyparser import symbol

# try to avoid numeric values conflict with tokens
# it's important for CPython, but I'm not so sure it's still
# important here

class SymbolMapper(object):
    """XXX dead"""
    def __init__(self, sym_name=None ):
        _anoncount = self._anoncount = -10
        _count = self._count = 0
        self.sym_name = {}
        self.sym_values = {}
        if sym_name is not None:
            for _value, _name in sym_name.items():
                if _value<_anoncount:
                    _anoncount = _value
                if _value>_count:
                    _count = _value
                self.sym_values[_name] = _value
                self.sym_name[_value] = _name
            self._anoncount = _anoncount
            self._count = _count

    def add_symbol( self, sym ):
        # assert isinstance(sym, str)
        if not sym in self.sym_values:
            self._count += 1
            val = self._count
            self.sym_values[sym] = val
            self.sym_name[val] = sym
            return val
        return self.sym_values[ sym ]

    def add_anon_symbol( self, sym ):
        # assert isinstance(sym, str)
        if not sym in self.sym_values:
            self._anoncount -= 1
            val = self._anoncount
            self.sym_values[sym] = val
            self.sym_name[val] = sym
            return val
        return self.sym_values[ sym ]

    def __getitem__(self, sym ):
        """NOT RPYTHON"""
        # assert isinstance(sym, str)
        return self.sym_values[ sym ]

    def __contains__(self, sym):
        """NOT RPYTHON"""
        return sym in self.sym_values
    

_cpython_symbols = SymbolMapper( symbol.sym_name )

# There is no symbol in this module until the grammar is loaded
# once loaded the grammar parser will fill the mappings with the
# grammar symbols

# XXX: is this completly dead ?
## # prepopulate symbol table from symbols used by CPython
## for _value, _name in _cpython_symbols.sym_name.items():
##     globals()[_name] = _value


def gen_symbol_file(fname):
    """
    Generate a compatible symbol file for symbol.py, using the grammar that has
    been generated from the grammar in the PyPy parser.  (Note that we assume
    that the parser generates the tokens deterministically.)
    """

    import ebnfparse
    gram = ebnfparse.parse_grammar( file(fname) )

    import os.path
    f = open(os.path.join(os.path.dirname(__file__), 'symbol.py'), 'w')
    print >> f, """
#  This file is automatically generated; please don't muck it up!
#
#  To update the symbols in this file, call this function from python_grammar()
#  and call PyPy.
"""
    for k, v in gram.symbols.sym_name.iteritems():
        if k >= 0:
            print >> f, '%s = %s' % (v, k)

    print >> f, """

# Generate sym_name
sym_name = {}
for _name, _value in globals().items():
    if type(_value) is type(0):
        sym_name[_value] = _name
"""
    f.close()
    
if __name__ == '__main__':
    import sys
    if len(sys.argv) != 2:
        print 'Call pysymbol with the filename of the python grammar'
        sys.exit(0)
    gen_symbol_file(sys.argv[1])
