Skip to content

Commit

Permalink
Add support for Wren language (#2271)
Browse files Browse the repository at this point in the history
Co-authored-by: Jean Abou Samra <jean@abou-samra.fr>
  • Loading branch information
PureFox48 and jeanas committed Nov 29, 2022
1 parent 880a217 commit a47833d
Show file tree
Hide file tree
Showing 5 changed files with 1,157 additions and 0 deletions.
1 change: 1 addition & 0 deletions pygments/lexers/_mapping.py
Expand Up @@ -529,6 +529,7 @@
'WebIDLLexer': ('pygments.lexers.webidl', 'Web IDL', ('webidl',), ('*.webidl',), ()),
'WhileyLexer': ('pygments.lexers.whiley', 'Whiley', ('whiley',), ('*.whiley',), ('text/x-whiley',)),
'WoWTocLexer': ('pygments.lexers.wowtoc', 'World of Warcraft TOC', ('wowtoc',), ('*.toc',), ()),
'WrenLexer': ('pygments.lexers.wren', 'Wren', ('wren',), ('*.wren',), ()),
'X10Lexer': ('pygments.lexers.x10', 'X10', ('x10', 'xten'), ('*.x10',), ('text/x-x10',)),
'XMLUL4Lexer': ('pygments.lexers.ul4', 'XML+UL4', ('xml+ul4',), ('*.xmlul4',), ()),
'XQueryLexer': ('pygments.lexers.webmisc', 'XQuery', ('xquery', 'xqy', 'xq', 'xql', 'xqm'), ('*.xqy', '*.xquery', '*.xq', '*.xql', '*.xqm'), ('text/xquery', 'application/xquery')),
Expand Down
99 changes: 99 additions & 0 deletions pygments/lexers/wren.py
@@ -0,0 +1,99 @@
"""
pygments.lexers.wren
~~~~~~~~~~~~~~~~~~~~
Lexer for Wren.
:copyright: Copyright 2006-2022 by the Pygments team, see AUTHORS.
:license: BSD, see LICENSE for details.
"""

import re

from pygments.lexer import include, RegexLexer, words
from pygments.token import Whitespace, Punctuation, Keyword, Name, Comment, \
Operator, Number, String, Error

__all__ = ['WrenLexer']

class WrenLexer(RegexLexer):
"""
For Wren source code, version 0.4.0.
.. versionadded:: 2.14.0
"""
name = 'Wren'
url = 'https://wren.io'
aliases = ['wren']
filenames = ['*.wren']

flags = re.MULTILINE | re.DOTALL

tokens = {
'root': [
# Whitespace.
(r'\s+', Whitespace),
(r'[,\\\[\]{}]', Punctuation),

# Really 'root', not '#push': in 'interpolation',
# parentheses inside the interpolation expression are
# Punctuation, not String.Interpol.
(r'\(', Punctuation, 'root'),
(r'\)', Punctuation, '#pop'),

# Keywords.
(words((
'as', 'break', 'class', 'construct', 'continue', 'else',
'for', 'foreign', 'if', 'import', 'return', 'static', 'super',
'this', 'var', 'while'), prefix = r'(?<!\.)',
suffix = r'\b'), Keyword),

(words((
'true', 'false', 'null'), prefix = r'(?<!\.)',
suffix = r'\b'), Keyword.Constant),

(words((
'in', 'is'), prefix = r'(?<!\.)',
suffix = r'\b'), Operator.Word),

# Comments.
(r'/\*', Comment.Multiline, 'comment'), # Multiline, can nest.
(r'//.*?$', Comment.Single), # Single line.
(r'#.*?(\(.*?\))?$', Comment.Special), # Attribute or shebang.

# Names and operators.
(r'[!%&*+\-./:<=>?\\^|~]+', Operator),
(r'[a-z][a-zA-Z_0-9]*', Name),
(r'[A-Z][a-zA-Z_0-9]*', Name.Class),
(r'__[a-zA-Z_0-9]*', Name.Variable.Class),
(r'_[a-zA-Z_0-9]*', Name.Variable.Instance),

# Numbers.
(r'0x[0-9a-fA-F]+', Number.Hex),
(r'\d+(\.\d+)?([eE][-+]?\d+)?', Number.Float),

# Strings.
(r'""".*?"""', String), # Raw string
(r'"', String, 'string'), # Other string
],
'comment': [
(r'/\*', Comment.Multiline, '#push'),
(r'\*/', Comment.Multiline, '#pop'),
(r'([^*/]|\*(?!/)|/(?!\*))+', Comment.Multiline),
],
'string': [
(r'"', String, '#pop'),
(r'\\[\\%"0abefnrtv]', String.Escape), # Escape.
(r'\\x[a-fA-F0-9]{2}', String.Escape), # Byte escape.
(r'\\u[a-fA-F0-9]{4}', String.Escape), # Unicode escape.
(r'\\U[a-fA-F0-9]{8}', String.Escape), # Long Unicode escape.

(r'%\(', String.Interpol, 'interpolation'),
(r'[^\\"%]+', String), # All remaining characters.
],
'interpolation': [
# redefine closing paren to be String.Interpol
(r'\)', String.Interpol, '#pop'),
include('root'),
],
}
122 changes: 122 additions & 0 deletions tests/examplefiles/wren/example.wren
@@ -0,0 +1,122 @@
#!/bin/wren

/* IMPORTS */
import "random" for Random as Rand

/* COMMENTS */

// single line comment

/*
multiline comment
/*
nested multiline comment
*/
*/

/* CLASSES & ATTRIBUTES */

#!type = "parent"
class Parent {
#method
static setField (field) {
__field = field
}

construct new(parent) {
_parent = parent
return
}

parent { _parent }

foreign method()
}

#!type = "child"
#group(
multiple,
lines = true
)
class Child is Parent {
construct new(parent, child) {
super(parent)
_child = child
}

child { _child }

toString { this.parent }
}

/* VARIABLES & STRINGS */

var rand = Rand.new()
var name = """David"""
var fullName = "%(name) Smith"
var firstChild = Child.new("Philip Smith", fullName)
var age = 21
var weight = 70.25
var male = true
var sex = male ? "M" : "F"
var address = """
"House name" 12 Any Street
Some Town
\t %("Some Country") "
"""
/* LOOPS & CONDITIONALS */
for (i in 1..5) {
if (i == 2) {
continue
} else if (i == 4) {
break
}
System.print(i)
}
var j = 6
while (j <= 1e+1) {
if (j == 8) break
System.print(j)
j = j + 1
}
/* ARITHMETIC OPERATORS */
var a = 1
var b = 2
var c = [-a, a + b, a - b, a * b, a / b, a % b]
var add = c[1]
/* BITWISE OPERATORS */
var d = 3
var e = 4
var f = [~d, d & e, d | e, d ^ e, d << 2, e >> 1]
/* COMPARISON OPERATORS */
var g = 5
var h = 6
var i = [a == b, a != b, a < b, a <= b, a > b, a >= b]
var k = firstChild is Parent
/* FUNCTIONS */
var func = Fn.new { |param|
var z = "this"
System.print(z + " " + param)
}
func.call("function")
/* MISCELLANEOUS */
var hex = 0x12ac
var nul = null
var l = false
var m = true
var n = l && m
var o = l || m
var esc = "\\ \% \" \0 \a \b \t \f \n \r \v \e \x01 \uabcd \Uabcdef01"
var uni = "£ é 😀 ‎🎷"
var map = {"a": 1, "b": 2}
var iex = "%(map["a"] + map[("b")])"
var odd = (1...h).where { |i| i % 2 == 1 }
.toList
var emp = ""

0 comments on commit a47833d

Please sign in to comment.