\ сравнение строки и маски, содержащей метасимволы (wildcards) * ? \ ver 0.3 \ for SPF \ ver 0.1 - 11.06.1999 Ruvim Pinka \ for GNU Forth -- Alex Malyshev (alexript@mail.ru) uses StartUp uses Ext.comment uses Ext.var VARS m.wc m.wclen m.str m.strlen ; \ макросы ( тут бы временный словарь заюзать... :) : wc+ S" m.wc @ 1+ m.wc ! m.wclen @ 1- m.wclen ! " EVALUATE ; IMMEDIATE : str+ S" m.str @ 1+ m.str ! m.strlen @ 1- m.strlen ! " EVALUATE ; IMMEDIATE : WildCMP ( addr1 u1 addr2 u2 -- n ) \ case sensitive - non \ addr1 u1 - string \ addr2 u2 - mask \ n = 0, если строка подходит под шаблон, (Yes) \ n = -1, - если несовпадающий символ НЕ найден, но строки разной длины. \ - если он найден, причем первый несовпадающий символ \ строки имеет меньшее числовое значение, чем соответсвующий \ символ маски \ (No) \ n = 1 в остальных случаях, т.е. если первый несовпадающий символ \ строки имеет не большее числовое значение, чем соответсвующий \ символ маски. (No) \ Маска : \ * - string of any symbols \ ? - any symbol m.wclen ! m.wc ! m.strlen ! m.str ! BEGIN m.wclen @ 0= IF m.strlen @ 0= IF 0 EXIT THEN -1 EXIT THEN m.strlen @ 0= IF -1 EXIT THEN m.wc @ C@ DUP [CHAR] ? = IF DROP str+ wc+ ELSE DUP [CHAR] * = IF DROP wc+ \ пропустим все метасимволы после * BEGIN m.wclen @ IF m.wc @ C@ [CHAR] * = m.wc @ C@ [CHAR] ? = OR ELSE 0 EXIT THEN \ выход, если * - последний в шаблоне WHILE wc+ REPEAT BEGIN \ попробуем сравнить оставшиеся части m.str @ m.strlen @ m.wc @ m.wclen @ RECURSE 0<> WHILE \ пропустим символ в строке, если не успешно m.strlen @ 0= IF -1 EXIT THEN str+ REPEAT ELSE m.str @ C@ 2DUP <> IF > IF -1 EXIT ELSE 1 EXIT THEN THEN 2DROP str+ wc+ THEN THEN AGAIN ; /* : test S" 012WebMaster" S" ???w??mas*" WildCMP CR ." result: " . S" 012webmaster" S" ???w??mas*" WildCMP CR ." result: " . ; */ /* : test S" /~alex/" S" */" WildCMP CR ." result: " . ; */