Tim Hatch avatar Tim Hatch committed 2a8aabf

Incorporate lexer for the Fancy language (closes #663)

Comments (0)

Files changed (5)

 * Paul Baumgart, 280 North, Inc. -- Objective-J lexer
 * Michael Bayer -- Myghty lexers
 * John Benediktsson -- Factor lexer
+* Christopher Bertels -- Fancy lexer
 * Jarrett Billingsley -- MiniD lexer
 * Adam Blinkinsop -- Haskell, Redcode lexers
 * Frits van Bommel -- assembler lexers
 Issue numbers refer to the tracker at
 http://bitbucket.org/birkenfeld/pygments-main/issues.
 
+Version 1.5
+-----------
+(codename not decided, released Jul xx, 2011)
+
+- Lexers added:
+
+  * Fancy (#633)
+
+
 Version 1.4
 -----------
 (codename Unschärfe, released Jan 03, 2011)

pygments/lexers/_mapping.py

     'EvoqueLexer': ('pygments.lexers.templates', 'Evoque', ('evoque',), ('*.evoque',), ('application/x-evoque',)),
     'EvoqueXmlLexer': ('pygments.lexers.templates', 'XML+Evoque', ('xml+evoque',), ('*.xml',), ('application/xml+evoque',)),
     'FactorLexer': ('pygments.lexers.agile', 'Factor', ('factor',), ('*.factor',), ('text/x-factor',)),
+    'FancyLexer': ('pygments.lexers.agile', 'Fancy', ('fancy', 'fy'), ('*.fy', '*.fancypack'), ('text/x-fancysrc',)),
     'FelixLexer': ('pygments.lexers.compiled', 'Felix', ('felix', 'flx'), ('*.flx', '*.flxh'), ('text/x-felix',)),
     'FortranLexer': ('pygments.lexers.compiled', 'Fortran', ('fortran',), ('*.f', '*.f90'), ('text/x-fortran',)),
     'GLShaderLexer': ('pygments.lexers.compiled', 'GLSL', ('glsl',), ('*.vert', '*.frag', '*.geo'), ('text/x-glslsrc',)),

pygments/lexers/agile.py

 __all__ = ['PythonLexer', 'PythonConsoleLexer', 'PythonTracebackLexer',
            'RubyLexer', 'RubyConsoleLexer', 'PerlLexer', 'LuaLexer',
            'MiniDLexer', 'IoLexer', 'TclLexer', 'ClojureLexer',
-           'Python3Lexer', 'Python3TracebackLexer', 'FactorLexer', 'IokeLexer']
+           'Python3Lexer', 'Python3TracebackLexer', 'FactorLexer',
+           'IokeLexer', 'FancyLexer']
 
 # b/w compatibility
 from pygments.lexers.functional import SchemeLexer
             (r'[a-z_][a-zA-Z0-9_!:?]*', Name)
         ]
     }
+
+class FancyLexer(RegexLexer):
+    """
+    Pygments Lexer For `Fancy <http://www.fancy-lang.org/>`_.
+
+    Fancy is a self-hosted, pure object-oriented, dynamic,
+    class-based, concurrent general-purpose programming language
+    running on Rubinius, the Ruby VM.
+
+    **New in Pygments 1.5**
+    """
+    name = 'Fancy'
+    filenames = ['*.fy', '*.fancypack']
+    aliases = ['fancy', 'fy']
+    mimetypes = ['text/x-fancysrc']
+
+    tokens = {
+        # copied from PerlLexer:
+        'balanced-regex': [
+            (r'/(\\\\|\\/|[^/])*/[egimosx]*', String.Regex, '#pop'),
+            (r'!(\\\\|\\!|[^!])*![egimosx]*', String.Regex, '#pop'),
+            (r'\\(\\\\|[^\\])*\\[egimosx]*', String.Regex, '#pop'),
+            (r'{(\\\\|\\}|[^}])*}[egimosx]*', String.Regex, '#pop'),
+            (r'<(\\\\|\\>|[^>])*>[egimosx]*', String.Regex, '#pop'),
+            (r'\[(\\\\|\\\]|[^\]])*\][egimosx]*', String.Regex, '#pop'),
+            (r'\((\\\\|\\\)|[^\)])*\)[egimosx]*', String.Regex, '#pop'),
+            (r'@(\\\\|\\\@|[^\@])*@[egimosx]*', String.Regex, '#pop'),
+            (r'%(\\\\|\\\%|[^\%])*%[egimosx]*', String.Regex, '#pop'),
+            (r'\$(\\\\|\\\$|[^\$])*\$[egimosx]*', String.Regex, '#pop'),
+        ],
+        'root': [
+            (r'\s+', Text),
+
+            # balanced delimiters (copied from PerlLexer):
+            (r's{(\\\\|\\}|[^}])*}\s*', String.Regex, 'balanced-regex'),
+            (r's<(\\\\|\\>|[^>])*>\s*', String.Regex, 'balanced-regex'),
+            (r's\[(\\\\|\\\]|[^\]])*\]\s*', String.Regex, 'balanced-regex'),
+            (r's\((\\\\|\\\)|[^\)])*\)\s*', String.Regex, 'balanced-regex'),
+            (r'm?/(\\\\|\\/|[^/\n])*/[gcimosx]*', String.Regex),
+            (r'm(?=[/!\\{<\[\(@%\$])', String.Regex, 'balanced-regex'),
+
+            # Comments
+            (r'#(.*?)\n', Comment.Single),
+            # Symbols
+            (r'\'[^\'\s]+', String.Symbol),
+            # Multi-line DoubleQuotedString
+            (r'"""(\\\\|\\"|[^"])*"""', String),
+            # DoubleQuotedString
+            (r'"(\\\\|\\"|[^"])*"', String),
+            # keywords
+            (r'(def|class|try|catch|finally|retry|return|return_local|match|'
+             r'case|->|=>)\b', Keyword),
+            # constants
+            (r'(self|super|nil|false|true)\b', Name.Constant),
+            (r'[(){};,/?\|:\\]', Punctuation),
+            # names
+            (r'(Object|Array|Hash|Directory|File|Class|String|Number|'
+             r'Enumerable|FancyEnumerable|Block|TrueClass|NilClass|'
+             r'FalseClass|Tuple|Symbol|Stack|Set|FancySpec|Method|Package|'
+             r'Range)\b', Name.Builtin),
+            # functions
+            (r'[a-zA-Z]([a-zA-Z0-9_]|[-+?!=*/^><%])*:', Name.Function),
+            # operators, must be below functions
+            (r'[-+*/~,<>=&!?%^\[\]\.$]+', Operator),
+            ('[A-Z][a-zA-Z0-9_]*', Name.Constant),
+            ('@[a-zA-Z_][a-zA-Z0-9_]*', Name.Variable.Instance),
+            ('@@[a-zA-Z_][a-zA-Z0-9_]*', Name.Variable.Class),
+            ('[a-zA-Z_][a-zA-Z0-9_]*', Name),
+            # numbers - / checks are necessary to avoid mismarking regexes,
+            # see comment in RubyLexer
+            (r'(0[oO]?[0-7]+(?:_[0-7]+)*)(\s*)([/?])?',
+             bygroups(Number.Oct, Text, Operator)),
+            (r'(0[xX][0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*)(\s*)([/?])?',
+             bygroups(Number.Hex, Text, Operator)),
+            (r'(0[bB][01]+(?:_[01]+)*)(\s*)([/?])?',
+             bygroups(Number.Bin, Text, Operator)),
+            (r'([\d]+(?:_\d+)*)(\s*)([/?])?',
+             bygroups(Number.Integer, Text, Operator)),
+            (r'\d+([eE][+-]?[0-9]+)|\d+\.\d+([eE][+-]?[0-9]+)?', Number.Float),
+            (r'\d+', Number.Integer)
+        ]
+    }

tests/examplefiles/example_file.fy

+class Person {
+  def initialize: @name age: @age {
+    """
+    This is a docstring for the Person constructor method.
+    Docstrings usually are multi-line, like this one.
+    """
+  }
+
+  def to_s {
+    # return is optional in this case, but we use it nontheless
+    return "Person with name: #{@name inspect} and age: #{@age}"
+  }
+}
+
+class PersonWithCity : Person {
+  def initialize: @name age: @age city: @city {
+  }
+
+  def to_s {
+    super to_s ++ " living in: #{@city inspect}"
+  }
+}
+
+p1 = Person new: "Johnny Jackson" age: 42
+p1 println # prints: Person with name: "Johnny Jackson" and age: 42
+
+p2 = PersonWithCity new: "John Appleseed" age: 55 city: "New York"
+p2 println # prints: Person with name: "John Appleseed" age: 55 living in: "New York"
+
+array = [1,2,3, "foo", 'bar]
+hash = <['foo => "bar", 'bar => 42]>
+tuple = (1,2,"hello","world")
+block = |x, y| {
+  x + y println
+}
+block call: [4,2]
+
+0b010101 & 0b00101 to_s: 2 . println
+0xFF & 0xAB to_s: 16 . println
+0o77 > 0o76 println
+123.123 + 0.222 println
+
+x = 0
+try {
+  10 / x println
+} catch ZeroDivisionError => e {
+  x = 3
+  retry
+} finally {
+  "Finally, done!" println
+}
+
+def a_method: arg1 with_default_arg: arg2 (42) {
+  arg1 * arg2 println
+}
+
+a_method: 42
+a_method: 42 with_default_arg: 85
+
+class ClassWithClassMethod {
+  def self class_method1 {
+    'works
+  }
+
+  def ClassWithClassMethod class_method2 {
+    'this_as_well
+  }
+}
+
+ClassWithClassMethod class_method1 println
+ClassWithClassMethod class_method2 println
+
+def another_method: block {
+  1 upto: 10 . map: block
+}
+
+# local returns
+another_method: |x| { return_local x * 2 } . inspect println
+
+
+# pattern matching:
+class PatternMatching {
+  def match_it: obj {
+    match obj {
+      case String -> "It's a String!" println
+      case Fixnum -> "It's a Number!" println
+      case _ -> "Aything else!" println
+    }
+  }
+
+  def match_with_extract: str {
+    match str {
+      # m holds the MatchData object, m1 & m2 the first and second matches
+      case /^(.*) : (.*)$/ -> |m, m1, m2|
+        "First match: #{m1}" println
+        "Second match: #{m2}" println
+    }
+  }
+}
+
+pm = PatternMatching new
+pm match_it: "foo"
+pm match_it: 42
+pm match_it: 'foo
+
+pm match_with_extract: "Hello : World!"
+
+
+# calling ruby methods:
+[3, 2, 1] reverse() each() |a| { puts(a) }
+"Hello" sub("ll", "y") println
+[3, 2, 1] map() |a| { a * 2 } inject(0) |s i| { s + i } println
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.