1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119
|
# -*- coding: utf-8 -*- #
# frozen_string_literal: true
module Rouge
module Lexers
load_lexer 'ocaml/common.rb'
class ReScript < OCamlCommon
title "ReScript"
desc "The ReScript programming language (rescript-lang.org)"
tag 'rescript'
filenames '*.res', '*.resi'
mimetypes 'text/x-rescript'
def self.keywords
@keywords ||= Set.new(%w(
open let rec and as exception assert lazy if else
for in to downto while switch when external type private
mutable constraint include module of with try import export
))
end
def self.types
@types ||= Set.new(%w(
bool int float char string
unit list array option ref exn format
))
end
def self.word_operators
@word_operators ||= Set.new(%w(mod land lor lxor lsl lsr asr or))
end
state :root do
rule %r/\s+/m, Text
rule %r([,.:?~\\]), Text
# Boolean Literal
rule %r/\btrue|false\b/, Keyword::Constant
# Module chain
rule %r/#{@@upper_id}(?=\s*[.])/, Name::Namespace, :dotted
# Decorator
rule %r/@#{@@id}(\.#{@@id})*/, Name::Decorator
# Poly variant
rule %r/\##{@@id}/, Name::Class
# Variant or Module
rule @@upper_id, Name::Class
# Comments
rule %r(//.*), Comment::Single
rule %r(/\*), Comment::Multiline, :comment
# Keywords and identifiers
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.types.include? match
token Keyword::Type
else
token Name
end
end
# Braces
rule %r/[(){}\[\];]+/, Punctuation
# Operators
rule %r([;_!$%&*+/<=>@^|-]+), Operator
# Numbers
rule %r/-?\d[\d_]*(.[\d_]*)?(e[+-]?\d[\d_]*)/i, Num::Float
rule %r/0x\h[\h_]*/i, Num::Hex
rule %r/0o[0-7][0-7_]*/i, Num::Oct
rule %r/0b[01][01_]*/i, Num::Bin
rule %r/\d[\d_]*/, Num::Integer
# String and Char
rule %r/'(?:(\\[\\"'ntbr ])|(\\[0-9]{3})|(\\x\h{2}))'/, Str::Char
rule %r/'[^'\/]'/, Str::Char
rule %r/'/, Keyword
rule %r/"/, Str::Double, :string
# Interpolated string
rule %r/`/ do
token Str::Double
push :interpolated_string
end
end
state :comment do
rule %r([^/\*]+), Comment::Multiline
rule %r(/\*), Comment::Multiline, :comment
rule %r(\*/), Comment::Multiline, :pop!
rule %r([*/]), Comment::Multiline
end
state :interpolated_string do
rule %r/[$]{/, Punctuation, :interpolated_expression
rule %r/`/, Str::Double, :pop!
rule %r/\\[$`]/, Str::Escape
rule %r/[^$`\\]+/, Str::Double
rule %r/[\\$]/, Str::Double
end
state :interpolated_expression do
rule %r/}/, Punctuation, :pop!
mixin :root
end
end
end
end
|