Nightly build
--------------
+This release has some interesting new features and general usability improvements.
+It does have a couple rather LARGE syntax changes that will affect nearly every program
+written in Onyx. The two major syntax changes:
+
+ For loops:
+ for x in array instead of for x: array
+
+ Cases with captures:
+ case Value as capture instead of case capture: Value
+
+These syntax changes help improve readability and makes the language more friendly to newcomers.
+These changes also introduce two new keywords into the language that could see use in other places
+in the future. This is a small improvement to make, but it is better to make it now while a
+(relatively) small amount of Onyx code has been written.
+
Additions:
- OVM-Wasm support on MacOS (thanks to @judah-caruso).
- This enables debugging support when on MacOS.
- Available from installer.
+- `.*` as a postfix alternative to `*`.
- `where` clauses can contain arbitrary boolean expressions (thanks to @judah-caruso).
- Small arrays (4 or fewer elements) have special accessors for their components.
- Tree-shaking is performed prior to code generation, reducing binary size drastically in some cases.
- Operation overloads for `+`, `-` and `*` for small arrays.
+- `where defer` as a cleaner alternative to `where #bottom_test`
- `core.intrinsics.wasm.memory_equal`
- `core.iter.counter`
- `core.iter.sum`
Changes:
- Due to tree shaking, the `methods` member of `Type_Info_Struct` and `Type_Info_Union` is not populated by default anymore.
- Use the `--generate-method-info` CLI flag to add this information back in.
+- Due to `as` being a keyword now, `cptr.as` was renamed to `cptr.as_unsafe`.
Bugfixes:
- Error reporting in many cases saw a lot of improvements.
- - Specially with polymorphic procedures, l-values, and code blocks.
+ - Especially with polymorphic procedures, l-values, and code blocks.
- Implementation of `core.array.remove`.
-- Implementation
Contributors:
- @judah-caruso (10 pull requests)
- @magnetenstad (1 pull request)
- @jtakakura (1 pull request)
- @hatappo (1 pull request)
+- @Syuparn (1 pull request)
Release v0.1.8
TileData :: [TILE_DATA_WIDTH * TILE_DATA_HEIGHT] bool;
Tile :: struct {
- id : u32;
- orientation : TO;
- data : [] bool;
- edges : [] u32;
+ id : u32;
+ orientation : TO;
+ data : [] bool;
+ edges : [] u32;
- pos_x : u32 = 0;
- pos_y : u32 = 0;
+ pos_x : u32 = 0;
+ pos_y : u32 = 0;
edges_match : Sides = .{};
}
}
TO :: enum (u8) {
- N; R90; R180; R270;
- F; FR90; FR180; FR270;
+ N; R90; R180; R270;
+ F; FR90; FR180; FR270;
}
// TOT[t0][t1] = t1 * t0; t1 after t0
];
reverse_binary :: (n_: u32, digits := TILE_DATA_WIDTH) -> u32 {
- res := 0;
- n := n_;
- for _ in 0 .. digits {
- res <<= 1;
- res |= (n & 1);
- n >>= 1;
- }
-
- return res;
+ res := 0;
+ n := n_;
+ for _ in 0 .. digits {
+ res <<= 1;
+ res |= (n & 1);
+ n >>= 1;
+ }
+
+ return res;
}
build_edges :: (tile: [] bool, a := context.allocator) -> [] u32 {
- edges : [..] u32;
+ edges : [..] u32;
array.init(&edges, 8, allocator=a);
- for y in u32.[0, 9] {
- edge := 0;
- for x in 0 .. 10 {
- edge <<= 1;
- if tile[x + y * TILE_DATA_WIDTH] do edge |= 1;
- }
+ for y in u32.[0, 9] {
+ edge := 0;
+ for x in 0 .. 10 {
+ edge <<= 1;
+ if tile[x + y * TILE_DATA_WIDTH] do edge |= 1;
+ }
array.push(&edges, edge);
- }
+ }
- for x in u32.[0, 9] {
- edge := 0;
- for y in 0 .. 10 {
- edge <<= 1;
- if tile[x + y * TILE_DATA_WIDTH] do edge |= 1;
- }
+ for x in u32.[0, 9] {
+ edge := 0;
+ for y in 0 .. 10 {
+ edge <<= 1;
+ if tile[x + y * TILE_DATA_WIDTH] do edge |= 1;
+ }
array.push(&edges, edge);
- }
+ }
- for i in 0 .. 4 do array.push(&edges, reverse_binary(edges[i]));
+ for i in 0 .. 4 do array.push(&edges, reverse_binary(edges[i]));
- return edges.data[0 .. 8];
+ return edges.data[0 .. 8];
}
// These were not fun to think about by hand... But they make the
has_matching_edges :: (t1: &Tile, t2: &Tile) -> bool {
match := false;
- for e_idx in 0 .. t1.edges.count / 2 do for e2_idx in 0 .. t2.edges.count {
+ for e_idx in 0 .. t1.edges.count / 2 do for e2_idx in 0 .. t2.edges.count {
if t1.edges[e_idx] == t2.edges[e2_idx] {
match = true;
}
}
- return match;
+ return match;
}
// This assumes the `t` was in NORMAL orientation to begin with.
}
main :: (args: [] cstr) {
- contents := #file_contents "./input/day20.txt";
+ contents := #file_contents "./input/day20.txt";
- file := contents;
+ file := contents;
- tiles := array.make(Tile);
- defer array.free(&tiles);
+ tiles := array.make(Tile);
+ defer array.free(&tiles);
tile_map := map.make(u32, &Tile);
defer map.free(&tile_map);
- tile_data := cast(&TileData) calloc(200 * sizeof TileData);
- defer cfree(tile_data);
-
+ tile_data := make([] TileData, 200);
+ defer delete(&tile_data);
+
// This ring allocator could technically overflow and start
// allocating memory that isn't technically free, but there
// should be more than enough space in the allocator to not
// run into that problem... Hopefully.
- tile_data_ring := alloc.ring.make(.{ ~~ tile_data, 200 * sizeof TileData });
- tile_allocator := alloc.ring.make_allocator(&tile_data_ring);
+ tile_data_ring := alloc.ring.make(tile_data);
+ tile_allocator := alloc.ring.make_allocator(&tile_data_ring);
- while !string.empty(file) {
- string.advance(&file, 5); // 'Tile '
- id := cast(u32, conv.parse_int(&file));
+ while !string.empty(file) {
+ string.advance(&file, 5); // 'Tile '
+ id := cast(u32, conv.parse_int(&file));
- string.advance_line(&file);
+ string.advance_line(&file);
- td := cast([&] bool) raw_alloc(tile_allocator, sizeof TileData);
+ td := cast([&] bool) raw_alloc(tile_allocator, sizeof TileData);
- for y in 0 .. 10 {
- line, file~ := string.bisect(file, #char "\n");
+ for y in 0 .. 10 {
+ line, file~ := string.bisect(file, #char "\n");
- for x in 0 .. 10 {
- td[x + y * TILE_DATA_WIDTH] = (line[x] == #char "#");
- }
- }
+ for x in 0 .. 10 {
+ td[x + y * TILE_DATA_WIDTH] = (line[x] == #char "#");
+ }
+ }
- tile_data := td[0 .. TILE_DATA_HEIGHT * TILE_DATA_WIDTH];
- edges := build_edges(tile_data, tile_allocator);
+ tile_data := td[0 .. TILE_DATA_HEIGHT * TILE_DATA_WIDTH];
+ edges := build_edges(tile_data, tile_allocator);
- array.push(&tiles, .{
- id = id,
- orientation = TO.N,
- data = tile_data,
- edges = edges,
- });
+ array.push(&tiles, .{
+ id = id,
+ orientation = TO.N,
+ data = tile_data,
+ edges = edges,
+ });
- string.advance_line(&file);
- }
+ string.advance_line(&file);
+ }
for &t in tiles do map.put(&tile_map, t.id, t);
- prod: u64 = 1;
+ prod: u64 = 1;
top_left_id := 0;
- for i in 0 .. tiles.count - 1 {
- matching_count := 0;
+ for i in 0 .. tiles.count - 1 {
+ matching_count := 0;
- for j in 0 .. tiles.count {
- if i == j do continue;
- if has_matching_edges(&tiles[i], &tiles[j]) {
- matching_count += 1;
- }
- }
+ for j in 0 .. tiles.count {
+ if i == j do continue;
+ if has_matching_edges(&tiles[i], &tiles[j]) {
+ matching_count += 1;
+ }
+ }
- if matching_count == 2 {
- prod *= ~~tiles[i].id;
+ if matching_count == 2 {
+ prod *= ~~tiles[i].id;
// HACK!!!
if tiles[i].edges_match.top.tile != 0 && tiles[i].edges_match.right.tile != 0 {
if top_left_id == 0 do top_left_id = tiles[i].id;
}
}
- }
+ }
- printf("Corner product: {}\n", prod);
+ printf("Corner product: {}\n", prod);
grid : [12 * 12] u32;
memory.set(&grid, 0, sizeof [12 * 12] u32);