# -*- coding: UTF-8 -*-
#    This file is part of arena.
#   
#    arena is free software: you can redistribute it and/or modify it
#    under the terms of the GNU General Public License as published by the
#    Free Software Foundation; either version 3 of the License or, at your
#    option, any later version.
#
#    arena is distributed in the hope that it will be useful, but
#    WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABLITY
#    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
#    License for more details.
#
#    You should have received a copy of the GNU General Public License along
#    with arena.  If not, see <http://www.gnu.org/licenses/>. 

## @file
#  This file defines a class that binds an opcode to a token string.  It also
#  defines a class that manages a set of opcodes, which can be used to check the
#  syntax of a computer statement.

from Library.Memory.StringTrees import AStringLeaf
from Library.Memory.Dictionaries import ADictionaryEntry, ADictionary, \
    dDefaultItemsDelimiter

## The format used to create a representation of AnOpcode
oStringRepresentation = "\"{token}\""

## An opcode that matches a token string to an internal value used by a
#  parser.
class AnOpcode(ADictionaryEntry):
    # IsPrintable implementation -----------------------------------------------
    ## Return a string representation of the opcode.
    #    
    #  This representation returned is formatted according to the specification
    #  provided by oStringRepresentation.
    def toString(Self):
        return oStringRepresentation.format(token=Self._name)

## A set of opcodes.
#
#  This class is used to define one more sets of "grammar rules", that specify
#  how statements and expressions should be constructed within the language.
class AnOpcodeSet(ADictionary):
    ## Construct a new instance of an opcode set that contains the specified
    #  opcode values. 
    def __init__(Self, **opcodes):
        ADictionary.__init__(Self)
        
        if len(opcodes) > 0:
            for token, value in opcodes.iteritems():
                NewOpcode = AnOpcode(token, value)
                Self.insert(NewOpcode)
        
    ## Return a string that contains a list of all of the opcode tokens
    #    in the set.
    #    
    #    This routine is essentially a wrapper for ABinaryTree.implodeKeys().
    def list(Self, itemsDelimiter=dDefaultItemsDelimiter):
        return Self.implodeKeys(itemsDelimiter)
        
