Microsoft Small Basic

Program Listing: BKM132-2
' Word List 1.1
' Copyright © 2010-2017 Nonki Takahashi. The MIT License.
'
' History:
' 1.1 2017-04-16 Usage changed to allow argument (BKM132-2)
' 1.0 2017-04-15 Changed not to input full path (BKM132-1)
' 0.9 2014-05-13 Translated to English (209 lines, BKM132-0)
' 0.8 2010-06-29 Added operator to delimiter (208 lines)
' 0.7 2010-06-23 Removed performance test, rewrote comments (205 lines, BKM132)
' 0.6 2010-06-14 Performance upgrade (313 lines, program ID HBQ757)
' 0.5 2010-06-12 Added performance test (232 lines, program ID XLQ213)
' 0.4 2010-06-10 Completed (175 lines, program ID XFX546)
' 0.3 2010-06-09 Output word list (111 lines, program ID LDG385)
' 0.2 2010-05-05 Under debbuging (37 lines)
' 0.1 2010-05-05 Initial version: only pseudo code (11 lines)

' initialize variables
Init()
' read a line from input file
ReadLine()
' repeat the indented block until EOF comes
While Not[eof]
' write the line with line number
TextWindow.WriteLine(lno + " " + line)
' get separator between words from line
GetSeparator()
' get a word from line
GetWord()
' repeat the indented block until EOL comes
While word <> ""
' register given word to the word list
InsertWordList()
' get separator between words from line
GetSeparator()
' get a word from line
GetWord()
EndWhile
' count up line number
lno = lno + 1
' read a line from input file
ReadLine()
EndWhile
' print the word list
PrintWordList()

Sub CompareWord
' Compare word with wordlist[i]
' param word
' param wordlist - array for word list
' param i - index to the word list
' work k - character position in the word to compare
' work l, l1, l2 - length of words to compare
' work w1, w2 - words to compare
' work c1, c2 - characters to compare
' return cwresult - result: ">", "=" or "<"
w1 = Text.ConvertToLowerCase(word)
w2 = Text.ConvertToLowerCase(wordlist[i])
l1 = Text.GetLength(w1)
l2 = Text.GetLength(w2)
l = Math.Min(l1, l2)
cwresult = ""
For k = 1 To l
c1 = Text.GetCharacterCode(Text.GetSubText(w1, k, 1))
c2 = Text.GetCharacterCode(Text.GetSubText(w2, k, 1))
If (c1 > c2) Then
cwresult = ">"
k = l ' exit For
ElseIf (c1 < c2) Then
cwresult = "<"
k = l ' exit For
EndIf
EndFor
If cwresult <> "" Then
If (l1 > l2) Then
cwresult = ">"
ElseIf (l1 < l2) Then
cwresult = "<"
Else
cwresult = "="
EndIf
EndIf
EndSub

Sub GetSeparator
' Get separator between words in line
' param line
' param delim - delimiters
' work s - separator
' work space - "True" if there is space, tab or other delimiters
' work isDelim - "True" if the next character may delimiter
' return separator
separator = ""
space = "False"
isDelim = "True"
While (line <> "") And isDelim
s = Text.GetSubText(line, 1, 1)
While (s = " ") Or (s = TAB)
line = Text.GetSubText(line, 2, Text.GetLength(line) - 1)
s = Text.GetSubText(line, 1, 1)
space = "True"
EndWhile
If Text.IsSubText(delimwosp, s) Then
line = Text.GetSubText(line, 2, Text.GetLength(line) - 1)
separator = separator + s
Else
isDelim = "False" ' exit While
EndIf
EndWhile
If (separator = "") And space Then
separator = " "
EndIf
EndSub

Sub GetWord
' Get word from line
' param line
' param delim - delimiters
' work c - character
' work isDelim - "True" if the next character may delimiter
' return line - remaining characters in the line
' return word
word = ""
isDelim = "False"
While (line <> "") And Not[isDelim]
c = Text.GetSubText(line, 1, 1)
If Text.IsSubText(delim, c) Then
isDelim = "True" ' exit While
Else
line = Text.GetSubText(line, 2, Text.GetLength(line) - 1)
word = word + c
EndIf
EndWhile
EndSub

Sub Init
' Initialization
' array instead not operator
Not = "False=True;True=False;"
' character code for tab
TAB = Text.GetCharacter(9)
' character code for double quotation mark
WQ = Text.GetCharacter(34)
' delimiter w/o and w/ space
delimwosp = ",;:." + WQ + "()[]<>+-*/="
delim = " " + TAB + delimwosp
' initialze word list pointer
ptr[0] = 1
' get filename from keyboard
If 0 < Program.ArgumentCount Then
filename = Program.GetArgument(1)
If filename = "/?" Then
TextWindow.WriteLine("Usage:")
TextWindow.WriteLine("WordList [filename]")
TextWindow.Pause()
Program.End()
EndIf
Else
TextWindow.Write("Filename? ")
filename = TextWindow.Read()
EndIf
If Not[Text.IsSubText(filename, "\")] Then
filename = Program.Directory + "\" + filename
EndIf
' initialize line number
lno = 1
' initialize word number
wno = 0
' initialize variables for eof
' The following line could be harmful and has been automatically commented.
' len = Text.GetLength(File.ReadContents(filename))
eof = "False"
EndSub

Sub InsertWordList
' Insert a word to the word list
' param word
' param ptr - pointer to the next entry in word list
' param wordlist - array for word list
' param lnolist - array for line number list
' param wno - registered number of words
' work lastptr - pointer to the previous entry
' work currentptr - pointer to the current entry
' work i - index for word list
' work j - counter for entry
' return ptr - updated pointer to next entry in word list
' return wordlist - updated array for word list
' return lnolist - updated array for line number list
' return wno - updated number of words
lastptr = 0
currentptr = ptr[lastptr]
For j = 1 To wno
i = currentptr
' compare word and wordlist[i]
CompareWord()
' if word < wordlist[i] then
If cwresult = "<" Then
j = wno ' exit For
Else
lastptr = currentptr
currentptr = ptr[lastptr]
EndIf
EndFor
' insert word and line number at index i
wno = wno + 1
ptr[lastptr] = wno
ptr[wno] = currentptr
wordlist[wno] = word
lnolist[wno] = lno
EndSub

Sub PrintWordList
' Print word list to display (text window)
' param ptr - pointer to the next entry in word list
' param wordlist - array for word list
' param lnolist - array for line number list
' param wno - registered number of words
' work i - index to word list
' work j - counter for entry
' work currentword
' work lower - word converted into lower case letters
' work lastptr - pointer to the previous entry in word list
' word currentptr - pointer to the current entry
lastptr = 0
currentptr = ptr[lastptr]
currentword = ""
For j = 1 To wno
i = currentptr
lower = Text.ConvertToLowerCase(wordlist[i])
If lower = currentword Then
' output only line numbers while continuing the current word
TextWindow.Write(", " + lnolist[i])
Else
' output word ... line number when new word appears
TextWindow.WriteLine("")
TextWindow.Write(wordlist[i] + " ... " + lnolist[i])
currentword = lower
EndIf
lastptr = currentptr
currentptr = ptr[lastptr]
EndFor
TextWindow.WriteLine("")
EndSub

Sub ReadLine
If len <= _len Then
eof = "True"
line = ""
Else
' The following line could be harmful and has been automatically commented.
' line = File.ReadLine(filename, lno)
_len = _len + Text.GetLength(line) + 2
EndIf
EndSub