Merge tag 'upstream/0.2.1'
[debian/yforth] / double.c
1 /* yForth? - A Forth interpreter written in ANSI C
2  * Copyright (C) 2012 Luca Padovani
3  *
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 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  * ------------------------------------------------------------------------
17  * Module name:     double.c
18  * Abstract:        double-number word set
19  */
20
21 #include <stdio.h>
22 #include "yforth.h"
23 #include "core.h"
24 #include "double.h"
25
26 /**************************************************************************/
27 /* WORDS ******************************************************************/
28 /**************************************************************************/
29
30 void _two_constant() {
31         register DCell d = GET_DCELL(sp);
32         sp += 2;
33         create_definition(A_2CONSTANT);
34         compile_cell((Cell) d);
35         compile_cell((Cell) (d >> CellBits));
36         mark_word(_last);
37 }
38
39 void _two_literal() {
40         compile_cell((Cell) _do_literal);
41     compile_cell((Cell) sp[1]);
42         compile_cell((Cell) _do_literal);
43     compile_cell((Cell) sp[0]);
44         sp += 2;
45 }
46
47 void _two_variable() {
48         create_definition(A_2VARIABLE);
49         compile_cell(0);
50         compile_cell(0);
51         mark_word(_last);
52 }
53
54 void _d_plus() {
55         register DCell d1 = GET_DCELL(sp + 2);
56         register DCell d2 = GET_DCELL(sp);
57         d1 += d2;
58         sp += 2;
59         PUT_DCELL(sp, d1);
60 }
61
62 void _d_minus() {
63         register DCell d1 = GET_DCELL(sp + 2);
64         register DCell d2 = GET_DCELL(sp);
65         d1 -= d2;
66         sp += 2;
67         PUT_DCELL(sp, d1);
68 }
69
70 void _d_dot() {
71         register DCell u = GET_DCELL(sp);
72         register int usign = u < 0;
73         if (usign) u = -u;
74         PUT_DCELL(sp, u);
75         _less_number_sign();
76         _number_sign_s();
77         if (usign) {
78                 *--sp = '-';
79                 _hold();
80         }
81         _number_sign_greater();
82         _type();
83         putchar(' ');
84 }
85
86 void _d_dot_r() {
87         register Cell r = *sp++;
88         register DCell u = GET_DCELL(sp);
89         register int usign = u < 0;
90         if (usign && _base == 10) u = -u;
91         PUT_DCELL(sp, u);
92         _less_number_sign();
93         _number_sign_s();
94         if (usign) {
95                 *--sp = '-';
96                 _hold();
97         }
98         _number_sign_greater();
99         if (sp[0] < r) {
100                 sp--;
101                 sp[0] = r - sp[1];
102                 _spaces();
103         }
104         _type();
105         putchar(' ');
106 }
107
108 void _d_zero_less() {
109         register DCell d = GET_DCELL(sp);
110         sp++;
111         sp[0] = FFLAG(d < 0);
112 }
113
114 void _d_zero_equals() {
115         register DCell d = GET_DCELL(sp);
116         sp++;
117         sp[0] = FFLAG(d == 0);
118 }
119
120 void _d_two_star() {
121         register DCell d = GET_DCELL(sp);
122         d <<= 1;
123         PUT_DCELL(sp, d);
124 }
125
126 void _d_two_slash() {
127         register DCell d = GET_DCELL(sp);
128         d >>= 1;
129         PUT_DCELL(sp, d);
130 }
131
132 void _d_less_than() {
133         register DCell d1 = GET_DCELL(sp + 2);
134         register DCell d2 = GET_DCELL(sp);
135         sp += 3;
136         sp[0] = FFLAG(d1 < d2);
137 }
138
139 void _d_equals() {
140         register DCell d1 = GET_DCELL(sp + 2);
141         register DCell d2 = GET_DCELL(sp);
142         sp += 3;
143         sp[0] = FFLAG(d1 == d2);
144 }
145
146 void _dabs() {
147         register DCell d = GET_DCELL(sp);
148         d = d > 0 ? d : -d;
149         PUT_DCELL(sp, d);
150 }
151
152 void _dmax() {
153         register DCell d1 = GET_DCELL(sp + 2);
154         register DCell d2 = GET_DCELL(sp);
155         sp += 2;
156         if (d2 > d1) PUT_DCELL(sp, d2);
157 }
158
159 void _dmin() {
160         register DCell d1 = GET_DCELL(sp + 2);
161         register DCell d2 = GET_DCELL(sp);
162         sp += 2;
163         if (d2 < d1) PUT_DCELL(sp, d2);
164 }
165
166 void _dnegate() {
167         register DCell d = -GET_DCELL(sp);
168         PUT_DCELL(sp, d);
169 }
170
171 void _m_star_slash() {
172         register Cell n2 = *sp++;
173         register Cell n1 = *sp++;
174         register DCell d = GET_DCELL(sp);
175         d = (d * n1) / n2;
176         PUT_DCELL(sp, d);
177 }
178
179 void _m_plus() {
180         _s_to_d();
181         _d_plus();
182 }
183
184