summaryrefslogtreecommitdiff
path: root/ipl/packs/idol/buffer.iol
blob: 52cb4f77b0499702059a490e247c1b333950a207 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
class buffer(public filename,text,index)
  # read a buffer in from a file
  method read()
    f := open(self.filename,"r") | fail
    self$erase()
    every put(self.text,!f)
    close(f)
    return
  end
  # write a buffer out to a file
  method write()
    f := open(self.filename,"w") | fail
    every write(f,!self.text)
    close(f)
  end
  # insert a line at the current index
  method insert(s)
    if self.index = 1 then {
      push(self.text,s)
    } else if self.index > *self.text then {
      put(self.text,s)
    } else {
      self.text := self.text[1:self.index]|||[s]|||self.text[self.index:0]
    }
    self.index +:= 1
    return
  end
  # delete a line at the current index
  method delete()
    if self.index > *self.text then fail
    rv := self.text[self.index]
    if self.index=1 then pull(self.text)
    else if self.index = *self.text then pop(self.text)
    else self.text := self.text[1:self.index]|||self.text[self.index+1:0]
    return rv
  end
  # move the current index to an arbitrary line
  method goto(l)
    if (1 <= l) & (l <= *self.text+1) then return self.index := l
  end
  # return the current line and advance the current index
  method forward()
    if self.index > *self.text then fail
    rv := self.text[self.index]
    self.index +:= 1
    return rv
  end
  # place the buffer's text into a contiguously allocated list
  method linearize()
    tmp := list(*self.text)
    every i := 1 to *tmp do tmp[i] := self.text[i]
    self.text := tmp
  end
  method erase()
    self.text     := [ ]
    self.index    := 1
  end
  method size()
    return *(self.text)
  end
initially
  if \ (self.filename) then {
    if not self$read() then self$erase()
  } else {
    self.filename := "*scratch*"
    self.erase()
  }
end


class buftable : buffer()
  method read()
    self$buffer.read()
    tmp := table()
    every line := !self.text do
      line ? { tmp[tab(many(&ucase++&lcase))] := line | fail }
    self.text := tmp
    return
  end
  method lookup(s)
    return self.text[s]
  end
end


class bibliography : buftable()
end


class spellChecker : buftable(parentSpellChecker)
  method spell(s)
    return \ (self.text[s]) | (\ (self.parentSpellChecker))$spell(s)
  end
end


class dictentry(word,pos,etymology,definition)
  method decode(s) # decode a dictionary entry into its components
    s ? {
      self.word       := tab(upto(';'))
      move(1)
      self.pos        := tab(upto(';'))
      move(1)
      self.etymology  := tab(upto(';'))
      move(1)
      self.definition := tab(0)
    }
  end
  method encode()  # encode a dictionary entry into a string
    return self.word||";"||self.pos||";"||self.etymology||";"||self.definition
  end
initially
  if /self.pos then {
    # constructor was called with a single string argument
    self$decode(self.word)
  }
end

class dictionary : buftable()
  method read()
    self$buffer.read()
    tmp := table()
    every line := !self.text do
      line ? { tmp[tab(many(&ucase++&lcase))] := dictentry(line) | fail }
    self.text := tmp
  end
  method write()
    f := open(b.filename,"w") | fail
    every write(f,(!self.text)$encode())
    close(f)
  end
end