aboutsummaryrefslogtreecommitdiff
path: root/lua/lexers/makefile.lua
diff options
context:
space:
mode:
authorMatěj Cepl <mcepl@cepl.eu>2023-08-11 01:27:32 +0200
committerRandy Palamar <randy@rnpnr.xyz>2024-03-27 06:04:21 -0600
commit4c4392d29df777ff702dfe99b4f3c23142976e05 (patch)
tree5355324abe18952f7d19d6cfc5dbeb5d6cb72b84 /lua/lexers/makefile.lua
parent95bf9f59f8a9a37148bdc0787db378d62c7cd032 (diff)
downloadvis-4c4392d29df777ff702dfe99b4f3c23142976e05.tar.gz
vis-4c4392d29df777ff702dfe99b4f3c23142976e05.tar.xz
update lexers to orbitalquark/scintillua@b789dde
Rather than cherry pick patches from after 6.2 we will just grab everything as is.
Diffstat (limited to 'lua/lexers/makefile.lua')
-rw-r--r--lua/lexers/makefile.lua167
1 files changed, 100 insertions, 67 deletions
diff --git a/lua/lexers/makefile.lua b/lua/lexers/makefile.lua
index 9c5f332..fd90ba2 100644
--- a/lua/lexers/makefile.lua
+++ b/lua/lexers/makefile.lua
@@ -1,88 +1,121 @@
--- Copyright 2006-2022 Mitchell. See LICENSE.
+-- Copyright 2006-2024 Mitchell. See LICENSE.
-- Makefile LPeg lexer.
-local lexer = require('lexer')
-local token, word_match = lexer.token, lexer.word_match
-local P, S = lpeg.P, lpeg.S
+local lexer = lexer
+local P, S, B = lpeg.P, lpeg.S, lpeg.B
-local lex = lexer.new('makefile', {lex_by_line = true})
+local lex = lexer.new(..., {lex_by_line = true})
--- Whitespace.
-local ws = token(lexer.WHITESPACE, lexer.space^1)
-lex:add_rule('whitespace', ws)
+-- Function definition.
+local word = (lexer.any - lexer.space - S('$:,#=(){}'))^1
+local func_name = lex:tag(lexer.FUNCTION, word)
+local ws = lex:get_rule('whitespace')
+local eq = lex:tag(lexer.OPERATOR, '=')
+lex:add_rule('function_def',
+ lex:tag(lexer.KEYWORD, lexer.word_match('define')) * ws * func_name * ws^-1 * eq)
-- Keywords.
-lex:add_rule('keyword', token(lexer.KEYWORD, P('!')^-1 * word_match({
- -- GNU Make conditionals.
- 'ifeq', 'ifneq', 'ifdef', 'ifndef', 'else', 'endif',
- -- Other conditionals.
- 'if', 'elseif', 'elseifdef', 'elseifndef',
- -- Directives and other keywords.
- 'define', 'endef', 'export', 'include', 'override', 'private', 'undefine', 'unexport', 'vpath'
-}, true)))
+lex:add_rule('keyword', lex:tag(lexer.KEYWORD, P('!')^-1 * lex:word_match(lexer.KEYWORD, true)))
-- Targets.
-local special_target = token(lexer.CONSTANT, word_match{
- '.PHONY', '.SUFFIXES', '.DEFAULT', '.PRECIOUS', '.INTERMEDIATE', '.SECONDARY', '.SECONDEXPANSION',
- '.DELETE_ON_ERROR', '.IGNORE', '.LOW_RESOLUTION_TIME', '.SILENT', '.EXPORT_ALL_VARIABLES',
- '.NOTPARALLEL', '.ONESHELL', '.POSIX'
-})
-local normal_target = token('target', (lexer.any - lexer.space - S(':#='))^1)
-local target_list = normal_target * (ws * normal_target)^0
-lex:add_rule('target', lexer.starts_line((special_target + target_list) * ws^0 * #(':' * -P('='))))
-lex:add_style('target', lexer.styles.label)
+local special_target = lex:tag(lexer.CONSTANT_BUILTIN, '.' * lex:word_match('special_targets'))
+-- local normal_target = lex:tag('target', (lexer.any - lexer.space - S(':+?!=#'))^1)
+local target = special_target -- + normal_target * (ws * normal_target)^0
+lex:add_rule('target', lexer.starts_line(target * ws^-1 * #(':' * lexer.space)))
--- Variables.
-local word_char = lexer.any - lexer.space - S(':#=(){}')
-local assign = S(':+?')^-1 * '='
-local expanded_var = '$' * ('(' * word_char^1 * ')' + '{' * word_char^1 * '}')
-local auto_var = '$' * S('@%<?^+|*')
-local special_var = word_match{
- 'MAKEFILE_LIST', '.DEFAULT_GOAL', 'MAKE_RESTARTS', '.RECIPEPREFIX', '.VARIABLES', '.FEATURES',
- '.INCLUDE_DIRS', 'GPATH', 'MAKECMDGOALS', 'MAKESHELL', 'SHELL', 'VPATH'
-} * #(ws^0 * assign)
-local implicit_var = word_match{
- -- Some common variables.
- 'AR', 'AS', 'CC', 'CXX', 'CPP', 'FC', 'M2C', 'PC', 'CO', 'GET', 'LEX', 'YACC', 'LINT', 'MAKEINFO',
- 'TEX', 'TEXI2DVI', 'WEAVE', 'CWEAVE', 'TANGLE', 'CTANGLE', 'RM',
- -- Some common flag variables.
- 'ARFLAGS', 'ASFLAGS', 'CFLAGS', 'CXXFLAGS', 'COFLAGS', 'CPPFLAGS', 'FFLAGS', 'GFLAGS', 'LDFLAGS',
- 'LDLIBS', 'LFLAGS', 'YFLAGS', 'PFLAGS', 'RFLAGS', 'LINTFLAGS',
- -- Other.
- 'DESTDIR', 'MAKE', 'MAKEFLAGS', 'MAKEOVERRIDES', 'MFLAGS'
-} * #(ws^0 * assign)
-local variable = token(lexer.VARIABLE, expanded_var + auto_var + special_var + implicit_var)
-local computed_var = token(lexer.OPERATOR, '$' * S('({')) * token(lexer.FUNCTION, word_match{
- -- Functions for String Substitution and Analysis.
- 'subst', 'patsubst', 'strip', 'findstring', 'filter', 'filter-out', 'sort', 'word', 'wordlist',
- 'words', 'firstword', 'lastword',
- -- Functions for File Names.
- 'dir', 'notdir', 'suffix', 'basename', 'addsuffix', 'addprefix', 'join', 'wildcard', 'realpath',
- 'abspath',
- -- Functions for Conditionals.
- 'if', 'or', 'and',
- -- Miscellaneous Functions.
- 'foreach', 'call', 'value', 'eval', 'origin', 'flavor', 'shell',
- -- Functions That Control Make.
- 'error', 'warning', 'info'
-})
-lex:add_rule('variable', variable + computed_var)
+-- Variable and function assignments.
+local func_assign = func_name * ws^-1 * eq *
+ #P(function(input, index) return input:find('%$%(%d%)', index) end)
+local builtin_var = lex:tag(lexer.VARIABLE_BUILTIN, lex:word_match(lexer.VARIABLE_BUILTIN))
+local var_name = lex:tag(lexer.VARIABLE, word)
+local var_assign = (builtin_var + var_name) * ws^-1 *
+ lex:tag(lexer.OPERATOR, S(':+?!')^-1 * '=' + '::=')
+lex:add_rule('assign', lexer.starts_line(func_assign + var_assign, true) + B(': ') * var_assign)
-- Operators.
-lex:add_rule('operator', token(lexer.OPERATOR, assign + S(':$(){}')))
+lex:add_rule('operator', lex:tag(lexer.OPERATOR, S(':(){}|')))
+
+-- Strings.
+lex:add_rule('string', lexer.range("'", true) + lexer.range('"', true))
-- Identifiers.
-lex:add_rule('identifier', token(lexer.IDENTIFIER, word_char^1))
+lex:add_rule('identifier', lex:tag(lexer.IDENTIFIER, word))
+
+-- Functions.
+local builtin_func = lex:tag(lexer.FUNCTION_BUILTIN, lex:word_match(lexer.FUNCTION_BUILTIN))
+local call_func = lex:tag(lexer.FUNCTION_BUILTIN, 'call') * ws * func_name
+local func = lex:tag(lexer.OPERATOR, '$' * S('({')) * (call_func + builtin_func)
+lex:add_rule('function', func)
+
+-- Variables.
+local auto_var = lex:tag(lexer.OPERATOR, '$') * lex:tag(lexer.VARIABLE_BUILTIN, S('@%<?^+|*')) +
+ lex:tag(lexer.OPERATOR, '$(') * lex:tag(lexer.VARIABLE_BUILTIN, S('@%<?^+*') * S('DF'))
+local var_ref = lex:tag(lexer.OPERATOR, P('$(') + '${') * (builtin_var + var_name)
+local var = auto_var + var_ref
+lex:add_rule('variable', var)
-- Comments.
-lex:add_rule('comment', token(lexer.COMMENT, lexer.to_eol('#')))
+lex:add_rule('comment', lex:tag(lexer.COMMENT, lexer.to_eol('#')))
--- Embedded Bash.
+-- Embedded Bash in target rules.
local bash = lexer.load('bash')
bash:modify_rule('variable',
- token(lexer.VARIABLE, '$$' * word_char^1) + bash:get_rule('variable') + variable)
-local bash_start_rule = token(lexer.WHITESPACE, '\t') + token(lexer.OPERATOR, ';')
-local bash_end_rule = token(lexer.WHITESPACE, '\n')
+ lex:tag(lexer.VARIABLE, '$$' * word) + func + var + bash:get_rule('variable'))
+local bash_start_rule = lex:tag(lexer.WHITESPACE, '\t') + lex:tag(lexer.OPERATOR, ';')
+local bash_end_rule = lex:tag(lexer.WHITESPACE, '\n')
lex:embed(bash, bash_start_rule, bash_end_rule)
+-- Embedded Bash in $(shell ...) calls.
+local shell = lexer.load('bash', 'bash.shell')
+bash_start_rule = #P('$(shell') * func
+bash_end_rule = -B('\\') * lex:tag(lexer.OPERATOR, ')')
+lex:embed(shell, bash_start_rule, bash_end_rule)
+
+-- Word lists.
+lex:set_word_list(lexer.KEYWORD, {
+ 'define', 'endef', -- multi-line
+ 'else', 'endif', 'ifdef', 'ifeq', 'ifndef', 'ifneq', -- conditionals
+ 'export', 'include', 'load', 'override', 'undefine', 'unexport', 'vpath', -- directives
+ 'private', --
+ 'if', 'elseif', 'elseifdef', 'elseifndef' -- non-Make conditionals
+})
+
+lex:set_word_list('special_targets', {
+ 'DEFAULT', 'DELETE_ON_ERROR', 'EXPORT_ALL_VARIABLES', 'IGNORE', 'INTERMEDIATE',
+ 'LOW_RESOLUTION_TIME', 'NOTPARALLEL', 'ONESHELL', 'PHONY', 'POSIX', 'PRECIOUS', 'SECONDARY',
+ 'SECONDEXPANSION', 'SILENT', 'SUFFIXES'
+})
+
+lex:set_word_list(lexer.VARIABLE_BUILTIN, {
+ -- Special.
+ '.DEFAULT_GOAL', '.FEATURES', '.INCLUDE_DIRS', '.LIBPATTERNS', '.LOADED', '.RECIPEPREFIX',
+ '.SHELLFLAGS', '.SHELLSTATUS', '.VARIABLES', --
+ 'COMSPEC', 'MAKESHELL', 'SHELL', -- choosing the shell
+ 'GPATH', 'VPATH', -- search
+ -- Make.
+ 'MAKE', 'MAKECMDGOALS', 'MAKEFILES', 'MAKEFILE_LIST', 'MAKEFLAGS', 'MAKELEVEL', 'MAKEOVERRIDES',
+ 'MAKE_RESTARTS', 'MAKE_TERMERR', 'MAKE_TERMOUT', 'MFLAGS',
+ -- Other.
+ 'CURDIR', 'OUTPUT_OPTION', 'SUFFIXES',
+ -- Implicit.
+ 'AR', 'ARFLAGS', 'AS', 'ASFLAGS', 'CC', 'CFLAGS', 'CO', 'COFLAGS', 'CPP', 'CPPFLAGS', 'CTANGLE',
+ 'CWEAVE', 'CXX', 'CXXFLAGS', 'FC', 'FFLAGS', 'GET', 'GFLAGS', 'LDFLAGS', 'LDLIBS', 'LEX',
+ 'LFLAGS', 'LINT', 'LINTFLAGS', 'M2C', 'MAKEINFO', 'PC', 'PFLAGS', 'RFLAGS', 'RM', 'TANGLE', 'TEX',
+ 'TEXI2DVI', 'WEAVE', 'YACC', 'YFLAGS', --
+ 'bindir', 'DESTDIR', 'exec_prefix', 'libexecdir', 'prefix', 'sbindir' -- directory
+})
+
+lex:set_word_list(lexer.FUNCTION_BUILTIN, {
+ -- Filename.
+ 'abspath', 'addprefix', 'addsuffix', 'basename', 'dir', 'join', 'notdir', 'realpath', 'suffix',
+ 'wildcard', --
+ 'and', 'if', 'or', -- conditional
+ 'error', 'info', 'warning', -- control
+ 'filter', 'filter-out', 'findstring', 'firstword', 'lastword', 'patsubst', 'sort', 'strip',
+ -- Text.
+ 'subst', 'word', 'wordlist', 'words', --
+ 'call', 'eval', 'file', 'flavor', 'foreach', 'origin', 'shell', 'value' -- other
+})
+
+lexer.property['scintillua.comment'] = '#'
return lex