from logging import error

reserved = {
    'module': 'MODULE',
    'true': 'TRUE',
    'false': 'FALSE',
    'if': 'IF',
    'else': 'ELSE',
    'use': 'USE',
    'include': 'INCLUDE',
    'function': 'FUNCTION',
    'for': 'FOR',
    'let': 'LET',
    'undef': 'UNDEF',
}

class ScadLikeLex(object):
    precedence = ()
    tokens = [
        'NUMBER',
        'COMMA',
        'SEMICOLON',
        'COLON',
        'QUESTION',
        'PLUS',
        'MOD',
        'MINUS',
        'TIMES',
        'DIVIDE',
        'EQUALS',
        'LPAREN',
        'RPAREN',
        'OBRACE',
        'EBRACE',
        'OSQUARE',
        'ESQUARE',
        'ID',
        'DOT',
        'STRING',
        'USESTRING',
        'ISEQUAL',
        'ISNOTEQUAL',
        'GE',
        'LE',
        'GT',
        'LT',
        'AND',
        'OR',
        'NOT',
    ] + list(reserved.values())

    t_NUMBER         = r'[0-9]*[\.]*[0-9]+([eE]-?[0-9]+)*'
    t_COMMA          = r','
    t_SEMICOLON      = r';'
    t_COLON          = r':'
    t_QUESTION       = r'\?'
    t_PLUS           = r'\+'
    t_MOD            = r'%'
    t_MINUS          = r'-'
    t_TIMES          = r'\*'
    t_DIVIDE         = r'/'
    t_EQUALS         = r'='
    t_LPAREN         = r'\('
    t_RPAREN         = r'\)'
    t_OBRACE         = r'{'
    t_EBRACE         = r'\}'
    t_OSQUARE        = r'\['
    t_ESQUARE        = r'\]'
    t_DOT            = r'\.'
    def t_STRING(self, t):
        r'"[^"]*"'
        t.value = t.value[1:-1]
        return t

    def t_USESTRING(self, t):
        r'<[^">= \t\r\n][^">]*>'
        t.value = t.value[1:-1]
        return t
    t_ISEQUAL        = r'=='
    t_ISNOTEQUAL     = r'!='
    t_GE             = r'>='
    t_LE             = r'<='
    t_GT             = r'>'
    t_LT             = r'<'
    t_ignore_COMMENT = r'//.*'
    t_AND            = r'&&'
    t_OR             = r'\|\|'
    t_NOT            = r'!'

    t_ignore = " \t"

    def t_comment(self, t):
        r'/\*(.|\n)*?\*/'
        t.lexer.lineno += t.value.count('\n')

    def t_ID(self, t):
        r'[$]?[a-zA-Z_][a-zA-Z_0-9]*'
        t.type = reserved.get(t.value, 'ID')
        return t

    def t_newline(self, t):
        r'\n+'
        t.lexer.lineno += t.value.count("\n")

    def t_error(self, t):
        error("Illegal character '%s'" % t.value[0])
        t.lexer.skip(1)
