Пишем компилирующий интерпретатор SHABASIC для 8080/8085

Советский компьютер Радио-86РК (1986) и его клоны

Moderator: Shaos

User avatar
Shaos
Admin
Posts: 24008
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Пишем компилирующий интерпретатор SHABASIC для 8080/8085

Post by Shaos »

Shaos wrote: Подумалось мне, что наверное можно сделать «глубокую» интеграцию этого нового Бейсика в ShaOS! Например в ОС уже есть редактор командной строки - почему бы им не воспользоваться? При вводе строки начинающейся с числа, командный процессор не будет искать команду с именем равным этому числу, а передаст всю строку на обработку в некий “Numeric Handler”, зарегистрированный в системе, и этот хендлер просто вызовет компиляцию введённой строки в память! Точно также например введя EDIT 100 команда EDIT выведет содержимое строки с номером 100 в буфер ввода редактора командной строки и даст возможность пользователю её редактировать. Также отдельными командами (программами в COM, EXE или SYS формате) могут быть LIST, RUN и SAVE/LOAD (или это будут созданные специально для Бейсика BSAVE/BLOAD).
Скажем у нас будет основной бинарь бейсика SHABASIC.EXE
ShaOS будет поддерживать простейшие BAT-файлы, которые будут пробоваться первыми, если имя команды задано без расширения.
Соответственно можно создать несколько BAT-файлов следующего содержания (тут $ будет означать все аргументы как есть):

NEW.BAT:
SHABASIC /N

EDIT.BAT:
SHABASIC /E $

LIST.BAT:
SHABASIC /L $

RUN.BAT:
SHABASIC /R $

BLOAD.BAT:
SHABASIC /I $

BSAVE.BAT:
SHABASIC /O $

SHABASIC будучи запущенным первый раз останется в памяти и будет исполняться прямо из памяти при всех последующих вызовах...

P.S. Диалоговый режим работы Бейсика также можно организовать через SHABASIC - если первым аргументом будет не опция начинающаяся с /, то это должно считаться командой Бейсика - например:
SHABASIC PRINT 10+20
SHABASIC LET A%=100
и т.д. (по идее можно понаделать ещё BAT-файлов типа PRINT.BAT: SHABASIC PRINT $ и т.д. - в этом случае SHABASIC каждый раз писать будет ненужно)
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24008
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Пишем компилирующий интерпретатор SHABASIC для 8080/8085

Post by Shaos »

При загрузке программы через BLOAD PROGRAM.BAS она будет скомпилирована в памяти и все дальнейшее редактирование текста программы будут вызывать построчную инкрементальную компиляцию.

Также можно создать программу с нуля выполнив NEW и затем добавляя строки одну за другой - при этом каждая новая строка будет запускать инкрементальную компиляцию этой строки и связанные с этим действия (как например замену всех ссылок на эту строку, если адрес компиляции изменился).

Дальнейшее сохранение программы BSAVE PROGRAM.BAS сохранит только текстовую часть, проигнорировав откомпилированную. Для сохранения откомпилированной части надо будет сделать сохранение в перемещаемом EXE-формате: BSAVE PROGRAM.EXE

ShaOS предоставляет сервис по аллокации блоков памяти, привязанных к процессу (в данном случае SHABASIC) - блоки выделяются размерами кратными 256 байт. У нас будет 2 типа аллокаций - для строк текста программы и для откомпилированного "шитого" кода. На все эти аллокации будет указывать карта ссылок, где каждой строке программы может быть отведено 8 байт:
2 байта - номер Бейсик строки (1...32767);
2 байта - адрес строки в текстовом виде (#0000...#FFFF);
2 байта - адрес откомпилированного "шитого" кода для этой строки (#0000...#FFFF);
2 байта - длина откомпилированного кода (может быть больше 256 байт).

В один 256-байтный блок влезает 32 таких записи - в начале работы, когда бейсик программа пустая, весь этот блок заполнен нулями.

Далее пользователь вводит первую строку:
10 CLS
После чего в карте ссылок появится первая запись:
10,#7F00,#7E00,9
где #7F00 является адресом строки "10 CLS",0
а #7E00 является адресом подпрограммы
CALL CHECK_BREAK
CALL BAS_CLS
JMP BAS_STOP
(адреса #7E00 и #7F00 взяты для примера - они просто указывают на два разных выделенных через систему 256-байтных блока памяти)

При добавлении пользователем следующей строки JMP в конце предыдущей строки будет заменён на адрес скомпилированной подпрограммы для вновь введённой строки.

Если пользователь меняет уже введённую строку, то её строковое представление и откомпилированное представление заменяется на новое - оно может занимать меньше места, чем занимало старое представление либо больше места - в этом случае строка создаётся в новом месте, а старое место освобождается и высвободившиеся в обоих случаях байты объявляются свободными для возможного дальнейшего использования (наверное где-то отдельно надо вести учёт этим свободным цепочкам байтов либо подразумевать, что любая цепочка байт, где идёт три или более #FF подряд считается свободной).
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24008
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Пишем компилирующий интерпретатор SHABASIC для 8080/8085

Post by Shaos »

Начать можно с 26 целочисленных переменных A%...Z% которые будут занимать 52 байта и как описывалось выше, у нас будет стек данных, который будет использоваться для передачи аргументов в команды с параметрами - по идее можно попробовать объединить стек данных и стек возвратов, как у меня уже было сделано в nedoPC SDK (там у меня вершина стека всегда хранилась в регистровой паре HL, а всё то что лежит глубже хранится в стеке возвратов) - в таком случае вызываемая подпрограмма, зная сколько у неё аргументов, будет вытаскивать их из стека, предварительно вызвав адрес возврата для его обратного засовывания:

Code: Select all

; POKE #7FFF, #00
  LXI H,#00
  PUSH H
  LXI H,#7FFF
  PUSH H ; можно опустить если мы примем, что вершина стека данных всегда сидит в HL
  CALL BAS_POKE
  ...
BAS_POKE:
  POP B ; временно вытаскиваем адрес возврата
  POP H ; вытаскиваем первый аргумент - можно опустить, если мы примем, что вершина стека данных всегда сидит в HL
  POP D ; вытаскиваем второй аргумент
  PUSH B ; засовываем адрес возврата обратно
  MOV M,E
  RET
Для выражений после LET придётся повторить на ассемблере 8080 алгоритм разбора длинных выражений из моего компилятора Robby после чего выражение будет превращено в вычисления на стеке:
https://gitlab.com/nedopc/sdk/-/blob/master/robbyc/robbyc2.c
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24008
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Пишем компилирующий интерпретатор SHABASIC для 8080/8085

Post by Shaos »

Shaos wrote:У нас будет 2 типа аллокаций - для строк текста программы и для откомпилированного "шитого" кода. На все эти аллокации будет указывать карта ссылок, где каждой строке программы может быть отведено 8 байт...
На самом деле все эти аллокации можно замесить вместе - просто заполняя всю доступную память от нижних адресов к высоким.
Либо городить тексты в высоких адресах, а код - в низких, что даст возможность если надо сохранять скомпилированный код цельным куском в неперемещаемом формате COM прям как есть.
Наверное даже можно первый прототип написать на языке высокого уровня - чисто на посмотреть насколько быстрый код будет получаться у такого "компилирующего интерпретатора"...
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24008
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Пишем компилирующий интерпретатор SHABASIC для 8080/8085

Post by Shaos »

Подобный же подход можно и на других процессорах организовать - например MIPS (PIC32) или RISC-V...
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24008
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Пишем компилирующий интерпретатор SHABASIC для 8080/8085

Post by Shaos »

Shaos wrote:Начать можно с 26 целочисленных переменных A%...Z% которые будут занимать 52 байта...
В будущем можно ещё и длинные целые поддержать - имя& ;)

Для плавающей точки под 8080 можно для начала взять 3-байтовую либу из Электроники МС2721:
Shaos wrote:3-байтовые числа с плавающей точкой в памяти располагаются так:
1й байт - экспонента: 1 бит знак, 7 битов - само число (представляет числа от -127 до +127);
2й байт - старший байт мантиссы: 1 бит знак, 1 бит переполнения, оставшиеся 6 битов - старшие биты мантиссы;
3й байт - младший байт мантиссы: 8 битов, которые с 6 битами из предыдущего байта формируют 14 бит мантиссы (т.е. 16383 это самое большое число, среди чисел, которые можно отобразить без потери точности подряд).
Мантисса представляет собой биты после десятичной точки, т.е. 00 20 00 означает 0.5 (соответственно 01 20 00 это 1, а 00 00 00 это 0)

P.S. Получается, что самое маленькое число (по абсолютному значению и неравное нулю), которое можно отобразить в этой системе, это FF 00 01 = (1/16384)*2^(-127) = 3.587324068671532e-43, а самое большое - 7F 2F FF = 16383/16384*2^127 = 1.7013079886675216e+38 (правда документация пишет про 0.5867e-38 и 0.1704e+39 соответственно - второе похоже, а вот первое - не очень)

P.P.S. Возможно в документации речь идёт о нормализованном представлении, когда старший бит мантиссы всегда 1 - тогда самым маленьким числом будет FF 20 00 = 0.5*2^(-127) = 2.938735877055719e-39 (что примерно в 2 раза меньше того, что задокументировано)
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Alikberov
Doomed
Posts: 347
Joined: 14 Oct 2019 18:10
Location: Tashkent

Re: Можно портануть к нам в ПЗУ новый маленький Бейсик!

Post by Alikberov »

Только вот на днях делал набросок Бейсика с подобием P-Кода.
Листинг, в отличии от традиционных Бейсиков, не кодируется токенами, которые в режиме интерпретации нужно декодировать, а записываются прямыми CALL-вызовами. То есть, сам листинг - практически откомпилированный исходный код.
  • В режиме отображения листинга вызов «CALL PRINT» просто печатает на экране «PRINT»…
  • В режиме исполнения, все вызовы типа «CALL PRINT» исполняются как и следует…
Вот пример кода:
You do not have the required permissions to view the files attached to this post.
User avatar
Shaos
Admin
Posts: 24008
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Можно портануть к нам в ПЗУ новый маленький Бейсик!

Post by Shaos »

Это ты решил мою задумку реализовать? ;)

P.S. Перенёс нашу беседу в правильный топик
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Alikberov
Doomed
Posts: 347
Joined: 14 Oct 2019 18:10
Location: Tashkent

Re: Можно портануть к нам в ПЗУ новый маленький Бейсик!

Post by Alikberov »

Shaos wrote:Это ты решил мою задумку реализовать? ;)

 Оффтоп
opozdal.jpg

You do not have the required permissions to view the files attached to this post.
User avatar
Shaos
Admin
Posts: 24008
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Можно портануть к нам в ПЗУ новый маленький Бейсик!

Post by Shaos »

Ну давай объединим усилия :)
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Alikberov
Doomed
Posts: 347
Joined: 14 Oct 2019 18:10
Location: Tashkent

Re: Пишем компилирующий интерпретатор SHABASIC для 8080/8085

Post by Alikberov »

Мой план немножечко отличается.

Проограмма может запускаться в трёх режимах:
  1. Холодный Пуск / Первый Прогон - с исполнением всего кода от начала до конца в порядке описания листинга, чтобы собрать адреса всех меток и т.д.;
  2. Горячий Запуск - исполнение кода в алгоритмическом порядке;
  3. Холостой Пуск - печать содержимого кода в текстовом листинге.
Порядок представления записи, типа «PRINT "Hello, World!";ABS(X1);» примерно таков:
  • «CALL LISTON» - Начало очередной строки листинга, перевод строки;
  • «LXI B,03158H» - Имя переменной «X1»;
  • «CALL GETVAR» - Поиск переменной в куче или печать имени в буфер;
  • «CALL FN@ABS» - Выполнение функции «ABS()» или печать имени в буфер;
  • «CALL LABEL1» - Обход последующего строкового литерала;
  • «DB 'Hello, World!',0» - Строковой литерал;
  • «LABEL1: POP B» - Помещаем адрес строкового литерала в регистры BC;
  • «CALL GETSTR» - Помещение в стек адреса на строку;
  • «CALL PRINT» - Выполнение оператора «PRINT» или печать имени в буфер;
  • «CALL LISTOK» - Закрытие строки листинга с выводом на печать.
Как-то так… :roll:
imsushka
Maniac
Posts: 232
Joined: 01 Jan 2022 04:34
Location: USSR, Tashkent

Re: Пишем компилирующий интерпретатор SHABASIC для 8080/8085

Post by imsushka »

васЁк-форт :mrgreen:

а на бк0010 был компилирующий бейсик, но там шитый код
шитый код проще и процонезависим
User avatar
Alikberov
Doomed
Posts: 347
Joined: 14 Oct 2019 18:10
Location: Tashkent

Re: Пишем компилирующий интерпретатор SHABASIC для 8080/8085

Post by Alikberov »

Shaos wrote:
Shaos wrote:Начать можно с 26 целочисленных переменных A%...Z% которые будут занимать 52 байта...
В будущем можно ещё и длинные целые поддержать - имя& ;)

Для плавающей точки под 8080 можно для начала взять 3-байтовую либу из Электроники МС2721:
В комплекте в текстовом редакторе ПОБЕДИТ¹ имеются библиотеки преобразования чисел с 24-битной мантиссой и поиск 24-битных токенов (27^5=14348907).
Правда, как человек, далёкий от высшей математики, писал код по своим понятиям и в некоторых случаях мантисса неверно отображается из-за ошибки округления. И библиотеку я свою пытаюсь написать уж пятый год.

А так, имена переменных можно хранить в трёх байтах как токен.

P.S.: ¹-Администрация и постояльцы могут игнорировать ссылки, так как они - для гостей форума.
User avatar
Shaos
Admin
Posts: 24008
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Пишем компилирующий интерпретатор SHABASIC для 8080/8085

Post by Shaos »

Я тоже ссылок толкаю везде перекрёстных уже третий десяток лет, надеясь, что гугл индекс цитирования повысит, а он, собака, вообще индексацию этого форума запретил :(
Я тут за главного - если что шлите мыло на me собака shaos точка net
User avatar
Shaos
Admin
Posts: 24008
Joined: 08 Jan 2003 23:22
Location: Silicon Valley

Re: Пишем компилирующий интерпретатор SHABASIC для 8080/8085

Post by Shaos »

imsushka wrote:а на бк0010 был компилирующий бейсик, но там шитый код
шитый код проще и процонезависим
на предыдущей странице даже ссылка на его сырцы была ;)
http://www.nedopc.org/forum/viewtopic.php?p=168224#p168224
и потом, как мы давеча разобрались, шытый код шытому коду рознь :roll:
Я тут за главного - если что шлите мыло на me собака shaos точка net