mirror of
https://github.com/Noratrieb/riverdelta.git
synced 2026-01-14 08:25:02 +01:00
123 lines
No EOL
2.7 KiB
Text
123 lines
No EOL
2.7 KiB
Text
function printlnI32(x: I32) = (
|
|
printI32(x);
|
|
print("\n");
|
|
);
|
|
|
|
function printlnInt(x: Int) = (
|
|
printInt(x);
|
|
print("\n");
|
|
);
|
|
|
|
function printI32(x: I32) = printInt(i32ToInt(x));
|
|
|
|
function printInt(x: Int) = (
|
|
let mag = log10(x);
|
|
|
|
loop (
|
|
if mag == 0 then break;
|
|
let base = pow(10, mag);
|
|
|
|
let digit = x / base;
|
|
print(stringForDigit(digit));
|
|
|
|
x = x % base;
|
|
mag = mag - 1;
|
|
);
|
|
|
|
print(stringForDigit(x % 10));
|
|
);
|
|
|
|
function stringForDigit(x: Int): String =
|
|
if x == 0 then "0"
|
|
else if x == 1 then "1"
|
|
else if x == 2 then "2"
|
|
else if x == 3 then "3"
|
|
else if x == 4 then "4"
|
|
else if x == 5 then "5"
|
|
else if x == 6 then "6"
|
|
else if x == 7 then "7"
|
|
else if x == 8 then "8"
|
|
else if x == 9 then "9"
|
|
else trap();
|
|
|
|
function log10(x: Int): Int = (
|
|
let i = 0;
|
|
loop (
|
|
if x < 10 then break;
|
|
i = i + 1;
|
|
x = x / 10;
|
|
);
|
|
i
|
|
);
|
|
|
|
function pow(base: Int, exp: Int): Int = (
|
|
let acc = 1;
|
|
loop (
|
|
if exp == 0 then break;
|
|
acc = acc * base;
|
|
exp = exp - 1;
|
|
);
|
|
acc
|
|
);
|
|
|
|
function println(s: String) = (
|
|
print(s);
|
|
print("\n");
|
|
);
|
|
|
|
mod rt (
|
|
// Start the heap at 1024. In practice this could probably be as low as we want.
|
|
global BASE_PTR: I32 = 1024_I32;
|
|
global HEAD_PTR: I32 = 1024_I32;
|
|
|
|
/*
|
|
Every struct has a header of an I32 as a refcount.
|
|
*/
|
|
|
|
// Allocate a new item. We do not deallocate anything yet.
|
|
// lol.
|
|
function allocateItem(objSize: I32, align: I32): I32 = (
|
|
if align < 4_I32 then std.abort("invalid alignment");
|
|
|
|
// Include the refcount header.
|
|
let actualSize = 4_I32 + objSize;
|
|
|
|
// Let's see whether we can fit the refcount into the align bits.
|
|
// I happen to know that everything will always be at least 4 bytes aligned.
|
|
let alignedPtr = std.alignUp(HEAD_PTR, align);
|
|
let actualObjPtr = if (alignedPtr - HEAD_PTR) > align then (
|
|
alignedPtr - 4_I32
|
|
) else (
|
|
// Take up the next spot.
|
|
alignedPtr + align - 4_I32
|
|
);
|
|
|
|
let newHeadPtr = actualObjPtr + actualSize;
|
|
|
|
if newHeadPtr > __memory_size() then (
|
|
// 16 pages, very arbitrary.
|
|
let result = __memory_grow(16_I32);
|
|
// If allocation failed we get -1. We don't have negative numbers yet, lol.
|
|
if result > 100000000_I32 then (
|
|
std.abort("failed to grow memory");
|
|
);
|
|
);
|
|
|
|
0_I32
|
|
);
|
|
);
|
|
|
|
function alignUp(x: I32, align: I32): I32 = (x + (align - 1_I32)) & !(align - 1_I32);
|
|
|
|
function i32ToInt(x: I32): Int = __i32_extend_to_i64_u(x);
|
|
|
|
function abort(message: String) = (
|
|
print("fatal error: ");
|
|
print(message);
|
|
println(".. aborting");
|
|
trap();
|
|
);
|
|
|
|
function main() = (
|
|
std.rt.allocateItem(100000000_I32, 8_I32);
|
|
); |