]> gitweb.factorcode.org Git - factor.git/commitdiff
vim/syntax: Even more fixups.
authorDusk <me@bb010g.com>
Tue, 9 Jun 2020 21:41:02 +0000 (14:41 -0700)
committerJohn Benediktsson <mrjbq7@gmail.com>
Wed, 10 Jun 2020 03:12:30 +0000 (03:12 +0000)
|:syn-priority| is respected now, :syn-skip & :syn-keepend are used
when appropriate, newlines don't jank stuff up, comments don't extend
match regions, numbers are much more reliable, and stack effect error
highlights return.

A feature request has even been sent to Bram.
https://github.com/vim/vim/issues/872#issuecomment-641025231

misc/syntax-test.factor
misc/vim/syntax/factor.vim

index ca39b3ad38ca978991a914a4a2c7f40fced001a4..6e9223770aef3c52ade67c7daa34e0ff49947907 100644 (file)
 ! Definitions
 
     : word ( x -- ) drop ;
 ! Definitions
 
     : word ( x -- ) drop ;
+    : word error drop ;
     :: word ( x -- ) x drop ;
     TYPED: word ( a b: class ... -- x: class y ... ) body ;
     TYPED:: word ( a b: class ... -- x: class y ... ) body ;
     MACRO: word ( inputs... -- ) definition... ) ;
     MACRO:: word ( vars... -- outputs... ) definition... ) ;
     :: word ( x -- ) x drop ;
     TYPED: word ( a b: class ... -- x: class y ... ) body ;
     TYPED:: word ( a b: class ... -- x: class y ... ) body ;
     MACRO: word ( inputs... -- ) definition... ) ;
     MACRO:: word ( vars... -- outputs... ) definition... ) ;
-    M: class generic (definition) ... ;
+    M: object explain drop "an object" print ;
+    M: class generic definition... ;
     M:: class generic ( vars... -- outputs... ) body... ;
     M:: class generic ( vars... -- outputs... ) body... ;
+    M:: class generic error body... ;
     GENERIC: word ( stack -- effect )
     GENERIC: word ( stack -- effect )
+    GENERIC: word
+        ( stack -- effect )
+    GENERIC: word
+( stack -- effect )
+    GENERIC: word ! comment
+        ( stack -- effect )
+    GENERIC: word drop ! 3rd token wrong
+    GENERIC: word ! next line wrong
+        drop
+    GENERIC: word
+drop ! wrong
     HOOK: word variable ( stack -- effect )
     GENERIC#: word 1 ( stack -- effect )
     HOOK: word variable ( stack -- effect )
     GENERIC#: word 1 ( stack -- effect )
+    GENERIC#: ! comment
+        word 1 ( stack -- effect )
+    GENERIC#: word 1 ( stack -- effect ) drop ! last token other
+    GENERIC#: word ! 2 should GENERIC# stack effect error
+        1 2 ( stack -- effect )
+    GENERIC#: word ! 2nd eff. should be independent of GENERIC#,
+        1 ! and 2 & 3 shouldn't GENERIC# highlight
+        ( stack -- effect ) ( independent -- effect ) 2 3
+    GENERIC#: word 1 ! comment
+        drop ! wrong
     MATH: + ( x y -- z ) foldable flushable
     SLOT: name
     C: <foo> foo
     MATH: + ( x y -- z ) foldable flushable
     SLOT: name
     C: <foo> foo
@@ -73,7 +97,7 @@
     TYPED:: word ( a b: class ... -- x: class y ... ) body ;
     MACRO: word ( inputs... -- ) definition... ) ;
     MACRO:: word ( vars... -- outputs... ) definition... ) ;
     TYPED:: word ( a b: class ... -- x: class y ... ) body ;
     MACRO: word ( inputs... -- ) definition... ) ;
     MACRO:: word ( vars... -- outputs... ) definition... ) ;
-    M: class generic (definition) ... ;
+    M: class generic definition... ;
     M:: class generic ( vars... -- outputs... ) body... ;
     GENERIC: word ( stack -- effect )
     HOOK: word variable ( stack -- effect )
     M:: class generic ( vars... -- outputs... ) body... ;
     GENERIC: word ( stack -- effect )
     HOOK: word variable ( stack -- effect )
@@ -226,12 +250,25 @@ PRIVATE>
     -1.5e30
     1.5e-30
     1,000.1,2
     -1.5e30
     1.5e-30
     1,000.1,2
-    0xCAFEBABE
+    0XCAFEBABE
     0x1AB4p30
     0x1AB4p30
-    0b10101
-    0o1234567
-    NAN: CAFE1234
+    0B10101
+    0O1234567
+    NAN: CAFE1234 0,. ! third token wrong
+    0,. ! wrong, next line also wrong
+    0,.
+    NAN: ! ff 0xff comment
+        xCAFE1234 ! wrong
+        ff ! shouldn't match as a hex number
+    0o7
     NAN: 0
     NAN: 0
+    drop
+    NAN: !
+        ! a 1 comment 1
+        f
+
+    NAN:
+f,
 
 ! Not numbers
 
 
 ! Not numbers
 
@@ -270,6 +307,8 @@ PRIVATE>
 
     ( x n -- (x)n )
 
 
     ( x n -- (x)n )
 
+    ( p:
+boolean -- q: boolean )
     ( m: integer -- n: float )
     ( :integer -- :float )
 
     ( m: integer -- n: float )
     ( :integer -- :float )
 
@@ -304,8 +343,33 @@ tail?
 -0.1
 -0,1.1
 1.
 -0.1
 -0,1.1
 1.
-.  ! wrong
--. ! wrong
+.  ! other
+-. ! other
+
+! Numeral comma separator parsing (!: wrong, ~: other):
+  ! int
+  0 00 0,0 +0,0 -0,,0
+  /* ! */ ,0 ,00 0,, 00,, +,0 -,,0 +0, -0,, /* ~ */ , +, -,,
+
+  ! float
+  0,0e0 0e0,0 0,0e0,0 +0,0e+0,0 -0,0e-0,0
+  /* ~ */ e e, ,e ,e, +e -e +e, -e,
+  /* ~ */ +e -e +,e -,e +e+, -e-, +,e-,, -,,e+,
+  /* ~ */ +e -e +,e -,e +e+, -e-, +,e-,, -,,e+,
+  /* ! */ e0, -e,0 ,0e, 0,e, +,e0 -,e-0 0,e0 +0,0e+ -0,0e-,, 0e+ -0e-
+  /* ! */ +0e+0, -0e-,,0
+
+  ! float
+  0,0. .0,0 /* ! */ 0,. .,0 ,.0 0., ,0. .0,
+  +0,0.0 -0,0.0,0
+  0,0.0,0e0 0,0.0,0e0,0
+  0,0.0,0e+0,0 0,0.0,0e-0,0
+
+  ! ratio
+  /* ~ */ / /. +/ -/ ,/ /, 0/ /0
+  0/1 1/1 1/1. 1/0. 0/0. /* ! */ 0/0 1/0 1./1
+  1/2 +1/2 -1/2 +2/2 /* ! */ 1/+2 1/-2 1/+0 +2/+2
+  +1+1/2 -0-1/2 /* ! */ +1+2/2 +1+1/2. +0-1/2 -0+1/2
 
 ! Regexp is colored wrong (on Github):
 
 
 ! Regexp is colored wrong (on Github):
 
index cd418c8ca563f8d81d0e2a3abb070db8e82addb2..70cec742a2ade75ecae533584efc81481e854edf 100644 (file)
@@ -18,7 +18,7 @@
 " ":echo (col('.') - 1) % 4" is handy here.
 "
 " All syntax patterns (|:syn-pattern|) are "very magic" (|/\v|).
 " ":echo (col('.') - 1) % 4" is handy here.
 "
 " All syntax patterns (|:syn-pattern|) are "very magic" (|/\v|).
-" Escape all literal [^0-9a-zA-Z_-!:;] characters in these patterns.
+" Escape all literal [^[:alnum:]_-!:;] characters in these patterns.
 " (Not escaping [-!:;] characters risks forward-incompatibility,
 "   but fixes if an incompatibile Vim arises would be trivial,
 "   and Factor likes these characters.)
 " (Not escaping [-!:;] characters risks forward-incompatibility,
 "   but fixes if an incompatibile Vim arises would be trivial,
 "   and Factor likes these characters.)
@@ -33,8 +33,8 @@
 " This still applies to clusters named "{group-name}Trans".
 "
 " Syntax groups "{group-name}Skip" have the form:
 " This still applies to clusters named "{group-name}Trans".
 "
 " Syntax groups "{group-name}Skip" have the form:
-" "syn match {group-name}Skip /\v%(\_\s+%(!>.*)?)*/ nextgroup={group-name} transparent contained"
-" Specifying "nextgroup={group-name}Skip" works like a Factor-aware
+" "syn match {group-name}Skip /\v%(\_\s+%(!>.*)?)*/ contains=@factorComment nextgroup={group-name} transparent contained"
+" Specifying "nextgroup={group-name}Skip skipempty" works like a Factor-aware
 "   "nextgroup={group-name} skipwhite skipempty"
 "   with required initial space (not optional).
 " "{cluster-name}Skip" works similarly, but with "nextgroup=@{cluster-name}".
 "   "nextgroup={group-name} skipwhite skipempty"
 "   with required initial space (not optional).
 " "{cluster-name}Skip" works similarly, but with "nextgroup=@{cluster-name}".
 " Vim's syntax highlighting freaks at paired "/\v\(" and "/\v\)". ☹
 " Switching into very nomagic (with "/\V(\v/" or "/\V)\v") averts that,
 "   as non-escaped parentheses don't extend pattern regions.
 " Vim's syntax highlighting freaks at paired "/\v\(" and "/\v\)". ☹
 " Switching into very nomagic (with "/\V(\v/" or "/\V)\v") averts that,
 "   as non-escaped parentheses don't extend pattern regions.
+"
+" A handy testing command:
+" "echo join(map(synstack(line('.'),col('.')),{sn->{i,s->{t->sn(s).(s==t?'':' ('.sn(t).')')}(synIDtrans(s))}}({s->synIDattr(s,'name')})),' -> ')"
+"   Outputs in the form "hi<...> trans<...> lo<...>":
+"     "hi": syntax group
+"     "trans": transparent syntax group (if not applicable, same as "hi")
+"     "lo": highlight group
 
 if exists('b:current_syntax')
   finish
 
 if exists('b:current_syntax')
   finish
@@ -114,31 +121,34 @@ syn match   factorTodo              /\v(TODO|FIXME|XXX):=/ contained
 
 syn cluster factorDefnContents      contains=@factorCluster
 
 
 syn cluster factorDefnContents      contains=@factorCluster
 
-syn region  factorDefnDelims      start=/\v<%(SYNTAX|%(MACRO|MEMO|TYPED)?:?):>/    skip=/\v<!>/ end=/\v<\S+>/ contains=@factorComment nextgroup=factorStackEffect contained
-syn region  factorDefn            start=/\v<%(SYNTAX|%(MACRO|MEMO|TYPED)?:?):>/    skip=/\v<!>/ matchgroup=factorDefnDelims     end=/\v<;>/ contains=factorDefnDelims,@factorDefnContents
-syn region  factorMethod          start=/\v<M::?>/                                 skip=/\v<!>/ matchgroup=factorDefnDelims     end=/\v<;>/ contains=factorMethodDelims,@factorDefnContents
-syn region  factorMethodDelims    start=/\v<M::?>/                                 skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment nextgroup=factorStackEffect contained
-syn region  factorGeneric         start=/\v<%(GENERIC|MATH|PRIMITIVE):>/           skip=/\v<!>/ end=/\v<\S+>/ contains=@factorComment nextgroup=factorStackEffect
-syn region  factorGenericN        start=/\v<GENERIC\#:>/                           skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\d+>/ contains=@factorComment nextgroup=factorStackEffect
-
-syn region  factorPDefn           start=/\v<%(SYNTAX|%(MACRO|MEMO|TYPED)?:?):>/    skip=/\v<!>/ matchgroup=factorPDefnDelims    end=/\v<;>/ contains=factorPDefnDelims,@factorDefnContents contained
-syn region  factorPDefnDelims     start=/\v<%(SYNTAX|%(MACRO|MEMO|TYPED)?:?):>/    skip=/\v<!>/ end=/\v<\S+>/ contains=@factorComment nextgroup=factorStackEffect contained
-syn region  factorPMethod         start=/\v<M::?>/                                 skip=/\v<!>/ matchgroup=factorPDefnDelims    end=/\v<;>/ contains=factorPMethodDelims,@factorDefnContents contained
-syn region  factorPMethodDelims   start=/\v<M::?>/                                 skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment nextgroup=factorStackEffect contained
-syn region  factorPGeneric        start=/\v<%(GENERIC|MATH|PRIMITIVE):>/           skip=/\v<!>/ end=/\v<\S+>/ contains=@factorComment nextgroup=factorStackEffect contained
-syn region  factorPGenericN       start=/\v<GENERIC\#:>/                           skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\d+>/ contains=@factorComment nextgroup=factorStackEffect contained
-
-syn region  None matchgroup=factorPrivate start=/\v<\<PRIVATE>/ end=/\v<PRIVATE\>>/ contains=@factorDefnContents,factorPDefn,factorPMethod,factorPGeneric,factorPGenericN
+syn region  factorDefn            start=/\v<%(SYNTAX|%(MACRO|MEMO|TYPED)?:?):>/                 matchgroup=factorDefnDelims     end=/\v<;>/ contains=factorDefnDelims,@factorDefnContents
+syn region  factorDefnDelims      start=/\v<%(SYNTAX|%(MACRO|MEMO|TYPED)?:?):>/ end=/\v<\S+>/   contains=@factorComment nextgroup=factorStackEffectSkip skipempty contained
+syn region  factorMethod          start=/\v<M:>/                                                matchgroup=factorMethodDelims     end=/\v<;>/ contains=factorMethodDelims,@factorDefnContents
+syn region  factorMethodDelims    start=/\v<M:>/               skip=/\v<!>.*/   end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment skipempty keepend contained
+syn region  factorLocalsMethod    start=/\v<M::>/                                               matchgroup=factorLocalsMethodDelims     end=/\v<;>/ contains=factorLocalsMethodDelims,@factorDefnContents
+syn region  factorLocalsMethodDelims    start=/\v<M::>/        skip=/\v<!>.*/   end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment nextgroup=factorStackEffectSkip skipempty keepend contained
+syn region  factorGeneric         start=/\v<%(GENERIC|MATH|PRIMITIVE):>/                        end=/\v<\S+>/   contains=@factorComment nextgroup=factorStackEffectSkip skipempty
+syn region  factorGenericN matchgroup=factorGenericN  start=/\v<GENERIC\#:>/   skip=/\v<!>.*/   end=/\v<\S+%(\_\s+%(!>.*)?)+\d+>/   contains=@factorComment nextgroup=factorStackEffectSkip skipempty keepend
+
+syn region  factorPDefn           start=/\v<%(SYNTAX|%(MACRO|MEMO|TYPED)?:?):>/                 matchgroup=factorPDefnDelims    end=/\v<;>/ contains=factorPDefnDelims,@factorDefnContents contained
+syn region  factorPDefnDelims     start=/\v<%(SYNTAX|%(MACRO|MEMO|TYPED)?:?):>/ end=/\v<\S+>/   contains=@factorComment nextgroup=factorStackEffectSkip skipempty contained
+syn region  factorPMethod         start=/\v<M:>/                                                matchgroup=factorPMethodDelims  end=/\v<;>/ contains=factorPMethodDelims,@factorDefnContents contained
+syn region  factorPMethodDelims   start=/\v<M:>/               skip=/\v<!>.*/   end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment skipempty keepend contained
+syn region  factorPLocalsMethod   start=/\v<M::>/                                               matchgroup=factorPLocalsMethodDelims    end=/\v<;>/ contains=factorPLocalsMethodDelims,@factorDefnContents contained
+syn region  factorPLocalsMethodDelims   start=/\v<M::>/        skip=/\v<!>.*/   end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment nextgroup=factorStackEffectSkip skipempty keepend contained
+syn region  factorPGeneric        start=/\v<%(GENERIC|MATH|PRIMITIVE):>/                        end=/\v<\S+>/   contains=@factorComment nextgroup=factorStackEffectSkip skipempty contained
+syn region  factorPGenericN matchgroup=factorPGenericN    start=/\v<GENERIC\#:>/   skip=/\v<!>.*/   end=/\v<\S+%(\_\s+%(!>.*)?)+\d+>/ contains=@factorComment nextgroup=factorStackEffectSkip skipempty keepend contained
+
+syn region  factorPrivate matchgroup=factorPrivate start=/\v<\<PRIVATE>/ end=/\v<PRIVATE\>>/ contains=@factorDefnContents,factorPDefn,factorPMethod,factorPLocalsMethod,factorPGeneric,factorPGenericN transparent
 
 syn cluster factorClusterValue      contains=factorBreakpoint,factorBoolean,factorFrySpecifier,factorChar,@factorString,@factorNumber,factorBackslash,factorMBackslash,factorLiteral,factorLiteralBlock,@factorStackEffect,@factorQuotation,@factorArray
 
 syn cluster factorClusterValue      contains=factorBreakpoint,factorBoolean,factorFrySpecifier,factorChar,@factorString,@factorNumber,factorBackslash,factorMBackslash,factorLiteral,factorLiteralBlock,@factorStackEffect,@factorQuotation,@factorArray
-syn match   factorClusterValueSkip  /\v%(\_\s+%(!>.*)?)*/ nextgroup=@factorClusterValue transparent contained
 
 syn keyword factorBoolean           f t
 syn keyword factorBreakpoint        B
 syn keyword factorFrySpecifier      @ _ contained
 syn keyword factorDeclaration       delimiter deprecated final flushable foldable inline recursive
 
 syn keyword factorBoolean           f t
 syn keyword factorBreakpoint        B
 syn keyword factorFrySpecifier      @ _ contained
 syn keyword factorDeclaration       delimiter deprecated final flushable foldable inline recursive
-syn match   factorCallQuotation     /\vcall\V(\v/me=e-1    nextgroup=@factorStackEffect
-syn match   factorExecute           /\vexecute\V(\v/me=e-1 nextgroup=@factorStackEffect
+syn match   factorCallQuotation     /\v<call\V(\v/me=e-1    nextgroup=@factorStackEffect
+syn match   factorExecute           /\v<execute\V(\v/me=e-1 nextgroup=@factorStackEffect
 syn keyword factorCallNextMethod    call-next-method
 
 syn region  factorChar        start=/\v<CHAR:>/ end=/\v\S+>/
 syn keyword factorCallNextMethod    call-next-method
 
 syn region  factorChar        start=/\v<CHAR:>/ end=/\v\S+>/
@@ -146,6 +156,7 @@ syn region  factorChar        start=/\v<CHAR:>/ end=/\v\S+>/
 syn cluster factorString            contains=factorString,factorTriString,factorPrefixedString
 syn match   factorEscape            /\v\\([\\astnrbvf0e\"]|u\x{6}|u\{\S+}|x\x{2})/  contained display
 syn region  factorString            matchgroup=factorStringDelims         start=/\v<"/                 skip=/\v\\"/ end=/\v"/   contains=factorEscape
 syn cluster factorString            contains=factorString,factorTriString,factorPrefixedString
 syn match   factorEscape            /\v\\([\\astnrbvf0e\"]|u\x{6}|u\{\S+}|x\x{2})/  contained display
 syn region  factorString            matchgroup=factorStringDelims         start=/\v<"/                 skip=/\v\\"/ end=/\v"/   contains=factorEscape
+" Removed Factor syntax.
 syn region  factorTriString         matchgroup=factorTriStringDelims      start=/\v<"""/               skip=/\v\\"/ end=/\v"""/ contains=factorEscape
 syn region  factorPrefixedString    matchgroup=factorPrefixedStringDelims start=/\v<[^[:blank:]"]+">/  skip=/\v\\"/ end=/\v"/   contains=factorEscape
 
 syn region  factorTriString         matchgroup=factorTriStringDelims      start=/\v<"""/               skip=/\v\\"/ end=/\v"""/ contains=factorEscape
 syn region  factorPrefixedString    matchgroup=factorPrefixedStringDelims start=/\v<[^[:blank:]"]+">/  skip=/\v\\"/ end=/\v"/   contains=factorEscape
 
@@ -153,8 +164,8 @@ syn region  factorPrefixedString    matchgroup=factorPrefixedStringDelims start=
 " This vocabulary reads the ambient lexer without "parse-raw".
 syn cluster factorString            add=factorMultilineString,factorHereDocString,factorPrefixedMultilineString
 syn region  factorMultilineString   matchgroup=factorMultilineStringDelims    start=/\v<\[\z(\={0,6})\[>/   end=/\v\]\z1\]/
 " This vocabulary reads the ambient lexer without "parse-raw".
 syn cluster factorString            add=factorMultilineString,factorHereDocString,factorPrefixedMultilineString
 syn region  factorMultilineString   matchgroup=factorMultilineStringDelims    start=/\v<\[\z(\={0,6})\[>/   end=/\v\]\z1\]/
-syn region  factorHereDoc           matchgroup=factorMultilineStringDelims    start=/\v<STRING:\s+\S+>/     end=/\v^;$/
-syn region  factorHereDocString     matchgroup=factorMultilineStringDelims    start=/\v<HEREDOC:\s+\z(.*)>/ end=/\v^\z1$/
+syn region  factorHereDoc           matchgroup=factorHereDocDelims            start=/\v<STRING:\s+\S+>/     end=/\v^;$/
+syn region  factorHereDocString     matchgroup=factorHereDocStringDelims      start=/\v<HEREDOC:\s+\z(.*)>/ end=/\v^\z1$/
 syn region  factorPrefixedMultilineString matchgroup=factorPrefixedMultilineStringDelims  start=/\v<[^[\][:blank:]]+\[\z(\={0,6})\[>/   end=/\v\]\z1\]/
 " These comments are normal syntax words, so no lexer privilege for them.
 " (Hence, no "syn cluster factorComment" membership.)
 syn region  factorPrefixedMultilineString matchgroup=factorPrefixedMultilineStringDelims  start=/\v<[^[\][:blank:]]+\[\z(\={0,6})\[>/   end=/\v\]\z1\]/
 " These comments are normal syntax words, so no lexer privilege for them.
 " (Hence, no "syn cluster factorComment" membership.)
@@ -162,75 +173,97 @@ syn cluster factorMultilineComment  contains=factorMultilineComment,factorMultil
 syn region  factorMultilineComment  matchgroup=factorMultilineCommentDelims   start=/\v<!\[\z(\={0,6})\[>/  end=/\v\]\z1\]/ contains=@factorCommentContents keepend
 syn region  factorMultilineCComment matchgroup=factorMultilineCCommentDelims  start=/\v<\/\*>/              end=/\v\*\//    contains=@factorCommentContents keepend
 
 syn region  factorMultilineComment  matchgroup=factorMultilineCommentDelims   start=/\v<!\[\z(\={0,6})\[>/  end=/\v\]\z1\]/ contains=@factorCommentContents keepend
 syn region  factorMultilineCComment matchgroup=factorMultilineCCommentDelims  start=/\v<\/\*>/              end=/\v\*\//    contains=@factorCommentContents keepend
 
-syn cluster factorReal                  contains=factorInt,factorFloat,factorPosRatio,factorNegRatio,@factorBin,@factorHex,@factorOct,factorNan
+syn cluster factorReal                  contains=@factorInteger,@factorFloat,@factorRatio,@factorBin,@factorOct,@factorHex,factorNan
 syn cluster factorNumber                contains=@factorReal,factorComplex
 syn cluster factorNumber                contains=@factorReal,factorComplex
-syn match   factorInt                   /\v<[+-]=[0-9]%([0-9,]*[0-9])?%([eE]%([+-])?[0-9]+)?>/
-syn match   factorFloat                 /\v<[+-]=[0-9]%([0-9,]*[0-9])?%(\.%(%([0-9,]*[0-9]+)?%([eE]%([+-])?[0-9]%([0-9,]*[0-9])?)?)?)?>/
-syn match   factorPosRatio              /\v<\+=[0-9]%([0-9,]*[0-9])?%(\+[0-9]%([0-9,]*[0-9]+)?)?\/-=[0-9]%([0-9,]*[0-9]+)?\.?>/
-syn match   factorNegRatio              /\v<\-[0-9]%([0-9,]*[0-9])?%(\-[0-9]%([0-9,]*[0-9]+)?)?\/-=[0-9]%([0-9,]*[0-9]+)?\.?>/
+syn cluster factorInteger               contains=factorInteger
+if !exists('g:factor_syn_no_error') " more general
+  syn cluster factorInteger             add=factorIntegerError
+  " + "\d|," with contained "\d"
+  syn match   factorIntegerError        /\v<[+-]=%(\d|,){-}\d%(\d|,)*>/
+endif
+" + "\d|," with leading "\d" and no trailing ","
+syn match   factorInteger               /\v<[+-]=\d%(\d|,)*,@1<!>/
+if !exists('g:factor_syn_no_error') " more general
+  syn cluster factorFloat               add=factorFloatError
+  syn match   factorFloatError          /\v<[+-]=%(\S{-}\d&%(\d|,)*%([eE][+-]=%(\d|,)*|\.%(\d|,)*%([eE][+-]=%(\d|,)*)?)|\.%(\d|,)+%([eE][+-]=%(\d|,)*)?)>/
+endif
+syn cluster factorFloat                 contains=factorFloat
+" exponent is followed by valid integer of radix 10
+" float of
+"   {valid integer,
+"     {"[eE]" exponent}
+"     or {"." mantissa sep, ? "[eE]" exponent}}
+"   or {"." mantissa sep, ? "[eE]" exponent}
+syn match   factorFloat                 /\v<[+-]=%(\d%(\d|,)*,@1<!%([eE][+-]=\d%(\d|,)*,@1<!|\.%(\d%(\d|,)*,@1<!)?%([eE][+-]=\d%(\d|,)*,@1<!)?)|\.\d%(\d|,)*,@1<!%([eE][+-]=\d%(\d|,)*,@1<!)?)>/
+syn cluster factorRatio                 contains=factorRatio
+if !exists('g:factor_syn_no_error') " more general
+  syn cluster factorRatio               add=factorRatioError
+  syn match   factorRatioError          /\v<[+-]=%(\S{-}\d.{-}\/&%(\d|,)*\.?%(\d|,)*%([+-]%(\d|,)*)?)\/[+-]=%(\S{-}\d&%(\d|,)*\.?%(\d|,)*%([eE][+-]=%(\d|,)*)?)>/
+endif
+syn match   factorRatio                 /\v<([+-]=)\d%(\d|,)*,@1<!%(\1@=[+-](\d%(\d|,)*,@1<!)\/\2@!\d%(\d|,)*,@1<!|\/%(\d%(\d|,)*,@1<!%(\.%(\d%(\d|,)*,@1<!)?)?|\.\d%(\d|,)*,@1<!)%([eE][+-]=\d%(\d|,)*,@1<!)?)%(\/0)@2<!>/
 syn region  factorComplex         start=/\v<C\{>/   end=/\v<\}>/    contains=@factorReal
 syn cluster factorBin                   contains=factorBin
 syn region  factorComplex         start=/\v<C\{>/   end=/\v<\}>/    contains=@factorReal
 syn cluster factorBin                   contains=factorBin
-syn match   factorBin                   /\v<[+-]=0b[01,]+>/
 if !exists('g:factor_syn_no_error')
 if !exists('g:factor_syn_no_error')
-  syn match   factorBinError            /\v<[+-]=0b[01,]*[^01 ]\S*>/
   syn cluster factorBin                 add=factorBinError
   syn cluster factorBin                 add=factorBinError
+  syn match   factorBinError            /\v<[+-]=0[bB]%(\S{-}\w&%(\w|,)*\.?%(\w|,)*%([pP][+-]=%(\w|,)*)?)>/
 endif
 endif
-syn cluster factorHexNoRadixTrans       contains=factorHexNoRadixTrans
-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
-syn cluster factorHex                   contains=factorHex
-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])?)?>/
-if !exists('g:factor_syn_no_error')
-  syn match   factorHexNoRadixError     /\v<%(,\S*|\S*,|[-0-9a-fA-Fp,]*[^-0-9a-fA-Fp, ]\S*)>/ contained
-  syn cluster factorHexNoRadixTrans     add=factorHexNoRadixError
-  syn match   factorHexError            /\v<[+-]=0x%(,\S*|\S*,|[-0-9a-fA-Fp,]*[^-0-9a-fA-Fp, ]\S*)>/
-  syn cluster factorHex                 add=factorHexError
-endif
+" basically a float, but with a radix and no integer case to not match
+syn match   factorBin                   /\v<[+-]=0[bB]%([01][01,]*,@1<!%(\.%([01][01,]*,@1<!)?)?|\.[01][01,]*,@1<!)%([pP][+-]=\d%(\d|,)*,@1<!)?>/
 syn cluster factorOct                   contains=factorOct
 syn cluster factorOct                   contains=factorOct
-syn match   factorOct                   /\v<[+-]=0o[0-7,]+>/
 if !exists('g:factor_syn_no_error')
 if !exists('g:factor_syn_no_error')
-  syn match   factorOctError             /\v<[+-]=0o%(,\S*|\S*,|[0-7,]*[^0-7, ]\S*)>/
   syn cluster factorOct                 add=factorOctError
   syn cluster factorOct                 add=factorOctError
+  syn match   factorOctError            /\v<[+-]=0[oO]%(\S{-}\o&%(\w|,)*\.?(\w|,)*%([pP][+-]=%(\w|,)*)?)>/
+endif
+syn match   factorOct                   /\v<[+-]=0[oO]%(\o%(\o|,)*,@1<!%(\.%(\o%(\o|,)*,@1<!)?)?|\.\o%(\o|,)*,@1<!)%([pP][+-]=\d%(\d|,)*,@1<!)?>/
+syn cluster factorHexNoRadix            contains=factorHexNoRadix
+syn cluster factorHex                   contains=factorHex
+if !exists('g:factor_syn_no_error')
+  syn cluster factorHexNoRadix          add=factorHexNoRadixError
+  syn cluster factorHex                 add=factorHexError
+  syn match   factorHexNoRadixError     /\v<[+-]=%(\S{-}\x&%(\w|,)*\.?(\w|,)*%([pP][+-]=%(\w|,)*)?)>/   contained
+  syn match   factorHexError            /\v<[+-]=0[xX]%(\S{-}\x&%(\x|,)*\.?(\x|,)*%([pP][+-]=%(\w|,)*)?)>/
 endif
 endif
-syn match   factorOct                   /\v<[+-]=0o[0-7,]+>/
-syn region  factorNan matchgroup=factorNan start=/\v<NAN:>/ matchgroup=NONE end=/\v<\S+>/ contains=@factorComment contains=@factorHexNoRadixTrans
+syn match   factorHexNoRadix            /\v<[+-]=%(\x%(\x|,)*,@1<!%(\.%(\x%(\x|,)*,@1<!)?)?|\.\x%(\x|,)*,@1<!)%([pP][+-]=\d%(\d|,)*,@1<!)?>/  contained
+syn match   factorHex                   /\v<[+-]=0[xX]%(\x%(\x|,)*,@1<!%(\.%(\x%(\x|,)*,@1<!)?)?|\.\x%(\x|,)*,@1<!)%([pP][+-]=\d%(\d|,)*,@1<!)?>/
+syn region  factorNan matchgroup=factorNan    start=/\v<NAN:>/ matchgroup=NONE skip=/\v<!>.*/   end=/\v<\S+>/   contains=@factorComment,@factorHexNoRadix keepend
 
 
-syn region  factorBackslash       start=/\v<\\>/   skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
-syn region  factorMBackslash      start=/\v<M\\>/  skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment
-syn region  factorLiteral         start=/\v<\$>/   skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
-syn region  factorLiteralBlock    start=/\v<\$\[>/              end=/\v<\]>/    contains=@factorComment
+syn region  factorBackslash       start=/\v<\\>/                    end=/\v<\S+>/   contains=@factorComment
+syn region  factorMBackslash      start=/\v<M\\>/  skip=/\v<!>.*/   end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment keepend
+syn region  factorLiteral         start=/\v<\$>/                    end=/\v<\S+>/   contains=@factorComment
+syn region  factorLiteralBlock    start=/\v<\$\[>/                  end=/\v<\]>/    contains=@factorComment
 
 
-syn region  factorIn      start=/\v<IN:>/      skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
-syn region  factorUse     start=/\v<USE:>/     skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
-syn region  factorUnuse   start=/\v<UNUSE:>/   skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
+syn region  factorIn      start=/\v<IN:>/       end=/\v<\S+>/   contains=@factorComment
+syn region  factorUse     start=/\v<USE:>/      end=/\v<\S+>/   contains=@factorComment
+syn region  factorUnuse   start=/\v<UNUSE:>/    end=/\v<\S+>/   contains=@factorComment
 
 syn region  factorUsing           start=/\v<USING:>/                        end=/\v<;>/     contains=@factorComment
 
 syn region  factorUsing           start=/\v<USING:>/                        end=/\v<;>/     contains=@factorComment
-syn region  factorQualified       start=/\v<QUALIFIED:>/       skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
-syn region  factorQualifiedWith   start=/\v<QUALIFIED-WITH:>/  skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment
+syn region  factorQualified       start=/\v<QUALIFIED:>/                    end=/\v<\S+>/   contains=@factorComment
+syn region  factorQualifiedWith   start=/\v<QUALIFIED-WITH:>/  skip=/\v<!>.*/   end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment keepend
 syn region  factorExclude         start=/\v<EXCLUDE:>/                      end=/\v<;>/     contains=@factorComment
 syn region  factorFrom            start=/\v<FROM:>/                         end=/\v<;>/     contains=@factorComment
 syn region  factorExclude         start=/\v<EXCLUDE:>/                      end=/\v<;>/     contains=@factorComment
 syn region  factorFrom            start=/\v<FROM:>/                         end=/\v<;>/     contains=@factorComment
-syn region  factorRename          start=/\v<RENAME:>/          skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+%(\_\s+%(!>.*)?)+\=\>%(\_\s+%(!>.*)?)+\S+>/  contains=@factorComment
+syn region  factorRename          start=/\v<RENAME:>/      skip=/\v<!>.*/   end=/\v<\S+%(\_\s+%(!>.*)?)+\S+%(\_\s+%(!>.*)?)+\=\>%(\_\s+%(!>.*)?)+\S+>/  contains=@factorComment keepend
 syn region  factorSingletons      start=/\v<SINGLETONS:>/                   end=/\v<;>/     contains=@factorComment
 syn region  factorSingletons      start=/\v<SINGLETONS:>/                   end=/\v<;>/     contains=@factorComment
-syn region  factorSymbol          start=/\v<SYMBOL:>/          skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
+syn region  factorSymbol          start=/\v<SYMBOL:>/                       end=/\v<\S+>/   contains=@factorComment
 syn region  factorSymbols         start=/\v<SYMBOLS:>/                      end=/\v<;>/     contains=@factorComment
 syn region  factorSymbols         start=/\v<SYMBOLS:>/                      end=/\v<;>/     contains=@factorComment
-syn region  factorConstructor2    start=/\v<CONSTRUCTOR:?/                  end=/\v<;>/     contains=@factorComment
+syn region  factorConstructor2    start=/\v<CONSTRUCTOR:>/                  end=/\v<;>/     contains=@factorComment
 syn region  factorIntersection    start=/\v<INTERSECTION:>/                 end=/\v<;>/     contains=@factorComment
 syn region  factorIntersection    start=/\v<INTERSECTION:>/                 end=/\v<;>/     contains=@factorComment
-syn cluster factorSlotAttr              contains=factorSlotAttrInitial contains=factorSlotAttrReadOnly
+syn cluster factorSlotAttr              contains=factorSlotAttrInitial,factorSlotAttrReadOnly
 syn cluster factorTupleSlotAttr         contains=@factorSlotAttr
 syn cluster factorTupleSlotAttr         contains=@factorSlotAttr
-syn match   factorTupleSlotName         /\v<\S+>/ nextgroup=factorTupleSlotClassSkip contained
-syn match   factorTupleSlotNameSkip     /\v%(\_\s+%(!>.*)?)*/ nextgroup=factorTupleSlotName transparent contained
-syn match   factorTupleSlotClass        /\v<\S+>/ contained
+syn match   factorTupleSlotName         /\v<\S+>/ nextgroup=factorTupleSlotClassSkip skipempty contained
+syn match   factorTupleSlotNameSkip     /\v%(\_\s+%(!>.*)?)*/ contains=@factorComment nextgroup=factorTupleSlotName transparent contained
+syn match   factorTupleSlotClass        /\v<\S+>/ nextgroup=factorTupleSlotAttrSkip skipempty contained
 " a class is optional, so let an attribute take priority if present
 " a class is optional, so let an attribute take priority if present
-syn match   factorTupleSlotClassSkip    /\v%(\_\s+%(!>.*)?)*/ nextgroup=factorTupleSlotClass,@factorTupleSlotAttr transparent contained
-syn region  factorTupleSlot matchgroup=factorTupleSlotDelims  start=/\v<\{>/                end=/\v<\}>/   contains=@factorComment,factorTupleSlotName,@factorTupleSlotAttr contained
-syn region  factorTuple matchgroup=factorTupleDelims          start=/\v<%(TUPLE|BUILTIN):>/ end=/\v<;>/ contains=@factorComment,factorTupleSlotName,factorTupleSlot
+syn match   factorTupleSlotClassSkip    /\v%(\_\s+%(!>.*)?)*/ contains=@factorComment nextgroup=factorTupleSlotClass,@factorTupleSlotAttr transparent contained
+syn region  factorTupleSlot matchgroup=factorTupleSlotDelims  start=/\v<\{>/                end=/\v<\}>/    contains=@factorComment,factorTupleSlotName,@factorTupleSlotAttr contained
+syn region  factorTuple matchgroup=factorTupleDelims          start=/\v<%(TUPLE|BUILTIN):>/ end=/\v<;>/     contains=@factorComment,factorTupleSlotName,factorTupleSlot
 " Abnormally named because factor*Error is reserved for syntax errors.
 syn region  factorErrorSyn        start=/\v<ERROR:>/            end=/\v<;>/     contains=@factorComment
 syn region  factorUnion           start=/\v<UNION:>/            end=/\v<;>/     contains=@factorComment
 syn cluster factorStructSlotAttr        contains=@factorSlotAttr,factorStructSlotAttrBits
 " Abnormally named because factor*Error is reserved for syntax errors.
 syn region  factorErrorSyn        start=/\v<ERROR:>/            end=/\v<;>/     contains=@factorComment
 syn region  factorUnion           start=/\v<UNION:>/            end=/\v<;>/     contains=@factorComment
 syn cluster factorStructSlotAttr        contains=@factorSlotAttr,factorStructSlotAttrBits
-syn match   factorStructSlotName        /\v<\S+>/ nextgroup=factorStructSlotTypeSkip contained
-syn match   factorStructSlotNameSkip    /\v%(\_\s+%(!>.*)?)*/ nextgroup=factorStructSlotName contained transparent
+syn match   factorStructSlotName        /\v<\S+>/ nextgroup=factorStructSlotTypeSkip skipempty contained
+syn match   factorStructSlotNameSkip    /\v%(\_\s+%(!>.*)?)*/ contains=@factorComment nextgroup=factorStructSlotName contained transparent
 syn match   factorStructSlotType        /\v<\S+>/ contained
 syn match   factorStructSlotType        /\v<\S+>/ contained
-syn match   factorStructSlotTypeSkip    /\v%(\_\s+%(!>.*)?)*/ nextgroup=factorStructSlotType contained transparent
+syn match   factorStructSlotTypeSkip    /\v%(\_\s+%(!>.*)?)*/ contains=@factorComment nextgroup=factorStructSlotType contained transparent
 syn region  factorStructSlot matchgroup=factorStructSlotDelims    start=/\v<\{>/     end=/\v<\}>/ contains=@factorComment,factorStructSlotName,@factorStructSlotAttr contained
 syn region  factorStruct matchgroup=factorStructDelims            start=/\v<%(UNION-STRUCT|STRUCT):>/   end=/\v<;>/ contains=@factorComment,factorStructSlot
 
 syn region  factorStructSlot matchgroup=factorStructSlotDelims    start=/\v<\{>/     end=/\v<\}>/ contains=@factorComment,factorStructSlotName,@factorStructSlotAttr contained
 syn region  factorStruct matchgroup=factorStructDelims            start=/\v<%(UNION-STRUCT|STRUCT):>/   end=/\v<;>/ contains=@factorComment,factorStructSlot
 
@@ -238,19 +271,19 @@ syn match   factorSlotAttrReadOnly      /\v<read-only>/ contained
 syn match   factorSlotAttrInitial       /\v<initial:>%(\_\s+%(!>.*)?)+/ contains=@factorComment nextgroup=factorWord,@factorClusterValue contained
 syn match   factorStructSlotAttrBits    /\v<bits:>%(\_\s+%(!>.*)?)+/    contains=@factorComment nextgroup=factorWord,@factorReal contained
 
 syn match   factorSlotAttrInitial       /\v<initial:>%(\_\s+%(!>.*)?)+/ contains=@factorComment nextgroup=factorWord,@factorClusterValue contained
 syn match   factorStructSlotAttrBits    /\v<bits:>%(\_\s+%(!>.*)?)+/    contains=@factorComment nextgroup=factorWord,@factorReal contained
 
-syn region  factorConstant        start=/\v<CONSTANT:>/    skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
-syn region  factorAlias           start=/\v<ALIAS:>/       skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment
-syn region  factorSingleton       start=/\v<SINGLETON:>/   skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
-syn region  factorPostpone        start=/\v<POSTPONE:>/    skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
-syn region  factorDefer           start=/\v<DEFER:>/       skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
-syn region  factorForget          start=/\v<FORGET:>/      skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
-syn region  factorMixin           start=/\v<MIXIN:>/       skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
-syn region  factorInstance        start=/\v<INSTANCE:>/    skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment
-syn region  factorHook            start=/\v<HOOK:>/        skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment nextgroup=factorStackEffect
-syn region  factorMain            start=/\v<MAIN:>/        skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
-syn region  factorConstructor     start=/\v<C:>/           skip=/\v<!>/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment
-syn region  factorAlien matchgroup=factorAlien start=/\v<ALIEN:>/ matchgroup=NONE  skip=/\v<!>/ end=/\v<\S+>/  contains=@factorComment,@factorHexNoRadixTrans 
-syn region  factorSlot            start=/\v<SLOT:>/        skip=/\v<!>/ end=/\v<\S+>/   contains=@factorComment
+syn region  factorConstant        start=/\v<CONSTANT:>/                 end=/\v<\S+>/   contains=@factorComment
+syn region  factorAlias           start=/\v<ALIAS:>/     skip=/\v<!>.*/ end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment keepend
+syn region  factorSingleton       start=/\v<SINGLETON:>/                end=/\v<\S+>/   contains=@factorComment
+syn region  factorPostpone        start=/\v<POSTPONE:>/                 end=/\v<\S+>/   contains=@factorComment
+syn region  factorDefer           start=/\v<DEFER:>/                    end=/\v<\S+>/   contains=@factorComment
+syn region  factorForget          start=/\v<FORGET:>/                   end=/\v<\S+>/   contains=@factorComment
+syn region  factorMixin           start=/\v<MIXIN:>/                    end=/\v<\S+>/   contains=@factorComment
+syn region  factorInstance        start=/\v<INSTANCE:>/    skip=/\v<!>.*/   end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment keepend
+syn region  factorHook            start=/\v<HOOK:>/    skip=/\v<!>.*/   end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment nextgroup=factorStackEffectSkip skipempty keepend
+syn region  factorMain            start=/\v<MAIN:>/                     end=/\v<\S+>/   contains=@factorComment
+syn region  factorConstructor     start=/\v<C:>/       skip=/\v<!>.*/   end=/\v<\S+%(\_\s+%(!>.*)?)+\S+>/   contains=@factorComment keepend
+syn region  factorAlien matchgroup=factorAlien start=/\v<ALIEN:>/ matchgroup=NONE   end=/\v<\S+>/  contains=@factorComment,@factorHexNoRadix
+syn region  factorSlot            start=/\v<SLOT:>/                     end=/\v<\S+>/   contains=@factorComment
 
 syn cluster factorWordOps   contains=factorConstant,factorAlias,factorSingleton,factorSingletons,factorSymbol,factorSymbols,factorPostpone,factorDefer,factorForget,factorMixin,factorInstance,factorHook,factorMain,factorConstructor
 
 
 syn cluster factorWordOps   contains=factorConstant,factorAlias,factorSingleton,factorSingletons,factorSymbol,factorSymbols,factorPostpone,factorDefer,factorForget,factorMixin,factorInstance,factorHook,factorMain,factorConstructor
 
@@ -268,11 +301,15 @@ syn cluster factorWordOps   contains=factorConstant,factorAlias,factorSingleton,
 " LIBRARY:
 "#\ "
 
 " LIBRARY:
 "#\ "
 
+if !exists('g:factor_syn_no_error')
+  syn match   factorStackEffectRequired /\v<\V(\@!\v\S+>/    contained
+endif
 syn cluster factorStackEffectContents   contains=@factorComment,factorStackEffectDelims,factorStackEffectVar,factorStackEffectType,factorStackEffectRowVar
 syn cluster factorStackEffect           contains=factorStackEffect
 " Erroring on stack effects without a "--" separator would be nice.
 " Unfortunately, that sort of vacuous detection is above Vim's pay-grade,
 "   especially when stack effects can be nested arbitrarily via types.
 syn cluster factorStackEffectContents   contains=@factorComment,factorStackEffectDelims,factorStackEffectVar,factorStackEffectType,factorStackEffectRowVar
 syn cluster factorStackEffect           contains=factorStackEffect
 " Erroring on stack effects without a "--" separator would be nice.
 " Unfortunately, that sort of vacuous detection is above Vim's pay-grade,
 "   especially when stack effects can be nested arbitrarily via types.
+syn match   factorStackEffectSkip       /\v%(\_\s+%(!>.*)?)*/ contains=@factorComment nextgroup=factorStackEffectRequired,@factorStackEffect transparent contained
 syn region  factorStackEffect       matchgroup=factorStackEffectDelims    start=/\v\V(\v>/  end=/\v<\V)\v>/ contains=@factorStackEffectContents
 syn match   factorStackEffectVar        /\v<\S+>/           contained
 " Note that ":!" parses to the "!" word and doesn't lex as a comment.
 syn region  factorStackEffect       matchgroup=factorStackEffectDelims    start=/\v\V(\v>/  end=/\v<\V)\v>/ contains=@factorStackEffectContents
 syn match   factorStackEffectVar        /\v<\S+>/           contained
 " Note that ":!" parses to the "!" word and doesn't lex as a comment.
@@ -280,11 +317,12 @@ syn match   factorStackEffectVar        /\v<\S+>/           contained
 "   boundary means a lot of our nicer syntax patterns don't match on
 "   "factorStackEffectType".
 " syn cluster factorStackEffectType contains=factorWord,@factorStackEffect
 "   boundary means a lot of our nicer syntax patterns don't match on
 "   "factorStackEffectType".
 " syn cluster factorStackEffectType contains=factorWord,@factorStackEffect
-syn cluster factorStackEffectType       contains=@factorClusterValue
-syn region  factorStackEffectVar    matchgroup=factorStackEffectVar       start=/\v<\S+:>/       matchgroup=NONE end=/\v%(\_\s+%(!>.*)?)+/ contains=@factorComment nextgroup=@factorStackEffectType transparent contained
-syn match   factorStackEffectType       /\v<:/              contained nextgroup=@factorStackEffectType
+syn cluster factorStackEffectType       contains=factorWord,@factorClusterValue
+syn match   factorStackEffectTypeSkip   /\v%(\_\s+%(!>.*)?)*/ contains=@factorComment nextgroup=@factorStackEffectType transparent contained
+syn match   factorStackEffectVar        /\v<\S+:>/          nextgroup=factorStackEffectTypeSkip skipempty contained
+syn match   factorStackEffectType       /\v<:/              nextgroup=@factorStackEffectType contained
 syn match   factorStackEffectRowVar     /\v<\.\.\S+>/       contained
 syn match   factorStackEffectRowVar     /\v<\.\.\S+>/       contained
-syn region  factorStackEffectRowVar matchgroup=factorStackEffectRowVar    start=/\v<\.\.\S+:>/   matchgroup=NONE end=/\v%(\_\s+%(!>.*)?)+/ contains=@factorComment nextgroup=@factorStackEffectType transparent contained
+syn match   factorStackEffectRowVar     /\v<\.\.\S+:>/      nextgroup=factorStackEffectTypeSkip skipempty contained
 syn match   factorStackEffectDelims     /\v<-->/            contained
 if !exists('g:factor_syn_no_error')
   syn cluster factorStackEffectContents add=factorStackEffectError
 syn match   factorStackEffectDelims     /\v<-->/            contained
 if !exists('g:factor_syn_no_error')
   syn cluster factorStackEffectContents add=factorStackEffectError
@@ -311,19 +349,19 @@ endif
 
 if exists('g:factor_syn_no_rainbow')
   syn cluster factorArray       contains=factorArray
 
 if exists('g:factor_syn_no_rainbow')
   syn cluster factorArray       contains=factorArray
-  syn region  factorArray          matchgroup=factorDelimiter start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/        end=/\v<\}>/    contains=ALL
+  syn region  factorArray          matchgroup=factorDelimiter start=/\v<%(\$|[-[:alnum:]]+)?\{>/        end=/\v<\}>/    contains=ALL
 else
   syn cluster factorArray       contains=factorArray0
 else
   syn cluster factorArray       contains=factorArray0
-  syn region  factorArray0               matchgroup=hlLevel0 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray1,factorQuotation1
-  syn region  factorArray1     contained matchgroup=hlLevel1 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray2,factorQuotation2
-  syn region  factorArray2     contained matchgroup=hlLevel2 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray3,factorQuotation3
-  syn region  factorArray3     contained matchgroup=hlLevel3 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray4,factorQuotation4
-  syn region  factorArray4     contained matchgroup=hlLevel4 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray5,factorQuotation5
-  syn region  factorArray5     contained matchgroup=hlLevel5 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray6,factorQuotation6
-  syn region  factorArray6     contained matchgroup=hlLevel6 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray7,factorQuotation7
-  syn region  factorArray7     contained matchgroup=hlLevel7 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray8,factorQuotation8
-  syn region  factorArray8     contained matchgroup=hlLevel8 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray9,factorQuotation9
-  syn region  factorArray9     contained matchgroup=hlLevel9 start=/\v<%(\$|[-a-zA-Z0-9]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray0,factorQuotation0
+  syn region  factorArray0               matchgroup=hlLevel0 start=/\v<%(\$|[-[:alnum:]]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray1,factorQuotation1
+  syn region  factorArray1     contained matchgroup=hlLevel1 start=/\v<%(\$|[-[:alnum:]]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray2,factorQuotation2
+  syn region  factorArray2     contained matchgroup=hlLevel2 start=/\v<%(\$|[-[:alnum:]]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray3,factorQuotation3
+  syn region  factorArray3     contained matchgroup=hlLevel3 start=/\v<%(\$|[-[:alnum:]]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray4,factorQuotation4
+  syn region  factorArray4     contained matchgroup=hlLevel4 start=/\v<%(\$|[-[:alnum:]]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray5,factorQuotation5
+  syn region  factorArray5     contained matchgroup=hlLevel5 start=/\v<%(\$|[-[:alnum:]]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray6,factorQuotation6
+  syn region  factorArray6     contained matchgroup=hlLevel6 start=/\v<%(\$|[-[:alnum:]]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray7,factorQuotation7
+  syn region  factorArray7     contained matchgroup=hlLevel7 start=/\v<%(\$|[-[:alnum:]]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray8,factorQuotation8
+  syn region  factorArray8     contained matchgroup=hlLevel8 start=/\v<%(\$|[-[:alnum:]]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray9,factorQuotation9
+  syn region  factorArray9     contained matchgroup=hlLevel9 start=/\v<%(\$|[-[:alnum:]]+)?\{>/         end=/\v<\}>/    contains=@factorCluster,factorArray0,factorQuotation0
 endif
 
 if !exists('g:factor_syn_no_error')
 endif
 
 if !exists('g:factor_syn_no_error')
@@ -332,7 +370,7 @@ if !exists('g:factor_syn_no_error')
 endif
 
 function! FactorSynDefineComment() abort
 endif
 
 function! FactorSynDefineComment() abort
-  syn region  factorComment   start=/\v<!>/ end=/\v$/   keepend oneline contains=@factorCommentContents
+  syn match   factorComment         /\v<!>.*$/ contains=@factorCommentContents
   syn match   factorShebang         /\v%^\#!.*$/ display
   if !exists('g:factor_syn_no_error')
     syn match   factorShebangError  /\v%^\#!\S+/
   syn match   factorShebang         /\v%^\#!.*$/ display
   if !exists('g:factor_syn_no_error')
     syn match   factorShebangError  /\v%^\#!\S+/
@@ -359,16 +397,22 @@ if !exists('g:factor_syn_no_init')
   if !exists('g:factor_syn_no_error')
     HiLink factorShebangError           Error
     HiLink factorBracketError           Error
   if !exists('g:factor_syn_no_error')
     HiLink factorShebangError           Error
     HiLink factorBracketError           Error
+    HiLink factorIntegerError           Error
+    HiLink factorFloatError             Error
+    HiLink factorRatioError             Error
     HiLink factorBinError               Error
     HiLink factorHexNoRadixError        Error
     HiLink factorHexError               Error
     HiLink factorOctError               Error
     HiLink factorBinError               Error
     HiLink factorHexNoRadixError        Error
     HiLink factorHexError               Error
     HiLink factorOctError               Error
+    HiLink factorStackEffectRequired    Error
     HiLink factorStackEffectError       Error
   endif
 
   HiLink   factorComment                Comment
   HiLink   factorMultilineComment       factorComment
     HiLink factorStackEffectError       Error
   endif
 
   HiLink   factorComment                Comment
   HiLink   factorMultilineComment       factorComment
+  HiLink   factorMultilineCommentDelims factorMultilineComment
   HiLink   factorMultilineCComment      factorComment
   HiLink   factorMultilineCComment      factorComment
+  HiLink   factorMultilineCCommentDelims factorMultilineCComment
   HiLink   factorShebang                PreProc
   HiLink   factorStackEffect            Type
   HiLink   factorStackEffectDelims      Delimiter
   HiLink   factorShebang                PreProc
   HiLink   factorStackEffect            Type
   HiLink   factorStackEffectDelims      Delimiter
@@ -387,6 +431,7 @@ if !exists('g:factor_syn_no_init')
   HiLink   factorBreakpoint             Debug
   HiLink   factorDefnDelims             Typedef
   HiLink   factorMethodDelims           Typedef
   HiLink   factorBreakpoint             Debug
   HiLink   factorDefnDelims             Typedef
   HiLink   factorMethodDelims           Typedef
+  HiLink   factorLocalsMethodDelims     Typedef
   HiLink   factorGeneric                Typedef
   HiLink   factorGenericN               Typedef
   HiLink   factorConstructor            Typedef
   HiLink   factorGeneric                Typedef
   HiLink   factorGenericN               Typedef
   HiLink   factorConstructor            Typedef
@@ -394,6 +439,7 @@ if !exists('g:factor_syn_no_init')
   HiLink   factorPrivate                Special
   HiLink   factorPDefnDelims            Special
   HiLink   factorPMethodDelims          Special
   HiLink   factorPrivate                Special
   HiLink   factorPDefnDelims            Special
   HiLink   factorPMethodDelims          Special
+  HiLink   factorPLocalsMethodDelims    Special
   HiLink   factorPGeneric               Special
   HiLink   factorPGenericN              Special
   HiLink   factorEscape                 SpecialChar
   HiLink   factorPGeneric               Special
   HiLink   factorPGenericN              Special
   HiLink   factorEscape                 SpecialChar
@@ -405,19 +451,21 @@ if !exists('g:factor_syn_no_init')
   HiLink   factorPrefixedStringDelims   factorPrefixedString
   HiLink   factorMultilineString        factorString
   HiLink   factorMultilineStringDelims  Typedef
   HiLink   factorPrefixedStringDelims   factorPrefixedString
   HiLink   factorMultilineString        factorString
   HiLink   factorMultilineStringDelims  Typedef
+  HiLink   factorHereDoc                factorMultilineString
+  HiLink   factorHereDocDelims          factorMultilineStringDelims
   HiLink   factorHereDocString          factorMultilineString
   HiLink   factorHereDocStringDelims    factorMultilineStringDelims
   HiLink   factorPrefixedMultilineString factorString
   HiLink   factorPrefixedMultilineStringDelims factorMultilineStringDelims
   HiLink   factorComplex                Number
   HiLink   factorHereDocString          factorMultilineString
   HiLink   factorHereDocStringDelims    factorMultilineStringDelims
   HiLink   factorPrefixedMultilineString factorString
   HiLink   factorPrefixedMultilineStringDelims factorMultilineStringDelims
   HiLink   factorComplex                Number
-  HiLink   factorPosRatio               Number
-  HiLink   factorNegRatio               Number
+  HiLink   factorRatio                  Number
   HiLink   factorBin                    Number
   HiLink   factorBin                    Number
+  HiLink   factorHexNoRadix             Number
   HiLink   factorHex                    Number
   HiLink   factorNan                    Number
   HiLink   factorOct                    Number
   HiLink   factorFloat                  Float
   HiLink   factorHex                    Number
   HiLink   factorNan                    Number
   HiLink   factorOct                    Number
   HiLink   factorFloat                  Float
-  HiLink   factorInt                    Number
+  HiLink   factorInteger                Number
   HiLink   factorUsing                  Include
   HiLink   factorQualified              Include
   HiLink   factorQualifiedWith          Include
   HiLink   factorUsing                  Include
   HiLink   factorQualified              Include
   HiLink   factorQualifiedWith          Include