// of the language. You will not make your own instance of the heap
// allocator, since it controls WASM intrinsics such as memory_grow.
-#load "core/memory"
#load "core/intrinsics/wasm"
use package core.intrinsics.wasm {
memory_size, memory_grow,
memory_copy,
}
+#private_file memory :: package core.memory
// The global heap state
#private_file
next : ^heap_block;
}
+// FIX: This does not respect the choice of alignment
#private_file
heap_alloc :: (size_: u32, align: u32) -> rawptr {
if size_ == 0 do return null;
size := size_ + sizeof heap_block;
- if size % align != 0 {
- size += align - (size % align);
- }
+ memory.align(~~^size, ~~align);
prev := ^heap_state.free_list;
hb := heap_state.free_list;
package core.alloc.log
+// FIXME: This should use context.logger instead of printf.
+
Allocation_Action_Strings := str.[
" alloc",
" free",
func = logging_allocator_proc,
data = alloc,
};
-}
\ No newline at end of file
+}
};
}
+#private_file Zipped :: struct (T: type_expr, R: type_expr) {
+ first: T;
+ second: R;
+}
+
+zip :: (left_iterator: Iterator($T), right_iterator: Iterator($R)) -> Iterator(Zipped(T, R)) {
+ ZippedIterator :: struct (T: type_expr, R: type_expr) {
+ iterator1: Iterator(T);
+ iterator2: Iterator(R);
+ }
+
+ zipped_iterator := new(#type ZippedIterator(T, R));
+ zipped_iterator.iterator1 = left_iterator;
+ zipped_iterator.iterator2 = right_iterator;
+
+ next :: ($T: type_expr, $R: type_expr, data: rawptr) -> (Zipped(T, R), bool) {
+ zi := cast(^ZippedIterator(T, R)) data;
+
+ v1, cont1 := zi.iterator1.next(zi.iterator1.data);
+ v2, cont2 := zi.iterator2.next(zi.iterator2.data);
+
+ return .{ v1, v2 }, cont1 && cont2;
+ }
+
+ close :: ($T: type_expr, $R: type_expr, data: rawptr) {
+ zi := cast(^ZippedIterator(T, R)) data;
+ zi.iterator1.close(zi.iterator1.data);
+ zi.iterator2.close(zi.iterator2.data);
+ cfree(data);
+ }
+
+ return .{
+ data = zipped_iterator,
+ next = #solidify next { T=T, R=R },
+ close = #solidify close { T=T, R=R },
+ };
+}
+
+const :: (value: $T) -> Iterator(T) {
+ next :: ($T: type_expr, data: rawptr) -> (T, bool) {
+ value := *(cast(^T) data);
+ return value, true;
+ }
+
+ allocated := cast(^T) calloc(sizeof T);
+ *allocated = value;
+
+ return .{
+ data = allocated,
+ next = #solidify next { T=T },
+ close = cfree,
+ };
+}
+
fold :: (it: Iterator($T), initial_value: R, combine: (T, $R) -> R) -> R {
for value: it {
initial_value = combine(value, initial_value);
count = count
};
}
+
+align :: proc {
+ (size: ^u64, align: u64) {
+ if *size % align != 0 {
+ *size += align - (*size % align);
+ }
+ },
+
+ (size: u64, align: u64) -> u64 {
+ if size % align != 0 {
+ size += align - (size % align);
+ }
+ return size;
+ }
+}
println("Test 2");
}
-[ ] Array literals used as default values for struct members can break things.
+[X] Array literals used as default values for struct members can break things.
Foo :: struct {
arr : [5] u32 = u32.[ 2, 3, 5, 7, 11 ];
};
-extern AstNode empty_node;
-
typedef enum EntityState {
Entity_State_Error,
#include "onyxparser.h"
#include "onyxutils.h"
-AstNode empty_node = { Ast_Kind_Error, 0, NULL, NULL };
-
static const char* ast_node_names[] = {
"ERROR",
"PACKAGE",
emit_deferred_stmts(mod, &code);
emit_leave_structured_block(mod, &code);
- // Flush deferred statements
-
local_raw_free(mod->local_alloc, WASM_TYPE_PTR);
local_raw_free(mod->local_alloc, WASM_TYPE_FUNC);
local_raw_free(mod->local_alloc, WASM_TYPE_FUNC);
.idx = 0,
};
// :ArbitraryConstant
+ // :WasmMemory
bh_table_put(WasmExport, module.exports, "memory", mem_export);
module.export_count++;
u8* leb = uint_to_uleb128((u64) 1, &leb_len);
bh_buffer_append(&vec_buff, leb, leb_len);
+ // FIXME: This needs to be dynamically chosen depending on the size of
+ // the data section and stack size pre-requeseted.
+ // :WasmMemory
output_limits(1024, -1, &vec_buff);
leb = uint_to_uleb128((u64) (vec_buff.length), &leb_len);
Closing the count iterator...
Closing the count iterator...
58
+
+Starting the zipped iteration...
+54 42.0000
+56 42.0000
+58 42.0000
+60 42.0000
+62 42.0000
+Closing the count iterator...
}
main :: (args: [] cstr) {
+ // Hopefully soon, the following will be possible.
+ // iterator := count_iterator(1, 10)
+ // |> iter.map(x => x * 2)
+ // |> iter.filter(x => x > 10)
+ // |> iter.map(x => x + 42)
+ // |> iter.take(5)
+ // |> iter.to_array();
iterator := count_iterator(1, 10)
|> iter.map((x: i32) -> i32 { return x * 2; })
|> iter.to_array();
println(arr[2]);
+
+ println("\nStarting the zipped iteration...");
+ zipped_iterator := count_iterator(1, 10)
+ |> iter.map((x: i32) -> i32 { return x * 2; })
+ |> iter.filter((x: i32) -> bool { return x > 10; })
+ |> iter.map((x: i32) -> i32 { return x + 42; })
+ |> iter.zip(iter.const(42.0f));
+
+ for value: zipped_iterator {
+ printf("%i %f\n", value.first, value.second);
+ }
}