BETA BASIC
Окончание.
(Начало см. на стр. 3, 47, 91, 135, 179).
6. DPEEK (адрес).
FN P(адрес).
См. также DPOKE.
Функция DPEEK - это то же самое, что и двойной РЕЕК. Эквивалентом этой функции в стандартном БЕЙСИКе является выражение:
LET а = PEEK (addr) + 256*PEEK (addr+1)
Таким образом, эта функция выдает содержимое двух следующих друг за другом байтов. Обратите внимание на то, что младший байт идет первым. Это очень удобно для проверки содержимого системных переменных и при анализе машиннокодовых процедур. Например:
10 LET nxt = DPEEK(23637):POKE nxt+5.65 20 REM ХХХХХ
В десятой строке будет прочитано содержимое системной переменной NXTLN, после чего в результате РОКЕ первый символ, следующий после оператора REM будет изменен на символ "А". Сдвиг на +5 байтов в строке 20 необходим для того, чтобы пропустить номер строки (2 байта), длину этой строки (2 байта) и код самого оператора REM (1 байт).
Оператор DPOKE обеспечивает двойной POKE точно так же, как функция DPEEK обеспечивает двойной РЕЕК.
7. EOF (номер потока).
FN E(номер потока).
Название функции EOF происходит из сокращения End of File (конец файла). При работе с микродрайвом эта функция говорит о том прочитан или нет последний байт из загружаемого файла.
Поток, номер которого указан в функции, должен быть предварительно открыт (OPEN#) для данного файла, содержащегося на ленте микродрайва. Если этого не сделать, то Вы получите сообщение об ошибке "Invalid Stream". Этот файл должен, конечно, физически существовать и быть открытым для чтения, иначе вы получите сообщение об оошибке "Reading a "Write" file"
Функция выдает "1", если последний байт данных считан из файла или "0", если он еще не считан. Это помогает точно установить момент конца считывания данных и избежать попыток прочтения большего количества данных, чем в этом файле есть, что вызвало бы появление ошибки.
Предположим, что на микродрайве у вас есть файл "data". Наиболее элегантный путь использования функции EOF выглядел бы так:
10 OPEN #5,"m",1,"data" 20 DO UNTIL EOF(5)=1 30 INPUT #5;a$: PRINT a$ 40 LOOP 50 STOP
Впрочем, строку 20 можно записать еще короче:
20 DO UNTIL EOF(5)
Если Вы еще не привыкли к использованию циклов DO...LOOP, то можете попробовать действовать так:
10 OPEN #5,"m",1,"data" 20 INPUT #5;a$: PRINT a$ 30 IF EOF(5)=0 THEN GO ТО 20 40 STOP
8. FILLED ().
FN F().
См. также команду FILL.
Эта функция дает количество пикселов, включенных по последней команде FILL. Например:
10 PLOT 0,0: DRAW 9,0: DRAW 0,9 20 DRAW -9,0: DRAW 0,-9 30 FILL 5,5 40 PRINT FILLED()
Длина стороны квадрата - 10 пикселов. (Мы давали число 9 в команде DRAW, но поскольку реальная линия на экране имеет толщину не менее одного пиксела, то и сторона квадрата у нас будет десять пикселов.) Внутренняя неокрашенная часть квадрата будет иметь линейный размер по 8 пикселов на сторону, и функция FILLED() даст нам значение 64.
Если Вы попробуете в строке 30 дать команду на стирание нарисованного квадрата: 30 FILL PAPER; 5,5
то функция FILLED() даст Вам результат - 100.
Разница между 100 и 64 - количество пикселов, ушедших на изображение периметра квадрата.
9. HEX$ (число).
FN Н(число).
См. также функцию DEC(строка).
Эта функция конвертирует десятиричный числовой аргумент в шестнадцатиричную символьную строку. Строка имеет два символа, если число было в диапазоне от -255 до +255 или четыре символа, если абсолютная величина числа была больше. Если же число по абсолютной величине больше, чем 65535, то выдается сообщение об ошибке "Integer out of range".
HEX$ (32) = "20"
HEX$ (255) = "FF"
HEX$ (512) = "200"
HEX$ (-64) = "C0"
HEX$ (-1024) = "FC00"
Возможность работы с отрицательными целыми числами будет полезна тем пользователям, которые работают с машинным кодом. В частности, это пригодится при расчете адресов обратных относительных переходов.
Эта функция очень удобна, если Вам надо распечатать содержимое памяти в шестнадцатиричном виде:
10 INPUT "Start address? "; addr 20 PRINT HEX$ (addr); " "; HEX$(PEEK addr) 30 LET addr=addr+1: GO TO 10
Если же Вы хотите и начальный адрес при вводе тоже задавать в шестнадцатиричном виде, то можете переделать строку 10 например так: 10 INPUT "start address? "; A$: LET addr = DEC (A$)
10. INARRAY (строковый массив (начальный элемент)<,границы>,искомая
строка).
FN U (строковый массив (начальный элемент)<,границы>,искомая строка).
См. также функцию INSTRING.
Функция INARRAY осуществляет сканирование строкового массива в поисках заданной строки. Если она не найдена, то выдается 0. Если же она разыскана, то выдается номер той строки в массиве, в которой данная символьная последовательность встретилась впервые.
В принципе функция INARRAY - разновидность функции INSTRING, но предназначенная для работы с массивами, поэтому будет неплохо, если Вы сначала прочитаете про работу функции INSTRING.
Нижеприведенный пример показывает, как можно разыскать все символьные сочетания "howdy" в заданном массиве
10 DIM а$(20,10) 20 LET a$(RND*19+l) = "howdy" 30 LET num= 1 40 DO
50 LET num=INARRAY (a$ (num),"howdy") 60 EXIT IF num=0 70 PRINT num;" ";a$(num) 80 LET num=num+l 90 LOOP UNTIL num > 20
В строке 50 выражение a$ (num) при num=1 предполагает, что поиск начнется с первой строки массива. Когда первое искомое сочетание символов будет найдено, строка, в которой оно содержится, будет выдана на печать, после чего поиск будет продолжен с (n+1) строки.
Оператор EXIT IF выведет программу из цикла, когда уже не останется неразысканных сочетаний "howdy". Оператор LOOP UNTIL в строке 90 безусловно прекратит работу программы, когда все элементы исходного массива будут просмотрены.
Программа проверит каждую строку полностью, но Вы можете ограничить пределы поиска внутри каждой строки исходного массива, задав границы поиска. 50 LET num=INARRAY(a$(num,3 TO 7),"howdy")
Эта возможность позволяет Вам разрабатывать и манипулировать с базами данных. Например, вам надо найти в базе все адреса, относящиеся к городу Брест. Тогда вы проведете поиск именно по тем участкам информации, которые имеют отношение к полю "Город", и исключите тем самым жителей города Москвы, проживающих на Брестской улице, поскольку поле "Улица" в розыск не попадет.
При поиске вы можете использовать символ-заместитель "#", который обозначает "любой символ". Это же, кстати, относится и к функции INSTRING. Единственный случай, когда этот символ ничего не замещает, а принимается сам за себя, - это когда он стоит первым символом в искомой символьной строке.
Вы можете практиковать довольно сложные условия для поиска. Например, у Вас в базе данных содержится список лиц с именами, фамилиями, адресами, цветом волос и т.п. Если каждое поле начинается строго с фиксированной позиции, а так и должно и быть в структурированной базе данных, то Вы можете найти всех содержащихся в ней жителей Лондона, имеющих коричневый цвет волос. Для тех позиций, которые соответствуют городу, Вы введете London, для тех, которые соответствуют цвету волос - Brown, а для всех прочих поставите символы "#".
Нижеприведенный пример покажет как это можно сделать. Здесь первые 20 символов отведены под имя персоны, а последующие 15 - под название города. 10 LET namelen=20, townlen=15 20 DIM d$(10,namelen+townlen) 30 FOR n=1 TO 10 40 INPUT "name? ";n$ 50 INPUT "town? ";t$ 60 LET d$(n,1 TO namelen)=n$ 70 LET d$(n,namelen+1 TO )=t$ 80 NEXT n
90 PRINT "массив заполнен"
Мы подготовили исходный массив для дальнейшей работы. Следующий программный блок позволит Вам найти заданную комбинацию имени и адреса. Примененная здесь функция STRING$ служит для генерации заданного количества символов "#", служащих для отделения между собой полей имен и адресов. 100 INPUT "name=? ";n$ 110 INPUT "town=? "; t$
120 LET s$=n$ + STRING$ (namelen-LEN n$,"#")+t$ 130 LET loc=INARRAY(a$(1),s$) 140 IF loc=0 THEN
PRINT "Not found "
ELSE
PRINT loc;" ";d$(loc) 150 GO TO 100
Примечание: функция INARRAY не может работать с массивами, размерность которых больше, чем 2.
11. INSTRING (старт, строка 1, строка 2).
FN I (старт, строка1, строка2).
См. также функции: MEMORY$, INARRAY.
Функция INSTRING просматривает строку 1 в поисках строки 2, начиная с символа "старт". Если такое вложение найдено, то функция выдает порядковый номер символа в строке 1, с которого начинается строка 2, в противном случае выдается ноль.
Первая строка может быть любой длины, а вторая - не более 256 символов, иначе будет выдано собщение об ошибке "Invalid argument". Если начальная позиция для поиска "старт" равна нулю, будет выдано сообщение об ошибке "Subscript wrong".
В тех случаях, когда длина второй строки больше, чем первой, а также когда "старт" больше, чем длина первой строки, функция выдает ноль.
В искомой строке можно использовать символ-заместитель "#", который служит вместо тех символов, которые при поиске не имеют значения. Например: PRINT INSTRING (1,A$,"SM#TH")
найдет появление SMITH, SMYTH, SMATH и т.п. в символьной строке A$.
Единственный случай, когда символ "#" воспринимается буквально, т.е. служит вместо самого себя - когда он стоит первым символом в искомой строке.
Возможность задания начальной позиции для поиска будет полезной в тех случаях, когда Вы рассчитываете найти не одно, а большее количество вхождении искомой строки в исходную. Ниже приведен пример, который разыщет строку "TEST" в символьной строке A$. 100 DIM a$(1000) 110 FOR n=1 ТО RND*10 + 3 130 LET pos = RND*995 130 LET A$ (pos ТО pos + 3) 140 NEXT n
150 PRINT "Press any key" 160 PAUSE 0 170 LET loc=1
180 LET loc = INSTRING (loc,a$,"TEST")
190 IF loc <>0 THEN PRINT "Found"; loc: LET loc=loc+1:GO TO 180 200 PRINT "Finish"
Строка A$ начинает просматриваться с позиции 1 (loc=1), пока не будет найдена последовательность символов "TEST". После этого поиск будет продолжен со следующего символа (loc=loc+1). Когда функция выдаст 0, поиск будет завершен.
Обратите внимание на то, что строку 190 можно немного упростить: 190 IF loc THEN PRINT ...
Если Вам надо сделать поиск по оперативной памяти или по ее части, Вы можете воспользоваться функцией MEMORY$.
Функцию INSTRING можно с успехом использовать в обучающих и в некоторых игровых программах (в частности в адвентюрных). Предположим, что программа задала пользователю вопрос, правильный ответ на который хранится в переменной с$="NAPOLEON". Те, кто введут в качестве ответа "NAPOLEON "(обратите внимание на финальный пробел) или "NAPOLEON BONAPARTE", будут разочарованы, поскольку программа воспримет эти ответы, как неправильные. А это очень часто случается, если подпрограмма сравнения ответа и эталона не обладает достаточной гибкостью. Функция INSTRING поможет справиться с этой проблемой. Она оценит как правильный любой ответ, при котором контрольная строка входит в состав введенной пользователем. INPUT a$: IF INSTRING (1,a$,c$)<> 0 THEN PRINT "Correct"
Вы можете решить при этом и проблему регистра, если заранее не знаете большими или малыми буквами будет набран ответ пользователя. Вам надо принудительно конвертировать его ответ в прописные буквы с помощью функции SHIFT$: LET a$=SHIFT$(1,a$)
Еще одно возможное применение функции INSTRING - для упаковки нескольких строк в одну длинную строку. При этом Вы можете, например использовать символы с 1-го по 31-ый в качестве "маркеров" входящих строк.
Так, символ CHR$ 1 будет отмечать начало первой подстроки в генеральной строке, символ CHR$ 2 - начало второй подстроки и так далее. Так хранить строки гораздо компактнее, чем в массиве, если они имеют неодинаковую длину. Найти строку с номером n в генеральной строке будет несложно:
PRINT a$(INSTRING(1,a$,CHR$ n)+1 ТО INSTRING (1,a$,CHR$(n+1)-1)
Возможны и многие другие интересные пути использования функции INSTRING.
12. ITEM ()
FN T()
См. также раздел, посвященный процедурам.
Эта функция дает информацию о следующей единице данных, которые подлежат вводу через READ. Как правило, функция используется при работе с процедурами, но может быть применена и при обычной технике READ...DATA. Функция возвращает следующие значения:
0 - все данные из текущего оператора DATA прочитаны. Текущий оператор DATA может быть при этом и списком параметров, следующим за вызовом процедуры.
1 - следующий объект - символьный.
2 - следующий объект - числовой.
При работе с процедурами функция ITEM() может дать информацию о физической природе первого объекта данных, но во всех остальные случаях она будет выдавать 0 до тех пор, пока хотя бы один объект не будет считан из списка DATA с помощью READ. В нижеприведенном примере проверяется ITEM() после READ.
100 DO
110 READ x PRINT x 120 LOOP UNTIL ITEM()=0 130 DATA 1,2,3,4,5,6
Таким образом, строки 100...120 могут считывать строки DATA произвольной длины.
13. LENGTH (п, "имя массива")
FN L(n,"имя массива")
Функция LEHGTH выдает размер массива. Для Бета-Бейсика это особенно важно, поскольку этот язык программирования позволяет во время работы проводить изменения длин массивов без потери данных. Эта же функция может быть использована для определения местоположения числовой или символьной последовательности в оперативной памяти компьютера.
Параметр n определяет о какой размерности для двумерных массивов идет речь. Если n=1, то функция возвращает размер массива в первом измерении, а если n=2, то во втором измерении (или единицу, если массив одномерный). С массивами размерности больше, чем 2, эта функция работать не может.
В имени массива значимыми являются только первые два символа, поэтому следующие имена будут приняты, как правильные: a$, b$, С(, d(), a$QWERT. Если вместо имени массива ввести имя простой символьной переменной, то она будет интерпретироваться как одномерный массив, состоящий из односимвольных элементов, количество элементов при этом равно длине символьной строки.
Примеры: 10 DIM a$(10,20) 20 PRINT LENGTH (1,"а$"): (10) 30 PRINT LENGTH (2,"а$"): (20) 40 DIM b(5)
50 PRINT LENGTH (1,"b("): 15) 60 PRINT LENGTH (2,"b("): (1)
функция имеет еще одно замечательное свойство. Если вместо параметра размерности массива ввести 0, то она выдаст адрес, в котором в памяти компьютера расположен первый элемент массива или символьной строки: LENGTH (0, имя массива)
Эта возможность может быть использована теми, кто программирует в машинных кодах - можно найти адрес, в котором хранятся те или иные данные и даже можно найти адрес, с которого начинается процедура, записанная в машинных кодах, если она оформлена, как массив данных. Для тех же, кто программирует на БЕЙСИКе, имеется тоже немало интересных приложений, особенно если этой функцией пользоваться совместно с оператором РОКЕ и функцией MEMORY$. Так, например, можно продублировать массив a$ в массиве b$, что может быть полезным при реорганизации данных: 20 LET e=LENGTH(1,"a$") 30 LET f=LENGTH(2,"a$") 40 DIM b$(e,f)
50 LET start = LENGTH(0,"a$")
60 POKE LENGTH (0,"b$"),MEMORY$()(start то start+e*f-1)
Примечание: если Вы перебрасываете не символьный, а числовой массив, то в строке 60 следовало бы вместо e*f подставить 5*е*^ поскольку каждое действительное число в "Спектруме" хранится в пятибайтной форме.
Приведенный выше алгоритм во многом отличается от команды Бета-Бейсика COPY для массивов. Он, конечно, менее удобен, но может служить неплохой основой для создания на его базисе быстро работающей процедуры копирования массивов. Добавьте для этого строки:
10 DEF PROC dup REF a$, REF b$ 70 END PROC
И теперь такая команда, как dup r$,t$ продублирует символьную строку r$ в строке t$.
Замечание для опытных пользователей:
Если у Вас уже есть ранее созданный массив данных, который Вы хотели бы использовать вместе с программой, написанной на Бета-Бейсике, но который слишком велик для загрузки, Вы можете разделить его на части и представить в виде блоков кодов (CODE), а затем использовать функцию LENGTH для того, чтобы программно перебрасывать эти блоки кодов в массив.
Без Бета-Бейсика Вы можете найти начало своего массива или символьной строки, если дадите им такое имя, которое обеспечит им первое место среди переменных в соответствующей области. Сделайте их объявление первым в программе. Затем найдите искомый адрес:
PRINT PEEK 23627+256*PEEK 23628+d
Здесь d=3, если Вы ищете символьную строку: d=6, если Вы ищете начало одномерного массива и d=8, если массив - двумерный.
Так Вы получите адрес первого байта данных в области переменных, поскольку символы, строки и числовые ряды в памяти идут друг за другом в линейной последовательности. Вы легко сможете рассчитать стартовый адрес и длину блока своего массива. Помните, что символы занимают по одному байту, а числа - по пять.
Примечание: поскольку с помощью оператора LET могут создаваться новые символьные строки или изменяться ранее существовавшие, то значения, ранее полученные функцией LENGTH (0,"имя") могут устаревать.
14. MEM ()
FN M()
Эта функция выдает количество свободных байтов в оперативной памяти компьютера. В скобках ставить ничего не надо. Попробуйте, например: PRINT MEM(): DIM a$(100):PRINT MEM()
Эта простая функция содержит в себе в основной только вызов процедуры из области ПЗУ. Если Вы работаете в стандартном Бейсике, то выполнить ту же операцию можете командой
PRINT 65535 - USR 7963
15. MEMORY$ ()
FN M$()
См. также POKE симв. строка.
Эта функция выдает содержимое оперативной памяти компьютера в виде символьной строки. Правда, при этом содержимое нулевой ячейки памяти не включается. Поэтому команда
CODE MEMORY$()(1)
- то же самое, что и РЕЕК 1. Последние три байта оперативной памяти также по техническим причинам исключены, поэтому эта функция имеет максимальную длину 65532.
Конечно, если Вы попробуете что-то типа:
LET a$ = MEMORY$ (),
то Вам не хватит оперативной памяти, чтобы разместить там переменную a$, но пользоваться этой функцией надо по-другому. Например:
LET a$=MEMORY$()(16364 ТО 22527)
Если учесть способность Бета-Бейсика выполнять POKE для символьных строк, то эта функция дает программисту возможность манипуляций с большими блоками памяти при очень высокой скорости (в отличие от стандартного БЕЙСИКа). Более подробно возможности применения этой функции Вы найдете в разделе, посвященном оператору РОКЕ.
Другое применение MEMORY$ - для сканирования оперативной памяти при использовании INSTRING. Вы можете просканировать заданную секцию в памяти, указав пределы в функции MEMORY$ () (23759 ТО ...). Но функция INSTRING работает настолько быстро, что этим можно и не пользоваться, а сканировать по всей памяти целиком.
10 REM asdfg
20 PRINT INSTRING (1,MEMORY$(), "asdfg")
Эта программа найдет строку asdfg в операторе REM в строке 10. Если Вы опустите строку 10, то asdfg будет найдена в строке 20. Если Вы присвоите:
LET a$ = "asdfg",
то эта символьная строка будет найдена в области программных переменных. Таким образом, где-нибудь в памяти, но Вы найдете содержимое любой символьной строки.
Вместо "1" в функции INSTRING мы могли бы дать DPEEK (23635) , т.е. содержимое системной переменной PROG для того, чтобы начинать поиск не от начала ПЗУ, а с того места, откуда начинается БЕЙСИК-программа.
Если же Вы хотите найти все случаи повторения в памяти заданной последовательности символов (байтов), то можете делать так:
10 LET adr=1
20 LET adr=INSTRING(adr, MEMORY$ (), a$)
30 IF adr THEN PRINT adr: LET adr=adr+1: GO TO 20
Поскольку Бета-Бейсик позволяет выполнение операции РОКЕ для символьных последовательностей, Вы можете легко организовать поиск нужной последовательности и ее замену, если хорошо представляете себе то, что задумали. Так, например, разрушительной будет операция замены группы байтов на другую группу, которая длиннее первой.
16. MOD (число, число)
FN У(число, число)
Эта функция дает остаток от деления первого числа на второе.
MOD (10, 3) = 1
MOD (66,16) = 2
MOD (125,35.5) = 18.5
Нижеприведенный пример показывает, как можно избежать попыток выполнения команды PLOT вне пределов экрана.
10 FOR n=0 ТО 400
20 PLOT MOD(n, 256),MOD(n,176)
30 NEXT n
17. NUMBER (симв. строка)
FN ^симв. строка)
См. также CHAR$ (число)
Функция преобразует двухсимвольную строку в целое число от 0 до 65535. Эквивалентом в стандартном БЕЙСИКе является выражение:
LET num=256*CODE c$(1)+CODE c$(2)
Если символьная строка имеет более двух символов, выдается сообщение об ошибке "Invalid argument".
С помощью функции CHAR$ функция NUMBER может применяться для создания целочисленных массивов, в которых вместо чисел использованы их символьные эквиваленты.
18. OR (число, число)
FN O^oro, число)
Эта функция произносится так же, как и обычное ключевое слово "OR", но имеет другое действие. В программе или при вводе отличается иным синтаксисом.
Функция дает результат побитной логической операции "ИЛИ" для двух чисел, каждое из которых находится в пределах от 0 до 65535. Если какой-либо бит включен в первом или втором числе, то в результате этот бит тоже включен (равен 1). Он будет равен 0 только если он выключен в обоих числах одновременно.
19. RNDM (число)
FN R^aro)
Если "число" равно 0, то функция RNDM выдает случайное число от 0 до 1 - точно так же, как и функция RND стандартного БЕЙСИКа. Если же "число" не ноль, то функция выдает случайное целое число, лежащее в диапазоне от нуля до заданного "числа".
Эта функция работает в два с половиной раза быстрее, чем работало бы выражение RND*'^^".
10 PLOT RNDM(255),RNDM(175) 20 GO TO 10
Оператор RANDOMIZE "число" устанавливает генерируемую псевдослучайную последовательность в определенное положение точно так же, как он делает это для функции RND в стандартном БЕЙСИКе.
20. SCRN$ (строка, столбец)
FN К$(строка, столбец)
Работает примерно так же, как и стандартная функция SCREEN$, за исключением того, что может распознавать и символы графики пользователя UDG. Кроме того, исправлена ошибка системного ПЗУ, которая отражается на работе функции SCREEN$. Об этой ошибке мы писали в недавно выпущенной "ИНФОРКОМом" книге "Элементарная графика". См. также статью "Ошибки ПЗУ" в этом номере "ZX-РЕВЮ".
Перед тем, как набрать нижеприведенный пример, дайте команду KEYWORDS 0. Программа распределит по экрану символы графики пользователя в виде случайного рисунка, а затем считает некоторые из них с экрана. 10 FOR a=USR "a" TO USR "u" + 7 20 POKE a, RND*255 30 NEXT a
40 PRINT "символы графики пользователя"
50 LET a$- =""
60 FOR c=1 to 31
70 LET a$ = a$ + SCRN$(0,c)
80 NEXT с
90 PRINT a$
Блочную графику "Спектрума" эта функция не распознает. Если Вам и это необходимо, то запрограммируйте некоторые символы графики пользователя так, чтобы они выглядели, как символы блочной графики.
Символы могут распознаваться только в том случае, если они изображены в
стандартном размере 8x8 пикселов (см. CSIZE).
21. SHIFT$ (число, строка)
FN Z$(число, строка)
SHIFT$ - многоцелевая функция для преобразования строковых переменных. Она имеет много разных режимов работы. Режим задается параметром "число" при вызове функции. Вот краткий обзор ее режимов.
1. Все символы строки преобразуются в верхний регистр (в прописные буквы).
2. Все символы преобразуются в нижний регистр (в строчные буквы).
3. Регистр всех символов меняется на противоположный.
4. Подавление управляющих кодов. Все символы, являющиеся управляющими кодами, за исключением символа CHR$ 13 (код ENTER) заменяются символом "точка" (".").
5. Подавление токенов ключевых слов. Символы CHR$ 128...255 заменяются символами 0...127. При этом управляющие коды, за исключением ENTER (CHR$ 13) заменяются символом ".".
6. Подавление токенов ключевых слов. Символы CHR$ 128...255 заменяются символами 0...127, при этой все управляющие коды заменяются символом ".".
7. Все ключевые слова преобразуются из токенизированной (однобайтной) формы в многобайтную (по байту на каждый символ).
8. Все ключевые слова преобразуются из формы с полным написанием в однобайтные токены. Регистр символов роли не играет. После каждого ключевого слова должен стоять небуквеный символ.
9. То же, что и предыдущий режим, но после ключевого слова может стоять любой символ.
10.То же, что и предыдущий режим, но не все ключевые слова должны быть набраны прописными литерами.
11. То же, что и режим 8, но все ключевые слова должны быть набраны прописными буквами.
SHIFT$1...SHIFT$3
Преобразования регистров. Рассмотрим примеры: SHIFT$ (1,"Basic") = "BASIC" SHIFT$ (2,"Basic") = "basic" SHIFT$ (3,"Basic") = "bASIC"
Обычное применение этих режимов - преобразование символьных строк, вводимых пользователем, перед сравнением с контрольной строкой в диалоговых программах. 100 INPUT i$: IF SHIFT$(1,1$) ="Y" THEN GO TO 200
Это поможет вам уйти от целой последовательности сравнений, таких, как IF i$ = "Y" OR i$ = "y"
При работе с базами данных, эта функция может использоваться для того, чтобы предварительно конвертировать массив записей пользователя в верхний регистр, прежде чем давать команду SORT.
SHIFT$4...SHIFT$6
Подавление управляющих кодов и токенов ключевых слов.
Эти режимы, по-видимому, найдут широкое применение у тех пользователей, которые программируют в машинных кодах. Так, при просмотре содержимого памяти компьютера, Вам может быть захочется распечатать содержимое ячеек командой PRINT CHR$(PEEK address)
Очень скоро по этой команде Вы получите сообщение об ошибке "Invalid colour". Это произойдет как только вы попытаетесь распечатать непечатный символ.
Например, последовательность 17, 200 будет интерпретироваться, как CHR$17; CHR$200, а это в переводе c машинного языка на БЕЙСИК означает PAPER 200. Компьютер отреагирует сообщением об ошибке.
Сам формат печати при этом будет выглядеть весьма неопрятно, поскольку символы выше 127 могут быть распечатаны, как символы UDG, как символы блочной графики и как токены ключевых слов, имеющие самую разную длину.
Функция SHIFT$ позволяет справиться с этой проблемой, подавляя неприятные эффекты. В течение нескольких минут Вы сможете "прощупать" память компьютера в поисках таблиц данных, сообщений и списков ключевых слов. 100 FOR n=1 ТО 65535 STEP 704 110 PRINT SHIFT$(6,MEMORY$())(n ТО n+703) 120 PAUSE 0: CLS 130 NEXT n
Если область памяти, которую вы сканируете, содержит не машинный код, а БЕЙСИК-программу, то может быть Вам нецелесообразно отключать изображение токенов ключевых слов и достаточно только подавить управляющие коды режимом SHIFT$4.
SHIFT$7
Преобразование токенов в полную символьную запись.
Начнем с примеров:
10 LET a$ = " THEN NOT":
REM это токены 20 PRINT a$, LEN a$:
REM LEN=2 30 LET t$ = SHIFT$(7,a$) 40 PRINT t$, LEN t$: REM LEN=9
Эта функция должна быть полезной для тех, кто работает с принтером. Если принтер подключен не через стандартный "Синклеровский" интерфейс, то он не сможет воспроизводить на печать токены ключевых слов БЕЙСИКа, поскольку он о них ничего не знает.
Подобная конверсия поможет вам получать распечатки ваших БЕЙСИК-программ.
SHIFT$8...SHIFT$11
Преобразование ключевых слов из полной формы записи в токенизированную форму.
Эта функция преобразует все символьные последовательности, которые являются ключевыми словами БЕЙСИКа в токенизированную форму. Ключевое слово не будет распознано, если непосредственно перед ним стоит какая-либо буква. Что же касается символа, стоящего непосредственно за ключевым словом, то его влияние зависит от того, какой конкретно режим был избран (см. выше).
Эта функция может пригодиться в том случае, если вы примете БЕЙСИК-программу через внешний порт или через сеть от компьютера другой системы. Конвертировав записанные символами ASCII ключевые слова в токены и подправив синтаксис программы под свой "Спектрум", вы сэкономите массу времени, т. к. вам не придется набирать текст программы вручную.
22. SINE (число)
FN S(число)
Это модифицированная функция "синус". Она дает менее точный результат по сравнению с функцией SIN стандартного БЕЙСИКа, но зато работает в шесть раз быстрее.
Если для математических приложения она, может быть и не годится, зато для работы с векторной графикой, при расчете координат проекций на экране она будет хороша.
23. STRING$ (число, строка)
FN S$ (число, строка)
Эта функция дает строковую переменную, состоящую из параметра "строка", повторенного столько раз, каково значение параметра "число".
STRING$ (32,"-") = "--..... --"
(32 знака)
STRING$ (4,"АВ") = "АВАВАВАВ" PRINT STRING$(704,"Х")
- печатает экран, заполненный символами "X".
PRINT STRING$(3,"A"+CHR$ 13)
печатает: А А А
Если вам нужно сгенерировать строку, состоящую из более, чем 14 повторяющихся символов, то использовать STRING$ удобнее, чем вводить символы от руки. Кроме того, функция STRING$ работает быстрее, чем цикл FOR...NEXT, который тоже может быть применен для создания длинной регулярной строки.
Эта функция может применяться в Бета-Бейсике для заполнения блоков оперативной памяти информацией, например для установки необходимых экранных атрибутов. Для этой цели она используется совместно с функцией РОКЕ.
24. TIME$ ()
FN T$()
См. также команду CLOCK.
Эта функция выдает текущие показания встроенных часов (если они были инициализированы в Бета-Бейсике). Если Вы несколько раз повторите команду PRINT TIME$(), то всякий раз получите разный результат. В программах невредно передать показания часов какой-либо переменной и, тем самым, "заморозить'' полученный отсчет.
100 CLOCK 1
110 LET n$ = TIME$(): PRINT n$
120 PRINT "HOUrS= "; n$(1 TO 2);"Mins = ";n$(4 TO 5)
130 GO TO 110
Так можно встроить в программу контроль за временем исполнения программы пользователя. Подробности смотрите в разделе, посвященном описанию команды CLOCK.
25. USING$ (строка, число)
FN и$(строка, число)
См. также команду USING.
Функция конвертирует "число" в строковую переменную в формате, заданном параметром "строка". Вы можете задать количество изображаемых символов до десятичной точки и после. Ключевое слово USING, расположенное на клавише U обеспечивает то же самое в команде PRINT. В отличие от него, функция USING$ позволяет не только распечатать полученный результат, но и запомнить его. Она может быть использована не только с командой PRINT, но и с другими командами, допускающими работу со строковыми переменными. Более подробное описание смотрите в разделе, посвященном команде USING.
26. XOR (число, число)
FN X^a^, число)
Функция выдает результат побитной операции "ИСКЛЮЧАЮЩЕЕ ИЛИ" для двух чисел, которые должны быть в пределах от 0 до 65535. Если какой-то бит и в первом числе и во втором равны между собой, то в результате этот бит будет равен нулю. Если же они противоположны, то в результате он будет равен единице.
ПРИЛОЖЕНИЕ 1 Ключевые слова Бета-Бейсика. Версия 3.0.
КОД КЛАВИША ТОКЕН
131 |
3 |
END PROC |
132 |
4 |
RENUM |
133 |
5 |
WINDOW |
134 |
6 |
AUTO |
135 |
7 |
DELETE |
136 |
Shift 7 |
REF |
137 |
Shift 6 |
JOIN |
138 |
Shift 5 |
EDIT |
139 |
Shift 4 |
KEYIN |
140 |
Shift 3 |
LOCAL |
141 |
Shift 2 |
DEFAULT |
142 |
Shift 1 |
DEF KEY |
143 |
Shift 8 |
CSIZE |
144 |
A |
ALTER |
145 |
B |
|
146 |
C |
CLOCK |
147 |
D |
DO |
148 |
E |
ELSE |
149 |
F |
FILL |
150 |
G |
GET |
151 |
H |
|
152 |
I |
EXIT IF |
153 |
J |
WHILE |
154 |
K |
UHTIL |
155 |
L |
LOOP |
156 |
M |
SORT |
157 |
N |
ON ERROR |
158 |
O |
ON |
159 |
P |
DPOKE |
160 |
Q |
POP |
161 |
R |
ROLL |
162 |
S |
SCROLL |
163 |
T |
TRACE |
164 |
U |
USING |
Примечание:
Для того, чтобы вернуться к стандартному для "Спектрума" значению вышеуказанных кодов, нужно перейти в режим работы KEYWORDS 0.
ПРИЛОЖЕНИЕ 2.
Сообщения об ошибках Бета-Бейсика, версия 3.0.
G No room for line
Заданные параметры при перенумерации строк приводят к тому, что в результате перенумерации появляется строки с номерами из диапазона, не подлежащего перенумерации или появляются строки с номерами больше 9999.
Ошибка проявляется при работе команды RENUM.
S Missing LOOP
Оператор цикла по условию DO WHILE, DO UNTIL или оператор выхода из цикла EXIT IF не могут найти оператора конца цикла LOOP.
Ошибка проявляется при работе операторов DO WHILE, DO UNTIL, EXIT IF.
T LOOP without DO
В программе присутствует оператор LOOP, но нет соответствующего ему оператора
DO.
U No such line
В программе был использован оператор DELETE с указанием в качестве параметра номера строки, которой в программе нет.
Ошибка проявляется при работе оператора DELETE.
V No POP data
При попытке выполнить оператор POP оказывается, что стек GO SUB/ DO-LOOP/PROC - пуст. Это означает, что в данный момент времени не исполняются ни подпрограммы GO SUB, ни циклы DO-LOOP, ни процедуры PROC.
Ошибка проявляется при исполнении оператора POP.
W Missing DEF PROC
В программе была попытка исполнить процедуру, которая ранее не была определена оператором DEF PROC. То же происходит, если различаются имена процедуры при задании и при вызове. Ошибка может возникать, если встретился оператор END PROC, а процедура ранее не была объявлена через DEF PROC.
Ошибка проявляется при вызове процедур и при исполнении операторов END PROC и LOCAL.
X No END PROC
Программа во время работы пытается обойти объявление процедуры, но не может найти оператора END PROC, который соответствовал бы DEF PROC.
Ошибка проявляется при встрече оператора DEF PROC.
ПРИЛОЖЕНИЕ 3
Коды ошибок.
Ниже приведен список кодов, которые записываются в переменную ERROR по команде ON ERROR. Список состоит из трех разделов. В первом разделе перечислены состояния, связанные со стандартным БЕЙСИКОМ "Спектрума". Во втором разделе -ошибки БЕТА-БЕЙСИКА. В третьем разделе - ошибки, связанные с ИНТЕРФЕЙСОМ-1.
Примечание: Коды 0 и 9 (а они фактически ошибками не являются) не перехватываются оператором ON ERROR.
1. Для стандартного БЕЙСИКа.
Значение Код Сообщение
ERROR ошибки
0 |
0 |
О.К. |
1 |
1 |
NEXT without FOR |
2 |
2 |
variable not found |
3 |
3 |
Subscript wrong |
4 |
4 |
Out of memory |
5 |
5 |
Out of screen |
6 |
6 |
Number too big |
7 |
7 |
RETURN without GOSUB |
8 |
8 |
End of file |
9 |
9 |
Stop statement |
10 |
A |
Invalid argument |
11 |
B |
Integer out of range |
12 |
C |
Nonsense in Basic |
13 |
D |
BREAK-CONT repeats |
14 |
E |
Out of DATA |
15 |
F |
Invalid file name |
16 |
G |
No room for line |
17 |
H |
STOP in INPUT |
18 |
I |
FOR without NEXT |
19 |
J |
Invalid I/O device |
20 |
K |
Invalid colour |
21 |
L |
BREAK into program |
22 |
M |
RAMTOP no good |
23 |
N |
Statement lost |
24 |
O |
Invalid stream |
25 |
P |
FN without DEF |
26 |
Q |
Parameter error |
27 |
R |
Tape loading error |
2.. Для БЕТА-БЕЙСИКа |
|
28 |
S |
Missing LOOP |
29 |
Т |
LOOP without DO |
30 |
U |
No such line |
31 |
V |
No POP data |
32 |
W |
Missing DEF PROC |
33 |
X |
No END PROC |
3. Для ИНТЕРФЕЙСа-1 |
|
43 |
b |
Program finished |
44 |
с |
Nonsense in BASIC |
45 |
d |
Invalid stream number |
46 |
e |
Invalid device expression |
47 |
f |
Invalid name |
48 |
e |
Invalid drive number |
49 |
h |
Invalid station number |
50 |
i |
Missing name |
51 |
j |
Missing station number |
52 |
k |
Missing drive number |
53 |
l |
Missing baud rate |
54 |
m |
Header mismatch error |
55 |
n |
Stream already open |
56 |
о |
Writing to a "read" file |
57 |
p |
Reading a "write" file |
58 |
q |
Drive "write" protected |
59 |
r |
Microdrive full |
60 |
s |
Microdrive not present |
61 |
t |
File not found |
62 |
u |
Hook code error |
63 |
v |
CODE error |
64 |
w |
MERGE error |
65 |
x |
Verification has failed |
66 |
y |
Wrong file type |
На этом мы заканчиваем печать инструктивных материалов, посвященных диалектам БЕЙСИКА, выпущенным фирмой BETASOFT. За два года мы рассмотрели BETA-BASIC (версии 1.0, 1.8 и 3.0.).
Существует и еще более мощная версия 4.0, которая поддерживает работу с дисковой операционной системой. К сожалению, технической документации по этой версии у нас пока нет, а потому мы будем очень признательны тем из наших читателей, которые смогут такую документацию предоставить (на языке оригинала). Условия приобретения обсуждаются, в этом случае мы сможем довести эту информацию до самых широких кругов.