Программа Mcalc 1985–1988 гг. (Turbo Pascal 5.0) состоит из следующих файлов:
• mcalc.pas — файл основной программы;
• mcvars.pas — файл глобальных описаний;
• mcdisply.pas — файл подпрограмм работы с дисплеем;
• mcmvsmem.asm — ассемблерный файл подпрограмм запоминания в оперативной памяти информации экрана, а также восстановления ранее сохраненной информации экрана;
• mcinput.pas — файл подпрограмм ввода данных с клавиатуры;
• mcommand.pas — файл подпрограмм, обслуживающих систему меню и действий, выбранных посредством меню;
• mcutil.pas — файл вспомогательных подпрограмм;
• mcparser.pas — файл интерпретатора арифметических выражений формул клеток.
Все файлы закодированы с соблюдением развиваемых стандартов оформления. Так, в файлах mcdisply.pas, mcinput.pas описания прототипов подпрограмм выполнены с использованием более раннего синтаксиса языка программирования, что говорит об их заимствовании из программ, написанных ранее; при этом можно выявить их небольшое модифицирование (рефакторинг).
Хотя фирма "Borland Inc." занимается разработкой компиляторов, файл mcparser.pas также является заимствованным из UNIX YACC utility и лишь частично модифицированным. Остальные файлы являются оригинальными.
Ассемблерный файл mcmvsmem.asm является искусственно добавленным. Цель его добавления — демонстрация возможности использования ассемблерных вставок. Содержащиеся в нем алгоритмы вполне можно было бы реализовать на языке Pascal. Более того, можно было бы вообще обойтись без реализованных в нем подпрограмм, правда, при этом были бы видны некоторые задержки вывода информации на экран.
С целью совершения улучшающей проект новой проектной итерации получим из существующего проекта проектную документацию, состоящую из описания структуры данных программы; функционального описания основного ядра программы; схемы иерархии модулей основного ядра программы; спецификации назначения модулей основного ядра программы.
Рассмотрим организацию файла mcvars.pas, содержащего в основном описание структуры внутренних данных программы. Файл содержит описания в секции interface. Секция implementation пустая.
В начале файла содержится код, который в зависимости от наличия сопроцессора транслируется в одном из двух вариантов:
{$IFOPT N+}
{Есть встроенный сопроцессор}
type
Real = Extended; {Замена типа Real на Extended}
const
EXPLIMIT = 11356; {Предельное значение аргумента экспоненты}
SQRLIMIT = 1Е2466;{Предельное значение аргумента SQRT}
….
{$ELSE}
const
{Тип Real не переопределен}
EXPLIMIT = 88; {Предельное значение аргумента экспоненты}
SQRLIMIT = 1E18; {Предельное значение аргумента SQRT}
….
{$ENDIF}
Описания констант содержат следующие блоки:
— блок строчных констант, содержащих информацию всех выводимых на экран и в файлы текстовых надписей (для русификации всей программы требуется изменить только эту информацию);
— блок парных строк текстов меню и "горячих" клавиш выбора тем меню;
— блок описания важнейших констант, определяющих размерность таблицы и расположение информации на экране
MAXCOLS = 100; { Maximum is 702 } {Размер таблицы}
MAXROWS = 100;
MINCOLWIDTH = 3; {Минимальная ширина столбца}
MAXCOLWIDTH = 77; {Максимальная ширина столбца}
….
— блок описания цветов всех полей экрана, модификация констант которого позволяет оперативно изменять цвета;
— основные константы, мнемоника имен которых облегчает восприятие текстов программы
HIGHLIGHT = True; {Подсвеченная текущая клетка}
NOHIGHLIGHT = False; {Неподсвеченная клетка}
{Атрибут содержимого клетки}
ТХТ = 0;
VALUE = 1;
FORMULA = 2;
….
{Разрешенные буквы}
LETTERS: set of Char = ['A'..'Z', 'a'..'z'];
— коды управляющих клавиш клавиатуры.
Следует отметить, что приведены даже коды неиспользуемых в программе управляющих клавиш клавиатуры. Это соответствует факту копирования данных кодов из кода какой-то другой разработки.
Далее следуют описания типа информации содержимого табличной клетки и типа указателя на клетку:
type
CellRec = record
Error: Boolean;
case Attrib: Byte of
TXT: (T: IString);
VALUE: (Value: Real);
FORMULA: (Fvalue: Real;
Formula: IString);
end;
CellPtr = ^CellRec; {Указатель на клетку}
Данный тип организован так, что клетка всегда может содержать признак ошибки расчетов Error и размещать три варианта информации: текст, значение и формулу.
Далее описаны основные глобальные переменные. Описания начинаются с определения двухмерного, постоянно находящегося в памяти массива Cell указателя на клетки таблицы. Это позволяет не расходовать память на пустые клетки. Память под информацию клетки выделяется динамически в количестве, строго соответствующем информации клетки. Без использования динамически выделяемой памяти было бы невозможно разместить информацию клеток таблицы в 640К памяти машин того времени.
MAXCOLS*MAXROWS*[SizeOf(Istring)+SizeOf(Extened)] = 100*100*[80+10] = 900K
Далее следуют описание переменной, являющейся указателем на текущую клетку таблицы, описание массива форматов клеток и переменных позиционирования информации на экране.
Celclass="underline" array [1..MAXCOLS, 1..MAXROWS] of CellPtr;
CurCelclass="underline" CellPtr; {Указатель на текущую клетку}
Format: array [1..MAXCOLS, 1..MAXROWS] of Byte;
LeftCol, RightCol, TopRow, BottomRow,
{Позиционирование}
CurCol, CurRow, LastCol, LastRow: Word;
….
Следует отметить, что выделение отдельного массива форматов информации клеток является не оправданным. Практичнее ввести байт информации формата клетки в тип CellRec.
Сравните этот проект структуры данных с проектом структуры данных электронной таблицы, представленной в гл. 3.
Для составления оставшейся проектной документации выполним трассировку программы. После двойного нажатия клавиши <F7> начинает исполняться настроечный код, содержащийся в файлах *.TPU, и далее начинают выполняться операторы основной программы program Mcalc, находящейся в файле mcalc.pas.
В результате исследований была выявлена схема иерархии модулей программы, изображенная на рис. 7.3–7.5. Расшифровка обозначений схемы иерархии представлена в табл. 7.1.
Рис. 7.3. Фрагмент схемы иерархии основных модулей программы
Рис. 7.4. Схема иерархии модуля RedrawScreen
Рис. 7.5. Сокращенная схема иерархии модуля Run
Таблица 7.1
Расшифровка обозначений схемы иерархии
| Имя модуля | Файл | Назначение модуля |