Pull to refresh

Comments 20

Ох, форт, оргазмы юности… Я думал он уже кремирован!
Хочу его!

Работа с сокетами это как раз хардкор для форта.
Много ли сейчас интересующихся фортом? Живо ли сообщество? Современные фреймворки для форта — было бы весьма увлекательно.
Разделяю ваше возбуждение! Нужна FORTH-машина на JavaScript, с возможностью выполнять FORTH в браузере, и с прозрачным взаимодействием с FORTH-машиной, работающей на сервере! Хорошая тема для дипломной работы студентам!
О боже! Зачем городить такой огород? Форт тем и прелестен, что он вещь в себе. Нет никаких проблем сделать так, чтобы весь Форт-интерактив шел через браузер. Сделать все это средствами самого Форта.
80 порт в приведенной программе я назначил не просто так. К этому наносерверу можно подключиться любым браузером из любой точки интернета, если позволяет файервол.
Придется во второй части развить тему.

Уже пройденный этап — так неудобно. Удобнее всего с браузером взаимодействовать через веб-сокеты: использовал в одном проекте форт сокет-сервер для точных и быстрых вычислений, а GUI был на веб-ките. Вся графика на jQuery+Html, а ядро программы и основная логика — на форте (СПФ).
Например: github.com/yarus23/SPF.JS — заявлена совместимость с СПФ, но я его особо не ковырял — так что ничего конкретного сказать не могу.
Моя цель — подогреть интерес к Форту. Не как просто к одному из языков программирования, а как к целой концепции.
Стек-машины (форпт-машины) живут и здравствуют, а вот сам язык подзабыт, да. Печально.
Но это беда его эффективности, как это не странно. Во времена 16-ти бит, он творил натуральное волшебство, не претендуя на мегабайты памяти.

Наступила эпоха 32-х бит, а затем и 64-х, а у людей в мозгу до сих пор лежит устаревшая информация про эти самые 64 Килобайта. Как говорится «мем» на лицо.

А сейчас в добавок к этому, еще и натягивают факты на глобус, принижая возможности стек-ориентированных языков и замалчивая то, что по факту этот труженик невидимого фронта распространен повсеместно.

ЕМНИП, каноническая реализация JVM стек-машиной и является.

P.S. Дорогой автор, ждем от вас больше информации и лучшего оформления исходников.
Да, например загрузчик БСД или вот тот же самый ПДФ вырос из форта.
Спасибо! Оформление — большой больной вопрос. Непонятно как что работает.
Кто был достаточно внимателен, то заметил что мы переопределили базовые слова двоеточие и минус. Как быть с этим? Ответ ниже.

Эмм… Зачем же так извращаться-то? А дальше-то как писать? Таки немного покритикую выбранный подход: для демонстрации тех или иных способов решения задачи в целом пример годится. Но вот в продакшене данный код бесполезен. Во-первых: совершенно ненужное переопределение стандартных и привычных слов. Во-вторых, это нужно было делать в отдельный словарь и просто переключать поиск на него в тот момент, когда это нужно. В третьих: существует куча библиотек для строковых операций в подкаталоге ~devel, в т.ч. для сложения строк/чисел, так же существуют опенсорсные либы для работы со строками (например плагины к ннкрон). Достаточно подключить и можно использовать что-то типа такого:
" %DD%-%MM%-%YYYY%/%HH%:%MM%:%SS%"
В четвертых: можно использовать встроенный механизм конвертации чисел для получения строки с нужным форматированием.
Пример(код одноразовый — написал и забыл, приоритет — скорость):
Код из реального проекта для отдачи времени в заголовках браузеру по стандарту RFC 822
WINAPI: GetSystemTime Kernel32.dll

0
2 -- -Year		        \ Указывает текущий год
2 -- -Month		        \ Текущий месяц; Январь = 1, Февраль = 2, и так далее
2 -- -DayOfWeek       \ Текущий день недели; Воскресенье = 0, Понедельник = 1, и так далее
2 -- -Day             \ Текущий день месяца
2 -- -Hour            \ Час
2 -- -Minute          \ Минуты
2 -- -Second          \ Секунды
2 -- -Milliseconds    \ Миллисекунды
CONSTANT /SYSTEMTIME
USER-CREATE SYSTEMTIME-BUF /SYSTEMTIME USER-ALLOT
USER-CREATE WebTime[] 30 USER-ALLOT
29 CONSTANT WebTime#

CREATE WebDays S" Sun, Mon, Tue, Wed, Thu, Fri, Sat, " HERE SWAP DUP ALLOT 0 C, CMOVE
CREATE WebMonths  S"     Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec " HERE SWAP DUP ALLOT 0 C, CMOVE

: WebTime!   \ ( addr -- ) \ Записать по адресу addr строку с текущей датой вида "Fri, 04 Jul 2008 08:42:36 GMT"
  >R SYSTEMTIME-BUF GetSystemTime                               \ Получаем текущее системное время
  DUP -DayOfWeek W@  5 * WebDays + R@ 5 CMOVE  R> 5 + >R        \ и конвертируем его в формат RFC 822
  DUP -Day W@ 0 <# # # #> R@ SWAP CMOVE  R> 2 + >R              \ Код хоть и немного жуткий, зато быстрый — а это главное
  BL R> DUP 1+ >R C!
  DUP -Month W@  CELLS WebMonths + R@ 4 CMOVE  R> 4 + >R
  DUP -Year W@ 0 <# # # # # #> R@ SWAP CMOVE  R> 4 + >R
  BL R> DUP 1+ >R C!
  DUP -Hour W@ 0 <# # # #> R@ SWAP CMOVE R> 2 + >R
  [CHAR] : R> DUP 1+ >R C!
  DUP -Minute W@ 0 <# # # #> R@ SWAP CMOVE R> 2 + >R
  [CHAR] : R> DUP 1+ >R C!
  -Second W@ 0 <# # # #> R@ SWAP CMOVE R> 2 + >R
  S"  GMT" R> SWAP CMOVE
;

: GetWebTime   \ ( -- a u )
  WebTime[] WebTime!
  WebTime[] 29
;

В пятых:: оптимальнее сначала собирать все данные для отправки браузеру в один буфер и одним вызовом передавать в сокеты, а не делать овер 9000 апи-вызовов.
В шестых: можно использовать вектор NOTFOUND для сбора строк, не являющихся словами. Т.е. создаем словарь с нужным набором слов, которые просто пишут в текущую позицию в буфере. Далее, когда нужно сделать форматированную строку, то просто переключаем словарь и записываем в вектор NOTFOUND слово, которое будет неизвестные слова складывать в буфер. Но это уже ближе к экзотическим способам решения задачи.
Совершенно справедливо. Да, пример безусловно демонстрационный. Цель была — подогреть интерес. Приятно слышать, что язык активно используется и есть люди хорошо его знающие.
Буквально пару недель назад впервые попробовал Forth. С непривычки мозг вскипает.
Есть версия GNU Forth для Android, часто обновляется: gforth.
Глянул глазом, весьма крутая штука. И с документацией там все хорошо.
Да, gForth в целом довольно неплох и вполне юзабелен. Но и у него есть свои особенности, плюсы и недостатки. Один из немногих х64 фортов. Вот его репозиторий на гитхабе: github.com/forthy42/gforth — там всегда самая свежая версия. В официальных репозиториях линуксов отставание в год и более. На данный момент главное преимущество данной версии в полной поддержке стандартной либы ptheard — т.е. многопоточности. А вот с юзер-переменными там немного печальнее.
Андроидная версия все таки еще сырая, но в целом работает.
Когда я вижу или слышу слово «серверА» — моя рука тянется к пистолету.
Со своим небольшим знанием Фактора набросал нечто подобное:
USING:  io io.sockets kernel calendar 
io.streams.duplex accessors prettyprint
calendar.format io.encodings.utf8 
math.parser math.functions ;

IN: my.server

CONSTANT: port 80
CONSTANT: host "127.0.0.1"

: create-server ( -- server ) host port <inet4> utf8 <server> ;

: make-value ( -- ) 

: _ ( -- ) " " write ;

: - ( -- ) "-" write ;

: _: ( -- ) ":" write ;

: HOURS  ( time  -- ) hour>> number>string write ;
: MINUTES  ( time  -- ) minute>> number>string write ;
: SECONDS  ( time  -- ) second>> round number>string write ;

: print-date-now ( -- ) 
    now dup dup dup dup dup
    DAY - MONTH - YYYY _ HOURS _: MINUTES _: SECONDS ;

"Starting server..." print flush

create-server

"Start listening..." print flush

accept

"Connected: " write
[ host>> write ] [ ":" write port>> number>string print ] bi
[ 
  print-date-now
  "" print
  flush 
] with-stream

Было бы неплохо, если кто-нибудь расскажет, как сделать аналог make_delimeter, а то я с with-compilation-unit не могу разобраться.
Ох, блин, там ошибка, вот нормальный текст:
USING:  io io.sockets kernel calendar 
io.streams.duplex accessors prettyprint
calendar.format io.encodings.utf8 
math.parser math.functions ;

IN: my.server

CONSTANT: port 80
CONSTANT: host "127.0.0.1"

: create-server ( -- server ) host port <inet4> utf8 <server> ;

: _ ( -- ) " " write ;

: - ( -- ) "-" write ;

: _: ( -- ) ":" write ;

: HOURS  ( time  -- ) hour>> number>string write ;
: MINUTES  ( time  -- ) minute>> number>string write ;
: SECONDS  ( time  -- ) second>> round number>string write ;

: print-date-now ( -- ) 
    now dup dup dup dup dup
    DAY - MONTH - YYYY _ HOURS _: MINUTES _: SECONDS ;

"Starting server..." print flush

create-server

"Start listening..." print flush

accept

"Connected: " write
[ host>> write ] [ ":" write port>> number>string print ] bi

[ 
  print-date-now
  "" print
  flush 
] with-stream

Да, фактор как-то поинтереснее будет. Ну проще так точно :) Возможностей больше, довольно крутой рантайм, гора биндингов. Но у меня, к сожалению, ничего сложнее хелловорлда как-то не получалось на нём написать :(
Беглый просмотр документации на Фактор вызвал подозрение, что в нем нет возможности создавать определяющие слова. В большинстве языков способы создания новых понятий жестко зашиты в язык. У Форта имеется механизм создания определяющих слов. Которыми в примере являются make_value и make_delimeter. В Форте можно не просто создавать новые понятия, а создавать необходимые инструменты для создания понятий.
Sign up to leave a comment.

Articles