Интерпретатор BASIC — это интерпретатор , который позволяет пользователям вводить и запускать программы на языке BASIC и в начале эры микрокомпьютеров был приложением по умолчанию , которое запускали компьютеры. Ожидалось, что пользователи будут использовать интерпретатор BASIC для ввода программ или загрузки программ из хранилища (первоначально с кассет, затем с дискет ).
Интерпретаторы BASIC имеют историческое значение. Первым продуктом Microsoft , поступившим в продажу, стал интерпретатор BASIC ( Altair BASIC ), который проложил путь к успеху компании. До Altair BASIC микрокомпьютеры продавались в виде комплектов, которые нужно было запрограммировать с помощью машинного кода (например, Apple I ). В период Альтаира интерпретаторы BASIC продавались отдельно, став первым программным обеспечением, продаваемым частным лицам, а не организациям; Apple BASIC был первым программным продуктом Apple. После MITS Altair 8800 ожидалось, что микрокомпьютеры будут поставляться в комплекте с собственными интерпретаторами BASIC (например, Apple II , который имел несколько реализаций BASIC). Реакция на цену Altair BASIC от Microsoft также привела к ранней совместной разработке программного обеспечения для реализаций Tiny BASIC в целом и Palo Alto Tiny BASIC в частности.
Интерпретаторы BASIC перестали использоваться по мере того, как компьютеры росли в мощности, а связанные с ними программы становились слишком длинными, чтобы их можно было вводить в качестве разумного формата распространения. Программное обеспечение все чаще поставлялось предварительно скомпилированным и передавалось на дискетах или через системы досок объявлений , что делало необходимость в списках исходных кодов менее важной. Кроме того, все более сложные командные оболочки, такие как MS-DOS и графический интерфейс Apple Macintosh , стали основным пользовательским интерфейсом , и необходимость в BASIC действовать в качестве оболочки отпала. К середине 1980-х годов использование интерпретаторов BASIC в качестве основного языка и интерфейса к системам практически исчезло.
BASIC помог начать эру разделения времени, стал мейнстримом в эпоху микрокомпьютеров, затем исчез, превратившись в простое приложение в эпоху DOS и GUI, и сегодня выживает в нескольких нишах, связанных с разработкой игр, ретро-вычислениями и обучением.
Впервые реализованный как система компиляции, а не интерпретатор, BASIC возник как часть более широкого движения к системам разделения времени . General Electric , работавшая над системой разделения времени Dartmouth и связанным с ней Dartmouth BASIC , написала свою собственную базовую операционную систему и запустила онлайн-систему разделения времени, известную как Mark I, в которой в качестве одного из основных компонентов продаж использовался компилятор BASIC (а не интерпретатор). точки. Другие компании в развивающейся области быстро последовали этому примеру. К началу 1970-х годов BASIC был в значительной степени универсален на мэйнфреймах общего назначения. [1]
BASIC, как упрощенный язык, разработанный с учетом интегрированного редактирования строк, естественным образом подходил для портирования на рынок миникомпьютеров , который возник одновременно с услугами разделения времени. Эти машины имели очень маленькую оперативную память , возможно, всего лишь 4 КБ в современной терминологии, и им не хватало высокопроизводительного хранилища, такого как жесткие диски , которые делают компиляторы практичными. Напротив, интерпретатору потребуется меньше вычислительных ресурсов за счет производительности. В 1968 году Hewlett Packard представила HP 2000 — систему, основанную на интерпретаторе HP Time-Shared BASIC . [2] В 1969 году Дэн Пеймар и Айра Бакстер написали еще один ранний интерпретатор BASIC для Data General Nova . [3]
Одним из воздержавшихся была Digital Equipment Corporation (DEC), ведущий поставщик миникомпьютеров. Они выпустили новый язык, известный как FOCAL , на основе более раннего JOSS , разработанного на машине DEC в Стэнфордском исследовательском институте в начале 1960-х годов. JOSS во многих отношениях был похож на BASIC, а FOCAL представлял собой версию, предназначенную для работы в системах с очень маленькой памятью, особенно в PDP-8 , которая часто поставлялась с 4 КБ основной памяти . К концу 1960-х годов продавцы DEC, особенно в отделе продаж образовательных услуг, обнаружили, что их потенциальные клиенты не интересуются FOCAL и ищут свои системы в другом месте. Это побудило Дэвида Х. Ала нанять программиста для создания BASIC для PDP-8 и других машин DEC. В течение года весь интерес к альтернативам, таким как JOSS и FOCAL, исчез. [4]
Появление первых микрокомпьютеров в середине 1970-х годов продолжило бурный рост BASIC, который имел то преимущество, что был довольно хорошо известен молодым дизайнерам и любителям компьютеров, которые интересовались микрокомпьютерами, многие из которых видели BASIC на мини-компьютерах. или мейнфреймы. BASIC был одним из немногих языков, который был одновременно достаточно высоким уровнем , чтобы его могли использовать люди без подготовки, и достаточно маленьким, чтобы вписаться в микрокомпьютеры того времени. В 1972 году HP представила программируемый настольный калькулятор HP 9830A с интерпретатором BASIC Plus в постоянной памяти (ПЗУ). [5]
В июне 1974 года Альфред Уивер, Майкл Тиндалл и Рональд Дэниэлсон из Университета Иллинойса в Урбана-Шампейн в своей одноименной статье доказали возможность создания «Интерпретатора языка BASIC для микропроцессора Intel 8008». Приложение было развернуто на симуляторе 8008 для IBM 360/75 и требовало 16 КБ. [6]
В январе 1975 года был анонсирован Altair 8800 , который положил начало революции в области микрокомпьютеров . Одна из первых микрокомпьютерных версий BASIC была написана Гейтсом, Алленом и Монте-Давидоффом в соавторстве с их недавно созданной компанией Micro-Soft. Он был выпущен MITS в формате перфоленты для Altair 8800 вскоре после самой машины, [7] демонстрируя BASIC как основной язык для первых микрокомпьютеров.
В марте 1975 года Стив Возняк посетил первое собрание Домашнего компьютерного клуба и начал разрабатывать дизайн своего собственного компьютера. Члены клуба были в восторге от Altair BASIC. [8] Возняк пришел к выводу, что его машина должна иметь собственный Бейсик. В то время он работал в Hewlett Packard и использовал их диалект миникомпьютеров HP Time-Shared BASIC в качестве основы для своей собственной версии. Integer BASIC был выпущен на кассете для Apple I и поставлялся в ПЗУ при поставке Apple II летом 1977 года. [9]
Другие члены Homebrew Computer Club начали распространять копии Altair BASIC на бумажной ленте, в результате чего Гейтс написал свое « Открытое письмо любителям» , жалуясь на этот ранний пример программного пиратства . Частично в ответ на письмо Гейта, а частично для того, чтобы сделать BASIC еще меньшего размера, который можно было бы эффективно использовать на машинах с памятью 4 КБ, Боб Альбрехт призвал Денниса Эллисона написать свой собственный вариант языка. Как спроектировать и реализовать урезанную версию интерпретатора языка BASIC, было описано в статьях Эллисона в первых трех ежеквартальных выпусках информационного бюллетеня People's Computer Company , опубликованном в 1975 году, а также в реализациях с исходным кодом, опубликованных в журнале доктора Добба. Tiny BASIC Художественная гимнастика и ортодонтия: бегущий свет без лишнего байта . Это привело к появлению большого разнообразия Tiny BASIC с добавленными функциями или другими улучшениями, включая хорошо известные версии Тома Питтмана и Ли-Чен Ванга , обоих членов Homebrew Computer Club. [10] Tiny BASIC был опубликован открыто, и Ван придумал термин «авторское лево», чтобы побудить других копировать его исходный код. Любители и профессионалы создали свои собственные реализации, сделав Tiny BASIC примером проекта свободного программного обеспечения , существовавшего до движения за свободное программное обеспечение .
Многие фирмы разработали интерпретаторы BASIC. В 1976 году SCELBI представила SCELBAL для 8008 [11] , а Университет Айдахо и Ливерморская лаборатория Лоуренса объявили, что они будут публиковать в свободном доступе LLL BASIC, который включал поддержку чисел с плавающей запятой. [12] В 1977 году Apple II и TRS-80 Model I имели по две версии BASIC: уменьшенную версию, представленную в первых выпусках машин, и лицензионную версию Microsoft, представленную позже, по мере роста интереса к платформам.
Microsoft портировала свой интерпретатор на MOS 6502 , который быстро стал одним из самых популярных микропроцессоров 8-битной эпохи. Когда начали появляться новые микрокомпьютеры, такие как Commodore PET , их производители лицензировали Microsoft BASIC, адаптированный к возможностям оборудования. К 1978 году MS BASIC стал стандартом де-факто , и практически каждый домашний компьютер 1980-х годов включал его в ПЗУ . В 1980 году в рамках более крупного лицензионного соглашения, которое включало другие языки и DOS для ПК , IBM отклонила предложение Atari и вместо этого лицензировала MS-BASIC поверх своей собственной реализации, в конечном итоге выпустив четыре версии IBM BASIC , каждая из которых намного больше, чем предыдущие интерпретаторы ( например, Cartridge BASIC занимал 40 КБ). [13] Дон Эстридж , руководитель команды IBM PC , сказал: «У IBM есть отличный BASIC — он хорошо принят, быстро работает на мейнфреймах и намного более функционален, чем BASIC для микрокомпьютеров… Но [13] ] количество пользователей было бесконечно малым по сравнению с количеством пользователей Microsoft BASIC. У Microsoft BASIC были сотни тысяч пользователей по всему миру. Как вы собираетесь с этим спорить?» [14] ( Дальнейшую историю этих различных реализаций см. в Microsoft BASIC .)
Многие вендоры «с этим спорили» и пользовались услугами других фирм или писали свои интерпретаторы. В сентябре 1978 года компания Shepardson Microsystems заканчивала разработку Cromemco 16K Structured BASIC для автобусных машин Cromemco S-100 на базе Z80 . [15] [16] Пол Лотон и Кэтлин О'Брайен затем создали Atari BASIC [17] как, по сути, урезанную версию Cromemco BASIC, портированную на 6502. [18] В 1979 году Уоррен Робинетт разработал программный картридж BASIC для Atari. , Inc. , хотя поддерживала только программы с 9 строками кода (всего 64 символа). Также в 1979 году компания Texas Instruments выпустила TI BASIC с версией TI-99/4 , которая после модернизации в TI-99/4A будет продана почти 3 миллионами систем. Sinclair BASIC был разработан для ZX-80 Джоном Грантом и Стивом Викерсом из Nine Tiles. В 1980 году Софи Уилсон из Acorn Computers разработала Atom BASIC , который она позже превратила в BBC BASIC , один из первых интерпретаторов, предлагающих структурированное программирование на BASIC, с именованными / процедурами и функциями, циклами и структурами, вдохновленными COMAL . [19] [20] Ян Джонс разработал SuperBASIC , еще один британский BASIC, поддерживающий структурированное программирование, для Sinclair QL . В 1983 году Рэндалл Хайд разработал SmartBASIC для Coleco Adam . [21] Ричард Клейтон, Крис Холл и Пол Оверелл разработали Mallard BASIC для BBC Micro и Locomotive BASIC для Amstrad CPC , оба поддерживают команды для индексированной файловой системы ISAM . [22] В 1985 году MetaComCo выпустила ABasiC для Amiga и ST BASIC для Atari ST . DEF PROC
DEF FN
REPEAT UNTIL
IF THEN ELSE
В 1978 году Дэвид Лиен опубликовал первое издание « Справочника по BASIC: энциклопедия компьютерного языка BASIC» , в котором описаны ключевые слова на более чем 78 различных компьютерах. К 1981 году второе издание задокументировало ключевые слова с более чем 250 различных компьютеров, демонстрируя взрывной рост эпохи микрокомпьютеров. [23]
С появлением дисковых операционных систем и более поздних графических пользовательских интерфейсов интерпретаторы BASIC стали всего лишь одним из многих приложений, а не предоставляли первое приглашение, которое пользователь мог увидеть при включении компьютера.
В 1983 году дебютировал портативный компьютер TRS-80 Model 100 , реализация которого на Microsoft BASIC примечательна по двум причинам. Во-первых, программы редактировались с помощью простого текстового редактора ТЕКСТ, а не вводились построчно (но номера строк по-прежнему требовались). [24] Во-вторых, это был последний продукт Microsoft , который Билл Гейтс разработал лично. [25] [26]
Также в 1983 году Microsoft начала объединять GW-BASIC с DOS. Функционально идентичный IBM BASICA , его интерпретатор BASIC был полностью автономным исполняемым файлом и не нуждался в Cassette BASIC ROM, который был в исходном IBM PC . По словам Марка Джонса Лоренцо, учитывая масштабы языка, «GW-BASIC, возможно, является лучшим из семейства Microsoft BASIC с нумерацией строк, восходящего к Altair - и, возможно, даже из BASIC с нумерацией строк в целом». [27] С выпуском MS-DOS 5.0 место GW-BASIC занял QBasic .
MacBASIC представлял собой полностью интерактивную среду разработки для оригинального компьютера Macintosh и был разработан Донном Денманом, [28] Марианной Сюн, Ларри Кеньоном и Брайаном Стернсом. [29] MacBASIC был выпущен как бета-версия программного обеспечения в 1985 году и был принят для использования в таких местах, как факультет информатики Дартмутского колледжа , для использования во вводном курсе программирования. Он был обречен стать вторым BASIC, разработанным Apple, вместо BASIC от Microsoft. В ноябре 1985 года Apple внезапно прекратила проект в рамках соглашения с Microsoft о продлении лицензии BASIC на Apple II . [30] [31]
Интерпретаторы BASIC были не просто американской/британской разработкой. В 1984 году Hudson Soft выпустила Family BASIC на японском рынке для игровой консоли Nintendo Family Computer , реализацию только целых чисел, предназначенную для программирования игр, на основе Hudson Soft BASIC для Sharp MZ80 (с английскими ключевыми словами). [32] Turbo-Basic XL — это совместимый расширенный набор Atari BASIC, разработанный Фрэнком Островски и опубликованный в декабрьском номере немецкого компьютерного журнала Happy Computer за 1985 год , что делает его одним из последних интерпретаторов, опубликованных как программа ввода . Помимо интерпретатора, язык включал в себя компилятор и команды структурного программирования. Другие авторы выпустили несколько модифицированных версий, работающих с разными системами DOS. Во Франции Франсуа Лионе и Константин Сотиропулос разработали два интерпретатора BASIC с упором на мультимедиа: STOS BASIC для Atari ST в 1988 году [33] и AMOS BASIC для Amiga в 1990 году.
В мае 1991 года Microsoft выпустила Visual Basic , язык программирования, управляемый событиями, третьего поколения, известный своей моделью программирования Component Object Model (COM). [34] Visual Basic поддерживал быструю разработку приложений (RAD) приложений с графическим пользовательским интерфейсом (GUI) , доступ к базам данных с использованием объектов доступа к данным , объектов удаленных данных или объектов данных ActiveX , а также создание элементов управления и объектов ActiveX . Visual Basic использовался для разработки собственных, а также опубликованных приложений.
В 1993 году Microsoft выпустила Visual Basic для приложений , язык сценариев для приложений Microsoft Office , который заменяет и расширяет возможности более ранних языков макропрограммирования для конкретных приложений, таких как WordBASIC компании Word (который был представлен в 1989 году).
В 1996 году Microsoft выпустила VBScript в качестве альтернативы JavaScript для добавления интерактивных клиентских функций к веб-страницам , просматриваемым с помощью Internet Explorer . [35]
В 1999 году Бенуа Минизини выпустил Gambas в качестве альтернативы для разработчиков Visual Basic, решивших перейти на Linux . [36]
В 2000 году Ли Бамбер и Ричард Ваннер выпустили DarkBASIC , систему создания игр для Microsoft Windows , с сопутствующей IDE и инструментами разработки. [37]
В 2001 году SmallBASIC был выпущен для КПК Palm . [38] Еще одним интерпретатором BASIC для Palm был HotPaw BASIC, ответвление Chipmunk Basic .
В 2002 году Эммануэль Шайу, Паскаль Манури и Бруно Пагано опубликовали Tiny BASIC как пример разработки приложений с помощью Objective Caml . [39]
В 2011 году Microsoft выпустила Small Basic (отличный от SmallBASIC) вместе с учебной программой [40] и вводным руководством [41] , призванным помочь студентам, которые изучили языки визуального программирования, такие как Scratch , освоить текстовое программирование. [42] Соответствующая IDE обеспечивает упрощенную среду программирования с такими функциями, как подсветка синтаксиса , интеллектуальное завершение кода и доступ к документации в редакторе. [43] В языке всего 14 ключевых слов. [44] В 2019 году Microsoft анонсировала Small Basic Online (SBO), позволяющий студентам запускать программы из веб-браузера . [45] [46]
В 2014 году Робин Х. Эдвардс выпустил Arduino BASIC для Arduino , и теперь это широко разветвленная реализация. [47] Другая реализация с тем же названием была адаптирована из Palo Alto Tiny BASIC в 1984 году Гордоном Брэндли для его 68000 Tiny BASIC, позже перенесенного на C Майком Филдом. [48]
Многие интерпретаторы BASIC теперь доступны для смартфонов и планшетов через Apple App Store или магазин Google Play для Android.
Сегодня программирование интерпретаторов BASIC стало частью ретрокомпьютерного хобби. Языки программирования более высокого уровня в системах с большим объемом оперативной памяти упростили реализацию интерпретаторов BASIC. Например, управление строками просто, если ваш язык реализации поддерживает разреженные матрицы , управление переменными просто с помощью ассоциативных массивов , а выполнение программы легко с помощью функций оценки . В качестве примеров см. проект с открытым исходным кодом Vintage BASIC, написанный на Haskell [49] или OCaml Tiny BASIC.
Первоначально переводчики либо поставлялись в комплекте с компьютерным оборудованием, либо разрабатывались как отдельная услуга, прежде чем в конце 1960-х годов возникла отрасль, производящая независимо упакованное программное обеспечение для организаций. [50] Интерпретаторы BASIC сначала продавались отдельно от микрокомпьютеров, затем были встроены, а затем снова стали продаваться как приложения в эпоху DOS.
Когда рынок перешел на ПЗУ, размер ПЗУ стал доминировать при принятии решений о том, насколько большим может быть интерпретатор BASIC. Поскольку ОЗУ продавалось в виде микросхем емкостью 4 КБ, Altair BASIC изначально выпускался в отдельных редакциях для 4K, 8K и 12K; это перешло и на микросхемы ПЗУ, поскольку производители решали, сколько микросхем ПЗУ они могут разместить в своей конструкции, с учетом ценовых целей и других ограничений.
Первая реализация BASIC, Dartmouth BASIC , представляла собой компилятор. Как правило, компиляторы проверяют всю программу в ходе многоэтапного процесса и создают второй файл, который можно выполнить непосредственно на базовом машинном языке главного компьютера без ссылки на исходный код. Этот код часто состоит из вызовов предварительно написанных процедур в системе времени выполнения языка . Исполняемый файл обычно меньше исходного кода, в котором он был создан.
Главный недостаток компиляторов, по крайней мере в историческом контексте, заключается в том, что они требуют большого объема временной памяти. В процессе работы компилятор создает постоянно растущий выходной файл, который хранится в памяти вместе с исходным исходным кодом. Дополнительная память для временного поиска, особенно номеров строк в случае BASIC, увеличивает требования к памяти. Компьютеры той эпохи имели очень небольшой объем памяти; Говоря современным языком, типичный мэйнфрейм может иметь размер порядка 64 КБ. В системе с разделением времени, как это было в большинстве BASIC 1960-х годов, эта память распределялась между многими пользователями.
Чтобы компилятор работал, в системах должно было быть какое-то высокопроизводительное вторичное хранилище , обычно жесткий диск . Редактирование программы происходило в специальной среде, которая записывала исходный код пользователя во временный файл. Когда пользователь запускал программу, редактор закрывался и запускал компилятор, который считывал этот файл и создавал исполняемый код, а затем, наконец, компилятор завершал работу и запускал полученную программу. Такое разделение задачи уменьшило объем памяти, необходимый любой из частей общей системы BASIC; в любой момент времени нужно было загрузить только редактор, компилятор или среду выполнения, остальное находилось в хранилище.
В то время как мейнфреймы имели небольшой объем памяти, миникомпьютеры имели еще меньший объем: системы с объемом памяти 4 и 8 КБ были типичными для 1960-х годов. Но что еще более важно, миникомпьютеры, как правило, отсутствовали в какой-либо форме высокопроизводительной памяти; В большинстве ранних проектов в качестве основной системы хранения данных использовалась перфолента , а системы с магнитной лентой предназначались для верхнего сегмента рынка. В этой среде система, которая записала исходный код, скомпилировала его и затем прогнала результат, заняла бы несколько минут. Из-за этих ограничений число переводчиков увеличилось.
Интерпретаторы в конечном итоге выполняют те же основные задачи, что и компиляторы: считывают исходный код и преобразуют его в исполняемые инструкции, вызывающие функции времени выполнения. Основное различие заключается в том, когда они выполняют различные задачи. В случае компилятора весь исходный код преобразуется в ходе того, что кажется пользователю одной операцией, тогда как интерпретатор преобразует и запускает исходный код по одному оператору за раз. Результирующий машинный код выполняется, а не выводится, а затем этот код отбрасывается, и процесс повторяется со следующим оператором. Это устраняет необходимость в какой-либо форме вторичного хранилища во время сборки исполняемого файла. Основным недостатком является то, что вы больше не можете разделить различные части общего процесса: код, необходимый для преобразования исходного кода в машинные операции, должен быть загружен в память вместе со средой выполнения, необходимой для его выполнения, и в большинстве случаев редактор исходного кода, а также.
Создание языка со всеми этими компонентами, который мог бы уместиться в небольшом объеме памяти и при этом иметь место для исходного кода пользователя, является серьезной задачей, но он устраняет необходимость во вторичной памяти и был единственным практическим решением для первых миникомпьютеров и большинства компьютеров. История революции домашних компьютеров .
Разработка языка для первых интерпретаторов часто просто включала ссылки на другие реализации. Например, ссылками Возняка на BASIC были руководство HP по BASIC и копия 101 BASIC Computer Games . Основываясь на этих источниках, Возняк начал набрасывать синтаксическую схему языка. [51] Он не знал, что BASIC HP сильно отличался от разновидности BASIC DEC , используемой в 101 Games . Эти два языка принципиально различались с точки зрения обработки строк и структур управления. [52] Data General Business Basic , реализация только целых чисел, послужила источником вдохновения для Atari BASIC. [53]
Напротив, Деннис Эллисон , преподаватель факультета компьютерных наук Стэнфордского университета , написал спецификацию для простой версии языка. [54] Создать стандарт Эллисону посоветовал Боб Альбрехт из Домашнего компьютерного клуба , который видел BASIC на мини-компьютерах и чувствовал, что он идеально подойдет для новых машин, таких как Altair. Предложенная Эллисоном конструкция использовала только целочисленную арифметику и не поддерживала массивы или манипуляции со строками. Цель заключалась в том, чтобы программа умещалась в памяти от 2 до 3 килобайт. Общий дизайн Tiny BASIC был опубликован в сентябрьском выпуске информационного бюллетеня People's Computer Company (PCC) за 1975 год.
Грамматика приведена ниже в форме Бэкуса-Наура . [55] В листинге звездочка (" *
") обозначает ноль или более объектов слева от нее — за исключением первой звездочки в определении " term
", которая является оператором умножения; круглые скобки группируют объекты; а эпсилон (" ε
") означает пустой набор. Как это принято в обозначениях грамматики компьютерного языка, альтернативы выделяются вертикальной чертой (« |
»), а также перечислением в отдельных строках. Символ « CR
» обозначает возврат каретки .
строка :: = оператор числа CR | оператор CR оператор :: = PRINT список выражений IF выражение relop выражение THEN оператор GOTO выражение INPUT список переменных LET var = выражение выражение GOSUB RETURN CLEAR LIST RUN END список выражений :: = ( строка | выражение ) ( , ( строка | выражение ) ) * var-list :: = var ( , var ) * выражение :: = ( +|-|ε ) термин (( +|- ) термин ) * термин :: = фактор (( * | / ) фактор ) * коэффициент :: = var | номер | ( выражение ) var :: = A | Б | С ... | Ю | Z номер :: = цифра цифра * цифра :: = 0 | 1 | 2 | 3 | ... | 8 | 9 повторений :: = < ( >| = |ε ) | > ( <| знак равно |ε ) | "="
Этот синтаксис, каким бы простым он ни был, добавил одно нововведение: GOTO
он GOSUB
мог принимать выражение, а не номер строки, предоставляя назначенный GOTO [56] , а не оператор переключения структуры ON-GOTO/GOSUB
, более типичной для BASIC.
Sinclair BASIC использовал в качестве определения языка стандарт Minimal BASIC Американского национального института стандартов (ANSI) 1978 года, но сам по себе был неполной реализацией только с целочисленной арифметикой. [57] Стандарт ANSI был опубликован после разработки первого поколения интерпретаторов для микрокомпьютеров.
Общие компоненты интерпретатора BASIC: [58]
На ранних микрокомпьютерах не было инструментов разработки, и программисты разрабатывали свой код либо на миникомпьютерах, либо вручную. Например, Дик Уиппл и Джон Арнольд написали Tiny BASIC Extended непосредственно в машинном коде, используя восьмеричный код . [59] Роберт Уитервик от руки написал MICRO BASIC для SWTPC ( система 6800 ) на блокноте. [60] Стив Возняк написал код на Integer BASIC вручную, переведя инструкции ассемблерного кода в их эквиваленты машинного кода , а затем загрузив результат на свой компьютер. [61] (Из-за этого программу было очень трудно изменить, и Возняк не смог модифицировать ее достаточно быстро для Стива Джобса , который впоследствии лицензировал BASIC у Microsoft. [62] ).
У Гейтса и Аллена не было системы «Альтаир», на которой можно было бы разработать и протестировать свой интерпретатор. Однако Аллен написал эмулятор Intel 8008 для своего предыдущего проекта Traf-O-Data , который работал на компьютере с разделением времени PDP-10 . Аллен адаптировал этот эмулятор на основе руководства для программистов «Альтаир», и они разработали и протестировали интерпретатор на Гарвардском PDP-10. [63] Когда Гарвард прекратил использование этой системы, Гейтс и Аллен купили компьютерное время у службы разделения времени в Бостоне, чтобы завершить отладку своей программы на BASIC. Гейтс заявил в своем «Открытом письме любителям» в 1976 году, что стоимость компьютерного времени в первый год разработки программного обеспечения составила 40 000 долларов. [64]
Не то чтобы Аллен не умел писать код на машинном языке. На последнем этапе захода в аэропорт Альбукерке, чтобы продемонстрировать работу переводчика, Аллен понял, что забыл написать программу начальной загрузки для считывания ленты в память. Написав на машинном языке 8080, Аллен завершил программу до того, как самолет приземлился. Только когда он загрузил программу на «Альтаир» и увидел запрос на размер памяти системы, он понял, что интерпретатор работает на оборудовании «Альтаира». [65] [66]
Одной из самых популярных из многих версий Tiny BASIC была Palo Alto Tiny BASIC, или сокращенно PATB. PATB впервые появился в издании Dr. Dobbs в мае 1976 года , написанном на специальном языке ассемблера с нестандартной мнемоникой. Ли-Чен Ван написал свой интерпретатор в системе таймшера с помощью универсального ассемблера.
Единственным исключением из использования ассемблера было использование ALGOL 60 для интерпретатора Paisley XBASIC для больших систем Burroughs . [67] Еще одним исключением и программой ввода текста была Classic BASIC, написанная Леннартом Беншопом на Форте и опубликованная в голландском Форт-журнале Vijgeblad (выпуск № 42, 1993). [68]
Исходный код интерпретаторов часто был открытым (как в случае с Tiny BASIC) или публиковался авторами позже. Полный аннотированный исходный код и спецификации дизайна Atari BASIC были опубликованы как The Atari BASIC Source Book в 1983 году. [69]
Некоторые интерпретаторы BASIC были закодированы в промежуточном представлении виртуальной машины , чтобы добавить уровень абстракции и краткости над собственным машинным языком .
Хотя виртуальные машины использовались в системах компиляции и запуска, таких как BASIC-PLUS , они предназначались только для выполнения кода BASIC, а не для его анализа. [70] Tiny BASIC, напротив, был разработан для реализации в виде виртуальной машины, которая анализировала и выполняла (интерпретировала) операторы BASIC; в такой реализации интерпретатор Tiny BASIC сам запускается на интерпретаторе виртуальной машины. [71] Длина всей программы-интерпретатора составляла всего 120 операций виртуальной машины, состоящих из 32 команд. [72] Таким образом, выбор подхода с использованием виртуальной машины позволил сэкономить пространство памяти и усилия по реализации, хотя программы BASIC, выполняемые на ней, выполнялись несколько медленно. ( Отрывки и примеры команд см . в разделе Tiny BASIC: Реализация на виртуальной машине .) Хотя целью проекта было использование Tiny BASIC виртуальной машины, не каждая реализация делала это; среди тех, которые это сделали, были Tiny BASIC Extended, 6800 Tiny BASIC, [73] и NIBL.
Для своих компьютеров TI-99/4 и TI-99/4A компания Texas Instruments разработала виртуальную машину с языком под названием GPL, что означает «язык графического программирования». [74] (Хотя многие обвиняли в низкой производительности TI-BASIC , отчасти проблема заключалась в том, что виртуальная машина хранилась в графическом ПЗУ, которое имело медленный 8-битный интерфейс.) [75]
Непонимание ПЗУ Apple II заставило некоторых поверить, что Integer BASIC использовал виртуальную машину, специальный язык ассемблера, содержащийся в ПЗУ Apple и известный как SWEET16 . SWEET16 основан на байт-кодах , которые выполняются в простой 16-битной виртуальной машине, поэтому к памяти можно обращаться с помощью косвенных 16-битных указателей и 16-битных математических функций, вычисляемых без необходимости перевода их в базовый 8-битный 6502 с несколькими инструкциями. код. [76] Однако SWEET16 не использовался основным кодом BASIC, хотя позже он использовался для реализации нескольких утилит, таких как процедура перенумерации строк. [77]
Большинство реализаций BASIC той эпохи выступали как в качестве языкового интерпретатора, так и в качестве редактора строк . Когда BASIC работал, отображалась >
командная строка , в которой пользователь мог вводить инструкции. [78] Это было известно как « прямой режим ». При загрузке интерпретатор BASIC по умолчанию перешел в прямой режим.
Операторы, которые были введены с ведущими номерами, вводятся в память программы для «отложенного выполнения» [79] либо как новые строки, либо заменяют любые, которые ранее могли иметь тот же номер. [80] Операторы, которые вводились без номера строки , назывались командами и выполнялись немедленно. Номера строк без операторов (т. е. с последующим возвратом каретки ) удаляли ранее сохраненную строку.
Когда программа присутствует в памяти и пользователь вводит команду RUN
, система переходит в «косвенный режим». В этом режиме указатель устанавливается на первую строку программы, например, на строку 10. Исходный текст этой строки затем извлекается из хранилища и запускается так, как если бы пользователь только что набрал его в прямом режиме. Затем указатель перемещается на следующую строку, и процесс продолжается.
Различные реализации предлагали другие возможности редактирования программ. В Altair BASIC 8K была EDIT
команда перехода в режим редактирования на одну строку. Integer BASIC также включал AUTO
команду для автоматического ввода номеров строк с заданным начальным номером, например AUTO 100
, добавляя 10 к последнему номеру с каждой новой строкой. AUTO 300,5
нумерация начнется со строки 300 пятерками; 300, 305 и т. д. Автоматическую нумерацию отключали вводом MAN
. [81] Некоторые переводчики предлагали команды или утилиты перенумерации строк.
Чтобы сэкономить оперативную память и ускорить выполнение, все интерпретаторы BASIC кодировали некоторые символы строк ASCII в другие представления. Например, номера строк были преобразованы в целые числа, сохраненные в виде байтов или слов , а ключевым словам могли быть назначены однобайтовые токены (например, сохранение PRINT
как значение байта 145 в MS-BASIC). Эти представления затем будут преобразованы обратно в читаемый текст при LIST
запуске программы.
В качестве альтернативы токенизации для экономии оперативной памяти в ранних реализациях Tiny BASIC, таких как Extended Tiny BASIC, [82] Denver Tiny BASIC [83] и MINOL [84], были усечены ключевые слова: PR
for PRINT
, IN
for INPUT
, RET
for RETURN
. Полные традиционные ключевые слова не принимались.
Напротив, Palo Alto Tiny BASIC принимал традиционные ключевые слова, но позволял сокращать любое ключевое слово до минимальной уникальной строки с конечной точкой. Например, PRINT
можно было бы ввести P.
, хотя PR.
и другие варианты тоже работали. Эта система была сохранена в уровне I BASIC для TRS-80 , который использовал PATB, а также была найдена в Atari BASIC и BASIC различных карманных компьютеров Sharp . [85]
Чтобы расширить аббревиатуру, токенизатор Atari BASIC просматривает список зарезервированных слов, чтобы найти первое, соответствующее предоставленной части. Наиболее часто используемые команды идут первыми в списке зарезервированных слов, с REM
самого начала (его можно ввести как .
). При дальнейшем редактировании программы LIST
она обычно записывает полные слова. MS BASIC также допускал ?
использование краткой формы для PRINT
, но при перечислении расширял его, рассматривая как аббревиатуру, а не как синоним.
Большинство интерпретаторов BASIC выполняют по крайней мере некоторое преобразование исходной текстовой формы в различные форматы, специфичные для платформы. Tiny BASIC был прост: он только преобразовывал номер строки из десятичного формата в двоичный. Например, номер строки «100» стал однобайтовым значением, $64, что сделало его меньшим для хранения в памяти, а также более простым для поиска в машинном коде (некоторые версии Tiny BASIC допускали номера строк только от 1 до 254 или 255, хотя чаще всего используются двухбайтовые значения и номера строк от 1 до 999). Остальная часть строки осталась в исходном текстовом формате. [86] Фактически, Деннис Эллисон утверждал, что, учитывая ограничения памяти, для реализации токенизации потребуется больше кода, чем можно сэкономить. [87]
MS-BASIC пошли немного дальше, преобразовав номер строки в двухбайтовое значение, а также преобразовав ключевые слова, такие как FOR
или PRINT
, в однобайтовое значение, «токен». [88] Для значения токена был установлен старший бит, чтобы их можно было легко отличить во время выполнения. Все остальное в строке было оставлено в исходном формате, например, строка:
10 ДЛЯ I=1 ДО 10
будет токенизирован как:
$64$81 I$B211$A410
Обратите внимание, что пробел между FOR
и I
остается в маркированной строке, а имена переменных и констант не маркируются. Код, выполнявший эту токенизацию, известный как «чанкер», просто копировал все, что он не распознавал как токен, обратно в выходные данные, сохраняя пробелы как есть. Это означало, что оно PRINTA
хранилось в двух байтах, а PRINT A
в трех байтах, и удаление пробелов было распространенным способом улучшить использование памяти. [89] Sinclair BASIC немного изменил это, удалив пробелы из сохраненного кода и вставив их в код во время LIST
, так, PRINTA
чтобы казалось, что они PRINT A
еще не занимают лишний байт в памяти.
Напротив, Integer BASIC полностью преобразует строку 10 GOTO 100
в токены, которые можно немедленно прочитать и выполнить. В MS-BASIC строка будет выдавать $64 $89 100
, и во время выполнения цифру «100» придется преобразовывать в 16-битный формат каждый раз, когда она встречается. Напротив, Integer BASIC также маркировал числовые переменные, избегая этого преобразования и ускоряя выполнение. Полученное двухбайтовое значение было вставлено в токенизированный код вместе с префиксным байтом, указывающим последующее число. Префиксом было значение между $B0 и $B9 , последний полубайт значения был первой десятичной цифрой исходного значения. Вместо этого строковые литералы, такие как «HELLO WORLD», кодировались путем установки старшего бита каждого символа, чтобы он сохранялся как $C1 . Имена переменных были преобразованы таким же образом: буквы были закодированы так, чтобы их старший бит был включен, а любые цифры в имени были представлены соответствующими $B0– $ B9 , чтобы переменная была закодирована как $C1B5 (не сведено к жетону). [90] Было множество других оптимизаций; где Microsoft BASIC имел один токен для ключевого слова , Integer BASIC имел три токена: один, если за ключевым словом не следовали аргументы, один, если за ним следовало арифметическое выражение, и один, если за ним следовал строковый литерал. [91]A
A5
PRINT
Идя еще дальше, токенизатор Atari BASIC анализирует всю строку при ее вводе или изменении. Числовые константы анализируются в их 48-битной внутренней форме и затем помещаются в строку в этом формате, тогда как строки остаются в исходном формате, но с префиксом байта, описывающего их длину. Для переменных выделяется память по мере их появления, а не во время выполнения, а их имя заменяется указателем на место их хранения в памяти. Шепардсон назвал эту раннюю концепцию токенизации «интерпретатором предварительной компиляции»; операторы с синтаксическими ошибками фактически не могли быть сохранены, и пользователю немедленно предлагалось их исправить. [92]
Некоторые интерпретаторы, такие как системы Sinclair, в основном заставляли пользователя выполнять токенизацию, предоставляя специальные нажатия клавиш для ввода зарезервированных слов. Для наиболее распространенных команд требуется только одно нажатие клавиши; например, нажатие только Pв начале строки на Spectrum приводит к полной команде PRINT
. Менее частые команды требуют более сложных последовательностей клавиш. [93] Поскольку каждая строка начинается с ключевого слова ( LET
это не является обязательным), после ввода ключевого слова система возвращается к приему текста посимвольно. Одним из преимуществ этого подхода является то, что токенизатор не может путать строки с ключевыми словами. Например, он позволяет называть переменную PRINT
и выводить ее значение с помощью PRINT PRINT
.
Многие « карманные компьютеры » аналогичным образом используют одно нажатие клавиши (иногда которому предшествуют различные виды клавиш Shift) для создания одного байта (токена ключевого слова), который представляет собой полное ключевое слово BASIC, такое как EXP, SQR, IF или PEEK , например Sharp Pocket. наборы компьютерных символов и TI-BASIC . Расширение BASIC для Bally Astrocade также использует это.
Допустимые номера строк варьировались от реализации к реализации, но обычно составляли от 1 до 32767.
Большая часть памяти, используемой интерпретаторами BASIC, предназначалась для хранения самого листинга программ. Нумерованные операторы хранились в последовательном порядке в разреженном массиве , реализованном в виде линейной коллекции (технически это не список , поскольку ни один номер строки не может встречаться более одного раза).
Многие реализации Tiny BASIC хранят строки следующим образом:
Microsoft BASIC, начиная с Altair BASIC, сохранял следующие строки: [94]
LLL БАЗОВЫЙ: [95]
Максимальная длина строки варьировалась: 64 символа в Palo Alto Tiny BASIC, включая десятичное представление номера строки; 120 символов в Atari BASIC; 128 символов в Integer BASIC; [96] и 255 символов в MS-BASIC (не включая номер строки).
Интерпретаторы будут искать в программе построчно, просматривая номер каждой строки. Если бы он был меньше, чем номер новой строки, более поздние строки были бы перемещены в память, чтобы освободить место, необходимое для новой строки. Если бы это был тот же номер строки, а не одна и та же длина, последующие строки нужно было бы перемещать вперед или назад. [97] (Поскольку в памяти всегда сохранялся последовательный порядок, это не были связанные списки .)
В Tiny BASIC эти поиски требовали проверки каждого байта в строке: указатель увеличивался снова и снова, пока не встречался возврат каретки, чтобы найти байт перед следующей строкой. С другой стороны, в Altair BASIC и LLL BASIC указатель вместо этого будет установлен в начало следующей последовательной строки; это было намного быстрее, но требовало два байта на строку. Учитывая, что предполагалось, что программы Tiny BASIC будут иметь размер 4 КБ или меньше, это соответствовало общей философии дизайна Tiny BASIC, заключающейся в компромиссе между производительностью и минимизацией использования памяти.
Когда пользователь вводит LIST
командную строку, система перебирает массив строк, используя один из этих методов, преобразует номер строки обратно в десятичный формат, а затем распечатывает остальную часть текста в строке, декодируя любые токены. или другие закодированные представления.
Когда разработчики добавляли в BASIC конструкции структурированного программирования , они часто вообще устраняли необходимость в номерах строк и добавляли текстовые редакторы , а затем и интегрированные среды разработки .
Dartmouth BASIC и HP-BASIC ограничивали имена переменных максимум двумя символами (либо одной буквой, либо буквой, за которой следует одна цифра; например, от A до Z9). MS-BASIC допускал имена переменных, состоящие из букв, за которыми следовала необязательная буква или цифра (например, от A до ZZ), но игнорировал последующие символы: таким образом, можно было случайно написать программу с переменными «LOSS» и «LOAN», которая была бы рассматриваются как одинаковые; присвоение значения «LOAN» автоматически перезапишет значение, задуманное как «LOSS».
Integer BASIC необычно поддерживал имена переменных любой длины (например, SUM, GAMEPOINTS, PLAYER2), при условии, что они не содержали зарезервированного слова. [98] Ключевые слова нельзя было использовать в переменных во многих ранних версиях BASIC; «SCORE» будет интерпретироваться как «SC» ИЛИ «E», где OR — ключевое слово.
Во многих диалектах BASIC для микрокомпьютеров строковые переменные обычно выделяются суффиксом $ к их имени, а значения часто идентифицируются как строки, разделяясь «двойными кавычками». В более поздних реализациях для указания типа переменной будет использоваться другая пунктуация: A% для целого числа, A! для одинарной точности и A# для двойной точности .
За исключением массивов и (в некоторых реализациях) строк, в отличие от Паскаля и других более структурированных языков программирования, BASIC не требует объявления переменной перед обращением к ней. Значения обычно по умолчанию равны 0 (соответствующей точности) или нулевой строке.
Поскольку Tiny BASIC использовал только 26 однобуквенных переменных, переменные можно было хранить в виде массива без сохранения соответствующих им имен, используя формулу, основанную на значении ASCII буквы в качестве индекса. Palo Alto Tiny BASIC пошел еще дальше: двухбайтовые значения переменных располагались в оперативной памяти внутри программы, от байтов 130 (ASCII 65, 'A', умноженное на два) до 181 (ASCII 90, 'Z', умноженное на два). , плюс один для второго байта). [85]
Большинство BASIC предусматривали возможность иметь гораздо больше, чем 26 переменных, и поэтому требовались таблицы символов , в которых емкость памяти выделялась только для используемых переменных.
В LLL BASIC каждая запись в таблице символов хранилась следующим образом: [99]
В отличие от большинства интерпретаторов BASIC, UIUC BASIC имел хеш- функцию, хеширующую по букве имени переменной/функции/массива, а затем оттуда выполняющую линейный поиск. В UIUC BASIC запись в таблице символов была: [58]
FN
; буква ASCII)В Atari BASIC набор указателей (адресов) обозначал различные данные: имена переменных хранились в таблице имен переменных (VNTP – 82, 83 16 ), а их значения – в таблице значений переменных (указанных на VVTP – 86, 87 16 ). При таком косвенном указании имен переменных ссылке на переменную требовался всего один байт для адреса ее записи в соответствующей таблице. Строковые переменные имели свою собственную область.
Одна из оптимизаций производительности BBC BASIC включала использование нескольких связанных списков для поиска переменных, а не одного длинного списка, как в Microsoft BASIC .
Из-за небольшого объема оперативной памяти большинства систем, первоначально использовавшихся для запуска интерпретаторов BASIC, пришлось использовать умные методы управления памятью. Altair BASIC позволяет пользователям освободить место для функций тригонометрии, если они не использовались во время сеанса. PATB поместил начало наиболее распространенных подпрограмм в начале программы для использования 1-байтовым RST
кодом операции 8080 вместо 3-байтового CALL
кода операции. В LLL BASIC некоторые переменные занимали одни и те же ячейки памяти в тех случаях, когда разные переменные использовались только в командном режиме или только во время выполнения. [100]
Видео часто было адресовано к памяти, и некоторые эзотерические функции были доступны путем манипулирования значениями в определенных значениях памяти. Например, адреса с 32 по 35 содержали размеры текстового окна (в отличие от графического окна) в Applesoft BASIC. Команда POKE
и PEEK
функция (адаптированные из мониторов машинного кода, таких как монитор DECsystem-10 [101] ) обеспечивали прямой доступ к памяти для различных целей, [102] особенно для изменения специальных аппаратных регистров , отображаемых в памяти , для управления конкретными функциями компьютер, например периферийные устройства ввода/вывода. «Карты памяти» (в архаичном смысле списков адресов памяти и их функций) были популярны для использования с PEEK и POKE , причем одной из самых известных карт памяти была книга Mapping the Atari , написанная Яном Чедвиком.
Некоторые реализации интерпретатора Microsoft, например, работающие на моделях TRS-80 I/III, требовали от пользователя указания объема памяти, который будет использоваться интерпретатором. Это должно было позволить зарезервировать область памяти для установки подпрограмм машинного языка, которые могли быть вызваны интерпретируемой программой, для большей скорости выполнения. При включении моделей I/III пользователя приветствует запрос «Размер памяти?» для этой цели.
Integer BASIC, как следует из названия, использует целые числа в качестве основы для своего математического пакета. Они хранились внутри как 16-битные числа с прямым порядком байтов (как и 6502). Это позволяло использовать максимальное значение для любого расчета в диапазоне от -32767 до 32767. Вычисления, в результате которых значения выходили за пределы этого диапазона, приводили к ошибке. [103]
Большинство интерпретаторов Tiny BASIC (а также Sinclair BASIC 4K) поддерживали математические вычисления, используя только целые числа, без поддержки чисел с плавающей запятой . Использование целых чисел позволило хранить числа в гораздо более компактном 16-битном формате, который можно было читать и обрабатывать быстрее, чем 32- или 40-битные форматы с плавающей запятой, которые использовались в большинстве BASIC того времени. Однако это ограничивало его применимость в качестве языка общего назначения.
Реализации Business BASIC , такие как Data General Business Basic , также были целочисленными, но обычно с более высокой точностью: «двойная точность», т.е. 32-битная (плюс-минус 2 147 483 648) и «тройная точность» (плюс-минус 1,4x10). ^ 14).
Иногда использовались другие форматы компьютерных чисел . Например, MINOL Tiny BASIC поддерживал только беззнаковые байты , [84] , а MICRO-BASIC Tiny BASIC использовал двоично-десятичное число . [104] Но плавающая запятая стала бы преобладать.
Одна история объясняет, почему плавающая запятая считалась такой важной. На оригинальном прототипе модели TRS-80 I использовалась общедоступная версия Tiny BASIC Ли-Чен Вана . Для этого требовалось всего 2 КБ памяти для интерпретатора , оставляя в среднем еще 2 КБ свободными для пользовательских программ в обычных схемах памяти ранних машин с 4 КБ. Во время демонстрации руководителям тогдашний президент Tandy Corporation Чарльз Тэнди попытался ввести свою зарплату, но не смог этого сделать. Это произошло потому, что Tiny BASIC использовал 2-байтовые целые числа со знаком с максимальным значением 32 767. Результатом стал запрос на математические вычисления с плавающей запятой для производственной версии. [105] Это привело к замене существующего 16-битного целочисленного кода версией, использующей 32-битные числа с плавающей запятой одинарной точности, разработанной сотрудником Tandy Стивом Лейнингером. [106]
SCELBAL использовал подпрограммы с плавающей запятой , опубликованные Уодсвортом в 1975 году в книге «Программирование на машинном языке» для 8008, основанные на 32-битном (четырехбайтовом) формате для числовых вычислений, с 23-битной мантиссой , 1-битным знаком для мантиссы, 7-битным знаком. битовая экспонента и 1-битный знак экспоненты. Они были организованы в обратном порядке: младший байт мантиссы находился в первом байте, за ним следовал средний, а затем наиболее значимый байт со знаком в старшем бите. Показатель степени шел последним, опять же со знаком в старшем бите. [107] В руководстве представлен хорошо документированный ассемблерный код для всего математического пакета, включая точки входа и примечания по использованию. [108]
Консультантам обычно приходилось заниматься арифметикой с плавающей запятой — специализированной областью, хорошо изученной и разработанной для научных и коммерческих приложений, характерных для мэйнфреймов. Когда Аллен и Гейтс разрабатывали Altair BASIC, однокурсник Гарварда Монте Давидофф убедил их отказаться от целочисленной арифметики . Они наняли Давидоффа для написания пакета операций с плавающей запятой, который все еще мог бы уместиться в пределах памяти в 4 КБ. Стив Возняк обратился к Рою Ранкину из Стэнфордского университета с просьбой реализовать трансцендентные функции LOG, LOG10 и EXP; [109] однако Возняк так и не закончил добавление поддержки чисел с плавающей запятой в Integer BASIC. LLL BASIC , разработанный в Университете Айдахо Джоном Дикенсоном, Джерри Барбером и Джоном Титером, обратился к Дэвиду Миду, Хэлу Брэнду и Фрэнку Олкену за поддержкой операций с плавающей запятой. [110] Для UIUC BASIC был лицензирован пакет Datapoint 2200 с плавающей запятой. [111]
Напротив, системы с разделением времени часто полагались на аппаратное обеспечение. Например, GE-235 был выбран для реализации первой версии Dartmouth BASIC именно потому, что он имел « вспомогательный арифметический блок » для вычислений с плавающей запятой и вычислений двойной точности. [112] [113]
Ранние интерпретаторы использовали 32-битные форматы, аналогичные двоичному формату с плавающей запятой одинарной точности IEEE 754 , который определяет:
Вот значение 0,15625, сохраненное в этом формате:
Хотя в то время 32-битные форматы были распространены, более поздние версии BASIC, начиная с Microsoft BASIC для MOS 6502 , обычно использовали 40-битный (пятибайтовый) формат для большей точности. [114]
Инфиксные операторы обычно включали +
(сложение), -
(вычитание), *
(умножение), /
(деление) и показатель степени с использованием ^
символа. Относительные операции включали стандартный набор =
, >
, <
, >=
, <=
, и для «не равно» либо <>
или в стиле HP-TSB#
. [115] Бинарные операторы, такие как AND
, OR
и NOT
, присутствовали не во всех реализациях, некоторые из них выполняли булеву алгебру , а некоторые – нет.
Первоначальная редакция Dartmouth BASIC включала следующие функции: ABS
( абсолютное значение ), ATN
( арктангенс ), COS
( косинус ), EXP
( возведение e в степень), INT
(усечение любого дробного значения, возврат целого числа), LOG
( логарифм ), RND
( генератор псевдослучайных чисел ) , SIN
( синус ), SQR
( квадратный корень ) и TAN
( тангенс ). Он также включал DEF FN
оператор объявления однострочных функций, которые затем будут называться FNA()
, FNB()
и т. д.
Эта RND
функция была наиболее распространенной функцией, поддерживаемой в ранних версиях BASIC, хотя реализации различались:
RND
игнорировал этот параметр и всегда возвращал новое псевдослучайное число от 0 до 1.RND(6)+1
имитируется бросок кубика, возвращая значения от 1 до 6.RND(6)
будет возвращать значение от 1 до 6 и RND(1)
всегда будет возвращать 1. [117]Вторая версия Dartmouth BASIC поддерживала матрицы и матричные операции , полезные для решения наборов одновременных линейных алгебраических уравнений; MAT
Поддерживались матричные операции, такие как присвоение, сложение, умножение (совместимых типов матриц) и вычисление определителя.
Напротив, Tiny BASIC в первоначальном виде даже не имел никаких массивов из-за ограниченности основной памяти , доступной на ранних микрокомпьютерах , часто 4 КБ, которая должна была включать в себя как интерпретатор, так и программу BASIC. Palo Alto Tiny BASIC добавил один массив целых чисел переменной длины , размер которого не нужно было определять, но он использовал оперативную память, не используемую интерпретатором или листингом программы A()
.
SCELBAL поддерживал несколько массивов, но вместе взятые эти массивы могли содержать не более 64 элементов. Integer BASIC поддерживал одномерные массивы, размер которых ограничен только доступной памятью. [118] Tiny BASIC Extended поддерживал двумерные массивы размером до 255 на 255. Altair BASIC 4K поддерживал только массивы (одно измерение), тогда как версия 8K поддерживала матрицы размером до 34 измерений. [119]
Многие реализации поддерживали практику Dartmouth BASIC, не требующую определения размеров массива, и в этом случае предполагалось, что он содержит 11 элементов (от 0 до 10); например, {{{1}}}
в качестве побочного эффекта создаст массив из 11 элементов.
Вектор совместимости массивов менялся от реализации к реализации. Например, вектор примеси массива Altair BASIC 4K: [94]
Затем сами значения массива:
Реализации, поддерживающие матрицы, должны были записывать количество измерений и верхнюю границу каждого измерения. Кроме того, поскольку некоторые интерпретаторы имели только один тип данных (с плавающей запятой или целое число), вектору привязки нужно было просто записывать количество измерений и верхнюю границу каждого измерения. Интерпретаторам с несколькими типами данных приходилось записывать тип данных массива.
Несмотря на то, что Microsoft и другие BASIC поддерживали матрицы, матричные операции не были встроены, а должны были явно программироваться для элементов массива.
В исходном Dartmouth BASIC, некоторых его непосредственных потомках и реализациях Tiny BASIC отсутствовала обработка строк. Возникли две конкурирующие школы работы со строками, пионерами которых выступили HP и DEC, хотя позже появились и другие подходы. Для их реализации потребовались разные стратегии.
Простейшая обработка строк копировала HP Time-Shared BASIC и определяла строковые переменные как массивы символов, которые необходимо было DIM
преобразовать перед использованием. Строки в HP TSB обрабатываются как массив символов (всего до 72), а не как один многосимвольный объект. По умолчанию им выделяется один символ в памяти, и если необходима строка большей длины, их необходимо объявить. Например, будет настроена строка, которая может содержать максимум 10 символов. [120]DIM A$[10]
Доступ к подстрокам внутри строк осуществляется с использованием нотации « нарезки »: или , где подстрока начинается с самого левого символа, указанного индексом L, и продолжается до самого правого символа, указанного индексом R, или формы, в которой подстрока начинается с самого левого символа. указан индексом L и продолжается до конца строки. TSB принимает () или [] взаимозаменяемо. Индексы массива и подстроки начинаются с 1.A$(L,R)
A$[L,R]
A$[L]
Это резко контрастирует с BASICами, следующими шаблону DEC, которые используют такие функции LEFT$()
, как MID$()
, и RIGHT$()
для доступа к подстрокам. Нотация HP, позднее принятая в ANSI BASIC, также может использоваться на стороне назначения оператора LET
or INPUT
для изменения части существующего строкового значения, например or , что невозможно было сделать в ранних реализациях .100 A$[3,5]="XYZ"
120 B$[3]="CHANGE ALL BUT FIRST TWO CHARS"
LEFT$/MID$/RIGHT$
Более поздние версии Dartmouth BASIC включали строковые переменные. Однако они не использовали LEFT$/MID$/RIGHT$
функции для управления строками, а вместо этого использовали CHANGE
команду, которая преобразовывала строку в эквивалентные значения ASCII и обратно. (Позже принято DEC как есть и адаптировано HP, которая изменила ключевое слово на CONVERT
. [120] ). Кроме того, можно использовать одинарные кавычки для преобразования числовой константы в символ ASCII, что позволяет создавать строку по частям. ; A$='23 '64 '49 "DEF"
создал строку «ABCDEF» без необходимости использования функции CHR$()
. [120] Поддерживается шестое издание Dartmouth BASIC SEG$
(для MID$
) и POS
(для INSTR
).
Integer BASIC, North Star BASIC [121] и Atari BASIC [122] имитировали подход HP, который снова контрастировал со стилем, найденным в BASIC, производных от DEC , включая Microsoft BASIC , где строки являются внутренним типом переменной длины. [123]
Некоторые реализации Tiny BASIC поддерживали один или несколько предопределенных целочисленных массивов, которые можно было использовать для хранения кодов символов, при условии, что язык имел функциональность для ввода и вывода кодов символов (например, в Astro BASIC для этой цели имелся KP
и ).TV
Использование строками фиксированного объема памяти независимо от количества используемых в них символов (максимум до 255 символов) могло привести к пустой трате памяти [124] , но имело то преимущество, что можно было избежать необходимости реализации сборки мусора в куче . форма автоматического управления памятью, используемая для освобождения памяти, занятой строками, которые больше не используются. Освобожденные короткие строки могут храниться посреди других строк, предотвращая использование этой памяти, когда требуется более длинная строка.
На ранних микрокомпьютерах с их ограниченной памятью и медленными процессорами сборка мусора в BASIC часто могла вызывать случайные, необъяснимые паузы в процессе работы программы. Некоторые интерпретаторы BASIC, такие как Applesoft BASIC в семействе Apple II , неоднократно сканировали строковые дескрипторы в поисках строки, имеющей самый высокий адрес, чтобы сжать ее в большую память, что приводило к производительности O(n 2 ) , что могло привести к минутным затратам времени. приостанавливает выполнение строковых программ. В других версиях Microsoft BASIC сбор мусора работал очень медленно или даже некорректно. [125] Некоторые операционные системы, которые поддерживали фоновые задачи, управляемые прерываниями, такие как TRSDOS/LS-DOS 6.x на TRS-80 Model 4 , использовали периоды бездействия пользователя (например, периоды длительностью в миллисекунды между нажатиями клавиш и периоды после обновление видеоэкрана) для обработки сборки мусора во время работы программы BASIC.
Большинство интерпретаторов BASIC сильно различались по графике и звуку, которые сильно различались от микрокомпьютера к микрокомпьютеру. В Altair BASIC отсутствовали какие-либо графические или звуковые команды, как и в реализациях Tiny BASIC, тогда как Integer BASIC предоставлял богатый набор.
Уровень I BASIC для TRS-80 имел минимально возможный набор: CLS
, для CLear Screen; SET(X,Y)
, который подсветил место на дисплее; RESET(X,Y)
, который отключил его; и POINT(X,Y)
, который возвращал 1, если локация была освещена, и 0, если нет. Координаты могут быть любым выражением и находиться в диапазоне от 0 до 127 для оси X и от 0 до 47 для оси Y. Поддерживался только черно-белый дисплей. [126]
Напротив, Integer BASIC поддерживал цветную графику, простой звук и игровые контроллеры. Графический режим был включен с помощью GR
оператора и выключен с помощью TEXT
. [127] Рисование было модальным и обычно начиналось с подачи команды на изменение цвета, что достигалось установкой псевдопеременной; COLOR=12
установит цвет рисунка на 12, светло-зеленый. Затем можно было PLOT 10,10
создать одно пятно этого цвета, [128] HLIN 0,39 AT 20
нарисовать горизонтальную линию в строке 20, охватывающую экран, или VLIN 5,15 AT 7
нарисовать более короткую вертикальную линию вниз по столбцу 7. [129] A=SCRN X,Y
вернул цвет экрана в позиции X. , Ю. [130] [б]
Производители оборудования часто включали собственную поддержку полуграфики , простых фигур и значков, рассматриваемых как специальные символы . Примеры включали блочную графику ZX-81 и карточные символы ♠, ♣, ♥ и ♦ в наборе символов Commodore International PETSCII . BASIC мог генерировать эти символы, используя PRINT CHR$();
.
Microsoft добавила в IBM BASIC множество графических команд : LINE
, PSET
(Pixel SET), PRESET
(Pixel RESET), GET
(сохраняет прямоугольник экрана в массиве), PUT
(отображает сохраненный прямоугольный сегмент), LOCATE
(для перемещения текстового курсора) и DRAW
, который рисует фигуры, используя синтаксис типа LOGO . Билл Гейтс и Нил Конзен написали DONKEY.BAS , идущую в комплекте игру, для демонстрации цветной графики и звука интерпретатора . [131]
Другая область, где реализации расходились, заключалась в ключевых словах для работы с носителями (кассеты и дискеты), вводом с клавиатуры и игровыми контроллерами (если таковые имеются).
Поскольку интерпретаторы BASIC на базе ПЗУ часто функционировали как оболочки для загрузки в другие приложения, в реализации добавлялись команды, связанные с кассетами (например, CLOAD
и CSAVE
), двоичными дисковыми файлами (например, BLOAD
, BSAVE
и BRUN
) и программами BASIC на диске (например, LOAD
, SAVE
, и CATALOG
). В реализации Business BASIC добавлены команды для файлов с произвольным доступом. (Даже интерпретаторы BASIC на базе ПЗУ не были разработаны и не предназначались для использования в качестве операционных систем, а на микрокомпьютерах меньшего размера вообще не было никакой ОС. [132] ).
В Dartmouth BASIC не было команды для ввода данных с клавиатуры без приостановки работы программы. Для поддержки видеоигр в BASIC были добавлены собственные команды: INKEY$
это была функция в Microsoft BASIC , которая возвращала пустую строку, если не была нажата ни одна клавиша, или в противном случае один символ; KP
(для KeyPress ) вернул значение ASCII ввода в Astro BASIC .
В Palo Alto Tiny BASIC не было строк, но он позволял пользователям вводить математические выражения в качестве ответа на INPUT
утверждения; задав переменные, такие как Y=1; N=0
, пользователь мог ответить «Y», «1» или даже «3*2-5» на запрос «да/нет».
Некоторые системы поддерживали игровые контроллеры. Поддерживается Astro BASIC JX()
(заданное горизонтальное положение джойстика), JY()
(вертикальное положение джойстика), KN()
(состояние ручки) и TR()
(состояние триггера). Integer BASIC поддерживал игровой контроллер , манипулятор , который имел два контроллера на одном разъеме. Положение контроллера можно прочитать с помощью PDL
функции, передав номер контроллера 0 или 1, например A=PDL(0):PRINT A
, возвращая значение от 0 до 255. [133] [c]
В Integer BASIC отсутствовали какие-либо пользовательские команды ввода/вывода, а также DATA
оператор и связанный с ним файл READ
. Чтобы вводить данные в программу и из нее, функция ввода/вывода перенаправлялась в выбранный слот карты с помощью PR#x
и IN#x
, которые перенаправляли вывод или ввод (соответственно) в пронумерованный слот. С этого момента данные можно было отправлять на карту с помощью обычных PRINT
команд и считывать с нее с помощью INPUT
. [130] Создание звуков осуществлялось путем PEEK
определения местоположения в памяти простого «бипера», -16336. [д]
Хотя структурное программирование на примерах АЛГОЛ 58 и АЛГОЛ 60 было известно Кемени и Курцу, когда они разрабатывали BASIC, они адаптировали только цикл for, игнорируя оператор else, цикл while, повторяющийся цикл, именованные процедуры, параметр передача и локальные переменные. В результате последующие диалекты часто резко различались по формулировкам, используемым для структурированных техник. Например, WHILE...WEND
(в Microsoft BASIC ), WHILE...ENDWHILE
(в Turbo-Basic XL ) DO...LOOP WHILE
и даже WHILE
предложения (оба в BASIC-PLUS ).
Из реализаций Tiny BASIC только National Industrial Basic Language (NIBL) предлагал какие-либо команды цикла, DO/UNTIL
. [135] И это несмотря на то, что изобретатель Tiny BASIC Деннис Эллисон публично сокрушался о состоянии BASIC. [136]
BBC BASIC был одним из первых интерпретаторов микрокомпьютеров, предложивших структурированное программирование на BASIC с именованными DEF PROC
/ DEF FN
процедурами и функциями, REPEAT UNTIL
циклами и IF THEN ELSE
структурами, вдохновленными COMAL . BASIC второго поколения — например, SBASIC (1976), BBC BASIC (1981), True BASIC (1983), Beta BASIC (1983), QuickBASIC (1985) и AmigaBASIC (1986) — представили ряд функций в язык, в первую очередь связанный со структурным и процедурно-ориентированным программированием. Обычно нумерация строк опускается в языке и заменяется метками (для GOTO ) и процедурами , чтобы обеспечить более простой и гибкий дизайн. [137] Кроме того, были введены ключевые слова и структуры для поддержки повторения, выбора и процедур с локальными переменными.
Следующий пример приведен в Microsoft QBASIC, третьей реализации структурированного BASIC от Microsoft (после Macintosh BASIC в 1984 году и Amiga BASIC в 1985 году). [138]
Пример REM QBASICОбъявление REM Forward — позволяет основному коду вызывать подпрограмму REM, которая определена позже в исходном коде DECLARE SUB PrintSomeStars ( StarCount! ). REM Основная программа следует за DO INPUT «Сколько звезд вы хотите? (0, чтобы выйти)» , NumStars CALL PrintSomeStars ( NumStars ) LOOP WHILE NumStars > 0 END Определение подпрограммы REM SUB PrintSomeStars ( StarCount ) REM Эта процедура использует локальную переменную Stars $ Stars$ = STRING$ ( StarCount , " *" ) PRINT Stars$ END SUB
Первоначальная поддержка объектно-ориентированного программирования предусматривала только повторное использование объектов, созданных с помощью других языков, например, как Visual Basic и PowerBASIC поддерживали объектную модель компонентов Windows . По мере развития интерпретаторов BASIC в них добавлялась поддержка объектно-ориентированных функций, таких как методы , конструкторы , динамическое выделение памяти , свойства и временное выделение.
ПЗУ Integer BASIC также включали монитор машинного кода , «миниассемблер » и дизассемблер для создания и отладки программ на языке ассемблера . [90] [139] [140]
Одной из уникальных особенностей BBC BASIC был встроенный ассемблер , позволяющий пользователям писать программы на языке ассемблера для 6502 , а позже и для Zilog Z80 , NS32016 и ARM . Ассемблер был полностью интегрирован в интерпретатор BASIC и общие с ним переменные, которые можно было включать между символами [ и ], сохранять с помощью *SAVE и *LOAD и вызывать с помощью команд CALL или USR. Это позволило разработчикам писать не только код на языке ассемблера, но и код BASIC для создания языка ассемблера, что позволило использовать методы генерации кода и даже писать простые компиляторы на BASIC.
Как и в большинстве BASIC, программы запускались с помощью этой RUN
команды и, как обычно, могли быть направлены на определенный номер строки, например RUN 300
. [141] Выполнение можно остановить в любой момент, нажав + [142] (или BREAK, например, на TRS-80), а затем перезапустить с помощью inue ( в Integer BASIC). [143] Воспользовавшись уникальными возможностями интерпретируемых программ (код обрабатывается в реальном времени по одному оператору, в отличие от компиляторов ), пользователь за консолью мог просматривать переменные данные с помощью оператора PRINT и изменять такие данные по- the-fly, а затем возобновите выполнение программы. CtrlCCONT
CON
Для пошагового выполнения инструкцию TRON
или TRACE
можно использовать в командной строке или поместить в саму программу. Когда он был включен, номера строк распечатывались для каждой строки, которую посетила программа. Эту функцию можно снова отключить с помощью TROFF
или NOTRACE
. [144]
Некоторые реализации, такие как интерпретаторы Microsoft для различных марок TRS-80, включали команду ON ERROR GOSUB
. Это перенаправит выполнение программы на указанный номер строки для специальной обработки ошибок.
В отличие от большинства BASIC, Atari BASIC сканировал только что введенную строку программы и немедленно сообщал о синтаксических ошибках. Если обнаруживалась ошибка, редактор заново отображал строку, выделяя текст возле ошибки в инверсном видео .
Во многих интерпретаторах, включая Atari BASIC, ошибки отображаются в виде числовых кодов с описаниями, напечатанными в руководстве. [145] Многие MS-BASIC использовали двухсимвольные сокращения (например, SN для SYNTAX ERROR). Palo Alto Tiny BASIC и Level I BASIC использовали три слова для сообщений об ошибках: «ЧТО?» для синтаксических ошибок: «КАК?» для ошибок во время выполнения, таких как GOTO к несуществующей строке или числового переполнения, и «ИЗВИНИТЕ» для проблем с нехваткой памяти.
Хотя язык BASIC имеет простой синтаксис, математические выражения его не поддерживают, поддерживая разные правила приоритета для круглых скобок и различных математических операторов. Для поддержки таких выражений требуется реализация анализатора рекурсивного спуска . [146]
Этот парсер можно реализовать несколькими способами:
Диапазон проектных решений, которые были приняты при программировании интерпретатора BASIC, часто проявлялся в различиях в производительности.
Реализации линейного управления часто влияли на производительность и обычно использовали линейный поиск . Разделение каждой строки с помощью CR приведет к тому, что переход к более поздней строке GOTO или GOSUB займет больше времени, поскольку программе придется перебирать все строки, чтобы найти целевой номер строки. В некоторых реализациях, таких как Atari BASIC, длина каждой строки записывалась и сохранялась после номера строки, так что программе не приходилось сканировать каждый символ строки, чтобы найти следующий возврат каретки. Многие реализации всегда будут искать номер строки, к которой можно перейти от начала программы; MS-BASIC будет выполнять поиск с текущей строки, если номер строки назначения больше. Питтман добавил к своему 6800 Tiny BASIC патч, позволяющий использовать бинарный поиск. [148]
Работа исключительно с целочисленной математикой обеспечивает еще один значительный прирост скорости. Поскольку многие компьютерные тесты той эпохи были небольшими и часто выполняли простые математические вычисления, не требующие операций с плавающей запятой, Integer BASIC превзошел большинство других BASIC. [e] В одном из первых известных тестов микрокомпьютеров, тестах Rugg/Feldman , Integer BASIC был более чем в два раза быстрее, чем Applesoft BASIC на той же машине. [150] В Byte Sieve , где математика была менее важна, но доминировали доступ к массиву и производительность циклов, Integer BASIC занимал 166 секунд, а Applesoft — 200. [151] Он не появлялся в Creative Computing Benchmark , который был впервые опубликован в 1983 году. , к этому времени Integer BASIC больше не поставлялся по умолчанию. [152] Следующая серия тестов, взятая из обеих оригинальных статей Rugg/Feldman, [150] [149] показывает производительность Integer по сравнению с BASIC, производным от MS, на той же платформе.
Теоретически Atari BASIC должен был работать быстрее, чем современные BASIC, основанные на шаблоне Microsoft. Поскольку исходный код полностью токенизирован при вводе, все этапы токенизации и анализа уже завершены. Даже сложные математические операции готовы к выполнению: все числовые константы уже преобразованы во внутренний 48-битный формат, а значения переменных ищутся по адресу, а не искать их. Несмотря на эти теоретические преимущества, на практике Atari BASIC медленнее, чем другие BASIC для домашних компьютеров , часто значительно. [153] На практике это не подтвердилось. В двух широко используемых тестах того времени, Sieve of Eratosthenes журнала Byte и тесте Creative Computing , написанном Дэвидом Х. Алом , Atari финишировала ближе к концу списка с точки зрения производительности и была намного медленнее, чем современный Apple II. или Commodore PET , [154] несмотря на то, что у них тот же процессор, но он работает примерно в два раза быстрее, чем любой из них. Он финишировал позади относительно медленных машин, таких как Sinclair ZX81 , и даже некоторых программируемых калькуляторов. [155]
Большая часть медлительности языка связана с тремя проблемами. [153] Во-первых, математические процедуры с плавающей запятой были плохо оптимизированы. В тесте Ahl операция с одной экспонентой, которая внутренне перебирает функцию медленного умножения, была причиной большей части плохих результатов машины. [153] Во-вторых, преобразование между внутренним форматом с плавающей запятой и 16-битными целыми числами, используемыми в некоторых частях языка, было относительно медленным. Внутри эти целые числа использовались для номеров строк и индексации массивов, а также для некоторых других задач, но числа в токенизированной программе всегда хранились в двоично-десятичном формате (BCD). [156] Всякий раз, когда один из них встречается, например, в номере строки в GOTO 100
, токенизированное значение BCD должно быть преобразовано в целое число, операция, которая может занять до 3500 микросекунд. [157] Другие BASIC избегали этой задержки за счет специального преобразования чисел, которые могли быть только целыми числами, например, номера строки после GOTO
, переключившись на специальный код преобразования ASCII в целое число для повышения производительности. В-третьих, как Atari BASIC реализовывал ветвления и FOR
циклы. Чтобы выполнить переход в a GOTO
или GOSUB
, интерпретатор ищет во всей программе соответствующий номер строки, который ему нужен. [158] Одним из незначительных улучшений, обнаруженных в большинстве BASIC, производных от Microsoft, является сравнение номера целевой строки с текущим номером строки и поиск вперед от этой точки, если он больше, или начало сверху, если меньше. Это улучшение отсутствовало в Atari BASIC. [153] В отличие от почти всех других BASIC, которые помещали указатель на местоположение FOR
в стеке, поэтому, когда он достигал, NEXT
он мог легко вернуться к FOR
снова в одной операции ветвления, Atari BASIC вместо этого помещал номер строки. Это означало, что каждый раз, когда встречалось a NEXT
, системе приходилось просматривать всю программу, чтобы найти соответствующую FOR
строку. В результате любые циклы в программе Atari BASIC приводят к значительному снижению производительности по сравнению с другими BASIC. [153]
A=SCRN(X,Y)
.Краткое изложение положительных моментов: Visual Basic прост в освоении и широко доступен.
Поскольку TA очень велика (19 703 байта), я обнаружил, что выполнение стало мучительно медленным просто из-за сканирования памяти на предмет GOTO, GOSUB и RETURN.
Простой патч к интерпретатору преобразует его в
алгоритм двоичного поиска
, что ускоряет время выполнения примерно на порядок.
Необходимые изменения перечислены в Приложении.
Исходный код и проектная документация в хронологическом порядке выпуска реализаций BASIC: