@@ -279,19 +279,35 @@ func (op Token) Precedence() int {
279279 return LowestPrec
280280}
281281
282- var keywords map [ string ]Token
282+ var keywords [ 256 ]Token
283283
284284func init () {
285- keywords = make (map [string ]Token , keyword_end - (keyword_beg + 1 ))
286285 for i := keyword_beg + 1 ; i < keyword_end ; i ++ {
287- keywords [tokens [ i ] ] = i
286+ keywords [keywordsIndex ( i . String ()) ] = i
288287 }
289288}
290289
290+ // keywordsIndex maps an identifier to an index in keywords array.
291+ func keywordsIndex (maybeKeyword string ) uint8 {
292+ if len (maybeKeyword ) <= 3 {
293+ if len (maybeKeyword ) == 0 {
294+ return 0
295+ }
296+ return maybeKeyword [0 ]
297+ }
298+ v0 := maybeKeyword [0 ]
299+ v1 := maybeKeyword [1 ]
300+ v2 := maybeKeyword [2 ]
301+ v3 := maybeKeyword [3 ]
302+ h := v0 + v1 * 8 + v2 - v3
303+ return h
304+ }
305+
291306// Lookup maps an identifier to its keyword token or [IDENT] (if not a keyword).
292307func Lookup (ident string ) Token {
293- if tok , is_keyword := keywords [ident ]; is_keyword {
294- return tok
308+ maybeMatch := keywords [keywordsIndex (ident )]
309+ if maybeMatch != 0 && maybeMatch .String () == ident {
310+ return maybeMatch
295311 }
296312 return IDENT
297313}
@@ -319,10 +335,9 @@ func IsExported(name string) bool {
319335}
320336
321337// IsKeyword reports whether name is a Go keyword, such as "func" or "return".
322- func IsKeyword (name string ) bool {
323- // TODO: opt: use a perfect hash function instead of a global map.
324- _ , ok := keywords [name ]
325- return ok
338+ func IsKeyword (ident string ) bool {
339+ tok := keywords [keywordsIndex (ident )]
340+ return tok != 0 && tok .String () == ident
326341}
327342
328343// IsIdentifier reports whether name is a Go identifier, that is, a non-empty
0 commit comments