
# -*- coding: utf-8 -*-
"""
    pygments.lexers.picolisp
    ~~~~~~~~~~~~~~~~~~~

    Pygments lexer for PicoLisp..

    :copyright: Copyright 2006-2013 by the Pygments team, see AUTHORS.
    :license: BSD, see LICENSE for details.
"""

import re

from pygments.lexer import Lexer, RegexLexer, include, bygroups, using, \
     this
from pygments.token import Text, Comment, Operator, Keyword, Name, String, \
     Number, Punctuation
from pygments.util import get_choice_opt
from pygments import unistring as uni


__all__ = ['PicolispLexer']
           
class PicolispLexer(RegexLexer):
    """
    Lexer for `PicoLisp <http://picolisp.com/>`_ source code.

    *New in Pygments 1.6*
    """
    name = 'PicoLisp'
    aliases = ['pl']
    filenames = ['*.l']
    mimetypes = ['text/x-picolisp', 'application/x-picolisp']

    special_forms = [
        'NIL', 'T'
    ]

    declarations = [
        'de', 'dm', 'symbols', 'local', 'class', 'def'
    ]

    builtins = [
        'new', 'sym', 'str', 'char', 'name', 'sp?', 'pat?', 'fun?', 
        'all', 'symbols', 'local', 'import', 'intern', 'extern', 
        '====', 'qsym', 'loc', 'box?', 'str?', 'ext?', 'touch', 'zap', 
        'length', 'size', 'format', 'chop', 'pack', 'glue', 'pad', 
        'align', 'center', 'text', 'wrap', 'pre?', 'sub?', 'low?', 
        'upp?', 'lowc', 'uppc', 'fold', 'val', 'getd', 'set', 'setq', 
        'def', 'de', 'dm', 'recur', 'undef', 'redef', 'daemon', 'patch', 
        'xchg', 'on', 'off', 'onOff', 'zero', 'one', 'default', 'expr', 
        'subr', 'let', 'let?', 'use', 'accu', 'push', 'push1', 'pop', 
        'cut', 'del', 'queue', 'fifo', 'idx', 'lup', 'cache', 'locale', 
        'dirname', 'put', 'get', 'prop', ';', '=:', ':', '::', 'putl', 
        'getl', 'wipe', 'meta', 'atom', 'pair', 'circ?', 'lst?', 'num?', 
        'sym?', 'flg?', 'sp?', 'pat?', 'fun?', 'box?', 'str?', 'ext?', 
        'bool', 'not', '==', 'n==', '=', '<>', '=0', '=T', 'n0', 'nT', 
        '<', '<=', '>', '>=', 'match', '+', '-', '*', '/', '%', '*/', 
        '**', 'inc', 'dec', '>>', 'lt0', 'le0', 'ge0', 'gt0', 'abs', 
        'bit?', '&', '|', 'x|', 'sqrt', 'seed', 'rand', 'max', 'min', 
        'length', 'size', 'accu', 'format', 'pad', 'money', 'round', 'bin', 
        'oct', 'hex', 'hax', 'fmt64', 'car', 'cdr', 'caar', 'cadr', 
        'cdar', 'cddr', 'caaar', 'caadr', 'cadar', 'caddr', 'cdaar', 
        'cdadr', 'cddar', 'cdddr', 'cadddr', 'cddddr', 'nth', 'con', 
        'cons', 'conc', 'circ', 'rot', 'list', 'need', 'range', 'full', 
        'make', 'made', 'chain', 'link', 'yoke', 'copy', 'mix', 'append', 
        'delete', 'delq', 'replace', 'insert', 'remove', 'place', 'strip', 
        'split', 'reverse', 'flip', 'trim', 'clip', 'head', 'tail', 'stem', 
        'fin', 'last', 'member', 'memq', 'mmeq', 'sect', 'diff', 'index', 
        'offset', 'prior', 'assoc', 'asoq', 'rank', 'sort', 'uniq', 'group', 
        'length', 'size', 'bytes', 'val', 'set', 'xchg', 'push', 'push1', 
        'pop', 'cut', 'queue', 'fifo', 'idx', 'balance', 'get', 'fill', 
        'apply', 'load', 'args', 'next', 'arg', 'rest', 'pass', 'quote', 
        'as', 'lit', 'eval', 'run', 'macro', 'curry', 'def', 'de', 'dm', 
        'recur', 'recurse', 'undef', 'box', 'new', 'type', 'isa', 'method', 
        'meth', 'send', 'try', 'super', 'extra', 'with', 'bind', 'job', 'let', 
        'let?', 'use', 'and', 'or', 'nand', 'nor', 'xor', 'bool', 'not', 
        'nil', 't', 'prog', 'prog1', 'prog2', 'if', 'if2', 'ifn', 'when', 
        'unless', 'cond', 'nond', 'case', 'casq', 'state', 'while', 'until', 
        'loop', 'do', 'at', 'for', 'catch', 'throw', 'finally', 'co', 'yield', 
        '!', 'e', '$', 'call', 'tick', 'ipid', 'opid', 'kill', 'quit', 'task', 
        'fork', 'pipe', 'later', 'timeout', 'abort', 'bye', 'apply', 'pass', 
        'maps', 'map', 'mapc', 'maplist', 'mapcar', 'mapcon', 'mapcan', 'filter', 
        'extract', 'seek', 'find', 'pick', 'cnt', 'sum', 'maxi', 'mini', 'fish', 
        'by', 'path', 'in', 'out', 'err', 'ctl', 'ipid', 'opid', 'pipe', 'any', 
        'sym', 'str', 'load', 'hear', 'tell', 'key', 'poll', 'peek', 'char', 
        'skip', 'eol', 'eof', 'from', 'till', 'line', 'format', 'scl', 'read', 
        'print', 'println', 'printsp', 'prin', 'prinl', 'msg', 'space', 'beep', 
        'tab', 'flush', 'rewind', 'rd', 'pr', 'wr', 'wait', 'sync', 'echo', 
        'info', 'file', 'dir', 'lines', 'open', 'close', 'port', 'listen', 
        'accept', 'host', 'connect', 'udp', 'script', 'once', 'rc', 'acquire', 
        'release', 'pretty', 'pp', 'show', 'view', 'here', 'prEval', 'mail', 
        '*Class', 'class', 'dm', 'rel', 'var', 'var:', 'new', 'type', 'isa', 
        'method', 'meth', 'send', 'try', 'object', 'extend', 'super', 'extra', 
        'with', 'This', 'can', 'dep', 'pool', 'journal', 'id', 'seq', 'lieu', 
        'lock', 'commit', 'rollback', 'mark', 'free', 'dbck', 'dbs', 'dbs+', 
        'db:', 'tree', 'db', 'aux', 'collect', 'genKey', 'useKey', '+relation', 
        '+Any', '+Bag', '+Bool', '+Number', '+Date', '+Time', '+Symbol', 
        '+String', '+Link', '+Joint', '+Blob', '+Hook', '+Hook2', '+index', 
        '+Key', '+Ref', '+Ref2', '+Idx', '+Sn', '+Fold', '+IdxFold', '+Aux', 
        '+UB', '+Dep', '+List', '+Need', '+Mis', '+Alt', '+Swap', '+Entity', 
        'blob', 'dbSync', 'new!', 'set!', 'put!', 'inc!', 'blob!', 'upd', 
        'rel', 'request', 'obj', 'fmt64', 'root', 'fetch', 'store', 'count', 
        'leaf', 'minKey', 'maxKey', 'init', 'step', 'scan', 'iter', 'prune', 
        'zapTree', 'chkTree', 'prove', '->', 'unify', 'be', 'clause', 'repeat', 
        'asserta', 'assertz', 'retract', 'rules', 'goal', 'fail', 'pilog', 
        'solve', 'query', '?', 'pretty', 'pp', 'show', 'loc', '*Dbg', 'doc', 
        'more', 'depth', 'what', 'who', 'can', 'dep', 'debug', 'd', 'unbug', 
        'u', 'vi', 'em', 'ld', 'trace', 'untrace', 'traceAll', 'proc', 'hd', 
        'bench', 'edit', 'lint', 'lintAll', 'select', 'update', 'cmd', 'argv', 
        'opt', 'version', 'gc', 'raw', 'alarm', 'protect', 'heap', 'stack', 
        'adr', 'env', 'trail', 'up', 'sys', 'date', 'time', 'usec', 'stamp', 
        'dat$', '$dat', 'datSym', 'datStr', 'strDat', 'expDat', 'day', 'week', 
        'ultimo', 'tim$', '$tim', 'telStr', 'expTel', 'locale', 'allowed', 
        'allow', 'pwd', 'cd', 'chdir', 'ctty', 'info', 'dir', 'dirname', 'errno', 
        'native', 'call', 'tick', 'kill', 'quit', 'task', 'fork', 'forked', 'pipe', 
        'timeout', 'mail', 'assert', 'test', 'bye', 'NIL', 'pico', '*CPU', '*OS', 
        '*DB', 'T', '*Solo', '*PPid', '*Pid', '@', '@@', '@@@', 'This', '*Prompt', 
        '*Dbg', '*Zap', '*Scl', '*Class', '*Dbs', '*Run', '*Hup', '*Sig1', '*Sig2', 
        '^', '*Err', '*Msg', '*Uni', '*Led', '*Tsm', '*Adr', '*Allow', '*Fork', '*Bye'
    ]

    valid_name = r'(?!#)[\w!$%*+<=>?/.#-]+'

    def _multi_escape(entries):
        return '(%s)' % ('|'.join(re.escape(entry) + ' ' for entry in entries))

    tokens = {
        'root': [
            # the comments - always starting with semicolon
            # and going to the end of the line
            (r'#.*$', Comment.Single),

            # whitespaces - usually not relevant
            (r'[,\s]+', Text),

            # numbers
            (r'-?\d+\.\d+', Number.Float),
            (r'-?\d+', Number.Integer),
            (r'0x-?[abcdef\d]+', Number.Hex),

            # strings, symbols and characters
            (r'"(\\\\|\\"|[^"])*"', String),
            (r"'" + valid_name, String.Symbol),                        

            # special operators
            (r'~@|[`\'#^~&@]', Operator),

            # highlight the special forms
            (_multi_escape(special_forms), Keyword),

            (_multi_escape(declarations), Keyword.Declaration),

            # highlight the builtins
            (_multi_escape(builtins), Name.Builtin),

            # the remaining functions
            (r'(?<=\()' + valid_name, Name.Function),

            # find the remaining variables
            (valid_name, Name.Variable),

            # the famous parentheses!
            (r'(\(|\))', Punctuation),
        ],
    }
