lex.ha (1330B)
1 use lex; 2 use strings; 3 use strconv; 4 5 fn lexinit(in: str) lex::lexer = { 6 let actions: []lex::action = []; 7 8 append(actions, lex::action{ 9 expr = `([A-z][A-z0-9]+)`, 10 cb = &word, 11 name = "word", 12 ... 13 })!; 14 15 append(actions, lex::action{ 16 expr = `(-?[0-9]+)`, 17 cb = &number, 18 name = "word", 19 ... 20 })!; 21 22 append(actions, lex::action{ 23 expr = `\$([A-z][A-z0-9]+)`, 24 cb = &var, 25 name = "var", 26 ... 27 })!; 28 29 append(actions, lex::action{ 30 expr = `( |\t|\n|\r)+`, 31 cb = &skip, 32 ... 33 })!; 34 35 const backend = lex::def_backend()!(actions)!; 36 return lex::init(backend, in); 37 }; 38 39 fn word(sc: *lex::scanner, 40 lexeme: const str, 41 user: nullable *opaque 42 ) (str | *lex::token | lex::error) = { 43 44 let t = lex::scan_token(sc, void, lexeme)?; 45 t.value = t.morphene; 46 return t; 47 }; 48 49 fn var(sc: *lex::scanner, 50 lexeme: const str, 51 user: nullable *opaque 52 ) (str | *lex::token | lex::error) = { 53 54 let t = lex::scan_token(sc, void, lexeme)?; 55 t.value = strings::sub(t.morphene, 1); 56 return t; 57 }; 58 59 fn number(sc: *lex::scanner, 60 lexeme: const str, 61 user: nullable *opaque 62 ) (str | *lex::token | lex::error) = { 63 64 let t = lex::scan_token(sc, void, lexeme)?; 65 t.value = strconv::stoi64(t.morphene)!; 66 return t; 67 }; 68 69 fn skip(sc: *lex::scanner, 70 lexeme: const str, 71 user: nullable *opaque 72 ) (str | *lex::token | lex::error) = { 73 return lexeme; 74 }; 75