33
44require "rouge"
55
6+ # Register tB-specific token types so the highlighter can distinguish symbols
7+ # the way the twinBASIC IDE's theme system does -- e.g. Boolean / Empty /
8+ # Nothing / Null are each their own slot in tB's Symbol* palette, and the
9+ # line-continuation '_' has its own SymbolContinuationCharacter colour.
10+ module Rouge ::Token ::Tokens
11+ [
12+ [ Literal , :Boolean , 'lb' ] ,
13+ [ Literal , :Empty , 'le' ] ,
14+ [ Literal , :Nothing , 'ln' ] ,
15+ [ Literal , :Null , 'lu' ] ,
16+ [ Punctuation , :LineContinuation , 'lc' ] ,
17+ ] . each do |parent , name , shortname |
18+ parent . token ( name , shortname ) unless parent . const_defined? ( name , false )
19+ end
20+ end
21+
622module Rouge
723 module Lexers
824 class TwinBasic < RegexLexer
@@ -17,20 +33,30 @@ def self.keywords
1733 @keywords ||= Set . new %w(
1834 alias byref byval call case class close coclass const
1935 continue declare default delegate dim do each else elseif
20- empty end endif enum erase error event exit extends
21- false finally for friend function get global gosub
36+ end endif enum erase error event exit extends
37+ finally for friend function get global gosub
2238 goto handles if implements imports inherits input interface
2339 let lib line lock loop me mid module
24- namespace new next nothing null of on open option optional
40+ namespace new next of on open option optional
2541 overloads paramarray preserve print private property public
2642 put raiseevent redim resume return select set
2743 shared static step stop structure sub
28- then throw to true try type unlock until
44+ then throw to try type unlock until
2945 using wend when while width
3046 with withevents write
3147 )
3248 end
3349
50+ def self . keyword_constants
51+ @keyword_constants ||= {
52+ 'true' => Literal ::Boolean ,
53+ 'false' => Literal ::Boolean ,
54+ 'empty' => Literal ::Empty ,
55+ 'nothing' => Literal ::Nothing ,
56+ 'null' => Literal ::Null ,
57+ }
58+ end
59+
3460 def self . keywords_type
3561 @keywords_type ||= Set . new %w(
3662 any boolean byte currency date decimal double integer long
@@ -54,7 +80,7 @@ def self.builtins
5480 id = /[a-z_]\w */i
5581
5682 state :whitespace do
57- rule %r/_[ \t ]*\n / , Keyword
83+ rule %r/_[ \t ]*\n / , Punctuation :: LineContinuation
5884 rule %r/\n / , Text , :bol
5985 rule %r/[^\S \n ]+/ , Text
6086 rule %r/rem\b .*?$/i , Comment ::Single
@@ -72,12 +98,15 @@ def self.builtins
7298 rule %r(
7399 [#]If\b .*? \b Then
74100 | [#]ElseIf\b .*? \b Then
101+ | [#]Else\b
75102 | [#]End \s + If
76103 | [#]Const
77104 | [#]Region .*? \n
78105 | [#]End \s + Region
79106 )xi , Comment ::Preproc
80107
108+ rule %r/#\d [^#\n ]*#/ , Literal ::Date
109+
81110 rule %r/\[ / , Punctuation , :attribute
82111
83112 rule %r/(\d +\. \d *|\d *\. \d +)(e[+-]?\d +)?[!#@]?/i , Num ::Float
@@ -103,7 +132,9 @@ def self.builtins
103132
104133 rule id do |m |
105134 key = m [ 0 ] . downcase
106- if self . class . keywords . include? key
135+ if ( kc = self . class . keyword_constants [ key ] )
136+ token kc
137+ elsif self . class . keywords . include? key
107138 token Keyword
108139 elsif self . class . keywords_type . include? key
109140 token Keyword ::Type
@@ -157,7 +188,9 @@ def self.builtins
157188 rule %r/\d +[%&!#@]?/ , Num ::Integer
158189 rule id do |m |
159190 key = m [ 0 ] . downcase
160- if self . class . keywords . include? key
191+ if ( kc = self . class . keyword_constants [ key ] )
192+ token kc
193+ elsif self . class . keywords . include? key
161194 token Keyword
162195 elsif self . class . keywords_type . include? key
163196 token Keyword ::Type
0 commit comments