aboutsummaryrefslogtreecommitdiff
path: root/lua/lexers
diff options
context:
space:
mode:
authororbitalquark <70453897+orbitalquark@users.noreply.github.com>2024-10-20 14:38:03 -0400
committerRandy Palamar <randy@rnpnr.xyz>2025-01-04 12:35:27 -0700
commit016d58d8549a66a295feaf49efdfd5a15eed2132 (patch)
treeb59adcacdfff6572b78329b5a233daab062f8378 /lua/lexers
parente54caf087cecda02b625b5d5d51c667746002a3e (diff)
downloadvis-016d58d8549a66a295feaf49efdfd5a15eed2132.tar.gz
vis-016d58d8549a66a295feaf49efdfd5a15eed2132.tar.xz
Add Factor lexer
Thanks to John Benediktsson.
Diffstat (limited to 'lua/lexers')
-rw-r--r--lua/lexers/factor.lua71
-rw-r--r--lua/lexers/lexer.lua1
2 files changed, 72 insertions, 0 deletions
diff --git a/lua/lexers/factor.lua b/lua/lexers/factor.lua
new file mode 100644
index 0000000..2760154
--- /dev/null
+++ b/lua/lexers/factor.lua
@@ -0,0 +1,71 @@
+-- Copyright 2013 Michael T. Richter. See LICENSE.
+-- Copyright 2024 John Benediktsson <mrjbq7@gmail.com>
+-- Factor lexer (http://factorcode.org).
+
+-- At this time the lexer is usable, but not perfect. Problems include:
+-- * identifiers like (foo) get treated and coloured like stack declarations
+-- * other as-yet unknown display bugs :-)
+
+local lexer = lexer
+local P, R, S = lpeg.P, lpeg.R, lpeg.S
+
+local lex = lexer.new(...)
+
+-- General building blocks.
+local pre = lexer.upper^1
+local post = pre
+local opt_pre = pre^-1
+local opt_post = opt_pre
+
+-- Comments.
+lex:add_rule('comment', lex:tag(lexer.COMMENT, P('#')^-1 * lexer.to_eol('!')))
+
+-- Strings.
+local dq1_str = opt_pre * lexer.range('"', true)
+lex:add_rule('string', lex:tag(lexer.STRING, dq1_str))
+
+-- Numbers.
+-- Note that complex literals like C{ 1/3 27.3 } are not covered by this lexer.
+-- The C{ ... } notation is treated as an operator--to be specific a
+-- "constructor" (for want of a better term).
+-- Also note that we cannot use lexer.number because numbers do not support the '+' prefix or
+-- case-insensitive base-changing prefixes.
+local hex_digits = lexer.xdigit^1
+local binary = P('-')^-1 * '0b' * S('01')^1
+local octal = P('-')^-1 * '0o' * R('07')^1
+local decimal = P('-')^-1 * lexer.digit^1
+local hexadecimal = P('-')^-1 * '0x' * hex_digits
+local integer = binary + octal + hexadecimal + decimal
+local ratio = decimal * '/' * decimal
+local dfloat_component = decimal * '.' * decimal^-1
+local hfloat_component = hexadecimal * ('.' * hex_digits^-1)^-1
+local float = (dfloat_component * (S('eE') * decimal)^-1) + (hfloat_component * S('pP') * decimal) +
+ (ratio * '.') + (P('-')^-1 * '1/0.') + ('0/0')
+lex:add_rule('number', lex:tag(lexer.NUMBER, (float + ratio + integer)))
+
+-- Keywords.
+-- Things like NAN:, USE:, USING:, POSTPONE:, etc. are considered keywords, as are similar
+-- words that end in #.
+-- Patterns like <<WORD ... WORD>> are similarly considered to be "keywords" (for want of a
+-- better term).
+local colon_words = pre * S(':#') + S(':;')^1
+local angle_words = (P('<')^1 * post) + (pre * P('>')^1)
+lex:add_rule('keyword', lex:tag(lexer.KEYWORD, (colon_words + angle_words)))
+
+-- Operators.
+-- The usual suspects like braces, brackets, angle brackets, parens, etc. are considered to be
+-- operators. They may, however, have prefixes like C{ ... }.
+local constructor_words = opt_pre * S('{[<') + S('}]>') + pre * '(' + ')'
+local stack_declaration = lexer.range('(', ')')
+local other_operators = S('+-*/<>')
+lex:add_rule('operator',
+ lex:tag(lexer.OPERATOR, (stack_declaration + constructor_words + other_operators)))
+
+-- Identifiers.
+-- Identifiers can be practically anything but whitespace.
+local symbols = S('`~!@#$%^&*()_-+={[<>]}:;X,?/')
+lex:add_rule('identifier', lex:tag(lexer.IDENTIFIER, (lexer.alnum + symbols)^1))
+
+lexer.property['factor.comment'] = '!'
+
+return lex
diff --git a/lua/lexers/lexer.lua b/lua/lexers/lexer.lua
index 0faeae9..357f926 100644
--- a/lua/lexers/lexer.lua
+++ b/lua/lexers/lexer.lua
@@ -1630,6 +1630,7 @@ function M.detect(filename, line)
elm = 'elm', --
erl = 'erlang', hrl = 'erlang', --
fs = 'fsharp', --
+ factor = 'factor', --
fan = 'fantom', --
dsp = 'faust', --
fnl = 'fennel', --