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