diff options
Diffstat (limited to 'doc/test.txt')
| -rw-r--r-- | doc/test.txt | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/doc/test.txt b/doc/test.txt new file mode 100644 index 0000000..da8f501 --- /dev/null +++ b/doc/test.txt @@ -0,0 +1,119 @@ +type string = []char + +func split(src: string, by: char, a: ^Arena): [dyn]string do + let r: [dyn]string = {} + let s: string = "" + for c in src do + if c == by then + r.push(s, a) + s = "" + else + s.push(c, a) + end + end + return r +end + +proc main do + let a = Arena() + let lines = split(stdin.readAll(@a), '\n', @a) + for i in 0..len(lines) do + print(lines[i]) + end +end + +--- + +fn next_line(src, line: ^[]u8) -> bool { + if len(src) < 1 { + return false + } + let idx = find(src, '\n') + if idx <> -1 { + line^ := src^[0..idx] + } else { + line^ := src^ + } + src^ = src^[len(line)..] + return true +} + +fn main { + let a = Arena() + let buf = readall(stdin, &a) + let line: []u8 + while next_line(&buf, &line) { + print(line) + } +} + +--- + +/* builtin slice type */ + +fn print(str []u8) { + for i in str { + putchar(str[i]) + } + putchar('\n') +} + +/* iterators are just functions that return an initial state object and a + * step function that acts on it to produce a value */ + +type LineIterFn = fn(it ^[]u8) ([]u8, bool) + +fn lines(src []u8) ([]u8, LineIterFn) { + fn step(it ^[]u8) []u8, bool { + if len(it^) < 1 { return {}, false } + idx := find(it^, '\n') + line := if idx == -1 { it^ } else { it^[0..idx] } + it^ = it^[len(line)..] + return line, true + } + return src, step +} + +/* if multiple values used in if/while condition, only the last one is checked */ + +fn main { + a := Arena {} + buf := readall(stdin, &a) + for line in lines(buf) { + print(line) + } +} + +/* generics? */ + +fn reverse[T any](buf []T) ([]T, fn(it ^[]T) (T, bool)) { + fn step(it ^[]T) (T, bool) { + if len(^it) < 1 { return {}, false } + n := len(it^) - 1 + v := it^[n] + it^ := it^[0..n] + return v, true + } + return buf, step +} + +fn foo { + s := "Hello, world!" + // print(reverse(s)) <- wouldn't actually work, because iterators can't be cast back to slices + a := Arena {} + print(collect(reverse(s), &a)) +} + +struct MapIter[In any, Out any] { + ctx: rawptr, + iter: fn(it rawptr) In, + map: fn(x ^In) Out +} + +fn map[In any, Out any](p rawptr, f func(it rawptr) In, f func(x ^In) Out) (MapIter[In, Out], fn(it ^MapIter[In, Out]) (Out, bool)) { + fn step(it ^MapIter[In, Out]) (Out, bool) { + v, ok := it.iter(it.ctx) + if !ok { return {}, false } + return it.map(&v), true + } +} |
