По поводу поиска

3 messages Options
Embed this post
Permalink
azekeprofit

По поводу поиска

Reply Threaded More More options
Print post
Permalink
Это я пишу от mOleg'а. У него там не срослось с рассылкой:

ну вот примерно такой вариант поиска не рабтает с magic value
и немножко, какмне кажется удобнее располагает свои параметры
на стеке. Пока чтобы не путаться все "новые" слова набраны в
нижнем регистре.

Какие будут замечания или предложения?

Да, найдена неудобность, а точнее даже неточность в ?IMMEDIATE
и еще одна правка нужна в СПФовском INTERPRET - вместо:
STATE @ = нужно STATE @ >

\ 28-12-2006 ~mOleg
\ заменяем неудобный SFIND на более логичный
\ порядок следования параметров теперь будет следующим:
\ ( asc # --> asc # false | wid imm true )
\ то есть всегда возвращаем три числа!
\ либо возвращаем начальную строку с признаком false
\ либо - адрес флаг_immediate true

S" lib/include/tools.f" INCLUDED

\ в СПФ4 - это слово работает не очень верно - переопределил
: ?IMMEDIATE ( NFA -> F ) NAME>F C@ &IMMEDIATE AND 0<> ;

\ удалить с вершины стека указанное число параметров
: nDROP ( [ .. ] n --> ) 1+ CELLS SP@ + SP! ;

\ выдать адрес и длинну идентификатора имени
: id>asc ( NFA --> asc # ) DUP 1+ SWAP C@ ;

\ сравнить полученную лексему с именем слова
\ так проще менять код, если изменится формат словарной статьи
: identify ( asc # nameid --> flag )
id>asc 2SWAP COMPARE ;

\ заглушка на случай хешированных словарей
\ используя лексему и id словаря найти адрес начала цепочки слов, в которой
\ необходимо искать слова. Оптимизатор всеравно call выкинет.
: hashname ( asc # wid --> asc # link ) @ ;

\ найти слово в указанном словаре
\ тоже меняем порядок параметров.
: search-wordlist ( asc # voc-id -- asc # false | xt imm_flag true )
hashname
BEGIN DUP WHILE
 >R 2DUP R@ identify WHILE
R> CDR
REPEAT
2DROP R@ NAME>C @
R> ?IMMEDIATE TRUE
THEN ;

\ на входе список словарей, в которых нужно вести поиск и их кол-во
\ и строка - идентификатор имени
\ на выходе в случае неуспеха строка и false
\ в случае успеха исполнимый адрес слова и два флага
\ immediate и true
: sfindin ( widn ... widb wida # asc # --> asc # false | xt imm_flag true)
ROT BEGIN DUP WHILE 1- >R \ кол-во словарей для просмотрана R
ROT search-wordlist 0= WHILE \ лучше бы WHILENOT
R>
REPEAT
R> -ROT 2>R nDROP 2R> TRUE \ немного чудес на стеках 8)
THEN ;

\ найти слово в контексте
: sfind ( addr u -- addr u 0 | xt imm true )
2>R GET-ORDER 2R> sfindin ;

\ найти адрес слова, представленного строкой в тексте
\ после ' в текущем контексте.
\ Возвращает адрес, в случае ненахождения слова возникает исключение
: ' ( "<spaces>name" -- xt )
NextWord sfind
IF DROP \ признак immediate нам не нужен
ELSE -321 THROW
THEN ;

\ найти слово, если операция успешна скомпилировать его адрес в текущее
\ собираемое определение.
: ['] ( | name --> )
?COMP ' LIT,
; IMMEDIATE

\ выполнить действие, согласно переменной state
: stateact ( xt imm_flag --> )
STATE @ > IF COMPILE, ELSE EXECUTE THEN ;

\ интерпретировать слово, представленное строкой
\ выполнить действие, согласно состоянию STATE
: eval-name ( asc # --> )
sfind IF stateact
ELSE -2003 THROW
THEN ;

\ интерпретировать лексему ( слово или число ) представленное строкой
\ выполнить действие, согласно состоянию STATE
: eval-word ( asc # --> )
sfind IF stateact
ELSE ?SLITERAL
THEN ;

\ тут важный вопрос - в СПФ сначала ищется слово, если оно не найдено
\ но найден NOTFOUND, товыполняем его- иначе пытаемся понять число.
\ Это хорошо в случае, если, например числа нам нужно перекрыть, но
\ поиск по notfound может быть достаточно длинным, к томуже в начале
\ стандартногоNOTFOUND-а сначала ищется число, лишь затем пытаемся
\ что-то другое подобрать. - так получается быстрее разбор чисел (нет
\ поиска по словарю NOTFOUND-a), но числа, например нельзя запретить
\ или распознать как-то иначе. Для ускорения первого вариантаможно
\ для каждого словаря хранить последний определенный NOTFOUND в отдельной
\ ячейке, и @ ?EXECUTE над ней.

1 [IF] \ это вариант аналогичный стандартному

\ выделил в отдельное слово, почему бы и нет?
: notfound ( asc # --> )
S" NOTFOUND" sfind
IF DROP EXECUTE
ELSE 2DROP ?SLITERAL
THEN ;

\ интерпретировать входной поток до тех пор, пока он не закончится
: interpret ( -> )
BEGIN NextWord DUP WHILE
['] eval-name CATCH
IF notfound THEN
?STACK
REPEAT 2DROP ;

[ELSE] \ это с измененным порядком
следования ?sliteral & notfound

: notfound ( asc # --> )
S" NOTFOUND" sfind
IF DROP EXECUTE
ELSE -2003 THROW
THEN ;

: interpret ( -> )
BEGIN NextWord DUP WHILE
['] eval-word CATCH
IF notfound THEN
?STACK
REPEAT 2DROP ;
[THEN]

\ EOF совместимость со стандартным СПФом

\ это для совместимости со старым спф
: SEARCH-WORDLIST1 ( asc # voc-id -- asc # false | xt -1/1 )
search-wordlist
IF IF 1 ELSE -1 THEN
ELSE FALSE
THEN ;

: SFIND
2>R GET-ORDER 2R> sfindin
IF IF 1 ELSE -1 THEN
ELSE FALSE
THEN ;

: EVAL-WORD ( asc # --> ) eval-name ;
Ruvim Pinka

Re: По поводу поиска

Reply Threaded More More options
Print post
Permalink
Привет!

On 12/29/06, Azamadt Smaguloff <[hidden email]> wrote:
> Это я пишу от mOleg'а. У него там не срослось с рассылкой:

> Какие будут замечания или предложения?

1. Вместо ( asc # ) писать ( c-addr u ); asc ассоциируется с ascii и ASCIIZ.
2. Семантика слова SFIND не может быть изменена (как и SEARCH-WORDLIST ).
3. Сначала вариант реализации транслятора лучше делать в виде
полноценного расширения SPF4 (т.е., чтобы он, после его подключения,
выполнял всю трансляцию вместо штатного транслятора).


--
Ruvim
Aleksej Saushev

Re: По поводу поиска

Reply Threaded More More options
Print post
Permalink
In reply to this post by azekeprofit
"Azamadt Smaguloff"
<[hidden email]> writes:

> ну вот примерно такой вариант поиска не рабтает с magic value
> и немножко, какмне кажется удобнее располагает свои параметры
> на стеке. Пока чтобы не путаться все "новые" слова набраны в
> нижнем регистре.
>
> Какие будут замечания или предложения?
>
> Да, найдена неудобность, а точнее даже неточность в ?IMMEDIATE
> и еще одна правка нужна в СПФовском INTERPRET - вместо:
> STATE @ = нужно STATE @ >
>
> \ 28-12-2006 ~mOleg
> \ заменяем неудобный SFIND на более логичный
> \ порядок следования параметров теперь будет следующим:
> \ ( asc # --> asc # false | wid imm true )
> \ то есть всегда возвращаем три числа!
> \ либо возвращаем начальную строку с признаком false
> \ либо - адрес флаг_immediate true
>
> S" lib/include/tools.f" INCLUDED
>
> \ в СПФ4 - это слово работает не очень верно - переопределил
> : ?IMMEDIATE ( NFA -> F ) NAME>F C@ &IMMEDIATE AND 0<> ;

IMMEDIATE? - поскольку возвращает признак.
Ср. KEY? EMIT?


> \ удалить с вершины стека указанное число параметров
> : nDROP ( [ .. ] n --> ) 1+ CELLS SP@ + SP! ;

DISCARD - используйте уже данные имена.

> \ выдать адрес и длинну идентификатора имени
> : id>asc ( NFA --> asc # ) DUP 1+ SWAP C@ ;

Не используйте сокращения "asc", в России он не используется.

> \ найти слово в указанном словаре
> \ тоже меняем порядок параметров.
> : search-wordlist ( asc # voc-id -- asc # false | xt imm_flag true )
> hashname
> BEGIN DUP WHILE
>  >R 2DUP R@ identify WHILE
> R> CDR

Про CDR я тоже писал: не надо использовать неочевидных сокращений.

> : stateact ( xt imm_flag --> )

Зачем писать слитно? Подчёркивания и дефисы уже отменили?

Есть общее правило: код пишут не для машины, а для человека,
потому что машина переварит любую мешанину, а человек нет.