summaryrefslogtreecommitdiff
path: root/chapter25/src/test/java/com
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2026-10-07 12:57:31 -0700
committerCliff Click <cliffc@acm.org>2026-10-07 12:57:31 -0700
commitaaec6f8136df6f7020bfc05f79ff5273adf73de1 (patch)
tree5df4aae069bd88dd09f45d957c85161e571b7a46 /chapter25/src/test/java/com
parent514b3147bf08817d17aacc492be255621209ec8b (diff)
downloadSimple-aaec6f8136df6f7020bfc05f79ff5273adf73de1.tar.gz
Simple-aaec6f8136df6f7020bfc05f79ff5273adf73de1.zip
flt->int conversion
Diffstat (limited to 'chapter25/src/test/java/com')
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter12Test.java4
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter14FloatTest.java19
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter17bTest.java4
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Chapter21Test.java21
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/Eval2.java2
-rw-r--r--chapter25/src/test/java/com/seaofnodes/simple/progs/floatToInteger.c25
6 files changed, 71 insertions, 4 deletions
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter12Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter12Test.java
index a71cc167..f1ff2e14 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter12Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter12Test.java
@@ -124,8 +124,8 @@ struct N { !N? !next; int i; };
n.i = 3.14;
return n.i;
""");
- try { code.parse().opto().typeCheck(); fail(); }
- catch( Exception e ) { assertEquals("Type 3.14 is not of declared type i64",e.getMessage()); }
+ code.parse().opto().typeCheck();
+ assertEquals("3",Eval2.eval(code,0));
}
@Test
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter14FloatTest.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter14FloatTest.java
index 20274581..80f70ff8 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter14FloatTest.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter14FloatTest.java
@@ -5,6 +5,25 @@ import org.junit.Test;
import static org.junit.Assert.assertEquals;
public class Chapter14FloatTest {
+ @Test public void testNumericAssignments() {
+ String[][] tests = {
+ {"int rounded=17.3/2.5; return rounded;", "6", "6"},
+ {"int rounded=arg/2.5; return rounded;", "6", "-6"},
+ {"int rounded=0; rounded=arg/2.5; return rounded;", "6", "-6"},
+ {"i8 rounded=arg*16.0; return rounded;", "16", "-16"},
+ {"int rounded=1e100; return rounded;", "9223372036854775807", "9223372036854775807"},
+ {"int rounded=-1e100; return rounded;", "-9223372036854775808", "-9223372036854775808"},
+ {"int rounded=1e300*1e300-1e300*1e300; return rounded;", "0", "0"},
+ {"f32 rounded=arg+16777216.0; return rounded;", "1.6777232E7", "1.6777199E7"}
+ };
+ for( String[] test : tests ) {
+ var code = new CodeGen(test[0]).parse().opto().typeCheck();
+ assertEquals(test[0],test[1],Eval2.eval(code,17));
+ assertEquals(test[0],test[2],Eval2.eval(code,-17));
+ }
+ }
+
+
@Test public void testSubZeroFloat() {
var code = new CodeGen("flt x = arg; return 0-x;").parse().opto().typeCheck();
// Compare strings so +0.0 and -0.0 remain distinct.
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter17bTest.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter17bTest.java
index ab1a59e1..62d0b261 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter17bTest.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter17bTest.java
@@ -123,8 +123,8 @@ return s.x;
@Test public void testInt10() {
CodeGen code = new CodeGen("flt x = 1.5; x++; int i = x; return i;");
- try { code.parse().opto().typeCheck(); fail(); }
- catch( Exception e ) { assertEquals("Type 2.5f is not of declared type i64",e.getMessage()); }
+ code.parse().opto().typeCheck();
+ assertEquals("2",Eval2.eval(code,0));
}
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter21Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter21Test.java
index 4d610a42..ba71d1dd 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter21Test.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter21Test.java
@@ -15,6 +15,27 @@ import static org.junit.Assert.*;
public class Chapter21Test {
+ @Test public void testFloatToInteger() throws IOException {
+ String src = "val float_to_int={ flt x -> int i=x; return i; };"+
+ "val float_to_u8={ flt x -> u8 i=x; return i; };";
+ TestC.runC(src,"floatToInteger","",-1);
+ for( double x : new double[]{0.0,-0.0,6.92,-6.92,255.75,-257.75,
+ 0x1p63,Math.nextDown(0x1p63),-0x1p63,Math.nextDown(-0x1p63),
+ Double.POSITIVE_INFINITY,Double.NEGATIVE_INFINITY,Double.NaN} ) {
+ for( String name : new String[]{"float_to_int","float_to_u8"} ) {
+ long expected = name.equals("float_to_u8") ? ((long)x)&255 : (long)x;
+ EvalRisc5 r = TestRisc5.build(src,name,0,-1,false);
+ r.fregs[riscv.FA0-riscv.F_OFFSET]=x;
+ assertEquals(0,r.step(1000));
+ assertEquals(name+"("+x+")",expected,r.regs[riscv.A0]);
+ EvalArm64 a = TestArm64.build(name,src,0,-1,false);
+ a.fregs[arm.D0-arm.D_OFFSET]=x;
+ assertEquals(0,a.step(1000));
+ assertEquals(name+"("+x+")",expected,a.regs[arm.X0]);
+ }
+ }
+ }
+
@Test public void testReadBeforeConditionalStore() {
var code = new CodeGen("""
struct S { int x; }; !S !a=new S; !S !b=new S;
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Eval2.java b/chapter25/src/test/java/com/seaofnodes/simple/Eval2.java
index 5716c1b8..21e677ce 100644
--- a/chapter25/src/test/java/com/seaofnodes/simple/Eval2.java
+++ b/chapter25/src/test/java/com/seaofnodes/simple/Eval2.java
@@ -307,6 +307,8 @@ public abstract class Eval2 {
case SubNode sub -> sub.mode()==1
? (Object)(x(sub.in(1)) - x(sub.in(2)))
: (Object)(d(sub.in(1)) - d(sub.in(2)));
+ case RoundF32Node rnd -> (double)(float)d(rnd.in(1));
+ case ToIntegerNode cvt -> (long)d(cvt.in(1));
case ToFloatNode toflt-> (double)x(toflt.in(1));
case XorNode xor -> x(xor.in(1)) ^ x(xor.in(2));
default -> throw Utils.TODO();
diff --git a/chapter25/src/test/java/com/seaofnodes/simple/progs/floatToInteger.c b/chapter25/src/test/java/com/seaofnodes/simple/progs/floatToInteger.c
new file mode 100644
index 00000000..cf9390d8
--- /dev/null
+++ b/chapter25/src/test/java/com/seaofnodes/simple/progs/floatToInteger.c
@@ -0,0 +1,25 @@
+#include <stdint.h>
+#include <math.h>
+#include <stdio.h>
+
+extern int64_t float_to_int(double);
+extern int64_t float_to_u8(double);
+
+int main(void) {
+ double values[] = {0.0,-0.0,6.92,-6.92,0.99,-0.99,255.75,-257.75,
+ 0x1p63,0x1.fffffffffffffp62,-0x1p63,-0x1.0000000000001p63,
+ INFINITY,-INFINITY,NAN,-NAN};
+ for( unsigned i=0; i<sizeof(values)/sizeof(values[0]); i++ ) {
+ double x=values[i];
+ int64_t expected=isnan(x) ? 0 : x>=0x1p63 ? INT64_MAX
+ : x<=-0x1p63 ? INT64_MIN : (int64_t)x;
+ int64_t actual=float_to_int(x), narrow=float_to_u8(x);
+ if( actual!=expected || narrow!=(expected&255) ) {
+ fprintf(stderr,"conversion of %g: got %lld / %lld, expected %lld / %lld\n",
+ x,(long long)actual,(long long)narrow,
+ (long long)expected,(long long)(expected&255));
+ return 1;
+ }
+ }
+ return 0;
+}