Разработчик | Лаборатории Ванга |
---|---|
Впервые появился | 1973 (1973) |
Под влиянием | |
Дартмут БАЗОВЫЙ |
Wang BASIC — это серия языков программирования BASIC для компьютеров от Wang Laboratories . Этот термин может использоваться для обозначения BASIC на любой машине Wang, но в основном ассоциируется с версиями на серии миникомпьютеров Wang 2200 начала 1970-х годов. Когда эти машины были обновлены до серии VP в 1976 году, был представлен BASIC-2, который оставался образцом для будущих машин в серии 2200. Планируемый BASIC-3 так и не был выпущен.
Ван предложил несколько моделей каждой версии серии 2200, отличающихся только объемом микрокода, хранящегося в постоянном запоминающем устройстве (ПЗУ), и, следовательно, количеством команд, доступных в BASIC на этой машине. Например, машины модели B отличались от базовой модели A удвоением ПЗУ и использованием его для хранения различных команд ввода/вывода и управления файлами.
Wang BASIC по синтаксису был близок к оригинальному Dartmouth BASIC , но был интерпретатором , а не системой компиляции и запуска . Примечательной особенностью было то, что вся математика использовала формат двоично-десятичного кода двойной точности (BCD), что было необычно для BASIC той эпохи. [a] В нем отсутствовали многие функции, общие для более поздних диалектов, таких как Microsoft BASIC , но многие из этих функций были добавлены в BASIC-2.
Следующее описание основано на оригинальном BASIC, найденном в 2200A. Не все инструкции, перечисленные ниже, будут доступны в базовой модели; 2200B и C добавили десятки новых ключевых слов и описаны отдельно ниже.
Оригинальный Wang BASIC для 2200 является относительно стандартной версией концепции Dartmouth BASIC и будет знаком пользователям любых распространенных интерпретаторов BASIC, таких как Microsoft BASIC . Как и большинство интерпретаторов BASIC, Wang BASIC работал в режиме немедленного запуска или в режиме программы , переключаясь на последний, когда номер строки отображается в начале строки при EXECнажатии клавиши (return). Номера строк варьировались от 0 до 9999. Строки могли содержать до 192 символов, охватывая несколько строк на экране, [1] и строки могли содержать несколько операторов, разделенных двоеточиями. [2] Для организации больших программ язык включал RENUMBER
команду. [3]
LIST
использовался для отображения исходного кода программы, при этом LIST S
отображались только первые 15 строк, а затем делалась пауза. При паузе нажатие клавиши EXEC отображало следующие 15 строк. [4] SAVE "filename"
сохранял текущую программу на кассету и LOAD "filename"
считывал ее обратно. SKIP 2F
считывал следующие два файла, найденных на кассете, а затем останавливался, позволяя последующему LOAD
или SAVE
работать с третьим файлом. [5] BACKSPACE
был противоположностью SKIP, перематывая указатель файла. Работа с дисковым хранилищем была немного сложнее, с использованием LOAD DC F "filename"
, где F ссылался на один из ряда предопределенных дисков, в данном случае «Fixed». [6]
RUN
начал выполнение и мог быть направлен на определенную строку, как в RUN 100
. STOP
Команда, обычно используемая для отладки, допускала необязательную следующую строку, которая была напечатана при выполнении этого оператора. [7] TRACE
можно было использовать для печати строк по мере их выполнения, что часто использовалось в сочетании с пользовательскими клавишами (break) и на клавиатуре для перемещения по строкам программы. [8] использовалось для установки задержки между строками в единицах 1 ⁄ 6 секунды; установка задержки на ноль заставляла бы ее делать паузу 1 ⁄ 2 секунды после каждой строки. [9]HALTSTEP SELECT P
TRACE
SELECT P0
SELECT P3
Не было NEW
команды для очистки памяти существующей программы, [10] вместо нее использовалась команда CLEAR
для сброса памяти. [11] CLEAR P
(для "P"rogram) была эквивалентна NEW, но добавляла необязательные номера строк from и to, [12] удаляя только этот диапазон строк способом, похожим на DELETE
команду, встречающуюся в некоторых диалектах. CLEAR V
очищает значения переменных, [13] обычно выполняется с помощью CLR
в большинстве диалектов. [14] CLEAR N
была похожа на CLEAR V, но не очищала значения общих переменных (см. ниже). [12]
Ветвление поддерживалось через IF...THEN
, GOTO
и GOSUB
. Альтернативная форма, GO TO
, не поддерживалась. Одним из ограничений Wang BASIC, как и в случае с оригинальным Dartmouth, является то, что предложение THEN оператора IF могло быть только номером строки, в отличие от более современных диалектов, которые допускают любой оператор после THEN. В нем также отсутствовали булевы союзы, такие как AND
или OR
, поэтому тест мог иметь только одно сравнение. [15]
Одним из интересных дополнений к языку была идея именованных процедур. Реализация была основана на DEF FN
операторе, за которым следовала одинарная кавычка, а затем число от 0 до 255, например, DEFFN' 1
. Затем это можно было вызвать с помощью GOSUB '1
. Чтобы еще больше запутать ситуацию, строка DEFFN была настоящим определением функции и могла использовать параметры, такие как DEFFN'5(A$, N)
, которые можно было вызвать с помощью GOSUB'5("hello", 4)
. В позволяет реализовывать многострочные определения функций, которые другие диалекты иногда предлагали с использованием обычного стиля функций, а не с помощью GOSUB. [16] Кроме того, именованные процедуры в диапазоне от 0 до 31 были назначены клавишам с аналогичными номерами на клавиатуре 2200, что позволяло вызывать их напрямую одним нажатием клавиши. [17]
PRINT
поддерживал запятую и точку с запятой в качестве разделяющих параметров, первая перемещала курсор в следующий столбец шириной 16 символов, вторая оставляла курсор в конце печатаемого значения. Он поддерживал функцию TAB()
, но не SPC()
. Как и другие «высококлассные» BASIC той эпохи, Wang BASIC предлагал форматированный вывод с PRINTUSING
и отдельным «изображением». Изображение определялось с помощью отдельной строки, начинающейся, например, со знака процента, 180 % ##,###.##
а затем с использованием этого формата с 190 PRINTUSING 180, N
. [18] Любые символы, кроме символов форматирования, отображались обратно во время печати, поэтому можно было определить полный вывод с помощью чего-то вроде 180 % ANGLE= #.#### RADIANS
. [19]
INPUT
Операторы могли включать подсказку вместе с разделенным запятыми списком из одной или нескольких переменных. Точки с запятой не могли использоваться в INPUT, и курсор всегда оставался в конце последнего напечатанного элемента во время ввода. [20]
Как и в большинстве диалектов той эпохи, имена переменных могли состоять из одной заглавной буквы или буквы, за которой следовала одна цифра. Он не поддерживал двухбуквенные имена. [21] Множество переменных могли быть установлены в начальное значение с помощью списка, разделенного запятыми, например, LET A,B,C=1
. Как и в большинстве BASIC, LET
всегда был необязательным. [22] Переменные могли быть объединены в списки (одномерные массивы) с помощью DIM
, как в DIM A(5)
which создал список из 5 числовых значений. [23] или двумерные массивы с помощью DIM B(5,5)
. [24]
Реляционные операторы включали стандартный набор =
, <
, >
, <>
, <=
и >=
. [25] Тригонометрические функции включали SIN
, COS
, TAN
, ARCSIN
, ARCCOS
, ARCTAN
, LOG
, EXP
и SQR
. [26] ATN
был псевдонимом для ARCTAN. [27] Тригонометрические функции обычно работали в радианах , но могли быть настроены на использование градусов с помощью SELECT D
или градиентов с помощью SELECT G
, возвращаясь к радианам с помощью SELECT R
. Другие функции включали INT
, ABS
, SGN
, [28] RND
и #PI
псевдопеременную. [29]
В отличие от большинства BASIC, RND
функция не обрабатывала параметр как заполнитель; любое ненулевое значение заставляло ее работать как RND, наблюдаемый в других BASIC, в то время как значение нуля перезапускало числовую последовательность таким же образом, как оператор, RANDOMIZE
наблюдаемый в других BASIC. [29] Это потенциальный источник ошибок при портировании из других диалектов, которые обычно игнорировали параметр и часто использовали ноль в качестве параметра просто как общий заполнитель. [b]
Поддерживались строковые переменные, а также поддерживалась конкатенация с использованием оператора «плюс». В отличие от более поздних BASIC, которые использовали динамические строки длины в куче, как Microsoft, Wang BASIC устанавливал для всех строк длину по умолчанию в 16 символов и игнорировал любые символы, назначенные сверх этого. [c] Неиспользуемые символы в конце строки заполнялись пробелами, а любые конечные пробелы игнорировались в операторах PRINT, [30] что является еще одним потенциальным источником проблем при переносе кода в Wang BASIC.
Длина хранения любой отдельной строки может быть изменена с помощью DIM
оператора, который в этом случае использовал немного странный синтаксис, указав длину сразу после имени переменной, например DIM A$40
, [31] вместо использования скобок, как в типичном операторе DIM. [32] Строки имели максимальную длину 64 символа. [33] Синтаксис допускал списки строк, например, DIM A$(5)
создал список из 5 строк длиной по умолчанию в 16 символов, в то время как DIM B$(10)20
создал список из 10 строк по 20 символов. [34]
Существовал небольшой набор строковых функций. STR
— это универсальная команда нарезки массива , которая заменяет DEC/Microsoft-style MID
/ LEFT
/ RIGHT
. Например, STR(B$,10,5)
возвращает пять символов A$, начиная с символа 10. [35] Второй параметр был необязательным, STR(C$,5)
возвращал все, начиная с 5-го символа. LEN
возвращал длину строки, игнорируя конечные пробелы, поэтому LEN("ABC ")
возвращал 3. [36] Чтобы еще больше запутать ситуацию, пустые строковые переменные всегда возвращали длину 1. [37] Обратите внимание, что строковые функции не включают $, в отличие от большинства BASIC, где эти функции были бы названы STR$
, например, указывая, что возвращаемое значение является строкой, а не числовым значением. [38]
В соответствии с моделью Дартмута, Wang BASIC включал DATA
операторы для хранения констант в программном коде, и они считывались с помощью READ
оператора, который начинался с первого элемента данных, а затем перемещал указатель вперед на следующий элемент с каждым READ. RESTORE
мог сбросить указатель READ и был расширен по сравнению с оригинальной версией Дартмута, позволяя устанавливать указатель на определенный элемент в списке, например, RESTORE 10
, что устанавливало его на 10-й элемент. Всего в одной программе в операторах DATA можно было ввести только 256 значений. [39]
Оператор SELECT
может использоваться для перенаправления вывода из других команд BASIC на другие устройства, на основе «адреса» устройства. Например, SELECT PRINT 215
будет отправлять вывод последующих операторов PRINT на принтер по адресу 215, в то время как SELECT PRINT 005
возвращаемый вывод на встроенный CRT. SELECT LIST 215
будет делать то же самое для любых последующих операторов LIST. [40] SELECT также имел необязательный параметр following для установки максимальной длины строки, например SELECT PRINT 215 (132)
. Можно было использовать SELECT с различными предопределенными устройствами, такими как CI для «консольного ввода» (обычно клавиатура) или LIST для перенаправления листинга программы на другое устройство. [40]
Поскольку машины той эпохи имели очень ограниченный объем памяти, большинство диалектов BASIC включали некоторый способ «связывать» программы вместе, чтобы позволить разбить одну программу на более мелкие модули. В Wang BASIC это достигалось с помощью операторов COM
и LOAD
. [41]
COM
объявляли одну или несколько переменных "общими", [d] или глобальными в современной терминологии. Программа, использующая цепочку, обычно объявляет ряд переменных общими в верхней части кода, возможно COM A,B,I,A$20
. [42] Когда отдельный программный модуль LOADed, значения в этих переменных не будут очищены, в отличие от необщих переменных, которые будут сброшены. Общие переменные могут быть очищены явно с помощью CLEAR V
, в то время как CLEAR N
очищает необщие переменные и оставляет общие переменные в покое. Переменные также могут быть объявлены необщими с помощью COM CLEAR
, что сбрасывает все общие переменные в нормальное состояние или COM CLEAR A
сбрасывает только статус A. Как ни странно, COM CLEAR также сбрасывает любые другие переменные COM, определенные до A, поэтому результаты COM CLEAR A будут другими, если бы исходная программа использовала COM S,B,A
или COM A,B,S
, в первом примере все три были бы сброшены, а во втором была бы сброшена только A. [43]
Команда LOAD также использовалась для цепочек. Можно было по желанию добавить начальные и конечные номера строк, в этом случае любые существующие строки между этими пределами будут удалены, или от начальной строки до конца программы, если был указан только один номер. Затем новая программа загружается в этой точке, и выполнение начинается с номера начальной строки или с начала программы, если начальная строка не была указана. [44]
Оригинальный Wang BASIC выпускался в нескольких версиях, различающихся объемом микрокода в ПЗУ и, следовательно, количеством поддерживаемых ключевых слов.
BASIC в 2200B был крупным расширением версии 2200A. Дополнения можно в целом разделить на четыре категории: отсутствующие функции, дополнительные строковые команды, векторно-подобные команды и ввод/вывод. Различия между версиями можно найти в табличной форме в обзорном документе 2200. [45]
Отсутствующие функции, которые были устранены в 2200B, включали добавление ON...GOTO
[46] и ON...GOSUB
. [47] KEYIN
считывание символа с клавиатуры без паузы, аналогично INKEY$
MS BASIC. VAL
поиск строки и возврат числового значения в ней. Функция NUM
была похожа на LEN, но возвращала длину подстроки до первого нечислового символа. Например, если A$ равно "1234.5", NUM(A$)
вернет 6, тогда как если A$ равно "1234.5" , NUM вернет 10, поскольку пробелы допустимы в числах. [48]
2200B не добавил функцию STR$, которая преобразует числовое значение в строку. Вместо этого они добавили CONVERT
команду для чтения строк в числа и наоборот. Например, использование A$ выше CONVERT A$ TO B
приведет к тому, что B будет содержать значение 1234.5, в то время как CONVERT 123 TO B$
B$ останется с чем-то вроде "123". [49] Dartmouth BASIC включал команду CHANGE, но она была совсем другой по назначению, в Dartmouth, CHANGE A$ TO B
создавала массив значений в B, где каждый элемент содержал код ASCII для соответствующего символа в A$; в этом случае B будет содержать 49,50,51,52,46,53, значения ASCII для символов "1234.5". CONVERT Вана также имел второй режим, который принимал спецификатор формата, такой как PRINTUSING, и использовал его для преобразования числа в форматированную строку способом, аналогичным sprintf в C. [ 49]
Функция POS
возвращает индекс заданного символа в строке; POS("HELLO WORLD", "L")
вернет 3. В отличие от MS INSTR
, POS может искать только один символ, а не многосимвольную строку.
HEX
преобразовывал шестнадцатеричное значение в соответствующий символ. Например, A$=HEX(20)
поместит пробел (hex 20) в первый символ A$. [50] Можно вставить несколько кодов одновременно; PRINT HEX(080809)
выдает три символа, два возврата на одну позицию и курсор вправо. [51] HEX — аналог функции ASC, присутствующей в большинстве BASIC, [52] но использует шестнадцатеричный ввод вместо десятичного числа. BIN
делал то же самое для двоичных чисел. [37]
Была добавлена специальная команда для заполнения строки начальным значением, не являющимся пробелом. INIT ("X") A$
Она заполнит A$ символами X, а INIT (41) B$
шестнадцатеричное значение 41, символ A, поместит в B$. [53]
2200B также включал ряд команд, которые работали векторно-подобным образом для выполнения общих задач, которые обычно выполнялись бы с использованием цикла или в версиях Dartmouth, матричных математических команд. Например, ADD
брал список выражений, складывал их и возвращал результат. Это было выполнено намного быстрее, чем то же самое, выраженное с использованием инфиксного выражения; A=ADD(B,C,D)
будет выполнено быстрее, чем A=B+C+D
. Похожие команды были OR
, AND
и XOR
.
Большинство дополнений в 2200B были связаны с вводом/выводом и в основном с работой с файлами на дискетах. Он ввел концепцию наличия нескольких различных типов файлов, включая файл данных, обозначенный префиксом "DA" в командах файла. Различные другие команды поддерживали работу с этими файлами, включая COPY
дублирование файла, MOVE
внутри файла, VERIFY
файлов и SCRATCH
стирание файла или SCRATCH DISK
стирание всего.
В отличие от версии 2200B, которая была крупным расширением 2200A, 2200C была гораздо более ограниченной по области применения. Она добавила COM CLEAR
команду для очистки общих переменных, версия, DEFFN'
которая возвращала hex, RETURN CLEAR
использовалась для «выталкивания» GOSUB из стека, [47] и ON ERROR
для перехвата ошибок в программе.
Более поздние модели в серии добавили некоторые или все команды в версиях B или C, но только 2200T расширил их. Наиболее заметным в расширениях было добавление матричной математики, но также были добавлены некоторые детали ввода-вывода.
Математические команды для работы с матрицами были в значительной степени идентичны тем, что были в более поздних версиях Dartmouth BASIC. Они обычно имели форму присваивания, как LET, но замена LET на MAT
. Например, MAT A=B+C
создавала бы матрицу A, элементы которой были бы суммами соответствующих элементов в матрицах B и C. [54] Другие матричные команды включают INV
ert IDN
для единичной матрицы и ZER
для нулевой матрицы, а также различные утилиты, такие как COPY
, MERGE
, MOVE
и SORT
. [45]
Введение совершенно нового набора инструкций 2200VP потребовало написания совершенно нового BASIC с нуля. Хотя обратная совместимость была основной целью, новый BASIC-2 также добавил ряд недостающих функций. Самым заметным изменением было то, что BASIC больше не хранился в постоянном запоминающем устройстве (ПЗУ), а вместо этого загружался с диска во время загрузки, что позволяло легко исправлять его в полевых условиях для исправления ошибок. Он также был намного быстрее, примерно в восемь раз, из-за фокусировки на производительности, а не на размере, и лучшей производительности платформы VP. [55]
Операторы IF были ограничены в оригинальной версии и были значительно улучшены в BASIC-2. Были добавлены булевы союзы, что позволило использовать более сложные тесты, например: Оператор, следующий за THEN, больше не должен был быть подразумеваемым GOTO, что позволяло использовать общие операторы, например : . Было добавлено предложение, которое должно было следовать за двоеточием; . ELSE также можно было использовать с операторами ON; переходило бы на строки 10, 20 или 30, если бы значение в X было 1, 2 или 3, в то время как любое другое значение переходило бы на 100. [55]IF X=5 AND Y=10 THEN...
IF X=10 THEN PRINT "IT IS TEN"
ELSE
IF X=10 THEN PRINT "IT IS TEN":ELSE PRINT "IT IS NOT TEN"
ON X GOTO 10,20,30:ELSE 100
Новые функции включают FIX
, которая всегда округляется в сторону нуля вместо INT, которая всегда округляется в меньшую сторону; FIX(-4.5)
возвращает -4, тогда как INT(-4.5)
возвращает -5. ROUND(value,num)
похожа на FIX, но округляет до десятичного знака, указанного во втором параметре. MOD
выполняет целочисленное деление и возвращает остаток. MAX(a,b,c...)
и MIN(d,e,f...)
возвращает значение из списка входных данных с наибольшим или наименьшим значением. LGT
возвращает десятичный логарифм значения. VER
проверяет, соответствует ли строка в первом параметре формату во втором, формат был таким же, как у PRINTUSING. [55]
PRINTUSING теперь могла выводить в строку; PRINTUSING TO A$, "#.##", SQR(3)
форматировала квадратный корень из трех до двух десятичных знаков и помещала результат в A$. Несколько новых псевдофункций были добавлены в PRINT; функция AT(X,Y)
была похожа по концепции на TAB, но перемещала курсор в положение X, Y, BOX(W,H)
рисовала прямоугольник заданной ширины и высоты с верхним левым углом в текущей позиции курсора и HEXOF(v)
возвращала шестнадцатеричное значение. [55]
Размер строки по умолчанию не изменился, но максимальный размер был увеличен с 64 до 124 символов. Максимальные размеры массива увеличились с 255 до 65535 элементов. [55]
В марте 1977 года Ван объявил о расширенной версии системы VP, которая включала больше памяти, до 256 КБ, и систему терминального сервера, позволяющую одной машине поддерживать до двенадцати терминалов. Известные как 2200MVP, первые устройства были отправлены в январе 1978 года. Четырехпользовательские модели LVP и однопользовательская SVP той же машины были отправлены в 1980 году. [56]
2 апреля 1981 года на Ганноверской ярмарке Ван объявил о крупном обновлении микрокода серии MVP. Опция «C» за 2000 долларов добавила компилятор COBOL , а также еще одну обновленную версию BASIC, BASIC-3. В то время они ожидали выпустить ее в бета-версии в августе, а для всех клиентов — в ноябре. [57] Система была отправлена на небольшое количество сайтов для бета-тестирования, но так и не была выпущена. [58]
RND(0)
.COMMON
.