1use core::Core;
4use exception::INVALID_MEMORY_ADDRESS;
5use memory::{DataSpace, Memory};
6use std::f64::consts::PI;
7use std::mem;
8use {FALSE, TRUE};
9
10pub trait Float: Core {
11 fn add_float(&mut self) {
12 self.add_primitive("fconstant", Float::fconstant);
13 self.add_primitive("float+", Float::float_plus);
14 self.add_primitive("floats", Float::floats);
15 self.add_primitive("faligned", Float::faligned);
16 self.add_primitive("falign", Float::falign);
17 self.add_primitive("pi", Float::pi);
18 self.add_primitive("f!", Float::fstore);
19 self.add_primitive("f@", Float::ffetch);
20 self.add_primitive("fabs", Float::fabs);
21 self.add_primitive("fsin", Float::fsin);
22 self.add_primitive("fcos", Float::fcos);
23 self.add_primitive("ftan", Float::ftan);
24 self.add_primitive("fsincos", Float::fsincos);
25 self.add_primitive("fasin", Float::fasin);
26 self.add_primitive("facos", Float::facos);
27 self.add_primitive("fatan", Float::fatan);
28 self.add_primitive("fatan2", Float::fatan2);
29 self.add_primitive("fsqrt", Float::fsqrt);
30 self.add_primitive("fdrop", Float::fdrop);
31 self.add_primitive("fdup", Float::fdup);
32 self.add_primitive("fswap", Float::fswap);
33 self.add_primitive("fnip", Float::fnip);
34 self.add_primitive("fover", Float::fover);
35 self.add_primitive("frot", Float::frot);
36 self.add_primitive("fpick", Float::fpick);
37 self.add_primitive("s>f", Float::s_to_f);
38 self.add_primitive("f>s", Float::f_to_s);
39 self.add_primitive("f+", Float::fplus);
40 self.add_primitive("f-", Float::fminus);
41 self.add_primitive("f*", Float::fstar);
42 self.add_primitive("f/", Float::fslash);
43 self.add_primitive("f**", Float::fpowf);
44 self.add_primitive("f~", Float::fproximate);
45 self.add_primitive("f0<", Float::f_zero_less_than);
46 self.add_primitive("f0=", Float::f_zero_equals);
47 self.add_primitive("f<", Float::f_less_than);
48 self.add_primitive("fmin", Float::fmin);
49 self.add_primitive("fmax", Float::fmax);
50 self.add_primitive("floor", Float::floor);
51 self.add_primitive("fround", Float::fround);
52 self.add_primitive("fceil", Float::fceil);
53 self.add_primitive("fnegate", Float::fnegate);
54 }
55
56 fn p_fconst(&mut self) {
59 let wp = self.state().word_pointer();
60 let pos = DataSpace::aligned_f64(self.wordlist()[wp].dfa());
61 let v = unsafe { self.data_space().get_f64(pos) };
62 self.f_stack().push(v);
63 }
64
65 fn fconstant(&mut self) {
66 let v = self.f_stack().pop();
67 self.define(Float::p_fconst, Core::compile_fconst);
68 self.data_space().align_f64();
69 self.data_space().compile_f64(v);
70 }
71
72 fn float_plus(&mut self) {
76 let v = self.s_stack().pop();
77 self.s_stack().push(v + mem::size_of::<f64>() as isize);
78 }
79
80 fn floats(&mut self) {
84 let v = self.s_stack().pop();
85 self.s_stack().push(v * mem::size_of::<f64>() as isize);
86 }
87
88 fn faligned(&mut self) {
92 let pos = self.s_stack().pop();
93 let pos = DataSpace::aligned_f64(pos as usize);
94 self.s_stack().push(pos as isize);
95 }
96
97 fn falign(&mut self) {
101 self.data_space().align_f64();
102 }
103
104 fn pi(&mut self) {
105 self.f_stack().push(PI);
106 }
107
108 fn ffetch(&mut self) {
111 let t = DataSpace::aligned_f64(self.s_stack().pop() as usize);
112 if self.data_space().start() <= t && t < self.data_space().limit() {
115 let value = unsafe { self.data_space().get_f64(t) };
116 self.f_stack().push(value);
117 } else {
118 self.abort_with(INVALID_MEMORY_ADDRESS);
119 }
120 }
121
122 fn fstore(&mut self) {
123 let t = DataSpace::aligned_f64(self.s_stack().pop() as usize);
124 let n = self.f_stack().pop();
125 if self.data_space().start() <= t && t < self.data_space().limit() {
128 unsafe { self.data_space().put_f64(n, t) };
129 } else {
130 self.abort_with(INVALID_MEMORY_ADDRESS);
131 }
132 }
133
134 fn fabs(&mut self) {
135 let t = self.f_stack().pop();
136 self.f_stack().push(t.abs());
137 }
138
139 fn fsin(&mut self) {
140 let t = self.f_stack().pop();
141 self.f_stack().push(t.sin());
142 }
143
144 fn fcos(&mut self) {
145 let t = self.f_stack().pop();
146 self.f_stack().push(t.cos());
147 }
148
149 fn ftan(&mut self) {
150 let t = self.f_stack().pop();
151 self.f_stack().push(t.tan());
152 }
153
154 fn fsincos(&mut self) {
155 let t = self.f_stack().pop();
156 let (s, c) = t.sin_cos();
157 self.f_stack().push2(s, c);
158 }
159
160 fn fasin(&mut self) {
161 let t = self.f_stack().pop();
162 self.f_stack().push(t.asin());
163 }
164
165 fn facos(&mut self) {
166 let t = self.f_stack().pop();
167 self.f_stack().push(t.acos());
168 }
169
170 fn fatan(&mut self) {
171 let t = self.f_stack().pop();
172 self.f_stack().push(t.atan());
173 }
174
175 fn fatan2(&mut self) {
176 let t = self.f_stack().pop();
177 let n = self.f_stack().pop();
178 self.f_stack().push(n.atan2(t));
179 }
180
181 fn fsqrt(&mut self) {
182 let t = self.f_stack().pop();
183 self.f_stack().push(t.sqrt());
184 }
185
186 fn fswap(&mut self) {
187 let t = self.f_stack().pop();
188 let n = self.f_stack().pop();
189 self.f_stack().push2(t, n);
190 }
191
192 fn fnip(&mut self) {
193 let t = self.f_stack().pop();
194 let _ = self.f_stack().pop();
195 self.f_stack().push(t);
196 }
197
198 fn fdup(&mut self) {
199 let t = self.f_stack().pop();
200 self.f_stack().push2(t, t);
201 }
202
203 fn fdrop(&mut self) {
204 let _ = self.f_stack().pop();
205 }
206
207 fn frot(&mut self) {
208 let x3 = self.f_stack().pop();
209 let x2 = self.f_stack().pop();
210 let x1 = self.f_stack().pop();
211 self.f_stack().push3(x2, x3, x1);
212 }
213
214 fn fover(&mut self) {
215 let t = self.f_stack().pop();
216 let n = self.f_stack().pop();
217 self.f_stack().push3(n, t, n);
218 }
219
220 fn fpick(&mut self) {
224 let t = self.s_stack().pop() as u8;
225 let len = self.f_stack().len;
226 let x = self.f_stack()[len.wrapping_sub(t.wrapping_add(1))];
227 self.f_stack().push(x);
228 }
229
230 fn s_to_f(&mut self) {
231 let t = self.s_stack().pop();
232 self.f_stack().push(t as f64);
233 }
234
235 fn f_to_s(&mut self) {
236 let t = self.f_stack().pop();
237 self.s_stack().push(t as isize);
238 }
239
240 fn fplus(&mut self) {
241 let t = self.f_stack().pop();
242 let n = self.f_stack().pop();
243 self.f_stack().push(n + t);
244 }
245
246 fn fminus(&mut self) {
247 let t = self.f_stack().pop();
248 let n = self.f_stack().pop();
249 self.f_stack().push(n - t);
250 }
251
252 fn fstar(&mut self) {
253 let t = self.f_stack().pop();
254 let n = self.f_stack().pop();
255 self.f_stack().push(n * t);
256 }
257
258 fn fslash(&mut self) {
259 let t = self.f_stack().pop();
260 let n = self.f_stack().pop();
261 self.f_stack().push(n / t);
262 }
263
264 fn fpowf(&mut self) {
265 let t = self.f_stack().pop();
266 let n = self.f_stack().pop();
267 self.f_stack().push(n.powf(t));
268 }
269
270 fn fproximate(&mut self) {
271 let (x1, x2, x3) = self.f_stack().pop3();
272 if x3 > 0.0 {
273 self.s_stack()
274 .push(if (x1 - x2).abs() < x3 { TRUE } else { FALSE });
275 } else if x3 == 0.0 {
276 self.s_stack().push(if x1 == x2 { TRUE } else { FALSE });
277 } else {
278 self.s_stack()
279 .push(if (x1 - x2).abs() < (x3.abs() * (x1.abs() + x2.abs())) {
280 TRUE
281 } else {
282 FALSE
283 });
284 }
285 }
286
287 fn f_zero_less_than(&mut self) {
288 let t = self.f_stack().pop();
289 self.s_stack().push(if t < 0.0 { TRUE } else { FALSE });
290 }
291
292 fn f_zero_equals(&mut self) {
293 let t = self.f_stack().pop();
294 self.s_stack().push(if t == 0.0 { TRUE } else { FALSE });
295 }
296
297 fn f_less_than(&mut self) {
298 let t = self.f_stack().pop();
299 let n = self.f_stack().pop();
300 self.s_stack().push(if n < t { TRUE } else { FALSE });
301 }
302
303 fn fmin(&mut self) {
304 let (n, t) = self.f_stack().pop2();
305 self.f_stack().push(t.min(n));
306 }
307
308 fn fmax(&mut self) {
309 let (n, t) = self.f_stack().pop2();
310 self.f_stack().push(t.max(n));
311 }
312
313 fn fround(&mut self) {
314 let t = self.f_stack().pop();
315 self.f_stack().push(t.round());
316 }
317
318 fn floor(&mut self) {
319 let t = self.f_stack().pop();
320 self.f_stack().push(t.floor());
321 }
322
323 fn fceil(&mut self) {
324 let t = self.f_stack().pop();
325 self.f_stack().push(t.ceil());
326 }
327
328 fn fnegate(&mut self) {
329 let t = self.f_stack().pop();
330 self.f_stack().push(-t);
331 }
332}
333
334#[cfg(test)]
335mod tests {
336 use super::Float;
337 use core::Core;
338 use exception::Exception::UndefinedWord;
339 use mock_vm::VM;
340
341 #[test]
342 fn test_ans_forth_float() {
343 let vm = &mut VM::new();
344 vm.set_source("1E");
345 vm.evaluate_input();
346 assert_eq!(vm.f_stack().len(), 1);
347 assert_ulps_eq!(vm.f_stack().pop(), 1.0);
348 vm.set_source("1.E");
349 vm.evaluate_input();
350 assert_eq!(vm.f_stack().len(), 1);
351 assert_ulps_eq!(vm.f_stack().pop(), 1.0);
352 vm.set_source("1.E+");
353 vm.evaluate_input();
354 assert_eq!(vm.f_stack().len(), 1);
355 assert_ulps_eq!(vm.f_stack().pop(), 1.0);
356 vm.set_source("1.E-");
357 vm.evaluate_input();
358 assert_eq!(vm.f_stack().len(), 1);
359 assert_ulps_eq!(vm.f_stack().pop(), 1.0);
360 vm.set_source("1.E2");
361 vm.evaluate_input();
362 assert_eq!(vm.f_stack().len(), 1);
363 assert_ulps_eq!(vm.f_stack().pop(), 100.0);
364 vm.set_source("1.0E");
365 vm.evaluate_input();
366 assert_eq!(vm.f_stack().len(), 1);
367 assert_ulps_eq!(vm.f_stack().pop(), 1.0);
368 vm.set_source("-1E");
369 vm.evaluate_input();
370 assert_eq!(vm.f_stack().len(), 1);
371 assert_ulps_eq!(vm.f_stack().pop(), -1.0);
372 vm.set_source("1.23E");
373 vm.evaluate_input();
374 assert_eq!(vm.f_stack().len(), 1);
375 assert_ulps_eq!(vm.f_stack().pop(), 1.23);
376 vm.set_source("12.3E-2");
377 vm.evaluate_input();
378 assert_eq!(vm.f_stack().len(), 1);
379 assert_ulps_eq!(vm.f_stack().pop(), 0.123);
380 vm.set_source("-12.3E+2");
381 vm.evaluate_input();
382 assert_eq!(vm.f_stack().len(), 1);
383 assert_ulps_eq!(vm.f_stack().pop(), -1230.0);
384 vm.set_source(".3E");
385 vm.evaluate_input();
386 assert_eq!(vm.last_error(), Some(UndefinedWord));
387 assert_eq!(vm.f_stack().len(), 0);
388 }
389
390 #[test]
391 fn test_evaluate_f64() {
392 let vm = &mut VM::new();
393 vm.set_source("1.0E 2.5E");
394 vm.evaluate_input();
395 assert_eq!(vm.last_error(), None);
396 assert_eq!(vm.f_stack().len(), 2);
397 assert!(0.99999 < vm.f_stack().as_slice()[0]);
398 assert!(vm.f_stack().as_slice()[0] < 1.00001);
399 assert!(2.49999 < vm.f_stack().as_slice()[1]);
400 assert!(vm.f_stack().as_slice()[1] < 2.50001);
401 }
402
403 #[test]
404 fn test_fconstant() {
405 let vm = &mut VM::new();
406 vm.set_source("1.1E fconstant x x x");
407 vm.evaluate_input();
408 assert_eq!(vm.last_error(), None);
409 assert_eq!(vm.f_stack().as_slice(), [1.1, 1.1]);
410 }
411
412 #[test]
413 fn test_fstore_ffetch() {
414 let vm = &mut VM::new();
415 vm.set_source("3.3e here f! 0.0e here f@");
416 vm.evaluate_input();
417 assert_eq!(vm.last_error(), None);
418 assert_eq!(vm.f_stack().as_slice(), [0.0, 3.3]);
419 }
420
421 #[test]
422 fn test_fabs() {
423 let vm = &mut VM::new();
424 vm.set_source("-3.14E fabs");
425 vm.evaluate_input();
426 assert_eq!(vm.last_error(), None);
427 assert_eq!(vm.f_stack().len(), 1);
428 assert!(match vm.f_stack().pop() {
429 t => t > 3.13999 && t < 3.14001,
430 });
431 }
432
433 #[test]
434 fn test_fsin() {
435 let vm = &mut VM::new();
436 vm.set_source("3.14E fsin");
437 vm.evaluate_input();
438 assert_eq!(vm.last_error(), None);
439 assert_eq!(vm.f_stack().len(), 1);
440 assert!(match vm.f_stack().pop() {
441 t => t > 0.0015925 && t < 0.0015927,
442 });
443 }
444
445 #[test]
446 fn test_fcos() {
447 let vm = &mut VM::new();
448 vm.set_source("3.0E fcos");
449 vm.evaluate_input();
450 assert_eq!(vm.last_error(), None);
451 assert_eq!(vm.f_stack().len(), 1);
452 assert!(match vm.f_stack().pop() {
453 t => t > -0.989993 && t < -0.989991,
454 });
455 }
456
457 #[test]
458 fn test_ftan() {
459 let vm = &mut VM::new();
460 vm.set_source("3.0E ftan");
461 vm.evaluate_input();
462 assert_eq!(vm.last_error(), None);
463 assert_eq!(vm.f_stack().len(), 1);
464 assert!(match vm.f_stack().pop() {
465 t => t > -0.142547 && t < -0.142545,
466 });
467 }
468
469 #[test]
470 fn test_fasin() {
471 let vm = &mut VM::new();
472 vm.set_source("0.3E fasin");
473 vm.evaluate_input();
474 assert_eq!(vm.last_error(), None);
475 assert_eq!(vm.f_stack().len(), 1);
476 assert!(match vm.f_stack().pop() {
477 t => t > 0.304691 && t < 0.304693,
478 });
479 }
480
481 #[test]
482 fn test_facos() {
483 let vm = &mut VM::new();
484 vm.set_source("0.3E facos");
485 vm.evaluate_input();
486 assert_eq!(vm.last_error(), None);
487 assert_eq!(vm.f_stack().len(), 1);
488 assert!(match vm.f_stack().pop() {
489 t => t > 1.266102 && t < 1.266104,
490 });
491 }
492
493 #[test]
494 fn test_fatan() {
495 let vm = &mut VM::new();
496 vm.set_source("0.3E fatan");
497 vm.evaluate_input();
498 assert_eq!(vm.last_error(), None);
499 assert_eq!(vm.f_stack().len(), 1);
500 assert!(match vm.f_stack().pop() {
501 t => t > 0.291455 && t < 0.291457,
502 });
503 }
504
505 #[test]
506 fn test_fatan2() {
507 let vm = &mut VM::new();
508 vm.set_source("3.0E 4.0E fatan2");
509 vm.evaluate_input();
510 assert_eq!(vm.last_error(), None);
511 assert_eq!(vm.f_stack().len(), 1);
512 assert!(match vm.f_stack().pop() {
513 t => t > 0.643500 && t < 0.643502,
514 });
515 }
516
517 #[test]
518 fn test_fsqrt() {
519 let vm = &mut VM::new();
520 vm.set_source("0.3E fsqrt");
521 vm.evaluate_input();
522 assert_eq!(vm.last_error(), None);
523 assert_eq!(vm.f_stack().len(), 1);
524 assert!(match vm.f_stack().pop() {
525 t => t > 0.547721 && t < 0.547723,
526 });
527 }
528
529 #[test]
530 fn test_fdrop() {
531 let vm = &mut VM::new();
532 vm.f_stack().push(1.0);
533 vm.fdrop();
534 assert_eq!(vm.last_error(), None);
535 assert_eq!(vm.f_stack().as_slice(), []);
536 }
537
538 #[test]
539 fn test_fnip() {
540 let vm = &mut VM::new();
541 vm.f_stack().push2(1.0, 2.0);
542 vm.check_stacks();
543 match vm.last_error() {
544 Some(_) => assert!(true, "Floating point stack overflow"),
545 None => {}
546 };
547 vm.fnip();
548 assert_eq!(vm.last_error(), None);
549 assert_eq!(vm.f_stack().as_slice(), [2.0]);
550 }
551
552 #[test]
553 fn test_fswap() {
554 let vm = &mut VM::new();
555 vm.f_stack().push2(1.0, 2.0);
556 vm.check_stacks();
557 match vm.last_error() {
558 Some(_) => assert!(true, "Floating point stack overflow"),
559 None => {}
560 };
561 vm.fswap();
562 assert_eq!(vm.last_error(), None);
563 assert_eq!(vm.f_stack().as_slice(), [2.0, 1.0]);
564 }
565
566 #[test]
567 fn test_fdup() {
568 let vm = &mut VM::new();
569 vm.f_stack().push(1.0);
570 vm.fdup();
571 vm.check_stacks();
572 assert_eq!(vm.last_error(), None);
573 assert_eq!(vm.f_stack().as_slice(), [1.0, 1.0]);
574 }
575
576 #[test]
577 fn test_fover() {
578 let vm = &mut VM::new();
579 vm.f_stack().push2(1.0, 2.0);
580 vm.fover();
581 vm.check_stacks();
582 assert_eq!(vm.last_error(), None);
583 assert_eq!(vm.f_stack().as_slice(), [1.0, 2.0, 1.0]);
584 }
585
586 #[test]
587 fn test_frot() {
588 let vm = &mut VM::new();
589 vm.f_stack().push3(1.0, 2.0, 3.0);
590 vm.frot();
591 vm.check_stacks();
592 assert_eq!(vm.last_error(), None);
593 assert_eq!(vm.f_stack().as_slice(), [2.0, 3.0, 1.0]);
594 }
595
596 #[test]
597 fn test_fpick() {
598 let vm = &mut VM::new();
599 vm.f_stack().push(1.0);
600 vm.s_stack().push(0);
601 vm.fpick();
602 vm.check_stacks();
603 assert_eq!(vm.last_error(), None);
604 assert_eq!(vm.s_stack().as_slice(), []);
605 assert_eq!(vm.f_stack().as_slice(), [1.0, 1.0]);
606
607 let vm = &mut VM::new();
608 vm.f_stack().push(1.0);
609 vm.f_stack().push(0.0);
610 vm.s_stack().push(1);
611 vm.fpick();
612 vm.check_stacks();
613 assert_eq!(vm.last_error(), None);
614 assert_eq!(vm.s_stack().as_slice(), []);
615 assert_eq!(vm.f_stack().as_slice(), [1.0, 0.0, 1.0]);
616 }
617
618 #[test]
619 fn test_fplus_fminus_fstar_fslash() {
620 let vm = &mut VM::new();
621 vm.set_source("9.0e 10.0e f+ 11.0e f- 12.0e f* 13.0e f/");
622 vm.evaluate_input();
623 assert_eq!(vm.last_error(), None);
624 assert_eq!(vm.f_stack().len(), 1);
625 assert!(match vm.f_stack().pop() {
626 t => t > 7.384614 && t < 7.384616,
627 });
628 vm.check_stacks();
629 assert_eq!(vm.last_error(), None);
630 }
631
632 #[test]
633 fn test_f_zero_less_than() {
634 let vm = &mut VM::new();
635 vm.set_source("0.0e f0< 0.1e f0< -0.1e f0<");
636 vm.evaluate_input();
637 assert_eq!(vm.last_error(), None);
638 assert_eq!(vm.s_stack().len(), 3);
639 assert_eq!(vm.s_stack().pop(), -1);
640 assert_eq!(vm.s_stack().pop(), 0);
641 assert_eq!(vm.s_stack().pop(), 0);
642 assert_eq!(vm.f_stack().as_slice(), []);
643 vm.check_stacks();
644 assert_eq!(vm.last_error(), None);
645 }
646
647 #[test]
648 fn test_f_zero_equals() {
649 let vm = &mut VM::new();
650 vm.set_source("0.0e f0= 0.1e f0= -0.1e f0=");
651 vm.evaluate_input();
652 assert_eq!(vm.last_error(), None);
653 assert_eq!(vm.s_stack().len(), 3);
654 assert_eq!(vm.s_stack().pop(), 0);
655 assert_eq!(vm.s_stack().pop(), 0);
656 assert_eq!(vm.s_stack().pop(), -1);
657 assert_eq!(vm.f_stack().as_slice(), []);
658 vm.check_stacks();
659 assert_eq!(vm.last_error(), None);
660 }
661
662 #[test]
663 fn test_f_less_than() {
664 let vm = &mut VM::new();
665 vm.set_source("0.0e 0.0e f< 0.1e 0.0e f< -0.1e 0.0e f<");
666 vm.evaluate_input();
667 assert_eq!(vm.last_error(), None);
668 assert_eq!(vm.s_stack().len(), 3);
669 assert_eq!(vm.s_stack().pop(), -1);
670 assert_eq!(vm.s_stack().pop(), 0);
671 assert_eq!(vm.s_stack().pop(), 0);
672 assert_eq!(vm.f_stack().as_slice(), []);
673 vm.check_stacks();
674 assert_eq!(vm.last_error(), None);
675 }
676
677 #[test]
678 fn test_fproximate() {
679 let vm = &mut VM::new();
680 vm.set_source("0.1e 0.1e 0.0e f~ 0.1e 0.1000000001e 0.0e f~");
681 vm.evaluate_input();
682 assert_eq!(vm.last_error(), None);
683 assert_eq!(vm.s_stack().len(), 2);
684 assert_eq!(vm.s_stack().pop(), 0);
685 assert_eq!(vm.s_stack().pop(), -1);
686 assert_eq!(vm.f_stack().as_slice(), []);
687 vm.check_stacks();
688 assert_eq!(vm.last_error(), None);
689 vm.s_stack().reset();
690 vm.set_source("0.1e 0.1e 0.001e f~ 0.1e 0.109e 0.01e f~ 0.1e 0.111e 0.01e f~");
691 vm.evaluate_input();
692 assert_eq!(vm.last_error(), None);
693 assert_eq!(vm.s_stack().len(), 3);
694 assert_eq!(vm.s_stack().pop(), 0);
695 assert_eq!(vm.s_stack().pop(), -1);
696 assert_eq!(vm.s_stack().pop(), -1);
697 assert_eq!(vm.f_stack().as_slice(), []);
698 vm.check_stacks();
699 assert_eq!(vm.last_error(), None);
700 vm.s_stack().reset();
701 vm.set_source("0.1e 0.1e -0.001e f~ 0.1e 0.109e -0.1e f~ 0.1e 0.109e -0.01e f~");
702 vm.evaluate_input();
703 assert_eq!(vm.last_error(), None);
704 assert_eq!(vm.s_stack().len(), 3);
705 assert_eq!(vm.s_stack().pop(), 0);
706 assert_eq!(vm.s_stack().pop(), -1);
707 assert_eq!(vm.s_stack().pop(), -1);
708 assert_eq!(vm.f_stack().as_slice(), []);
709 vm.check_stacks();
710 assert_eq!(vm.last_error(), None);
711 vm.s_stack().reset();
712 }
713
714 #[test]
715 #[cfg(not(target_arch = "x86_64"))]
716 fn test_very_long_float() {
717 let vm = &mut VM::new();
718 vm.set_source("0.10000000000000001e");
719 vm.evaluate_input();
720 assert_eq!(vm.last_error(), Some(UndefinedWord));
721 }
722
723 #[test]
724 #[cfg(target_arch = "x86_64")]
725 fn test_very_long_float() {
726 let vm = &mut VM::new();
727 vm.set_source("0.10000000000000001e");
728 vm.evaluate_input();
729 assert_eq!(vm.last_error(), None);
730 }
731
732 #[test]
733 fn test_n_to_f() {
734 let vm = &mut VM::new();
735 vm.set_source("0 s>f -1 s>f 1 s>f");
736 vm.evaluate_input();
737 assert_eq!(vm.last_error(), None);
738 assert_eq!(vm.f_stack().as_slice(), [0.0, -1.0, 1.0]);
739 }
740
741 #[test]
742 fn test_f_to_n() {
743 let vm = &mut VM::new();
744 vm.set_source("0.0e f>s -1.0e f>s 1.0e f>s");
745 vm.evaluate_input();
746 assert_eq!(vm.last_error(), None);
747 assert_eq!(vm.s_stack().as_slice(), [0, -1, 1]);
748 }
749
750 #[test]
751 fn test_flit_and_compile_float() {
752 let vm = &mut VM::new();
753 vm.set_source(": test 1.0e 2.0e ; test");
754 vm.evaluate_input();
755 assert_eq!(vm.last_error(), None);
756 assert_eq!(vm.f_stack().as_slice(), [1.0, 2.0]);
757 }
758}