//[of]:license //[c] Code Browser - a folding text editor for programmers //[c] Copyright (C) 2003-07 Marc Kerbiquet //[c] //[c] This program is free software; you can redistribute it and/or modify //[c] it under the terms of the GNU General Public License as published by //[c] the Free Software Foundation; either version 2 of the License, or //[c] (at your option) any later version. //[c] //[c] This program is distributed in the hope that it will be useful, //[c] but WITHOUT ANY WARRANTY; without even the implied warranty of //[c] MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //[c] GNU General Public License for more details. //[c] //[c] You should have received a copy of the GNU General Public License //[c] along with this program; if not, write to the Free Software //[c] Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //[cf] //[of]:imports import "base/types" import "base/memory" import "base/memory-allocator" import "text/string" //[cf] //[c] //[of]:word dictionary //[of]:description //[c]Associates a state to a word //[cf] //[of]:definition //[c] public struct word dictionary private match case : bool private compare function : {mem, mem, size} int private number of items : size private table : [array size] word item end //[cf] //[c] //[of]:initialize - release //[of]:initialize (m, case sensitive) //[c]Initializes a word dictionary //[c] //[c]ARGUMENTS //[c] m - the word dictionary to initialize //[c] match case - searches will be case sensitive //[c] public func initialize (m: word dictionary, match case: bool) number of items (m) = 0 match case (m) = match case compare function (m) = (match case -> ^compare (mem, mem, size), ^compare no case (string, string, size) ) def i = 0 while i < array size table (m) [i] = nil ++ i end end //[cf] //[of]:initialize (m, case sensitive, [] word dictionary pair) //[c]Initializes a word dictionary with a list of key-value pairs //[c] //[c]ARGUMENTS //[c] m - the word dictionary to initialize //[c] match case - searches will be case sensitive //[c] pairs - the list of static key-value pairs //[c] public func initialize ( m: word dictionary, match case: bool, pairs: [] local word dictionary pair) initialize (m, match case) def p = pairs repeat def word = key (p[]) def state = code (p[]) if is nil (word) return end add (m, word, state) ++ p end end //[cf] //[of]:release (m) //[c] public func release (m: word dictionary) each slot (m) ? item def i = item while not nil (i) def next = next (i) delete (i) i = next end end end //[cf] //[cf] //[of]:adding - removing //[of]:add (m, string, state) //[c]Adds a pair of word -> state //[c] public func add (m: word dictionary, s: string, state: int) def slot = slot (m, s) def item = allocate memory (sizeof local word item) : word item next (item) = table (m) [slot] size (item) = size (s) state (item) = state id (item) = new string (s) table (m) [slot] = item ++ number of items (m) end //[cf] //[cf] //[of]:accessing //[of]:size (m) //[c] public equ size (m: word dictionary) = number of items (m) //[cf] //[of]:state (m, string, size) //[c]Test if a word is in the dictionary //[c]Returns the associated state or -1 if not found //[c] public func state (m: word dictionary, s: string, n: size) def item = table (m) [slot (m, s)] while not nil (item) if n == size (item) && (compare function (m) {s, id (item), n} == 0) return state (item) end item = next (item) end return -1 end //[cf] //[cf] //[of]:testing //[of]:is empty (m) //[c] public equ is empty (m: word dictionary) = number of items (m) == 0 //[cf] //[of]:not empty (m) //[c] public equ not empty (m: word dictionary) = number of items (m) <> 0 //[cf] //[cf] //[c] //[of]:private //[of]:constants //[c] //[c]Size of the hash table; must be a power of two //[c] equ array size = 256 //[cf] //[c] //[of]:each slot (m) //[c]Enumerate the array //[c] equ each slot (m: word dictionary) def i = 0 while i < array size def item = table (m) [i] yield (item) ++ i end end //[cf] //[of]:slot (m, string) //[c]Returns the slot for a string //[c] equ slot (m: word dictionary, s: string) = // cast to unsigned 8 bits before extending to int // to not propagate sign (match case (m) -> s[0], upper(s[0])) : byte : int //[cf] //[cf] //[cf] //[of]:word dictionary pair //[of]:definition //[c]Word dictionary pair is used only to initialize a dictionary //[c]with a list of pairs. //[c] public struct word dictionary pair key : string code : int end //[cf] //[cf] //[c] //[c]private: //[of]:word item //[of]:definition //[c] private struct word item next : word item size : size id : string state : int // anything but -1 end //[cf] //[c] //[of]:delete (m) //[c] func delete (m: word item) delete (id (m)) free memory (m) end //[cf] //[cf]