Skip to content

Commit

Permalink
Cloned and renamed the OCaml files
Browse files Browse the repository at this point in the history
Cloned and renamed the OCaml files for a start of the FSharp lexer
  • Loading branch information
raymens committed May 19, 2016
1 parent 53f00b8 commit c21ea62
Show file tree
Hide file tree
Showing 3 changed files with 144 additions and 0 deletions.
12 changes: 12 additions & 0 deletions lib/rouge/demos/fsharp
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
(* Binary tree with leaves car­rying an integer. *)
type tree = Leaf of int | Node of tree * tree

let rec exists_leaf test tree =
match tree with
| Leaf v -> test v
| Node (left, right) ->
exists_leaf test left
|| exists_leaf test right

let has_even_leaf tree =
exists_leaf (fun n -> n mod 2 = 0) tree
111 changes: 111 additions & 0 deletions lib/rouge/lexers/fsharp.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
# -*- coding: utf-8 -*- #

module Rouge
module Lexers
class FSharp < RegexLexer
title "FSharp"
desc 'F# (fsharp.net)'
tag 'fsharp'
filenames '*.fs', '*.fsx'
mimetypes 'application/fsharp-script', 'text/x-fsharp', 'text/x-fsi'

def self.keywords
@keywords ||= Set.new %w(
as assert begin class constraint do done downto else end
exception external false for fun function functor if in include
inherit initializer lazy let match method module mutable new
object of open private raise rec sig struct then to true try
type value val virtual when while with
)
end

def self.keyopts
@keyopts ||= Set.new %w(
!= # & && ( ) * \+ , - -. -> . .. : :: := :> ; ;; < <- =
> >] >} ? ?? [ [< [> [| ] _ ` { {< | |] } ~
)
end

def self.word_operators
@word_operators ||= Set.new %w(and asr land lor lsl lxor mod or)
end

def self.primitives
@primitives ||= Set.new %w(unit int float bool string char list array)
end

operator = %r([\[\];,{}_()!$%&*+./:<=>?@^|~#-]+)
id = /[a-z][\w']*/i
upper_id = /[A-Z][\w']*/

state :root do
rule /\s+/m, Text
rule /false|true|[(][)]|\[\]/, Name::Builtin::Pseudo
rule /#{upper_id}(?=\s*[.])/, Name::Namespace, :dotted
rule upper_id, Name::Class
rule /[(][*](?![)])/, Comment, :comment
rule id do |m|
match = m[0]
if self.class.keywords.include? match
token Keyword
elsif self.class.word_operators.include? match
token Operator::Word
elsif self.class.primitives.include? match
token Keyword::Type
else
token Name
end
end

rule operator do |m|
match = m[0]
if self.class.keyopts.include? match
token Punctuation
else
token Operator
end
end

rule /-?\d[\d_]*(.[\d_]*)?(e[+-]?\d[\d_]*)/i, Num::Float
rule /0x\h[\h_]*/i, Num::Hex
rule /0o[0-7][0-7_]*/i, Num::Oct
rule /0b[01][01_]*/i, Num::Bin
rule /\d[\d_]*/, Num::Integer

rule /'(?:(\\[\\"'ntbr ])|(\\[0-9]{3})|(\\x\h{2}))'/, Str::Char
rule /'[.]'/, Str::Char
rule /'/, Keyword
rule /"/, Str::Double, :string
rule /[~?]#{id}/, Name::Variable
end

state :comment do
rule /[^(*)]+/, Comment
rule(/[(][*]/) { token Comment; push }
rule /[*][)]/, Comment, :pop!
rule /[(*)]/, Comment
end

state :string do
rule /[^\\"]+/, Str::Double
mixin :escape_sequence
rule /\\\n/, Str::Double
rule /"/, Str::Double, :pop!
end

state :escape_sequence do
rule /\\[\\"'ntbr]/, Str::Escape
rule /\\\d{3}/, Str::Escape
rule /\\x\h{2}/, Str::Escape
end

state :dotted do
rule /\s+/m, Text
rule /[.]/, Punctuation
rule /#{upper_id}(?=\s*[.])/, Name::Namespace
rule upper_id, Name::Class, :pop!
rule id, Name, :pop!
end
end
end
end
21 changes: 21 additions & 0 deletions spec/lexers/fsharp_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# -*- coding: utf-8 -*- #

describe Rouge::Lexers::FSharp do
let(:subject) { Rouge::Lexers::FSharp.new }

describe 'guessing' do
include Support::Guessing

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

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

0 comments on commit c21ea62

Please sign in to comment.