summaryrefslogtreecommitdiffstats
path: root/public/prism/prism-factor.js
diff options
context:
space:
mode:
authorArmand Philippot <git@armandphilippot.com>2021-12-30 19:47:21 +0100
committerArmand Philippot <git@armandphilippot.com>2021-12-30 19:47:21 +0100
commita98b5ea6fe8e8cc98a55e0fd793e6e8660ea31c1 (patch)
tree542810ab5aef99150db228bb54fd58303dcb31c7 /public/prism/prism-factor.js
parentab355897a12b7bda1089a44de326d41455a0f7a3 (diff)
chore: add prismjs for syntax highlighting
Diffstat (limited to 'public/prism/prism-factor.js')
-rw-r--r--public/prism/prism-factor.js963
1 files changed, 963 insertions, 0 deletions
diff --git a/public/prism/prism-factor.js b/public/prism/prism-factor.js
new file mode 100644
index 0000000..fdbe1cc
--- /dev/null
+++ b/public/prism/prism-factor.js
@@ -0,0 +1,963 @@
+(function (Prism) {
+ var comment_inside = {
+ function:
+ /\b(?:BUGS?|FIX(?:MES?)?|NOTES?|TODOS?|XX+|HACKS?|WARN(?:ING)?|\?{2,}|!{2,})\b/,
+ };
+ var string_inside = {
+ number: /\\[^\s']|%\w/,
+ };
+
+ var factor = {
+ comment: [
+ {
+ // ! single-line exclamation point comments with whitespace after/around the !
+ pattern: /(^|\s)(?:! .*|!$)/,
+ lookbehind: true,
+ inside: comment_inside,
+ },
+
+ /* from basis/multiline: */
+ {
+ // /* comment */, /* comment*/
+ pattern: /(^|\s)\/\*\s[\s\S]*?\*\/(?=\s|$)/,
+ lookbehind: true,
+ greedy: true,
+ inside: comment_inside,
+ },
+ {
+ // ![[ comment ]] , ![===[ comment]===]
+ pattern: /(^|\s)!\[(={0,6})\[\s[\s\S]*?\]\2\](?=\s|$)/,
+ lookbehind: true,
+ greedy: true,
+ inside: comment_inside,
+ },
+ ],
+
+ number: [
+ {
+ // basic base 10 integers 9, -9
+ pattern: /(^|\s)[+-]?\d+(?=\s|$)/,
+ lookbehind: true,
+ },
+ {
+ // base prefix integers 0b010 0o70 0xad 0d10 0XAD -0xa9
+ pattern: /(^|\s)[+-]?0(?:b[01]+|o[0-7]+|d\d+|x[\dA-F]+)(?=\s|$)/i,
+ lookbehind: true,
+ },
+ {
+ // fractional ratios 1/5 -1/5 and the literal float approximations 1/5. -1/5.
+ pattern: /(^|\s)[+-]?\d+\/\d+\.?(?=\s|$)/,
+ lookbehind: true,
+ },
+ {
+ // positive mixed numbers 23+1/5 +23+1/5
+ pattern: /(^|\s)\+?\d+\+\d+\/\d+(?=\s|$)/,
+ lookbehind: true,
+ },
+ {
+ // negative mixed numbers -23-1/5
+ pattern: /(^|\s)-\d+-\d+\/\d+(?=\s|$)/,
+ lookbehind: true,
+ },
+ {
+ // basic decimal floats -0.01 0. .0 .1 -.1 -1. -12.13 +12.13
+ // and scientific notation with base 10 exponents 3e4 3e-4 .3e-4
+ pattern: /(^|\s)[+-]?(?:\d*\.\d+|\d+\.\d*|\d+)(?:e[+-]?\d+)?(?=\s|$)/i,
+ lookbehind: true,
+ },
+ {
+ // NAN literal syntax NAN: 80000deadbeef, NAN: a
+ pattern: /(^|\s)NAN:\s+[\da-fA-F]+(?=\s|$)/,
+ lookbehind: true,
+ },
+ {
+ /*
+ base prefix floats 0x1.0p3 (8.0) 0b1.010p2 (5.0) 0x1.p1 0b1.11111111p11111...
+ "The normalized hex form ±0x1.MMMMMMMMMMMMM[pP]±EEEE allows any floating-point number to be specified precisely.
+ The values of MMMMMMMMMMMMM and EEEE map directly to the mantissa and exponent fields of the binary IEEE 754 representation."
+ <https://docs.factorcode.org/content/article-syntax-floats.html>
+ */
+ pattern:
+ /(^|\s)[+-]?0(?:b1\.[01]*|o1\.[0-7]*|d1\.\d*|x1\.[\dA-F]*)p\d+(?=\s|$)/i,
+ lookbehind: true,
+ },
+ ],
+
+ // R/ regexp?\/\\/
+ regexp: {
+ pattern:
+ /(^|\s)R\/\s(?:\\\S|[^\\/])*\/(?:[idmsr]*|[idmsr]+-[idmsr]+)(?=\s|$)/,
+ lookbehind: true,
+ alias: 'number',
+ inside: {
+ variable: /\\\S/,
+ keyword: /[+?*\[\]^$(){}.|]/,
+ operator: {
+ pattern: /(\/)[idmsr]+(?:-[idmsr]+)?/,
+ lookbehind: true,
+ },
+ },
+ },
+
+ boolean: {
+ pattern: /(^|\s)[tf](?=\s|$)/,
+ lookbehind: true,
+ },
+
+ // SBUF" asd", URL" ://...", P" /etc/"
+ 'custom-string': {
+ pattern: /(^|\s)[A-Z0-9\-]+"\s(?:\\\S|[^"\\])*"/,
+ lookbehind: true,
+ greedy: true,
+ alias: 'string',
+ inside: {
+ number: /\\\S|%\w|\//,
+ },
+ },
+
+ 'multiline-string': [
+ {
+ // STRING: name \n content \n ; -> CONSTANT: name "content" (symbol)
+ pattern: /(^|\s)STRING:\s+\S+(?:\n|\r\n).*(?:\n|\r\n)\s*;(?=\s|$)/,
+ lookbehind: true,
+ greedy: true,
+ alias: 'string',
+ inside: {
+ number: string_inside.number,
+ // trailing semicolon on its own line
+ 'semicolon-or-setlocal': {
+ pattern: /([\r\n][ \t]*);(?=\s|$)/,
+ lookbehind: true,
+ alias: 'function',
+ },
+ },
+ },
+ {
+ // HEREDOC: marker \n content \n marker ; -> "content" (immediate)
+ pattern: /(^|\s)HEREDOC:\s+\S+(?:\n|\r\n).*(?:\n|\r\n)\s*\S+(?=\s|$)/,
+ lookbehind: true,
+ greedy: true,
+ alias: 'string',
+ inside: string_inside,
+ },
+ {
+ // [[ string ]], [==[ string]==]
+ pattern: /(^|\s)\[(={0,6})\[\s[\s\S]*?\]\2\](?=\s|$)/,
+ lookbehind: true,
+ greedy: true,
+ alias: 'string',
+ inside: string_inside,
+ },
+ ],
+
+ 'special-using': {
+ pattern: /(^|\s)USING:(?:\s\S+)*(?=\s+;(?:\s|$))/,
+ lookbehind: true,
+ alias: 'function',
+ inside: {
+ // this is essentially a regex for vocab names, which i don't want to specify
+ // but the USING: gets picked up as a vocab name
+ string: {
+ pattern: /(\s)[^:\s]+/,
+ lookbehind: true,
+ },
+ },
+ },
+
+ /* this description of stack effect literal syntax is not complete and not as specific as theoretically possible
+ trying to do better is more work and regex-computation-time than it's worth though.
+ - we'd like to have the "delimiter" parts of the stack effect [ (, --, and ) ] be a different (less-important or comment-like) colour to the stack effect contents
+ - we'd like if nested stack effects were treated as such rather than just appearing flat (with `inside`)
+ - we'd like if the following variable name conventions were recognised specifically:
+ special row variables = ..a b..
+ type and stack effect annotations end with a colon = ( quot: ( a: ( -- ) -- b ) -- x ), ( x: number -- )
+ word throws unconditional error = *
+ any other word-like variable name = a ? q' etc
+
+ https://docs.factorcode.org/content/article-effects.html
+
+ these are pretty complicated to highlight properly without a real parser, and therefore out of scope
+ the old pattern, which may be later useful, was: (^|\s)(?:call|execute|eval)?\((?:\s+[^"\r\n\t ]\S*)*?\s+--(?:\s+[^"\n\t ]\S*)*?\s+\)(?=\s|$)
+ */
+
+ // current solution is not great
+ 'stack-effect-delimiter': [
+ {
+ // opening parenthesis
+ pattern: /(^|\s)(?:call|eval|execute)?\((?=\s)/,
+ lookbehind: true,
+ alias: 'operator',
+ },
+ {
+ // middle --
+ pattern: /(\s)--(?=\s)/,
+ lookbehind: true,
+ alias: 'operator',
+ },
+ {
+ // closing parenthesis
+ pattern: /(\s)\)(?=\s|$)/,
+ lookbehind: true,
+ alias: 'operator',
+ },
+ ],
+
+ combinators: {
+ pattern: null,
+ lookbehind: true,
+ alias: 'keyword',
+ },
+
+ 'kernel-builtin': {
+ pattern: null,
+ lookbehind: true,
+ alias: 'variable',
+ },
+
+ 'sequences-builtin': {
+ pattern: null,
+ lookbehind: true,
+ alias: 'variable',
+ },
+
+ 'math-builtin': {
+ pattern: null,
+ lookbehind: true,
+ alias: 'variable',
+ },
+
+ 'constructor-word': {
+ // <array> but not <=>
+ pattern: /(^|\s)<(?!=+>|-+>)\S+>(?=\s|$)/,
+ lookbehind: true,
+ alias: 'keyword',
+ },
+
+ 'other-builtin-syntax': {
+ pattern: null,
+ lookbehind: true,
+ alias: 'operator',
+ },
+
+ /*
+ full list of supported word naming conventions: (the convention appears outside of the [brackets])
+ set-[x]
+ change-[x]
+ with-[x]
+ new-[x]
+ >[string]
+ [base]>
+ [string]>[number]
+ +[symbol]+
+ [boolean-word]?
+ ?[of]
+ [slot-reader]>>
+ >>[slot-setter]
+ [slot-writer]<<
+ ([implementation-detail])
+ [mutater]!
+ [variant]*
+ [prettyprint].
+ $[help-markup]
+
+ <constructors>, SYNTAX:, etc are supported by their own patterns.
+
+ `with` and `new` from `kernel` are their own builtins.
+
+ see <https://docs.factorcode.org/content/article-conventions.html>
+ */
+ 'conventionally-named-word': {
+ pattern:
+ /(^|\s)(?!")(?:(?:change|new|set|with)-\S+|\$\S+|>[^>\s]+|[^:>\s]+>|[^>\s]+>[^>\s]+|\+[^+\s]+\+|[^?\s]+\?|\?[^?\s]+|[^>\s]+>>|>>[^>\s]+|[^<\s]+<<|\([^()\s]+\)|[^!\s]+!|[^*\s]\S*\*|[^.\s]\S*\.)(?=\s|$)/,
+ lookbehind: true,
+ alias: 'keyword',
+ },
+
+ 'colon-syntax': {
+ pattern: /(^|\s)(?:[A-Z0-9\-]+#?)?:{1,2}\s+(?:;\S+|(?!;)\S+)(?=\s|$)/,
+ lookbehind: true,
+ greedy: true,
+ alias: 'function',
+ },
+
+ 'semicolon-or-setlocal': {
+ pattern: /(\s)(?:;|:>)(?=\s|$)/,
+ lookbehind: true,
+ alias: 'function',
+ },
+
+ // do not highlight leading } or trailing X{ at the begin/end of the file as it's invalid syntax
+ 'curly-brace-literal-delimiter': [
+ {
+ // opening
+ pattern: /(^|\s)[a-z]*\{(?=\s)/i,
+ lookbehind: true,
+ alias: 'operator',
+ },
+ {
+ // closing
+ pattern: /(\s)\}(?=\s|$)/,
+ lookbehind: true,
+ alias: 'operator',
+ },
+ ],
+
+ // do not highlight leading ] or trailing [ at the begin/end of the file as it's invalid syntax
+ 'quotation-delimiter': [
+ {
+ // opening
+ pattern: /(^|\s)\[(?=\s)/,
+ lookbehind: true,
+ alias: 'operator',
+ },
+ {
+ // closing
+ pattern: /(\s)\](?=\s|$)/,
+ lookbehind: true,
+ alias: 'operator',
+ },
+ ],
+
+ 'normal-word': {
+ pattern: /(^|\s)[^"\s]\S*(?=\s|$)/,
+ lookbehind: true,
+ },
+
+ /*
+ basic first-class string "a"
+ with escaped double-quote "a\""
+ escaped backslash "\\"
+ and general escapes since Factor has so many "\N"
+
+ syntax that works in the reference implementation that isn't fully
+ supported because it's an implementation detail:
+ "string 1""string 2" -> 2 strings (works anyway)
+ "string"5 -> string, 5
+ "string"[ ] -> string, quotation
+ { "a"} -> array<string>
+
+ the rest of those examples all properly recognise the string, but not
+ the other object (number, quotation, etc)
+ this is fine for a regex-only implementation.
+ */
+ string: {
+ pattern: /"(?:\\\S|[^"\\])*"/,
+ greedy: true,
+ inside: string_inside,
+ },
+ };
+
+ var escape = function (str) {
+ return (str + '').replace(/([.?*+\^$\[\]\\(){}|\-])/g, '\\$1');
+ };
+
+ var arrToWordsRegExp = function (arr) {
+ return new RegExp('(^|\\s)(?:' + arr.map(escape).join('|') + ')(?=\\s|$)');
+ };
+
+ var builtins = {
+ 'kernel-builtin': [
+ 'or',
+ '2nipd',
+ '4drop',
+ 'tuck',
+ 'wrapper',
+ 'nip',
+ 'wrapper?',
+ 'callstack>array',
+ 'die',
+ 'dupd',
+ 'callstack',
+ 'callstack?',
+ '3dup',
+ 'hashcode',
+ 'pick',
+ '4nip',
+ 'build',
+ '>boolean',
+ 'nipd',
+ 'clone',
+ '5nip',
+ 'eq?',
+ '?',
+ '=',
+ 'swapd',
+ '2over',
+ 'clear',
+ '2dup',
+ 'get-retainstack',
+ 'not',
+ 'tuple?',
+ 'dup',
+ '3nipd',
+ 'call',
+ '-rotd',
+ 'object',
+ 'drop',
+ 'assert=',
+ 'assert?',
+ '-rot',
+ 'execute',
+ 'boa',
+ 'get-callstack',
+ 'curried?',
+ '3drop',
+ 'pickd',
+ 'overd',
+ 'over',
+ 'roll',
+ '3nip',
+ 'swap',
+ 'and',
+ '2nip',
+ 'rotd',
+ 'throw',
+ '(clone)',
+ 'hashcode*',
+ 'spin',
+ 'reach',
+ '4dup',
+ 'equal?',
+ 'get-datastack',
+ 'assert',
+ '2drop',
+ '<wrapper>',
+ 'boolean?',
+ 'identity-hashcode',
+ 'identity-tuple?',
+ 'null',
+ 'composed?',
+ 'new',
+ '5drop',
+ 'rot',
+ '-roll',
+ 'xor',
+ 'identity-tuple',
+ 'boolean',
+ ],
+ 'other-builtin-syntax': [
+ // syntax
+ '=======',
+ 'recursive',
+ 'flushable',
+ '>>',
+ '<<<<<<',
+ 'M\\',
+ 'B',
+ 'PRIVATE>',
+ '\\',
+ '======',
+ 'final',
+ 'inline',
+ 'delimiter',
+ 'deprecated',
+ '<PRIVATE',
+ '>>>>>>',
+ '<<<<<<<',
+ 'parse-complex',
+ 'malformed-complex',
+ 'read-only',
+ '>>>>>>>',
+ 'call-next-method',
+ '<<',
+ 'foldable',
+ // literals
+ '$',
+ '$[',
+ '${',
+ ],
+ 'sequences-builtin': [
+ 'member-eq?',
+ 'mismatch',
+ 'append',
+ 'assert-sequence=',
+ 'longer',
+ 'repetition',
+ 'clone-like',
+ '3sequence',
+ 'assert-sequence?',
+ 'last-index-from',
+ 'reversed',
+ 'index-from',
+ 'cut*',
+ 'pad-tail',
+ 'join-as',
+ 'remove-eq!',
+ 'concat-as',
+ 'but-last',
+ 'snip',
+ 'nths',
+ 'nth',
+ 'sequence',
+ 'longest',
+ 'slice?',
+ '<slice>',
+ 'remove-nth',
+ 'tail-slice',
+ 'empty?',
+ 'tail*',
+ 'member?',
+ 'virtual-sequence?',
+ 'set-length',
+ 'drop-prefix',
+ 'iota',
+ 'unclip',
+ 'bounds-error?',
+ 'unclip-last-slice',
+ 'non-negative-integer-expected',
+ 'non-negative-integer-expected?',
+ 'midpoint@',
+ 'longer?',
+ '?set-nth',
+ '?first',
+ 'rest-slice',
+ 'prepend-as',
+ 'prepend',
+ 'fourth',
+ 'sift',
+ 'subseq-start',
+ 'new-sequence',
+ '?last',
+ 'like',
+ 'first4',
+ '1sequence',
+ 'reverse',
+ 'slice',
+ 'virtual@',
+ 'repetition?',
+ 'set-last',
+ 'index',
+ '4sequence',
+ 'max-length',
+ 'set-second',
+ 'immutable-sequence',
+ 'first2',
+ 'first3',
+ 'supremum',
+ 'unclip-slice',
+ 'suffix!',
+ 'insert-nth',
+ 'tail',
+ '3append',
+ 'short',
+ 'suffix',
+ 'concat',
+ 'flip',
+ 'immutable?',
+ 'reverse!',
+ '2sequence',
+ 'sum',
+ 'delete-all',
+ 'indices',
+ 'snip-slice',
+ '<iota>',
+ 'check-slice',
+ 'sequence?',
+ 'head',
+ 'append-as',
+ 'halves',
+ 'sequence=',
+ 'collapse-slice',
+ '?second',
+ 'slice-error?',
+ 'product',
+ 'bounds-check?',
+ 'bounds-check',
+ 'immutable',
+ 'virtual-exemplar',
+ 'harvest',
+ 'remove',
+ 'pad-head',
+ 'last',
+ 'set-fourth',
+ 'cartesian-product',
+ 'remove-eq',
+ 'shorten',
+ 'shorter',
+ 'reversed?',
+ 'shorter?',
+ 'shortest',
+ 'head-slice',
+ 'pop*',
+ 'tail-slice*',
+ 'but-last-slice',
+ 'iota?',
+ 'append!',
+ 'cut-slice',
+ 'new-resizable',
+ 'head-slice*',
+ 'sequence-hashcode',
+ 'pop',
+ 'set-nth',
+ '?nth',
+ 'second',
+ 'join',
+ 'immutable-sequence?',
+ '<reversed>',
+ '3append-as',
+ 'virtual-sequence',
+ 'subseq?',
+ 'remove-nth!',
+ 'length',
+ 'last-index',
+ 'lengthen',
+ 'assert-sequence',
+ 'copy',
+ 'move',
+ 'third',
+ 'first',
+ 'tail?',
+ 'set-first',
+ 'prefix',
+ 'bounds-error',
+ '<repetition>',
+ 'exchange',
+ 'surround',
+ 'cut',
+ 'min-length',
+ 'set-third',
+ 'push-all',
+ 'head?',
+ 'subseq-start-from',
+ 'delete-slice',
+ 'rest',
+ 'sum-lengths',
+ 'head*',
+ 'infimum',
+ 'remove!',
+ 'glue',
+ 'slice-error',
+ 'subseq',
+ 'push',
+ 'replace-slice',
+ 'subseq-as',
+ 'unclip-last',
+ ],
+ 'math-builtin': [
+ 'number=',
+ 'next-power-of-2',
+ '?1+',
+ 'fp-special?',
+ 'imaginary-part',
+ 'float>bits',
+ 'number?',
+ 'fp-infinity?',
+ 'bignum?',
+ 'fp-snan?',
+ 'denominator',
+ 'gcd',
+ '*',
+ '+',
+ 'fp-bitwise=',
+ '-',
+ 'u>=',
+ '/',
+ '>=',
+ 'bitand',
+ 'power-of-2?',
+ 'log2-expects-positive',
+ 'neg?',
+ '<',
+ 'log2',
+ '>',
+ 'integer?',
+ 'number',
+ 'bits>double',
+ '2/',
+ 'zero?',
+ 'bits>float',
+ 'float?',
+ 'shift',
+ 'ratio?',
+ 'rect>',
+ 'even?',
+ 'ratio',
+ 'fp-sign',
+ 'bitnot',
+ '>fixnum',
+ 'complex?',
+ '/i',
+ 'integer>fixnum',
+ '/f',
+ 'sgn',
+ '>bignum',
+ 'next-float',
+ 'u<',
+ 'u>',
+ 'mod',
+ 'recip',
+ 'rational',
+ '>float',
+ '2^',
+ 'integer',
+ 'fixnum?',
+ 'neg',
+ 'fixnum',
+ 'sq',
+ 'bignum',
+ '>rect',
+ 'bit?',
+ 'fp-qnan?',
+ 'simple-gcd',
+ 'complex',
+ '<fp-nan>',
+ 'real',
+ '>fraction',
+ 'double>bits',
+ 'bitor',
+ 'rem',
+ 'fp-nan-payload',
+ 'real-part',
+ 'log2-expects-positive?',
+ 'prev-float',
+ 'align',
+ 'unordered?',
+ 'float',
+ 'fp-nan?',
+ 'abs',
+ 'bitxor',
+ 'integer>fixnum-strict',
+ 'u<=',
+ 'odd?',
+ '<=',
+ '/mod',
+ '>integer',
+ 'real?',
+ 'rational?',
+ 'numerator',
+ ],
+ // that's all for now
+ };
+
+ Object.keys(builtins).forEach(function (k) {
+ factor[k].pattern = arrToWordsRegExp(builtins[k]);
+ });
+
+ var combinators = [
+ // kernel
+ '2bi',
+ 'while',
+ '2tri',
+ 'bi*',
+ '4dip',
+ 'both?',
+ 'same?',
+ 'tri@',
+ 'curry',
+ 'prepose',
+ '3bi',
+ '?if',
+ 'tri*',
+ '2keep',
+ '3keep',
+ 'curried',
+ '2keepd',
+ 'when',
+ '2bi*',
+ '2tri*',
+ '4keep',
+ 'bi@',
+ 'keepdd',
+ 'do',
+ 'unless*',
+ 'tri-curry',
+ 'if*',
+ 'loop',
+ 'bi-curry*',
+ 'when*',
+ '2bi@',
+ '2tri@',
+ 'with',
+ '2with',
+ 'either?',
+ 'bi',
+ 'until',
+ '3dip',
+ '3curry',
+ 'tri-curry*',
+ 'tri-curry@',
+ 'bi-curry',
+ 'keepd',
+ 'compose',
+ '2dip',
+ 'if',
+ '3tri',
+ 'unless',
+ 'tuple',
+ 'keep',
+ '2curry',
+ 'tri',
+ 'most',
+ 'while*',
+ 'dip',
+ 'composed',
+ 'bi-curry@',
+ // sequences
+ 'find-last-from',
+ 'trim-head-slice',
+ 'map-as',
+ 'each-from',
+ 'none?',
+ 'trim-tail',
+ 'partition',
+ 'if-empty',
+ 'accumulate*',
+ 'reject!',
+ 'find-from',
+ 'accumulate-as',
+ 'collector-for-as',
+ 'reject',
+ 'map',
+ 'map-sum',
+ 'accumulate!',
+ '2each-from',
+ 'follow',
+ 'supremum-by',
+ 'map!',
+ 'unless-empty',
+ 'collector',
+ 'padding',
+ 'reduce-index',
+ 'replicate-as',
+ 'infimum-by',
+ 'trim-tail-slice',
+ 'count',
+ 'find-index',
+ 'filter',
+ 'accumulate*!',
+ 'reject-as',
+ 'map-integers',
+ 'map-find',
+ 'reduce',
+ 'selector',
+ 'interleave',
+ '2map',
+ 'filter-as',
+ 'binary-reduce',
+ 'map-index-as',
+ 'find',
+ 'produce',
+ 'filter!',
+ 'replicate',
+ 'cartesian-map',
+ 'cartesian-each',
+ 'find-index-from',
+ 'map-find-last',
+ '3map-as',
+ '3map',
+ 'find-last',
+ 'selector-as',
+ '2map-as',
+ '2map-reduce',
+ 'accumulate',
+ 'each',
+ 'each-index',
+ 'accumulate*-as',
+ 'when-empty',
+ 'all?',
+ 'collector-as',
+ 'push-either',
+ 'new-like',
+ 'collector-for',
+ '2selector',
+ 'push-if',
+ '2all?',
+ 'map-reduce',
+ '3each',
+ 'any?',
+ 'trim-slice',
+ '2reduce',
+ 'change-nth',
+ 'produce-as',
+ '2each',
+ 'trim',
+ 'trim-head',
+ 'cartesian-find',
+ 'map-index',
+ // math
+ 'if-zero',
+ 'each-integer',
+ 'unless-zero',
+ '(find-integer)',
+ 'when-zero',
+ 'find-last-integer',
+ '(all-integers?)',
+ 'times',
+ '(each-integer)',
+ 'find-integer',
+ 'all-integers?',
+ // math.combinators
+ 'unless-negative',
+ 'if-positive',
+ 'when-positive',
+ 'when-negative',
+ 'unless-positive',
+ 'if-negative',
+ // combinators
+ 'case',
+ '2cleave',
+ 'cond>quot',
+ 'case>quot',
+ '3cleave',
+ 'wrong-values',
+ 'to-fixed-point',
+ 'alist>quot',
+ 'cond',
+ 'cleave',
+ 'call-effect',
+ 'recursive-hashcode',
+ 'spread',
+ 'deep-spread>quot',
+ // combinators.short-circuit
+ '2||',
+ '0||',
+ 'n||',
+ '0&&',
+ '2&&',
+ '3||',
+ '1||',
+ '1&&',
+ 'n&&',
+ '3&&',
+ // combinators.smart
+ 'smart-unless*',
+ 'keep-inputs',
+ 'reduce-outputs',
+ 'smart-when*',
+ 'cleave>array',
+ 'smart-with',
+ 'smart-apply',
+ 'smart-if',
+ 'inputs/outputs',
+ 'output>sequence-n',
+ 'map-outputs',
+ 'map-reduce-outputs',
+ 'dropping',
+ 'output>array',
+ 'smart-map-reduce',
+ 'smart-2map-reduce',
+ 'output>array-n',
+ 'nullary',
+ 'input<sequence',
+ 'append-outputs',
+ 'drop-inputs',
+ 'inputs',
+ 'smart-2reduce',
+ 'drop-outputs',
+ 'smart-reduce',
+ 'preserving',
+ 'smart-when',
+ 'outputs',
+ 'append-outputs-as',
+ 'smart-unless',
+ 'smart-if*',
+ 'sum-outputs',
+ 'input<sequence-unsafe',
+ 'output>sequence',
+ // tafn
+ ];
+
+ factor.combinators.pattern = arrToWordsRegExp(combinators);
+
+ Prism.languages.factor = factor;
+})(Prism);