]> gitweb.factorcode.org Git - factor.git/blob - misc/vim/syntax/factor.vim
0b325f83eccd74fe1167c1771cd3c037c42e6ef8
[factor.git] / misc / vim / syntax / factor.vim
1 " Vim syntax file
2 " Language: Factor
3 " Maintainer: Alex Chapman <chapman.alex@gmail.com>
4 " Last Change: 2020 Jun 05
5 " Minimum Version: 600
6
7 " Factor |syntax| file guide & conventions:
8 "
9 " Inside |:comment|s, words in |bars| contain |:help| keywords.
10 "   |K| looks these up.
11 "
12 " Alignment columns should normally occur on multiples of 4.
13 " Align Vim syntax alternatives naturally. E.g.:
14 "   "syn match   ..."
15 "   "syn cluster ..."
16 "   "syn region  ..."
17 " Align |:syn-start|, |:syn-skip|, and |:syn-end| on their patterns.
18 " ":echo (col('.') - 1) % 4" is handy here.
19 "
20 " All syntax patterns (|:syn-pattern|) are "very magic" (|/\v|).
21 " Escape all literal [^0-9a-zA-Z_-!:;] characters in these patterns.
22 " (Not escaping [-!:;] characters risks forward-incompatibility,
23 "   but fixes if an incompatibile Vim arises would be trivial,
24 "   and Factor likes these characters.)
25 "
26 " Syntax groups ending in "Error" match errors via |:syn-priority|,
27 "   and should normally |:hi-link| to "Error".
28 "
29 " Syntax groups named "{group-name}Trans" are |:syn-transparent|.
30 "
31 " |:syn-cluster|s named "{group-name}" mean to allow |:syn-contains| use of
32 "   |:syn-priority|-based error-detection.
33 " This still applies to clusters named "{group-name}Trans".
34 "
35 " Syntax groups "{group-name}Skip" have the form:
36 " "syn match {group-name}Skip /\v%(\_\s+%(!>.*)?)*/ nextgroup={group-name} transparent contained"
37 " Specifying "nextgroup={group-name}Skip" works like a Factor-aware
38 "   "nextgroup={group-name} skipwhite skipempty"
39 "   with required initial space (not optional).
40 " "{cluster-name}Skip" works similarly, but with "nextgroup=@{cluster-name}".
41 "
42 " Vim's syntax highlighting freaks at paired "/\v\(" and "/\v\)". ☹
43 " Switching into very nomagic (with "/\V(\v/" or "/\V)\v") averts that,
44 "   as non-escaped parentheses don't extend pattern regions.
45
46 if exists('b:current_syntax')
47   finish
48 endif
49
50 " Factor is case sensitive.
51 syn case match
52
53 " Make all of these characters part of a word (useful for skipping over words with w, e, and b)
54 let s:iskeyword = '!,@,33-35,%,$,38-64,A-Z,91-96,a-z,123-126,128-255'
55 let s:set_iskeyword = has('patch-7.4.1142') ? 'syn iskeyword ' :
56       \ 'setlocal iskeyword='
57 execute s:set_iskeyword . s:iskeyword
58
59 syn match   factorWord   /\v<\S+>/  contains=@factorWord transparent display
60 syn cluster factorClusterNoComment  contains=factorWord,@factorMultilineComment,@factorClusterValue,factorBoolean,factorBreakpoint,factorDeclaration,factorCallQuotation,factorExecute,factorCallNextMethod,@factorWordOps,factorAlien,factorSlot,factorTuple,factorErrorSyn,factorStruct
61 syn cluster factorCluster           contains=@factorComment,@factorClusterNoComment
62
63 " A crash course on Factor's lexer:
64 "
65 " The "lexer" vocabulary parses lines (arrays of strings) into tokens.
66 " Tokens are non-space strings, effectively words.
67 " "[ f skip ] call( i seq -- n )" finds the next space, erroring on tabs.
68 "   "t skip" finds the next non-space.
69 " The "lexer" class holds lex state.
70 " Lexer method "skip-word" advances to the next space (via "f skip"),
71 "     while also counting leading double quotation marks as their own words.
72 "   I.e., this advances to the end of the current token
73 "     (if currently at a token, otherwise nothing changes).
74 " Method "skip-blank" advances to the next non-space (via "t skip"),
75 "     while also skipping shebangs at the beginning of the first line.
76 "   I.e., this advances to the start of the next token
77 "     (if one is present, otherwise it advances to the line's end).
78 " "(parse-raw)" advances a lexer through an immediate token via "skip-word",
79 "   and returns the (sub)token advanced through.
80 "   Note that this will not advance a lexer at space,
81 "     and an empty string will be returned.
82 " "next-line" advances a lexer to the start of the next line,
83 "   adding an effectively empty line to the end (as an EOF state).
84 " "parse-raw" advances a lexer through the next token,
85 "   first via alternating "skip-blank" & "next-line" if the line ended,
86 "     then via "(parse-raw)",
87 "   and returns it if found, otherwise (i.e. upon EOF) returning "f".
88 "     Note that the lexer will be advanced to EOF if "f" is returned.
89 " Comments are (unprocessed) remainders of lines, after a "!" word.
90 " "parse-token" advances a lexer though the next token via "parse-raw",
91 "   then returns it if found, otherwise returning "f".
92 "   while also advancing through comments
93 "     via mutual recursion with "skip-comment".
94 "   "[ skip-comment ] call( lexer str -- str' )" tests if a token is "!",
95 "     returning that token if so,
96 "     otherwise first advancing a lexer to the next line via "next-line"
97 "         (i.e. discarding the rest of the current line)
98 "       and then advancing it via "parse-token" & returning that token,
99 "     ensuring the return of "parse-token"'s desired non-comment token.
100 " The "lexer" dynamic variable holds the ambient lexer.
101 " "?scan-token" advances the ambient lexer through the next token
102 "     via "parse-token",
103 "   and returns it if found, otherwise returning "f".
104 " "scan-token" advances the ambient lexer through the next token
105 "     via "?scan-token",
106 "   and returns it if found, otherwise throwing an exception.
107 " All other words in the "lexer" vocabulary read via "scan-token", if at all.
108 " So! To know when double quotes & exclamation marks aren't special,
109 "   grep for "parse-raw". (Mostly. To be certain, grep for "lexer".)
110
111 syn cluster factorComment           contains=factorComment
112 syn cluster factorCommentContents   contains=factorTodo,@Spell
113 syn match   factorTodo              /\v(TODO|FIXME|XXX):=/ contained
114
115 syn cluster factorDefnContents      contains=@factorCluster
116
117 syn region  factorDefn            start=/\v<%(SYNTAX|%(MACRO|MEMO|TYPED)?:?):>/    skip=/\v<!>/ matchgroup=factorDefnDelims     end=/\v<;>/ contains=factorDefnDelims,@factorDefnContents
118 syn region  factorMethod          start=/\v<M::?>/                                 skip=/\v<!>/ matchgroup=factorDefnDelims     end=/\v<;>/ contains=factorMethodDelims,@factorDefnContents
119 syn region  factorGeneric         start=/\v<%(GENERIC|MATH|PRIMITIVE):>/           skip=/\v<!>/ end=/\v<\S+>/ contains=@factorComment nextgroup=factorStackEffectSkip
120 syn region  factorGenericN        start=/\v<GENERIC\#:>/                           skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\d+>/ contains=@factorComment nextgroup=factorStackEffectSkip
121
122 syn region  factorPDefn           start=/\v<%(SYNTAX|%(MACRO|MEMO|TYPED)?:?):>/    skip=/\v<!>/ matchgroup=factorPDefnDelims    end=/\v<;>/ contains=factorPDefnDelims,@factorDefnContents contained
123 syn region  factorPMethod         start=/\v<M::?>/                                 skip=/\v<!>/ matchgroup=factorPDefnDelims    end=/\v<;>/ contains=factorPMethodDelims,@factorDefnContents contained
124 syn region  factorPGeneric        start=/\v<%(GENERIC|MATH|PRIMITIVE):>/           skip=/\v<!>/ end=/\v<\S+>/ contains=@factorComment nextgroup=factorStackEffectSkip contained
125 syn region  factorPGenericN       start=/\v<GENERIC\#:>/                           skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\d+>/ contains=@factorComment nextgroup=factorStackEffectSkip contained
126
127 syn region  factorDefnDelims      start=/\v<%(SYNTAX|%(MACRO|MEMO|TYPED)?:?):>/    skip=/\v<!>/ end=/\v<\S+>/ contains=@factorComment nextgroup=factorStackEffectSkip contained
128 syn region  factorMethodDelims    start=/\v<M::?>/                                 skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment nextgroup=factorStackEffectSkip contained
129 syn region  factorPDefnDelims     start=/\v<%(SYNTAX|%(MACRO|MEMO|TYPED)?:?):>/    skip=/\v<!>/ end=/\v<\S+>/ contains=@factorComment nextgroup=factorStackEffectSkip contained
130 syn region  factorPMethodDelims   start=/\v<M::?>/                                 skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment nextgroup=factorStackEffectSkip contained
131
132 syn region  None matchgroup=factorPrivate start=/\v<\<PRIVATE>/ end=/\v<PRIVATE\>>/ contains=@factorDefnContents,factorPrivateDefn,factorPrivateMethod,factorPGeneric,factorPGenericN
133
134 syn cluster factorClusterValue      contains=factorBreakpoint,factorBoolean,factorFrySpecifier,factorChar,@factorString,@factorNumber,factorBackslash,factorMBackslash,factorLiteral,factorLiteralBlock,@factorStackEffect,@factorQuotation,@factorArray
135 syn match   factorClusterValueSkip  /\v%(\_\s+%(!>.*)?)*/ nextgroup=@factorClusterValue transparent contained
136
137 syn keyword factorBoolean           f t
138 syn keyword factorBreakpoint        B
139 syn keyword factorFrySpecifier      @ _ contained
140 syn keyword factorDeclaration       delimiter deprecated final flushable foldable inline recursive
141 syn match   factorCallQuotation     /\vcall\V(\v/me=e-1    nextgroup=@factorStackEffect
142 syn match   factorExecute           /\vexecute\V(\v/me=e-1 nextgroup=@factorStackEffect
143 syn keyword factorCallNextMethod    call-next-method
144
145 syn region  factorChar        start=/\v<CHAR:>/ end=/\v\S+>/
146
147 syn cluster factorString            contains=factorString,factorTriString,factorPrefixedString
148 syn match   factorEscape            /\v\\([\\astnrbvf0e\"]|u\x{6}|u\{\S+}|x\x{2})/  contained display
149 syn region  factorString            matchgroup=factorStringDelims         start=/\v<"/                 skip=/\v\\"/ end=/\v"/   contains=factorEscape
150 syn region  factorTriString         matchgroup=factorTriStringDelims      start=/\v<"""/               skip=/\v\\"/ end=/\v"""/ contains=factorEscape
151 syn region  factorPrefixedString    matchgroup=factorPrefixedStringDelims start=/\v<[^[:blank:]"]+">/  skip=/\v\\"/ end=/\v"/   contains=factorEscape
152
153 " Vocabulary: multiline
154 " This vocabulary reads the ambient lexer without "parse-raw".
155 syn cluster factorString            add=factorMultilineString,factorHereDocString,factorPrefixedMultilineString
156 syn region  factorMultilineString   matchgroup=factorMultilineStringDelims    start=/\v<\[\z(\={0,6})\[>/   end=/\v\]\z1\]/
157 syn region  factorHereDoc           matchgroup=factorMultilineStringDelims    start=/\v<STRING:\s+\S+>/     end=/\v^;$/
158 syn region  factorHereDocString     matchgroup=factorMultilineStringDelims    start=/\v<HEREDOC:\s+\z(.*)>/ end=/\v^\z1$/
159 syn region  factorPrefixedMultilineString matchgroup=factorPrefixedMultilineStringDelims  start=/\v<[^[\][:blank:]]+\[\z(\={0,6})\[>/   end=/\v\]\z1\]/
160 " These comments are normal syntax words, so no lexer privilege for them.
161 " (Hence, no "syn cluster factorComment" membership.)
162 syn cluster factorMultilineComment  contains=factorMultilineComment,factorMultilineCComment
163 syn region  factorMultilineComment  matchgroup=factorMultilineCommentDelims   start=/\v<!\[\z(\={0,6})\[>/  end=/\v\]\z1\]/ contains=@factorCommentContents keepend
164 syn region  factorMultilineCComment matchgroup=factorMultilineCCommentDelims  start=/\v<\/\*>/              end=/\v\*\//    contains=@factorCommentContents keepend
165
166 syn cluster factorReal                  contains=factorInt,factorFloat,factorPosRatio,factorNegRatio,@factorBin,@factorHex,@factorOct,factorNan
167 syn cluster factorNumber                contains=@factorReal,factorComplex
168 syn match   factorInt                   /\v<[+-]=[0-9]%([0-9,]*[0-9])?%([eE]%([+-])?[0-9]+)?>/
169 syn match   factorFloat                 /\v<[+-]=[0-9]%([0-9,]*[0-9])?%(\.%(%([0-9,]*[0-9]+)?%([eE]%([+-])?[0-9]%([0-9,]*[0-9])?)?)?)?>/
170 syn match   factorPosRatio              /\v<\+=[0-9]%([0-9,]*[0-9])?%(\+[0-9]%([0-9,]*[0-9]+)?)?\/-=[0-9]%([0-9,]*[0-9]+)?\.?>/
171 syn match   factorNegRatio              /\v<\-[0-9]%([0-9,]*[0-9])?%(\-[0-9]%([0-9,]*[0-9]+)?)?\/-=[0-9]%([0-9,]*[0-9]+)?\.?>/
172 syn region  factorComplex         start=/\v<C\{>/   end=/\v<\}>/    contains=@factorReal
173 syn cluster factorBin                   contains=factorBin
174 syn match   factorBin                   /\v<[+-]=0b[01,]+>/
175 if !exists('g:factor_syn_no_error')
176   syn match   factorBinError            /\v<[+-]=0b[01,]*[^01 ]\S*>/
177   syn cluster factorBin                 add=factorBinError
178 endif
179 syn cluster factorHexNoRadixTrans       contains=factorHexNoRadixTrans
180 syn match   factorHexNoRadixTrans       /\v<[0-9a-fA-F]%([0-9a-fA-F,]*[0-9a-fA-F])?%(\.[0-9a-fA-F]%([0-9a-fA-F,]*[0-9a-fA-F])?)?%(p-=[0-9]%([0-9,]*[0-9])?)?>/ contained transparent
181 syn cluster factorHex                   contains=factorHex
182 syn match   factorHex                   /\v<[+-]=0x[0-9a-fA-F]%([0-9a-fA-F,]*[0-9a-fA-F])?%(\.[0-9a-fA-F]%([0-9a-fA-F,]*[0-9a-fA-F])?)?%(p-=[0-9]%([0-9,]*[0-9])?)?>/
183 if !exists('g:factor_syn_no_error')
184   syn match   factorHexNoRadixError     /\v<%(,\S*|\S*,|[-0-9a-fA-Fp,]*[^-0-9a-fA-Fp, ]\S*)>/ contained
185   syn cluster factorHexNoRadixTrans     add=factorHexNoRadixError
186   syn match   factorHexError            /\v<[+-]=0x%(,\S*|\S*,|[-0-9a-fA-Fp,]*[^-0-9a-fA-Fp, ]\S*)>/
187   syn cluster factorHex                 add=factorHexError
188 endif
189 syn cluster factorOct                   contains=factorOct
190 syn match   factorOct                   /\v<[+-]=0o[0-7,]+>/
191 if !exists('g:factor_syn_no_error')
192   syn match   factorOctError             /\v<[+-]=0o%(,\S*|\S*,|[0-7,]*[^0-7, ]\S*)>/
193   syn cluster factorOct                 add=factorOctError
194 endif
195 syn match   factorOct                   /\v<[+-]=0o[0-7,]+>/
196 syn region  factorNan matchgroup=factorNan start=/\v<NAN:>/ matchgroup=NONE end=/\v<\S+>/ contains=@factorComment,@factorHexNoRadixTrans
197
198 syn region  factorBackslash       start=/\v<\\>/   skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
199 syn region  factorMBackslash      start=/\v<M\\>/  skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment
200 syn region  factorLiteral         start=/\v<\$>/   skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
201 syn region  factorLiteralBlock    start=/\v<\$\[>/              end=/\v<\]>/    contains=@factorComment
202
203 syn region  factorIn      start=/\v<IN:>/      skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
204 syn region  factorUse     start=/\v<USE:>/     skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
205 syn region  factorUnuse   start=/\v<UNUSE:>/   skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
206
207 syn region  factorUsing           start=/\v<USING:>/                        end=/\v<;>/     contains=@factorComment
208 syn region  factorQualified       start=/\v<QUALIFIED:>/       skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
209 syn region  factorQualifiedWith   start=/\v<QUALIFIED-WITH:>/  skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment
210 syn region  factorExclude         start=/\v<EXCLUDE:>/                      end=/\v<;>/     contains=@factorComment
211 syn region  factorFrom            start=/\v<FROM:>/                         end=/\v<;>/     contains=@factorComment
212 syn region  factorRename          start=/\v<RENAME:>/          skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+%(\_\s+%(!>.*)?)+\=\>%(\_\s+%(!>.*)?)+\S+>/  contains=@factorComment
213 syn region  factorSingletons      start=/\v<SINGLETONS:>/                   end=/\v<;>/     contains=@factorComment
214 syn region  factorSymbol          start=/\v<SYMBOL:>/          skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
215 syn region  factorSymbols         start=/\v<SYMBOLS:>/                      end=/\v<;>/     contains=@factorComment
216 syn region  factorConstructor2    start=/\v<CONSTRUCTOR:?/                  end=/\v<;>/     contains=@factorComment
217 syn region  factorIntersection    start=/\v<INTERSECTION:>/                 end=/\v<;>/     contains=@factorComment
218 syn cluster factorSlotAttr              contains=factorSlotAttrInitial,factorSlotAttrReadOnly
219 syn cluster factorTupleSlotAttr         contains=@factorSlotAttr
220 syn match   factorTupleSlotName         /\v<\S+>/ nextgroup=factorTupleSlotClassSkip contained
221 syn match   factorTupleSlotNameSkip     /\v%(\_\s+%(!>.*)?)*/ nextgroup=factorTupleSlotName transparent contained
222 syn match   factorTupleSlotClass        /\v<\S+>/ contained
223 " a class is optional, so let an attribute take priority if present
224 syn match   factorTupleSlotClassSkip    /\v%(\_\s+%(!>.*)?)*/ nextgroup=factorTupleSlotClass,@factorTupleSlotAttr transparent contained
225 syn region  factorTupleSlot matchgroup=factorTupleSlotDelims  start=/\v<\{>/                end=/\v<\}>/   contains=@factorComment,factorTupleSlotName,@factorTupleSlotAttr contained
226 syn region  factorTuple matchgroup=factorTupleDelims          start=/\v<%(TUPLE|BUILTIN):>/ end=/\v<;>/ contains=@factorComment,factorTupleSlotName,factorTupleSlot
227 " Abnormally named because factor*Error is reserved for syntax errors.
228 syn region  factorErrorSyn        start=/\v<ERROR:>/            end=/\v<;>/     contains=@factorComment
229 syn region  factorUnion           start=/\v<UNION:>/            end=/\v<;>/     contains=@factorComment
230 syn cluster factorStructSlotAttr        contains=@factorSlotAttr,factorStructSlotAttrBits
231 syn match   factorStructSlotName        /\v<\S+>/ nextgroup=factorStructSlotTypeSkip contained
232 syn match   factorStructSlotNameSkip    /\v%(\_\s+%(!>.*)?)*/ nextgroup=factorStructSlotName contained transparent
233 syn match   factorStructSlotType        /\v<\S+>/ contained
234 syn match   factorStructSlotTypeSkip    /\v%(\_\s+%(!>.*)?)*/ nextgroup=factorStructSlotType contained transparent
235 syn region  factorStructSlot matchgroup=factorStructSlotDelims    start=/\v<\{>/     end=/\v<\}>/ contains=@factorComment,factorStructSlotName,@factorStructSlotAttr contained
236 syn region  factorStruct matchgroup=factorStructDelims            start=/\v<%(UNION-STRUCT|STRUCT):>/   end=/\v<;>/ contains=@factorComment,factorStructSlot
237
238 syn match   factorSlotAttrReadOnly      /\v<read-only>/ contained
239 syn match   factorSlotAttrInitial       /\v<initial:>%(\_\s+%(!>.*)?)+/ contains=@factorComment nextgroup=factorWord,@factorClusterValue contained
240 syn match   factorStructSlotAttrBits    /\v<bits:>%(\_\s+%(!>.*)?)+/    contains=@factorComment nextgroup=factorWord,@factorReal contained
241
242 syn region  factorConstant        start=/\v<CONSTANT:>/    skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
243 syn region  factorAlias           start=/\v<ALIAS:>/       skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment
244 syn region  factorSingleton       start=/\v<SINGLETON:>/   skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
245 syn region  factorPostpone        start=/\v<POSTPONE:>/    skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
246 syn region  factorDefer           start=/\v<DEFER:>/       skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
247 syn region  factorForget          start=/\v<FORGET:>/      skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
248 syn region  factorMixin           start=/\v<MIXIN:>/       skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
249 syn region  factorInstance        start=/\v<INSTANCE:>/    skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment
250 syn region  factorHook            start=/\v<HOOK:>/        skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment nextgroup=factorStackEffectSkip
251 syn region  factorMain            start=/\v<MAIN:>/        skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
252 syn region  factorConstructor     start=/\v<C:>/           skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment
253 syn region  factorAlien matchgroup=factorAlien start=/\v<ALIEN:>/ matchgroup=NONE  skip=/\v<!>/ end=/\v<\S+>/  contains=@factorComment,@factorHexNoRadixTrans 
254 syn region  factorSlot            start=/\v<SLOT:>/        skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
255
256 syn cluster factorWordOps   contains=factorConstant,factorAlias,factorSingleton,factorSingletons,factorSymbol,factorSymbols,factorPostpone,factorDefer,factorForget,factorMixin,factorInstance,factorHook,factorMain,factorConstructor
257
258 "TODO:
259 "misc:
260 " HELP:
261 " ARTICLE:
262 "literals:
263 " PRIMITIVE:
264
265 "C interface:
266 " C-ENUM:
267 " FUNCTION:
268 " TYPEDEF:
269 " LIBRARY:
270 "#\ "
271
272 if !exists('g:factor_syn_no_error')
273   syn match   factorStackEffectRequired /\v<\V(\@!\v\S+>/    contained
274 endif
275 syn cluster factorStackEffectContents   contains=@factorComment,factorStackEffectDelims,factorStackEffectVar,factorStackEffectType,factorStackEffectRowVar
276 syn cluster factorStackEffect           contains=factorStackEffect
277 " Erroring on stack effects without a "--" separator would be nice.
278 " Unfortunately, that sort of vacuous detection is above Vim's pay-grade,
279 "   especially when stack effects can be nested arbitrarily via types.
280 syn match   factorStackEffectSkip       /\v%(\_\s+%(!>.*)?)*/ nextgroup=factorStackEffectRequired,@factorStackEffect transparent contained
281 syn region  factorStackEffect       matchgroup=factorStackEffectDelims    start=/\v\V(\v>/  end=/\v<\V)\v>/ contains=@factorStackEffectContents
282 syn match   factorStackEffectVar        /\v<\S+>/           contained
283 " Note that ":!" parses to the "!" word and doesn't lex as a comment.
284 " Also, even though we take any value, the leading ":" breaking the word
285 "   boundary means a lot of our nicer syntax patterns don't match on
286 "   "factorStackEffectType".
287 " syn cluster factorStackEffectType contains=factorWord,@factorStackEffect
288 syn cluster factorStackEffectType       contains=@factorClusterValue
289 syn region  factorStackEffectVar    matchgroup=factorStackEffectVar       start=/\v<\S+:>/       matchgroup=NONE end=/\v%(\_\s+%(!>.*)?)+/ contains=@factorComment nextgroup=@factorStackEffectType transparent contained
290 syn match   factorStackEffectType       /\v<:/              contained nextgroup=@factorStackEffectType
291 syn match   factorStackEffectRowVar     /\v<\.\.\S+>/       contained
292 syn region  factorStackEffectRowVar matchgroup=factorStackEffectRowVar    start=/\v<\.\.\S+:>/   matchgroup=NONE end=/\v%(\_\s+%(!>.*)?)+/ contains=@factorComment nextgroup=@factorStackEffectType transparent contained
293 syn match   factorStackEffectDelims     /\v<-->/            contained
294 if !exists('g:factor_syn_no_error')
295   syn cluster factorStackEffectContents add=factorStackEffectError
296   syn keyword factorStackEffectError    (                   contained
297 endif
298
299 " adapted from lisp.vim
300 if exists('g:factor_syn_no_rainbow')
301   syn cluster factorQuotation   contains=factorQuotation
302   syn region  factorQuotation      matchgroup=factorDelimiter start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/    contains=ALL
303 else
304   syn cluster factorQuotation   contains=factorQuotation0
305   syn region  factorQuotation0            matchgroup=hlLevel0 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/    contains=@factorCluster,factorQuotation1,factorArray1
306   syn region  factorQuotation1 contained  matchgroup=hlLevel1 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/    contains=@factorCluster,factorQuotation2,factorArray2
307   syn region  factorQuotation2 contained  matchgroup=hlLevel2 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/    contains=@factorCluster,factorQuotation3,factorArray3
308   syn region  factorQuotation3 contained  matchgroup=hlLevel3 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/    contains=@factorCluster,factorQuotation4,factorArray4
309   syn region  factorQuotation4 contained  matchgroup=hlLevel4 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/    contains=@factorCluster,factorQuotation5,factorArray5
310   syn region  factorQuotation5 contained  matchgroup=hlLevel5 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/    contains=@factorCluster,factorQuotation6,factorArray6
311   syn region  factorQuotation6 contained  matchgroup=hlLevel6 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/    contains=@factorCluster,factorQuotation7,factorArray7
312   syn region  factorQuotation7 contained  matchgroup=hlLevel7 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/    contains=@factorCluster,factorQuotation8,factorArray8
313   syn region  factorQuotation8 contained  matchgroup=hlLevel8 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/    contains=@factorCluster,factorQuotation9,factorArray9
314   syn region  factorQuotation9 contained  matchgroup=hlLevel9 start=/\v<%(%(%('|\$|)\[)|\[%(let|\|))>/  end=/\v<\]>/    contains=@factorCluster,factorQuotation0,factorArray0
315 endif
316
317 if exists('g:factor_syn_no_rainbow')
318   syn cluster factorArray       contains=factorArray
319   syn region  factorArray          matchgroup=factorDelimiter start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/        end=/\v<\}>/    contains=ALL
320 else
321   syn cluster factorArray       contains=factorArray0
322   syn region  factorArray0               matchgroup=hlLevel0 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray1,factorQuotation1
323   syn region  factorArray1     contained matchgroup=hlLevel1 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray2,factorQuotation2
324   syn region  factorArray2     contained matchgroup=hlLevel2 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray3,factorQuotation3
325   syn region  factorArray3     contained matchgroup=hlLevel3 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray4,factorQuotation4
326   syn region  factorArray4     contained matchgroup=hlLevel4 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray5,factorQuotation5
327   syn region  factorArray5     contained matchgroup=hlLevel5 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray6,factorQuotation6
328   syn region  factorArray6     contained matchgroup=hlLevel6 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray7,factorQuotation7
329   syn region  factorArray7     contained matchgroup=hlLevel7 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray8,factorQuotation8
330   syn region  factorArray8     contained matchgroup=hlLevel8 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray9,factorQuotation9
331   syn region  factorArray9     contained matchgroup=hlLevel9 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray0,factorQuotation0
332 endif
333
334 if !exists('g:factor_syn_no_error')
335   syn match   factorBracketError    /\v<\]>/
336   syn match   factorBracketError    /\v<\}>/
337 endif
338
339 function! FactorSynDefineComment() abort
340   syn region  factorComment   start=/\v<!>/ end=/\v$/   keepend oneline contains=@factorCommentContents
341   syn match   factorShebang         /\v%^\#!.*$/ display
342   if !exists('g:factor_syn_no_error')
343     syn match   factorShebangError  /\v%^\#!\S+/
344   endif
345 endfunction
346
347 if !exists('g:factor_syn_no_comment')
348   call FactorSynDefineComment()
349 endif
350
351 " Syntax that bypasses comment lexing.
352 function! FactorSynDefineAfterComment() abort
353 endfunction
354
355 if !exists('g:factor_syn_no_after_comment')
356   call FactorSynDefineAfterComment()
357 endif
358
359 syn sync lines=100
360
361 if !exists('g:factor_syn_no_init')
362   command -nargs=+ -bar HiLink hi def link <args>
363
364   if !exists('g:factor_syn_no_error')
365     HiLink factorShebangError           Error
366     HiLink factorBracketError           Error
367     HiLink factorBinError               Error
368     HiLink factorHexNoRadixError        Error
369     HiLink factorHexError               Error
370     HiLink factorOctError               Error
371     HiLink factorStackEffectRequired    Error
372     HiLink factorStackEffectError       Error
373   endif
374
375   HiLink   factorComment                Comment
376   HiLink   factorMultilineComment       factorComment
377   HiLink   factorMultilineCComment      factorComment
378   HiLink   factorShebang                PreProc
379   HiLink   factorStackEffect            Type
380   HiLink   factorStackEffectDelims      Delimiter
381   HiLink   factorStackEffectVar         Identifier
382   HiLink   factorStackEffectRowVar      factorStackEffectVar
383   HiLink   factorStackEffectType        Type
384   HiLink   factorTodo                   Todo
385   HiLink   factorInclude                Include
386   HiLink   factorWord                   Keyword
387   HiLink   factorCallQuotation          Keyword
388   HiLink   factorExecute                Keyword
389   HiLink   factorCallNextMethod         Keyword
390   HiLink   factorOperator               Operator
391   HiLink   factorFrySpecifier           Operator
392   HiLink   factorBoolean                Boolean
393   HiLink   factorBreakpoint             Debug
394   HiLink   factorDefnDelims             Typedef
395   HiLink   factorMethodDelims           Typedef
396   HiLink   factorGeneric                Typedef
397   HiLink   factorGenericN               Typedef
398   HiLink   factorConstructor            Typedef
399   HiLink   factorConstructor2           Typedef
400   HiLink   factorPrivate                Special
401   HiLink   factorPDefnDelims            Special
402   HiLink   factorPMethodDelims          Special
403   HiLink   factorPGenericDelims         Special
404   HiLink   factorPGenericNDelims        Special
405   HiLink   factorEscape                 SpecialChar
406   HiLink   factorString                 String
407   HiLink   factorStringDelims           factorString
408   HiLink   factorTriString              factorString
409   HiLink   factorTriStringDelims        factorTriString
410   HiLink   factorPrefixedString         factorString
411   HiLink   factorPrefixedStringDelims   factorPrefixedString
412   HiLink   factorMultilineString        factorString
413   HiLink   factorMultilineStringDelims  Typedef
414   HiLink   factorHereDocString          factorMultilineString
415   HiLink   factorHereDocStringDelims    factorMultilineStringDelims
416   HiLink   factorPrefixedMultilineString factorString
417   HiLink   factorPrefixedMultilineStringDelims factorMultilineStringDelims
418   HiLink   factorComplex                Number
419   HiLink   factorPosRatio               Number
420   HiLink   factorNegRatio               Number
421   HiLink   factorBin                    Number
422   HiLink   factorHex                    Number
423   HiLink   factorNan                    Number
424   HiLink   factorOct                    Number
425   HiLink   factorFloat                  Float
426   HiLink   factorInt                    Number
427   HiLink   factorUsing                  Include
428   HiLink   factorQualified              Include
429   HiLink   factorQualifiedWith          Include
430   HiLink   factorExclude                Include
431   HiLink   factorFrom                   Include
432   HiLink   factorRename                 Include
433   HiLink   factorUse                    Include
434   HiLink   factorUnuse                  Include
435   HiLink   factorIn                     Define
436   HiLink   factorChar                   Character
437   HiLink   factorDelimiter              Delimiter
438   HiLink   factorBackslash              Special
439   HiLink   factorMBackslash             Special
440   HiLink   factorLiteral                Special
441   HiLink   factorLiteralBlock           Special
442   HiLink   factorDeclaration            Typedef
443   HiLink   factorSymbol                 Define
444   HiLink   factorSymbols                Define
445   HiLink   factorConstant               Define
446   HiLink   factorAlias                  Define
447   HiLink   factorSingleton              Define
448   HiLink   factorSingletons             Define
449   HiLink   factorMixin                  Typedef
450   HiLink   factorInstance               Typedef
451   HiLink   factorHook                   Typedef
452   HiLink   factorMain                   Define
453   HiLink   factorPostpone               Define
454   HiLink   factorDefer                  Define
455   HiLink   factorForget                 Define
456   HiLink   factorAlien                  Define
457   HiLink   factorSlot                   Define
458   HiLink   factorIntersection           Typedef
459   HiLink   factorSlot                   Typedef
460   HiLink   factorSlotDelims             factorSlot
461   HiLink   factorSlotName               Identifier
462   HiLink   factorSlotClass              Type
463   HiLink   factorSlotType               factorSlotClass
464   HiLink   factorSlotAttr               Special
465   HiLink   factorSlotAttrInitial        factorSlotAttr
466   HiLink   factorSlotAttrReadOnly       factorSlotAttr
467   HiLink   factorStructSlotAttr         factorSlotAttr
468   HiLink   factorStructSlotAttrBits     factorStructSlotAttr
469   HiLink   factorTuple                  Typedef
470   HiLink   factorTupleDelims            factorTuple
471   HiLink   factorTupleSlot              factorSlot
472   HiLink   factorTupleSlotDelims        factorSlotDelims
473   HiLink   factorTupleSlotName          factorSlotName
474   HiLink   factorTupleSlotClass         factorSlotClass
475   HiLink   factorErrorSyn               Typedef
476   HiLink   factorUnion                  Typedef
477   HiLink   factorStruct                 Typedef
478   HiLink   factorStructDelims           factorStruct
479   HiLink   factorStructSlot             factorSlot
480   HiLink   factorStructSlotDelims       factorSlotDelims
481   HiLink   factorStructSlotName         factorSlotName
482   HiLink   factorStructSlotType         factorSlotType
483
484   if &bg == 'dark'
485     hi   hlLevel0 ctermfg=red           guifg=red1
486     hi   hlLevel1 ctermfg=yellow        guifg=orange1
487     hi   hlLevel2 ctermfg=green         guifg=yellow1
488     hi   hlLevel3 ctermfg=cyan          guifg=greenyellow
489     hi   hlLevel4 ctermfg=magenta       guifg=green1
490     hi   hlLevel5 ctermfg=red           guifg=springgreen1
491     hi   hlLevel6 ctermfg=yellow        guifg=cyan1
492     hi   hlLevel7 ctermfg=green         guifg=slateblue1
493     hi   hlLevel8 ctermfg=cyan          guifg=magenta1
494     hi   hlLevel9 ctermfg=magenta       guifg=purple1
495   else
496     hi   hlLevel0 ctermfg=red           guifg=red3
497     hi   hlLevel1 ctermfg=darkyellow    guifg=orangered3
498     hi   hlLevel2 ctermfg=darkgreen     guifg=orange2
499     hi   hlLevel3 ctermfg=blue          guifg=yellow3
500     hi   hlLevel4 ctermfg=darkmagenta   guifg=olivedrab4
501     hi   hlLevel5 ctermfg=red           guifg=green4
502     hi   hlLevel6 ctermfg=darkyellow    guifg=paleturquoise3
503     hi   hlLevel7 ctermfg=darkgreen     guifg=deepskyblue4
504     hi   hlLevel8 ctermfg=blue          guifg=darkslateblue
505     hi   hlLevel9 ctermfg=darkmagenta   guifg=darkviolet
506   endif
507 endif
508 delcommand HiLink
509
510 let b:current_syntax = 'factor'
511
512 " vim: set ft=vim et sw=2 isk+=/,\\ :