General Notes for Logflash Conversion
1.The break-up of the program into multiple source files is
arbitrary. Turbo-Pascal cannot handle more than 64K source, and
the totality of LogFlash source is much greater. Insert the other
files' source into the main program "LOGFLASH.PAS" at the {$I
filename} statements for each.
2.Other compile directives {$I-} disables I/O checking on the
indicated I/O procedure call. This prevents MS-DOS from aborting
on file I/O errors; instead it returns a status (which procedure
FILEIO checks).
3.File structures:
a. The input file is a text file editable by an outside editor.
It uses fixed length fields to easily enable data inspection
and input. It also is flexible; it allows the same file to be
used for input to LogFlash2, which will test and teach affixes.
1) LOGDATA.FLA (rawfile)
Format: sequential text file; no random access possible.
80 character length.
Line 1:
chars 1-5 number words in file, excluding control rcd.
chars 7-21 language name (blank defaults to LOGLAN).
chars 22-80 comments.
Other lines:
chars 1-6 Loglan word.
1 space
chars 8-19Affixes.
1 space
chars 21-35 English word.
1 space
chars 37-76 English explanation.
2) Lesson file (also sometimes called wordfile or filefile)
[name] + 1.FLA or NONAME1.FLA (if default).
Format: random access file with 1 control record and many
records of word data.
First record (control record - filefile):
sn integer session # init 1, incremented
as we go.
ty char session-type init C = gaining
Control
can be M =
Maintenance
B = Brush-up
ls integer last lesson# init 12 (failure
error)
forces next
lesson=13 (new wds)
ml integer "more lesson" lesson number of
current lesson pile
if it has move than
250 words. The
program updates the
file after a 250-
word partial lesson,
setting this flag.
So, if you stop and
restart it doesn't
screw up.
bg integer # new words lessons left
nr integer # records in file
wdcnt array[1-14] integer # words in each
lesson pile.
filelang string[15] language name from rawfile.
comments string[59] any comments from rawfile.
morecount integer # more done if this lesson has
ml flag set (more
words for this
lesson exist), this
tells how many parts
(@ 250 words per
part) have been
done.
dummy 393 bytes pad out record to total of 512
bytes.
Other records (word data - wordfile):
(6 words are packed in a record, with this format
for each word. Each word takes up 83 bytes,
leaving 14 spare at the end of the record (and
they are padded to make the record 512 bytes).
Word-subrecord:
lg/lw string[6] Loglan word (Loglan word to be typed
in)
en/ew string[15] English word (keyword to be typed
in)
es1/sp1 string[12] Affix data, or special data to go
with lg/lw
es2/sp2 string[40] expanded English definition to go
with en/ew
fp/pii integer current lesson number for word.
sr/lr integer word number in file; allows random
access to position directly to word
for file update.
ym integer if new word pile, this is the session
to introduce the word; otherwise,
it's the last session # the word was
tested in.
3) LOGWORK.FLA(Cassette file position)
Uses identical file record structure to #2's control record,
but only field sn is used. It contains an integer value
which points to the word in the rawfile (see #1) which was
saved at the end of a previous cassette review. The file is
recreated any time a new save is done. An I/O error will
terminate the program if no position was ever saved.
Only 1 LOGWORK.FLA can exist per disk, so only 1 position
can be saved. This makes sense since we will only be
sending one cassette per order. It makes copying the
program with cassette a little less friendly an option.
4.Much of the organization of the files and program structure is done
to minimize I/O reads & writes of the word files. This is slow by
any standard, and must be written for maximal efficiency. A
normal session has between 10 and 12 lessons actually tested.
This means 25 times reading the entire file (possibly more).
Running the program with a floppy-based data file is extremely
slow. The packed data file itself is over 100k, so it is not a
reasonable option to keep it in memory.
5.For modularity, any common procedure which opens the word file will
close the word file before returning. This ensures that the
processing starts at the beginning of the file and that the
correct format for the type of record is used.
6.The program was originally written in interactive BASIC, then
translated to Turbo-Pascal. We are left with a lot of two-letter
variables and some fragmented code because of this (also some
parenthetical references to line numbers). We had to maintain the
flow to be sure all loose ends were caught. In particular, the
procedure session (see later) was very complex, so structuring did
not work cleanly. It relies on null conditions, etc. So, please
test any rewrite, especially in this area, extremely thoroughly.
7.At least one change is planned for the future. When the textbook
is complete, we will have a set of lessons where we expect certain
words to have been introduced. We thus will add a setup menu
option to use the textbook-order for lessons. A 2-digit textbook-
lesson number will be on each line of the raw file to use in
assigning the initial session number for the new word lesson
(rather than a random one used in the present program).
We may also restructure at some point to:
a. Separate setup from the regular program or make it a Main
Menu option.
b. Create an umbrella program for all LogFlash programs with a
Main Menu for setup or run of any of the LogFlash programs.
We would like feedback on how these will affect your versions.
8.Please test your revisions thoroughly, since we can't. Errors will
give LogFlash a bad name.
9.It will be seen that LogFlash is currently designed as a generic
language program. While distributing a Loglan version, we are
attempting to hold rights to distribute a slightly modified
generic version as a tool for teaching other languages. The
proceeds from such a program would support Loglan. Our Shareware
license is specifically written to cover modifications to the code
to preserve our marketability. Please be considerate of our
intent, and, in distributing your work, enclose the license in any
distributions.
10. It should be explained that there are three learning modes in
LogFlash: "C" = Gaining Control, "M" = Maintenance, "B" = Brush-
up. The user starts out in "C", and can change to "M" whenever he
has no New Words left unseen. In "C", the Under Control words are
not tested. In "M", neither the New Words nor the Recog2 words are
tested. "B" mode is meant to be a quicker form of "C", so it does
test the New Words, but doesn't test Under Control or Recog2.
Notes on Data Items in Turbo-Pascal
type STRING maximum size is set by the type statement, so string[6]
has up to six bytes of character data. As stored on a
file, the string is prefixed by a 1-byte binary value
indicating the actual length of the item, but the max
length is always reserved in the record. So, even
though that string[6] may hold only three bytes of data,
on the file it takes up 7 bytes: 6 bytes for maximum
allowable length + 1 for the length-byte (which has a
value of 3).
type CHAR 1-byte ASCII data.
type INTEGER 2 bytes binary data (low order byte first, though this
shouldn't matter to you).
Order of Procedures In Files
LOGFLASH.PAS (main program, which will include all the others)
(include here LANGKEY.PAS, for receiving and processing key input)
langline Processing of special characters for some foreign
languages. Will be expanded in Logflash2 to handle
screen positioning for multiple inputs per screen.
(include here LANGIO.PAS, for handling I/O errors)
fileioProcess MS-DOS file errors to give some understandable
explanation of the problem.
(include here LANGMISC.PAS, procedures yanked out of main program
because of space problems. It includes mainly some common
routines and special routines done only at certain times.)
readchr Get a character from the keyboard and echo it.
upcases Set a string to all uppercase for comparison.
asksess At the end of a session, ask user if he wants another
session.
askless At the end of a lesson, ask user if he wants to
continue to the next lesson.
endrunClean up at end of run (includes ensuring control data is
updated). Normal termination.
resetfReset all words to new word pile. Effectively allows
user to start all over again like new.
regroup Regroup remaining New Word or Under Control words
(depending on session type) to mix words and even-out
lessons.
chgsess Change session type to Maintenance/Brush-Up if no new
words left.
newdone processing when all new words are done. Asks if user
wants to change to Maintenance, since all New Words have
been seen.
mix Pseudo-random mixing of the lesson words (in arr[]).
review Review of words at the start of New Word and Error lessons.
recprac Practice of Recog/Recall errors for each word until it is
correct 6 times consecutively.
update Updates the wordfile at the end of each lesson.
testreco Test recognition (Loglan prompt, English answer)
testreca Test recall (English prompt, Loglan answer)
getwds Select words for this lesson from word file.
getfdata Get session control information from control record in
word file (called filefile when accessing control record).
errpile Control for error word lesson. "Error" lessons are those
with even numbers for the lesson number.
goodpile control for regular (non-error) word lesson. Note that
the "Failure" pile is a regular lesson.
session Controlling procedure for full session of lessons 1-14.
(include here LANGFL1B.PAS, more procedures yanked out of main
program because of size limitations. It includes mainly some
common routines and the set-up menu processing.)
vocab Review of words (from raw file) to go along with the
cassette.
setfil1 Common processing for word file creation. It does the
formatting and writing of the control record for the
word file.
setfil2 More common processing for word file creation. This
one neatens up at the end for the last file record.
buildwd Control to build one word's data to lesson file
(wordfile) from the raw file.
buildfil Control building of file when selecting all raw-file
words for the user.
selctfil Control building of file when user is selecting
individual words to include.
setup Control setup-menu processing. Routes to the correct
procedure.
checkftot Check word pile counts vs a control total. Allows
automatic recovery from certain abnormal terminations
(such as power out) where the control record may not
have been updated properly. This has happened.
initvalues initialization at start of run.
main pgm Present summary of piles & main menu. Route based on
main menu selection.
System Routines - you may need to supply these if you have no
equivalent
randomize Set up random number generator.
clrscr Clear screen
gotoxy Position cursor to (column,row)
read Read non-text file.
write Write non-text file or, if screen, write text without CR.
readln Read text line.
writeln Write text line with CR.
clreol Clear from screen position to end of line.
(fileio) Must be redone to handle your machine's I/O errors. We
want to have a normal termination (not a bomb) when
possible. We also want user-friendly error messages when
files are missing, etc.
fillchar(x,y,z) fills a data area, x, with z, for a length of y
bytes.
delay(x) Delay x milliseconds, then continue.
odd(x) True if x, an integer, is odd. False if it is not.
upcase(x) x, a character, is made upper case.
pos(x,y) Function giving the starting position in string y of
string x. Zero if x not contained in y.
copy(x,y,z) Returns z characters from string x, starting at position
y.
length(x) Returns length of string x.
halt Stops program and returns to operating system.
keypressed Returns "true" if a key has been pressed.
random(x) Returns a random number between 0 and x.
sizeof(x) Returns the number of bytes reserved in memory for variable
x. So, for a string[6] storing 3 bytes of data, this will
return "6".
assign Links a real file name with a file variable name to be used
in the program.
rewrite Opens a file for output. To write a new file or overwrite
an existing file.
reset Opens a file for input & position to the beginning of the
file, or, for output, open an existing file.
seek(x,y) Position random file x to record number y (first record in
record number zero).
flush Ensure that last buffer-full of data has really been written
out to the file.
close Close file.
IOResult Returns a value based on the type of I/O error that has
occurred.
Detailed Structure of LOGFLASH1
Main program (last 2 pages of LOGFLASH.PAS)
Randomize: system routine to set up random number generator.
Initvalues: initialize pile counts.
Copyright screen.
Display set-up functions. Ask if set-up desired (Y/N).
Y ->set-up:
Initialization for set-up.
Loop until set-up option 4 is chosen and processed (or
termination requested with option "*").
Clrscr: clear screen: system routine.
Display set-up menu.
Read selected option (1 char).
Process based on selected option:
1 - Vocab "REVIEW VOCABULARY":
Fileio called after each I/O to the files on disk.
Clrscr: clear screen.
User may have saved a tape position. Only one such saved
file exists. If a tape position was not saved, it is
presumed that the user has rewound the tape, so we want
to start at the beginning.
Continue from saved position (Y/N).
N - Skip control record and continue.
Y - Skip number of words already reviewed (number is
LOGWORK.FLA- field "sn"in, minus 1), then continue.
Clrscr
Display a logo and legend
Any key continues, except:
"*" key returns to set-up menu.
"1" resets to beginning of file, to go with beginning
of tape.
Loop until end of file:
Read a raw record (LOGDATA.FLA).
Position on screen to 1,5 (col,row).
Clear to end of line
Display the raw record as is; the tape will match the
raw file order.
Read a character from keyboard.
"*" - ask if user wants to save position.
If Y, then write current position to
LOGWORK.FLA.
"1" - reset to beginning of rawfile.
Anything else - get next raw record
End of loop-until-end-of-file.
2 - Buildfl (select all words for a user).
Open raw text file.
Read first line (control data).
Get # of words in file (chars 1-5 of control line).
Setfil1 (common processing part 1):
Reopen raw text file.
Read control line
Get # of words in file.
Clrscrn.
Get user name (up to 7 characters), with
default="NONAME". Note: turn of special character
processing for this input to allow ":" in for
specifying non-current disk (e.g. A:5CHAR); otherwise
it tries to make an A with an umlaut.
Langline (accept data until ENTER is hit,
modifying for foreign characters).
Ask user for number of New Words per lesson (0-99,
default=40).
Check for valid entry.
Set-up control record in Word/Lesson file (user-
nameL.FLA).
session = 1.
lesson = 12 (i.e. - New Word Lesson, #13, next)
session type = C (Gaining Control).
No overflow lesson.
#New-Word-piles = #Words / pilesize + 1.
# records in Word/lesson file = #Words / 6 + 1
(add 1 if rounding requires incomplete final
record, at 6 words per record).
Get language name, if any, from raw file.
Get comments, if any, from raw file.
Write control record.
Close and then reopen file with alternate record
format for words.
Skip control record.
For each record in the raw file:
Read the raw record
buildwd (copy the raw data to the Word/Lesson-file
word-subrecord, and assign a new word lesson at
random).
count subrecords, and store every 6 as one physical
record in the Word/Lesson file.
At end of file:
setfil2 (remainder of common processing)
Close the raw file.
Write our any incomplete word-file record, padding
it out first.
Notify user.
3 - Selectfil (user-selected wordset. We may sometime get
rid of this).
clrscr
Ask user how many words maximum to select (he can quit
before this, but can't get more).
setfil1 (remainder of common processing. See option 2,
buildfl).
For each record until end of file or max words selected
or user asks to quit:
Get a raw record.
Display it and # words left to select.
Ask user if he wants this word.
Y - (add word as in option 2):
buildwd.
Decrement counter.
N - (skip word).* - (exit set-up).
other - (process same as N).
4 - Exit set-up:
Exits the set-up loop and falls though end of routine,
thus continuing on to Main "N" answer, below.
* - Exits program.
End of set-up loop.
N - (regular menu processing).
Ask user's name.
Eliminate special character processing to allow ":" in name.
Langline.
Add suffix to get wordfile name [name]L.FLA or NONAMEL.FLA.
Initialize flag ("ct" for "change type of lesson") used in
resetf to false; this indicates that if file is reset, the type
of lesson will be "Gaining Control".
Getfdata (get word file control record data):
If the user has a bad name (i.e. file not there), the
program will terminate per fileio.
Open the lesson file for the control record (filefile).
Get the control record (it is first).
Overwrite language name if it isn't blank in control record,
otherwise use "LOGLAN".
Close lesson file.
Checkftot (ensure lesson file integrity).
Check each file count for negative number of words.
Add all pile counts and check against control record total
word count.
If any pile has a negative count, or the total word counts
do not match:
Read the entire word file, recreating the control-record
word counts and total count. Notify the user that this
is happening.
Get first lesson #.
If it is his first time through, don't ask the user if he wants
to continue.
Main Menu processing:
Repeat until an "*" entry, either from main menu or from
deep in lesson processing (where it always means the user
wants to quit).
clrscr.
Display most recent session # and lesson #, and all lesson
names and #'s of words in each lesson.
Display Main Menu - ask for choice (these procedures are
described elsewhere to keep the flow clearer). Note:
choices 2, 3 and 4 all come back to the main menu loop;
others don't.
1 - Start lesson: session (do lessons) - see on page ###.
2 - Chgsess (change type of session, e.g. from Gaining-
Control to Maintenance) - see page ###.
3 - Resetf (restart at beginning).
Go back to initialization as if just starting in "N"
for answer to set-up question;, however skip the
prompt for the name.
4 - regroup (reorder word-presentation groupings) - see
page ###.
* - endrun (clean up at end) - see page ###.
Exit Main Menu loop.
other - ask again for valid entry.
End of Main Menu loop.
End of program.
Expansion of Main Menu Routines.
Endrun:
Cleans up lesson numbers.
Updates control record to ensure a proper start next time.
Ends program.
Chgsess:
Clrscr
Do not allow session change if new words remain (return if error,
with user msg).
Otherwise, indicate current session type and ask which type to run
next.
Input selection and validate.
If change to Brush-Up, must move all data back to "New Word" pile.
This calls resetf. The flag "ct" (change type) is set to true to
indicate that we want Brush-up as the type in the control record,
not "Gaining Control".
Reset "ct" to false, so if resetf done again from elsewhere, it
will go back to "Gaining Control".
Return.
Resetf:
(note: this is called either from Main Menu processing or from
chgsess, above).
Almost identical to the set-up routine buildfl, but it doesn't need
to read the raw data. It updates the control record. It asks the
user for a pile size (average), then randomly distributes the words
in the lesson file into "New Word" lessons with that average size.
These are all put down in the new word pile. The control record
session type is changed based on whether the flag "ct" (change
type) is true or false.
Return to calling procedure.
Regroup:
Similar to resetf, but doesn't move words in any lessons except
"Under Control" (if session type is Maintenance) or "New Words" (if
session type is "Gaining Control" or "Brush-Up").
The session number and other control record data is unchanged, but
the number of new word lessons is changed, if applicable.
Return to Main Menu.
Session: This is the main procedure controlling activities in a
session, both lessons and practices. The first thing it does is
figure out which lesson is next. The lesson file control area has the
last lesson number, as well as an indicator of an overflow lesson that
was only partially completed. Session type (C, M or B) also affects
lesson order. If the user types an "*" at any of several points, the
initial "while" clause will cause an exit to Main, which will in turn
exit via endrun. Otherwise this procedure loops indefinitely, running
lesson after lesson based on the lesson determination logic in the
first half of the procedure and the "case" statement covering each
lesson type in the second half of the procedure.
If an overflow lesson, do it next, otherwise increment last lesson
by one.
In M (Maintenance) or B (Brush-Up) mode, all Recog2 words are put
in the Recog3 pile, so skip the Recog2 lesson (lesson #7 and its
error lesson #8).
If M mode, the last lesson of the session is 12 (Failure Errors).
If C or B mode, then last lesson of the session is 14 (New Word
Errors)
If last lesson of session has been run, start new session:
Increment session number.
Determine first lesson of new session:
session 1: start with New Words (lesson #13).
session 2: start with Recog1 (#9).
session 3: start with Recog2 (#7).
session 4: start with Recog3 (#5).
session 5 and on: Basically, start with Recall1 (#3), but
see below.
In M mode, we have Under Control, but not New Word, so
start 2 lessons higher (one regular lesson plus its error
lesson).
In B mode we have New Words, but lesson #7 (Recog2) is
skipped; therefore, if session is 3 or 4 we will be
starting 2 lessons higher.
If "fs" (first entry) flag is true:
Don't bother asking user if he wants to start the "next"
session; assume he does.
If "fs" is not true,
asksess: (ask user if he wants a new session)
Give lesson status and ask user about new session.
Validate response.
If response is "N" ("no"), then endrun (clean up and end).
Move all error word piles from previous session into the Failure
lesson. This entails a full read of the lesson file. Any word
in an even numbered lesson is moved into pile #11 (of course
skipping any stray data in the padded portion of the last
record, which would have a zero lesson number). "Chgflg" (Change
Flag) is used to minimize file writes. It is set to true if any
logical record of the physical record needs to be updated, so we
only have to rewrite a record if "chgflg" is true.
If first lesson of session, error lesson (even numbered lesson) or
continuation of an incomplete lesson:
Do not ask if user wants the lesson. Assume he does.
Otherwise:
askless (ask if user wants lesson; very similar to asksess,
which asks about a new session):
If response is "N" ("no"), then endrun (clean up and end).
Control lesson based on lesson number:
#1 (Under Control pile):
Note: the Under Control pile has many sessions' data, but
the last session tested for each word is in its "ym" field.
Determine the oldest words (lowest "ym" field).
If it is a continuation lesson for Under Control (mr > 0)
or the oldest set of words has already been determined
(oldestset > 0), then there is no need to re-find the
oldest session number in the Under Control pile words.
Otherwise:
Read through the file for all words in pile #1 (Under
Control), and save the lowest "ym" (session number
last used).
Incidentally, since we're going through the words
anyway, make sure all Recog2 (pile #7) and Recog2
error (pile #8) words (never used when Under Control
is used) have been dumped into Recog3 and Recog3
errors (piles #5 and 6) instead.
Only rewrite the record if a change was made to one
of its subrecords.
Set variable "k" (a temporary parameter) to one more than
the oldest session number. This will allow the common
processing routine getwds to select the correct words; it
selects for words OLDER (i.e. with a lower session number)
than "k".
#1 continued, #2 through #12, and #14:
If an error lesson, the word stays in this pile (same lesson
number) for later gathering into the failure pile (when a
new session starts. Thus "np" ("next pile") is not needed.
"ep" ("error pile") tells the processing to leave the word
in this pile. Procedure errpile is called to test error
words (see later explanation).
If a non-error lesson (odd number), we indicate with
variable "np" where to put successful tested words, and with
"ep" where to put error words. Procedure goodpile is called
to test the lesson words (see later explanation).
#13 (New Word lesson):
Note: This, like the Under Control lesson, is complicated by
having several subpiles. At setup or resetf or regroup
(described earlier), a session number was assigned to each
word to indicate when it should be first tested as a New
Word.
We have a dummy check for accidental fall-though in "M"
("maintenance") mode. It should not occur.
Check if any new word subpiles are left.
If so,
Set "k" to the current session + 1. This will allow the
common processing routine getwds to select the correct
words; it selects for words OLDER (i.e. with a lower
session number) than "k".
Run the lesson:
review, testreco, update (all described later).
Set ld, hm, fs and bgi as in goodpile (described
later).
If no new word piles are left,
perform newdone - ask user whether to change to "M" mode,
and do so if user says "Y" (yes).
Pretend like we've run a lesson, setting ld, hm, fs and
bgi as in goodpile (described later).
Others: Shouldn't happen, but we have a check.
Loop back to beginning of session for next lesson or end.
Review:
This procedure is called by session for new words, and by recprac
from errpile in each error lesson. It presumes the words for the
lesson have been read in.
Loop through the words in the lesson (in arr[]),showing a new word
each time the user enters a character, until all displayed or "*"
entered by user. Blank existing fields then write data for word in
formatted screen.
Goodpile (Common processing for non-error word lessons):
If not Under Control lesson (#1), set "k" so only words that have
not been tested this session are requested from getwds. (There
should be no others, so this check is probably superfluous now.)
If not a continuation lesson, reset the lesson statistics: "gt"
(number words tested), "gs" (number correct), "sc" (percent score).
Otherwise we want to continue accumulations.
Getwds: get words for requested lesson pile. Described later.
If words found, either testreca or testreco depending on lesson
number.
If back from testreca or testreco with "*" last entered, abort the
lesson, saving no data from the lesson even if partially complete.
Set up variables for update to ensure the control record is correct
and that session operates correctly.
Update:
Random access is used to update each word. It calculates a
record number and subrecord number for each item in arr[]. Then
seek the record update it, and rewrite it.
We then do a read through the entire file to update our lesson
counts. This was put in to prevent early bugs and could
possibly be omitted by using the totals kept by the lesson
procedures in "gt" and "gs".
Return to session.
Getwds (Get words from lesson pile meeting the session criteria)
Variables used for controlling selection of words:
hr = number of words to skip if "mr" flag is set (error pile
only).
nw = number of words selected for this lesson (initially zero).
mr = overflow flag if more words than 250 for a lesson.
hw = counter up to hr when skipping words (error pile only).
Since there may be more than 250 words in the lesson, this
procedure got very complicated. With 99-word new word lessons, we
have seen a lesson as high as 254 words in normal use, so this
logic is critical. And you may need a smaller array than 250 in
your machine.
Initialize number of words to skip (hr) to zero.
If there are no records for the lesson (control record word count =
0), set all variables (hr, nw, mr, hw) to zero UNLESS this is "M"
or "B" mode lesson #5 (Recog 3) where lesson #7 (Recog 2, which is
skipped in these modes) has words in it; we will want to pick up
the lesson #7 words in lesson #5.
Write message indicating words are being read, since this takes a
while on floppy.
If an error pile and a continuation lesson (God help a person with
more than 250 error words), set up "hr" so that the poor guy
doesn't get the same words twice.
Read all the records and all the words in each record, skipping
blank words (may be in the last record).
For each word:
Skip all words up to "hr", if any.
If word is in pile #7 and we're in "M" or "B" mode, handle it
instead as if in pile #5.
If not in lesson wanted, skip word.
If error lesson, and word not put in during current session,
skip word (this may be an obsolete check).
If non-error lesson, and word not older (i.e. less than)
session "k", skip word.
If array is full, set "mr" for next time and exit the routine.
Otherwise, add word to the array:
Extract the data.
Increment "nw".
At end, ensure that the overflow flags will cause proper processing
in session.
Errpile (common error pile processing controller):
Similar to Goodpile, except:
Recprac is called instead of testreca/testreco, to practice
instead of test. A flag tells recprac whether recall or
recognition is required.
Some of the logic duplicated from the if/then/else in goodpile
has been simplified.
Update is not called, since the words remain in the error pile
until the end of the session (this saves a lot of file I/O).
Recprac (Does error word practice):
This procedure requires that a given word be typed correctly 6
times in a row before it is dropped from the practice. Beware of
logic problems if modified, especially ending conditions.
Key control variables:
xx = count of words to practice.
pii = count from 0 to 6; how many times in a row correct.
fd = true if at least one word needed practice (pii[word] < 6).
n = Index to the array for testing order. Equals 1 if about to
start next pass. Equals "nw" at the end of the pass.
Incremented in the loop. This is also used as an indicator to
know when to mix the pile of words.
pisave = pii to be saved for the "until" clause, since the
array index changes before the end test (a Pascal artifact).
Pack the array; this may be an artifact of earlier versions, but it
ensures integrity and doesn't take long.
For each word, initialize pii to 0.
If there are errors, call review.
If no errors, just return.
Initialize fd to false; will be set true if item to test is found.
Initialize n to 1.
Loop until:
"*" entered, or
This pass through deck complete (n=nw) AND no words were
practiced this time through (fd is false) AND the current word
has been tested 6 times. We needed all of these conditions to
avoid logic glitches.
In the loop:
Count number of words to be practiced this time.
If at least one word is left, and we are at the beginning of
the deck/pass, then
mix: shuffle nw words in arr[] pseudo-randomly by
exchanges.
If current word (n) has not been practiced 6 times
correctly:
Set "fd" to true.
clrscr.
Build either a recall or recog test screen based on
recaflag (it was set by errpile based on lesson number).
(Screen-building notes:
language name found in the rawfile at setup will
override default "Loglan" if non-blank.
function langline is used. This checks for special
characters and supports use of this program for
languages other than Loglan, allowing, for example,
umlauts.
after displaying a correct/error notice, we allow
user to quit with "*". Since no update is performed,
he must restart the error lesson next time.)
If word correct, increment pii for word (one more time
correct). Otherwise set pii for word to zero (start
collecting your six times all over again).
If the user has not typed "*" to exit, increment "n" or, if
all words done (i.e. n=nw), reset it to 1.
Perform "until" check to see if we're done.
When loop done, return.
Testreco: test recognition. Called by either goodpile or,for New
Words, session.
Mix: pseudo-random exchange of words to shuffle the deck.
For each word in the pile, or until "*" response:
Update lesson statistics (# correct, # left, % correct).
Write the Loglan and request English.
Get user's response, using routine langline.
Change response to upper case and compare to English keyword.
If correct:
Write "Correct" message.
Increment correct count.
Put word in next "good pile", np.
If incorrect:
Write "incorrect" message and correct answer.
Put word in error pile for lesson, ep.
Recalculate and display scores.
Ask user for key to continue or "*" to exit.
clrscr.
Give final score.
Exit the routine.
Testreca: identical to testreco except test recall for lessons called
by goodpile.
Display and loop the same, except we display the English keyword
(and accompanying English further explanation) and ask for the
Loglan (or other language) word.
Langline: gets keys as pressed, edits (for foreign characters), writes
to screen; finishes in .
Note: Routine expects to get screen and line position to start at,
and max length of the entry expected (it will beep if user tries to
go beyond).
Position on requested screen position and display "cursor".
For each character entered until :
Get pressed character.
If accents to be considered (not used for file names because
":" might umlaut a vowel),
If item is one of "accents" (/\^:@%~_), remember relative
position in list, for later translation.
Error if used in 1st position, so BEEP if there; it is
expected after the thing it is to accent.
Check the previous character entered to see if it is allowed
this accent.
if it can, replace that character by the correctly
accented version.
if not, it's an error; BEEP and stay in same place on
screen.
If accents are not to be considered OR entry is not an accent,
processing depends on just what was hit:
: Just write out a blank. Don't accumulate it into
the answer string. This will end the loop.
:
If at beginning of line (pos=0), this is an error, so
BEEP.
Otherwise, back up 1 character on screen, erase it,
delete last letter accumulated into answer string.
other:
If beyond the end (max allowed), this is an error, so
BEEP.
Otherwise, add item to screen line and accumulate into
answer string.
Note:
Accent: / \ ^ : @ % ~ _
Takes char: aeiouE aeiou aeiou aeiouAOUy aA cC nN ao
To make: aeiouE aeiou aeiou aeiouAOUy aA cC nN ao