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 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
# -*- coding: utf-8 -*- #
# frozen_string_literal: true
module Rouge
module Lexers
class Brightscript < RegexLexer
title "BrightScript"
desc "BrightScript Programming Language (https://developer.roku.com/en-ca/docs/references/brightscript/language/brightscript-language-reference.md)"
tag 'brightscript'
aliases 'bs', 'brs'
filenames '*.brs'
# https://developer.roku.com/en-ca/docs/references/brightscript/language/global-utility-functions.md
# https://developer.roku.com/en-ca/docs/references/brightscript/language/global-string-functions.md
# https://developer.roku.com/en-ca/docs/references/brightscript/language/global-math-functions.md
def self.name_builtin
@name_builtin ||= Set.new %w(
ABS ASC ATN CDBL CHR CINT CONTROL COPYFILE COS CREATEDIRECTORY CSNG
DELETEDIRECTORY DELETEFILE EXP FINDMEMBERFUNCTION FINDNODE FIX
FORMATDRIVEFORMATJSON GETINTERFACE INSTR INT LCASE LEFT LEN LISTDIR
LOG MATCHFILES MID MOVEFILE OBSERVEFIELD PARSEJSON PARSEXML
READASCIIFILE REBOOTSYSTEM RIGHT RND RUNGARBAGECOLLECTOR SGN SIN
SLEEP SQR STR STRI STRING STRINGI STRTOI SUBSTITUTE TANTEXTTOP TEXT
TRUCASE UPTIME VALVISIBLE VISIBLE WAIT
)
end
# https://developer.roku.com/en-ca/docs/references/brightscript/language/reserved-words.md
def self.keyword_reserved
@keyword_reserved ||= Set.new %w(
BOX CREATEOBJECT DIM EACH ELSE ELSEIF END ENDFUNCTION ENDIF ENDSUB
ENDWHILE EVAL EXIT EXITWHILE FALSE FOR FUNCTION GETGLOBALAA
GETLASTRUNCOMPILEERROR GETLASTRUNRUNTIMEERROR GOTO IF IN INVALID LET
LINE_NUM M NEXT OBJFUN POS PRINT REM RETURN RUN STEP STOP SUB TAB TO
TRUE TYPE WHILE
)
end
# These keywords are present in BrightScript, but not supported in standard .brs files
def self.keyword_reserved_unsupported
@keyword_reserved_unsupported ||= Set.new %w(
CLASS CONST IMPORT LIBRARY NAMESPACE PRIVATE PROTECTED PUBLIC
)
end
# https://developer.roku.com/en-ca/docs/references/brightscript/language/expressions-variables-types.md
def self.keyword_type
@keyword_type ||= Set.new %w(
BOOLEAN DIM DOUBLE DYNAMIC FLOAT FUNCTION INTEGER INTERFACE INVALID
LONGINTEGER OBJECT STRING VOID
)
end
# https://developer.roku.com/en-ca/docs/references/brightscript/language/expressions-variables-types.md#operators
def self.operator_word
@operator_word ||= Set.new %w(
AND AS MOD NOT OR THEN
)
end
# Scene graph components configured as builtins. See BrightScript component documentation e.g.
# https://developer.roku.com/en-ca/docs/references/brightscript/components/roappinfo.md
def self.builtins
@builtins ||= Set.new %w(
roAppendFile roAppInfo roAppManager roArray roAssociativeArray
roAudioGuide roAudioMetadata roAudioPlayer roAudioPlayerEvent
roAudioResourceroBitmap roBoolean roBoolean roBrightPackage roBrSub
roButton roByteArray roCaptionRenderer roCaptionRendererEvent
roCecInterface roCECStatusEvent roChannelStore roChannelStoreEvent
roClockWidget roCodeRegistrationScreen
roCodeRegistrationScreenEventroCompositor roControlDown roControlPort
roControlPort roControlUp roCreateFile roDatagramReceiver
roDatagramSender roDataGramSocket roDateTime roDeviceInfo
roDeviceInfoEvent roDoubleroEVPCipher roEVPDigest roFileSystem
roFileSystemEvent roFloat roFont roFontMetrics roFontRegistry
roFunction roGlobal roGpio roGridScreen roGridScreenEvent
roHdmiHotPlugEventroHdmiStatus roHdmiStatusEvent roHMAC roHttpAgent
roImageCanvas roImageCanvasEvent roImageMetadata roImagePlayer
roImageWidgetroInput roInputEvent roInt roInt roInvalid roInvalid
roIRRemote roKeyboard roKeyboardPress roKeyboardScreen
roKeyboardScreenEventroList roListScreen roListScreenEvent
roLocalization roLongInteger roMessageDialog roMessageDialogEvent
roMessagePort roMicrophone roMicrophoneEvent roNetworkConfiguration
roOneLineDialog roOneLineDialogEventroParagraphScreen
roParagraphScreenEvent roPath roPinEntryDialog roPinEntryDialogEvent
roPinentryScreen roPosterScreen roPosterScreenEventroProgramGuide
roQuadravoxButton roReadFile roRectangleroRegexroRegion roRegistry
roRegistrySection roResourceManager roRSA roRssArticle roRssParser
roScreen roSearchHistory roSearchScreen roSearchScreenEvent
roSerialPort roSGNode roSGNodeEvent roSGScreenroSGScreenEvent
roSlideShowroSlideShowEvent roSNS5 roSocketAddress roSocketEvent
roSpringboardScreen roSpringboardScreenEventroSprite roStorageInfo
roStreamSocket roStringroSystemLogroSystemLogEvent roSystemTime
roTextFieldroTextScreen roTextScreenEvent roTextToSpeech
roTextToSpeechEvent roTextureManager roTextureRequest
roTextureRequestEventroTextWidget roTimer roTimespan roTouchScreen
roTunerroTunerEvent roUniversalControlEvent roUrlEvent roUrlTransfer
roVideoEvent roVideoInput roVideoMode roVideoPlayer roVideoPlayerEvent
roVideoScreen roVideoScreenEventroWriteFile roXMLElement roXMLList
)
end
id = /[$a-z_][a-z0-9_]*/io
state :root do
rule %r/\s+/m, Text::Whitespace
# https://developer.roku.com/en-ca/docs/references/brightscript/language/expressions-variables-types.md#comments
rule %r/\'.*/, Comment::Single
rule %r/REM.*/i, Comment::Single
# https://developer.roku.com/en-ca/docs/references/brightscript/language/expressions-variables-types.md#operators
rule %r([~!%^&*+=\|?:<>/-]), Operator
rule %r/\d*\.\d+(e-?\d+)?/i, Num::Float
rule %r/\d+[lu]*/i, Num::Integer
rule %r/".*?"/, Str::Double
rule %r/#{id}(?=\s*[(])/, Name::Function
rule %r/[()\[\],.;{}]/, Punctuation
rule id do |m|
caseSensitiveChunk = m[0]
caseInsensitiveChunk = m[0].upcase
if self.class.builtins.include?(caseSensitiveChunk)
token Keyword::Reserved
elsif self.class.keyword_reserved.include?(caseInsensitiveChunk)
token Keyword::Reserved
elsif self.class.keyword_reserved_unsupported.include?(caseInsensitiveChunk)
token Keyword::Reserved
elsif self.class.keyword_type.include?(caseInsensitiveChunk)
token Keyword::Type
elsif self.class.name_builtin.include?(caseInsensitiveChunk)
token Name::Builtin
elsif self.class.operator_word.include?(caseInsensitiveChunk)
token Operator::Word
else
token Name
end
end
end
end
end
end
|