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.
15 #include "ao_scheme.h"
18 static void float_mark(void *addr)
23 static int float_size(void *addr)
27 return sizeof (struct ao_scheme_float);
30 static void float_move(void *addr)
35 const struct ao_scheme_type ao_scheme_float_type = {
43 #define FLOAT_FORMAT "%g"
47 ao_scheme_float_write(ao_poly p)
49 struct ao_scheme_float *f = ao_scheme_poly_float(p);
61 printf (FLOAT_FORMAT, v);
65 ao_scheme_poly_number(ao_poly p)
67 switch (ao_scheme_poly_base_type(p)) {
69 return ao_scheme_poly_int(p);
71 switch (ao_scheme_other_type(ao_scheme_poly_other(p))) {
72 case AO_SCHEME_BIGINT:
73 return ao_scheme_bigint_int(ao_scheme_poly_bigint(p)->value);
75 return ao_scheme_poly_float(p)->value;
82 ao_scheme_float_get(float value)
84 struct ao_scheme_float *f;
86 f = ao_scheme_alloc(sizeof (struct ao_scheme_float));
87 f->type = AO_SCHEME_FLOAT;
89 return ao_scheme_float_poly(f);
93 ao_scheme_do_inexactp(struct ao_scheme_cons *cons)
95 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
97 if (ao_scheme_poly_type(ao_scheme_arg(cons, 0)) == AO_SCHEME_FLOAT)
98 return _ao_scheme_bool_true;
99 return _ao_scheme_bool_false;
103 ao_scheme_do_finitep(struct ao_scheme_cons *cons)
108 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
109 return AO_SCHEME_NIL;
110 value = ao_scheme_arg(cons, 0);
111 switch (ao_scheme_poly_type(value)) {
113 case AO_SCHEME_BIGINT:
114 return _ao_scheme_bool_true;
115 case AO_SCHEME_FLOAT:
116 f = ao_scheme_poly_float(value)->value;
117 if (!isnan(f) && !isinf(f))
118 return _ao_scheme_bool_true;
120 return _ao_scheme_bool_false;
124 ao_scheme_do_infinitep(struct ao_scheme_cons *cons)
129 if (!ao_scheme_check_argc(_ao_scheme_atom_led, cons, 1, 1))
130 return AO_SCHEME_NIL;
131 value = ao_scheme_arg(cons, 0);
132 switch (ao_scheme_poly_type(value)) {
133 case AO_SCHEME_FLOAT:
134 f = ao_scheme_poly_float(value)->value;
136 return _ao_scheme_bool_true;
138 return _ao_scheme_bool_false;
142 ao_scheme_do_sqrt(struct ao_scheme_cons *cons)
146 if (!ao_scheme_check_argc(_ao_scheme_atom_sqrt, cons, 1, 1))
147 return AO_SCHEME_NIL;
148 value = ao_scheme_arg(cons, 0);
149 if (!ao_scheme_number_typep(ao_scheme_poly_type(value)))
150 return ao_scheme_error(AO_SCHEME_INVALID, "%s: non-numeric", ao_scheme_poly_atom(_ao_scheme_atom_sqrt)->name);
151 return ao_scheme_float_get(sqrtf(ao_scheme_poly_number(value)));