Skip to content

Commit c57bb5a

Browse files
madman-bobgallais
authored andcommitted
Add RefC StringIterator support
1 parent 58a321c commit c57bb5a

File tree

7 files changed

+89
-3
lines changed

7 files changed

+89
-3
lines changed

libs/contrib/Data/String/Iterator.idr

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ data StringIterator : String -> Type where [external]
2323
-- to avoid subverting the linearity guarantees of withString.
2424
%foreign
2525
"scheme:blodwen-string-iterator-new"
26+
"C:stringIteratorNew"
2627
"javascript:stringIterator:new"
2728
private
2829
fromString : (str : String) -> StringIterator str
@@ -37,6 +38,7 @@ withString str f = f (fromString str)
3738
||| iterator `it`
3839
%foreign
3940
"scheme:blodwen-string-iterator-to-string"
41+
"C:stringIteratorToString"
4042
"javascript:stringIterator:toString"
4143
export
4244
withIteratorString : (str : String)
@@ -61,6 +63,7 @@ data UnconsResult : String -> Type where
6163
-- (e.g. byte offset into an UTF-8 string).
6264
%foreign
6365
"scheme:blodwen-string-iterator-next"
66+
"C:stringIteratorNext"
6467
"javascript:stringIterator:next"
6568
export
6669
uncons : (str : String) -> (1 it : StringIterator str) -> UnconsResult str

src/Libraries/Data/String/Iterator.idr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ data StringIterator : String -> Type where [external]
2222
-- to avoid subverting the linearity guarantees of withString.
2323
%foreign
2424
"scheme:blodwen-string-iterator-new"
25+
"C:stringIteratorNew"
2526
"javascript:stringIterator:new"
2627
private
2728
fromString : (str : String) -> StringIterator str
@@ -49,6 +50,7 @@ data UnconsResult : String -> Type where
4950
-- (e.g. byte offset into an UTF-8 string).
5051
%foreign
5152
"scheme:blodwen-string-iterator-next"
53+
"C:stringIteratorNext"
5254
"javascript:stringIterator:next"
5355
export
5456
uncons : (str : String) -> (1 it : StringIterator str) -> UnconsResult str

support/refc/stringOps.c

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,3 +185,65 @@ char *fastConcat(Value *strList)
185185

186186
return retVal;
187187
}
188+
189+
typedef struct
190+
{
191+
char *str;
192+
int pos;
193+
} String_Iterator;
194+
195+
Value *stringIteratorNew(char *str)
196+
{
197+
int l = strlen(str);
198+
199+
String_Iterator *it = (String_Iterator *)malloc(sizeof(String_Iterator));
200+
it->str = (char *)malloc(l + 1);
201+
it->pos = 0;
202+
memcpy(it->str, str, l + 1); // Take a copy of str, in case it gets GCed
203+
204+
Value_Arglist *arglist = newArglist(2, 2);
205+
Value *(*onCollectRaw)(Value_Arglist*) = onCollectStringIterator_arglist;
206+
Value_Closure *onCollect = makeClosureFromArglist(onCollectRaw, arglist);
207+
208+
return (Value *)makeGCPointer(it, onCollect);
209+
}
210+
211+
Value *onCollectStringIterator(Value_Pointer *ptr, void *null)
212+
{
213+
String_Iterator *it = (String_Iterator *)ptr->p;
214+
free(it->str);
215+
free(it);
216+
return NULL;
217+
}
218+
219+
Value *onCollectStringIterator_arglist(Value_Arglist *arglist)
220+
{
221+
return onCollectStringIterator(
222+
(Value_Pointer *)arglist->args[0],
223+
arglist->args[1]
224+
);
225+
}
226+
227+
Value *stringIteratorToString(void *a, char *str, Value *it_p, Value_Closure *f)
228+
{
229+
String_Iterator *it = ((Value_GCPointer *)it_p)->p->p;
230+
return apply_closure((Value *)f, (Value *)makeString(it->str + it->pos));
231+
}
232+
233+
Value *stringIteratorNext(char *s, Value *it_p)
234+
{
235+
String_Iterator *it = (String_Iterator *)((Value_GCPointer *)it_p)->p->p;
236+
char c = it->str[it->pos];
237+
238+
if (c == '\0') {
239+
return (Value *)newConstructor(0, 0, "Data_String_Iterator_EOF");
240+
}
241+
242+
it->pos ++; // Ok to do this as StringIterator linear
243+
244+
Value_Constructor *retVal = newConstructor(2, 1, "Data_String_Iterator_Character");
245+
retVal->args[0] = (Value *)makeChar(c);
246+
retVal->args[1] = newReference(it_p);
247+
248+
return (Value *)retVal;
249+
}

support/refc/stringOps.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,10 @@ char *fastPack(Value *charList);
1515
Value *fastUnpack(char *str);
1616
char *fastConcat(Value *strList);
1717

18+
Value *stringIteratorNew(char *str);
19+
Value *onCollectStringIterator(Value_Pointer *ptr, void *null);
20+
Value *onCollectStringIterator_arglist(Value_Arglist *arglist);
21+
Value *stringIteratorToString(void *a, char *str, Value *it_p, Value_Closure *f);
22+
Value *stringIteratorNext(char *s, Value *it_p);
23+
1824
#endif

tests/refc/strings/TestStrings.idr

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,14 @@
11
module TestStrings
22

33
import Data.String
4+
import Data.String.Iterator
5+
6+
iteratorTail : String -> String
7+
iteratorTail str = withString str $ \it => unconsTail str (uncons str it)
8+
where
9+
unconsTail : (str : String) -> (1 _ : UnconsResult str) -> String
10+
unconsTail str EOF = ""
11+
unconsTail str (Character _ tailIt) = withIteratorString str tailIt id
412

513
main : IO ()
614
main = do
@@ -20,13 +28,16 @@ main = do
2028
putStrLn $ show $ fastUnpack "unpack"
2129
putStrLn $ fastConcat ["con", "cat", "en", "ate"]
2230

23-
let chars = ['a', 'A', '~', '0', ' ', '\n', '\x9f']
31+
let chars = the (List Char) ['a', 'A', '~', '0', ' ', '\n', '\x9f']
2432
putStrLn $ show $ map isUpper chars
2533
putStrLn $ show $ map isLower chars
2634
putStrLn $ show $ map isDigit chars
2735
putStrLn $ show $ map isSpace chars
2836
putStrLn $ show $ map isNL chars
2937
putStrLn $ show $ map isControl chars
3038

31-
putStrLn $ show $ map chr [97, 65, 126, 48, 32, 10, 159]
39+
putStrLn $ show $ map {f = List} chr [97, 65, 126, 48, 32, 10, 159]
3240
putStrLn $ show $ map ord chars
41+
42+
putStrLn $ show $ Data.String.Iterator.unpack "iterator unpack"
43+
putStrLn $ show $ iteratorTail "iterator tail"

tests/refc/strings/expected

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,5 @@ concatenate
1616
[False, False, False, False, False, True, True]
1717
['a', 'A', '~', '0', ' ', '\LF', '\159']
1818
[97, 65, 126, 48, 32, 10, 159]
19+
['i', 't', 'e', 'r', 'a', 't', 'o', 'r', ' ', 'u', 'n', 'p', 'a', 'c', 'k']
20+
"terator tail"

tests/refc/strings/run

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
$1 --no-banner --no-color --console-width 0 --cg refc -o refc_strings TestStrings.idr > /dev/null
1+
$1 --no-banner --no-color --console-width 0 --cg refc -p contrib -o refc_strings TestStrings.idr > /dev/null
22
./build/exec/refc_strings
33

44
rm -rf build

0 commit comments

Comments
 (0)