2022-09-29 18:44:55 +03:00
|
|
|
-- streams without memoization
|
|
|
|
|
2023-01-03 15:49:04 +03:00
|
|
|
type stream {
|
2022-09-29 18:44:55 +03:00
|
|
|
cons : integer -> (unit -> stream) -> stream;
|
|
|
|
}
|
|
|
|
|
2023-12-15 15:55:53 +03:00
|
|
|
function force(f : unit -> stream) : stream {
|
2022-09-29 18:44:55 +03:00
|
|
|
push unit;
|
2023-12-15 15:55:53 +03:00
|
|
|
push f;
|
2022-09-29 18:44:55 +03:00
|
|
|
tcall $ 1;
|
|
|
|
}
|
|
|
|
|
2023-12-15 15:55:53 +03:00
|
|
|
function filter(f : integer -> bool, s : unit -> stream, unit) : stream {
|
|
|
|
push s;
|
2022-09-29 18:44:55 +03:00
|
|
|
call force;
|
2023-12-15 15:55:53 +03:00
|
|
|
tsave s1 {
|
|
|
|
push s1.cons[0];
|
|
|
|
push f;
|
|
|
|
call $ 1;
|
|
|
|
br {
|
|
|
|
true: {
|
|
|
|
push s1.cons[1];
|
|
|
|
push f;
|
|
|
|
calloc filter 2;
|
|
|
|
push s1.cons[0];
|
|
|
|
alloc cons;
|
|
|
|
ret;
|
|
|
|
}
|
|
|
|
false: {
|
|
|
|
push unit;
|
|
|
|
push s1.cons[1];
|
|
|
|
push f;
|
|
|
|
tcall filter;
|
|
|
|
}
|
|
|
|
};
|
2022-09-29 18:44:55 +03:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2023-12-15 15:55:53 +03:00
|
|
|
function nth(n : integer, s : unit -> stream) : integer {
|
|
|
|
push s;
|
2022-09-29 18:44:55 +03:00
|
|
|
call force;
|
2023-12-15 15:55:53 +03:00
|
|
|
tsave s1 {
|
|
|
|
push n;
|
|
|
|
push 0;
|
|
|
|
eq;
|
|
|
|
br {
|
|
|
|
true: { push s1.cons[0]; ret; }
|
|
|
|
false: {
|
|
|
|
push s1.cons[1];
|
|
|
|
push 1;
|
|
|
|
push n;
|
|
|
|
sub;
|
|
|
|
tcall nth;
|
|
|
|
}
|
|
|
|
};
|
2022-09-29 18:44:55 +03:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2023-12-15 15:55:53 +03:00
|
|
|
function numbers(n : integer, unit) : stream {
|
|
|
|
push n;
|
2022-09-29 18:44:55 +03:00
|
|
|
push 1;
|
|
|
|
add;
|
|
|
|
calloc numbers 1;
|
2023-12-15 15:55:53 +03:00
|
|
|
push n;
|
2022-09-29 18:44:55 +03:00
|
|
|
alloc cons;
|
|
|
|
ret;
|
|
|
|
}
|
|
|
|
|
2023-12-15 15:55:53 +03:00
|
|
|
function indivisible(n : integer, m : integer) : bool {
|
|
|
|
push n;
|
|
|
|
push m;
|
2022-09-29 18:44:55 +03:00
|
|
|
mod;
|
|
|
|
push 0;
|
|
|
|
eq;
|
|
|
|
br {
|
|
|
|
true: { push false; ret; }
|
|
|
|
false: { push true; ret; }
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2023-12-15 15:55:53 +03:00
|
|
|
function eratostenes(s : unit -> stream, unit) : stream {
|
|
|
|
push s;
|
2022-09-29 18:44:55 +03:00
|
|
|
call force;
|
2023-12-15 15:55:53 +03:00
|
|
|
tsave s1 {
|
|
|
|
push s1.cons[1];
|
|
|
|
push s1.cons[0];
|
|
|
|
calloc indivisible 1;
|
|
|
|
calloc filter 2;
|
|
|
|
calloc eratostenes 1;
|
|
|
|
push s1.cons[0];
|
|
|
|
alloc cons;
|
|
|
|
ret;
|
|
|
|
};
|
2022-09-29 18:44:55 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
function primes() : unit -> stream {
|
|
|
|
push 2;
|
|
|
|
calloc numbers 1;
|
|
|
|
calloc eratostenes 1;
|
|
|
|
ret;
|
|
|
|
}
|
|
|
|
|
|
|
|
function main() {
|
|
|
|
call primes;
|
|
|
|
push 10;
|
|
|
|
call nth;
|
|
|
|
trace;
|
|
|
|
pop;
|
|
|
|
call primes;
|
|
|
|
push 50;
|
|
|
|
call nth;
|
|
|
|
trace;
|
|
|
|
pop;
|
|
|
|
push void;
|
|
|
|
ret;
|
|
|
|
}
|