diff --git a/examples/is-prime.porth b/examples/is-prime.porth new file mode 100644 index 00000000..494541d5 --- /dev/null +++ b/examples/is-prime.porth @@ -0,0 +1,90 @@ +include "std.porth" + +// Probably need to add to standard library. +// It's useful to have such definition of true, instead of +// `macro true 1 end` +// because it will allow appropriate typechecking +macro true + 0 0 = +end + +macro false + 0 0 != +end + + +macro CHAR_CAPACITY 11 end +macro CHARS_PTR mem end +macro NUM_PTR CHARS_PTR CHAR_CAPACITY + end + +macro digits_to_number + CHARS_PTR swap while dup 1 > do + swap dup , // read char + '0' - + // dig bool + dup 0 >= over 10 < band if + NUM_PTR ,64 10 * + NUM_PTR swap .64 + 1 + swap 1 - + else + drop + 1 + swap dup - + end + end drop drop +end + +// returns number read from stdin +macro read_number + NUM_PTR 0 .64 + CHAR_CAPACITY CHARS_PTR stdin read + dup 0 <= if + "ERROR: could not read your name, sorry ( ._.)\n" stderr write drop + 1 exit + end + digits_to_number + NUM_PTR ,64 +end + +// expects number divisor +macro divisible + % 0 = +end + + +// expects number +macro is_prime + dup 2 = over + 3 = bor over + 5 = bor + if + drop true + else + dup 2 divisible over 3 divisible bor over 5 divisible bor if + drop false + else + true swap 5 while over over dup * >= do + over over divisible if + 2drop drop false 0 1 + else + 2 + + end + over over dup * >= if + over over divisible if + 2drop drop false 0 1 + else + 6 + + end + end + end drop drop + end + end +end + +"Enter number?\n" stdout write drop + +read_number + +is_prime + +if "It's prime\n" else "It's not a prime\n" end stdout write drop + +// This algorithm works with O(sqrt N) \ No newline at end of file