dotfiles

dot files
git clone git://git.rr3.xyz/dotfiles
Log | Files | Refs

glsl.lua (8130B)


      1 -- TODO: Hack: This is just a copy of the ansi_c lexer with some additions.
      2 
      3 local M = {_NAME = "glsl"}
      4 
      5 local l = require("lexer")
      6 local P, R, S = lpeg.P, lpeg.R, lpeg.S
      7 local T = l.token
      8 local any = P(1)
      9 local oct = R"07"
     10 local dec = R"09"
     11 local hex = R("09", "AF", "af")
     12 local alpha = R("AZ", "az")
     13 local letter = alpha + dec + "_"
     14 local word = (alpha + P"_") * letter^0
     15 local pm = S"+-"
     16 local hws = S"\t "
     17 local vws = S"\n\r"
     18 local ws = hws + vws
     19 local function I(s)  -- Case-insensitive string match
     20 	local p = P(true)
     21 	for i = 1, #s do
     22 		local c = s:sub(i, i)
     23 		p = p * (P(c:lower()) + P(c:upper()))
     24 	end
     25 	return p
     26 end
     27 local function N(p, min, max)
     28 	max = max or min
     29 	return p^min - p^(max+1)
     30 end
     31 
     32 local whitespace = T("whitespace", ws^1)
     33 
     34 local comment_keyword = T("comment_keyword", (I"todo" + I"xxx" + I"fixme" + I"sync" + I"fallthrough" + I"unreachable") * #(any - letter))
     35 local line_comment_text = T("comment_text", (any - comment_keyword - S"\\\n" + P"\\\n" + P"\\")^1)
     36 local line_comment = T("comment_text", P"//") * (line_comment_text + comment_keyword)^0 * (T("whitespace", P"\n") + P"")
     37 local block_comment_text = T("comment_text", (any - comment_keyword - P"*/")^1)
     38 local block_comment = T("comment_text", P"/*") * (block_comment_text + comment_keyword)^0 * T("comment_text", P"*/")^-1
     39 local comment = line_comment + block_comment
     40 
     41 local fltlit_dec_exp = S"eE" * pm^-1 * dec^1
     42 local fltlit_dec = dec^1 * (P"." * dec^0 * fltlit_dec_exp^-1 + fltlit_dec_exp) + P"." * dec^1 * fltlit_dec_exp^-1
     43 local fltlit_hex_exp = S"pP" * pm^-1 * dec^1
     44 local fltlit_hex = P"0" * S"xX" * (hex^1 * (P"." * hex^0)^-1 + P"." * hex^1) * fltlit_hex_exp
     45 local fltlit_suffix = S"fFlL"
     46 -- local fltlit = pm^-1 * (fltlit_hex + fltlit_dec) * fltlit_suffix^-1
     47 local fltlit = (fltlit_hex + fltlit_dec) * fltlit_suffix^-1
     48 
     49 local intlit_oct = P"0" * oct^1
     50 local intlit_dec = dec^1
     51 local intlit_hex = P"0" * S"xX" * hex^1
     52 local intlit_width = P"ll" + P"l" + P"LL" + P"L"
     53 local intlit_suffix = (S"uU" * intlit_width^-1) + (intlit_width * S"uU"^-1)
     54 -- local intlit = pm^-1 * (intlit_hex + intlit_oct + intlit_dec) * intlit_suffix^-1
     55 local intlit = (intlit_hex + intlit_oct + intlit_dec) * intlit_suffix^-1
     56 
     57 local numlit = T("numlit", fltlit + intlit)
     58 
     59 local escape = T("escape",
     60 	  P"\\" * S"'\"?\\abfnrtv"
     61 	+ P"\\" * dec * dec^-2
     62 	+ P"\\x" * hex^1
     63 	+ P"\\u" * N(hex, 4)
     64 	+ P"\\U" * N(hex, 8))
     65 local bad_escape = T("bad_escape", P"\\" * any)
     66 
     67 local charlit_text = T("charlit_text", (any - vws - S"'\\")^1)
     68 local charlit_prefix = T("charlit_delim", P"u8" + P"u" + P"U" + P"L")
     69 local charlit_delim = T("charlit_delim", P"'")
     70 local charlit = charlit_prefix^-1 * charlit_delim
     71 	* (charlit_text + escape + bad_escape)^0 * charlit_delim
     72 
     73 local strlit_format_param = dec^1 * P"$"
     74 local strlit_format = T("strlit_format", P"%"
     75 	* strlit_format_param^-1
     76 	* S"-+ 0'#"^0                                           -- flags
     77 	* (R"19" * dec^0 + (P"*" * strlit_format_param^-1))^-1  -- width
     78 	* (P"." * (P"*" * strlit_format_param^-1 + dec^0))^-1   -- precision
     79 	* (S"Lhjltz" + P"hh" + P"ll")^-1                        -- length
     80 	* S"%diuoxXeEfFgGaAcspn")                               -- type
     81 local strlit_text = T("strlit_text", (any - vws - S"\"\\" - strlit_format)^1)
     82 local strlit_prefix = T("strlit_delim", P"u8" + P"u" + P"U" + P"L")
     83 local strlit_delim = T("strlit_delim", P"\"")
     84 local strlit = strlit_prefix^-1 * strlit_delim
     85 	* (strlit_text + strlit_format + escape + bad_escape)^0 * strlit_delim
     86 
     87 local delimiter = T("delimiter", S"(){};,\\")
     88 
     89 local operator = T("operator", S"+-*/%!&|^~<=>?:.[]" + P"sizeof" + P"_Alignof" + P"alignof")
     90 
     91 local preproc_cond = T("preproc_cond", P"#") * T("whitespace", hws^0)
     92 	* T("preproc_cond", P"ifdef" + P"ifndef" + P"if" + P"elif" + P"else" + P"endif")
     93 local preproc_def = T("preproc", P"#") * T("whitespace", hws^0)
     94 	* T("preproc", P"define") * T("whitespace", hws^0)
     95 	* (T("function", word) * #P"(" + T("identifier", word))
     96 local preproc_inc = T("preproc", P"#") * T("whitespace", hws^0)
     97 	* T("preproc", P"include") * (
     98 		  T("whitespace", hws^0)
     99 		* T("strlit_delim", P"<")
    100 		* T("strlit_text", (any - vws - P">")^0)
    101 		* T("strlit_delim", P">")
    102 	)^-1
    103 local preproc_other = T("preproc", P"#") * T("whitespace", hws^0)
    104 	* T("preproc", P"undef" + P"pragma" + P"include" + P"error" + P"warning" + P"line" + P"version")
    105 local preproc = preproc_cond + preproc_def + preproc_inc + preproc_other + T("preproc", "#")
    106 
    107 local keyword = T("keyword", l.word_match{
    108 	-- Storage classes
    109 	"extern", "static", "auto", "register", "_Thread_local",
    110 	"thread_local",  -- <threads.h>
    111 
    112 	-- Type qualifiers
    113 	"const", "restrict", "volatile", "_Atomic",
    114 
    115 	-- Function specifier
    116 	"inline", "_Noreturn",
    117 	"noreturn",  -- <stdnoreturn.h>
    118 
    119 	-- Control flow
    120 	"return", "break", "continue", "goto",
    121 	"if", "else",
    122 	"switch", "case","default",
    123 	"do", "while", "for",
    124 
    125 	-- Misc
    126 	"typedef", "_Alignas", "_Generic", "_Static_assert",
    127 	"alignas",  -- <stdalign.h>
    128 	"static_assert",  -- <assert.h>
    129 
    130 	-- GNU
    131 	"__typeof__", "typeof",
    132 	"__attribute__",
    133 	"__asm__", "asm",
    134 
    135 	-- rcx macros
    136 	"likely", "unlikely",
    137 	"unreachable",
    138 
    139 	-- GLSL
    140 	"in", "out", "inout", "layout",
    141 	"uniform", "buffer", "shared",
    142 	"lowp", "mediump", "highp", "precision",
    143 	"coherent", "readonly", "writeonly",
    144 })
    145 
    146 local constant = T("constant", l.word_match{
    147 	-- Very special constants only.
    148 	"__DATE__", "__FILE__", "__LINE__", "__TIME__", "__func__",
    149 	"__VA_ARGS__",
    150 	"NULL",
    151 	"true", "false",  -- <stdbool.h>
    152 })
    153 
    154 local type_builtin = l.word_match{
    155 	"void",
    156 	"_Bool", "char", "int", "float", "double",
    157 	"bool",  -- <stdbool.h>
    158 	"short", "long",
    159 	"signed", "unsigned",
    160 	"_Complex", "_Imaginary",
    161 	"complex", "imaginary",  -- <complex.h>
    162 	"struct", "union", "enum",
    163 }
    164 local type_std = l.word_match{
    165 	"ptrdiff_t", "size_t", "ssize_t", "max_align_t", "wchar_t",
    166 }
    167 local type_stdint = P"u"^-1 * P"int" * ((P"_least" + P"_fast")^-1 * dec^1 + P"max" + P"ptr") * P"_t" * #(any - letter)
    168 local type_nice = P"__"^-1 * (P"v" * dec^1)^-1 * S"usifc" * dec^1 * (P"a" * dec^1)^-1 * P"_t"^-1 * #(any - letter) + l.word_match{
    169 	"schar", "uchar", "ushort", "uint", "ulong", "llong", "ullong",
    170 }
    171 local type_rcx = (S"iu" * (P"max" + P"ptr" + P"size") + P"rune" + P"maxalign") * #(any - letter)
    172 local type_glsl = (
    173 		S"buid"^-1 * P"vec" * R"24" +
    174 		S"d"^-1 * P"mat" * R"24" * (P"x" * R"24")^-1 +
    175 		(S"ui"^-1 * (P"sampler" + P"image") + P"image") * (
    176 				P"1D" + P"2D" + P"3D" + P"Cube" + P"2DRect" + P"1DArray" +
    177 				P"2DArray" + P"CubeArray" + P"Buffer" + P"2DMS" + P"2DMSArray"
    178 			) +
    179 		P"sampler" * (
    180 				P"1D" + P"2D" + P"Cube" + P"2DRect" +
    181 				P"1DArray" + P"2DArray" + P"CubeArray"
    182 			) * P"Shadow" +
    183 		P"atomic_uint"
    184 	) * #(any - letter)
    185 local type_ = T("type", type_builtin + type_std + type_stdint + type_nice + type_rcx + type_glsl)
    186 
    187 local label = T("whitespace", hws^0) * T("label", word) * T("delimiter", P":")
    188 
    189 --local function_ = T("function", word) * T("whitespace", ws^0) * #P"("
    190 local function_ = T("function", word) *  #P"("
    191 
    192 local identifier = T("identifier", word)
    193 
    194 M._rules = {
    195 	{"whitespace", whitespace},
    196 	{"comment", comment},
    197 	{"numlit", numlit},
    198 	{"charlit", charlit},
    199 	{"strlit", strlit},
    200 	{"delimiter", delimiter},
    201 	{"operator", operator},
    202 	{"preproc", preproc},
    203 	{"keyword", keyword},
    204 	{"constant", constant},
    205 	{"type", type_},
    206 	{"label", label},
    207 	{"function", function_},
    208 	{"identifier", identifier},
    209 
    210 	{"error", T("error", any)},  -- TODO: TEMP
    211 }
    212 
    213 M._tokenstyles = {
    214 	whitespace = l.STYLE_WHITESPACE,
    215 
    216 	comment_text = l.STYLE_COMMENT,
    217 	comment_keyword = l.STYLE_COMMENT_KEYWORD,
    218 
    219 	numlit = l.STYLE_NUMBER,
    220 
    221 	escape = l.STYLE_ESCAPE,
    222 	bad_escape = l.STYLE_ERROR,
    223 
    224 	charlit_delim = l.STYLE_NUMBER,
    225 	charlit_text = l.STYLE_NUMBER,
    226 
    227 	strlit_delim = l.STYLE_STRING,
    228 	strlit_text = l.STYLE_STRING,
    229 	strlit_format = l.STYLE_STRING_FORMAT,
    230 
    231 	delimiter = l.STYLE_DELIMITER,
    232 	operator = l.STYLE_OPERATOR,
    233 
    234 	preproc = l.STYLE_PREPROCESSOR,
    235 	preproc_cond = l.STYLE_PREPROCESSOR_CONDITIONAL,
    236 
    237 	keyword = l.STYLE_KEYWORD,
    238 	constant = l.STYLE_CONSTANT,
    239 	["type"] = l.STYLE_TYPE,
    240 	label = l.STYLE_LABEL,
    241 	["function"] = l.STYLE_FUNCTION,
    242 	identifier = l.STYLE_IDENTIFIER,
    243 }
    244 
    245 return M