-//
-// The standard function to convert something to an Iterator.
-// For-loops currently do not use this function to determine
-// how to iterate over something unknown, but that could be
-// a feature down the line.
+#doc """
+ The standard function to convert something to an Iterator.
+ For-loops currently do not use this function to determine
+ how to iterate over something unknown, but that could be
+ a feature down the line.
+"""
as_iter :: #match -> Iterator {}
-//
-// Helper interface to test if something can be passed to
-// as_iter successfully.
+#doc """
+ Helper interface to test if something can be passed to
+ as_iter successfully.
+"""
Iterable :: interface (t: $T) {
{ as_iter(t) } -> Iterator;
}
-//
-// Helper function to get the next value out of an iterator.
+#doc "Helper function to get the next value out of an iterator."
next :: (it: Iterator) -> (it.Iter_Type, bool) {
return it.next(it.data);
}
-//
-// Helper function to close an iterator, if a close function
-// is defined.
+#doc """
+ Helper function to close an iterator, if a close function
+ is defined.
+"""
close :: (it: Iterator) {
if it.close != null_proc {
it.close(it.data);
// Most of these procedures come in two variants,
// one that takes a context paramter, and one that does not.
-//
-// Only yields the values for which the predicate is true.
+#doc "Only yields the values for which the predicate is true."
filter :: #match #local {}
#overload
fi => { close(fi.iterator); });
-//
-// Transforms every value that comes out of an iterator
-// using the transform function.
+#doc """
+ Transforms every value that comes out of an iterator
+ using the transform function.
+"""
map :: #match #local {}
#overload
mi => { close(mi.iterator); })
-//
-// Only yields the first `count` values, then closes.
+#doc "Only yields the first `count` values, then closes."
take :: (it: Iterator($T), count: u32) -> Iterator(T) {
return generator(
&.{ iterator = it, remaining = count },
}
-//
-// Yields values while the predicate returns true.
+#doc "Yields values while the predicate returns true."
take_while :: (it: Iterator($T), predicate: (T) -> bool) -> Iterator(T) {
return generator(
&.{ iterator = it, predicate = predicate },
}
-//
-// Discards the first `count` values and yields all remaining values,
+#doc "Discards the first `count` values and yields all remaining values."
skip :: (it: Iterator($T), count: u32) -> Iterator(T) {
return generator(
&.{ iterator = it, to_skip = count, skipped = false },
}
-//
-// Discards values while the predicate is true, then yields all values.
+#doc "Discards values while the predicate is true, then yields all values."
skip_while :: #match #local {}
#overload
}
-//
-// Combines two iterators into one by yielding a Pair of
-// the value from each of the iterators.
+#doc """
+ Combines two iterators into one by yielding a Pair of
+ the value from each of the iterators.
+"""
zip :: (left_iterator: Iterator($T), right_iterator: Iterator($R)) -> Iterator(Pair(T, R)) {
return generator(
&.{ left_iter = left_iterator, right_iter = right_iterator },
}
-//
-// Combines iterators by first yielding all values from
-// one, then yielding all values from the next, and so on.
+
+#doc """
+ Combines iterators by first yielding all values from
+ one, then yielding all values from the next, and so on.
+"""
concat :: (iters: ..Iterator($T)) -> Iterator(T) {
return generator(
&.{
});
}
-//
-// Yields the same value indefinitely. Useful with iter.zip.
+#doc "Yields the same value indefinitely. Useful with `iter.zip`."
const :: (value: $T) -> Iterator(T) {
return generator(&.{ v = value }, c => (c.v, true));
}
-//
-// Yields a value that contains: 1) the value from the iterator,
-// and 2) an incrementing integer.
+#doc """
+ Yields a value that contains:
+ 1) the value from the iterator,
+ 2) an incrementing integer.
+"""
enumerate :: #match #local {}
#overload
-//
-// Extract the next value out of an iterator. Closes it when
-// the iterator is out of values, if no_close is false.
+#doc """
+ Extract the next value out of an iterator. Closes it when
+ the iterator is out of values, if no_close is false.
+"""
take_one :: (it: Iterator($T), no_close := false) -> (T, bool) {
ret, cont := next(it);
if !cont && !no_close { close(it); }
return ret, cont;
}
-// Macro that allows you to extract elements from an iterator in a simple way:
-//
-// value: i32;
-// iterator: Iterator(i32) = ...;
-//
-// if #(value) << iterator {
-// ...iterater closed...
-// }
+#doc """
+ Macro that allows you to extract elements from an iterator in a simple way:
+
+ value: i32;
+ iterator: Iterator(i32) = ...;
+
+ if #(value) << iterator {
+ ...iterater closed...
+ }
+"""
#operator << macro (dest: Code, it: Iterator($T)) -> bool {
take_one :: take_one
#overload
as_iter :: from_array
-//
-// `from_array` has two almost identical implementations,
-// but the details are important here. Normally, `from_array`
-// returns an iterator by value, unless the array is of
-// structures, then it returns an iterator by pointer.
-// This seems weird, but in practice it is closer to what
-// you want, as you don't want to have to copy every structure
-// out of the array. While for primitives, you don't want to
-// dereference it everywhere.
+#doc """
+ `from_array` has two almost identical implementations,
+ but the details are important here. Normally, `from_array`
+ returns an iterator by value, unless the array is of
+ structures, then it returns an iterator by pointer.
+ This seems weird, but in practice it is closer to what
+ you want, as you don't want to have to copy every structure
+ out of the array. While for primitives, you don't want to
+ dereference it everywhere.
+"""
from_array :: #match #local {}
#overload
);
-//
-// Iterators created from pointers to dynamic arrays are
-// special, because they support the #remove directive.
+#doc """
+ Iterators created from pointers to dynamic arrays are
+ special, because they support the #remove directive.
+"""
#local
generic_dynamic_array_as_iter :: (x: &[..] $T, $access: Code, $return_type: type_expr) => {
Context :: struct (T: type_expr) {
// Iterator reducing
//
-//
-// Incremently calls `combine` on the yielded value and the
-// accumulated value, producing a new accumulated value. Returns
-// the final accumulated value.
+#doc """
+ Incremently calls `combine` on the yielded value and the
+ accumulated value, producing a new accumulated value. Returns
+ the final accumulated value.
+"""
fold :: #match #local {}
#overload
}
-//
-// Returns how many times the `cond` was true.
+#doc "Returns how many times the `cond` was true."
count :: #match #local {}
#overload
-//
-// Returns if `cond` returned true for *any* yielded value.
+#doc "Returns if `cond` returned true for *any* yielded value."
some :: #match #local {}
#overload
}
-//
-// Returns if `cond` returned true for *all* yielded values.
+#doc "Returns if `cond` returned true for *all* yielded values."
every :: #match #local {}
#overload
}
-//
-// Places all yielded values into a dynamically allocated array,
-// using the allocator provided (context.allocator by default).
+#doc """
+ Places all yielded values into a dynamically allocated array,
+ using the allocator provided (context.allocator by default).
+"""
to_array :: (it: Iterator($T), allocator := context.allocator) -> [..] T {
arr := array.make(T, allocator=allocator);
for v: it do array.push(&arr, v);
}
-//
-// Produces an iterator that first yields all values from the
-// first iterable, combined with the first yield value from the
-// second iterable. Then, steps the second iterable, and repeats.
-//
-// For example,
-//
-// iter.prod(1 .. 4, 1 .. 3)
-//
-// Would yield:
-// (1, 1), (2, 1), (3, 1), (1, 2), (2, 2), (3, 2)
+#doc """
+ Produces an iterator that first yields all values from the
+ first iterable, combined with the first yield value from the
+ second iterable. Then, steps the second iterable, and repeats.
+
+ For example,
+
+ iter.prod(1 .. 4, 1 .. 3)
+
+ Would yield:
+ (1, 1), (2, 1), (3, 1), (1, 2), (2, 2), (3, 2)
+"""
prod :: #match #local {}
#overload
}
-//
-// Simple iterator comprehensions, in the same vein
-// as Pythons comprehension syntax.
-//
-// Python:
-// results = [it * 2 for it in [1, 2, 3, 4, 5]]
-// Onyx:
-// results := iter.comp(u32.[1, 2, 3, 4, 5], #(it * 2));
+#doc """
+ Simple iterator comprehensions, in the same vein
+ as Pythons comprehension syntax.
+
+ Python:
+ results = [it * 2 for it in [1, 2, 3, 4, 5]]
+ Onyx:
+ results := iter.comp(u32.[1, 2, 3, 4, 5], #(it * 2));
+"""
comp :: #match #local {}
#overload
#this_package.comp(#this_package.as_iter(i), value);
-//
-// Using the polymorph solving system, you can write type
-// free versions of arbitrary iterators. This is used
-// heavily by many of the functions defined above.
-//
-// Maybe at some point an alternate allocator would be good
-// for this? For now, I think the temporary allocator is sufficient.
+#doc """
+ Using the polymorph solving system, you can write type
+ free versions of arbitrary iterators. This is used
+ heavily by many of the functions defined above.
+
+ Maybe at some point an alternate allocator would be good
+ for this? For now, I think the temporary allocator is sufficient.
+"""
generator :: #match #local {}
#overload
return .{c, #solidify next {T=it.Iter_Type}, #solidify close {T=it.Iter_Type}};
}
- //
- // Allows you to easily write a parallelized for-loop over an iterator.
- // For example,
- //
- // iter.parallel_for(1 .. 100, 4, &.{}) {
- // printf("Thread {} has {}!\n", context.thread_id, it);
- // }
- //
+ #doc """
+ Allows you to easily write a parallelized for-loop over an iterator.
+ For example,
+
+ iter.parallel_for(1 .. 100, 4, &.{}) {
+ printf("Thread {} has {}!\n", context.thread_id, it);
+ }
+ """
parallel_for :: #match #local {}
#overload
use core.intrinsics.onyx { __initialize }
#doc """
- Map is a generic hash-map implementation that uses chaining.
- Values can be of any type. Keys must of a type that supports
- the core.hash.hash, and the '==' operator.
+ Map is a generic hash-map implementation that uses chaining.
+ Values can be of any type. Keys must of a type that supports
+ the core.hash.hash, and the '==' operator.
"""
@conv.Custom_Format.{ #solidify format_map {K=Key_Type, V=Value_Type} }
Map :: struct (Key_Type: type_expr, Value_Type: type_expr) where ValidKey(Key_Type) {
return map;
}
-//
-// Initializes a map.
+#doc "Initializes a map."
init :: (use map: &Map($K, $V), default := V.{}) {
__initialize(map);
array.init(&entries, allocator=allocator);
}
-//
-// Allows for deletion of a Map using delete(&map).
+#doc "Allows for deletion of a Map using `delete(&map)`."
#match builtin.delete core.map.free
-//
-// Destroys a map and frees all memory.
+#doc """
+ Destroys a map and frees all memory.
+"""
free :: (use map: &Map) {
if hashes.data != null do memory.free_slice(&hashes, allocator=allocator);
if entries.data != null do array.free(&entries);
}
-//
-// Sets the value at the specified key, or creates a new entry
-// if the key was not already present.
+#doc """
+ Sets the value at the specified key, or creates a new entry
+ if the key was not already present.
+"""
put :: (use map: &Map, key: map.Key_Type, value: map.Value_Type) {
lr := lookup(map, key);
if full(map) do grow(map);
}
-//
-// Returns true if the map contains the key.
+#doc """
+ Returns true if the map contains the key.
+"""
has :: (use map: &Map, key: map.Key_Type) -> bool {
lr := lookup(map, key);
return lr.entry_index >= 0;
}
-//
-// Returns the value at the specified key, or map.default_value if
-// the key is not present.
-//
-// This is subject to change with the addition of Optional to the
-// standard library.
-//
+#doc """
+ Returns the value at the specified key, or map.default_value if
+ the key is not present.
+
+ This is subject to change with the addition of Optional to the
+ standard library.
+"""
get :: (use map: &Map, key: map.Key_Type) -> map.Value_Type {
lr := lookup(map, key);
if lr.entry_index >= 0 do return entries[lr.entry_index].value;
return default_value;
}
-//
-// Returns a pointer to the value at the specified key, or null if
-// the key is not present.
+#doc """
+ Returns a pointer to the value at the specified key, or null if
+ the key is not present.
+"""
get_ptr :: (use map: &Map, key: map.Key_Type) -> &map.Value_Type {
lr := lookup(map, key);
if lr.entry_index >= 0 do return &entries[lr.entry_index].value;
return null;
}
-//
-// Returns a pointer to the value at the specified key. If the key
-// is not in the map, a new value is created and inserted, then the
-// pointer to that value is returned.
+#doc """
+ Returns a pointer to the value at the specified key. If the key
+ is not in the map, a new value is created and inserted, then the
+ pointer to that value is returned.
+"""
get_ptr_or_create :: (use map: &Map, key: map.Key_Type) -> &map.Value_Type {
lr := lookup(map, key);
if lr.entry_index < 0 {
return &entries[lr.entry_index].value;
}
-//
-// Returns an Optional of the value at the specified key. The Optional
-// has a value if the key is present, otherwise the optional does not
-// have a value.
+#doc """
+ Returns an Optional of the value at the specified key. The Optional
+ has a value if the key is present, otherwise the optional does not
+ have a value.
+"""
get_opt :: (use map: &Map, key: map.Key_Type) -> ?map.Value_Type {
lr := lookup(map, key);
if lr.entry_index >= 0 do return Optional.make(entries[lr.entry_index].value);
return .{};
}
-//
-// Removes an entry from the map.
+#doc "Removes an entry from the map."
delete :: (use map: &Map, key: map.Key_Type) {
lr := lookup(map, key);
if lr.entry_index < 0 do return;
}
}
-//
-// Removes all entries from the hash map. Does NOT
-// modify memory, so be wary of dangling pointers!
+#doc """
+ Removes all entries from the hash map. Does NOT
+ modify memory, so be wary of dangling pointers!
+"""
clear :: (use map: &Map) {
for i: 0 .. hashes.count do hashes.data[i] = -1;
entries.count = 0;
}
-//
-// Returns if the map does not contain any elements.
+#doc "Returns if the map does not contain any elements."
empty :: (use map: &Map) -> bool {
return entries.count == 0;
}
-//
-// Helper procedure to nicely format a Map when printing.
-// Rarely ever called directly, instead used by conv.format_any.
+#doc """
+ Helper procedure to nicely format a Map when printing.
+ Rarely ever called directly, instead used by conv.format_any.
+"""
format_map :: (output: &conv.Format_Output, format: &conv.Format, x: &Map($K, $V)) {
if format.pretty_printing {
output->write("{\n");
}
}
-//
-// Quickly create a Map with some entries.
-//
-// Map.literal(str, i32, .[
-// .{ "test", 123 },
-// .{ "foo", 456 },
-// ]);
-//
+#doc """
+ Quickly create a Map with some entries.
+
+ Map.literal(str, i32, .[
+ .{ "test", 123 },
+ .{ "foo", 456 },
+ ]);
+"""
literal :: ($Key: type_expr, $Value: type_expr, values: [] MapLiteralValue(Key, Value)) => {
m := core.map.make(Key, Value);
for & values {
value: V;
}
-//
-// Produces an iterator that yields all values of the map,
-// in an unspecified order, as Map is unordered.
+#doc """
+ Produces an iterator that yields all values of the map,
+ in an unspecified order, as Map is unordered.
+"""
as_iter :: (m: &Map) =>
core.iter.generator(
&.{ m = m, i = 0 },