2 * Copyright © 2017 Keith Packard <keithp@keithp.com>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
18 static void float_mark(void *addr)
23 static int float_size(void *addr)
27 return sizeof (struct ao_lisp_float);
30 static void float_move(void *addr)
35 const struct ao_lisp_type ao_lisp_float_type = {
43 ao_lisp_float_write(ao_poly p)
45 struct ao_lisp_float *f = ao_lisp_poly_float(p);
57 printf ("%g", f->value);
61 ao_lisp_poly_number(ao_poly p)
63 switch (ao_lisp_poly_base_type(p)) {
65 return ao_lisp_poly_int(p);
67 switch (ao_lisp_other_type(ao_lisp_poly_other(p))) {
69 return ao_lisp_bigint_int(ao_lisp_poly_bigint(p)->value);
71 return ao_lisp_poly_float(p)->value;
78 ao_lisp_float_get(float value)
80 struct ao_lisp_float *f;
82 f = ao_lisp_alloc(sizeof (struct ao_lisp_float));
83 f->type = AO_LISP_FLOAT;
85 return ao_lisp_float_poly(f);
89 ao_lisp_do_inexactp(struct ao_lisp_cons *cons)
91 if (!ao_lisp_check_argc(_ao_lisp_atom_led, cons, 1, 1))
93 if (ao_lisp_poly_type(ao_lisp_arg(cons, 0)) == AO_LISP_FLOAT)
94 return _ao_lisp_bool_true;
95 return _ao_lisp_bool_false;
99 ao_lisp_do_finitep(struct ao_lisp_cons *cons)
104 if (!ao_lisp_check_argc(_ao_lisp_atom_led, cons, 1, 1))
106 value = ao_lisp_arg(cons, 0);
107 switch (ao_lisp_poly_type(value)) {
110 return _ao_lisp_bool_true;
112 f = ao_lisp_poly_float(value)->value;
113 if (!isnan(f) && !isinf(f))
114 return _ao_lisp_bool_true;
116 return _ao_lisp_bool_false;
120 ao_lisp_do_infinitep(struct ao_lisp_cons *cons)
125 if (!ao_lisp_check_argc(_ao_lisp_atom_led, cons, 1, 1))
127 value = ao_lisp_arg(cons, 0);
128 switch (ao_lisp_poly_type(value)) {
130 f = ao_lisp_poly_float(value)->value;
132 return _ao_lisp_bool_true;
134 return _ao_lisp_bool_false;
138 ao_lisp_do_sqrt(struct ao_lisp_cons *cons)
142 if (!ao_lisp_check_argc(_ao_lisp_atom_sqrt, cons, 1, 1))
144 value = ao_lisp_arg(cons, 0);
145 if (!ao_lisp_number_typep(ao_lisp_poly_type(value)))
146 return ao_lisp_error(AO_LISP_INVALID, "%s: non-numeric", ao_lisp_poly_atom(_ao_lisp_atom_sqrt)->name);
147 return ao_lisp_float_get(sqrtf(ao_lisp_poly_number(value)));