lambda-calculus/number/prettyprint.c
2025-01-13 20:36:07 -06:00

154 lines
2.7 KiB
C

#include <assert.h>
#include <debug.h>
#include <string/new.h>
#include <string/free.h>
#include <stringtree/new.h>
#include <stringtree/append.h>
#include <stringtree/prepend.h>
#include <stringtree/free.h>
#include "struct.h"
#include "prettyprint.h"
static struct stringtree* prettyprint_mpn(
mpz_srcptr printme,
const wchar_t* digits)
{
ENTER;
struct stringtree* tree = new_stringtree();
mpz_t countdown, digit, ten;
mpz_init(digit);
mpz_init_set_ui(ten, 10);
mpz_init_set(countdown, printme);
assert(mpz_sgn(countdown) >= 0);
if (mpz_sgn(countdown) == 0)
{
stringtree_append_cstr(tree, L"0");
}
else while (mpz_sgn(countdown))
{
mpz_fdiv_qr(countdown, digit, countdown, ten);
wchar_t wc = digits[mpz_get_ui(digit)];
dpvwc(wc);
struct string* d = new_string(&wc, 1);
stringtree_prepend_string(tree, d);
free_string(d);
}
mpz_clear(countdown);
mpz_clear(digit);
mpz_clear(ten);
EXIT;
return tree;
}
struct stringtree* number_prettyprint(
struct number* this)
{
ENTER;
struct stringtree* tree = new_stringtree();
mpq_t clone;
mpq_init(clone);
mpq_set(clone, this->number);
if (mpq_sgn(clone) < 0)
{
stringtree_append_cstr(tree, L"-");
mpq_abs(clone, clone);
}
mpz_t whole;
mpz_init(whole);
mpz_fdiv_q(whole, mpq_numref(clone), mpq_denref(clone));
struct stringtree* whole_tree = prettyprint_mpn(whole, L"0123456789");
stringtree_append_stringtree(tree, whole_tree);
// subtract whole out of clone:
{
mpq_t tmp;
mpq_init(tmp);
mpq_set_z(tmp, whole);
mpq_sub(clone, clone, tmp);
mpq_clear(tmp);
}
// print decimal:
if (mpq_sgn(clone))
{
struct stringtree* num_tree = prettyprint_mpn(
mpq_numref(clone), L"⁰¹²³⁴⁵⁶⁷⁸⁹");
struct stringtree* den_tree = prettyprint_mpn(
mpq_denref(clone), L"₀₁₂₃₄₅₆₇₈₉");
// stringtree_append_cstr(tree, L" ");
stringtree_append_stringtree(tree, num_tree);
stringtree_append_cstr(tree, L"/");
stringtree_append_stringtree(tree, den_tree);
free_stringtree(num_tree);
free_stringtree(den_tree);
}
free_stringtree(whole_tree);
mpz_clear(whole);
mpq_clear(clone);
EXIT;
return tree;
}