summaryrefslogtreecommitdiff
path: root/pygments/lexers/functional.py
diff options
context:
space:
mode:
Diffstat (limited to 'pygments/lexers/functional.py')
-rw-r--r--pygments/lexers/functional.py306
1 files changed, 280 insertions, 26 deletions
diff --git a/pygments/lexers/functional.py b/pygments/lexers/functional.py
index 770e6bd9..122114fa 100644
--- a/pygments/lexers/functional.py
+++ b/pygments/lexers/functional.py
@@ -5,7 +5,7 @@
Lexers for functional languages.
- :copyright: Copyright 2006-2013 by the Pygments team, see AUTHORS.
+ :copyright: Copyright 2006-2014 by the Pygments team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""
@@ -18,8 +18,8 @@ from pygments.token import Text, Comment, Operator, Keyword, Name, \
__all__ = ['RacketLexer', 'SchemeLexer', 'CommonLispLexer', 'HaskellLexer',
'AgdaLexer', 'LiterateHaskellLexer', 'LiterateAgdaLexer',
'SMLLexer', 'OcamlLexer', 'ErlangLexer', 'ErlangShellLexer',
- 'OpaLexer', 'CoqLexer', 'NewLispLexer', 'ElixirLexer',
- 'ElixirConsoleLexer', 'KokaLexer']
+ 'OpaLexer', 'CoqLexer', 'NewLispLexer', 'NixLexer', 'ElixirLexer',
+ 'ElixirConsoleLexer', 'KokaLexer', 'IdrisLexer', 'LiterateIdrisLexer']
line_re = re.compile('.*?\n')
@@ -30,7 +30,7 @@ class RacketLexer(RegexLexer):
Lexer for `Racket <http://racket-lang.org/>`_ source code (formerly known as
PLT Scheme).
- *New in Pygments 1.6.*
+ .. versionadded:: 1.6
"""
name = 'Racket'
@@ -71,7 +71,7 @@ class RacketLexer(RegexLexer):
'syntax/loc', 'time', 'transcript-off', 'transcript-on', 'unless',
'unquote', 'unquote-splicing', 'unsyntax', 'unsyntax-splicing',
'when', 'with-continuation-mark', 'with-handlers',
- 'with-handlers*', 'with-syntax', 'λ'
+ 'with-handlers*', 'with-syntax', u'λ'
]
# From namespace-mapped-symbols
@@ -599,7 +599,7 @@ class SchemeLexer(RegexLexer):
It supports the full Scheme syntax as defined in R5RS.
- *New in Pygments 0.6.*
+ .. versionadded:: 0.6
"""
name = 'Scheme'
aliases = ['scheme', 'scm']
@@ -720,10 +720,10 @@ class CommonLispLexer(RegexLexer):
"""
A Common Lisp lexer.
- *New in Pygments 0.9.*
+ .. versionadded:: 0.9
"""
name = 'Common Lisp'
- aliases = ['common-lisp', 'cl', 'lisp']
+ aliases = ['common-lisp', 'cl', 'lisp', 'elisp', 'emacs']
filenames = ['*.cl', '*.lisp', '*.el'] # use for Elisp too
mimetypes = ['text/x-common-lisp']
@@ -898,7 +898,7 @@ class HaskellLexer(RegexLexer):
"""
A Haskell lexer based on the lexemes defined in the Haskell 98 Report.
- *New in Pygments 0.8.*
+ .. versionadded:: 0.8
"""
name = 'Haskell'
aliases = ['haskell', 'hs']
@@ -996,7 +996,7 @@ class HaskellLexer(RegexLexer):
],
'character': [
# Allows multi-chars, incorrectly.
- (r"[^\\']", String.Char),
+ (r"[^\\']'", String.Char, '#pop'),
(r"\\", String.Escape, 'escape'),
("'", String.Char, '#pop'),
],
@@ -1017,12 +1017,121 @@ class HaskellLexer(RegexLexer):
}
+class IdrisLexer(RegexLexer):
+ """
+ A lexer for the dependently typed programming language Idris.
+
+ Based on the Haskell and Agda Lexer.
+
+ .. versionadded:: 2.0
+ """
+ name = 'Idris'
+ aliases = ['idris', 'idr']
+ filenames = ['*.idr']
+ mimetypes = ['text/x-idris']
+
+ reserved = ['case','class','data','default','using','do','else',
+ 'if','in','infix[lr]?','instance','rewrite','auto',
+ 'namespace','codata','mutual','private','public','abstract',
+ 'total','partial',
+ 'let','proof','of','then','static','where','_','with',
+ 'pattern', 'term', 'syntax','prefix',
+ 'postulate','parameters','record','dsl','impossible','implicit',
+ 'tactics','intros','intro','compute','refine','exaxt','trivial']
+
+ ascii = ['NUL','SOH','[SE]TX','EOT','ENQ','ACK',
+ 'BEL','BS','HT','LF','VT','FF','CR','S[OI]','DLE',
+ 'DC[1-4]','NAK','SYN','ETB','CAN',
+ 'EM','SUB','ESC','[FGRU]S','SP','DEL']
+
+ annotations = ['assert_total','lib','link','include','provide','access',
+ 'default']
+
+ tokens = {
+ 'root': [
+ # Declaration
+ (r'^(\s*)([^\s\(\)\{\}]+)(\s*)(:)(\s*)',
+ bygroups(Text, Name.Function, Text, Operator.Word, Text)),
+ # Comments
+ (r'^(\s*)(%%%s)' % '|'.join(annotations),
+ bygroups(Text, Keyword.Reserved)),
+ (r'--(?![!#$%&*+./<=>?@\^|_~:\\]).*?$', Comment.Single),
+ (r'{-', Comment.Multiline, 'comment'),
+ # Identifiers
+ (r'\b(%s)(?!\')\b' % '|'.join(reserved), Keyword.Reserved),
+ (r'(import|module)(\s+)', bygroups(Keyword.Reserved, Text), 'module'),
+ (r"('')?[A-Z][\w\']*", Keyword.Type),
+ (r'[a-z][A-Za-z0-9_\']*', Text),
+ # Special Symbols
+ (r'(<-|::|->|=>|=)', Operator.Word), # specials
+ (r'([\(\)\{\}\[\]:!#$%&*+.\\/<=>?@^|~-]+)', Operator.Word), # specials
+ # Numbers
+ (r'\d+[eE][+-]?\d+', Number.Float),
+ (r'\d+\.\d+([eE][+-]?\d+)?', Number.Float),
+ (r'0[xX][\da-fA-F]+', Number.Hex),
+ (r'\d+', Number.Integer),
+ # Strings
+ (r"'", String.Char, 'character'),
+ (r'"', String, 'string'),
+ (r'[^\s\(\)\{\}]+', Text),
+ (r'\s+?', Text), # Whitespace
+ ],
+ 'module': [
+ (r'\s+', Text),
+ (r'([A-Z][a-zA-Z0-9_.]*)(\s+)(\()',
+ bygroups(Name.Namespace, Text, Punctuation), 'funclist'),
+ (r'[A-Z][a-zA-Z0-9_.]*', Name.Namespace, '#pop'),
+ ],
+ 'funclist': [
+ (r'\s+', Text),
+ (r'[A-Z][a-zA-Z0-9_]*', Keyword.Type),
+ (r'(_[\w\']+|[a-z][\w\']*)', Name.Function),
+ (r'--.*$', Comment.Single),
+ (r'{-', Comment.Multiline, 'comment'),
+ (r',', Punctuation),
+ (r'[:!#$%&*+.\\/<=>?@^|~-]+', Operator),
+ # (HACK, but it makes sense to push two instances, believe me)
+ (r'\(', Punctuation, ('funclist', 'funclist')),
+ (r'\)', Punctuation, '#pop:2'),
+ ],
+ # NOTE: the next four states are shared in the AgdaLexer; make sure
+ # any change is compatible with Agda as well or copy over and change
+ 'comment': [
+ # Multiline Comments
+ (r'[^-{}]+', Comment.Multiline),
+ (r'{-', Comment.Multiline, '#push'),
+ (r'-}', Comment.Multiline, '#pop'),
+ (r'[-{}]', Comment.Multiline),
+ ],
+ 'character': [
+ # Allows multi-chars, incorrectly.
+ (r"[^\\']", String.Char),
+ (r"\\", String.Escape, 'escape'),
+ ("'", String.Char, '#pop'),
+ ],
+ 'string': [
+ (r'[^\\"]+', String),
+ (r"\\", String.Escape, 'escape'),
+ ('"', String, '#pop'),
+ ],
+ 'escape': [
+ (r'[abfnrtv"\'&\\]', String.Escape, '#pop'),
+ (r'\^[][A-Z@\^_]', String.Escape, '#pop'),
+ ('|'.join(ascii), String.Escape, '#pop'),
+ (r'o[0-7]+', String.Escape, '#pop'),
+ (r'x[\da-fA-F]+', String.Escape, '#pop'),
+ (r'\d+', String.Escape, '#pop'),
+ (r'\s+\\', String.Escape, '#pop')
+ ],
+ }
+
+
class AgdaLexer(RegexLexer):
"""
For the `Agda <http://wiki.portal.chalmers.se/agda/pmwiki.php>`_
dependently typed functional programming language and proof assistant.
- *New in Pygments 1.7.*
+ .. versionadded:: 2.0
"""
name = 'Agda'
@@ -1049,12 +1158,12 @@ class AgdaLexer(RegexLexer):
(r'{!', Comment.Directive, 'hole'),
# Lexemes:
# Identifiers
- (ur'\b(%s)(?!\')\b' % '|'.join(reserved), Keyword.Reserved),
+ (r'\b(%s)(?!\')\b' % '|'.join(reserved), Keyword.Reserved),
(r'(import|module)(\s+)', bygroups(Keyword.Reserved, Text), 'module'),
(r'\b(Set|Prop)\b', Keyword.Type),
# Special Symbols
(r'(\(|\)|\{|\})', Operator),
- (ur'(\.{1,3}|\||[\u039B]|[\u2200]|[\u2192]|:|=|->)', Operator.Word),
+ (u'(\\.{1,3}|\\||[\u039B]|[\u2200]|[\u2192]|:|=|->)', Operator.Word),
# Numbers
(r'\d+[eE][+-]?\d+', Number.Float),
(r'\d+\.\d+([eE][+-]?\d+)?', Number.Float),
@@ -1161,7 +1270,7 @@ class LiterateHaskellLexer(LiterateLexer):
is autodetected: if the first non-whitespace character in the source
is a backslash or percent character, LaTeX is assumed, else Bird.
- *New in Pygments 0.9.*
+ .. versionadded:: 0.9
"""
name = 'Literate Haskell'
aliases = ['lhs', 'literate-haskell', 'lhaskell']
@@ -1173,6 +1282,29 @@ class LiterateHaskellLexer(LiterateLexer):
LiterateLexer.__init__(self, hslexer, **options)
+class LiterateIdrisLexer(LiterateLexer):
+ """
+ For Literate Idris (Bird-style or LaTeX) source.
+
+ Additional options accepted:
+
+ `litstyle`
+ If given, must be ``"bird"`` or ``"latex"``. If not given, the style
+ is autodetected: if the first non-whitespace character in the source
+ is a backslash or percent character, LaTeX is assumed, else Bird.
+
+ .. versionadded:: 2.0
+ """
+ name = 'Literate Idris'
+ aliases = ['lidr', 'literate-idris', 'lidris']
+ filenames = ['*.lidr']
+ mimetypes = ['text/x-literate-idris']
+
+ def __init__(self, **options):
+ hslexer = IdrisLexer(**options)
+ LiterateLexer.__init__(self, hslexer, **options)
+
+
class LiterateAgdaLexer(LiterateLexer):
"""
For Literate Agda source.
@@ -1184,7 +1316,7 @@ class LiterateAgdaLexer(LiterateLexer):
is autodetected: if the first non-whitespace character in the source
is a backslash or percent character, LaTeX is assumed, else Bird.
- *New in Pygments 1.7.*
+ .. versionadded:: 2.0
"""
name = 'Literate Agda'
aliases = ['lagda', 'literate-agda']
@@ -1200,7 +1332,7 @@ class SMLLexer(RegexLexer):
"""
For the Standard ML language.
- *New in Pygments 1.5.*
+ .. versionadded:: 1.5
"""
name = 'Standard ML'
@@ -1526,7 +1658,7 @@ class OcamlLexer(RegexLexer):
"""
For the OCaml language.
- *New in Pygments 0.7.*
+ .. versionadded:: 0.7
"""
name = 'OCaml'
@@ -1620,7 +1752,7 @@ class ErlangLexer(RegexLexer):
Blame Jeremy Thurgood (http://jerith.za.net/).
- *New in Pygments 0.9.*
+ .. versionadded:: 0.9
"""
name = 'Erlang'
@@ -1725,7 +1857,7 @@ class ErlangShellLexer(Lexer):
"""
Shell sessions in erl (for Erlang code).
- *New in Pygments 1.1.*
+ .. versionadded:: 1.1
"""
name = 'Erlang erl session'
aliases = ['erl']
@@ -1768,7 +1900,7 @@ class OpaLexer(RegexLexer):
"""
Lexer for the Opa language (http://opalang.org).
- *New in Pygments 1.5.*
+ .. versionadded:: 1.5
"""
name = 'Opa'
@@ -2091,7 +2223,7 @@ class CoqLexer(RegexLexer):
"""
For the `Coq <http://coq.inria.fr/>`_ theorem prover.
- *New in Pygments 1.5.*
+ .. versionadded:: 1.5
"""
name = 'Coq'
@@ -2232,7 +2364,7 @@ class NewLispLexer(RegexLexer):
"""
For `newLISP. <www.newlisp.org>`_ source code (version 10.3.0).
- *New in Pygments 1.5.*
+ .. versionadded:: 1.5
"""
name = 'NewLisp'
@@ -2359,11 +2491,133 @@ class NewLispLexer(RegexLexer):
}
+class NixLexer(RegexLexer):
+ """
+ For the `Nix language <http://nixos.org/nix/>`_.
+
+ .. versionadded:: 2.0
+ """
+
+ name = 'Nix'
+ aliases = ['nixos', 'nix']
+ filenames = ['*.nix']
+ mimetypes = ['text/x-nix']
+
+ flags = re.MULTILINE | re.UNICODE
+
+ keywords = ['rec', 'with', 'let', 'in', 'inherit', 'assert', 'if',
+ 'else', 'then', '...']
+ builtins = ['import', 'abort', 'baseNameOf', 'dirOf', 'isNull', 'builtins',
+ 'map', 'removeAttrs', 'throw', 'toString', 'derivation']
+ operators = ['++', '+', '?', '.', '!', '//', '==',
+ '!=', '&&', '||', '->', '=']
+
+ punctuations = ["(", ")", "[", "]", ";", "{", "}", ":", ",", "@"]
+
+ tokens = {
+ 'root': [
+ # comments starting with #
+ (r'#.*$', Comment.Single),
+
+ # multiline comments
+ (r'/\*', Comment.Multiline, 'comment'),
+
+ # whitespace
+ (r'\s+', Text),
+
+ # keywords
+ ('(%s)' % '|'.join(re.escape(entry) + '\\b' for entry in keywords), Keyword),
+
+ # highlight the builtins
+ ('(%s)' % '|'.join(re.escape(entry) + '\\b' for entry in builtins),
+ Name.Builtin),
+
+ (r'\b(true|false|null)\b', Name.Constant),
+
+ # operators
+ ('(%s)' % '|'.join(re.escape(entry) for entry in operators),
+ Operator),
+
+ # word operators
+ (r'\b(or|and)\b', Operator.Word),
+
+ # punctuations
+ ('(%s)' % '|'.join(re.escape(entry) for entry in punctuations), Punctuation),
+
+ # integers
+ (r'[0-9]+', Number.Integer),
+
+ # strings
+ (r'"', String.Double, 'doublequote'),
+ (r"''", String.Single, 'singlequote'),
+
+ # paths
+ (r'[a-zA-Z0-9._+-]*(\/[a-zA-Z0-9._+-]+)+', Literal),
+ (r'\<[a-zA-Z0-9._+-]+(\/[a-zA-Z0-9._+-]+)*\>', Literal),
+
+ # urls
+ (r'[a-zA-Z][a-zA-Z0-9\+\-\.]*\:[a-zA-Z0-9%/?:@&=+$,\\_.!~*\'-]+', Literal),
+
+ # names of variables
+ (r'[a-zA-Z0-9-_]+\s*=', String.Symbol),
+ (r'[a-zA-Z_][a-zA-Z0-9_\'-]*', Text),
+
+ ],
+ 'comment': [
+ (r'[^/\*]+', Comment.Multiline),
+ (r'/\*', Comment.Multiline, '#push'),
+ (r'\*/', Comment.Multiline, '#pop'),
+ (r'[\*/]', Comment.Multiline),
+ ],
+ 'singlequote': [
+ (r"'''", String.Escape),
+ (r"''\$\{", String.Escape),
+ (r"''\n", String.Escape),
+ (r"''\r", String.Escape),
+ (r"''\t", String.Escape),
+ (r"''", String.Single, '#pop'),
+ (r'\$\{', String.Interpol, 'antiquote'),
+ (r"[^']", String.Single),
+ ],
+ 'doublequote': [
+ (r'\\', String.Escape),
+ (r'\\"', String.Escape),
+ (r'\\${', String.Escape),
+ (r'"', String.Double, '#pop'),
+ (r'\$\{', String.Interpol, 'antiquote'),
+ (r'[^"]', String.Double),
+ ],
+ 'antiquote': [
+ (r"}", String.Interpol, '#pop'),
+ # TODO: we should probably escape also here ''${ \${
+ (r"\$\{", String.Interpol, '#push'),
+ include('root'),
+ ],
+ }
+
+ def analyse_text(text):
+ rv = 0.0
+ # TODO: let/in
+ if re.search(r'import.+?<[^>]+>', text):
+ rv += 0.4
+ if re.search(r'mkDerivation\s+(\(|\{|rec)', text):
+ rv += 0.4
+ if re.search(r'with\s+[a-zA-Z\.]+;', text):
+ rv += 0.2
+ if re.search(r'inherit\s+[a-zA-Z()\.];', text):
+ rv += 0.2
+ if re.search(r'=\s+mkIf\s+', text):
+ rv += 0.4
+ if re.search(r'\{[a-zA-Z,\s]+\}:', text):
+ rv += 0.1
+ return rv
+
+
class ElixirLexer(RegexLexer):
"""
For the `Elixir language <http://elixir-lang.org>`_.
- *New in Pygments 1.5.*
+ .. versionadded:: 1.5
"""
name = 'Elixir'
@@ -2378,7 +2632,7 @@ class ElixirLexer(RegexLexer):
(r'(%[A-Ba-z])?"""(?:.|\n)*?"""', String.Doc),
(r"'''(?:.|\n)*?'''", String.Doc),
(r'"', String.Double, 'dqs'),
- (r"'.*'", String.Single),
+ (r"'.*?'", String.Single),
(r'(?<!\w)\?(\\(x\d{1,2}|\h{1,2}(?!\h)\b|0[0-7]{0,2}(?![0-7])\b|'
r'[^x0MC])|(\\[MC]-)+\w|[^\s\\])', String.Other)
]
@@ -2474,7 +2728,7 @@ class ElixirConsoleLexer(Lexer):
iex> length [head | tail]
3
- *New in Pygments 1.5.*
+ .. versionadded:: 1.5
"""
name = 'Elixir iex session'
@@ -2520,7 +2774,7 @@ class KokaLexer(RegexLexer):
Lexer for the `Koka <http://koka.codeplex.com>`_
language.
- *New in Pygments 1.6.*
+ .. versionadded:: 1.6
"""
name = 'Koka'