Skip to content

Commit

Permalink
...
Browse files Browse the repository at this point in the history
  • Loading branch information
tjjfvi committed Sep 24, 2024
1 parent 7f7bf6c commit 426f7ce
Show file tree
Hide file tree
Showing 6 changed files with 280 additions and 0 deletions.
4 changes: 4 additions & 0 deletions ivm/src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,8 @@ ext_fns! {
u32_add_high,
u32_mul_high,

u32_clz,

io_print_char,
io_print_byte,
io_flush,
Expand Down Expand Up @@ -234,6 +236,8 @@ impl ExtFnKind {
u32_add_high => ExtVal::new_u32((((a.as_u32() as u64) + (b.as_u32() as u64)) >> 32) as u32),
u32_mul_high => ExtVal::new_u32((((a.as_u32() as u64) * (b.as_u32() as u64)) >> 32) as u32),

u32_clz => ExtVal::new_u32(a.as_u32().leading_zeros()),

io_print_char => {
a.as_io();
print!("{}", char::try_from(b.as_u32()).unwrap());
Expand Down
25 changes: 25 additions & 0 deletions vine/examples/sort.vi
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@

use std::{
u32,
io::println,
rng, rng::gen_u32,
array::{Array, Array::{push, len, map, join, sort}},
};

const length = 100;
const max_val = 1000;

fn main(io) {
let rng = rng::default;
let nums = Array::empty;

Check warning on line 14 in vine/examples/sort.vi

View workflow job for this annotation

GitHub Actions / cspell

Unknown word (nums)
while nums.len() < length {

Check warning on line 15 in vine/examples/sort.vi

View workflow job for this annotation

GitHub Actions / cspell

Unknown word (nums)
nums.push(rng.gen_u32() % max_val);

Check warning on line 16 in vine/examples/sort.vi

View workflow job for this annotation

GitHub Actions / cspell

Unknown word (nums)
}
io.println("unsorted: " ++ show(nums));

Check warning on line 18 in vine/examples/sort.vi

View workflow job for this annotation

GitHub Actions / cspell

Unknown word (nums)
nums.sort();

Check warning on line 19 in vine/examples/sort.vi

View workflow job for this annotation

GitHub Actions / cspell

Unknown word (nums)
io.println("sorted: " ++ show(nums));
}

fn show(nums) {
nums.map(u32::to_string).join(", ")
}
119 changes: 119 additions & 0 deletions vine/std/array.vi
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@

mod sort_ = "./array/sort.vi";

mod Array {
use sort_::sort;

const empty = (0, _);

fn single(value) {
(1, value)
}

fn len((&len, &_)) {
len
}

fn push((&len, &vals), value) {

Check warning on line 17 in vine/std/array.vi

View workflow job for this annotation

GitHub Actions / cspell

Unknown word (vals)
if len {
let cap = calc_cap(len);
if len == cap {
cap = cap * 2;
vals = (vals, _);

Check warning on line 22 in vine/std/array.vi

View workflow job for this annotation

GitHub Actions / cspell

Unknown word (vals)

Check warning on line 22 in vine/std/array.vi

View workflow job for this annotation

GitHub Actions / cspell

Unknown word (vals)
}
let &slot = get_part(len, cap, &vals);

Check warning on line 24 in vine/std/array.vi

View workflow job for this annotation

GitHub Actions / cspell

Unknown word (vals)
slot = value;
len += 1;
} else {
len = 1;
vals = value;

Check warning on line 29 in vine/std/array.vi

View workflow job for this annotation

GitHub Actions / cspell

Unknown word (vals)
}
}

fn get((&len, &vals), i) {
get_part(i, calc_cap(len), vals)
}

fn get_part(i, cap, &vals) {
let half = cap / 2;
if half {
if i < half {
let (&left, &_) = &vals;
get_part(i, half, &left)
} else {
let (&_, &right) = &vals;
get_part(i - half, half, &right)
}
} else {
&vals
}
}

fn map(&move arr, f) {
let (len, vals) = arr;

if len { (len, map_part(len, calc_cap(len), vals, f)) } else { Array::empty }
}

fn map_part(len, cap, vals, f) {
let half = cap / 2;
if half {
let (left, right) = vals;
if len <= half {
(map_part(len, half, left, f), _)
} else {
(map_full(half, left, f), map_part(len - half, half, right, f))
}
} else {
f(vals)
}
}

fn map_full(len, vals, f) {
let half = len / 2;
if half {
let (left, right) = vals;
(map_full(half, left, f), map_full(half, right, f))
} else {
f(vals)
}
}

fn join(&move arr, sep) {
let (len, vals) = arr;

if len { join_part(len, calc_cap(len), vals, sep) } else { "" }
}

fn join_part(len, cap, vals, sep) {
let half = cap / 2;
if half {
let (left, right) = vals;
if len <= half {
join_part(len, half, left, sep)
} else {
join_full(half, left, sep)
++ sep
++ join_part(len - half, half, right, sep)
}
} else {
vals
}
}

fn join_full(len, vals, sep) {
let half = len / 2;
if half {
let (left, right) = vals;
join_full(half, left, sep)
++ sep
++ join_full(half, right, sep)
} else {
vals
}
}
}

fn calc_cap(len) {
1 << (32 - u32::leading_zeros(len - 1))
}
127 changes: 127 additions & 0 deletions vine/std/array/sort.vi
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@

fn sort((&len, &vals)) {
let cap = calc_cap(len);
sort_part(len, cap, &vals);
}

fn sort_part(len, cap, &vals) {
let half = cap / 2;
if half {
if len <= half {
let (&left, &_) = &vals;
sort_part(len, half, &left);
} else {
let (&left, &right) = &vals;
let jag = len - half;
sort_full(half, &left);
sort_part(jag, half, &right);
hump_part(jag, half, &left, &right);
stack_full(half, &left);
stack_part(jag, half, &right);
}
}
}

fn sort_full(cap, &vals) {
let half = cap / 2;
if half > 1 {
let (&left, &right) = &vals;
sort_full(half, &left);
sort_full(half, &right);
hump_full(half, &left, &right);
stack_full(half, &left);
stack_full(half, &right);
}
}

fn hump_part(len, cap, &a, &b) {
let half = cap / 2;
if half {
if len <= half {
let (&_, &ar) = &a;
let (&bl, &_) = &b;
hump_part(len, half, &ar, &bl)
} else {
let (&al, &ar) = &a;
let (&bl, &br) = &b;
hump_full(half, &ar, &bl);
hump_part(len - half, half, &al, &br);
}
} else {
cmp(&a, &b);
}
}

fn hump_full(cap, &a, &b) {
let half = cap / 2;
if half {
let (&al, &ar) = &a;
let (&bl, &br) = &b;
hump_full(half, &ar, &bl);
hump_full(half, &al, &br);
} else {
cmp(&a, &b);
}
}

fn stack_part(len, cap, &vals) {
let half = cap / 2;
if half {
if len <= half {
let (&left, &_) = &vals;
stack_part(len, half, &left);
} else {
let (&left, &right) = &vals;
let jag = len - half;
slide_part(jag, half, &left, &right);
stack_full(half, &left);
stack_part(jag, half, &right);
}
}
}

fn stack_full(cap, &vals) {
let half = cap / 2;
if half {
let (&left, &right) = &vals;
slide_full(half, &left, &right);
stack_full(half, &left);
stack_full(half, &right);
}
}

fn slide_part(len, cap, &a, &b) {
let half = cap / 2;
if half {
if len <= half {
let (&al, &_) = &a;
let (&bl, &_) = &b;
slide_part(len, half, &al, &bl)
} else {
let (&al, &ar) = &a;
let (&bl, &br) = &b;
slide_full(half, &al, &bl);
slide_part(len - half, half, &ar, &br);
}
} else {
cmp(&a, &b);
}
}

fn slide_full(cap, &a, &b) {
let half = cap / 2;
if half {
let (&al, &ar) = &a;
let (&bl, &br) = &b;
slide_full(half, &al, &bl);
slide_full(half, &ar, &br);
} else {
cmp(&a, &b);
}
}

fn cmp(&a, &b) {
if a > b {
(b, a) = (a, b)
}
}
1 change: 1 addition & 0 deletions vine/std/std.vi
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@

mod array = "./array.vi";
mod bool = "./bool.vi";
mod io = "./io.vi";
mod option = "./option.vi";
Expand Down
4 changes: 4 additions & 0 deletions vine/std/u32.vi
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,7 @@ inline_ivy! rotate_left {
inline_ivy! rotate_right {
fn(@u32_rotr(x y) fn(x y))
}

inline_ivy! leading_zeros {
fn(@u32_clz(0 x) x)
}

0 comments on commit 426f7ce

Please sign in to comment.