Forth и другие саморасширяющиеся системы программирования Locations of visitors to this page
Текущее время: Ср янв 17, 2018 11:14

...
Google Search
Forth-FAQ Spy Grafic

Часовой пояс: UTC + 3 часа [ Летнее время ]




Начать новую тему Ответить на тему  [ Сообщений: 39 ]  На страницу 1, 2, 3  След.
Автор Сообщение
 Заголовок сообщения: Я написал интерпретатор форт-подобного языка.
СообщениеДобавлено: Сб июл 26, 2008 09:33 
Не в сети

Зарегистрирован: Сб июл 26, 2008 06:22
Сообщения: 21
Благодарил (а): 0 раз.
Поблагодарили: 1 раз.
В общем - если оффтопик - то не ругайте.
Написал я тут интерпретатор-компилятор форт-подобного языка.

Прошу оценить, если конечно у кого есть время и желание.

Исходные тексты (там же - исходники документации): http://www.nedopc.org/nedopc/upload/afort-cl-1.0.6.tar.bz2
Документация в pdf и dvi: http://www.nedopc.org/nedopc/upload/afort-cl-doc-1.0.6.tar.bz2

Синтаксис не фортовский, хотя весьма похож.
Отличия: есть примитивная типизация (строки, массивы, целые - они же - байты и короткие целые, вещественные). команды сравнения работают как со строками, так и с числами. Массивы - динамически изменяемой длины.
Есть возможность посреди откомпилированного слова исполнить любую строку как последовательность команд (в том числе и определить новое слово).

Что там от ФОРТА:
- все слова разделяются пробелами.
- обратная польская запись выражений.
- компиляция "на лету".
- виртуальная форт-машина.

Что там своего:
по языку:
- типизация (целые, вещественные, строки).
- возможность иметь тип - массив байт.
- адреса памяти преравнены к целым.
- сравнение в соответствии с типом (например можно сравнить две строки - поёмёт).

по виртуальной машине:
- абсолютная модульность - дописать новое слово можно очень быстро.
- словари можно подключать-отключать при компиляции очень просто - добавляя-удаляя их из списка соловарей.
- автогенерация документации по словорям.

Язык писался и опробывался НЕ ТОЛЬКО на PC, но и на процессоре с ядром ARM7.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Сб июл 26, 2008 09:45 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 22:48
Сообщения: 6142
Благодарил (а): 14 раз.
Поблагодарили: 96 раз.
Интересная штука. :)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Сб июл 26, 2008 10:08 
Не в сети

Зарегистрирован: Сб июл 26, 2008 06:22
Сообщения: 21
Благодарил (а): 0 раз.
Поблагодарили: 1 раз.
Хищник писал(а):
Интересная штука. :)


А по существу ? :)

У меня там системозависимых слов - всего ничего: putc, getc, open и close.
Менеджер памяти может быть как системный, так и самописный (есть у меня такой, я его на ARM использовал, но он аппаратно-независим, на 8битках тоже шёл на "ура").

Так что, хотя это всё на GСС писано - может работать практически везде.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Сб июл 26, 2008 10:20 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 22:48
Сообщения: 6142
Благодарил (а): 14 раз.
Поблагодарили: 96 раз.
По существу для переносимых систем стоит активнее выделять системно-зависимые слои, их бывает аж до трех. Тут надо соблюсти определенный баланс, потому что putc для вывода все-таки маловато, а попытка расширения функциональности может забросить нас в область PC-only. Скажем, позиционирование курсора еще можно добавить, а вот вывод графики уже под вопросом. В плане набора слов тут можно попробовать написать что-то конкретное, и посмотреть, чего именно не хватает. А так получилась классическая виртуальная форт-машина :) Классическая - в смысле по реализации на ЯВУ стека и командного интерпретатора.

Пункт для обсуждения, который бросился в глаза - "умное" слово variable. А если я ошибусь в записи начального значения, и тип не тот получится?...


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Сб июл 26, 2008 11:01 
Не в сети

Зарегистрирован: Сб июл 26, 2008 06:22
Сообщения: 21
Благодарил (а): 0 раз.
Поблагодарили: 1 раз.
Хищник писал(а):
По существу для переносимых систем стоит активнее выделять системно-зависимые слои, их бывает аж до трех. Тут надо соблюсти определенный баланс, потому что putc для вывода все-таки маловато, а попытка расширения функциональности может забросить нас в область PC-only.


Там это так и сделано практически. В корневом каталоге сборки есть файлик: dict.lst
Так вот - в этом файлике - указано, какие именно словари используются для формирования встроенных слов при сборке.
На данный момент - словарь один: stddict (Словарь - подкаталог в каталоге dicts).

Для каждой архитектуры можно создать отдельный дополнительный словарь и дополнить им файл dict.lst.
stddict - это минимальный словарь. Он и привязан к системе по минимуму. Для его сборки достаточно, чтобы были определены POSIX-функции:

fopen() fclose() fputc() fgetc() fgets() malloc(), realloc() и free()

Если же aForth работает на чёмто без признаков OS, то можно эти функции тупо сэмулировать. Например как это сделано на AVR.
Я запускал aForth под писанной мной же многозадачной операционке NEDOPC-ARMOS, так что привязка к PC-ONLY отпадала сразу: http://www.nedopc.org/nedopc/upload/armos-0.11.0.tar.bz2

Более же продвинутые функции привязки к системе лучше сделать в виде отдельных вкомпилируемых по мере необходимости словарей, например:
armos.dict
avr.dict
linux.dict - поместить словари в каталог dicts и указывать список нужных в файле dict.lst

Хищник писал(а):
Скажем, позиционирование курсора еще можно добавить, а вот вывод графики уже под вопросом. В плане набора слов тут можно попробовать написать что-то конкретное, и посмотреть, чего именно не хватает. А так получилась классическая виртуальная форт-машина :) Классическая - в смысле по реализации на ЯВУ стека и командного интерпретатора.


Почему под вопросом ? сделать отдельные словари опять же. загляни в каталог stddict - там помоему всё прозрачно организовано. Скажем - отдельно словарь terminal.dict - для курсора и цверов на терминале и отдельно - graph.dict

Тогда конфигурирование системы для конкретного проца или ОС сведётся к указанию в dict.lst - какие словари использовать. Ну и вместо make написать, например - make CROSS=arm-linux-

Хищник писал(а):
Пункт для обсуждения, который бросился в глаза - "умное" слово variable. А если я ошибусь в записи начального значения, и тип не тот получится?...


Да - если ошибёшься - не тот тип будет.

0 variable A - целая переменная A
0.0 variable A - вещественная переменная A
"" variable A - строка A

Можно синтезировать слова и переменные "на лету":

Код:
(
    С константами-массивами можно работать только в режиме интерпертации.
    Но - голь на выдумки хитра!
    Пример программки, которая на лету синтезирует массив из 3х переменных.
    Причём массив может быть int short или byte
)
"dict.af" include
( Пустой массив А )

{ } array A "Пустой массив. A=" . A size . CR

( Переменные )
0x10 variable I1
0x20 variable I2
0x30 variable I3

( mode - хранит режим синтеза массива  - byte, short или int )
"" variable mode

(
    Слово array-syntes - синтезирует строку
    "{ <mode> I1 I2 I3 }" и выполняет её в режиме интерпретации с
    помощью слова doword, затем сохраняет синтезированный массив в том,
    что находится на стеке.
)
: array-syntes "{ " mode + " I1 I2 I3 }" + doword swap !! ;

"Синтезируем массив байт" . CR
"byte" mode !!
A array-syntes
A VARDUMP
CR

"Синтезируем массив коротких целых" . CR
"short" mode !!
A array-syntes
A VARDUMP
CR

"Синтезируем массив целых" . CR
"int" mode !!
A array-syntes
A VARDUMP
CR


В массивах можно перемешивать целые разных типов (байты, короткие, целые)

Код:
{
    byte 1 2 3 4 5 ( байты, занимают по 1 байту )
    short 1 2 3 4 5 ( Короткие - занимают по 2 байта )
    int 1 2 3 4 5 ( целые - занимают по 4 байта)
    "Ёжик в тумане" ( Строка - занимает столько, сколько в ней символов +1 байт на завершающий '\0' )
} array MASSIV ( Всё что в фигурных скобках - помещено в массив, программист - разбирайся сам )


В архиве с докой - примеров есть ещё не мало.

Массивы можно объединять:

{ "Ёжик " } array A
{ "в " } array B
{ "тумане" } array C

{ A B C } array D

Массив D содержит 3 строки друг за другом:
( Ёжик 0в 0тумане0 ) - 0 - это символ '\0'


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Сб июл 26, 2008 12:55 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 22:48
Сообщения: 6142
Благодарил (а): 14 раз.
Поблагодарили: 96 раз.
SfS писал(а):
Почему под вопросом ? сделать отдельные словари опять же. загляни в каталог stddict - там помоему всё прозрачно организовано. Скажем - отдельно словарь terminal.dict - для курсора и цверов на терминале и отдельно - graph.dict

Но если на целевой системе просто нет графики, то тут придется как-то выкручиваться. Самый простой вариант - заглушки, но о том и речь, для переносимой системы приходится продумывать интерфейсы доступа к периферии.
SfS писал(а):
Да - если ошибёшься - не тот тип будет.

0 variable A - целая переменная A
0.0 variable A - вещественная переменная A
"" variable A - строка A

Тут вообще получается RunTime Type Inference... оно не то чтобы не нужно, просто представляет собой альтернативу. Более сложные проблемы начинаются, когда требуются операции по приведению типов или арифметика указателей.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Сб июл 26, 2008 13:12 
Не в сети

Зарегистрирован: Сб июл 26, 2008 06:22
Сообщения: 21
Благодарил (а): 0 раз.
Поблагодарили: 1 раз.
Хищник писал(а):
Но если на целевой системе просто нет графики, то тут придется как-то выкручиваться. Самый простой вариант - заглушки, но о том и речь, для переносимой системы приходится продумывать интерфейсы доступа к периферии.


Хм. А какая проблема ? Перед сборкой компилятора просто не указываешь словарь graph - и всё. Соответственно будут отсутствовать все слова, связанные с графикой.
Но какой дурень будет запускать приложения с графикой на платформе без графики ? Так что проблемы - нет как таковой или я чего-то не понимаю.

Хищник писал(а):
Тут вообще получается RunTime Type Inference... оно не то чтобы не нужно, просто представляет собой альтернативу. Более сложные проблемы начинаются, когда требуются операции по приведению типов или арифметика указателей.


Сейчас сделано так:

1. Тип переменной - будучи один раз задан при создании переменной - не меняется!
2. Тип значения, сохраняемого в переменной - ВСЕГДА приводится к типу переменной.
3. Указатель ПОЛНОСТЬЮ равнозначен целому. Фактически в языке нет различий между указателем и целым. Так что хоть умножай их хоть складывай.

Не сделано пока:
4. Ещё не сделаны слова принудительного приведения типов.
5. Определение типа значения на стеке.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Сб июл 26, 2008 13:17 
Не в сети

Зарегистрирован: Сб июл 26, 2008 06:22
Сообщения: 21
Благодарил (а): 0 раз.
Поблагодарили: 1 раз.
Вообче - от роду системе aForth- 3 недели.
Да и в доке у меня немало написано - с примерами.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Сб июл 26, 2008 14:04 
Не в сети

Зарегистрирован: Вт май 09, 2006 12:31
Сообщения: 3438
Благодарил (а): 5 раз.
Поблагодарили: 16 раз.
Хищник писал(а):
SfS писал(а):
Почему под вопросом ? сделать отдельные словари опять же. загляни в каталог stddict - там помоему всё прозрачно организовано. Скажем - отдельно словарь terminal.dict - для курсора и цверов на терминале и отдельно - graph.dict

Но если на целевой системе просто нет графики, то тут придется как-то выкручиваться. Самый простой вариант - заглушки, но о том и речь, для переносимой системы приходится продумывать интерфейсы доступа к периферии.
SfS писал(а):
Да - если ошибёшься - не тот тип будет.

0 variable A - целая переменная A
0.0 variable A - вещественная переменная A
"" variable A - строка A

Тут вообще получается RunTime Type Inference... оно не то чтобы не нужно, просто представляет собой альтернативу. Более сложные проблемы начинаются, когда требуются операции по приведению типов или арифметика указателей.

Хищник, автор сделал очень интересную работу, разве нет?

_________________
понимаю некоторую бестолковость некоторых вопросов


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Сб июл 26, 2008 14:16 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 22:48
Сообщения: 6142
Благодарил (а): 14 раз.
Поблагодарили: 96 раз.
SfS писал(а):
Хм. А какая проблема ? Перед сборкой компилятора просто не указываешь словарь graph - и всё. Соответственно будут отсутствовать все слова, связанные с графикой.
Но какой дурень будет запускать приложения с графикой на платформе без графики ? Так что проблемы - нет как таковой или я чего-то не понимаю.

Речь идет о "голубой мечте" - наборе систем, которые будут очень лояльными по отношению к прикладным программам. Так-то понятно, что от набора библиотек будет зависеть возможность доступа к той или иной аппаратуре.
SfS писал(а):
Не сделано пока:
4. Ещё не сделаны слова принудительного приведения типов.
5. Определение типа значения на стеке.

В принципе, такое делается тэгами, которые заводятся параллельно стеку данных.

вопрос писал(а):
Хищник, автор сделал очень интересную работу, разве нет?

Очень.


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Сб июл 26, 2008 14:18 
Не в сети

Зарегистрирован: Вт май 09, 2006 12:31
Сообщения: 3438
Благодарил (а): 5 раз.
Поблагодарили: 16 раз.
принудительное приведение типов сделать, конечно, прийдётся... судя по тому, что я понял в замысле автораИМХО

_________________
понимаю некоторую бестолковость некоторых вопросов


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Сб июл 26, 2008 17:57 
Не в сети

Зарегистрирован: Сб июл 26, 2008 06:22
Сообщения: 21
Благодарил (а): 0 раз.
Поблагодарили: 1 раз.
Хищник писал(а):
Речь идет о "голубой мечте" - наборе систем, которые будут очень лояльными по отношению к прикладным программам. Так-то понятно, что от набора библиотек будет зависеть возможность доступа к той или иной аппаратуре.



См. Юникс-путь. Каждая программка - делает чтото одно, но хорошо. Если это программа закачаки сайтов, то это ПРОГРАММА ЗАКАЧКИ САЙТОВ (например wget). А если это "графическая морда" ПРОГРАММЫ ЗАКАЧКИ САЙТОВ - то это ГРАФИЧЕСКАЯ МОРДА.
При этом сам wget работает хоть где, а "графическая морда" - разумеется только там, где есть графика.

Помоему этот подход - не зависит от системы. И тем более языка.

Виндоыс-программы в том и проигрывают часто, что каждая из них стремиться стать СУПЕР-МЕГА-КОМБАЙНОМ. То есть - если это программа закачки файлов, то в ней и графморда и просмотрщик мультиков и стиральная машинка. Причём - все встроенное и неизменяемое. Такой подход - мало того, что плодит глюки, так их ещё и фиг отловишь.

Но ведь путь Forth - именно аналогичен присловутому ЮниксВэй. Каждое слово отдельная маленькая чётко определённая функция. И если ктото перемешал неразделимо в какомто мегаслове слова как закачки файлов, так и вывда какойто графики - то он сам себе злющий буратинА и сам пусть с этим мучается, а не требует, чтобы система на AVR, спрятанная в маленькой кладовке, понимала слова для работы мега-3Д-акселлератором.

Хищник писал(а):
В принципе, такое делается тэгами, которые заводятся параллельно стеку данных.


У меня это реализовано, просто ещё слова не прописал, возвращающие код типа данных.
Я сделал проще. На стеке - каждая запись хранится в виде пары 32битных слов. В этом же формате хранятся и команды виртуальной машины. Первое слово - определяен что хранится во втором- это может быть:
- команда виртуального кода (быстрая команда для условий и циколв) .
- константа.
- слово.
- признак конца виртуального кода.

Как оно хранится:
- целые, вещественные константы - хранятся прямо во втором слове.
- строки-константы - в виде адреса-указателя на строку.
- все слова (переменные, массивы, процедура) - хранятся в виде номера слова.

Так что надо просто посмотреть - что на стеке и выдать код типа (целое) на стек. И накаких параллельных тегов для основных типов :)

Вот прямо сегодня пропишу слова:
istype - снимает значение со стека и возвращает его тип
int-type real-type str-type array-type - возвращают константы - коды соответствующих типов.

тогда можно писать типозависимый код типа
( На стеке нечто хз-какого типа )
: type-test
istype
dup int-type =
if
"На стеке целое" . CR
endif
dup real-type =
if
"На стеке вещественное" . CR
endif
dup str-type =
if
"На стеке строка" . CR
endif
drop
;

Плюс вытащу в виде слова процедуру принудительногго приведения типа
typecastto.

Например:
int-type typecastto - приведёт вершину стека к целому (если строка - вылетим по ошибке)

Далее - надо процедуру проверки - имеется ли такое слово:
"dup" isword ( вернёт на стек 1 - слово dup имеется )
"rrrr" isword ( вернёт на стек 0 - слова rrr не имеется в словаре )

Ну и сделать процедуру удаления всех слов, начиная с указанного и определённых после него :) Не сделал я ещё этого !!! Забыл.



За это сообщение автора SfS поблагодарил: Majestio
Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Сб июл 26, 2008 19:46 
Не в сети

Зарегистрирован: Сб июл 26, 2008 06:22
Сообщения: 21
Благодарил (а): 0 раз.
Поблагодарили: 1 раз.
ну вот и результат работы с типами:

Код:
( Слово istype снимает со стека значение ивозвращает на стек константу-код, соответствующую типу снятого значения. Каждый тип данных имеет свой уникальный код. Слова array-type, int-type, real-type, str-type возвращают на стек код соответствующего типа. )


    ( Проверка типов. На стеке значение неизвестного типа. )

    : checktype

        istype

        dup array-type = if "Тип: массив" CR endif

        dup int-type = if "Тип: целое" CR endif

        dup real-type = if "Тип: вещественное" CR endif

            str-type = if "Тип: строка" CR endif
    ;


( Слово принудительно приводит тип значения на вершине стека к указанному, если типы совместимы. Всегда возвращает константу указанного типа на стеке.

    Формат команды: <значение> <код типа> typecast )


    ( Приведение к целому типу )
    2.345 int-type typecast . CR ( Напечатает 2 - целое число )
    ( Приведение к вещественному типу )
    5     real-type typecast . CR ( Напечатает 5.00000 - вещестенное число )




Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Сб июл 26, 2008 20:01 
Не в сети
Administrator
Administrator
Аватара пользователя

Зарегистрирован: Вт май 02, 2006 22:48
Сообщения: 6142
Благодарил (а): 14 раз.
Поблагодарили: 96 раз.
SfS писал(а):
См. Юникс-путь. Каждая программка - делает чтото одно, но хорошо. Если это программа закачаки сайтов, то это ПРОГРАММА ЗАКАЧКИ САЙТОВ (например wget). А если это "графическая морда" ПРОГРАММЫ ЗАКАЧКИ САЙТОВ - то это ГРАФИЧЕСКАЯ МОРДА.
При этом сам wget работает хоть где, а "графическая морда" - разумеется только там, где есть графика.

В этом же разделе есть мой Quark-Forth, сделанный в таком стиле :)
Речь немножко не об этом. Если мы уже двинулись в сторону мультиплатформенности, причем не диаметрально противоположной, то неплохо было бы сделать так, чтобы действительные различия были вынесены в отдельный слой. Иначе нам под каждую платформу и под каждый стиль придется писать свою программу, а из-за какого-нибудь "очень полезного" вызова WinAPI этот же модуль не пойдет на ARM. Хотя ARM сам по себе не такая уж слабая платформа, и вполне можно иметь некий репозиторий модулей, реализующих разные алгоритмы (скажем, сортировка массивов или поиск пути), и одинаково успешно транслирующихся под самые разные платформы. Как сегодня часто бывает, сегодня PC, завтра попросили то же самое в коробочке под ARM, а послезавтра в ПЛИС упаковали со всей периферией. Что же теперь, софт переписывать?
SfS писал(а):
У меня это реализовано, просто ещё слова не прописал, возвращающие код типа данных.
Я сделал проще. На стеке - каждая запись хранится в виде пары 32битных слов. В этом же формате хранятся и команды виртуальной машины. Первое слово - определяен что хранится во втором- это может быть:

В принципе, разновидность тэга.


А вообще интересный подход, welcome в нашу форумную компанию! :)


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
 Заголовок сообщения:
СообщениеДобавлено: Сб июл 26, 2008 20:39 
Не в сети

Зарегистрирован: Сб июл 26, 2008 06:22
Сообщения: 21
Благодарил (а): 0 раз.
Поблагодарили: 1 раз.
Ну вот - добавил isword.
Версия с исправлениями и дока :

http://www.nedopc.org/nedopc/upload/afort-cl-1.0.8.tar.bz2

http://www.nedopc.org/nedopc/upload/afort-cl-doc-1.0.8.tar.bz2


Вернуться к началу
 Профиль Отправить личное сообщение  
Ответить с цитатой  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 39 ]  На страницу 1, 2, 3  След.

Часовой пояс: UTC + 3 часа [ Летнее время ]


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group
phpBB сборка от FladeX // Русская поддержка phpBB