~ecs/hare.lua

c38dfc889307380dc347104feb84f746315a6003 — Ember Sawady 2 years ago
Initial commit
3 files changed, 94 insertions(+), 0 deletions(-)

A README.md
A hare.lua
A hare_detect.lua
A  => README.md +12 -0
@@ 1,12 @@
# hare.lua

Vis plugin for Hare programming.

## Usage

Copy hare.lua into `$XDG_CONFIG_HOME/vis/lexers`, copy hare\_detect.lua
into `$XDG_CONFIG_HOME/vis`, and add `require("hare_detect")` to your
visrc.

If there's a different standard used in the vis world for third-party
plugins, patches are welcome.

A  => hare.lua +79 -0
@@ 1,79 @@
-- ? LPeg lexer.

local l = require('lexer')
local token, word_match = l.token, l.word_match
local P, R, S = lpeg.P, lpeg.R, lpeg.S

local M = {_NAME = 'hare'}

local builtin = token(l.FUNCTION, word_match{
	'len', 'offset', 'free', 'alloc', 'assert',
})

local comment = token(l.COMMENT, '//' * l.nonnewline_esc^0)

local constant = token(l.CONSTANT, word_match{
	'true', 'false',
})

local identifier = token(l.IDENTIFIER, l.word)

local keyword = token(l.KEYWORD, word_match{
	'let', 'const', 'fn', 'def', 'static', 'export', 'defer', 'for',
	'while', 'return', 'break', 'continue', 'if', 'else', 'match',
	'switch',
})

local operator = token(l.OPERATOR, word_match{
	'is', 'as', "..", "...",
} + S('+-/*%<>~!=^&|?~:;,.()[]{}'))

local hex_digit = R("09") + R("af") + R("AF")
local integer_suffix = word_match{
	"i", "u", "z", "i8", "i16", "i32", "i64", "u8", "u16", "u32",
	"u64",
}
local integer_constant = (P("0x") * hex_digit^1
	+ P("0o") * R("07")^1
	+ P("0b") * R("01")^1
	+ R("09")^1) * integer_suffix^-1
-- TODO: write spec for floating-constant
local number = token(l.NUMBER, integer_constant)

local preproc = token(l.PREPROCESSOR,
	l.starts_line('use ') * l.nonnewline_esc^0 * lpeg.B(';')
	+ '@' * R("az")^1)

local named_escape = P('\\0') + '\\a' + '\\b' + '\\f' + '\\n' + '\\r' + '\\v' + '\\\\' + '\\\'' + '\\"'
local escape_sequence = named_escape
	+ '\\x' * hex_digit * hex_digit
	+ '\\u' * hex_digit * hex_digit * hex_digit * hex_digit
local rune = escape_sequence + l.nonnewline_esc-S("\\'")
local string_char = escape_sequence + l.nonnewline_esc-S('\\"')
local string = token(l.STRING, "'" * rune * "'" + '"' * string_char^0 * '"')

-- TODO: highlight size correctly both as keyword and type
local type = token(l.TYPE, word_match{
	'u8', 'u16', 'u32', 'u64', 'i8', 'i16', 'i32', 'i64', 'uint',
	'int', 'uintptr', 'size', 'f32', 'f64', 'bool', 'char', 'str',
	'void', 'struct', 'union', 'enum', 'nullable', 'null',
})

local ws = token(l.WHITESPACE, l.space^1)

M._rules = {
	{'builtin', builtin},
	{'constant', constant},
	{'comment', comment},
	{'keyword', keyword},
	{'number', number},
	{'operator', operator},
	{'preproc', preproc},
	{'string', string},
	{'type', type},
	{'whitespace', ws},

	{'identifier', identifier},
}

return M

A  => hare_detect.lua +3 -0
@@ 1,3 @@
vis.ftdetect.filetypes.hare = {
	ext = { "%.ha$" },
}