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
|