diff options
-rw-r--r-- | pygments/lexers/_mapping.py | 1 | ||||
-rw-r--r-- | pygments/lexers/compiled.py | 78 | ||||
-rw-r--r-- | tests/examplefiles/99_bottles_of_beer.chpl | 118 |
3 files changed, 196 insertions, 1 deletions
diff --git a/pygments/lexers/_mapping.py b/pygments/lexers/_mapping.py index 5e20c433..4bf3a25b 100644 --- a/pygments/lexers/_mapping.py +++ b/pygments/lexers/_mapping.py @@ -56,6 +56,7 @@ LEXERS = { 'CbmBasicV2Lexer': ('pygments.lexers.other', 'CBM BASIC V2', ('cbmbas',), ('*.bas',), ()), 'CeylonLexer': ('pygments.lexers.jvm', 'Ceylon', ('ceylon',), ('*.ceylon',), ('text/x-ceylon',)), 'Cfengine3Lexer': ('pygments.lexers.other', 'CFEngine3', ('cfengine3', 'cf3'), ('*.cf',), ()), + 'ChapelLexer': ('pygments.lexers.compiled', 'Chapel', ('chapel', 'chpl'), ('*.chpl',), ()), 'CheetahHtmlLexer': ('pygments.lexers.templates', 'HTML+Cheetah', ('html+cheetah', 'html+spitfire', 'htmlcheetah'), (), ('text/html+cheetah', 'text/html+spitfire')), 'CheetahJavascriptLexer': ('pygments.lexers.templates', 'JavaScript+Cheetah', ('js+cheetah', 'javascript+cheetah', 'js+spitfire', 'javascript+spitfire'), (), ('application/x-javascript+cheetah', 'text/x-javascript+cheetah', 'text/javascript+cheetah', 'application/x-javascript+spitfire', 'text/x-javascript+spitfire', 'text/javascript+spitfire')), 'CheetahLexer': ('pygments.lexers.templates', 'Cheetah', ('cheetah', 'spitfire'), ('*.tmpl', '*.spt'), ('application/x-cheetah', 'application/x-spitfire')), diff --git a/pygments/lexers/compiled.py b/pygments/lexers/compiled.py index 6dc3ea84..51656129 100644 --- a/pygments/lexers/compiled.py +++ b/pygments/lexers/compiled.py @@ -30,7 +30,8 @@ __all__ = ['CLexer', 'CppLexer', 'DLexer', 'DelphiLexer', 'ECLexer', 'Modula2Lexer', 'BlitzMaxLexer', 'BlitzBasicLexer', 'NimrodLexer', 'FantomLexer', 'RustLexer', 'CudaLexer', 'MonkeyLexer', 'SwigLexer', 'DylanLidLexer', 'DylanConsoleLexer', 'CobolLexer', - 'CobolFreeformatLexer', 'LogosLexer', 'ClayLexer', 'PikeLexer'] + 'CobolFreeformatLexer', 'LogosLexer', 'ClayLexer', 'PikeLexer', + 'ChapelLexer'] class CFamilyLexer(RegexLexer): @@ -3762,3 +3763,78 @@ class LogosLexer(ObjectiveCppLexer): if LogosLexer._logos_keywords.search(text): return 1.0 return 0 + + +class ChapelLexer(RegexLexer): + """ + For `Chapel <http://chapel.cray.com/>`_ source. + """ + name = 'Chapel' + filenames = ['*.chpl'] + aliases = ['chapel', 'chpl'] + # mimetypes = ['text/x-chapel'] + + tokens = { + 'root': [ + (r'\n', Text), + (r'\s+', Text), + (r'\\\n', Text), + + (r'//(.*?)\n', Comment.Single), + (r'/(\\\n)?[*](.|\n)*?[*](\\\n)?/', Comment.Multiline), + + (r'(config|const|in|inout|out|param|ref|type|var)\b', + Keyword.Declaration), + (r'(false|nil|true)\b', Keyword.Constant), + (r'(bool|complex|imag|int|opaque|range|real|string|uint)\b', + Keyword.Type), + (r'(atomic|begin|break|by|cobegin|coforall|continue|iter|' + r'delete|dmapped|do|domain|else|enum|export|extern|for|forall|' + r'if|index|inline|label|lambda|let|local|new|on|otherwise|' + r'reduce|return|scan|select|serial|single|sparse|' + r'subdomain|sync|then|use|when|where|while|yield|zip)\b', + Keyword), + (r'(proc)((?:\s|\\\s)+)', bygroups(Keyword, Text), 'procname'), + (r'(class|module|record|union)(\s+)', bygroups(Keyword, Text), + 'classname'), + + # imaginary integers + (r'\d+i', Number), + (r'\d+\.\d*([Ee][-+]\d+)?i', Number), + (r'\.\d+([Ee][-+]\d+)?i', Number), + (r'\d+[Ee][-+]\d+i', Number), + + # reals cannot end with a period due to lexical ambiguity with + # .. operator. See reference for rationale. + (r'(\d*\.\d+)([eE][+-]?[0-9]+)?i?', Number.Float), + (r'\d+[eE][+-]?[0-9]+i?', Number.Float), + + # integer literals + # -- binary + (r'0[bB][0-1]+', Number), + # -- hex + (r'0[xX][0-9a-fA-F]+', Number.Hex), + # -- decimal + (r'(0|[1-9][0-9]*)', Number.Integer), + + # strings + (r'["\'](\\\\|\\"|[^"\'])*["\']', String), + + # tokens + (r'(=|\+=|-=|\*=|/=|\*\*=|%=|&=|\|=|\^=|&&=|\|\|=|<<=|>>=|' + r'<=>|\.\.|by|#|\.\.\.|' + r'&&|\|\||!|&|\||\^|~|<<|>>|' + r'==|!=|<=|>=|<|>|' + r'[+\-*/%]|\*\*)', Operator), + (r'[:;,.?()\[\]{}]', Punctuation), + + # identifiers + (r'[a-zA-Z_][a-zA-Z0-9_$]*', Name.Other), + ], + 'classname': [ + (r'[a-zA-Z_][a-zA-Z0-9_$]*', Name.Class, '#pop'), + ], + 'procname': [ + (r'[a-zA-Z_][a-zA-Z0-9_$]*', Name.Function, '#pop'), + ], + } diff --git a/tests/examplefiles/99_bottles_of_beer.chpl b/tests/examplefiles/99_bottles_of_beer.chpl new file mode 100644 index 00000000..f73be7b1 --- /dev/null +++ b/tests/examplefiles/99_bottles_of_beer.chpl @@ -0,0 +1,118 @@ +/*********************************************************************** + * Chapel implementation of "99 bottles of beer" + * + * by Brad Chamberlain and Steve Deitz + * 07/13/2006 in Knoxville airport while waiting for flight home from + * HPLS workshop + * compiles and runs with chpl compiler version 1.7.0 + * for more information, contact: chapel_info@cray.com + * + * + * Notes: + * o as in all good parallel computations, boundary conditions + * constitute the vast bulk of complexity in this code (invite Brad to + * tell you about his zany boundary condition simplification scheme) + * o uses type inference for variables, arguments + * o relies on integer->string coercions + * o uses named argument passing (for documentation purposes only) + ***********************************************************************/ + +// allow executable command-line specification of number of bottles +// (e.g., ./a.out -snumBottles=999999) +config const numBottles = 99; +const numVerses = numBottles+1; + +// a domain to describe the space of lyrics +var LyricsSpace: domain(1) = {1..numVerses}; + +// array of lyrics +var Lyrics: [LyricsSpace] string; + +// parallel computation of lyrics array +[verse in LyricsSpace] Lyrics(verse) = computeLyric(verse); + +// as in any good parallel language, I/O to stdout is serialized. +// (Note that I/O to a file could be parallelized using a parallel +// prefix computation on the verse strings' lengths with file seeking) +writeln(Lyrics); + + +// HELPER FUNCTIONS: + +proc computeLyric(verseNum) { + var bottleNum = numBottles - (verseNum - 1); + var nextBottle = (bottleNum + numVerses - 1)%numVerses; + return "\n" // disguise space used to separate elements in array I/O + + describeBottles(bottleNum, startOfVerse=true) + " on the wall, " + + describeBottles(bottleNum) + ".\n" + + computeAction(bottleNum) + + describeBottles(nextBottle) + " on the wall.\n"; +} + + +proc describeBottles(bottleNum, startOfVerse:bool = false) { + // NOTE: bool should not be necessary here (^^^^); working around bug + var bottleDescription = if (bottleNum) then bottleNum:string + else (if startOfVerse then "N" + else "n") + + "o more"; + return bottleDescription + + " bottle" + (if (bottleNum == 1) then "" else "s") + + " of beer"; +} + + +proc computeAction(bottleNum) { + return if (bottleNum == 0) then "Go to the store and buy some more, " + else "Take one down and pass it around, "; +} + + +// Modules... +module M1 { + var x = 10; +} + +module M2 { + use M1; + proc main() { + writeln("M2 -> M1 -> x " + x); + } +} + + +// Classes, records, unions... +const PI: real = 3.14159; + +record Point { + var x, y: real; +} +var p: Point; +writeln("Distance from origin: " + sqrt(p.x ** 2 + p.y ** 2)); +p = new Point(1.0, 2.0); +writeln("Distance from origin: " + sqrt(p.x ** 2 + p.y ** 2)); + +class Circle { + var p: Point; + var r: real; +} +var c = new Circle(r=2.0); +proc Circle.area() + return PI * r ** 2; +writeln("Area of circle: " + c.area()); + +class Oval: Circle { + var r2: real; +} +proc Oval.area() + return PI * r * r2; + +delete c; +c = nil; +c = new Oval(r=1.0, r2=2.0); +writeln("Area of oval: " + c.area()); + +union U { + var i: int; + var r: real; +} |