#!/usr/bin/env python
# -*- 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 helps to determine the semantics of the
#  Python computer language, for syntax highlighting.

from Library.Parse.Lex.Languages import AComputerLanguage, CharacterType, \
    TokenType

## Python opcodes understood the by the parser
PythonOpcodes = {
    "abs": TokenType.keyword,
    "all": TokenType.keyword,
    "and": TokenType.keyword,
    "any": TokenType.keyword,
    "as": TokenType.keyword,
    "assert": TokenType.keyword,
    "basestring": TokenType.typeIdentifier,
    "bin": TokenType.keyword,
    "bool": TokenType.typeIdentifier,
    "break": TokenType.keyword,
    "bytearray": TokenType.keyword,
    "callable": TokenType.typeIdentifier,
    "chr": TokenType.keyword,
    "class": TokenType.typeIdentifier,
    "classmethod": TokenType.keyword,
    "cmp": TokenType.keyword,
    "compile": TokenType.keyword,
    "complex": TokenType.typeIdentifier,
    "continue": TokenType.keyword,
    "def": TokenType.keyword,
    "del": TokenType.keyword,
    "delattr": TokenType.keyword,
    "dict": TokenType.typeIdentifier,
    "dir": TokenType.keyword,
    "divmod": TokenType.keyword,
    "elif": TokenType.keyword,
    "else": TokenType.keyword,
    "enumerate": TokenType.keyword,
    "eval": TokenType.keyword,
    "except": TokenType.keyword,
    "exec": TokenType.keyword,
    "execfile": TokenType.keyword,
    "file": TokenType.typeIdentifier,
    "filter": TokenType.keyword,
    "finally": TokenType.keyword,
    "float": TokenType.typeIdentifier,
    "for": TokenType.keyword,
    "format": TokenType.keyword,
    "from": TokenType.keyword,
    "frozenset": TokenType.typeIdentifier,
    "getattr": TokenType.keyword,
    "global": TokenType.keyword,
    "globals": TokenType.keyword,
    "hasattr": TokenType.keyword,
    "hash": TokenType.keyword,
    "help": TokenType.keyword,
    "hex": TokenType.keyword,
    "id": TokenType.keyword,
    "if": TokenType.keyword,
    "import": TokenType.keyword,
    "in": TokenType.keyword,
    "input": TokenType.keyword,
    "int": TokenType.keyword,
    "is": TokenType.keyword,
    "isinstance": TokenType.keyword,
    "issubclass": TokenType.keyword,
    "iter": TokenType.keyword,
    "lambda": TokenType.keyword,
    "len": TokenType.keyword,
    "list": TokenType.keyword,
    "locals": TokenType.keyword,
    "long": TokenType.typeIdentifier,
    "map": TokenType.keyword,
    "max": TokenType.keyword,
    "memoryview": TokenType.keyword,
    "min": TokenType.keyword,
    "next": TokenType.keyword,
    "not": TokenType.keyword,
    "object": TokenType.typeIdentifier,
    "oct": TokenType.keyword,
    "open": TokenType.keyword,
    "or": TokenType.keyword,
    "ord": TokenType.keyword,
    "pass": TokenType.keyword,
    "pow": TokenType.keyword,
    "print": TokenType.keyword,
    "property": TokenType.keyword,
    "raise": TokenType.keyword,
    "range": TokenType.keyword,
    "raw_input": TokenType.keyword,
    "reduce": TokenType.keyword,
    "reload": TokenType.keyword,
    "repr": TokenType.keyword,
    "return": TokenType.keyword,
    "reversed": TokenType.keyword,
    "round": TokenType.keyword,
    "set": TokenType.typeIdentifier,
    "setattr": TokenType.keyword,
    "slice": TokenType.keyword,
    "sorted": TokenType.keyword,
    "staticmethod": TokenType.keyword,
    "str": TokenType.typeIdentifier,
    "sum": TokenType.keyword,
    "super": TokenType.keyword,
    "try": TokenType.keyword,
    "tuple": TokenType.keyword,
    "type": TokenType.keyword,
    "unichr": TokenType.keyword,
    "unicode": TokenType.typeIdentifier,
    "vars": TokenType.keyword,
    "while": TokenType.keyword,
    "with": TokenType.keyword,
    "xrange": TokenType.keyword,
    "yield": TokenType.keyword,
    "zip": TokenType.keyword,
    "__import__": TokenType.keyword,
    "apply": TokenType.keyword,
    "buffer": TokenType.keyword,
    "coerce": TokenType.keyword,
    "intern": TokenType.keyword,
    "+": TokenType.operator,
    "-": TokenType.operator,
    "*": TokenType.operator,
    "**": TokenType.operator,
    "/": TokenType.operator,
    "//": TokenType.operator,
    "%": TokenType.operator,
    "&lt;&lt;": TokenType.operator,
    ">>": TokenType.operator,
    "&amp;": TokenType.operator,
    "|": TokenType.operator,
    "^": TokenType.operator,
    "~": TokenType.operator,
    "&lt;": TokenType.operator,
    ">": TokenType.operator,
    "&lt;=": TokenType.operator,
    ">=": TokenType.operator,
    "==": TokenType.operator,
    "!=": TokenType.operator,
    "&lt;>": TokenType.operator,
    "(": TokenType.special,
    ")": TokenType.special,
    "[": TokenType.special,
    "]": TokenType.special,
    "{": TokenType.special,
    "}": TokenType.special,
    "@": TokenType.special,
    ",": TokenType.special,
    ":": TokenType.special,
    ".": TokenType.special,
    "`": TokenType.special,
    "=": TokenType.special,
    ";": TokenType.special,
    "+=": TokenType.special,
    "-=": TokenType.special,
    "*=": TokenType.special,
    "/=": TokenType.special,
    "//=": TokenType.special,
    "%=": TokenType.special,
    "&amp;=": TokenType.special,
    "|=": TokenType.special,
    "^=": TokenType.special,
    ">>=": TokenType.special,
    "&lt;&lt;=": TokenType.special,
    "\"\"\"": TokenType.string,
    "\"": TokenType.string,
    "\'": TokenType.string,
    "\\r": TokenType.special,
    "\\n": TokenType.special,
    "\\t": TokenType.special,
    "\\x": TokenType.special
}

## Python syntax rulesets
PythonRules = {
    "comment/line": ("#",),
    "comment/block/begin": ("\"\"\"",),
    "comment/block/end": ("\"\"\"",),
    "string/escape": ("\\n", "\\r", "\\t", "\\x")
}

## Python character types
PythonCharacterTypes = {
    CharacterType.symbol: "()[]{}@,:.`=+-*/>%|^\"\'",
    CharacterType.letter: ("\\&_ABCDEFGHIJKLMNOPQRSTUVWXYZ"
                           "abcdefghijklmnopqrstuvwxyz"),
    CharacterType.alpha: ";",
    CharacterType.digit: "0123456789",
    CharacterType.numeric: ".-ABCDEFXabcdefx",
    CharacterType.space: ("\x00\x01\x02\x03\x04\x05\x06\x07\x08\x0B\x0C"
                          "\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19"
                          "\x1A\x1B\x1C\x1D\x1E\x1F\x20\x7F"),
    CharacterType.quote: "",
    CharacterType.endOfLine: "\x0A\x0D",
    CharacterType.endOfStream: "\x19"
}

## A class that represents the syntax and rules of the Python language
class python(AComputerLanguage):
    ## Constructor
    def init(Self):
        result = AComputerLanguage.init(Self)
        
        if result:
            # Set private attributes
            # This language is case-sensitive
            Self._caseAware = True
            # Opcodes recognized by the language
            Self.registerOpcodes(**PythonOpcodes)
            # Rules of the language
            Self._Rules.update(**PythonRules)
            # Character types recognized by the language
            for key in PythonCharacterTypes.iterkeys():
                Self.characters[key] = PythonCharacterTypes[key]
                
        return result
    
