SPF devel doc


Introduction
1. Network
2. Graphics
3. Archives
4. Linked lists
5. Records
6. Data structures
7. Sorting and search
8. Programming techniques
9. Debugging facilities
10. Math
11. Random numbers
12. Hashes
13. Cryptographic hashes
14. Compile-time constants
15. User interface
16. Windows COM
17. System services
18. Date and time
19. Databases
20. Processes, threads, etc
21. Windows registry and ini-files
22. Strings
23. Files
24. XML
25. OOP extensions
26. Vocabularies
27. Memory
28. Miscellaneous
29. Encodings

Introduction

Hello! Here's an introduction!

Глава 1. Network

Description

some description here

~ac/lib/win/winsock/SOCKETS.F

Описание

Windows Sockets

CreateSocket

( -- socket ior )

CreateSocketWithTimeout

( -- socket ior )

SetSocketTimeout

( timeout socket -- ior )

CreateUdpSocket

( -- socket ior )

CreateBroadcastSocket

( -- socket ior )

ToRead

( socket -- n ior )

сколько байт можно сейчас прочесть из сокета
можно использовать перед ReadSocket для того чтобы
избежать блокирования при n=0

BindSocketInterface

( port ip s -- ior )

ConnectSocket

( IP port socket -- ior )

CloseSocket

( s -- ior )

linger по умолчанию: graceful close без таймаута, устанавливаем таймаут на закрытие

FastCloseSocket

( s -- ior )

WriteSocket

( addr u s -- ior )

WriteSocketLine

( addr u s -- ior )

WriteSocketCRLF

( s -- ior )

ReadSocket

( addr u s -- rlen ior )

GetHostName

( IP -- addr u ior )

Get.Host.Name

( addr u -- addr u ior )

GetHostIP

( addr u -- IP ior )

иначе пустой хост S" " дает 0 0

GetPeerName

( s -- addr u ior )

GetPeerIP

( s -- IP ior )

GetPeerIP&Port

( s -- IP port ior )

SocketsStartup

( -- ior )

SocketsCleanup

( -- ior )

BindSocket

( port s -- ior )

ReuseAddrSocket

( s -- ior )

ReusedBindSocket

( port s -- ior )

ListenSocket

( s -- ior )

AcceptSocket

( s -- s2 ior )

SINLEN HERE

NtoA

( IP -- addr u )

[ BASE @ HEX ]
>R 0 0 <# 2DROP R@ 1000000 U/ FF AND 0 #S [CHAR] . HOLD
2DROP R@ 10000 U/ FF AND 0 #S [CHAR] . HOLD
2DROP R@ 100 U/ FF AND 0 #S [CHAR] . HOLD
2DROP R> FF AND 0 #S
#>
[ BASE ! ]

AcceptSocketNotBlock

( s -- s2 ior )

timeout 60 sec

GetHostIPs

( addr u -- IPab IPae ior )

Получить список IP multihomed-хоста
IPab IPae возвращаются в формате для последующего цикла DO, см. ConnectHost
иначе пустой хост S" " дает ior=0

ConnectHost

( addr u port -- sock ior )

Подключиться к хосту addr u на порт port
с автоматическим перебором всех IP хоста.
Если коннект не удался, то ior - код ошибки (на последнем хосте из списка)
и socks=0.
Если удался, то sock - новый соединенный сокет, ior=0.

READ-SOCK-EXACT

( a u socket -- ior )

ReadSocketExact

( a u socket -- ior )

~ac/lib/win/winsock/ssl.f

Описание

openssl брать на openssl.org, gnutls win32 на http://josefsson.org/gnutls4win/

LoadLibEx

( addr u -- h )

LoadSslLibrary

( -- )

LoadSsleLibrary

( -- )

CREATE-SSL-MUT

SSLAPI:

SSLEAPI:

SslInit

( -- )

SslNewServerContext

( pema pemu type \ c -- context )

SslNewClientContext

( pema pemu type \ c -- context )

SslSetVerifyDepth

( depth context -- )

SslSetVerify

( pema pemu mode context -- )

SslGetVerifyResults

( conn \ cert name mem -- cert addr u ior )

addr нужно после использования освобождать

SslObjConnect

( socket context -- conn_obj )

SslObjAccept

( socket context -- conn_obj )

SslWrite

( addr u conn_obj -- n )

>R SWAP R> SSL_write NIP NIP NIP

SslRead

( addr u conn_obj -- n )

>R SWAP R> SSL_read NIP NIP NIP

~ac/lib/win/winsock/sockets_ssl.f

Описание

Переопределение части функций из sockets.f для прозрачной работы по SSL

FailedSsl

( ior -- namea nameu cert )

SslServerSocket

( addr u verify s -- namea nameu cert )

addr u - имя файла с сертификатом и закрытым ключем в PEM-формате

SslClientSocket

( addr u verify s -- namea nameu cert )

addr u - имя файла с сертификатом и закрытым ключем в PEM-формате

WriteSocket

( addr u s -- ior )

WriteSocketLine

( addr u s -- ior )

WriteSocketCRLF

( s -- ior )

ReadSocket

( addr u s -- rlen ior )

CloseSocket

( s -- ior )

read

( addr len socket -- )

прочесть ровно len байт из сокета socket и записать в addr

upTo0

( -- )

READ-SOCK-EXACT

( a u socket -- ior )

ReadSocketExact

( a u socket -- ior )

~ac/lib/win/winsock/socketline2.f

Описание

Библиотека для построчного буферизированного чтения из сокета.
Copyright 1996-1999 A.Cherezov ac@eserv.ru

SocketLine

( socket -- addr-S )

SocketGetPending

( addr-S -- addr1 u1 )

SocketReadFromPending

( u1 addr-S -- addr1 u2 )

SocketContRead1

( addr-S -- )

SocketContRead2

( addr-S -- ior )

SocketContRead

SocketReadLine

( addr -- addr1 u1 )

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

CreateServerSocket

( port -- socket )

~ac/lib/win/winsock/SOCKNAME.F

Описание

Andrey Cherezov
старая библиотека для работы с UDP и добавления к TCP

sockIP&Port

( socket -- IP port )

IP=0, если клиент уже отключился!

ReadFrom

( addr u socket -- size IP port )

WriteTo

( IP port addr u socket -- )

~ac/lib/win/winsock/PSOCKET.F

Описание

Работа с сокетами в стиле PHP. Andrey Cherezov 30.Mar.2000

fsockopen < server port -- socketline >
Например: " www.forth.org.ru" 80 fsockopen -> s
- соединиться с сервером server по порту port и вернуть соединенный сокет.

fclose < socketline -- >
- закрыть сокет и соответственно разорвать его соединение
- для той стороны это будет graceful close, т.е. нормальное закрытие

fputs < str socketline -- >
Например " MAIL FROM:<ac@forth.org.ru>{CRLF}" s fputs
- отправить строку str в сокет socketline

fgets < socketline -- str >
- прочесть строку из сокета

Все слова throwable - в случае любой ошибки выполняется THROW.
Сбор строчной памяти на совести вызывающей программы.

Дополнительный пример TEST в конце текста.

fsock

( socketline -- socket )

fsockopen_old

( server port -- socketline )

fsockopen

( server port -- socketline )

fclose

( socketline -- )

: fclose ( socketline -- )
fsock CloseSocket THROW
;
fixed by Sergey Shisminzev [sergey@michint.kiev.ua]
лучше DROP

fast-fclose

( socketline -- )

fixed by Sergey Shisminzev [sergey@michint.kiev.ua]
лучше DROP

fputs

( str socketline -- )

fgets

( socketline -- str )

: fgets ( socketline -- str )
{ sock \ str }
"" -> str
sock SocketReadLine str STR!
str
;

~ac/lib/win/winsock/foreach_ip.f

Описание

25.04.2001 [C] Andrey Cherezov mailto:spf@users.sourceforge.net
ForEachIP - выполнение заданного действия для каждого IP хоста,
на котором это запускается. Компьютер, выполняющий
роль прокси, обычно имеет минимум 3 IP:
127.0.0.1 [всегда] - localhost
10.1.1.1 [пример] - адрес LAN-интерфейса
194.186.20.62 [пример] - адрес WAN-интерфейса

Изменения 23.01.2002: Добавлен ExternIP для тех несчастных,
кто работает за NAT-proxy, но хотят считать его IP своим

Изменения 30.10.2008: Добавлен ExternIPs для тех несчастных,
у кого внешних IP на целую строку, но приходится сидеть за NAT'ом.

ExternIP:

EIP,

ExternIPs:

ForEachIP

( xt \ addr -- ior )

xt - процедура ( IP -- ), запускаемая для каждого IP

IsLocalhost

( ip -- flag )

IsMyIP

( ip \ addr sp -- flag )

IsMyHostname

( addr u -- flag )

IsMyHostnameAndNotLocalhost

( addr u -- flag )

~ac/lib/win/winsock/dns_q.f

Описание

Библиотека работы с DNS-серверами.
Протокол DNS описан в RFC1035

Обновление 19.01.2003:
добавлено слово GetRRs, являющееся основным средством
DNS-запросов вместо прежних более узко специализированных.
"Прежние" теперь могут быть в основном переписаны через GetRRs :->

Использование:
S" domain.name" dns-record-type GetRRs
Например:
S" forth.org.ru" TYPE-MX GetRRs

Результат GetRRs - число полученных записей.
"Нормальные" ответы - 0,1,2 и т.д. неотрицательные числа.
Особые ответы:
-1 - сетевые проблемы [невозможен обмен UDP-пакетами]
это может быть следствием отсутствия модемной связи, например,
т.е. просто недоступен целевой сервер. Или невозможно найти имена DNS-серверов.
-2 - связь вроде есть, но ответы не приходят с 6 попыток - скорее
всего очень большие таймауты
-3 - указанный домен "не существует в природе"
-5 - DNS-сервер не хочет выполнять ваши запросы [чужой сервер, наверное]

Добавление 04.04.2007:
-6 - ошибки на всех DNS-серверах списка [только GetMXs]
-7 - ошибка DNS-сервера [обычно NS-сервера запрашиваемого домена]

Добавление 28.02.2008:
-8 - ошибка в формате DNS-ответа

GetRRn отличается от GetRRs тем, что не разбирает список
полученных записей, а только выясняет их число, т.е. экономит
время и память, если не нужен собственно список записей.
Ответы все те же.

Инициализацию сети и поиск подходящего DNS-сервера библиотека
производит сама при первой необходимости. Но можно указать желаемый
DNS-сервер опцией "-s сервер".

Ещё полезные слова:
DnsValidateDomain [ domaina domainu -- flag ]
DnsValidateEmailDomain [ emaila emailu -- flag ]
Проверяют, является ли домен валидным почтовым доменом,
т.е. можно ли на него отправлять почту. Это делается запросом
MX- и A-записей для этого домена. Если есть хотя бы одна, то
считается валидным. Существование имени user@ в данном домене
не проверяется, и "отзывчивость" найденных почтовых серверов
также не проверяется - т.е. собственно попыток почтовых сессий не
делается. Отрицательные ответы GetRR трактуются как "невалидный
домен". Т.е. использовать эти слова можно только при рабочем DNS.

DnsDomainExists [ domaina domainu -- flag ]
Если GetRRn возвращает -3, то домена точно нет. Все остальные
ответы, в т.ч. отрицательные трактуются как "есть", означающее
на деле "есть или невозможно проверить из-за проблем DNS или сети".
Если у домена нет MX- и A-записей, то он также считается несуществующим.

NextMX [ -- servera serveru true | false ]

Методика перебора MX-записей по приоритетам для попыток отправки почты.
S" domain" GetMXs 0 MAX 0 ?DO NextMX ... LOOP

DnsDomainExists отличается от DnsValidateDomain отношением к
ошибкам DNS. DnsDomainExists при ошибках НЕ отвергает домен,
а DnsValidateDomain отвергает. При рабочем DNS они равноценны.

>B<

TOKEN,

( addr u -- )

WT,

( x -- )

HOLDS

( addr u -- )

XCOUNT

FreeField

( af -- )

GetFieldData

( af -- addr u )

SetFieldData

( addr u af -- )

AddName

( addr u -- )

FreeRlist

PrintRL

( addr -- )

PrintRLIST

( -- )

PrintReceivedRDs

( type -- )

PrintReceivedMXs

( -- )

EnumReceivedRDs

( type -- n )

имеет смысл только если записи получались не по GetRRs,
а другим способом. При GetRRs список и так содержит только записи
одного (заказанного :) типа

EnumReceivedMXs

( -- n )

PrepareDnsQuery

( qtype addr u -- )

BsStartup

BsCloseSocket

BsReopen

уже точно не получить затерявшиеся ответы на старые запросы!

SendDnsQuery

PrintName1

PrintName

ParseName1

( -- ... )

ParseName

( -- addr u )

ParseAddName

( -- )

PrintType

ParseType

PrintClass

ParseClass

PrintTTL

ParseTTL

NextRD

PrintRD

ParseRD

PrintDnsQuestions

( n -- )

ParseDnsQuestions

( n -- )

PrintDnsAnswers

( n -- )

ParseDnsAnswers

( n -- )

PrintDnsReply

ParseDnsReply

ParseAnswer

RecvDnsReplyIdMismatch

RecvDnsReply

NextDNS

( -- flag )

DNS-SERVER.

GetRRs

( hosta hostu type \ attempts -- n )

GetRRn

( hosta hostu type \ attempts -- n )

GetDomainFromEmail

GetUserFromEmail

DnsValidateDomain

( domaina domainu -- flag )

DnsValidateEmailDomain

( emaila emailu -- flag )

DnsValidateList

( addr u -- )

GetMXs_old

( domaina domainu -- n )

GetMXs

( domaina domainu -- n )

NextMX

( -- servera serveru true | false )

DnsDomainExistsOld

( domaina domainu -- flag )

DnsDomainExists

( domaina domainu -- flag )

GetHosts

( namea nameu -- n )

NextRR

( type -- hosta hostu true | false )

NextHost

( -- hosta hostu true | false )

IsNameMatchesIp

( namea nameu ip -- err false | true )

~ac/lib/win/winsock/transmit.f

Описание

PutFileTr

( h s -- ior )

~ac/lib/win/snmp/snmp.f

Описание

SNMP v2 клиент/сервер. (C) 2005 Andrey CHerezov

SnmpFreeOutValue

( -- )

SnmpDumpReceivedPdu

( -- )

SnmpGraphReceivedPdu

( -- )

SnmpExecReceivedPdu

( -- )

SnmpFreeReceivedPdu

SnmpGetType

( S"oid" type S"host" -- )

SnmpGetTypeExSend

( S"oid" type S"community" S"host" port -- )

SnmpGetTypeExRecv

( -- )

SnmpGetTypeEx

( S"oid" type S"community" S"host" port -- )

SnmpGet

( S"oid" S"host" -- )

SnmpGetNext

( S"oid" S"host" -- )

SnmpInit

SnmpStrValue

( addr u -- addr2 )

SnmpGaugeValue

( x -- addr2 )

SnmpIntValue

( n -- addr2 )

SnmpUintValue

( n -- addr2 )

SnmpCounterValue

( n -- addr2 )

SnmpOidValue

( addr u -- addr2 )

SnmpTimeValue

( n -- addr2 )

SnmpOidName

( addr u -- addr2 )

SnmpFreeVbIndex

( index -- )

SnmpSetStrReply

( index S"str" -- )

SnmpSetGaugeReply

( index x -- )

OVER SnmpFreeVbIndex

SnmpSetIntReply

( index n -- )

SnmpSetUintReply

( index u -- )

SnmpSetCounterReply

( index u -- )

SnmpSetOidReply

( index S"o.i.d" -- )

SnmpSetTimeReply

( index n -- )

SnmpSetReplyName

( index S"o.i.d" -- )

1.3.6.1.2.1.1.1.0

1.3.6.1.2.1.1.2.0

1.3.6.1.2.1.1.3.0

1.3.6.1.2.1.1.4.0

1.3.6.1.2.1.1.5.0

1.3.6.1.2.1.1.6.0

1.3.6.1.2.1.1.7.0

1.3.6.1.2.1.2.1.0

1.3.6.1.2.1.6.9.0

1.3.6.1.2.1.6.9

1.3.6.1.2.1.2.2.1.10.0

MRTG def stats

1.3.6.1.2.1.2.2.1.16.0

1.3.6.1.4.1.18474

.iso.org.dod.internet.private.enterprises.etype

Error: "source/~ac/lib/lin/curl/curl.f.docbook" not found.

~nn/lib/web/server.f

Описание

ROOT-DIR

HTTP-WRITE

( a u -- )

NOT_FOUND

SEND_FILE

( filename -- )

PROCESS_REQUEST

( addr u -- )

(WS-THREAD)

( s \ mem offs -- )

|| s mem offs || (( s ))

CP-WEB-INFO

( s -- a )

(WS-SERVER)

( port \ ss -- )

WEB-SERVER

( port S"dir" -- task_id )

Глава 2. Graphics

Description

some description here

~ygrek/lib/joopengl/GLWindow.f

Описание

Last changes 07/05/2005

07.May.2005 ~ygrek
Небольшие фиксы

TODO: Разобраться с многочисленными багами, глюками и ошибками
которые появляются при запуске. Такие как - GL error 502 итп

OpenGL demo in Forth
with jOOP by ~day
(c) yGREK heretix mailto:heretix@yandex.ru
Started 20/02/2005

ShowAbout

( c-addr1 u1 c-addr2-u2 hwnd)

Сначала имя приложения, затем версия

status

M,

( addr u -- addr+4 )

MC,

( addr c -- addr+4 )

MW,

( addr c -- addr+4 )

show

( node -- )

~ygrek/lib/wfl/opengl/GLWindow.f

Описание

$Id: GLWindow.f,v 1.10 2007/12/13 08:05:25 ygreks Exp $

M,

( addr u -- addr+4 )

MC,

( addr c -- addr+4 )

MW,

( addr c -- addr+4 )

~profit/misc/basicdraw.f

Описание

Простейшее средство для вывода графики
После подключения basicdraw.f , создайте слово-отрисовщик
и его xt дайте как аргумент слову START-DRAW:
' <слово-отрисовщик> START-DRAW
Это слово создаёт openGL-окно и начинает цикл отображения
Заданное вами действие отрисовки будет выполнятся всякий
при обновления окна

На данный момент, <слово-отрисовщик> обязательно должно содержать
установку ширины и высоты окна словом SET-SIZE (см. пример)

Реакции на нажатия клавиш можно задавать так:
set-reactions keys
CHAR A asc: <действия> <обрабатывающие> <нажатие> <клавиши-A> ;
...

Реакции на нажатие мыши по экрану задаются так:
' <обработчик мыши> TO click
На вход обработчика подаются координаты нажатия в виду двух чисел

См. также пример внизу


TODO: вывод текста
TODO: исправление неточности в позиционировании курсора мыши
TODO: попеременное послание нескольких клавиш при одновременном нажатии
TODO: обработка пропущенных кадров, синхронизация по времени при вызовах REFRESH'а
TODO: внедрение в Grid

set-reactions

( "state-table -- )

glTHROW

( res -- )

CLS

( -- )

PIXEL

( x y -- )

SET-COLOR

( r g b -- )

SET-SIZE

( w h -- )

START-DRAW

( xt -- n )

REFRESH

( -- )

Глава 3. Archives

Description

some description here

Error: "source/~ac/lib/win/arc/gzip/zlib.f.docbook" not found.

Error: "source/~profit/lib/7zip-dll.f.docbook" not found.

Глава 4. Linked lists

Description

some description here

~day/joop/lib/list.f

Описание

Двухсвязный список.
Можно добавлять как объект, так и значение c массивом
Если добавляем объект или массив, то при уничтожении списка оные
будут уничтожены

mfree

FreeNode

( node -- f)

~ac/lib/list/STR_LIST.F

Описание

str_list.f - реализация простых списков, в частности списков строк.
DoList, NodeValue, AddNode, FreeList работают с односвязными
списками. Каждый элемент списка хранит значение value [ячейка]
и указатель на следующий элемент. Т.е. там не обязательно строки.
Только inList считает, что значение value списка является
адресом xcount-строки.

XCOUNT

( addr -- addr1 u1 )

получить строку addr1 u1 из строки со счетчиком addr
счетчик - ячейчка, а не байт, в отличие от обычного COUNT

NodeValue

( node -- value )

получить значение элемента списка

NextNode

( node1 -- node2 | 0 )

FirstNode

( list -- node )

DoList

( xt list -- )

выполнить токен xt для каждого элемента (node, а не value) списка list
xt ( node -- )

inList

( addr u list -- flag )

проверяет, находится ли строка addr u в списке строк list

FreeNode

( node -- )

FreeList

( list -- )

освобождает динамическую память, занимаемую структурами списка.
Не освобождает память, выделенную элементам списка, если эти
элементы - внешние значения, например строки.

AddNode

( value list -- )

добавляет value в список list

ReverseList

( list -- )

развернуть порядок элементов в списке на обратный

~day/common/link.f

Описание

Dmitry Yakimov 13.03.2000
ftech@tula.net

Идея взята из Win32Forth
Формат записи списка:
4 - указатель на предыдущий узел
n - данные узла
Список представляет просто переменную, хранящую адрес
последнего узла


После применения этого слова обязательно нужно скомпилировать данные
Например,
LINK,
123 ,

LINK,

( list -- )

DO-LIST

( list -- )

На случай если данные узлов - указатели на исполняемые слова

ITERATE-LIST

( list xt -- )

Исполняет xt с параметром `указатель на данные узлов`
Если xt возващает -1 то заканчиваем итерации, если 0 - продолжаем

ITERATE-LIST2

( list xt -- f )

Возвращает параметр плюс xt получает параметры до вызова

CHAIN

( "name" -- )

INHERITH-CHAIN

( list "name" -- )

Создает новый список, но наследует предыдущий

ADD-LINK

( list "name" -- )

~day/lib/staticlist.f

Описание

$Id: staticlist.f,v 1.4 2007/10/20 18:33:39 forther Exp $

двухсвязный динамический список

firstNode

( list -- addr | 0 )

Получить первый элемент списка

CalculateLastNode

( list -- addr | 0 )

Найти последний элемент списка проходом по нему

lastNode

( list -- addr | 0 )

Получить последний элемент списка

listNodeSize

( list - u )

Вернуть размер элемента списка

NextCircleNode

( node -- node1 )

Вернуть следующий элемент списка, после последнего - первый

PrevCircleNode

( node -- node1 )

Вернуть предыдущий элемент списка, после первого - последний

InsertNodeBegin

( addr list )

Вставить элемент addr в начало списка list, связать.

InsertNodeAfter

( addr node list -- )

InsertNodeEnd

( addr list )

ZALLOCATE

( u -- addr )

Выделить память в хипе, обнулить

ZALLOT

( u -- addr )

Выделить память в словаре, обнулить

AllocateNodeBegin

( list -- addr | 0 )

Создать элемент списка в хипе, вставить в список, вернуть адрес
list addr

AllocateNodeEnd

( list -- addr | 0 )

Создать элемент списка в хипе, вставить в список, вернуть адрес
list addr

AllocateNode

AllotNodeBegin

( list -- addr )

Создать элемент списка в словаре, вставить в список, вернуть адрес
list addr

AllotNodeEnd

( list -- addr )

Создать элемент списка в словаре, вставить в список, вернуть адрес
list addr

list:

( u "ccc" )

Создать в словаре именованный список с данным размером элемента

CreateList

( u -- addr )

Создать в хипе список с данным размером элемента, вернуть адрес

CreateStaticList

( u -- addr )

Создать в словаре список с данным размером элемента, вернуть адрес

ForEach

( xt list -- )

Выполнить xt для каждого элемента списка
xt ( node -- )

?ForEachFrom

( xt node -- node | 0 )

Выполнить xt для каждого элемента списка начиная с элемента node
xt ( node -- f ) если f = 0 то прекратить обход

?ForEach

( xt list -- node | 0 )

xt ( node -- f ) если f = 0 то прекратить обход

ForEach:

?ForEach:

FreeNode

( node -- )

Удалить элемент списка

FastFreeNode

FreeList

( list -- )

Удалить все элементы списка

(listSize)

listSize

( list -- u )

(listNth)

list[]

( n list -- node | 0)

(PrintList)

PrintList

( list -- )

~pinka/lib/list_ext.f

Описание

29.Jun.2002 Sat 23:34 created

list-bottom

( hlist -- node )

node=hlist, если список пуст

catanation-lists

( h1 h2 -- )

list+s

( i*x i list -- )

@list

( list -- i*x i )

reverse-list-small

( list -- )

reverse-list

( list -- )

list_allot+

( value hlist -- )

-list_allot+

( value hlist -- )

добавляю узел вниз

list_alloc+

( value hlist -- )

dealloc-list

( hlist -- )

list-each_value

( xt hList -- )

xt ( value -- )

for-list_values

( hList xt -- )

xt ( value -- )

exist-list_value

( value hlist -- flag )

list_entry-node

( value hlist -- node )

enum-list

( xt hList -- )

xt ( -- )

HoldEnum

?enum-list

( xt hList -- )

xt ( -- )

node-entry

( node -- value )

CELL+ @

list-top

( hlist -- node )

~ygrek/lib/list/core.f

Описание

$Id: core.f,v 1.8 2007/09/23 18:17:59 ygreks Exp $
Ещё одна либа для списков
Основной элемент - cons pair, то бишь пара CELL'ов : car с данными и cdr со связью

элемент списка

NEW-NODE

( -- node )

FREE-NODE

( node -- )

освободить память занимаемую элементом списка

LINK-NODE

( node1 node2 -- )

установить связь node1->node2

vnode

( val -- node )

создать новый элемент списка с данными val

empty?

( node -- ? )

TRUE - элемент пуст, нет перехода
FALSE - иначе

cdr

( node1 -- node2 )

перейти к следующему элементу в списке после элемента node1

car

( node -- val )

содержимое ячейки данных элемента node

setcar

( val node -- )

установить данные ячейки

cddr

сокращения :)

cdddr

cdar

cddar

end

( node -- node2 )

пройти по цепочке элементов до последнего - указывающего на ()

cons

( node1 node2 -- node1 )

Добавить элемент в начало списка и вернуть получившийся список
node1->node2

vcons

( value node -- node1 )

node1(value)->node

concat-list

( node1 node2 -- node )

Присоединить весь список node1 в начало списка node2

map

( xt node1 -- )

Применить xt ко всем элементам списка node1
xt: ( node -- ) \ xt получает параметром каждый элемент на нетронутом стеке

mapcar

( xt node -- )

Применить xt к данным всех элементов списка node1
xt: ( node.car -- ) \ xt получает параметром car ячейку каждого элемента на нетронутом стеке

nth

( n node -- node )

Получить n-ый элемент списка, прямым проходом

length

( node -- n )

получить длину списка - прямым проходом до конца списка

FREE-LIST

( node -- )

освободить память занятую списком

(append)

( node1 node2 -- )

node2->...->node1->nil

append

( node1 node2 -- node )

добавить элемент node1 в конец списка node2 (перед пустым элементом)
node2->...->node1->nil

reverse-list

( node -- node1 )

развернуть список в обратную сторону

member?

( n node -- ? )

Проверка на принадлежность

LIST>

( node -- x1 x2 ... xn )

Элементы списка на стек

~ygrek/lib/list/ext.f

Описание

$Id: ext.f,v 1.9 2007/07/13 07:44:35 ygreks Exp $
Типы данных в списке (строка, список, число) и упрощённое задание списка в виде
%[ 1 % " hello" %s %[ 3 % 4 % ]% %l 5 % ]%
%[ 10 0 DO I % LOOP ]%

as-value

( node -- node )

as-list

( node -- node )

as-str

( node -- )

value?

( node -- ? )

str?

( node -- ? )

list?

( node -- ? )

list-what

( node -- n )

cur-list

( -- list )

cur-list!

( list -- )

add-node

( node -- )

%n

( u -- )

%

( u -- )

Добавить u как значение в текущий список

%l

( l -- )

Добавить l как элемент-список в текущий список

%s

( s -- )

Добавить s как элемент-строку (~ac/lib/str4.f) в текущий список

lst(

( -- )

начать новый список - добавлять элементы с помощью %

)lst

( -- list )

завершить создание списка

%[

]%

]%l

FREE-LIST

( node -- )

освободить память занимаемую самим списком, а также данными каждого элемента
используется информация о типах
для строк - STRFREE
для списков - рекурсивно FREE-LIST
для value - ничего

~ygrek/lib/list/more.f

Описание

$Id: more.f,v 1.17 2007/10/11 13:41:34 ygreks Exp $
Больше операций со списками

filter-this

( xt node1 -- node2 )

Вызвать xt для каждого элемента списка
Если xt возвращает 0 - элемент удаляется из списка (память занимаемая самой ячейкой освобождается)
Иначе остаётся
Возвращается результирующий список
xt: ( node -- ? ) \ TRUE - remain, FALSE - free node

scan-list

( xt node -- node1 -1 | empty-list 0 )

Поиск по списку
В случае успеха (xt вернул -1) возвращается node1 на которой поиск был остановлен
иначе - пустой список
xt: ( node -- ? ) \ TRUE - stop scan, FALSE - continue

mapcar

( xt node -- )

map

( xt node1 -- )

list-remove-all

( val node -- node1 )

Вариация с использованием динамического xt
тут используем тот факт что axt=> работает на чистом стеке то есть можно
передавать параметр node в bac4th-вызов и возвращать результат из вызова напрямую на стеке

mapcar!

( xt node -- )

Модифицировать каждый элемент списка с помощью xt
xt: ( node-car -- val ) \ val будет записано в текущий обрабатываемый элемент списка

list-remove-dublicates

( lst -- )

удалить из списка lst все значения-дубликаты

(list-iterate)

( addr )

list-iterator

( list -- xt )

создать xt который при каждом вызове будет оставлять на стеке очередной элемент списка
xt: ( -- node1 )

nlist

( v1 ... vn n -- l )

создать список as-value длиной n из элементов на стеке v1...vn

list->

( node --> node1 \ <-- )

bac4th-итератор по списку

list=>

( node --> node1 \ <-- )

bac4th-итератор по списку

insert-after

( node1 list -- )

Вставить элемент node1 в список list после первого элемента
если list пуст - ничего не делать
list->...->nil
list->node1->...->nil

zipcar!

( xt node1 -- )

применить xt последовательно к парам соседних элементов
и сохранить результат в элемент списка
При этом весь список укорачивается на один элемент
xt: ( node1-car node2-car )

zipcar

( xt node1 -- )

применить xt последовательно к каждым двум соседним элементам
xt: ( node1-car node2-car )

map2

( xt node1 node2 -- )

применить xt к "соответствующим" парам элементов списков node1 node2
xt: ( node1i node2i -- )

equal?

( node1 node2 -- ? )

Проверка на равенство по значению

~ygrek/lib/list/write.f

Описание

$Id: write.f,v 1.7 2007/10/11 13:41:34 ygreks Exp $
Распечатка списка

PARSE-DATA

( n -- a u )

выбрать n символов из входного потока

(.)

( n -- )

print-str-for-eval

( s -- )

print-quoted-str-cut

( s -- )

write-node

( node -- )

write-list

( node -- )

Распечатать список, удобный для интерактива вариант, длинные сроки затроеточиваются

print-node

( node -- )

print-list

( node -- )

Распечатать список, строковое представление пригодное для восстановление EVALUATE'ом
В момент выполнения EVALUATE потребуются слова
>STR из ~ac/lib/str5.f
lst( % %l %s )lst из ~ygrek/lib/list/ext.f
PARSE-DATA из этой либы

dump-node

( node -- )

dump-list

( node -- )

Распечатать список, без лишней обработки - просто адреса

~ygrek/lib/list/all.f

Описание

Глава 5. Records

Description

some description here

lib/ext/struct.f

Описание

STRUCT:

;STRUCT

~af/lib/struct.f

Описание

Andrey Filatkin, af@forth.org.ru
Объявление структур, содержащих элементы - функции.

STRUCT:

( "name" -- old-current )

;STRUCT

( old-current -- )

f:

( offset "new-name" -- offset+cell )

f...:

( offset "new-name" -- offset+cell )

~af/lib/struct-t.f

Описание

Andrey Filatkin, af@forth.org.ru
Объявление структур, содержащих элементы - функции.
Слова для доступа к полям структуры создаются во временном словаре.

TVOC

( -- )

(f:)

( obj offset -- )

(f...:)

( obj cells offset -- )

STRUCT:

( "name" -- old-current )

;STRUCT

( old-current -- )

--

f:

( offset "new-name" -- offset+cell )

f...:

( offset "new-name" -- offset+cell )

Глава 6. Data structures

Description

some description here

~day/joop/lib/stack.f

Описание

~pinka/lib/queue_pr.f

Описание

07.Jul.2001 Sat 21:27 Ruv

Очередь с приоритетом Low Value First

module export:
.queue LeaveLow Enterly New-Queue
VocPrioritySupport Del-Queue

05.Jul.2002 Fri 23:47 + Queue-Count + ^cnt
14.Sep.2003 Sun + mapQueue * Исправлена серьезная ошибка насчет ^cnt

New-Queue

( -- queue )

Enterly

( x pr queue \ newel -- )

включить элемент x в очередь queue с приоритетом pr

LeaveLow

( queue -- x true | false )

исключить из очереди первый элемент (c наименьшим численным значением pr),
оставить элемент на стеке и true, в случае успеха
или false в случае не успеха (пустая очередь).

Del-Queue

( queue -- )

queue.

( q -- )

Queue-Count

( q -- count )

mapQueue

( q xt \ e -- )

xt ( value pr -- )

~mlg/SrcLib/bitfield.f

Описание

>ROR>

( x -- x' )

===========================================================================

>SHR>

( x -- x' )

<SHL<

( x -- y )

D<SHL<

( x -- yl yh )

<ROL<

( x -- y )

x+m0

( x mask -- x' elem )

replace non-zero bits in mask by bits from x producing elem;
x' contains remaining bits

x+m

( x mask -- elem )

x.mask:=

( x field mask -- x.mask:=field )

x/m0

( x' opc-elem mask -- x )

extract the bits from opc-elem masked by mask; append them to x'

x.mask

( x mask -- x' )

~pinka/lib/charset.f

Описание

<INTRODUCTION>
множество символов
ver 0.2 ( 27.04.2000)

(c) 1999-2000 Ruvim Pinka
</INTRODUCTION>

<HISTORY>
09.04.99г. 04:36:16 - создано.
... кое что добавлено
03.01.2000
добавлен постфикс.
27.04.2000
дурной синтаксис был ( addr value )
исправил, сделав работу по аналогии со словами ! +! ( value addr )
</HISTORY>

<BODY>




256 бит = 8 бит * 32 = 32 байта
= 32 bit * 8 = 8 cells

created-set

( a u -- )

create-set

( -- )

создать пустое множество в словаре

new-set

( -- a-set )

динамически создать пустое множество. освобождение по FREE

getmask

( char a-set -- a-byte byte-mask )

belong

( char a-set -- f )

проверить элемент

set+

( char a-set -- )

включить элемент

set-

( char a-set -- )

исключить элемент

set-str+

( addr u a-set -- )

включить все символы из заданной строки во множество

set.

( a-set -- )

Глава 7. Sorting and search

Description

some description here

~mlg/SrcLib/hsort.f

Описание

above

leftrightbelow

[min]exch[MAX]n?

( i j -- i j ~f )

chooseMAX

( i j -- k )

AddToPyr

( i -- )

ConstrPyr

( -- )

TopGoesDown

( m -- m )

SortPyr

( -- )

HeapSort

( -- )

Error: "source/~pinka/samples/2003/common/QSORT.F.docbook" not found.

~profit/lib/binary-search.f

Описание

binary-search

( a b f -- i 0|-1 )

binary-search неудобный! Используйте reverse-function

fork-cycle

( a b --> c \ <-- flag )

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

reverse-function

( a b res --> x \ x flag <-- x' )

Ищет в диапазоне (a,b) такое значение x, что функция
(записанная в шитом коде после неё) равна res
Если найдено flag=TRUE и x -- значение, где f(x)=res
Если не найдено, то flag=FALSE и x -- равно либо
floor(x'), где f(x')=res, либо равно одному из краевых
значений если искомого значения аргумента вообще нет в
заданном диапазоне.
Только для линейных функций, само собой.
PRO .. CONT не работают из-за того что PREDICATE .. SUCCEEDS тоже используют L-стек
поэтому адрес успеха сохраняем в локальной переменной и вызываем вручную

Глава 8. Programming techniques

Description

some description here

lib/ext/locals.f

Описание

28.Mar.2000 Andrey Cherezov Copyright [C] RU FIG

Использованы идеи следующих авторов:
Ruvim Pinka; Dmitry Yakimov; Oleg Shalyopa; Yuriy Zhilovets;
Konstantin Tarasov; Michail Maximov.

!! Работает только в SPF4.


Простое расширение СП-Форта локальными переменными.
Реализовано без использования LOCALS стандарта 94.

Объявление временных переменных, видимых только внутри
текущего слова и ограниченных временем вызова данного
слова выполняется с помощью слова "{". Внутри определения
слова используется конструкция, подобная стековой нотации Форта
{ список_инициализированных_локалов \ сп.неиниц.локалов -- что угодно }
Например:

{ a b c d \ e f -- i j }

Или { a b c d \ e f[ EVALUATE_выражение ] -- i j }
Это значит что для переменной f[ будет выделен на стеке возвратов участок
памяти длиной n байт. Использование переменной f[ даст адрес начала этого
участка. \В стиле MPE\

Или { a b c d \ e [ 12 ] f -- i j }
Это значит что для переменной f будет выделен на стеке возвратов участок
памяти длиной 12 байт. Использование переменной f даст адрес начала этого
участка.

Часть "\ сп.неиниц.локалов" может отсутствовать, например:

{ item1 item2 -- }

Это заставляет СП-Форт автоматически выделять место в
стеке возвратов для этих переменных в момент вызова слова
и автоматически освобождать место при выходе из него.

Обращение к таким локальным переменным - как к VALUE-переменным
по имени. Если нужен адрес переменной, то используется "^ имя"
или "AT имя".


Вместо \ можно использовать |
Вместо -> можно использовать TO

Примеры:

: TEST { a b c d \ e f -- } a . b . c . b c + -> e e . f . ^ a @ . ;
Ok
1 2 3 4 TEST
1 2 3 5 0 1 Ok

: TEST { a b -- } a . b . CR 5 0 DO I . a . b . CR LOOP ;
Ok
12 34 TEST
12 34
0 12 34
1 12 34
2 12 34
3 12 34
4 12 34
Ok

: TEST { a b } a . b . ;
Ok
1 2 TEST
1 2 Ok

: TEST { a b \ c } a . b . c . ;
Ok
1 2 TEST
1 2 0 Ok

: TEST { a b -- } a . b . ;
Ok
1 2 TEST
1 2 Ok

: TEST { a b \ c -- d } a . b . c . ;
Ok
1 2 TEST
1 2 0 Ok

: TEST { \ a b } a . b . 1 -> a 2 -> b a . b . ;
Ok
TEST
0 0 1 2 Ok

Имена локальных переменных существуют в динамическом
временном словаре только в момент компиляции слова, а
после этого вычищаются и более недоступны.

Использовать конструкцию "{ ... }" внутри одного определения можно
только один раз.

Компиляция этой библиотеки добавляет в текущий словарь компиляции
Только два слова:
словарь "vocLocalsSupport" и "{"
Все остальные детали "спрятаны" в словаре, использовать их
не рекомендуется.

{

~pinka/lib/lambda.f

Описание

Лямбда-конструкция.
Код под SPF
идея: SU.FORTH, от Piter Sovietov
Ruvim, 06.01.2000
14.May.2007 добавлена установка LAST-NON для RECURSE (true-grue, ygrek)

LAMBDA{

( -- )

время компиляции ( -- orig1 xt )

}

( -- xt )

время компиляции ( orig1 xt -- )
код внутри конструкции LAMBDA{ } не выполняется, возвращается xt на этот код.

~yz/lib/inline.f

Описание

вставка кусков кода инлайном
Юрий Жиловец, 27.10.2003

(:

( -- resolve xt id)

;)

( -- resolve xt id)

~spn/se.f

Описание

S-expressions 20070727, Peter Sovietov

.s-mark

.s-tag

.s-car

.s-cdr

/s-obj

lp-reset

( n )

s-depth

( -- n )

p->s

( x -- s: x )

s->p

( s: x -- x )

s-dup

( s: x -- s: x x )

s-drop

( s: x )

s-swap

( s: x y -- s: y x )

s-over

( s: x y -- s: x y x )

cp-reset

( n )

s->c

( s: x -- c: x )

c->s

( c: x -- s: x )

c-pick

( n -- s: x )

(pair)

( a )

(null)

( a )

(number)

( a )

(xt)

( a )

()

( -- s: 0 )

s-variable

get

( a -- s: x )

set

( a s: x )

s-reserve

( a n )

s-mark

( a )

s-sweep

gc

(cons)

( x y -- z )

cons

( s: x y -- s: z )

->s

( n -- s: n )

xt->s

( a -- s: a )

s->

( s: x )

pair?

( s: x -- ? )

null?

( s: x -- ? )

number?

( s: x -- ? )

xt?

( s: x -- ? )

car

( s: x -- s: y )

cdr

( s: x -- s: y )

set-car!

( s: x y )

set-cdr!

( s: x y )

list

( n s: ... -- s: x )

s(

( -- n )

)s

( n s: ... -- s: x )

eq?

( s: x y -- ? )

equal?

( s: x y -- ? )

list-tail

( n s: x -- s: y )

list-ref

( n s: x -- s: y )

s-execute

( s: f )

for-each-pair

( s: x f )

last-pair'

( s: x e -- s: e )

last-pair

( s: x -- s: y )

for-each

( s: x f )

length'

( i s: e -- j )

length

( s: x -- n )

fold

( s: x z f -- s: y )

reverse'

( s: x e -- s: y )

reverse

( s: x -- s: y )

reverse!'

( s: x e -- s: y )

reverse!

( s: x -- s: y )

map'

( s: f x e -- s: y )

map

( s: x f -- s: y )

list-copy

( s: x -- s: y )

append

( s: x y -- s: z )

filter'

( s: f x e -- s: y )

filter

( s: x f -- s: y )

1pr

( a -- s: f )

1op

( a -- s: f )

2op

( a -- s: f )

(.atom)

( s: x )

.atom

.se

( s: x )

gc-free

( -- n )

.free

.locals

~ygrek/lib/fun/memoize.f

Описание

auto-memoize

memoize - сохранение промежуточных результатов вычислений функции
авто-memoize - это конструкция превращающая любую функцию (CELL -> CELL) в её
memoize'ованную версию

restrictions of this implementation:
recursive function must use run-time lookup and the name of the
memoized version overlaps the name of the original func

memoize:

( "name" -- )

~profit/lib/bac4th.f

Описание

Бэкфорт, порт на SPF
см. статью http://forth.org.ru/~mlg/index.html#bacforth
Копия этой статьи есть в дистрибутиве: <папка SPF>/devel/~mlg/index.html#bacforth

ENTER

( xt -- )

Выполнение вектора исполнения xt

ONFALSE

( f -- )

ONTRUE

( f -- )

Откат если f=true, то есть _пропускает_ только f=0

R@ENTER,

: R@ENTER, SetOP 0xFF C, 0x14 C, 0x24 C, ; ( \ CALL [ESP]

R>ENTER,

: R>ENTER, SetOP 0x5B C, SetOP 0xFF C, 0xD3 C, ; ( \ POP EBX CALL EBX

PRO

CONT

: CONT L> >R R@ ENTER R> >L ; (

RUSH

( xt -- )

MOV EBX, EAX
MOV EAX, 0 [EBP]
LEA EBP, 4 [EBP]
JMP EBX

RUSH>

( "name )

RESTB

( n --> n / n <-- )

Не изменяя стек при прямом проходе, на откатном ходу кладёт на стек сохранённое значение вершины стека
: RESTB ( n --> n / n <-- ) R> OVER >R ENTER R> ; (
POP EBX
PUSH EAX
CALL EBX
MOV -4 [EBP] , EAX
POP EAX
LEA EBP, -4 [EBP]

2RESTB

Аналог RESTB для двойных значений
: 2RESTB ( d --> d / d <-- ) R> -ROT 2DUP 2>R ROT ENTER 2R> ; (
POP EBX
PUSH [EBP]
PUSH EAX
CALL EBX
MOV -4 [EBP] , EAX
POP EAX
LEA EBP, -8 [EBP]
POP [EBP]

BSWAP

( a b <--> b a )

Откатываемый SWAP, т.е. выполняет SWAP и на прямом и на обратном ходу,
откатывая стек к начальному положению

SWAPB

( a b --> a b \ b a <-- a b )

SWAP при откате, т.е. на прямом ходу ничего не делает, на обратном ходу
-- выполняет SWAP.

BDROP

( n <--> )

Откатываемый DROP

DROPB

( n --> n / <-- n )

DROP при откате, этим словом можно приводить одиночные значения на стеке
к итерируемым значениям, нужных для некоторых агрегаторов (типа seq{ }seq)

2DROPB

( n --> n / <-- n )

Двойной DROP при откате

KEEP

Восстановление значения переменной addr при откате
: KEEP ( addr --> / <-- ) R> SWAP DUP @ 2>R ENTER 2R> SWAP ! ; (
POP EBX
PUSH EAX
MOV EAX , [EAX]
PUSH EAX
MOV EAX , 0 [EBP]
LEA EBP , 4 [EBP]
CALL EBX
POP EBX
POP EDX
MOV [EDX] , EBX

KEEP!

( n addr --> / <-- )

Запись значения в переменную addr с восстановлением при откате
: KEEP! ( n addr --> / <-- ) R> OVER DUP @ 2>R -ROT ! ENTER 2R> SWAP ! ; (

BACK

Задать действия при откате ( BACK .. TRACKING ), или, иначе говоря,
положить адрес начала последовательности шитого кода между словами
BACK ... TRACKING на стек возвратов

TRACKING

START{

( -- org dest $TART )

Открывающая скобка "суперцикла"

DIVE

Рекурсивный нырок внутри суперцикла в самое себя

}EMERGE

Закрывающая скобка "суперцикла"

S|

Восстановление стека
Нужно для обеспечения баланса стека при прямом и обратном ходе, при наличии таких
опасных процедур как отсечения (NOT: -NOT или CUT: -CUT)

NOT:

Квантор отрицания

-NOT

PREDICATE

Предикат, преобразование успеха/неуспеха в логическое значение

SUCCEEDS

ALL

квантор общности, выраженный через два вложенных квантора отрицания

ARE

OTHER

Почему-то у mlg в дипломке согласно иллюстрации OTHER делает так (я несколько месяцев честно пытался понять этот перехлёст):
: OTHER ?COMP N0T ?PAIRS >RESOLVE2 POSTPONE (-NOT) ; IMMEDIATE
но должно так:

WISE

CUT:

отсечение
адр. вершины стека возвр.--> на L-стек
а при откате - убрать эту отметку

-CUT

-NOCUT

убрать точки возврата до отметки

*>

блок альтернатив

<*>

<*

agg{

( -- )

храним значение накопителя

{agg}

( intermed -- )

Выдача промежуточного накапливаемого в данный момент значения агрегатора
из накопителя

}agg

( agg succ -- )

Во время исполнения на стеке должно лежать значение которое надо
при-обработать к начальному (добавить, сконкатенировать, умножить и т.д.)

+{

Сумматор итерируемых значений

}+

MAX{

Определение максимума среди итерируемых значений

}MAX

*{

Произведение итерируемых значений

}*

&{

Лог. произведение итерируемых значений

}&

|{

Лог. сложение итерируемых значений

}|

{}

Выдача промежуточных результатов простых агрегаторов ( +{ ... }+ и прочие)

(AMONG)

Блок AMONG ... EACH ... ITERATE
порождается код:
(among) (among>) {addr} ... (each) ... (iterate) addr: код_за_циклом
Адрес (AMONG>)
При откате убрать указатель трассы итератора
Указатель начала трассы итератора
(AMONG>): успех цикла при неуспехе итератора

(AMONG>)

Адрес ссылки на код за циклом
Сохранить указатель начала трассы

(EACH)

Адрес тела цикла
Новый адрес конца трассы итератора
При откате убрать адрес конца трассы
и саму трассу итератора

(ITERATE)

Убрать адрес кода, находящегося за циклом
Указатели на начало и конец трассы итератора
Сохранить указатели трассы итератора
Убрать новый указатель начала трассы и
восстановить старые указатели
при откате
Адрес конца и длина трассы итератора
Новый адрес начала трассы итератора
Отвести место на стеке возвратов
Скопировать трассу итератора

FINIS

AMONG

EACH

ITERATE

~profit/lib/bac4th-closures.f

Описание

Замыкания или частично определённые функции.
Функция задаётся строкой, которая компилируется в кучу.
При откате занятая функцией область в куче снимается.

S" 2 DUP * ." axt ( xt ) -- выдаст на стек адрес кода
который соответсвует коду получившемуся при компиляции
строки

Взятый таким образом отрезок кода необходимо снимать
словом DESTROY-VC (~profit/lib/compile2Heap.f)

Чтобы снимать отрезок кода автоматически, при выходе
из текущего определения (или при поднятии "из глубины"
bac4th-успеха) можно использовать axt=>
S" 2 DUP * ." axt=> ( xt )

Возможно также отрезок кода задать в несколько строк
через динамические строки ~ac/lib/str5.f
(строка со стека освобождается внутри слова):
" 2 DUP
* . " straxt=> ( xt )

При этом в генерируемый отрезок кода кода можно скомпилировывать
свои куски, задавая их на стеке или выполняя компилирующие действия
IMMEDIATE-словами подобными LITERAL , его можно использовать для
передачи числа на стеке в компилируемую функцию:
4 2 1 S" LITERAL LITERAL + LITERAL * ." axt EXECUTE
Сформирует код "1 2 + 4 *" и выполнив его, напечатает: "12"

Или же можно входить напрямую в режим интерпретации словами [ и ] :
' . S" 3 0 DO I [ COMPILE, ] LOOP " axt EXECUTE
выведет 0 1 2
Действие для обработки чисел мы задали снаружи замыкания ( ' . )
[ COMPILE, ] вкомпилировал xt внутрь генерируемой функции

Такая передача значений, внутрь "замыкания", противоречит
следующему абзацу пункта 3.2.3.2 ANS-94:

"Стек потока-управления, может, но не обязательно, физически
существовать в реализации. Если он существует, то может быть,
но не обязательно, реализован с использованием стека данных.
Формат стека потока-управления -- определяется реализацией.
Так как стек потока-управления может быть реализован с
использованием стека данных, элементы, помещенные на стек
данных недоступны для программ после помещения элементов
на стек потока-управления, и остаются недоступным до удаления
элементов стека потока-управления."

REQUIRE MemReport ~day/lib/memreport.f

axt

( addr u -- xt )

создаём виртуальный кодофайл
подключаем словарь с своими структурами управления
компилируем строку в виртуальный кодофайл
отключаем его по окончании компиляции
ставим команду выхода
оставляем исполняемый адрес начала кодофайла

axt=>

( addr u --> xt \ <-- )

компилируем строку, берём исполняемый адрес кода
по окончании обработки очистить кодофайл
и кидаем его наверх

straxt=>

( s --> xt \ <-- )

То же самое что и compiledCode , но с динамическими строками из ~ac/lib/str5.f
Это позволяет писать код в несколько строк
Поданая на вход строка сразу после использования освобождается

compiledCode

( addr u --> xt \ <-- )

STRcompiledCode

( s --> xt \ <-- )

Глава 9. Debugging facilities

Description

some description here

~ac/lib/memory/heap_enum2.f

Описание

GetHeaps

( -- addr n )

addr - адрес массива с хэндлами хипов
n - к-во хэндлов в массиве

HeapEnum

( xt h -- )

MemDump1

( entry -- )

MemDump

( entry -- )

MEM

~day/lib/mem_sanity.f

Описание


~day\lib\mem_sanity.f

FillStub

( u addr )

ALLOCATE

( u -- addr ior )

mem_abort1

mem_abort2

FREE

~day/lib/memreport.f

Описание

$Id: memreport.f,v 1.5 2007/11/05 10:05:16 ygreks Exp $
Report all memory leaks, just use MemReport word
Use it for debug purposes, mind - it slowdowns the program!
[c] Dmitry Yakimov ftech@tula.net


+ выводит не только утечки но распечатку стека возвратов при их возникновении
+ многопоточна, может выводить отчеты для отдельных потоков, MemReportThread
+ отметки блоков памяти с воможностью указать диапазон для вывода в отчёте

ALLOCATE

( n -- addr ior )

HEAP-COPY

( addr u -- addr1 )

FREE

( addr -- ior )

AllocList listSize CR ." Size - " .

RESIZE

( addr n -- addr2 ior )

ClearMemInfo

( -- )

FreeList is broken?

countMem

( -- size n )

RemoveThreadMemoryInfo

( threadId -- )

MemReport

( -- )

MemReportThread

( threadId -- )

NewMemoryMark

( -- n )

Установить новую отметку и вернуть её номер

SetReportMark

( n -- )

В отчёте MemReport показывать только те блоки памяти что были выделены после отметки n
0 для того чтобы показывать все блоки

ShowFailedFree

( -- )

HideFailedFree

( -- )

lib/ext/debug/accert.f

Описание

$Id: accert.f,v 1.3 2007/11/03 09:26:29 ygreks Exp $
~day 11.02.2001
В ACCERT удобно выводить лог, например
ACCERT( 2DUP LOG )
проверять значения на правильность, выводить отладочную
информацию
Уровни ACCERT-LEVEL:
0 - не компилировать ACCERT'ы
1 - компилировать все ACCERT'ы
2 - компилировать ACCERT уровня выше 1
3 - компилировать ACCERT уровня выше 2

_LINE_

компилирует строковый литерал - u - номер текущей строки

_FILE_

компилирует строковый литерал - имя текущего файла трансляции

ACCERT-EV

( addr u n -- )

_ACCERT(

( n -- )

компилирует текст до ) если n > ACCERT-LEVEL-1
иначе пропускает его

ACCERT1(

ACCERT2(

ACCERT3(

ACCERT(

lib/ext/debug/tracer.f

Описание

(c) ~micro 2001

DOES>

:

;

~af/lib/elapse.f

Описание

Таймер

get-local-time

( -- )

ms@

( -- ms )

time-reset

( -- )

.elapsed

( -- )

elapse

( -<commandline>- )

~pinka/lib/tools/profiler.f

Описание

промежуточное. до ver 0.3 не доведено

Отладчик времени выполнения слов (profiler). SPF3.70
example - в конце.

history
11.1999,,, 02.2000
06.07.2000 ver 0.1
- сменил имя debug на profile
- было LAST @ ,сделал LATEST (***) ( чтобы с locals.f правильно работало и вообще.)
/ profiler.f должен подключатся до locals.f, чтобы работал для слов с локальными переменными /
- ведение списка слов с таймеров
- сброс статистики
- если 0 вызовов, то не выводит строку для этого слова.
27.11.2000 ver 0.2
- отвязка от структуры словаря. достигнуто минимальными изменениями и переработкой.

12.03.2001 ver 0.3
* фикс THROW - неверно получало timer-info текущего слова.
* пофиксил получение timer-info - слово last_timer_info

19.Nov.2002 Tue 01:02
* исправил ошибку в слове DU<
see:
From: mlg 3 <m_l_g3@yahoo.com>
To: spf-dev@lists.sourceforge.net
Date: Sat, 9 Nov 2002 10:05:16 -0800 (PST)
11.Dec.2003 Thu 11:17 * GetTimes принимает строку: ( a u -- ... )

Copyright (C) R.P., 1999-2002

profile on - включить компиляцию кода таймера ( на все след. слова вешается таймер )
profile off - отключить компиляцию кода таймера ( на все след. слова таймер не вешается)
timer on/off - если вЫключено, то ничего не подсчитывается.
ResetProfiles - сбросить статистику.
.AllStatistic - генерирует статистику по времени выполнения каждого слова
Формат
Calls Ticks AverageTicks Name (Rets)
Где
Calls - количество вызовов
Ticks - общее время работы слова
AverageTicks - среднее время за вызов
Name - имя
(Rets) - число зафиксированных возвратов, если оно отличается
от числа вызов. Суммарное и среднее время считается только
по зафиксированным выходам.
Выходы фиксируются по EXIT , THROW , ";"

Данный профайлер не реентерабелен к многопоточности и рекурсии.
Т.е. если слово с таймером будет рекурсиво вызываться или будет
работать одновременно в разных потоках, то результаты для этого слова будут
не верны.

Неопределенная ситуация, если значение profile меняется
в процессе компиляции слова с off на on
Т.е. значение profile лучше не менять во время компиляции слова :)
( например, последовательностью [ profile on ] )

Значение AverageTicks занимает DWORD.
если результат не влезает, то выводится '-'
Это может произойти, если среднее время выполнения превысит ~14 сек ( на 300 МГц)
( если бы были слова D* D/ то не было бы этого ограничения ;)

>NAME

( CFA -- NFA )

GetTacts

on

( a -- )

off

( a -- )

GetTimes

( a u -- d-ticks u-rets true | false )

ResetProfiles

( -- )

.AllStatistic_o

( -- )

старый вариант. узнает слово с таймеров по идендификатору.
( вывод ограничен контекстом словарей )

.AllStatistic

( -- )

новый варинат. выводит все по списку.

.StatisticByCFA

( CFA_last_word -- )

EXIT

THROW

( errno -- )

:

( -- )

;

( -- )

~ygrek/lib/testcase.f

Описание

$Id: testcase.f,v 1.4 2008/02/04 16:22:29 ygreks Exp $
30.Dec.2006 taken from forthgui by ~day

testcase.f day

((

->

RECORD DEPTH
IF THERE IS SOMETHING ON STACK
SAVE THEM

))

(ACTUAL) CONTENTS.
IF DEPTHS MATCH
IF THERE IS SOMETHING ON THE STACK
FOR EACH STACK ITEM
COMPARE ACTUAL WITH EXPECTED

TESTING

TEST-ARRAY

( addr u addr1 u1 )

comparing arrays

TESTCASES

END-TESTCASES

~profit/lib/testing.f

Описание

/TEST
Слово отделяющее секцию с проверочным кодом
библиотеки от собственно рабочего кода.

Отличие от \EOF в том что для запуска тестового
кода менять исходник библиотеки не надо. Просто
запускай его и всё. При этом при подключении
библиотеки из других файлов тестовый код не
запускается.

То есть: запускаешь саму библиотеку -- тесты
идут. Запускаешь файл, использующий библиотеку,
-- тесты не проходят.

/TEST

$>

Глава 10. Math

Description

some description here

lib/include/float2.f

Описание

Float-библиотека для spf4
Слова высокого уровня
[c] Dmitry Yakimov [ftech@tula.net]
64 битная арифметика по умолчанию!

+ FABORT заменен FNOP
! исправлен FINIT, автоматическая реинициализация при исключении
! новый необрезающий REPRESENT
! исправлена бесконечность ~yGREK

! переписан F. ,рефакторинг ( 9.03.2005 ~day )
! пофиксен FS. ( 9.03.2005 ~day )

Hi level words
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\

~day\float\floatkern.f

FSTRICT

( -- ? )

SET-FSTRICT

( ? -- )

2e

1e

.e

PRECISION

( -- u )

SET-PRECISION

( u -- )

PRINT-EXP

PRINT-FIX

FSINGLE

FDOUBLE

FLONG

FLOATS

FLOAT+

FSTATE

stackIsEmpty

DF,

( F: r -- )

SF,

( F: r -- )

FINF

-FINF

ERROR-MODE

Младшие шесть бит маскируют ошибки #I #D #Z #O #U #P
потому что #P реагирует на ноль

NORMAL-MODE

SILENT-MODE

FPUmask

FPUstate

F!

F@

F,

( F: r -- )

TNUM

( addr u -- d )

F10X

( u -- R: 10^u )

SEARCH-EXP

( c-addr1 u -- c-addr2 u flag )

GET-EXP

( addr u -- d )

FRAC>F

( addr u -- F: r )

>FLOAT-ABS

( addr u -- F: r D: bool )

CHECK-SET

( addr u max min addr2 u2 -- addr2 u2 bool )

<SIGN>

( addr u max min -- addr2 u2 bool )

<EXP>

( addr u max min -- addr2 u2 bool )

<DOT>

( addr u max min -- addr2 u2 bool )

<DIGITS>

( addr u max min -- addr2 u2 bool )

?FLOAT

( addr u -- bool )

>FLOAT

( addr u -- F: r true | false )

FABORT

Если нет маски, то ругаемся

FLOOR

( F: r1 -- r2 )

FROUND

( F: r1 -- r2 )

#EXP

( -- n )

Дает число знаков целой части числа

0.1E

REPRESENT

( c-addr u -- n flag1 flag2 )

from http://www.alphalink.com.au/~edsa/represent.html

(T0)

( c-addr u1 -- c-addr u2 )

trim trailing '0's

FDISPLAY

( n -- )

format-exp

( ud1 -- ud2 )

.EXP

PrintFInf

( F: r -- r )

(F.)

( n1 n2 )

n1 - exponent
n2 - sign

FS.

( r -- )

F.

( r -- )

G.

( r)

Adjust

( n - n' 1|2|3 )

FE.

( r)

C-TO-PAD

( c )

S-TO-PAD

( addr u )

>FNUM

( F: r -- addr u )

DFLOAT+

( addr1 -- addr2 )

DFLOATS

( n1 -- n2 )

SFLOAT+

( addr1 -- addr2 )

SFLOATS

( n1 -- n2 )

FLIT,

FLITERAL

( F: r -- )

F~

( F1 F2 F3 -- FLAG )

FALOG

FSINH

FCOSH

FTANH

FATANH

FASINH

FACOSH

FTO

HIGH-FINIT

FALIGN

FALIGNED

SFALIGN

SFALIGNED

DFALIGN

DFALIGNED

FVARIABLE

FCONSTANT

FVALUE

NOTFOUND

( c-addr u -- )

~nn/lib/fraction.f

Описание

Fractions

S" ~nn/lib/gcd-code.f" INCLUDED

GCD

( n1 n2 -- u3)

FR-NORMALIZE

( a1/b1 -- a2/b2)

FR+

( a1/b1 a2/b2 -- [a1*b2+a2*b1]/[b1*b2])

FR-NEGATE

FR-ABS

FR-

FR*

( a1/b1 a2/b2 -- a3/b3)

FR/

( a1/b1 a2/b2 -- a3/b3)

FRS*

( a1/b1 n2 -- a2/b2)

?SPACES

R-TYPE

( addr len1 len-field -- )

L-TYPE

( addr len1 len-field -- )

FR>/STR

( a/b -- addr u)

FR/.R

( a/b len --)

FR/.L

( a/b len --)

FR/.

( a/b --)

FR>STR

( a/b -- addr u)

FR.R

( a/b len --)

FR.L

( a/b len --)

FR.

?FR-SLITERAL

( addr u -- )

NOTFOUND

( addr u -- )

FR:

( -- a/b)

FR-VARIABLE

FR-CONSTANT

FR0=

FR0<

( a/b -- ?)

FR0>

( a/b -- ?)

FR<

( a1/b1 a2/b2 -- ?)

FR>

( a1/b1 a2/b2 -- ?)

FR=

FR!

FR@

FR?

FR-DUP

FR-DROP

FR-SWAP

FR-OVER

FR-NIP

FR-TUCK

FR-SIGN

FRR/.

( a/b --)

~pinka/lib/BigMath.f

Описание

OPTIONAL BIGMATH 64 Bit Math with Rational Approximations

{ ====================================================================
(C) Copyright 1999 FORTH, Inc. www.forth.com

RATIONAL APPROXIMATIONS
==================================================================== }

{ --------------------------------------------------------------------
Given a number expressed as a ratio of 63-bit unsigned integers,
calculates a ratio of 31-bit numbers that very closely approximates the
original ratio. Such 31-bit ratios may then be used with */ for
accurate multiplication by "real" constants.

These routines will reproduce, or improve upon, the ratios used in
STARTING FORTH, Leo Brodie, p.122. For best results, use the largest
values (with the most sig- nificant bits) possible, as in these
examples:

18.84955592 6.00000000 RATIO . . ( Pi, gives 235619449/75000000 )
19.02797280 7.00000000 RATIO . . ( e, gives 11892483/4375000 )

Dependencies: Double Number Operators

Exports: D* DU/MOD RATIO
-------------------------------------------------------------------- }

{ ---------------------------------------------------------------------
Double Number Arithmetic by Wil Baden

For a full copy of the source for his article send e-mail to
WilBaden@Netcom.com requesting Stretching Forth #19: Double Number
Arithmetic.

TUM* TUM/ triple Unsigned Mixed Multiply and Divide.

T+ T- triple Add and Subtract.

DU/MOD Double Unsigned Division with Remainder. Given an unsigned
2-cell dividend and an unsigned 2-cell divisor, return a 2-cell
remainder and a 2-cell quotient. The algorithm is based on Knuth’s
algorithm in volume 2 of his Art of Computer Programming, simplified
for two-cell dividend and two-cell divisor.

--------------------------------------------------------------------- }

addeded 07.03.2001 by ruv
--- for compatibility to SPF2.5 ---

NOT

+CARRY

( a b -- a+b carry )

-BORROW

( a b -- a-b borrow )

D*

( a . b . -- a*b . )

TUM*

( n . mpr -- t . . )

TUM/

( t . . dvr -- n . )

T+

( t1 . . t2 . . -- t3 . . )

T-

( t1 . . t2 . . -- t3 . . )

NORMALIZE-DIVISOR

( divr . -- divr' . shift )

DU/MOD

( divd . divr . -- rem . quot . )

ARRAY

( n -- )

ADV

( -- flag )

(RATIO)

( -- )

RATIO

( +d +d -- n n )

~ygrek/lib/math/inv_normal.f

Описание

$Id: inv_normal.f,v 1.1 2007/04/18 19:49:52 ygreks Exp $
Квантиль нормального распределения
http://algolist.manual.ru/maths/matstat/normal/index.php

F>

inv_normalDF

( F: level -- F: q )

~ygrek/lib/math/gcd.f

Описание

$Id: gcd.f,v 1.1 2007/08/25 09:03:46 ygreks Exp $
Наибольший общий делитель
Обратное число по модулю
Только для обычных чисел - 1 CELL

gcd-step

( x y -- y r n )

x = n*y+r

(gcd)

( x y -- n )

check-gcd-conditions

( x y -- x y )

GCD

( x y -- z )

z = НОД(x,y)
Наибольший Общий Делитель

InvertNumber

( a m | z q p0 p1 -- x )

x : ax = 1 (mod m)
Обратное число по модулю

Глава 11. Random numbers

Description

some description here

lib/ext/rnd.f

Описание

RND DAY 04.05.2001

SEED

( U -- )

RANDOM

( -- U )

CHOOSE

( U1 -- U2 )

U2 - RANDOM NUMBER FROM 0 TO U1

RANDOMIZE

~day/common/RND.F

Описание

Неплохой и быстрый генератор псевдослучайной последовательности чисел.
ВНИМАНИЕ: В предыдущей версии CHOOSE не работало!!!

Якимов Д. А. 24.01.99 nsoft@chat.ru
Для СП-ФОРТ 3.15

В принципе может применяться в криптографии, но нужно действовать сл.
образом: массив заполняем генератором с одним параметром,
а индекс в нем выбираем с помощью другого генератора, с другими
немного параметрами.
Элемент по этому индексу и есть псевдо-случайное число.
После выборки элемента заменяем его на новый с помощью 1-го
генератора.
Делать 5 минут, да мне не нужно :

RANDOMIZE

RANDOM

( -- u )

CHOOSE

( u1 -- u2 )

Псевдослучайная величина от 0 до u1-1

~af/lib/random.f

Описание

generates random numbers 12jan94py

Copyright (C) 1995 Free Software Foundation, Inc.

This file is part of Gforth.

Gforth is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

RANDOMIZE

RANDOM

( -- n )

CHOOSE

( n -- 0..n-1 )

~ygrek/lib/neilbawd/mersenne.f

Описание

Mersenne Twister
<!--BASE HREF="http://home.earthlink.net/~neilbawd/mersenne.html"-->

SGENRAND

( seed -- )

LSGENRAND

( &seed-array -- )

The length of seed-array[] must be at least MTN cells.

GENRAND

( -- u )

GENRANDMAX

( u -- n )

FGENRAND

( F: -- 0. <= r <= 1. )

FGENRAND-1

( F: -- 0. <= r < 1. )

Глава 12. Hashes

Description

some description here

~pinka/lib/hash-table.f

Описание

Расстановочные таблицы
Ю. Жиловец, 18.12.2002, с добавлениями А. Черезова
18.Sep.2003 ruvim@forth.org.ru версия оригинального ~yz\lib\hash.f
распределяющая память стандартным образом ALLOCATE/FREE
(по умолчанию, локальную память потока)
Максимальная длина значения для 'HASH!' -- 255 байт! (т.к. через CALLOC)
22.Sep.2003 ruv,
* HASH! и т.п. к виду ( avalue nvalue akey nkey h -- )
+ for-hash
+ clear-hash, hash-count, hash-empty? \ by "Igor Panasenko" <PanasenkoIG@lankgroup.ru> ( ~pig)
24.Sep.2003 pig,
+ HASH? - проверка наличия ключа в хэше
31.Oct.2003 pig,
* исправление clear-hash - записи удалялись, но ссылки на них оставались в таблице
01.Nov.2003 ruv
* make-hash теперь new-hash - и вынесен в интерфейс.
22.Dec.2003 pig
* итераторы all-hash, for-hash теперь позволяют вложенный вызов

SALLOC

( a u -- a1 )

CALLOC

( a u -- a1 )

ZALLOC

( az -- a1 )

new-hash

( n -- h )

HASH!

( avalue nvalue akey nkey h -- )

HASH!Z

( zvalue akey nkey h -- )

HASH!N

( value akey nkey h -- )

HASH!R

( size akey nkey h -- adr )

-HASH

( akey nkey h -- )

HASH?

( akey ukey h -- true|false )

HASH@

( akey nkey h -- avalue nvalue / 0 0)

HASH@R

( akey nkey h -- a/0)

HASH@Z

( akey nkey h -- a/0)

HASH@N

( akey nkey h -- n TRUE / FALSE)

small-hash

( -- h )

large-hash

( -- h)

big-hash

( -- h)

traverse-hash

( xt h -- )

clear-hash

( h -- )

del-hash

( h -- )

all-hash

( xt h -- )

xt ( akey ukey a|value -- )

for-hash

( h xt -- )

xt ( a|value akey ukey -- )

hash-empty?

( h -- flag )

hash-count

( h -- n )

~af/lib/simple_hash.f

Описание

Andrey Filatkin, af@forth.org.ru
Work in spf3, spf4
Либа для работы с массивом строк. Для поиска строки в массиве
используется ее хэш. Каждой строке может быть сопоставлено число.
Создание массива - n_size ListCreate, где n_size - размер хэш-таблицы.
В либе используется свой менеджер памяти, в связи с чем длина одной строки
должна быть не больше чем n_size*4*4.

HashCode

( addr u list -- hash )

ListAllocate

( list size -- addr )

NodeCreate

( addr_key u_key list -- node )

ListCreate

( size -- list )

ListDestroy

( list --)

AddListItem

( addr u prev list -- node)

AddNode

( addr_key u_key list -- node )

FindNode

( addr_key u_key list -- node )

NextNode

( list -- node)

Hash Table iterator data/functions

FirstNode

( list -- node)

ListCount

( list -- n)

Error: "source/~yz/lib/hash.f.docbook" not found.

~day/common/hash.f

Описание

(c) D. Yakimov [ftech@tula.net]
Думаю - получилась неплохая функция хэша
И главное быстрая

ROL

( u -- u1 )

HASH

( addr u -- u1 )

Глава 13. Cryptographic hashes

Description

some description here

~clf/MD5.F

Описание

PLACE

( CADDR N ADDR -)

PLACE AND STRING FOR SYSTEM IF NEEDED
NOT NEEDED FOR SWIFTFORTH V 2.00.3, NEEDED FOR WIN32FORTH V 4.10

STRING

( CHAR "CCC" -)

ANEW

VERSIONS OF /STRING AND ANEW IF SYSTEM DOESN'T HAVE THEM
: /STRING ( A N K - A+K N-K) ( OVER MIN) TUCK - >R CHARS + R> ;

SPLIT-AT-CHAR

( A N CHAR - A K A+K N-K)

DOES>MACRO

MACRO

MACRO CREATION WORD WHICH ALLOWS PARAMETER INSERTION

]L

ENDIAN@

( A1 - N1 )

FOR ENDIAN TESTING
IF LITTLE ENDIAN CPU

ENDIAN!

( N A1 -- )

TRANSFORM

( ADR -- )

MD5INT

( -- )

SETLEN

( -- )

DOFULLBLOCKS

( ADR1 COUNT1 -- ADR2 COUNT2 )

DO ALL 64 BYTE BLOCKS LEAVING REMAINDER BLOCK

DOFINAL

( ADDR COUNT -- )

MD5FULL

( ADDR COUNT -- )

COMPUTE MD5 FROM A COUNTED BUFFER OF TEXT

INTDIGITS

( -- )

SAVEDIGIT

( N -- )

BYTEDIGITS

( N1 -- )

CELLDIGITS

( A1 -- )

LITTLE ENDIAN

MD5STRING

( -- ADR COUNT )

QUOTESTRING

( ADR COUNT -- )

===================== MD5 TEST SUITE ======================

.MD5

( ADR COUNT -- )

INPUTFILENAME

( -- IOR)

TRYAGAIN?

( -- ?)

BYTES@

( ADR N - )

READ N BYTES FROM INPUT FILE, STORE AT ADDR ARRAY

STORELEN

( LO HI - )

GETPARTIAL

( CNT -- BUF[] CNT2 ?)

MD5FILE

( -- )

ENTER FILENAME
NOT VALID, TRY (NOT) AGAIN
VALID FILE, INIT TRANSFORM
GET BYTESIZE OF INPUT FILE
DEC CNT BY 2 FOR CR|LF EOF
DISPLAY FILESIZE TO SCREEN
SAVE MESSAGE CNT ON RETURN
COMPUTE NBLOCKS & REMBYTES
DO N FULL BLOCKS
READ REMAINING BYTES
DO IF REMBYTES > 55
DO LAST BLOCK
SHOW MD5 HASH FOR FILE
CLOSE THE INPUT FILE

MD5

( addr u -- addr2 u2 )

~clf/md5-ts.f

Описание

изменения для thread-safe
~ac

PLACE

( CADDR N ADDR -)

PLACE AND STRING FOR SYSTEM IF NEEDED
NOT NEEDED FOR SWIFTFORTH V 2.00.3, NEEDED FOR WIN32FORTH V 4.10

STRING

( CHAR "CCC" -)

SPLIT-AT-CHAR

( A N CHAR - A K A+K N-K)

VERSIONS OF /STRING AND ANEW IF SYSTEM DOESN'T HAVE THEM
: /STRING ( A N K - A+K N-K) ( OVER MIN) TUCK - >R CHARS + R> ;
: ANEW >IN @ BL WORD FIND IF EXECUTE ELSE DROP THEN >IN ! MARKER ;

DOES>MACRO

MACRO

MACRO CREATION WORD WHICH ALLOWS PARAMETER INSERTION

]L

ENDIAN@

( A1 - N1 )

FOR ENDIAN TESTING
IF LITTLE ENDIAN CPU

ENDIAN!

( N A1 -- )

TRANSFORM

( ADR -- )

MD5INT

( -- )

SETLEN

( -- )

[ BUF[] 60 + ]L !
[ BUF[] 56 + ]L !

DOFULLBLOCKS

( ADR1 COUNT1 -- ADR2 COUNT2 )

DO ALL 64 BYTE BLOCKS LEAVING REMAINDER BLOCK

DOFINAL

( ADDR COUNT -- )

MD5FULL

( ADDR COUNT -- )

COMPUTE MD5 FROM A COUNTED BUFFER OF TEXT

INTDIGITS

( -- )

SAVEDIGIT

( N -- )

BYTEDIGITS

( N1 -- )

CELLDIGITS

( A1 -- )

LITTLE ENDIAN

MD5STRING

( -- ADR COUNT )

QUOTESTRING

( ADR COUNT -- )

===================== MD5 TEST SUITE ======================

.MD5

( ADR COUNT -- )

INPUTFILENAME

( -- IOR)

TRYAGAIN?

( -- ?)

BYTES@

( ADR N - )

READ N BYTES FROM INPUT FILE, STORE AT ADDR ARRAY

STORELEN

( LO HI - )

GETPARTIAL

( CNT -- BUF[] CNT2 ?)

MD5FILE

( -- )

ENTER FILENAME
NOT VALID, TRY (NOT) AGAIN
VALID FILE, INIT TRANSFORM
GET BYTESIZE OF INPUT FILE
DEC CNT BY 2 FOR CR|LF EOF
DISPLAY FILESIZE TO SCREEN
SAVE MESSAGE CNT ON RETURN
COMPUTE NBLOCKS & REMBYTES
DO N FULL BLOCKS
READ REMAINING BYTES
DO IF REMBYTES > 55
DO LAST BLOCK
SHOW MD5 HASH FOR FILE
CLOSE THE INPUT FILE

MD5

( addr u -- addr2 u2 )

lib/alg/md5-jz.f

Описание

MD5

( a u -- a1 u2 )

MD5FILE

( a u -- a1 u2 )

QUOTESTRING

( ADR COUNT -- )

.MD5

( ADR COUNT -- )

md5-jz.f

( -- )

MD5TEST

( -- )

UTIMER

[TEST]

TEST

Глава 14. Compile-time constants

Description

some description here

~yz/lib/const.f

Описание

ћ. †Ё«®ўҐж, http://www.forth.org.ru/~yz
‡ Јаг¦ Ґ¬лҐ в Ў«Ёжл Є®­бв ­в 1.04

LOAD-CONSTANT €бЇа ў«Ґ­® ЊЁе Ё«®¬ Њ ЄбЁ¬®ўл¬

FIND-CONSTANT

( name-a name-n -- n T / F)

FIND-CONSTANT2

( name-a name-n -- n)

W:

( ->bl)

(*

LOAD-CONSTANTS

( file-a file-n -- )

REMOVE-ALL-CONSTANTS

lib/ext/const.f

Описание

$Id: const.f,v 1.4 2008/06/27 14:44:07 ygreks Exp $
Константы времени компиляции

Ветка от ~day/wincons/wc.f v1.5

REQUIRE +LibraryDirName src/win/spf_win_module.f

SEARCH-CONST

( addr u -- u -1 | 0 )

NOTFOUND

( addr u -- )

ADD-CONST-VOC

( addr u -- )

REMOVE-ALL-CONSTANTS

~day/wincons/compile.f

Описание

Windows loadable constants support for spf375
(c) Dmitry Yakimov 30.05.2000

Windows loadable constants compiler for spf375
(c) Dmitry Yakimov 30.05.2000



Компилятор констант.

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

Строим бинарное дерево в непрерывном прстранстве данных.
Все смещения относительно начала словаря.

Можно искать по бинарному дереву [как и было в первой версии], но
дерево получается неравновесное и поиск иногда может быть долгим
[при поиске порядка 100000 значений].

Поэтому итоговый файл в формате ~yz.
Мои словари прекрасно подходят к ~yz\wincons.f
Хотя для порядка сделал свой форт модуль для подключения.

BEGIN-CONST

ADD-NODE

( u1 addr u2 -- addr2 )

ADD-LEFT

( u1 addr u2 dad -- )

ADD-RIGHT

( u1 addr u2 dad -- )

INSERT-NODE

( u1 addr u2 dad -- )

_SEARCH-NODE

( addr u node -- u -1 | 0 )

SEARCH-NODE

( addr u -- u -1 | 0 )

ADD-TO-STUB

( node -- )

MAKE-STUB

( node -- )

FORM-STUB

SAVE-CONST

( c-addr u -- )

_CONSTANT

( u1 addr u2 -- )

CONSTANT

#define

NOTFOUND

( addr u -- )

Глава 15. User interface

Description

some description here

~yz/lib/winlib.f

Описание

WINLIB 1.14

Библиотека пользовательского интерфейса Windows
ч. 1. Базовые объекты, окна, меню, быстрые клавиши
Ю. Жиловец, 8.12.2001

OR!

( n a -- )

ORC!

( c a -- )

getter?

( a -- ?)

setter?

( a -- ?)

shared?

( a -- ?)

datatype

( a -- )

getproc

( index tab -- )

setproc

( value index tab -- )

indtab>a

( index tab -- addr)

store

( value index tab --)

storeset

( setproc index tab)

setitem

( value1 value2 index tab -- )

setflagitem

( val1 val2 flag index tab -- )

make-getter

( ; index -- )

make-setter

( ; index -- )

make-constant

( ; index -- )

table

( ->bl; parenttable/0 -- a)

generate-names

endtable

( a -- )

save-name

( ->bl; n --)

item

( ->bl ; a n -- a)

shared

set

getset

type

( n -- )

new-table

( table -- a)

del-table

( table -- )

send-to-window

( wparam lparam msg hwnd -- result)

send

( wparam lparam msg win -- result)

?send

( ctl message -- n/ )

wsend

( wparam ctl message -- n/ )

lsend

( lparam ctl message -- n/ )

set-text

( z ctl -- )

-text#

( ctl -- )

>bgr

( rgb -- bgr )

rgb

( r g b -- rgb)

syscolor

( index -- rgb)

invalidate

( ctl \ [ 4 CELLS ] rect -- )

?invalidate

( ctl -- )

window!

( n hwnd -- )

window@

( hwnd -- n)

:no

----------------------------------------
Формат универсальной таблицы:
+0 cell число записей
+4 cell текущий указатель
+8 ... данные

:ptr

:data

create-utable

( bytes -- ut)

destroy-utable

( ut -- )

u>>

( n ut -- )

uw>>

( w ut -- )

uc>>

( c ut -- )

uan>>

( a n ut -- )

ut++

( ut -- )

utable-size

( ut -- bytes )

land-utable

( ut -- adr )

land-utable-without-header

( ut -- adr )

:link

init-xtptr

>xtptr

( n -- )

save-xtname

( a # -- )

init-yptr

>yptr

( n -- )

c>yptr

( c -- )

>>yptr

( a # -- )

MESSAGES:

( ->bl; -- )

create-saved-xtname

land-xttable

( -- )

land-ytable

( -- )

MESSAGES;

( -- )

:M

( msg# -- xt secret-sign)

M:

( ->message-name; -- msg# xt secret-sign)

M;

( msg# xt secret-sign -- )

XLIST

( ->bl; -- )

create-xlist

( -- xlist)

empty-xlist

( xlist -- )

insert-to-begin

( xtable xlist -- )

insert-to-end

( xtable xlist -- )

find-in-xtable

( id xttable -- result true / false)

?find-in-xtable

( id xttable -- ?)

если вызванное слово вернуло false, делаем вид, что ничего не нашли

RETURN

( n -- )

find-and-execute

( id xlist -- ? )

?find-and-execute

( id xlist -- ? )

nc-win-size

( dx dy win \ [ 4 CELLS ] rect -- ex ey )

высчитывает полный размер окна по размеру клиентской области
+ высота статуса + высота панели инструмента

wm-paint-proc

end-dialog

( code -- )

dialog-ok

( -- )

dialog-cancel

( -- )

set-colors

не наше окно

extend-window-proc

( xtable -- )

create-window-with-styles

( parent style exstyle -- )

create-window

( parent -- win/0)

dialog-window

( parent -- win/0)

tool-window

( parent -- win/0)

destroy-window

( win -- )

(show)

( win flag -- )

winshow

( win -- )

winhide

( win -- )

winminimize

( win -- )

winmaximize

( win -- )

winrestore

( win -- )

winenable

( win -- )

windisable

( win -- )

winfocus

( ctl -- )

win-rect

( win \ [ 4 CELLS ] rect -- x1 y1 x2 y2 )

child-win-rect

( win \ [ 4 CELLS ] rect -- x1 y1 x2 y2 )

То же самое, но в координатах родительского окна

win-size

( win -- )

Настоящий размер окна

winmove

( x y win -- )

new-size

( xsize ysize win -- )

resize

( xsize ysize win -- )

Изменить размер простого окна (типа органа управления)

winresize

( xsize ysize win -- )

Изменить размер сложного окна

force-redraw

( win -- )

заставить окно перерисоваться в ближайшее время

message-box

( title text style -- result)

msg

( text -- )

err

( text -- )

screen-x

( -- x)

screen-y

( -- x)

wincenter

( win -- )

--------------------------------------

next-menu-id

( -- n)

MENU:

( ->bl; -- )

LINE

( -- )

SUBMENU

( ->eol; menu -- )

MENUITEM

( ->eol; proc -- )

CHECKED

DISABLED

MENU;

( -- )

append-to-menu

( menu hmenu \ ptr flags -- )

wake-menu

( menu -- )

wake-menubar

( menu -- )

destroy-menu

( menu -- )

append-xtable-to-menuslist

( menu mlist \ ptr -- )

make-menus-list

( menu -- menu-list )

attach-menubar

( menu window -- )

detach-menubar

( window -- )

show-menu

( menu x y \ menulist -- )

работает только при установленном winmain

check-menu-item

( no menu -- )

uncheck-menu-item

( no menu -- )

(un)check-me

( -- ?)

check-menu-radio

( first last no menu -- )

select-me

( first last -- )

enable-menu-item

( no menu -- )

disable-menu-item

( no menu -- )

default-menu-item

( no menu -- )

redraw-window-menu

( win -- )

KEYTABLE

( -- )

?modifier

( adr n -- adr1 n1 flags )

parse-key

( adr n -- key flags )

ONKEY

( ->bl; proc -- )

таблицы клавиш заводят для процедуры еще один id, даже если у нее уже есть
свой код, выделенный MENUITEM. Это не страшно, поскольку 16000 id должно
хватить всем

KEYTABLE;

( -- )

bold

italic

underline

strike-out

pt>devunits

( n -- n1)

create-font-devunits

( zname devunits -- )

create-font

( zname size -- font )

delete-font

( font -- )

hdu

( n -- n1)

пересчет базовых диалоговых единиц в пиксели

vdu

( n -- n1)

dunits

( n n1 -- n2 n3)

initcc

( what \ [ 2 CELLS ] buf -- )

WINDOWS...

инициализация

?dialog

( msg -- ?)

...WINDOWS

~profit/lib/winlibex.f

Описание

Небольшие тонкости и дополнения к WinLib

tool-unclosable-window

( parent -- win/0)

win-pos

( tab \ [ 4 CELLS ] rect -- x y )

through-control

сквозной статичный элемент, не перехватывающий фокуса

set-page-size

( page-size ctl \ [ 7 CELLS ] scrollinfo -- )

установить размер страницы для скроллбара

tv-del-all-items

( ctl --)

очистить дерево

create-font-uni

( zname size -- )

имя шрифта в уникоде

~day/joop/win/framewindow.f

Описание


23.Jun.2001 Sat 00:21 Ruv Исправил зевок в W: WM_PAINT
было handle @ EndPaint DROP
надо ps[ handle @ EndPaint DROP
в NONAME для WNDPROC: (WIN-GATE) исправлено
было dep DEPTH - 0= IF 0 THEN
надо DEPTH dep - 0= IF 0 THEN

DisableTaskWindows

( param -- )

EnableTaskWindows

( stack -- )

~day/wfl/wfl.f

Описание

[[

~day/common/console.f

Описание

Console operations

?WinError

AT-XY

( X Y -- )

TEXT-ATTR

( fg bg -- )

MAX-XY

( -- x y )

CLS

HIDE-CURSOR

Взято у ~micro
Спрятать курсор

~pi/lib/console.f

Описание

-----------------------------------------------------------------------------
__ ___ ____ ___
\ \ / (_) |___ \__ \ Console for Windows
\ \ /\ / / _ _ __ __) | ) | pi@alarmomsk.ru
\ \/ \/ / | | '_ \ |__ < / / ЃЁЎ«Ё®вҐЄ  ¤«п а Ў®вл б Є®­б®«мо
\ /\ / | | | | |___) / /_ Pretorian 2007
\/ \/ |_|_| |_|____/____|
-----------------------------------------------------------------------------

DUPS

( n -> )

XY->N

( x y -> n )

“Ї Є®ў вм Є®®а¤Ё­ вл ў зЁб«®

N->XY

( n -> x y )

ђ бЇ Є®ў вм Є®®а¤Ё­ вл Ё§ зЁб« 

Color->N

( 梥в д®­ -> n )

“Ї Є®ў вм 梥⠨ д®­ ў зЁб«®

N->Color

( n -> 梥в д®­ )

ђ бЇ Є®ў вм 梥⠨ д®­ Ё§ зЁб« 

SetTitle

( addr n -> )

€§¬Ґ­Ёвм вЁвг« Є®­б®«Ё

SetLocate

( x y -> )

“бв ­®ўЁвм Єгаб®а ў Є®­б®«Ё ў § ¤ ­­лҐ Є®®а¤Ё­ вл

HideCursore

( -> )

‘Їапв вм Єгаб®а ­  Є®­б®«Ё

ShowCursore

( -> )

Џ®Є § вм Єгаб®а ­  Є®­б®«Ё

SizeCursore

( n -> )

ђ §¬Ґа Єгаб®а  (0-100)

SizeConsole

( lenght height -> )

ђ §¬Ґа Є®­б®«Ё (®в 80) (®в 25)

GetLength

( -> n )

„«Ё­­  Є®­б®«Ё

GetHeight

( -> n )

‚лб®в  Є®­б®«Ё

GetX

( -> n )

Љ®®а¤Ё­ в  Єгаб®а  X

GetY

( -> n )

Љ®®а¤Ё­ в  Єгаб®а  Y

GetLocate

( -> x y )

Џ®«гзЁвм Є®®а¤Ё­ вл Єгаб®а 

GetColor

( -> n )

’ҐЄгйЁ© 梥⠪®­б®«Ё

GetBackground

( -> n )

’ҐЄгйЁ© д®­ Є®­б®«Ё

SetColor

( n -> )

€§¬Ґ­Ёвм 梥⠢л室пйЁе бЁ¬ў®«®ў ­  Є®­б®«м

SetBackground

( n -> )

€§¬Ґ­Ёвм д®­ ўл室пйЁе бЁ¬ў®«®ў ­  Є®­б®«м

SetX

( n -> )

€§¬Ґ­Ёвм Є®®а¤Ё­ вг X Єгаб®а  ў Є®­б®«Ё

SetY

( n -> )

€§¬Ґ­Ёвм Є®®а¤Ё­ вг Y Єгаб®а  ў Є®­б®«Ё

Cls

( -> )

ЋзЁбвЁвм Є®­б®«м

FullConsole

( -> )

ђ §ўҐа­гвм Є®­б®«м ­  ўҐбм нЄа ­

WindowsConsole

( -> )

‚Ґа­гвЁ Ї®«­®нЄа ­­го Є®­б®«м ў ®Є­®

AttrWindow

( -> )

“бв ­®ўЁвм  ваЁЎгвл ў ®Є­Ґ Є®­б®«Ё

ClearWindow

( -> )

ЋзЁбвЁвм ®Є­® ў Є®­б®«Ё ЎҐ§ Ё§¬Ґ­Ґ­Ёп  ваЁЎгв®ў

ClsWindow

( -> )

ЋзЁбвЁвм ®Є­® ­  Є®­б®«Ё

SwapColor

( -> )

Џ®¬Ґ­пвм жўҐв  д®­ Ё жўҐв  Є®­б®«Ё ¬Ґбв ¬Ё

Print‘

( n addr x y -> )

‚лў®¤ бва®ЄЁ ЎҐ§ ᬥ饭Ёп Єгаб®а  Ё ЎҐ§ Ё§¬Ґ­Ґ­Ёп 梥в 

Emit‘

( x y char -> )

‚лў®¤ бЁ¬ў®«  ЎҐ§ ᬥ饭Ёп Єгаб®а  Ё ЎҐ§ Ё§¬Ґ­Ґ­Ёп 梥в 

LineH

( n -> )

Ћ¤Ё­ а­ п Ј®аЁ§®­в «м­ п «Ё­Ёп

DLineH

( n -> )

„ў®©­ п Ј®аЁ§®­в «м­ п «Ё­Ёп

LineV

( n -> )

Ћ¤Ё­ а­ п ўҐавЁЄ «м­ п «Ё­Ёп

DLineV

( n -> )

„ў®©­ п ўҐавЁЄ «м­ п «Ё­Ёп

Box

( -> )

‚뢥бвЁ ®¤Ё­ а­го а ¬Єг Ї® ўЁавг «м­®¬г ®Є­г

DBox

( -> )

‚뢥бвЁ ¤ў®©­го а ¬Єг Ї® ўЁавг «м­®¬г ®Є­г

Console

( -> )

‘в ­¤ ав­лҐ гбв ­®ўЄЁ  ваЁЎгв®ў Є®­б®«Ё

Глава 16. Windows COM

Description

some description here

~ac/lib/win/com/COM.F

Описание

работа с COM/DCOM, OLE, ActiveX
А.Черезов 4.02.2000

>UNICODE

( addr u -- addr2 u2 )

UNICODE>

( addr u -- addr2 u2 )

на входе - длина в байтах, а WideCharToMultiByte хочет к-во символов

UTF8>UNICODE

( addr u -- addr2 u2 )

UNICODE>UTF8

( addr u -- addr2 u2 )

на входе - длина в байтах, а WideCharToMultiByte хочет к-во символов

>UTF8

( addr u -- addr2 u2 )

UTF8>

( addr u -- addr2 u2 )

UASCIIZ>

( addr -- addr u )

>BSTR

( addr u -- bstr )

BSTR>

( bstr -- addr2 u2 )

пустые строки передаются в вариантах VT_0x400B

ComInit

( -- ior )

ComExit

( -- )

void

ComCreateGUID

( GUIaddr -- ior )

CLSID>String

( GUIaddr -- addr u ior )

String>CLSID

( addr u -- addr2 ior )

ProgID>CLSID

( addr u -- addr2 ior )

CLSID,

( addr u -- )

ComGetForthGUID

( addr -- )

используется во всех тестах

InvokeMethod

( parameters interface_pointer method_number -- result )

interface_pointer, он же oid, будет передаваться первым параметром неявно
как в C++

Methods#

( interface_id -- n )

Methods#!

( n interface_id -- )

Interface:

( parent_interface "name" "clsid" -- interface_id n )

Interface;

Method:

( interface_id n "name" -- interface_id n+1 )

CreateObject

( addr u -- oid ior )

addr u - имя программы, создающей требуемые объекты
например S" WordPad.Document.1" CreateObject THROW -> WPDOC

CreateClass

( addr u -- oid ior )

GetIDispatch

( oid -- idispatch ior )

GetIdOfName

( idisp addr u -- n ior )

~ac/lib/win/com/com_server.f

Описание

Class.

( oid -- oid )

Class:

( implement_interface "name" "clsid" -- current class_int )

Class;

Class

( oid -- class_int )

SpfClassName

( oid -- addr u )

здесь oid - com'овский указатель на указатель vtable
т.е. тот, что первым параметром в вызовах

SpfClassWid

( oid -- wid )

methods#
пропустили vtable
пропустили -1 в структуре Class: выше
пропустили voc-list

ComClassIID

( oid -- addr u )

NewComObj

( extra_size class_oid -- oid )

Создать объект заданного класса с дополнительной памятью размера size.
Минимально рабочий COM-объект (extra_size=0) требует память только
для указателя на vmt (который тот же что и у нашего объекта "класс").
Наример: /BROWSER SPF.IWebBrowserEvents2 NewComObj

IsMyComObject?

( oid -- flag )

(AddRef)

( oid -- cnt )

(Release)

( oid -- cnt )

Extends

( class_int -- class_int )

ToVtable

( class_int xt -- class_int )

METHOD

( class_int -- class_int )

Глава 17. System services

Description

some description here

~ac/lib/win/service/SERVICE.F

Описание

30.12.2001 ac Исправлены ошибки с числом параметров в (ServiceControlHandler)
и в (ServiceMain)
20.09.2002 ruvim: исправления в стековой нотации и исправление CreateSevice

DeleteService

( addr u -- 0 | 1 )

CreateService

( addr u -- 0 | handle )

(ServiceControlHandler)

( fdwControl -- )

управляющая процедура сервиса
поступают аргументы =1 или =4

(ServiceMain)

( dwArgc *lpszArgv -- void )

StartService

( addr u -- flag )

~ac/lib/win/service/service95.f

Описание

InstallService95

( S" service_name" -- ior )

UninstallService95

( S" service_name" -- ior )

Глава 18. Date and time

Description

some description here

~ac/lib/win/date/date-int.f

Описание

W-DATE

M-DATE

>Date>W

( d m y -- w )

DateW>S

( w -- addr u )

DateM>S

( m -- addr u )

#:

( -- )

#N

( n -- )

#N##

( n -- )

#SG

( n -- )

<<#

( -- 0 0 )

<#N

( n -- xd )

Date#

( d m y -- )

Time#

( h m s -- )

DateTime#

( s m h d m1 y -- )

DateTime#GMT

( s m h d m1 y -- )

Zone#

( -- )

DateTime#Z

( s m h d m1 y -- )

CurrentDateTime#

CurrentDateTime#Z

~ac/lib/win/date/unixdate.f

Описание

SecsSince1970

( -- n )

UnixDate

( -- n )

UnixDate#

UnixDate.#

UNIXDATE

~ac/lib/win/file/filetime.f

Описание

UTC>LOCAL

( filetime1 -- filetime2 )

GET-FILETIME-WRITE

( h -- filetime )

GET-FILETIME

( h -- filetime )

FILETIME>TIME&DATE

( tlo thi -- sec min hr day mt year )

GET-FILE-LASTWRITETIME

( h -- sec min hr day mt year )

NOW-FILETIME

( -- filetime )

NOW-UTC-FILETIME

( -- filetime )

DAYS-OLD

( h -- days )

DELETE-IF-OLDER

( filename days -- flag )

FileDateTime#

( h -- )

FileDateTime#GMT

( h -- )

CurrentDateTime#UTC

~ygrek/lib/spec/sdate.f

Описание

$Id: sdate.f,v 1.6 2007/12/05 21:15:22 ygreks Exp $

Разбор даты в виде S" Tue, 19 Dec 2006 19:55:16 +0300"

target: RFC-822

?DayOfWeek

( a u -- ? )

MonthName

( a u -- n ? )

?MonthName

( a u -- ? )

parse-unixdate

( a u -- timestamp|0 )

parse-date?

( a u -- ss mm hh d m y -1 | 0 )

~ygrek/lib/spec/sdate2.f

Описание

$Id: sdate2.f,v 1.1 2007/02/04 20:29:05 ygreks Exp $

Разбор даты в виде S" 2007-01-27T17:40:36+03:00"

Не знаю что за формат такой - его использует ForthWiki
Парсить правда проще :)

parse-num-unixdate

( a u -- timestamp|0 )

~ygrek/lib/spec/unixdate.f

Описание

$Id: unixdate.f,v 1.8 2007/10/26 10:47:54 ygreks Exp $
unix timestamp в дату
и наоборот

URL в тему - http://vsg.cape.com/~pbaum/date/date0.htm

unix_epoch_j

( -- j_double )

Julian day начала эпохи unix

Num>DateTime

( n -- s m h d m1 y )

преобразовать timestamp в дату
секунды
минуты
часы

DateTime>Num

( s m h d m1 y -- n )

преобразовать дату в timestamp

Num>Time

( n -- s m h )

извлечь только время из timestamp

DateTime>Days

( s m h d m1 y -- days )

дату в число дней

DateTime>PAD

( s m h d m1 y -- a u )

Представить дату как строку в буфере PAD

Глава 19. Databases

Description

some description here

~yz/lib/ODBC.F

Описание

Доступ к базам данных через ODBC
Ю. Жиловец, 16.10.2003

Некоторые фрагменты (инициализация, подключение к базе, обработка ошибок)
позаимствованы у А. Черезова: ~ac/lib/win/odbc/odbc.f

ColNumAttribute

( col attr fodbc \ num -- n )

ColStrAttribute

( addr col attr fodbc \ len -- )

Предполагаем, что длинней 50 символов свойств не будет

ColSize

( col fodbc -- n)

ColDisplaySize

( col fodbc -- n)

ColType

( col fodbc -- n)

ColCount

( fodbc -- n)

ColName

( a col fodbc -- )

SQL_OK?

SQL_INTEGER

( ->bl; -- )

SQL_SMALLINT

( ->bl; -- )

SQL_TINYINT

( ->bl; -- )

SQL_FLOAT

( ->bl; -- )

SQL_DOUBLE

( ->bl; -- )

SQL_CHAR

( ->bl; --)

SQL_BINARY

( ->bl; -- )

SQL_BIT

( ->bl; -- )

SQL_DATE

( ->bl; -- )

SQL_TIME

( ->bl; -- )

SQL_TIMESTAMP

( ->bl; -- )

BIND

( -- )

BIND;

( -- )

ISNULL

( field-len -- )

StartSQL

( -- fodbc flag )

StopSQL

( fodbc -- )

ConnectSQL

( S" data source" S" name" S" pass" fodbc -- ior )

ResultCols

( fodbc -- n )

AffectedRows

( fodbc -- n )

ExecuteSQL

( z-stat fodbc -- ior )

NextRowWithInfo

( fodbc -- ? )

NextRow

( fodbc -- ? )

~ac/lib/win/odbc/ODBC.F

Описание

17.08.1999 Черезов А.

Работа с базами данных ODBC, замена библиотеки s.txt двухлетней давности.
+ обновление 19.08.1999
+ замена temps на locals 7.12.2000

SqlIsBinary

( type -- flag )

65532 CONSTANT SQL_LONGVARBINARY \ -4
65535 CONSTANT SQL_LONGVARCHAR \ -1
65530 CONSTANT SQL_TINYINT \ -6
: SqlIsBinary ( type -- flag ) DUP 65531 65535 WITHIN SWAP 5 = OR ;

SQL_OK?

SQL_Error_old

( ior fodbc -- )

SQLDumpError

( addr u -- )

SQL_Error

( ior fodbc \ pcbErrorMsg ErrNat mem -- )

SQL_ConnError

( ior fodbc \ pcbErrorMsg ErrNat mem -- )

StartSQL

( -- fodbc flag )

ConnectSQL

( S" data source" S" name" S" pass" fodbc -- ior )

FreeStmt

( fodbc -- )

ReconnectSQL

( fodbc -- ior )

ResultCols

( fodbc -- n )

AffectedRows

( fodbc -- n )

IndexResultCol

( n fodbc -- errcode )

IndexResultCols

( fodbc -- )

RowSize

( fodbc -- n )

BindCols

( fodbc -- )

UnbindCols

( fodbc -- )

cash-odbc-params

( fodbc -- )

SQLLastQuery

( addr u -- )

ExecSQL

( S" statement" fodbc -- ior )

FreeExec

( fodbc -- )

fodbc odbcStat @ SQLCloseCursor DROP
0 ( SQL_COMMIT) fodbc odbcEnv @ 1 ( SQL_HANDLE_ENV) SQLEndTran DROP

StopSQL

( fodbc -- )

ExecSQLfile

( S" filename" fodbc -- ior )

ColFind

( n fodbc -- ci )

ColName

( n fodbc \ ci -- addr u )

ColSize

( n fodbc -- n )

ColType

( n fodbc -- n )

Row

( fodbc -- addr u )

NextRow

( fodbc -- flag )

Col

( n fodbc -- addr u )

~pinka/lib/win/odbc/ODBC-txt.f

Описание

25.Feb.2004 ruv
$Id: ODBC-txt.f,v 1.1 2004/03/23 09:50:10 ruv Exp $
слово ExecSQLTxt
- эмулирует DELETE через SELECT INTO и DROP TABLE
Необходимо, если используется Text File Driver
---
В этом запросе DELETE слово FROM обязательно.

SqlTxtDelete

( S" statement" fodbc -- sql_ior )

ExecSQLTxt

( S" statement" fodbc -- sql_ior )

Error: "source/~ac/lib/lin/sql/sqlite3.f.docbook" not found.

~day/lib/mysql.f

Описание

MySQL wrapper
(c) Dmitry Yakimov 2001; ftech@tula.net
This wrapper does not contain all of possible
functions of the dll, but it is quite enough for me.
I know many ways of improvement of speed and comfort of the lib,
but it's still quite enough for me :)
Enjoy!

MyErrStr

( -- addr u )

MyConnect

( host hu user uu passw pu -- h ior )

h - connection handle
ior - error code

MyClose

( h -- )

MyStat

( h -- addr u )

MySelectDB

( addr u h -- f )

MyQuery

( addr u h -- f )

MyStoreRes

( h -- res )

MyFreeRes

( res -- )

MyNumRows

( res -- u )

MyNumFields

( res -- u )

MyFetchField

( u res -- field )

MyFetchRow

( res -- row )

FieldName

( field -- addr u )

FieldSize

( field -- u )

ColData

( u row res -- addr u )

get data from column of field 'u' in row 'row'

Глава 20. Processes, threads, etc

Description

some description here

~ac/lib/win/process/process.f

Описание

~ac: изменения 25.03.2004
Добавлено функциональное слово StartAppWaitDir
S" app_path.exe cmdline" S" curr_dir" wait StartAppWaitDir THROW ." res=" .
Т.е. в отличие от StartApp возвращает не сишный bool, а ior
плюс код завершения. Код завершения валидный только в случае
ненулевого заданного времени ожидания wait.
StartApp и StartAppWait теперь определены через это слово.

~ac: изменения 30.03.2004
* Если запуск неудачен, то попыток получения кода возврата не производится,
т.к. это портит код в GetLastError и StartAppWaitDir возвращает 6.

P.S. Если процесс еще не завершился, то возвращаемый код 259.
Если ему указан неверный текущий каталог, то 267.

StartAppWaitDir

( S" application.exe" S" curr_directory" wait -- exit_code ior )

StartApp

( S" application.exe" -- flag )

StartAppWait

( S" application.exe" -- flag )

Visible

~ac/lib/win/access/nt_access.f

Описание

GetProcessACL

( handle -- dacl ior )

CreateEveryoneACE

( -- )

CreateEveryoneACL

( -- acl ior )

SetObjectACL

( acl h -- ior )

~ac/lib/win/isapi/isapi.f

Описание

IsapiTYPE

IsapiSetStatus

IsapiSetHeader

SCRIPT_FILENAME

SCRIPT_NAME

веб-сервер должен переопределить SCRIPT_NAME!

SERVER_PROTOCOL

SERVER_SOFTWARE

IsapiMapPath

( addr u -- addr2 u2 )

PHP может передавать отрицательную длину! :-)
." Map logical path:<" 2DUP TYPE ." >" CR

IsapiExtension:

IsapiInitExtension

( addr -- )

IsapiCallExtension

( ecb addr -- res )

IsapiAdump

IsapiRunExtension

( scriptaddr scriptu addr -- code )

~ac/lib/win/thread/pool.f

Описание

CREATE-CP

( max-threads -- h ior )

GET-CP

( time h -- flag ior )

Возвращает ior=0, если нет ошибок. При этом flag=true, если был
таймаут ожидания (не было событий за time ms)
При любых ошибках ior<>0, а flag не определен.

POST-CP

( over key bytes h -- ior )

В тестах ior всегда =0, даже попытки переполнения очереди
(не вычитывание через WAIT-CP) не увенчались "успехом" :)
см. TEST1
Потоку можно передать 3 параметра, названия over key bytes
ни к чему не обязывают, если речь не о файлах.

lib/win/mutex.f

Описание

CREATE-MUTEX

( addr u flag -- handle ior )

создает объект взаимного исключения
addr u - имя
flag=TRUE, если создаваемый объект нужно сразу занять

CLOSE-MUTEX

( handle -- ior )

RELEASE-MUTEX

( handle -- ior )

освобождает объект

WAIT

( time handle -- flag ior )

возвращает истину, если объект освобожден другим потоком
(либо он освободился сам собой при завершении др.потока)
и после этого занят текущим

~pinka/lib/multi/critical.f

Описание

18.Jan.2004 ~ruv
$Id: critical.f,v 1.5 2007/04/16 07:39:22 ruv Exp $

ENTER-CS можно сделать в потоке несколько раз,
потом столько же LEAVE-CS.
Пока входов больше - другой поток не войдет,
если выходов больше - можно будет войти
только после выполнения ActivateCSs
/WinXP/

MAKE-CS,

( -- )

CREATED-CS

( name-a name-u -- )

CREATE-CS

( "name" -- )

Создать критическую секцию с именем name

ActivateCSs

( -- )

DeactivateCSs

( -- )

ENTER-CS

( cs -- )

Войти (завладеть) в критическую секцию cs
Пока какой-либо поток владеет критической секцией,
остальные будут ждать внутри ENTER-CS

LEAVE-CS

( cs -- )

Покинуть (освободить) критическую секцию cs

NEW-CS

( -- cs )

DEL-CS

( cs -- )

~pinka/lib/multi/Synchr.f

Описание

22.10.99г. Ruv - WaitAny, WaitAll, Wait
01.04.2001 выделил в отдельную либу в связи с наличием semaphore.f.
* Wait и Release* не возвращают ior. При ошибке вызывают THROW внутри.
(просмотр исходников показал, что эти ошибки не обрабатывается
иначе, чем DROP или THROW почти всегда).

WaitAny

( h1 h2 ... hn n time -- false|number_from_top )

flag-WaitAll=0 - any object

WaitAll

( h1 h2 ... hn n time -- flag )

flag-WaitAll = -1 -all objects

Wait

( handle time -- flag )

возвращает истину, если объект освобожден другим потоком
(либо он освободился сам собой при завершении др.потока)
и после этого занят текущим

Глава 21. Windows registry and ini-files

Description

some description here

~ac/lib/win/registry2.f

Описание

02.08.1999 Черезов А.
28.03.2001 дополнения
10.07.2001 перенос registry.f под locals.f

Работа с Windows Registry, замена библиотеки reg.txt двухлетней давности.
Основные слова:
StrValue, NumValue и BinValue - получают строчные, числовые и двоичные
значения заданных ключей registry.
Те же слова с "!" на конце - записывают. Если указанного ключа нет,
он будет автоматически создан.
Эти слова работают с принятым по умолчанию хэндлом "корневого" ключа,
хранимом в переменной EK. Удобно записывать туда хэндл своего "поддерева"
в Registry и работать с более короткими строками имен ключей [см. примеры]
Слова для перечисления списков ключей и значений:
RG_ForEachKey и RG_ForEachValue
запускают слово с заданным xt для каждого ключа или значения.

RG_OpenKey

( addr u key -- h ior )

RG_CreateKey

( addr u key -- h ior )

RG_ForEachKey

( xt h -- )

RG_ForEachValue

( xt h -- )

RG_QueryValue

( valuename-a valuename-u h -- addr u type )

RG_SetValue

( addr u type valuename-a valuename-u h -- )

Value

( valuename-a valuename-u keyname-a keyname-u -- addr u type )

Value!

( addr u type valuename-a valuename-u keyname-a keyname-u -- )

StrValue

( valuename-a valuename-u keyname-a keyname-u -- addr u )

NumValue

( valuename-a valuename-u keyname-a keyname-u -- x )

BinValue

( valuename-a valuename-u keyname-a keyname-u -- addr u )

StrValue!

( addr u valuename-a valuename-u keyname-a keyname-u -- )

NumValue!

( x valuename-a valuename-u keyname-a keyname-u -- )

FormatV

( addr u type -- addr u )

FormatValue

( valuename-a valuename-u keyname-a keyname-u -- addr u )

~ac/lib/win/ini.f

Описание

Работа с ini-файлами.
Плюс упрощенный синтаксис Section[key], File.Section[key]
Плюс исправление ошибок, когда в строчном литерале S" или "
забывают пробел после кавычки. Примеры см. в конце текста.
Ограничение: максимальная длина строки задается в IniMaxString, default=4000
Задействованная память НЕ освобождается до завершения потока.

(IniFile@)

( S" key" S" section" S" file" -- S" value" )

получить значение ключа из ini-файла (без раскрытия {})

IniFile@

( S" key" S" section" S" file" -- S" value" )

получить значение ключа из ini-файла
получить строку без раскрытия
раскрыть макросы в строке
освободить буфер

IniFile!

( S" value" S" key" S" section" S" file" -- )

записать значение ключа в ini-файл

(IniEnum)

IniEnum

( a u xt -- ... )

выполнить xt для каждой строки в списке a u
a u - список asciiz-строк, возвращенных IniFile@ в случае,
если запрашивался список, т.е. одно из входных значений было нулевое

IniFileExists_old

( addr u -- flag )

IniFileExists

( addr u -- flag )

IniDefault2

IniDefault1

STRNIL

SFS!

( s addr -- )

(File.Section[Key]>)

File.Section[Key]>

FileOrig.Section[Key]>

(IniS@)

(IniS!)

( va vu -- )

IniS@

( a u -- S" value" )

IniS!

( va vu a u -- S" value" )

""@

( a u -- str )

"S"@

( a u -- str )

NOTFOUND

( a u -- ... )

Глава 22. Strings

Description

some description here

~ac/lib/str5.f

Описание

12.10.1999 Черезов А.
модификация 25.12.2000-07.02.2007

Простое расширение СП-Форта операциями над динамическими
строками произвольной длины. Эти процедуры сделаны в стиле
Perl или PHP, но синтаксис и другие детали сделаны более
соответствующими Форт-стилю, нежели Perl'у.

Создание строк:

" текст строки"

Или:

" многострочный
текст
строки"

В строку можно включать вычисляемые выражения, которые
должны вернуть строку [два числа - addr u] или число. Поскольку
Форт оставлен бестиповым языком, то единственный способ, по
которому реализованные здесь библиотеки могут узнать, чтО
возвращено - это измерение изменения глубины стека. Если
добавилось два числа, считаем это адресом и длиной строки,
если одно, то считаем это числом. Возвращенная строка вставляется
в то место исходной строки, откуда вызывалось вычисление. Если
вернули число, то оно преобразуется в строку в десятичной системе
счисления. Пример:

: text S" текст" ;
" многострочный
{text}
строки"

Создаст ту же строку, что и предыдущий пример.

Слово " [кавычка] возвращает строку не в виде addr u, а в виде
одного числа s, которое можно преобразовать в addr u с помощью
слова

STR@ [ s -- addr u ]

Если слово " используется внутри компилируемого определения, то
строка компилируется в исходном невычисленном виде, и будет вычислена
при выполнении скомпилированного определения. Например:

: TEST " многострочный
{text}
строки" ;

При выполнении TEST получится такая же строка, как в предыдущем
примере.

При вычислении выражения в {} всегда используется десятичная
система счисления.

Все операции со строками выполняются в динамической памяти,
каждое s, возвращенное словом " , необходимо после использования
удалять из памяти словом

STRFREE [ s -- ]

Все операции помещают ноль в конце строки, поэтому возвращаемое
по STR@ значение строки можно смело использовать в функциях Windows,
требующих ASCIIZ-строк.

Создание пустой строки:

"" [ -- s ]

Добавление строки addr u в конец строки s:

STR+ [ addr u s -- ]

Добавление строки s1 в конец строки s2 с удалением s1:

S+ [ s1 s2 -- ]

Если внутри строки, создаваемой кавычкой, требуется вставить кавычку,
можно это сделать с помощью {''}, а конец строки - {CRLF}. Например:

" многострочный{CRLF}{text}
строки"

вернет ту же строку, что и в предыдущем примере.

Если при вычислении выражения в {} происходит ошибка [throw], то
значением выражения, вставляемым в строку, будет "Error: код_ошибки".

Особый вариант вычисления выражения {} используется в случае, если
внутри {} используются имена локальных для текущей компилируемой
процедуры переменных. Эти имена существуют только в момент компиляции,
а в момент выполнения процедуры, когда вычисляется {} - нет. Поэтому
будет возникать ошибка. Для предотвращения такого исхода и сохранения
возможности использования локальных переменных внутри строк принят
следующий синтаксис использования локальной переменной внутри строки:
{$имя_переменной}. Например:

: TEST { \ t }
" abcd" -> t
" 123{$t}123" STYPE
;

Выполнение слова TEST напечатает 123abcd123.
Последовательности вида {$имя} обрабатываются в момент компиляции
и заменяются последовательностью {число RP@ + @ STR@}, где "число" -
смещение локальной перемеменной в стеке.

Если локальную переменную нужно вставить в строку как числовое
значение, то используется {#имя_переменной}.

Для работы со строковыми литералами внутри {} можно использовать
слово S', являющееся аналогом S", но использующее одинарную кавычку
при парсинге.

Для вставки содержимого файла в строку можно использовать слово
FILE [ addr u -- addr1 u1 ], здесь addr u - имя файла, а addr1 u1 -
его содержимое. Например:

" text1{S' filename.txt' FILE}text2"

EVAL-FILE делает то же самое, но вычисляет выражения в {} внутри файла.
EVAL-FILE можно использовать и внутри файлов, включаемых по EVAL-FILE.
Это фактически аналог слова INCLUDED, но интерпретирующий только
выражения внутри {}, и возвращающий строку как результат.

Описанных выше слов " "" STR+ STR@ STRFREE CRLF '' FILE EVAL-FILE
достаточно для использования этой библиотеки. Рекомендуется не использовать
другие определенные в реализации слова чтобы не потерять
совместимость с будущими версиями.

Потенциально узкое место - если в процессе "роста" строка становится
длиннее 4Кб, производится выделение нового буфера, при его исчерпании -
следующего, и т.д. Все старые буферы кроме самого первого размером 4Кб
автоматически освобождаются. В служебных структурах первого буфера
делаются необходимые "редиректы". Исходный указатель на строку - s -
продолжает оставаться валидным для всех описанных операций. А вот
сохранять во внешних переменных указатели на addr u не рекомендуется,
т.к по мере роста указатель addr может измениться при описанном
перевыделении буфера. Лучше работать с указателем вида s, и, когда
необходимо, получать строку в виде addr u операцией STR@.

Скомпилированный размер библиотеки - около 7Кб.

25.12.2000
Добавлена спец-обработка случаев {n} и {s}. Если они встречаются
в разбираемой строке, то значения для вставки берутся не из переменных
и не из EVALUATE, а со стека - то что там лежало до ". n - просто число,
s - строка addr u.

08.09.2007
Добавлена спец-обработка случая {c} - вставка символа по его коду со стека.
[по пожеланию из бага SF#1785461]

26.12.2007
Добавлена спец-обработка случая {m} - вставка числа со знаком.
[вместо неработающего "-n" в mlogc из Eserv]

12.03.2008
{m} [вставка числа со знаком] заменено на {-} из-за конфликта {m} с
большим объемом старого кода, где {m} обозначает месяц.

XCOUNT

( xs -- addr1 u1 )

получить строку addr1 u1 из строки со счетчиком xs
счетчик - ячейчка, а не байт, в отличие от обычного COUNT

S'

SALLOT

( addr u -- xs )

sALLOT

s@

( s -- xs )

s!

( xs s -- )

STR@

( s -- addr u )

STRFREE

( s -- )

STYPE

( s -- )

STR+

( addr u s -- )

DEBUG @ IF ." STR+:" addr u TYPE CR THEN

STR!

( addr u s -- )

S+

( s1 s -- )

""

( -- s )

LSTRFREE1

( -- )

{eval}

( ... s -- s )

{sn}

( ... s -- s )

({...})

( -- s )

{...}

( addr u -- ... )

S"{"

( -- addr u )

S"}"

( -- addr u )

"delimiters

( addr 2 -- )

"delimiters:

( -- )

(("))

( -- s )

(")

( addr u -- s )

{STR@LOCAL}

( addr u s -- )

(STR@LOCAL)

( -- s )

STR@LOCALs

( addr u -- s )

_STRLITERAL

( -- s )

STRLITERAL

( addr u -- )

: S, ( addr u -- )
HERE SWAP DUP ALLOT CMOVE
;
похоже на SLITERAL, но длина строки не ограничена 255
и компилируемая строка при выполнении "разворачивается" по (")

CRLF

''

PARSE"

( \ s c -- addr u )

"

( "ccc" -- )

LastFileFree

LastFileSize

FILE

( addr u -- addr1 u1 )

FILEFREE

( a -- )

S@

( addr u -- addr2 u2 )

вычислить {} в строке
ValidateThreadHeap<

EVAL-FILE

( addr u -- addr1 u1 )

S!

( addr u var_addr -- )

ValidateThreadHeap<

>STR

( addr u -- str )

~ygrek:

STRLEN

STRA

~ac/lib/transl/BNF.F

Описание

Поддержка основных типов данных BNF. Удобно применять для реализации
на Форте трансляторов с других языков, для которых существует формальное
описание синтаксиса на BNF.
Andrey Cherezov, 26.Mar.2000

GetNextChar

( -- )

13=CR - трактуется как конец строки

Expected

( addr u -- )

i.e. ABORT"

Match

( char -- )

IsDigit_nz

( char -- flag )

IsDigit

( char -- flag )

GetNumber

( -- s )

GetNzNumber

( -- s )

IsCHAR

( char -- flag )

IsTEXT_CHAR

( char -- flag )

IsCHAR8

( char -- flag )

CHAR8 ::= <any 8-bit octet except NUL, 0x01 - 0xff>

IsCTL

( char -- flag )

CTL ::= <any ASCII control character and DEL,
0x00 - 0x1f, 0x7f>

IsSPACE

( char -- flag )

SPACE ::= <ASCII SP, space, 0x20>

IsQuotedSpecials

( char -- flag )

IsQUOTED_CHAR

( char -- flag )

после проверки этой функцией использовать дальше Look @, т.к. может измениться

GetQuoted

( -- s )

quoted ::= <"> *QUOTED_CHAR <">

LookString

( addr u -- flag )

проверить, есть ли заданная строка в текущей позиции парсинга

SkipString

( addr u -- flag )

пропустить строку addr u если она есть в текущей позиции парсинга

BNF

~day/common/sbnf.f

Описание

simple bnf-sorta parser

Выражение типа 16 0 <DIGITS> значит что
позиция парсинга переместится вправо на столько символов, сколько
их будет соответствовать цифрам (в данном случае), но не меньше 0
в данном случае и не больше 16 (если больше 16, парсер просто дальше не
пойдет)

Сдвинуть позицию в строке вправо на число присутствующих символов, но не
больше чем MIN(u, max)

Если сдвигов было меньше чем min то выдаем 0, иначе -1.

CHECK-SET

( addr u max min addr2 u2 -- addr2 u2 bool )

<SIGN>

( addr u max min -- addr2 u2 bool )

<EXP>

( addr u max min -- addr2 u2 bool )

<DOT>

( addr u max min -- addr2 u2 bool )

<DIGITS>

( addr u max min -- addr2 u2 bool )

?FLOAT

( addr u -- bool )

~pinka/lib/mask.f

Описание

сравнение строки и маски, содержащей метасимволы (wildcards) * ?
for SPF
(c) Ruvim Pinka

ver 0.1 11.06.1999
ver 0.4 18.03.2000
* исправлена некорректная обработка случая S" aaa" S" aaa*"
ver 0.5
+ переход к locals, небольшое улучшение алгоритма.
ver 0.6 13.05.2000
+ добавлена возможность квотить метасимволы \* \? \\
* где-то там еще было заюзывание временного словаря...

UpCase

( c1 -- c2 )

возвращает верхний регистр символа ( только для основного набора)

WildCMP-U

( str strlen wc wclen -- n )

addr1 u1 - строка
addr2 u2 - маска ( шаблон)
n = 0, если строка подходит под шаблон,
n = -1, - если несовпадающий символ НЕ найден, но строки разной длины.
- если он найден, причем первый несовпадающий символ
строки имеет меньшее числовое значение, чем соответсвующий
символ маски
n = 1 в остальных случаях, т.е. если первый несовпадающий символ
строки имеет не большее числовое значение, чем соответсвующий
символ маски.
Маска :
* - любое количество любых символов
? - любой символ

~pinka/lib/like.f

Описание

05.Apr.2004 (p) ruvim@forth.org.ru
сравнение строки и маски, содержащей метасимволы (wildcards) * ?
Сделал по другому старую либу ~pinka\lib\mask.f
( на что сподвигнул меня ~pig ;-)

Данная библиотека использует возможности парсера SPF4
$Id: like.f,v 1.5 2008/05/12 13:21:18 ruv Exp $

слово LIKE и ULIKE ( a u a-mask u-mask -- flag )
сопоставляет строку a u с маской,
возвращает TRUE при успехе
и FALSE, если сопоставление невозможно.
Wildcards:
* - любое количество любых символов
? - любой символ
\ - префикс "квотирования" специальных символов:
\\ -> \
\* -> *
\? -> ?
\q -> " ( предложение ~pig )
Особенности: для ускорения работы бэктрекинг сведен к минимуму
и сделан через обычный цикл; используется SEARCH и COMPARE

SEARCH&SKIP

( a u a-subs u-subs -- a2 u2 true | a u false )

искать в строке a u подстроку a-subs u-subs
если найдена, вернуть часть строки после найденного образа и true
иначе вернуть a u false.

MATCH-SIMPLE

( a u apat upat -- a1 u1 flag )

сопоставить apat upat c a upat
если совпадает, вернуть a+upat u-upat true,
иначе a u false

LIKE

( a1 u1 a-mask u-mask -- flag )

ULIKE

( a1 u1 a-mask u-mask -- flag )

Error: "source/~ac/lib/string/regexp.f.docbook" not found.

Error: "source/~ac/lib/string/bregexp/bregexp.f.docbook" not found.

~ac/lib/string/uppercase.f

Описание

новая версия сделана ~ygrek

: CHAR-UPPERCASE ( c -- c1 )
DUP [CHAR] a [CHAR] z 1+ WITHIN
OVER [CHAR] а [CHAR] я 1+ WITHIN OR IF 32 - THEN ;

еще новее ~ruv

CHAR-UPPERCASE

( c -- c1 )

UPPERCASE

( addr1 u1 -- )

~ac/lib/string/compare-u.f

Описание

COMPARE-CHAR-U

( c1 c2 -- -1|0|1 )

COMPARE-U

( addr1 u1 addr2 u2 -- flag )

~ac/lib/string/get_params.f

Описание

Простая библиотека для преобразования строки параметров
в список пар параметр-значение. Например, выполнение
S" error_code=10060&from=http://10.1.1.11/" GetParamsFromString
приведет к тому, что в динамическом списке, на который
указывает переменная PARAMS, появятся элементы с именами
error_code и from, с которыми связаны значения-строки addr u
Основные слова - GetParam, SetParam, IsSet, примеры см. в конце.

CONVERT

( a u c1 c2 -- )

CONVERT%

( a u \ a2 u2 i -- a2 u2 )

SetParam1

( va vu na nu -- )

STRING:

Name:Value

AllocParams

GetParamsFromString

( addr u -- )

ForEachParam

( xt \ a -- )

DumpParam

( na nu va vu -- )

DumpParams

SearchParam

( na nu \ a -- a true | false )

IsSet

( addr u -- flag )

SetParam

( va vu na nu -- )

GetParam

( na nu -- va vu )

~pinka/samples/2005/lib/split.f

Описание

Dec.2004
$Id: split.f,v 1.6 2006/12/10 16:00:28 ruv Exp $

SPLIT-

( a u a-key u-key -- a-right u-right a-left u-left true | a u false )

разделить строку a u на часть слева от подстроки a-key u-key
и на часть справа от этой подстроки.

SPLIT

( a u a-key u-key -- a-left u-left a-right u-right true | a u false )

вариант дает более 'логичный' порядок на выходе: левая_часть правая_часть

MOVE-

( a-dst a-src u-src -- )

INPLACE-

( a u a-key u-key a-value u-value -- )

записывает value по всем key

SEAT-

( a-dst u-dst a-src u-src -- )

SEATED-

( a-dst u-dst a-src u-src -- a-dst u )

SEATED

( a-src u-src a-dst u-dst -- a-dst u )

REPLACE-

( a u a-k u-k a-new u-new -- a u3 )

заменяет "на месте". Перемещает на каждом шаге весь оставшийся кусок. Без проверки границ.

CROP

( a1 u1 a-dst u-dst-max -- a-rest u-rest )

CROP-

( a-dst u-dst-max a1 u1 -- a-rest u-rest )

REPLACE-TO

( a u a-k u-k a-new u-new a-dst u-dst-max -- a-dst u )

делает замену в указанный буфер с проверкой границ.

~pinka/samples/2005/lib/replace-str.f

Описание

Dec.2004
$Id: replace-str.f,v 1.6 2008/03/27 02:46:24 spf Exp $

replace-str-

( s s-old s-new -- )

заменить s-old на s-new в строке s
s-old и s-new освобождаются

replace-str

( s-new s-old s -- )

~pinka/samples/2005/lib/split-white.f

Описание

13.Dec.2005
04.Nov.2006 Sat 21:37
$Id: split-white.f,v 1.1 2006/12/18 19:59:08 ruv Exp $

IS-WHITE

( c -- flag )

FINE-HEAD

( c-addr u -- c-addr1 u1 )

"очистить голову" - дать строку за вычетом пробельных символов вначале

FINE-TAIL

( c-addr u -- c-addr u2 )

"очистить хвост" - дать строку за вычетом пробельных символов в конце

SPLIT-WHITE-FORCE

( c-addr u -- c-addr-left u-left c-addr-right u-right )

'FORCE' значит, что без флага
если разделитель не найден, то правая часть имеет длину 0.
white как бы имеет длину ноль (т.е., он остается в правой части)

-SPLIT-WHITE-FORCE

( c-addr u -- c-addr-left u-left c-addr-right u-right )

поиск в обратном направлении, начиная с конца строки
если разделитель не найден, то левая часть имеет длину 0.
если найден, то он остается в левой части.

UNBROKEN

( c-addr u -- c-addr u2 )

Если в конце нет пробельных символов, но в строке они имеются,
то выкидывает последнее слово как сомнительное в целостности.

~ygrek/lib/typestr.f

Описание

$Id: typestr.f,v 1.4 2007/12/05 15:44:11 ygreks Exp $

Перенаправление всего вывода слова в строку
TYPE>STR ( xt -- s )
Ловит исключения внутри xt, работает независимо в каждом потоке

Пример
:NONAME 3 . ." test" 3 SPACES ." hello" ; TYPE>STR
даёт " 3 test hello"

в TYPE подсовывается попоточный USER-TYPE
см. обсуждение в http://www.nabble.com/IsDelimiter-t4856219.html

TYPE>STR-CATCH

( xt | old.type old.heap old.str -- str ior )

Весь консольный вывод xt будет сохранён в строку str

TYPE>STR

( xt -- str )

Сохранить весь консольный вывод
Игнорировать исключения - лог будет сохранён в строку (если был)

~profit/lib/bac4th-str.f

Описание

Работа со строками, которые автоматически переносятся в кучу,
и автоматически (при откате) с неё снимаются
bac4th strings AKA "бэкфортовы шнуры". Без понимания работ
~mlg по бэктрекингу лучше и не соваться
см. http://fforum.winglion.ru/viewtopic.php?t=167

S>

( a u -- s )

S>STR

( a u --> s \ <-- s )

S>STR2

( a u --> s \ <-- )

copy-patch

( a u i l \ e t -- a+i l )

copy

( a u i l --> s \ <-- s )

byChar

( c <--> xt )

Генерирует функцию сравнивающую на равенство с числом

find

( a u f <--> a1 )

находит в строке a u все символы, на которых функция f даст TRUE и генерирует вызовы для каждого символа
Функция f ( с -- 0|-1 ) получает на входе значение символа и выводит логическое значение

split-patch

( a u f <--> addr u )

разбивает строку a u символами, на которых функция f даст TRUE и генерирует
вызов для каждого *отрезка* в строке a u

first-patch

( a u f -- addr u )

first

( a u f <--> s )

divide-patch

( a u f -- addr1 u1 addr2 u2 )

divide

( a u f --> s1 s2 \ <-- s1 s2 )

split

( a u f <--> s1 )

разбивает строку a u символами, на которых функция f даст TRUE и генерирует вызов для
каждой последовательности между этими символами с автоматическим выделением и снятием памяти

last-patch

( a u f <--> addr u )

last

( a u f <--> s1 )

notEmpty

( s <--> s )

concat{

конструкция ... concat{ генератор-строк ( addr u ) }concat ( s <-> s ) ...

}concat

load-file

( addr u <--> addr1 u1 )

iterateStrings

( addr u <--> s )

~pinka/spf/string-equal.f

Описание

2006, 2007

CEQUAL

( c-addr1 u1 c-addr2 u2 -- flag )

EQUAL

( c-addr1 u1 c-addr2 u2 -- flag )

Глава 23. Files

Description

some description here

~ac/lib/win/file/share-delete.f

Описание

открытие файла в таком режиме позволяет переименовывать
и даже удалять этот открытый файл. Реальное удаление
произойдет после закрытия всех хэндлов.
работает только в WinNT*

OPEN-FILE-SHARED-DELETE

( c-addr u fam -- fileid ior )

CREATE-FILE-SHARED-DELETE

( c-addr u fam -- fileid ior )

CREATE-FILE-SHARED-DELETE-ON-CLOSE

( c-addr u fam -- fileid ior )

В отличие от предыдущей функции здесь не просто разрешается
удаление открытого файла, но и указывается на необходимость его
автоматического удаления при закрытии всех его хэндлов.
Это похоже на CREATE-FILE-SHARED-DELETE+(сразу)DELETE-FILE при
создании файла-флага, но позволяет работать с этим смертником (читать-писать).

~pinka/samples/2005/lib/lay-path.f

Описание

13.May.2005 ruvim@forth.org.ru
$Id: lay-path.f,v 1.2 2008/05/12 13:21:29 ruv Exp $
Module provide words for lay a path to file (creating non-existent folders)
originally prime from acWEB\src\ext.f # CREATE-FILE-PATH

example:
S" .\test-folder\aaa\" LAY-PATH
S" test-string" S" c:\work\test1\aaa\bbb\my-file.txt" FORCE-PATH ATTACH

CREATE-FOLDER

( addr u -- ior )

LAY-PATH-CATCH

( a u -- ior )

LAY-PATH

( a u -- )

FORCE-PATH

( a u -- a u )

~pinka/samples/2005/lib/append-file.f

Описание

09.Dec.2004
$Id: append-file.f,v 1.7 2007/09/16 13:51:18 ruv Exp $

9REPOSITION-FILE

( fileid -- ior )

Reposition the file identified by fileid to end of file.
see also ~pinka\lib\FileExt.f # TOEND-FILE

OPEN-LOGFILE

( a u -- h ior )

ATTACH-CATCH

( a u a-file u-file -- ior )

ATTACH

( a u a-file u-file -- )

ATTACH-LINE

( a u a-file u-file -- )

ATTACH-LINE-CATCH

( a u a-file u-file -- ior )

EMPTY

( file-a file-u -- )

: OCCUPY ( a u a-file u-file -- )
2DUP FILE-EXIST IF 2DUP DELETE-FILE THROW THEN ATTACH
;

OCCUPY

( a u a-file u-file -- )

OCCUPY-CATCH

( a u a-file u-file -- ior )

~pinka/samples/2005/ext/tank.f

Описание

02.Jul.2002 ruv
Output redirection, output control
Управление выходным потоком.

12.Jul.2002 for Eproxy

25.Jan.2005 Tue 12:43
from cvs\eserv\trafc\src\lib\ext\mouth.f

11.May.2005
mouth -> tank

SAVE-TANK

( -- i*x i )

RESTORE-TANK

( i*x i -- )

TANK-ID!

( hfile -- )

STD-TANK

( -- )

SPEAK-FILE-WITH

( i*x hfile xt -- j*x ior )

execute xt within hfile for stdout

APPEND-FILE

( a-file u-file -- h )

open file for append, or create file

APPEND-FILE-CATCH

( a-file u-file -- h ior )

SPEAK-WITH

( i*x a u xt -- j*x )

Глава 24. XML

Description

some description here

~ac/lib/lin/xml/expat.f

Описание

$Id: expat.f,v 1.6 2008/07/21 11:28:15 spf Exp $
Простейший расширяемый обработчик XML-файлов на базе SAX-библиотеки Expat
Для компиляции и работы требуется libexpat.dll (тестировалось с версией 2.0)
Примеры использования - в конце файла.

Основные слова - XML_NewEvaluator и XML_Evaluate.
XML_Evaluate передает парсеру очередную порцию xml-файла. Парсер переключает
контексты форта - запуском словаря, имя которого совпадает с текущим тэгом,
после этого выполняет в словаре слова, совпадающие с именами атрибутов этого
узла xml, и .CDATA для текстовых данных. При закрытии тэга вызывается слово
.CLOSE текущего контекста. Т.е. для обработки заданной xml-структуры достаточно
создать соответствующую словарную структуру в Форте, и "выполнить" XML в
этом контексте.

Эта библиотека позволяет обрабатывать файл по мере поступления его контента,
не дожидаясь загрузки всего файла, как в xml.f. Такой режим экономит ресурсы
и позволяет работать с приложениями/протоколами, в которых достаточно
последовательной обработки xml-документа. А в некоторых случаях (очень большие
XML-файлы, не помещающиеся в память, или "долгоиграющие" документы типа XMPP
протокола) этот SAX-режим является единственным приемлемым решением.

XML_DumpAttrs

( addr -- )

SEARCH-ATTRIBUTE

( a u wid -- 0 | xt true )

XML_ExecAttrs

( addr -- )

>NAME

VOC-NAME

( wid -- addr u )

XML_NewParserGenerator

( \ p -- p )

XML_DumpError

( p -- )

XML_PFree

( p -- )

XML_Generate

( islast addr u p -- )

XML_NewEvaluator

( \ p -- p )

XML_Evaluate

( islast addr u p -- )

X{

"Макросы" создания словарей

}X

Error: "source/~ac/lib/lin/xml/xml.f.docbook" not found.

Error: "source/~ac/lib/lin/xml/xslt.f.docbook" not found.

Error: "source/~ac/lib/lin/tidy/tidy.f.docbook" not found.

Глава 25. OOP extensions

Description

some description here

~day/joop/oop.f

Описание

09.Mar.2002 Sat 20:25 ruv
подправил на предмет ONLY FORTH DEFINITIONS
и нутро в отдельный словарь OO_Support

Yet another oop extention for sp-forth - just oop :
Dmitry Yakimov 2000 [c]

SWAP-CURRENT

this

WITH

( oid -- )

UnknownMsg

( -- a u )

RESOLVE-LINK

( addr u oid -- xt true | false )

ResolveLink

( addr u oid -- xt )

ExecuteMethod

( i*x xt oid -- j*x )

sendMessage

( ... addr u oid -- ... )

message:

( oid )

pvar:

<<

CLASS:

( - )

own_old

own

CONTEXT @ >R
GET-CURRENT CONTEXT ! '
R> CONTEXT !

>CLASS

from micro

M::

( c "WM_..." -- )

определить обработчик сообщения
c - символ типа сообщения

W:

C:

WM_...

N:

WM_COMMAND

P:

WM_NOTIFY

M:

WM_PARENTNOTIFY

SearchWM

( mess_id oid c -- xt -1 | 0)

->WM

( mess_id oid c)

Послать заданное сообщение объекту

WM:

METHODS{

( oid -- )

}METHODS

VARS{

( oid -- )

}VARS

EXPAND-CLASS

( oid -- )

;EXPAND-CLASS

( C: oid1 oid2 wid -- )

~af/mc/microclass.f

Описание

Andrey Filatkin, af@forth.org.ru
Переделка ~day\mc\microclass.f
13.05.2000 Dmitry Yakimov
ver. 1.5.
Эта библиотека была частично взята у ~1001bytes, доработана и исправлена [!].

Либа организует статический ООП поверх словарей. Дает возможность
наследования, динамического создания\уничтожения объектов.
Эта либа тесно связана с локалсами. В начале каждого метода создается
один локалс _mc, в котором хранится self. Так намного быстрее работает,
чем при хранении self в USER-переменной.

Создание классов:
CLASS: Test
0
CELL FIELD x
CELL FIELD y
CONSTANT /Test

M: INIT x ! y ! ;
;CLASS

CHILD: Test Test1
/Test
CELL FIELD z
CONSTANT /Test1
M: INIT INHERIT z ! ;
;CLASS

Создание статического объекта:
ALSO Test 1 2 /Test OBJECT
...
PREVIOUS

Создание динамического объекта:
: foo
[ ALSO Test ] 1 2 /Test NEWOBJ
...
DELETEOBJ [ PREVIOUS ]
;

CLASS:

( "name" -- 0 )

CHILD:

( -- u )

родитель

OBJECT

( length -- addr )

Создание объекта в словарном пространстве

NEWOBJ

( -- addr )

Создание объекта в куче

DELETEOBJ

( addr -- )

Удаление объекта

~day/mc/microclass.f

Описание

13.05.2000 Dmitry Yakimov
ver. 1.5.

Эта библиотека была частично взята у ~1001bytes, доработана и
исправлена [!]. Спасибо тебе друг за
светлые мысли. Фортерам [в моем лице] не хватает простого управления
словарями. А остальное из ООП можно вручную. Разберем по порядку:
В сравнении с ООП:
1. Наследование данных - есть, если будете соблюдать правило:
Использовать в классе структуры, размером указывать /ИМЯ_КЛАССА
Пример:

CLASS: Test
0
CELL FIELD x
CELL FIELD y
CONSTANT /Test
;CLASS


WITH Test CHILD: Test1
/Test
CELL FIELD z
CONSTANT /Test1
;CLASS

\ Можно автоматически брать начальную длину структуры, но лучше
\ дадим фортеру больше свободы [простота залог понимания и надежности]
\ Создание объекта:
WITH Test1
/Test1 OBJECT \ [ или /Test1 NEW]
...
WITHOUT

Причем, я думаю что константу /Test1 можно даже создавать автоматически,
простым добавление слэша в начале. Хотя будем оптимально минимальны.
Заметьте, что все является открытым с одной стороны, но ненавязчиво
с другой. Это как раз для фортера. Наследование очень необходимо
по той причине что фреймовое представление знаний оказывает нам услугу
упрятывания массы деталей и делая массу вещей by default.

[*] - FIELD - полный аналог -- только работает в контексте текущего
объекта - использует self.

2. Инкапсуляция
Без инкапсуляции [сваливания в одну кучу данных и методов] это будет
не ООП, а простой форт лексикон. Но нам не нужна зверская инкапсуляция
с++ [ее очень ругал Броуди]. Нам нужна инкапсуляция с человеческим
лицом, повернутым к нам и доброжелательным к тому же. Она есть.
Она не запрещает нам в полной мере использовать лексикон и данные класса.
АС скажет - а где приватные переменные как в Смоллтоке? А зачем они
нужны - отвечу я. Если переменная нам нужна как контейнер или если угодно
как некий переключатель состояния экземпляра и все операции с ней
сводятся к простой записи/считыванию то зачем городить огород - может
просто разрешить к ним доступ? Ну а действительно private переменные
нам никто и не запретит сделать, если захочется. Да, может быть трудность
в использовании ООП библиотек другими программистами [у форта положение
еще хуже], но если писать аккуратно, то все будет ОК.

3. Полиморфизм
Это когда каждый класс имеет свой метод с одинаковым именем, но они делают
разные вещи в разных классах. Например у класса Point метод paint
и у класса Rectangle метод paint.
А оно нам надо? Надо. Но в такой форме как у нас - когда экземпляр
НЕ знает своего класса и вообще экземпляр состоит только из данных то
будут возникать коллизии полиморфизма иногда [очень редко]. Это
как раз случай, когда массиву разных экземпляров посылается сообщение
с одним и тем же именем. Но МЫ - хозяевы :> - мы не то, что это
предусмотрим, мы автоматически включим например в экзмепляр переменную
селектор потому что мы пишем на форте и от форта никуда не отходили
- слова да слова [фортовские].
В общем, мне эта либа определенно нравится и она, можно сказать, плавлено
войдет в мои программы.
Можно и не пользоваться вышеприведенной схемой, а использовать только
для управления словарями.
Текст ниже. Комментарии больше либы в 2 раза. Вот вам и форт :]