An Erlang lexer and syntax highlighter in Gleam

Lex variables

+75 -37
+75 -37
src/pearl.gleam
··· 161 161 | "y" as char <> source 162 162 | "z" as char <> source -> lex_atom(advance(lexer, source), char) 163 163 164 + "A" as char <> source 165 + | "B" as char <> source 166 + | "C" as char <> source 167 + | "D" as char <> source 168 + | "E" as char <> source 169 + | "F" as char <> source 170 + | "G" as char <> source 171 + | "H" as char <> source 172 + | "I" as char <> source 173 + | "J" as char <> source 174 + | "K" as char <> source 175 + | "L" as char <> source 176 + | "M" as char <> source 177 + | "N" as char <> source 178 + | "O" as char <> source 179 + | "P" as char <> source 180 + | "Q" as char <> source 181 + | "R" as char <> source 182 + | "S" as char <> source 183 + | "T" as char <> source 184 + | "U" as char <> source 185 + | "V" as char <> source 186 + | "W" as char <> source 187 + | "X" as char <> source 188 + | "Y" as char <> source 189 + | "Z" as char <> source 190 + | "_" as char <> source -> lex_variable(advance(lexer, source), char) 191 + 164 192 "\"" <> source -> lex_string(advance(lexer, source), "") 165 193 "'" <> source -> lex_quoted_atom(advance(lexer, source), "") 166 194 ··· 227 255 } 228 256 } 229 257 230 - fn lex_atom(lexer: Lexer, lexed: String) -> #(Lexer, Token) { 258 + fn lex_variable_or_atom(lexer: Lexer, lexed: String) -> #(Lexer, String) { 231 259 case lexer.source { 232 260 "a" as char <> source 233 261 | "b" as char <> source ··· 292 320 | "8" as char <> source 293 321 | "9" as char <> source 294 322 | "_" as char <> source 295 - | "@" as char <> source -> lex_atom(advance(lexer, source), lexed <> char) 323 + | "@" as char <> source -> 324 + lex_variable_or_atom(advance(lexer, source), lexed <> char) 296 325 297 - _ -> { 298 - let token = case lexed { 299 - "after" -> token.After 300 - "begin" -> token.Begin 301 - "case" -> token.Case 302 - "catch" -> token.Catch 303 - "cond" -> token.Cond 304 - "else" -> token.Else 305 - "end" -> token.End 306 - "fun" -> token.Fun 307 - "if" -> token.If 308 - "let" -> token.Let 309 - "maybe" -> token.Maybe 310 - "of" -> token.Of 311 - "receive" -> token.Receive 312 - "try" -> token.Try 313 - "when" -> token.When 314 - "bnot" -> token.Bnot 315 - "div" -> token.Div 316 - "rem" -> token.Rem 317 - "band" -> token.Band 318 - "bor" -> token.Bor 319 - "bxor" -> token.Bxor 320 - "bsl" -> token.Bsl 321 - "bsr" -> token.Bsr 322 - "not" -> token.Not 323 - "and" -> token.And 324 - "or" -> token.Or 325 - "xor" -> token.Xor 326 - "andalso" -> token.Andalso 327 - "orelse" -> token.Orelse 326 + _ -> #(lexer, lexed) 327 + } 328 + } 328 329 329 - _ -> token.Atom(lexed, False) 330 - } 331 - #(lexer, token) 332 - } 330 + fn lex_variable(lexer: Lexer, char: String) -> #(Lexer, Token) { 331 + let #(lexer, name) = lex_variable_or_atom(lexer, char) 332 + #(lexer, token.Variable(name)) 333 + } 334 + 335 + fn lex_atom(lexer: Lexer, char: String) -> #(Lexer, Token) { 336 + let #(lexer, name) = lex_variable_or_atom(lexer, char) 337 + 338 + let token = case name { 339 + "after" -> token.After 340 + "begin" -> token.Begin 341 + "case" -> token.Case 342 + "catch" -> token.Catch 343 + "cond" -> token.Cond 344 + "else" -> token.Else 345 + "end" -> token.End 346 + "fun" -> token.Fun 347 + "if" -> token.If 348 + "let" -> token.Let 349 + "maybe" -> token.Maybe 350 + "of" -> token.Of 351 + "receive" -> token.Receive 352 + "try" -> token.Try 353 + "when" -> token.When 354 + "bnot" -> token.Bnot 355 + "div" -> token.Div 356 + "rem" -> token.Rem 357 + "band" -> token.Band 358 + "bor" -> token.Bor 359 + "bxor" -> token.Bxor 360 + "bsl" -> token.Bsl 361 + "bsr" -> token.Bsr 362 + "not" -> token.Not 363 + "and" -> token.And 364 + "or" -> token.Or 365 + "xor" -> token.Xor 366 + "andalso" -> token.Andalso 367 + "orelse" -> token.Orelse 368 + 369 + _ -> token.Atom(name, False) 333 370 } 371 + #(lexer, token) 334 372 } 335 373 336 374 fn lex_until_end_of_line(lexer: Lexer) -> #(Lexer, String) {