Skip to content

Commit

Permalink
Merge pull request rouge-ruby#106 from nilnor/moonscript-support
Browse files Browse the repository at this point in the history
Add Moonscript support
  • Loading branch information
jneen committed Oct 9, 2013
2 parents 1822e64 + 0a153d1 commit d9b446f
Show file tree
Hide file tree
Showing 4 changed files with 208 additions and 0 deletions.
16 changes: 16 additions & 0 deletions lib/rouge/demos/moonscript
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
util = require "my.module"

a_table = {
foo: 'bar'
interpolated: "foo-#{other.stuff 2 + 3}"
"string": 2
do: 'keyword'
}

class MyClass extends SomeClass
new: (@init, arg2 = 'default') =>
@derived = @init + 2
super!

other: =>
@foo + 2
108 changes: 108 additions & 0 deletions lib/rouge/lexers/moonscript.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
# -*- coding: utf-8 -*- #
#
require 'rouge/lexers/lua'

module Rouge
module Lexers
class Moonscript < RegexLexer
desc "Moonscript (http://www.moonscript.org)"
tag 'moonscript'
aliases 'moon'
filenames '*.moon'
mimetypes 'text/x-moonscript', 'application/x-moonscript'

def initialize(opts={})
@function_highlighting = opts.delete(:function_highlighting) { true }
@disabled_modules = opts.delete(:disabled_modules) { [] }
super(opts)
end

def self.analyze_text(text)
return 1 if text.shebang? 'moon'
end

def builtins
return [] unless @function_highlighting

@builtins ||= Set.new.tap do |builtins|
Rouge::Lexers::Lua.builtins.each do |mod, fns|
next if @disabled_modules.include? mod
builtins.merge(fns)
end
end
end

state :root do
rule %r(#!(.*?)$), Comment::Preproc # shebang
rule //, Text, :main
end

state :base do
ident = '(?:[\w_][\w\d_]*)'

rule %r((?i)(\d*\.\d+|\d+\.\d*)(e[+-]?\d+)?'), Num::Float
rule %r((?i)\d+e[+-]?\d+), Num::Float
rule %r((?i)0x[0-9a-f]*), Num::Hex
rule %r(\d+), Num::Integer
rule %r(@#{ident}*), Name::Variable::Instance
rule %r([A-Z][\w\d_]*), Name::Class
rule %r("?#{ident}+"?:), Literal::String::Symbol
rule %r(:#{ident}), Literal::String::Symbol

rule %r(\s+), Text::Whitespace
rule %r((==|~=|!=|<=|>=|\.\.\.|\.\.|->|=>|[=+\-*/%^<>#!\\])), Operator
rule %r([\[\]\{\}\(\)\.,:;]), Punctuation
rule %r((and|or|not)\b), Operator::Word

keywords = %w{
break class continue do else elseif end extends for if import in
repeat return switch super then unless until using when with while
}
rule %r((#{keywords.join('|')})\b), Keyword
rule %r((local|export)\b), Keyword::Declaration
rule %r((true|false|nil)\b), Keyword::Constant

rule %r([A-Za-z_][A-Za-z0-9_]*(\.[A-Za-z_][A-Za-z0-9_]*)?) do |m|
name = m[0]
if self.builtins.include?(name)
token Name::Builtin
elsif name =~ /\./
a, b = name.split('.', 2)
token Name, a
token Punctuation, '.'
token Name, b
else
token Name
end
end
end

state :main do
rule %r(--.*$), Comment::Single
rule %r(\[(=*)\[.*?\]\1\])m, Str::Heredoc

mixin :base

rule %r('), Str::Single, :sqs
rule %r("), Str::Double, :dqs
end

state :sqs do
rule %r('), Str::Single, :pop!
rule %r([^']+), Str::Single
end

state :interpolation do
rule %r(\}), Str::Interpol, :pop!
mixin :base
end

state :dqs do
rule %r(#\{), Str::Interpol, :interpolation
rule %r("), Str::Double, :pop!
rule %r(#[^{]), Str::Double
rule %r([^"#]+), Str::Double
end
end
end
end
21 changes: 21 additions & 0 deletions spec/lexers/moonscript_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
describe Rouge::Lexers::Moonscript do
let(:subject) { Rouge::Lexers::Moonscript.new }

describe 'guessing' do
include Support::Guessing

it 'guesses by filename' do
assert_guess :filename => 'foo.moon'
end

it 'guesses by mimetype' do
assert_guess :mimetype => 'text/x-moonscript'
assert_guess :mimetype => 'application/x-moonscript'
end

it 'guesses by source' do
assert_guess :source => '#!/usr/local/bin/moon'
assert_guess :source => '#! /usr/bin/env moon'
end
end
end
63 changes: 63 additions & 0 deletions spec/visual/samples/moonscript
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#! /usr/bin/moon

-- A heap of sample Moonscript syntax

util = require "my.module"

import SomeClass, member from util
import other from require "my.other_module"

a_table = {
foo: 'bar'
interpolated: "foo-#{other.stuff 2 + 3}"
"string-key": 2
do: 'keyword'
}

short_table_def = foo: 'bar', interpolated: "foo-#{other.stuff 2 + 3}"
scoped_table = :util, :a_table

multiline_string = "line 1
for the alliance!
line2"

other_multiline_string = [[ for
the
win
]]

local x
export y

x or= 1
x += 1
y and= x

empty_function ->
args_function (arg1, arg2) -> arg1 + arg2
var_args_function (...) -> table.concat {...}, '|'

while cond == true do empty_function!

comprehension = [item * 2 for i, item in ipairs items when item != 3]

for i = 1,10
continue unless i != 2

SomeClass(0xdeadbeef)\method 'foo'

with a_table
.foobar = {}

switch i
when 2
"not first"

class MyClass extends SomeClass
new: (@init, arg2 = 'default') =>
@derived = @init + 2
super!

other: =>
@@foo + 2
@

0 comments on commit d9b446f

Please sign in to comment.