Commits

Tim Hatch  committed aeb24ac Merge

Merged in daanl/pygments-main (pull request #102)

  • Participants
  • Parent commits 7cbffee, 6e9f232

Comments (0)

Files changed (3)

File pygments/lexers/_mapping.py

     'JuliaConsoleLexer': ('pygments.lexers.math', 'Julia console', ('jlcon',), (), ()),
     'JuliaLexer': ('pygments.lexers.math', 'Julia', ('julia', 'jl'), ('*.jl',), ('text/x-julia', 'application/x-julia')),
     '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',)),
     '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]')),

File pygments/lexers/functional.py

 __all__ = ['RacketLexer', 'SchemeLexer', 'CommonLispLexer', 'HaskellLexer',
            'LiterateHaskellLexer', 'SMLLexer', 'OcamlLexer', 'ErlangLexer',
            'ErlangShellLexer', 'OpaLexer', 'CoqLexer', 'NewLispLexer',
-           'ElixirLexer', 'ElixirConsoleLexer']
+           'ElixirLexer', 'ElixirConsoleLexer', 'KokaLexer' ]
 
 
 class RacketLexer(RegexLexer):
             for item in do_insertions(insertions,
                                       exlexer.get_tokens_unprocessed(curcode)):
                 yield item
+
+
+class KokaLexer(RegexLexer):
+    """
+    Lexer for the Koka language.
+    """
+
+    name = 'Koka'
+    aliases = ['koka']
+    filenames = ['*.kk', '*.kki']
+    mimetypes = ['text/x-koka']
+
+    keywords = [
+        'infix', 'infixr', 'infixl', 'prefix', 'postfix',
+        'type', 'cotype', 'rectype', 'alias',
+        'struct', 'con',
+        'fun', 'function', 'val', 'var',
+        'external',
+        'if', 'then', 'else', 'elif', 'return', 'match',
+        'private', 'public', 'private',
+        'module', 'import', 'as',
+        'include', 'inline',
+        'rec',
+        'try', 'yield', 'enum',
+        'interface', 'instance'
+    ]
+
+    # keywords that are followed by a type
+    typeStartKeywords = [
+        'type','cotype','rectype','alias','struct','enum'
+    ]
+
+    # keywords valid in a type
+    typekeywords = [
+        'forall', 'exists', 'some', 'with'      
+    ]
+
+    # builtin names and special names
+    builtin = [
+        'for', 'while', 'repeat',
+        'foreach', 'foreach-indexed', 
+        'error', 'catch', 'finally',
+        'cs', 'js', 'file', 'ref', 'assigned'
+    ]
+
+    # symbols that can be in an operator
+    symbols = '[\$%&\*\+@!/\\\^~=\.:\-\?\|<>]+'
+
+    # symbol boundary: an operator keyword should not be followed by any of these
+    sboundary = '(?!'+symbols+')'
+
+    # name boundary: a keyword should not be followed by any of these
+    boundary = '(?![a-zA-Z0-9_\\-])'
+
+    # main lexer
+    tokens = {
+        'root': [       
+            include('whitespace'),
+
+            # go into type mode
+            (r'::?'+sboundary, Keyword.Type, 'type'),
+            (r'alias'+boundary, Keyword,'alias-type'),
+            (r'struct'+boundary, Keyword,'struct-type'),
+            (r'(%s)' % '|'.join(typeStartKeywords)+boundary, Keyword, 'type'),
+
+            # special sequences of tokens (we use ?: for non-capturing group as required by 'bygroups')
+            (r'(module)(\s*)((?:interface)?)(\s*)((?:[a-z](?:[a-zA-Z0-9_]|\-[a-zA-Z])*\.)*[a-z](?:[a-zA-Z0-9_]|\-[a-zA-Z])*)'
+                , bygroups(Keyword,Text,Keyword,Text,Name.Namespace)),
+            (r'(import)(\s+)((?:[a-z](?:[a-zA-Z0-9_]|\-[a-zA-Z])*\.)*[a-z](?:[a-zA-Z0-9_]|\-[a-zA-Z])*)(\s*)((?:as)?)((?:[A-Z](?:[a-zA-Z0-9_]|\-[a-zA-Z])*)?)'
+                , bygroups(Keyword,Text,Name.Namespace,Text,Keyword,Name.Namespace)),
+
+            # keywords
+            (r'(%s)' % '|'.join(typekeywords) + boundary, Keyword.Type),
+            (r'(%s)' % '|'.join(keywords) + boundary, Keyword),
+            (r'(%s)' % '|'.join(builtin) + boundary, Keyword.Pseudo),
+            (r'::|:=|\->|[=\.:]' + sboundary, Keyword),
+            (r'\-' + sboundary, Generic.Strong),
+
+            # names
+            (r'[A-Z]([a-zA-Z0-9_]|\-[a-zA-Z])*(?=\.)',Name.Namespace),            
+            (r'[A-Z]([a-zA-Z0-9_]|\-[a-zA-Z])*(?!\.)',Name.Class),
+            (r'[a-z]([a-zA-Z0-9_]|\-[a-zA-Z])*',Name),
+            (r'_([a-zA-Z0-9_]|\-[a-zA-Z])*',Name.Variable),
+
+            # literal string
+            (r'@"', String.Double, 'litstring'),
+            
+            # operators
+            (symbols, Operator),
+            (r'`', Operator),
+            (r'[\{\}\(\)\[\];,]', Punctuation),
+
+            # literals. No check for literal characters with too many characters in it.
+            (r'[0-9]+\.[0-9]+([eE][\-\+]?[0-9]+)?', Number.Float),
+            (r'0[xX][0-9a-fA-F]+', Number.Hex),
+            (r'[0-9]+', Number.Integer),
+
+            (r"'", String.Char, 'char'),
+            (r'"', String.Double, 'string'),
+        ],
+
+        # type started by alias
+        'alias-type': [
+            (r'=',Keyword),
+            include('type')
+        ],
+
+        # type started by struct
+        'struct-type': [
+            (r'(?=\((?!,*\)))',Punctuation,'#pop'),
+            include('type')
+        ],
+
+        # type started by colon
+        'type': [
+            (r'[\(\[<]', Keyword.Type, 'type-nested' ),
+            include('type-content')
+        ],
+
+        # type nested in brackets: can contain parameters, comma etc.
+        'type-nested': [
+            (r'[\)\]>]', Keyword.Type, '#pop' ),
+            (r'[\(\[<]', Keyword.Type, 'type-nested' ),
+            (r'[,]', Keyword.Type),
+            (r'([a-z](?:[a-zA-Z0-9_]|\-[a-zA-Z])*)(\s*)(:)(?![:])',bygroups(Name.Variable,Text,Keyword.Type)),  # parameter name            
+            include('type-content')            
+        ],
+
+        # shared contents of a type
+        'type-content': [
+            include('whitespace'),
+
+            # keywords
+            (r'(%s)' % '|'.join(typekeywords) + boundary, Keyword.Type),
+            (r'(?=((%s)' % '|'.join(keywords) + boundary + '))', Keyword, '#pop'),  # need to match because names overlap..
+
+            # kinds
+            (r'[EPH]' + boundary, Keyword.Type),
+            (r'[\*\!]', Keyword.Type),            
+
+            # type names
+            (r'[A-Z]([a-zA-Z0-9_]|\-[a-zA-Z])*(?=\.)',Name.Namespace),            
+            (r'[A-Z]([a-zA-Z0-9_]|\-[a-zA-Z])*(?!\.)',Name.Class),
+            (r'[a-z][0-9]*(?![a-zA-Z_\-])',Keyword.Type),            # Generic.Emph
+            (r'_([a-zA-Z0-9_]|\-[a-zA-Z])*',Keyword.Type),           # Generic.Emph
+            (r'[a-z]([a-zA-Z0-9_]|\-[a-zA-Z])*',Keyword.Type),
+            
+            # type keyword operators
+            (r'::|\->|[\.:|]', Keyword.Type),
+
+            #catchall
+            (r'', Text, '#pop')
+        ],
+
+        # comments and literals
+        'whitespace': [
+            (r'\s+', Text),
+            (r'/\*', Comment.Multiline, 'comment'),
+            (r'//.*$', Comment.Single)
+        ],
+        'comment': [
+            (r'[^/\*]+', Comment.Multiline),
+            (r'/\*', Comment.Multiline, '#push'),
+            (r'\*/', Comment.Multiline, '#pop'),
+            (r'[\*/]', Comment.Multiline),            
+        ],
+        'litstring': [
+            (r'[^"]+', String.Double),
+            (r'""', String.Escape),
+            (r'"', String.Double, '#pop'),
+        ],
+        'string': [
+            (r'[^\\"\n]+', String.Double),
+            include('escape-sequence'),
+            (r'["\n]', String.Double, '#pop'),
+        ],
+        'char': [
+            (r'[^\\\'\n]+', String.Char),
+            include('escape-sequence'),
+            (r'[\'\n]', String.Char, '#pop'),
+        ],
+        'escape-sequence': [
+            (r'\\[abfnrtv0\\\"\'\?]', String.Escape),
+            (r'\\x[0-9a-fA-F]{2}', String.Escape),
+            (r'\\u[0-9a-fA-F]{4}', String.Escape),
+            (r'\\U[0-9a-fA-F]{6}', String.Escape)
+        ]        
+    }
+

File tests/examplefiles/garcia-wachs.kk

+/* This is an example in the Koka Language of the Garcia-Wachs algorithm */
+module garcia-wachs
+
+public fun main()
+{
+  test().print
+}
+
+//----------------------------------------------------
+// Trees
+//----------------------------------------------------
+public type tree<a> {
+  con Leaf(value :a)
+  con Node(left :tree<a>, right :tree<a>)
+}
+
+fun show( t : tree<char> ) : string
+{
+  match(t) {
+    Leaf(c) -> Core.show(c)
+    Node(l,r) -> "Node(" + show(l) + "," + show(r) + ")"
+  }
+}
+
+
+//----------------------------------------------------
+// Non empty lists
+//----------------------------------------------------
+public type list1<a> {
+  Cons1( head : a, tail : list<a> )
+}
+
+
+fun map( xs, f ) {
+  val Cons1(y,ys) = xs
+  return Cons1(f(y), Core.map(ys,f))
+}
+
+fun zip( xs :list1<a>, ys :list1<b> ) : list1<(a,b)> {
+  Cons1( (xs.head, ys.head), zip(xs.tail, ys.tail))
+}
+
+
+
+//----------------------------------------------------
+// Phase 1
+//----------------------------------------------------
+
+fun insert( after : list<(tree<a>,int)>, t : (tree<a>,int), before : list<(tree<a>,int)> ) : div tree<a>
+{
+  match(before) {
+    Nil -> extract( [], Cons1(t,after) )
+    Cons(x,xs) -> {
+      if (x.snd < t.snd) then return insert( Cons(x,after), t, xs )
+      match(xs) {
+        Nil        -> extract( [], Cons1(x,Cons(t,after)) )
+        Cons(y,ys) -> extract( ys, Cons1(y,Cons(x,Cons(t,after))) )
+      }
+    }
+  }
+}
+
+fun extract( before : list<(tree<a>,int)>, after : list1<(tree<a>,int)> ) : div tree<a>
+{
+  val Cons1((t1,w1) as x, xs ) = after
+  match(xs) {
+    Nil -> t1
+    Cons((t2,w2) as y, ys) -> match(ys) {
+      Nil -> insert( [], (Node(t1,t2), w1+w2), before )
+      Cons((_,w3),_zs) ->
+        if (w1 <= w3)
+         then insert(ys, (Node(t1,t2), w1+w2), before)
+         else extract(Cons(x,before), Cons1(y,ys))
+    }
+  }
+}
+
+
+
+fun balance( xs : list1<(tree<a>,int)> ) : div tree<a>
+{
+  extract( [], xs )
+}
+
+fun mark( depth :int, t :tree<(a,ref<h,int>)> ) : <write<h>> ()
+{
+  match(t) {
+    Leaf((_,d)) -> d := depth
+    Node(l,r)   -> { mark(depth+1,l); mark(depth+1,r) }
+  }
+}
+
+
+fun build( depth :int, xs :list1<(a,ref<h,int>)> ) : <read<h>,div> (tree<a>,list<(a,ref<h,int>)>)
+{
+  if (!xs.head.snd == depth) return (Leaf(xs.head.fst), xs.tail)
+
+  l = build(depth+1, xs)
+  match(l.snd) {
+    Nil -> (l.fst, Nil)
+    Cons(y,ys) -> {
+      r = build(depth+1, Cons1(y,ys))
+      (Node(l.fst,r.fst), r.snd)
+    }
+  }
+}
+
+public fun test() {
+  wlist = Cons1(('a',3), [('b',2),('c',1),('d',4),('e',5)])
+  tree  = wlist.garciawachs()
+  tree.show()
+}
+
+public fun garciawachs( xs : list1<(a,int)> ) : div tree<a>
+{
+  refs   = xs.map(fst).map( fun(x) { (x, ref(0)) } )
+  wleafs = zip( refs.map(Leaf), xs.map(snd) )
+
+  tree = balance(wleafs)
+  mark(0,tree)
+  build(0,refs).fst
+}
+