Class: Gruesome::Z::Dictionary

Inherits:
Object
  • Object
show all
Defined in:
lib/gruesome/z/dictionary.rb

Instance Method Summary collapse

Constructor Details

#initialize(memory) ⇒ Dictionary

Returns a new instance of Dictionary.



14
15
16
17
18
19
20
21
# File 'lib/gruesome/z/dictionary.rb', line 14

def initialize(memory)
  @memory = memory
  @header = Header.new(@memory.contents)

  @abbreviation_table = AbbreviationTable.new(@memory)

  @lookup_cache = {}
end

Instance Method Details

#addressObject



23
24
25
# File 'lib/gruesome/z/dictionary.rb', line 23

def address
  @header.dictionary_addr
end

#address_of_entriesObject



27
28
29
30
31
32
33
34
35
# File 'lib/gruesome/z/dictionary.rb', line 27

def address_of_entries
  addr = self.address
  num_input_codes = @memory.force_readb(addr)
  addr += 1
  addr += num_input_codes
  addr += 3

  addr
end

#entry_lengthObject



37
38
39
40
# File 'lib/gruesome/z/dictionary.rb', line 37

def entry_length
  addr = self.address_of_entries - 3
  return @memory.force_readb(addr)
end

#lookup_word(token) ⇒ Object



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/gruesome/z/dictionary.rb', line 70

def lookup_word(token)
  if token.length > 6 and @header.version <= 3
    token = token[0..5]
  elsif token.length > 9
    token = token[0..8]
  end
  cached_index = @lookup_cache[token]
  if cached_index != nil
    if self.word(cached_index) == token
      return cached_index
    end
  end

  number_of_words.times do |i|
    if word(i) == token
      cached_index = i
      break
    end
  end
  
  cached_index
end

#number_of_wordsObject



42
43
44
45
# File 'lib/gruesome/z/dictionary.rb', line 42

def number_of_words
  addr = self.address_of_entries - 2
  return @memory.force_readw(addr)
end

#parse(tokens) ⇒ Object



140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/gruesome/z/dictionary.rb', line 140

def parse(tokens)
  ret = []
  tokens.each do |token|
    index = lookup_word(token[:string])
    if index != nil
      addr = word_address(index)
    else
      addr = 0
    end
    ret << { :size => token[:string].size, :address => addr, :position => token[:position] }
  end

  ret
end

#tokenize(line) ⇒ Object



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/gruesome/z/dictionary.rb', line 113

def tokenize(line)
  orig_line = line

  # I. ensure that word separators are surrounded by spaces
  self.word_separators.each do |sep|
    line = line.gsub(sep, " " + sep + " ")
  end

  # II. break up the line into words delimited by spaces
  tokens = line.split(' ')

  line = orig_line
  last_pos = 0
  ret = tokens.map do |token|
    index = line.index(token)
    line = line[index+token.size..-1]

    index = index + last_pos
    last_pos = index + token.size

    index
    { :position => index, :string => token }
  end
  
  ret
end

#word(index) ⇒ Object



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/gruesome/z/dictionary.rb', line 54

def word(index)
  addr = word_address(index)

  codes = nil

  if @header.version <= 3
    codes = @memory.force_readzstr(addr, 4)[1]
  else
    codes = @memory.force_readzstr(addr, 6)[1]
  end

  str = ZSCII.translate(0, @header.version, codes, @abbreviation_table)
  @lookup_cache[str] = index
  return str
end

#word_address(index) ⇒ Object



47
48
49
50
51
52
# File 'lib/gruesome/z/dictionary.rb', line 47

def word_address(index)
  addr = address_of_entries
  addr += entry_length * index

  return addr
end

#word_separatorsObject



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/gruesome/z/dictionary.rb', line 93

def word_separators
  addr = self.address

  # the number of word separators
  num_input_codes = @memory.force_readb(addr)
  addr += 1

  codes = []
  num_input_codes.times do
    codes << @memory.force_readb(addr)
    addr += 1
  end

  codes = codes.map do |i|
    ZSCII.translate_Zchar(i)
  end

  return codes
end