duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit 1024013264e4d4ce43099f4e2a4de4670c8191fb
parent 6ca68a5be640af6151c30ee70628ce7403db40da
Author: binarycat <binarycat@envs.net>
Date:   Thu, 30 Jun 2022 12:55:52 -0400

filter subsystem redux

Here's my second attempt at this patch. "with'" has become "with" and the old "with" has been removed.
I found the code was more readable if I just used "to'", that way all the arguments were on the same side
of with.

I have added some more comments trying to explain how to use the system, hopefully this is good enough
for now.

Diffstat:
Mfs/lib/str.fs | 13+++++++++++++
Afs/lib/with.fs | 3+++
Afs/sys/filter.fs | 36++++++++++++++++++++++++++++++++++++
Mfs/tests/lib/all.fs | 1+
Mfs/tests/lib/str.fs | 5+++++
Afs/tests/lib/with.fs | 9+++++++++
6 files changed, 67 insertions(+), 0 deletions(-)

diff --git a/fs/lib/str.fs b/fs/lib/str.fs @@ -8,6 +8,19 @@ $100 value STR_MAXSZ \ "skip" str, that is, return the address following its last char : s) ( str -- a ) c@+ + ; +\\ append character to end of string +: sappend ( c str -- ) tuck s) c! dup c@ 1+ swap c! ; + +\\ checks if str1 contains all of str2 (is str2 a substring?) +: scontains ( str1 str2 -- f ) + >r c@+ begin + dup r@ c@ >= while + over r@ c@+ []= if + r> drop 2drop 1 exit + then + 1- swap 1+ swap + repeat r> drop 2drop 0 ; + \ find active string in "list" and return its index, -1 if not found. \ A list is a simple sequence of strings (length byte, then contents, then \ another one...) ended by a 0 length diff --git a/fs/lib/with.fs b/fs/lib/with.fs @@ -0,0 +1,3 @@ +\\ helper word to save and restore a variable across a function call. +: with ( w u addr -- ) dup >r dup @ >r ! execute r> r> ! ; + diff --git a/fs/sys/filter.fs b/fs/sys/filter.fs @@ -0,0 +1,36 @@ +\ filter executes a word and filters its output based on a substring match. +\ it parses first the word to execute, the the substring search to filter +\ the output by. + +?f<< lib/str.fs +?f<< lib/with.fs + +SPC value filter-delim + +\ internal state +create filter-buf $100 allot +0 value filter-str +alias abort filter-out + +: filter-chunk + filter-buf filter-str scontains if + filter-buf ['] stype to' filter-out @ to' emit with + filter-delim filter-out + then + 0 filter-buf c! ; + +: filter-char ( c -- ) + dup filter-delim = if drop + filter-chunk + else + filter-buf sappend + then ; + +: with-filter-str ( w str -- ) + \ TODO: replace emit with stdout when it is added + to filter-str + 0 filter-buf c! + to' emit @ to filter-out + ['] filter-char to' emit with filter-chunk ; + +: filter ( "word" "query" -- ) ' word with-filter-str ; diff --git a/fs/tests/lib/all.fs b/fs/tests/lib/all.fs @@ -3,3 +3,4 @@ f<< tests/lib/core.fs f<< tests/lib/str.fs f<< tests/lib/xdict.fs f<< tests/lib/struct.fs +f<< tests/lib/with.fs diff --git a/fs/tests/lib/str.fs b/fs/tests/lib/str.fs @@ -15,4 +15,9 @@ S" baz" list sfind -1 #eq '0' A-Za-z? not # 'z' alnum? # '0' alnum? # + +S" foobar" S" foo" scontains # +S" foobar" S" bar" scontains # +S" foobar" S" oba" scontains # +S" foobar" S" baz" scontains not # testend diff --git a/fs/tests/lib/with.fs b/fs/tests/lib/with.fs @@ -0,0 +1,9 @@ +?f<< lib/with.fs +?f<< tests/harness.fs +testbegin +\ testing lib/with +create cell1 7 , +: foo cell1 @ 55 #eq ; +: bar ['] foo 55 cell1 with ; +bar cell1 @ 7 #eq +testend