@@ -14,11 +14,10 @@ import (
1414
1515// A Dictionary entry. Contains the name, the word itself, and the flags.
1616type DictionaryEntry struct {
17- Name string
18- NameLower string
19- ulpName string // the name we're going to compile this to
20- Word Word
21- Flag Flag
17+ Name string
18+ ulpName string // the name we're going to compile this to
19+ Word Word
20+ Flag Flag
2221}
2322
2423func (d DictionaryEntry ) String () string {
@@ -44,13 +43,15 @@ func (d *DictionaryEntry) BodyLabel() string {
4443// The Forth Dictionary. This architecture uses individual entries
4544// representing words rather than a flat cell structure.
4645type Dictionary struct {
47- Entries []* DictionaryEntry
48- vm * VirtualMachine
46+ Entries []* DictionaryEntry
47+ vm * VirtualMachine
48+ entryMap map [string ][]* DictionaryEntry
4949}
5050
5151// Set up the empty dictionary.
5252func (d * Dictionary ) Setup (vm * VirtualMachine ) error {
5353 d .Entries = make ([]* DictionaryEntry , 0 )
54+ d .entryMap = make (map [string ][]* DictionaryEntry )
5455 d .vm = vm
5556 return nil
5657}
@@ -66,20 +67,37 @@ func (d *Dictionary) AddEntry(entry *DictionaryEntry) error {
6667 fmt .Fprintf (d .vm .Out , "Redefining %s " , name )
6768 }
6869 }
69- entry . NameLower = strings . ToLower (name )
70+ lower := d . standardizeName (name )
7071 d .Entries = append (d .Entries , entry )
72+ lst , ok := d .entryMap [lower ]
73+ if ! ok {
74+ lst = make ([]* DictionaryEntry , 0 )
75+ }
76+ lst = append (lst , entry )
77+ d .entryMap [lower ] = lst
7178 return nil
7279}
7380
81+ // standardizeName takes in the name of a word and
82+ // returns the standardized version. Currently this is
83+ // the lower case version for case-insensitivity but
84+ // it could be changes to a case-sensitive meaning.
85+ func (d * Dictionary ) standardizeName (name string ) string {
86+ return strings .ToLower (name )
87+ }
88+
7489func (d * Dictionary ) FindName (name string ) (* DictionaryEntry , error ) {
7590 if d .Entries == nil {
7691 return nil , fmt .Errorf ("Dictionary not set up when finding name, please file a bug report." )
7792 }
78- nameLower := strings .ToLower (name ) // case insensitive finding
79- for i := len (d .Entries ) - 1 ; i >= 0 ; i -- {
80- entry := d .Entries [i ]
81- if ! entry .Flag .Hidden && entry .NameLower == nameLower {
82- return entry , nil
93+ nameLower := d .standardizeName (name )
94+ same , ok := d .entryMap [nameLower ]
95+ if ok {
96+ for i := len (same ) - 1 ; i >= 0 ; i -- {
97+ entry := same [i ]
98+ if ! entry .Flag .Hidden {
99+ return entry , nil
100+ }
83101 }
84102 }
85103 return nil , fmt .Errorf ("%s not found in dictionary." , name )
0 commit comments