summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pygments/lexers/_mapping.py1
-rw-r--r--pygments/lexers/web.py118
-rw-r--r--tests/examplefiles/example.kal75
3 files changed, 193 insertions, 1 deletions
diff --git a/pygments/lexers/_mapping.py b/pygments/lexers/_mapping.py
index 3fe72269..2e9df4db 100644
--- a/pygments/lexers/_mapping.py
+++ b/pygments/lexers/_mapping.py
@@ -157,6 +157,7 @@ LEXERS = {
'JspLexer': ('pygments.lexers.templates', 'Java Server Page', ('jsp',), ('*.jsp',), ('application/x-jsp',)),
'JuliaConsoleLexer': ('pygments.lexers.math', 'Julia console', ('jlcon',), (), ()),
'JuliaLexer': ('pygments.lexers.math', 'Julia', ('julia', 'jl'), ('*.jl',), ('text/x-julia', 'application/x-julia')),
+ 'KalLexer': ('pygments.lexers.web', 'Kal', ('kal',), ('*.kal',), ('text/kal', 'application/kal')),
'KconfigLexer': ('pygments.lexers.other', 'Kconfig', ('kconfig', 'menuconfig', 'linux-config', 'kernel-config'), ('Kconfig', '*Config.in*', 'external.in*', 'standard-modules.in'), ('text/x-kconfig',)),
'KokaLexer': ('pygments.lexers.functional', 'Koka', ('koka',), ('*.kk', '*.kki'), ('text/x-koka',)),
'KotlinLexer': ('pygments.lexers.jvm', 'Kotlin', ('kotlin',), ('*.kt',), ('text/x-kotlin',)),
diff --git a/pygments/lexers/web.py b/pygments/lexers/web.py
index 6bc52da2..ab4758a4 100644
--- a/pygments/lexers/web.py
+++ b/pygments/lexers/web.py
@@ -27,7 +27,8 @@ __all__ = ['HtmlLexer', 'XmlLexer', 'JavascriptLexer', 'JsonLexer', 'CssLexer',
'MxmlLexer', 'HaxeLexer', 'HamlLexer', 'SassLexer', 'ScssLexer',
'ObjectiveJLexer', 'CoffeeScriptLexer', 'LiveScriptLexer',
'DuelLexer', 'ScamlLexer', 'JadeLexer', 'XQueryLexer',
- 'DtdLexer', 'DartLexer', 'LassoLexer', 'QmlLexer', 'TypeScriptLexer']
+ 'DtdLexer', 'DartLexer', 'LassoLexer', 'QmlLexer', 'TypeScriptLexer',
+ 'KalLexer']
class JavascriptLexer(RegexLexer):
@@ -2513,6 +2514,121 @@ class CoffeeScriptLexer(RegexLexer):
}
+class KalLexer(RegexLexer):
+ """
+ For `Kal`_ source code.
+
+ .. _Kal: http://rzimmerman.github.io/kal
+
+ """
+
+ name = 'Kal'
+ aliases = ['kal']
+ filenames = ['*.kal']
+ mimetypes = ['text/kal', 'application/kal']
+
+ flags = re.DOTALL
+ tokens = {
+ 'commentsandwhitespace': [
+ (r'\s+', Text),
+ (r'###[^#].*?###', Comment.Multiline),
+ (r'#(?!##[^#]).*?\n', Comment.Single),
+ ],
+ 'functiondef': [
+ (r'[$a-zA-Z_][a-zA-Z0-9_\$]*\s*', Name.Function, '#pop'),
+ include('commentsandwhitespace'),
+ ],
+ 'classdef': [
+ (r'\binherits\s+from\b', Keyword),
+ (r'[$a-zA-Z_][a-zA-Z0-9_\$]*\s*\n', Name.Class, '#pop'),
+ (r'[$a-zA-Z_][a-zA-Z0-9_\$]*\s*', Name.Class),
+ include('commentsandwhitespace'),
+ ],
+ 'listcomprehension': [
+ (r'\]', Punctuation, '#pop'),
+ (r'\b(property|value)\b', Keyword),
+ include('root'),
+ ],
+ 'waitfor': [
+ (r'\n', Punctuation, '#pop'),
+ (r'\bfrom\b', Keyword),
+ include('root'),
+ ],
+ 'root': [
+ include('commentsandwhitespace'),
+ (r'/(?! )(\\.|[^[/\\\n]|\[(\\.|[^\]\\\n])*])+/'
+ r'([gim]+\b|\B)', String.Regex),
+ (r'\?|:|_(?=\n)|==?|!=|-(?!>)|[<>+*/-]=?',
+ Operator),
+ (r'\band\b|\bor\b|\bis\b|\bisnt\b|\bnot\b|'
+ r'\bbut\b|\bbitwise\b|\bmod\b|\^|\bxor\b|\bexists\b|\bdoesnt\s+exist\b',
+ Operator.Word),
+ (r'(?:\([^()]+\))?\s*>', Name.Function),
+ (r'[{(]', Punctuation),
+ (r'\[', Punctuation, 'listcomprehension'),
+ (r'[})\]\.\,]', Punctuation),
+ (r'\b(function|method|task)\b', Keyword.Declaration, 'functiondef'),
+ (r'\bclass\b', Keyword.Declaration, 'classdef'),
+ (r'\b(safe\s+)?wait\s+for\b', Keyword, 'waitfor'),
+ (r'\b(me|this)(\.[$a-zA-Z_][a-zA-Z0-9_\.\$]*)?\b', Name.Variable.Instance),
+ (r'(?<![\.\$])(for(\s+(parallel|series))?|in|of|while|until|'
+ r'break|return|continue|'
+ r'when|if|unless|else|otherwise|except\s+when|'
+ r'throw|raise|fail\s+with|try|catch|finally|new|delete|'
+ r'typeof|instanceof|super|run\s+in\s+parallel|'
+ r'inherits\s+from)\b', Keyword),
+ (r'(?<![\.\$])(true|false|yes|no|on|off|null|nothing|none|'
+ r'NaN|Infinity|undefined)\b',
+ Keyword.Constant),
+ (r'(Array|Boolean|Date|Error|Function|Math|netscape|'
+ r'Number|Object|Packages|RegExp|String|sun|decodeURI|'
+ r'decodeURIComponent|encodeURI|encodeURIComponent|'
+ r'eval|isFinite|isNaN|parseFloat|parseInt|document|window|'
+ r'print)\b',
+ Name.Builtin),
+ (r'[$a-zA-Z_][a-zA-Z0-9_\.\$]*\s*(:|[\+\-\*\/]?\=)?\b', Name.Variable),
+ (r'[0-9][0-9]*\.[0-9]+([eE][0-9]+)?[fd]?', Number.Float),
+ (r'0x[0-9a-fA-F]+', Number.Hex),
+ (r'[0-9]+', Number.Integer),
+ ('"""', String, 'tdqs'),
+ ("'''", String, 'tsqs'),
+ ('"', String, 'dqs'),
+ ("'", String, 'sqs'),
+ ],
+ 'strings': [
+ (r'[^#\\\'"]+', String),
+ # note that all kal strings are multi-line.
+ # hashmarks, quotes and backslashes must be parsed one at a time
+ ],
+ 'interpoling_string' : [
+ (r'}', String.Interpol, "#pop"),
+ include('root')
+ ],
+ 'dqs': [
+ (r'"', String, '#pop'),
+ (r'\\.|\'', String), # double-quoted string don't need ' escapes
+ (r'#{', String.Interpol, "interpoling_string"),
+ include('strings')
+ ],
+ 'sqs': [
+ (r"'", String, '#pop'),
+ (r'#|\\.|"', String), # single quoted strings don't need " escapses
+ include('strings')
+ ],
+ 'tdqs': [
+ (r'"""', String, '#pop'),
+ (r'\\.|\'|"', String), # no need to escape quotes in triple-string
+ (r'#{', String.Interpol, "interpoling_string"),
+ include('strings'),
+ ],
+ 'tsqs': [
+ (r"'''", String, '#pop'),
+ (r'#|\\.|\'|"', String), # no need to escape quotes in triple-strings
+ include('strings')
+ ],
+ }
+
+
class LiveScriptLexer(RegexLexer):
"""
For `LiveScript`_ source code.
diff --git a/tests/examplefiles/example.kal b/tests/examplefiles/example.kal
new file mode 100644
index 00000000..c05c14ca
--- /dev/null
+++ b/tests/examplefiles/example.kal
@@ -0,0 +1,75 @@
+#!/usr/bin/env kal
+
+# This demo executes GET requests in parallel and in series
+# using `for` loops and `wait for` statements.
+
+# Notice how the serial GET requests always return in order
+# and take longer in total. Parallel requests come back in
+# order of receipt.
+
+http = require 'http'
+
+urls = ['http://www.google.com'
+ 'http://www.apple.com'
+ 'http://www.microsoft.com'
+ 'http://www.nodejs.org'
+ 'http://www.yahoo.com']
+
+# This function does a GET request for each URL in series
+# It will wait for a response from each request before moving on
+# to the next request. Notice the output will be in the same order as the
+# urls variable every time regardless of response time.
+# It is a task rather than a function because it is called asynchronously
+# This allows us to use `return` to implicitly call back
+task series_demo()
+ # The `series` keyword is optional here (for loops are serial by default)
+ total_time = 0
+
+ for series url in urls
+ timer = new Date
+
+ # we use the `safe` keyword because get is a "nonstandard" task
+ # that does not call back with an error argument
+ safe wait for response from http.get url
+
+ delay = new Date() - timer
+ total_time += delay
+
+ print "GET #{url} - #{response.statusCode} - #{response.connection.bytesRead} bytes - #{delay} ms"
+
+ # because we are in a task rather than a function, this actually exectutes a callback
+ return total_time
+
+# This function does a GET request for each URL in parallel
+# It will NOT wait for a response from each request before moving on
+# to the next request. Notice the output will be determined by the order in which
+# the requests complete!
+task parallel_demo()
+ total_time = 0
+
+ # The `parallel` keyword is only meaningful here because the loop contains
+ # a `wait for` statement (meaning callbacks are used)
+ for parallel url in urls
+ timer = new Date
+
+ # we use the `safe` keyword because get is a "nonstandard" task
+ # that does not call back with an error argument
+ safe wait for response from http.get url
+
+ delay = new Date() - timer
+ total_time += delay
+
+ print "GET #{url} - #{response.statusCode} - #{response.connection.bytesRead} bytes - #{delay}ms"
+
+ # because we are in a task rather than a function, this actually exectutes a callback
+ return total_time
+
+print 'Series Requests...'
+wait for time1 from series_demo()
+print "Total duration #{time1}ms"
+
+print ''
+
+print 'Parallel Requests...'
+wait for time2 from parallel_demo()
+print "Total duration #{time2}ms"