diff options
author | Georg Brandl <georg@python.org> | 2021-03-14 11:19:45 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-14 11:19:45 +0100 |
commit | 47e1e1bc7ea022e9ce4362fe3940369da3d61a05 (patch) | |
tree | 4921cca8b579838f9e92cbc39fc2d3449ed57036 | |
parent | bc2476b0716d2ece7ba991a63942aa08d5107e34 (diff) | |
download | pygments-git-47e1e1bc7ea022e9ce4362fe3940369da3d61a05.tar.gz |
Add KuinLexer (#1300)
* Add KuinLexer
* Add golden test output.
* Update mapfiles.
* Update URL.
* Fix regex lint failures.
Co-authored-by: tatt61880 <tatt61880@gmail.com>
Co-authored-by: Matthäus G. Chajdas <dev@anteru.net>
-rw-r--r-- | AUTHORS | 1 | ||||
-rw-r--r-- | pygments/lexers/_mapping.py | 1 | ||||
-rw-r--r-- | pygments/lexers/kuin.py | 299 | ||||
-rw-r--r-- | tests/examplefiles/kuin/example.kn | 37 | ||||
-rw-r--r-- | tests/examplefiles/kuin/example.kn.output | 366 |
5 files changed, 704 insertions, 0 deletions
@@ -208,6 +208,7 @@ Other contributors, listed alphabetically, are: * Tom Stuart -- Treetop lexer * Colin Sullivan -- SuperCollider lexer * Ben Swift -- Extempore lexer +* tatt61880 -- Kuin lexer * Edoardo Tenani -- Arduino lexer * Tiberius Teng -- default style overhaul * Jeremy Thurgood -- Erlang, Squid config lexers diff --git a/pygments/lexers/_mapping.py b/pygments/lexers/_mapping.py index b2cb6f99..25474ac2 100644 --- a/pygments/lexers/_mapping.py +++ b/pygments/lexers/_mapping.py @@ -243,6 +243,7 @@ LEXERS = { 'KernelLogLexer': ('pygments.lexers.textfmts', 'Kernel log', ('kmsg', 'dmesg'), ('*.kmsg', '*.dmesg'), ()), 'KokaLexer': ('pygments.lexers.haskell', 'Koka', ('koka',), ('*.kk', '*.kki'), ('text/x-koka',)), 'KotlinLexer': ('pygments.lexers.jvm', 'Kotlin', ('kotlin',), ('*.kt', '*.kts'), ('text/x-kotlin',)), + 'KuinLexer': ('pygments.lexers.kuin', 'Kuin', ('kuin',), ('*.kn',), ()), 'LSLLexer': ('pygments.lexers.scripting', 'LSL', ('lsl',), ('*.lsl',), ('text/x-lsl',)), 'LassoCssLexer': ('pygments.lexers.templates', 'CSS+Lasso', ('css+lasso',), (), ('text/css+lasso',)), 'LassoHtmlLexer': ('pygments.lexers.templates', 'HTML+Lasso', ('html+lasso',), (), ('text/html+lasso', 'application/x-httpd-lasso', 'application/x-httpd-lasso[89]')), diff --git a/pygments/lexers/kuin.py b/pygments/lexers/kuin.py new file mode 100644 index 00000000..5800db9c --- /dev/null +++ b/pygments/lexers/kuin.py @@ -0,0 +1,299 @@ +# -*- coding: utf-8 -*- +""" + pygments.lexers.kuin + ~~~~~~~~~~~~~~~~~~~~ + + Lexers for the Kuin language. +""" + +from pygments.lexer import RegexLexer, include, using, inherit, this, bygroups, words +from pygments.token import Text, Comment, Operator, Keyword, Name, String, Number, Punctuation + +__all__ = ['KuinLexer'] + +class KuinLexer(RegexLexer): + """ + For `Kuin <https://github.com/kuina/Kuin>`_ source code + + .. versionadded:: 2.9 + """ + name = 'Kuin' + aliases = ['kuin'] + filenames = ['*.kn'] + + tokens = { + 'root': [ + include('statement'), + ], + 'statement': [ + # Whitespace / Comment + include('whitespace'), + + # Block-statement + (r'(\+?[ \t]*\*?[ \t]*\bfunc)([ \t]+(?:\n\s*\|)*[ \t]*)([a-zA-Z_][0-9a-zA-Z_]*)', bygroups(Keyword, using(this), Name.Function), 'func_'), + (r'\b(class)([ \t]+(?:\n\s*\|)*[ \t]*)([a-zA-Z_][0-9a-zA-Z_]*)', bygroups(Keyword, using(this), Name.Class), 'class_'), + (r'\b(enum)([ \t]+(?:\n\s*\|)*[ \t]*)([a-zA-Z_][0-9a-zA-Z_]*)', bygroups(Keyword, using(this), Name.Constant), 'enum_'), + (r'\b(block)\b(?:([ \t]+(?:\n\s*\|)*[ \t]*)([a-zA-Z_][0-9a-zA-Z_]*))?', bygroups(Keyword, using(this), Name.Other), 'block_'), + (r'\b(ifdef)\b(?:([ \t]+(?:\n\s*\|)*[ \t]*)([a-zA-Z_][0-9a-zA-Z_]*))?', bygroups(Keyword, using(this), Name.Other), 'ifdef_'), + (r'\b(if)\b(?:([ \t]+(?:\n\s*\|)*[ \t]*)([a-zA-Z_][0-9a-zA-Z_]*))?', bygroups(Keyword, using(this), Name.Other), 'if_'), + (r'\b(switch)\b(?:([ \t]+(?:\n\s*\|)*[ \t]*)([a-zA-Z_][0-9a-zA-Z_]*))?', bygroups(Keyword, using(this), Name.Other), 'switch_'), + (r'\b(while)\b(?:([ \t]+(?:\n\s*\|)*[ \t]*)([a-zA-Z_][0-9a-zA-Z_]*))?', bygroups(Keyword, using(this), Name.Other), 'while_'), + (r'\b(for)\b(?:([ \t]+(?:\n\s*\|)*[ \t]*)([a-zA-Z_][0-9a-zA-Z_]*))?', bygroups(Keyword, using(this), Name.Other), 'for_'), + (r'\b(foreach)\b(?:([ \t]+(?:\n\s*\|)*[ \t]*)([a-zA-Z_][0-9a-zA-Z_]*))?', bygroups(Keyword, using(this), Name.Other), 'foreach_'), + (r'\b(try)\b(?:([ \t]+(?:\n\s*\|)*[ \t]*)([a-zA-Z_][0-9a-zA-Z_]*))?', bygroups(Keyword, using(this), Name.Other), 'try_'), + + # Line-statement + (r'\b(do)\b', Keyword, 'do'), + (r'(\+?[ \t]*\bvar)\b', Keyword, 'var'), + (r'\b(const)\b', Keyword, 'const'), + (r'\b(ret)\b', Keyword, 'ret'), + (r'\b(throw)\b', Keyword, 'throw'), + (r'\b(alias)\b', Keyword, 'alias'), + (r'\b(assert)\b', Keyword, 'assert'), + (r'\|', Text, 'continued_line'), + (r'[ \t]*\n', Text), + ], + + # Whitespace / Comment + 'whitespace': [ + (r'^[ \t]*;.*', Comment.Single), + (r'[ \t]+(?![; \t])', Text), + (r'\{', Comment.Multiline, 'multiline_comment'), + ], + 'multiline_comment': [ + (r'\{', Comment.Multiline, 'multiline_comment'), + (r'(?:\s*;.*|[^{}\n]+)', Comment.Multiline), + (r'\n', Comment.Multiline), + (r'\}', Comment.Multiline, '#pop'), + ], + + # Block-statement + 'func_': [ + include('expr'), + (r'\n', Text, 'func'), + ], + 'func': [ + (r'\b(end)([ \t]+(?:\n\s*\|)*[ \t]*)(func)\b', bygroups(Keyword, using(this), Keyword), '#pop:2'), + include('statement'), + ], + 'class_': [ + include('expr'), + (r'\n', Text, 'class'), + ], + 'class': [ + (r'\b(end)([ \t]+(?:\n\s*\|)*[ \t]*)(class)\b', bygroups(Keyword, using(this), Keyword), '#pop:2'), + include('statement'), + ], + 'enum_': [ + include('expr'), + (r'\n', Text, 'enum'), + ], + 'enum': [ + (r'\b(end)([ \t]+(?:\n\s*\|)*[ \t]*)(enum)\b', bygroups(Keyword, using(this), Keyword), '#pop:2'), + include('expr'), + (r'\n', Text), + ], + 'block_': [ + include('expr'), + (r'\n', Text, 'block'), + ], + 'block': [ + (r'\b(end)([ \t]+(?:\n\s*\|)*[ \t]*)(block)\b', bygroups(Keyword, using(this), Keyword), '#pop:2'), + include('statement'), + include('break'), + include('skip'), + ], + 'ifdef_': [ + include('expr'), + (r'\n', Text, 'ifdef'), + ], + 'ifdef': [ + (r'\b(end)([ \t]+(?:\n\s*\|)*[ \t]*)(ifdef)\b', bygroups(Keyword, using(this), Keyword), '#pop:2'), + (words(('rls', 'dbg'), prefix=r'\b', suffix=r'\b'), Keyword.Constant, 'ifdef_sp'), + include('statement'), + include('break'), + include('skip'), + ], + 'ifdef_sp': [ + include('expr'), + (r'\n', Text, '#pop'), + ], + 'if_': [ + include('expr'), + (r'\n', Text, 'if'), + ], + 'if': [ + (r'\b(end)([ \t]+(?:\n\s*\|)*[ \t]*)(if)\b', bygroups(Keyword, using(this), Keyword), '#pop:2'), + (words(('elif', 'else'), prefix=r'\b', suffix=r'\b'), Keyword, 'if_sp'), + include('statement'), + include('break'), + include('skip'), + ], + 'if_sp': [ + include('expr'), + (r'\n', Text, '#pop'), + ], + 'switch_': [ + include('expr'), + (r'\n', Text, 'switch'), + ], + 'switch': [ + (r'\b(end)([ \t]+(?:\n\s*\|)*[ \t]*)(switch)\b', bygroups(Keyword, using(this), Keyword), '#pop:2'), + (words(('case', 'default', 'to'), prefix=r'\b', suffix=r'\b'), Keyword, 'switch_sp'), + include('statement'), + include('break'), + include('skip'), + ], + 'switch_sp': [ + include('expr'), + (r'\n', Text, '#pop'), + ], + 'while_': [ + include('expr'), + (r'\n', Text, 'while'), + ], + 'while': [ + (r'\b(end)([ \t]+(?:\n\s*\|)*[ \t]*)(while)\b', bygroups(Keyword, using(this), Keyword), '#pop:2'), + include('statement'), + include('break'), + include('skip'), + ], + 'for_': [ + include('expr'), + (r'\n', Text, 'for'), + ], + 'for': [ + (r'\b(end)([ \t]+(?:\n\s*\|)*[ \t]*)(for)\b', bygroups(Keyword, using(this), Keyword), '#pop:2'), + include('statement'), + include('break'), + include('skip'), + ], + 'foreach_': [ + include('expr'), + (r'\n', Text, 'foreach'), + ], + 'foreach': [ + (r'\b(end)([ \t]+(?:\n\s*\|)*[ \t]*)(foreach)\b', bygroups(Keyword, using(this), Keyword), '#pop:2'), + include('statement'), + include('break'), + include('skip'), + ], + 'try_': [ + include('expr'), + (r'\n', Text, 'try'), + ], + 'try': [ + (r'\b(end)([ \t]+(?:\n\s*\|)*[ \t]*)(try)\b', bygroups(Keyword, using(this), Keyword), '#pop:2'), + (words(('catch', 'finally', 'to'), prefix=r'\b', suffix=r'\b'), Keyword, 'try_sp'), + include('statement'), + include('break'), + include('skip'), + ], + 'try_sp': [ + include('expr'), + (r'\n', Text, '#pop'), + ], + + # Line-statement + 'break': [ + (r'\b(break)\b([ \t]+)([a-zA-Z_][0-9a-zA-Z_]*)', bygroups(Keyword, using(this), Name.Other)), + ], + 'skip': [ + (r'\b(skip)\b([ \t]+)([a-zA-Z_][0-9a-zA-Z_]*)', bygroups(Keyword, using(this), Name.Other)), + ], + 'alias': [ + include('expr'), + (r'\n', Text, '#pop'), + ], + 'assert': [ + include('expr'), + (r'\n', Text, '#pop'), + ], + 'const': [ + include('expr'), + (r'\n', Text, '#pop'), + ], + 'do': [ + include('expr'), + (r'\n', Text, '#pop'), + ], + 'ret': [ + include('expr'), + (r'\n', Text, '#pop'), + ], + 'throw': [ + include('expr'), + (r'\n', Text, '#pop'), + ], + 'var': [ + include('expr'), + (r'\n', Text, '#pop'), + ], + 'continued_line': [ + include('expr'), + (r'\n', Text, '#pop'), + ], + + 'expr': [ + # Whitespace / Comment + include('whitespace'), + + # Punctuation + (r'\(', Punctuation,), + (r'\)', Punctuation,), + (r'\[', Punctuation,), + (r'\]', Punctuation,), + (r',', Punctuation), + + # Keyword + (words(( + 'true', 'false', 'null', 'inf' + ), prefix=r'\b', suffix=r'\b'), Keyword.Constant), + (words(( + 'me' + ), prefix=r'\b', suffix=r'\b'), Keyword), + (words(( + 'bit16', 'bit32', 'bit64', 'bit8', 'bool', + 'char', 'class', 'dict', 'enum', 'float', 'func', + 'int', 'list', 'queue', 'stack' + ), prefix=r'\b', suffix=r'\b'), Keyword.Type), + + # Number + (r'\b[0-9]\.[0-9]+(?!\.)(:?e[\+-][0-9]+)?\b', Number.Float), + (r'\b2#[01]+(?:b(?:8|16|32|64))?\b', Number.Bin), + (r'\b8#[0-7]+(?:b(?:8|16|32|64))?\b', Number.Oct), + (r'\b16#[0-9A-F]+(?:b(?:8|16|32|64))?\b', Number.Hex), + (r'\b[0-9]+(?:b(?:8|16|32|64))?\b', Number.Decimal), + + # String / Char + (r'"', String.Double, 'string'), + (r"'(?:\\.|.)+?'", String.Char), + + # Operator + (r'(?:\.|\$(?:>|<)?)', Operator), + (r'(?:\^)', Operator), + (r'(?:\+|-|!|##?)', Operator), + (r'(?:\*|/|%)', Operator), + (r'(?:~)', Operator), + (r'(?:(?:=|<>)(?:&|\$)?|<=?|>=?)', Operator), + (r'(?:&)', Operator), + (r'(?:\|)', Operator), + (r'(?:\?)', Operator), + (r'(?::(?::|\+|-|\*|/|%|\^|~)?)', Operator), + + # Identifier + (r"\b([a-zA-Z_][0-9a-zA-Z_]*)(?=@)\b", Name), + (r"(@)?\b([a-zA-Z_][0-9a-zA-Z_]*)\b", bygroups(Name.Other, Name.Variable)), + ], + + # String + 'string': [ + (r'(?:\\[^{\n]|[^"\\])+', String.Double), + (r'\\\{', String.Double, 'toStrInString'), + (r'"', String.Double, '#pop'), + ], + 'toStrInString': [ + include('expr'), + (r'\}', String.Double, '#pop'), + ], + } diff --git a/tests/examplefiles/kuin/example.kn b/tests/examplefiles/kuin/example.kn new file mode 100644 index 00000000..f3ea1ea2 --- /dev/null +++ b/tests/examplefiles/kuin/example.kn @@ -0,0 +1,37 @@ +{ Quine in Kuin. @tatt61880 } +func main() + func quine(str: []char) + var s: []char :: "" + foreach c(str) + switch(c) + case '\n' + do s :~ "\\n\" ~\n | \"" + case '\\', '"' + do s :~ "\\\{c}" + default + do s :~ c.toStr() + end switch + end foreach + do cui@print(str ~ s ~ "\"\n do quine(str)\nend func\n") + end func + const str: []char :: "" ~ + | "{ Quine in Kuin. @tatt61880 }\n" ~ + | "func main()\n" ~ + | " func quine(str: []char)\n" ~ + | " var s: []char :: \"\"\n" ~ + | " foreach c(str)\n" ~ + | " switch(c)\n" ~ + | " case '\\n'\n" ~ + | " do s :~ \"\\\\n\\\" ~\\n | \\\"\"\n" ~ + | " case '\\\\', '\"'\n" ~ + | " do s :~ \"\\\\\\{c}\"\n" ~ + | " default\n" ~ + | " do s :~ c.toStr()\n" ~ + | " end switch\n" ~ + | " end foreach\n" ~ + | " do cui@print(str ~ s ~ \"\\\"\\n do quine(str)\\nend func\\n\")\n" ~ + | " end func\n" ~ + | " const str: []char :: \"\" ~\n" ~ + | " | \"" + do quine(str) +end func diff --git a/tests/examplefiles/kuin/example.kn.output b/tests/examplefiles/kuin/example.kn.output new file mode 100644 index 00000000..a7c66736 --- /dev/null +++ b/tests/examplefiles/kuin/example.kn.output @@ -0,0 +1,366 @@ +'{' Comment.Multiline +' Quine in Kuin. @tatt61880 ' Comment.Multiline +'}' Comment.Multiline +'\n' Text + +'func' Keyword +' ' Text +'main' Name.Function +'(' Punctuation +')' Punctuation +'\n' Text + +' ' Text +'func' Keyword +' ' Text +'quine' Name.Function +'(' Punctuation +'str' Name.Variable +':' Operator +' ' Text +'[' Punctuation +']' Punctuation +'char' Keyword.Type +')' Punctuation +'\n' Text + +' ' Text +'var' Keyword +' ' Text +'s' Name.Variable +':' Operator +' ' Text +'[' Punctuation +']' Punctuation +'char' Keyword.Type +' ' Text +'::' Operator +' ' Text +'"' Literal.String.Double +'"' Literal.String.Double +'\n' Text + +' ' Text +'foreach' Keyword +' ' Text +'c' Name.Other +'(' Punctuation +'str' Name.Variable +')' Punctuation +'\n' Text + +' ' Text +'switch' Keyword +'(' Punctuation +'c' Name.Variable +')' Punctuation +'\n' Text + +' ' Text +'case' Keyword +' ' Text +"'\\n'" Literal.String.Char +'\n' Text + +' ' Text +'do' Keyword +' ' Text +'s' Name.Variable +' ' Text +':~' Operator +' ' Text +'"' Literal.String.Double +'\\\\n\\" ~\\n | \\"' Literal.String.Double +'"' Literal.String.Double +'\n' Text + +' ' Text +'case' Keyword +' ' Text +"'\\\\'" Literal.String.Char +',' Punctuation +' ' Text +'\'"\'' Literal.String.Char +'\n' Text + +' ' Text +'do' Keyword +' ' Text +'s' Name.Variable +' ' Text +':~' Operator +' ' Text +'"' Literal.String.Double +'\\\\' Literal.String.Double +'\\{' Literal.String.Double +'c' Name.Variable +'}' Literal.String.Double +'"' Literal.String.Double +'\n' Text + +' ' Text +'default' Keyword +'\n' Text + +' ' Text +'do' Keyword +' ' Text +'s' Name.Variable +' ' Text +':~' Operator +' ' Text +'c' Name.Variable +'.' Operator +'toStr' Name.Variable +'(' Punctuation +')' Punctuation +'\n' Text + +' ' Text +'end' Keyword +' ' Text +'switch' Keyword +'\n' Text + +' ' Text +'end' Keyword +' ' Text +'foreach' Keyword +'\n' Text + +' ' Text +'do' Keyword +' ' Text +'cui' Name +'@' Name.Other +'print' Name.Variable +'(' Punctuation +'str' Name.Variable +' ' Text +'~' Operator +' ' Text +'s' Name.Variable +' ' Text +'~' Operator +' ' Text +'"' Literal.String.Double +'\\"\\n do quine(str)\\nend func\\n' Literal.String.Double +'"' Literal.String.Double +')' Punctuation +'\n' Text + +' ' Text +'end' Keyword +' ' Text +'func' Keyword +'\n' Text + +' ' Text +'const' Keyword +' ' Text +'str' Name.Variable +':' Operator +' ' Text +'[' Punctuation +']' Punctuation +'char' Keyword.Type +' ' Text +'::' Operator +' ' Text +'"' Literal.String.Double +'"' Literal.String.Double +' ' Text +'~' Operator +'\n' Text + +' ' Text +'|' Text +' ' Text +'"' Literal.String.Double +'{ Quine in Kuin. @tatt61880 }\\n' Literal.String.Double +'"' Literal.String.Double +' ' Text +'~' Operator +'\n' Text + +' ' Text +'|' Text +' ' Text +'"' Literal.String.Double +'func main()\\n' Literal.String.Double +'"' Literal.String.Double +' ' Text +'~' Operator +'\n' Text + +' ' Text +'|' Text +' ' Text +'"' Literal.String.Double +' func quine(str: []char)\\n' Literal.String.Double +'"' Literal.String.Double +' ' Text +'~' Operator +'\n' Text + +' ' Text +'|' Text +' ' Text +'"' Literal.String.Double +' var s: []char :: \\"\\"\\n' Literal.String.Double +'"' Literal.String.Double +' ' Text +'~' Operator +'\n' Text + +' ' Text +'|' Text +' ' Text +'"' Literal.String.Double +' foreach c(str)\\n' Literal.String.Double +'"' Literal.String.Double +' ' Text +'~' Operator +'\n' Text + +' ' Text +'|' Text +' ' Text +'"' Literal.String.Double +' switch(c)\\n' Literal.String.Double +'"' Literal.String.Double +' ' Text +'~' Operator +'\n' Text + +' ' Text +'|' Text +' ' Text +'"' Literal.String.Double +" case '\\\\n'\\n" Literal.String.Double +'"' Literal.String.Double +' ' Text +'~' Operator +'\n' Text + +' ' Text +'|' Text +' ' Text +'"' Literal.String.Double +' do s :~ \\"\\\\\\\\n\\\\\\" ~\\\\n | \\\\\\"\\"\\n' Literal.String.Double +'"' Literal.String.Double +' ' Text +'~' Operator +'\n' Text + +' ' Text +'|' Text +' ' Text +'"' Literal.String.Double +' case \'\\\\\\\\\', \'\\"\'\\n' Literal.String.Double +'"' Literal.String.Double +' ' Text +'~' Operator +'\n' Text + +' ' Text +'|' Text +' ' Text +'"' Literal.String.Double +' do s :~ \\"\\\\\\\\\\\\{c}\\"\\n' Literal.String.Double +'"' Literal.String.Double +' ' Text +'~' Operator +'\n' Text + +' ' Text +'|' Text +' ' Text +'"' Literal.String.Double +' default\\n' Literal.String.Double +'"' Literal.String.Double +' ' Text +'~' Operator +'\n' Text + +' ' Text +'|' Text +' ' Text +'"' Literal.String.Double +' do s :~ c.toStr()\\n' Literal.String.Double +'"' Literal.String.Double +' ' Text +'~' Operator +'\n' Text + +' ' Text +'|' Text +' ' Text +'"' Literal.String.Double +' end switch\\n' Literal.String.Double +'"' Literal.String.Double +' ' Text +'~' Operator +'\n' Text + +' ' Text +'|' Text +' ' Text +'"' Literal.String.Double +' end foreach\\n' Literal.String.Double +'"' Literal.String.Double +' ' Text +'~' Operator +'\n' Text + +' ' Text +'|' Text +' ' Text +'"' Literal.String.Double +' do cui@print(str ~ s ~ \\"\\\\\\"\\\\n do quine(str)\\\\nend func\\\\n\\")\\n' Literal.String.Double +'"' Literal.String.Double +' ' Text +'~' Operator +'\n' Text + +' ' Text +'|' Text +' ' Text +'"' Literal.String.Double +' end func\\n' Literal.String.Double +'"' Literal.String.Double +' ' Text +'~' Operator +'\n' Text + +' ' Text +'|' Text +' ' Text +'"' Literal.String.Double +' const str: []char :: \\"\\" ~\\n' Literal.String.Double +'"' Literal.String.Double +' ' Text +'~' Operator +'\n' Text + +' ' Text +'|' Text +' ' Text +'"' Literal.String.Double +' | \\"' Literal.String.Double +'"' Literal.String.Double +'\n' Text + +' ' Text +'do' Keyword +' ' Text +'quine' Name.Variable +'(' Punctuation +'str' Name.Variable +')' Punctuation +'\n' Text + +'end' Keyword +' ' Text +'func' Keyword +'\n' Text |