summaryrefslogtreecommitdiff
path: root/src/test/java/com/seaofnodes/simple/Chapter23Test.java
diff options
context:
space:
mode:
authorCliff Click <cliffc@acm.org>2025-05-06 13:44:10 -0700
committerCliff Click <cliffc@acm.org>2025-07-08 20:29:09 -0700
commit664761624f4b0e3d6d1593b99e576854beec5949 (patch)
treeedff0e36e07cdc5aa82c8f7d144d68c52d5a4365 /src/test/java/com/seaofnodes/simple/Chapter23Test.java
parent018379b0cf4e286ceacb1e39f34dd80f770e381e (diff)
downloadSimple-linear-chapter23.tar.gz
Simple-linear-chapter23.zip
Chapter 23: Methods and Revisiting Typeslinear-chapter23
Diffstat (limited to 'src/test/java/com/seaofnodes/simple/Chapter23Test.java')
-rw-r--r--src/test/java/com/seaofnodes/simple/Chapter23Test.java118
1 files changed, 118 insertions, 0 deletions
diff --git a/src/test/java/com/seaofnodes/simple/Chapter23Test.java b/src/test/java/com/seaofnodes/simple/Chapter23Test.java
new file mode 100644
index 00000000..20a506fb
--- /dev/null
+++ b/src/test/java/com/seaofnodes/simple/Chapter23Test.java
@@ -0,0 +1,118 @@
+package com.seaofnodes.simple;
+
+import com.seaofnodes.simple.codegen.CodeGen;
+import com.seaofnodes.simple.type.TypeInteger;
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import org.junit.Ignore;
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+public class Chapter23Test {
+
+ @Test
+ public void testJig() throws IOException {
+ //String src = Files.readString(Path.of("src/test/java/com/seaofnodes/simple/progs/jig.smp"));
+ String src = Files.readString(Path.of("docs/examples/BubbleSort.smp"));
+ testCPU(src,"x86_64_v2", "Win64" ,-1,null);
+ testCPU(src,"riscv" , "SystemV",-1,null);
+ testCPU(src,"arm" , "SystemV",-1,null);
+ }
+
+ static CodeGen testCPU( String src, String cpu, String os, int spills, String stop ) {
+ CodeGen code = new CodeGen(src).driver(CodeGen.Phase.Encoding,cpu,os);
+ int delta = spills>>3;
+ if( delta==0 ) delta = 1;
+ if( spills != -1 )
+ assertEquals("Expect spills:",spills,code._regAlloc._spillScaled,delta);
+ if( stop != null )
+ assertEquals(stop, code._stop.toString());
+ return code;
+ }
+
+ @Test
+ public void testFRefFields() {
+ String src =
+"""
+// A hypothetical scanner class
+struct Scan {
+ int !x;
+ u8[~] buf;
+ // Skip whitespace
+ val skip = { Scan s ->
+ while( s.buf[s.x] <= ' ' )
+ s.x++;
+ };
+ // Peek a character; if matched consume it, else false.
+ val peek = { Scan s, u8 c ->
+ skip(s);
+ if( s.buf[s.x] != c ) return false;
+ s.x++;
+ return true;
+ };
+};
+Scan !s = new Scan{ buf = " q"; };
+return Scan.peek(s,'q');
+ """;
+
+ CodeGen code = new CodeGen(src).parse().opto().typeCheck();
+ assertEquals("return Phi(Region,0,1);", code._stop.toString());
+ assertEquals("1", Eval2.eval(code, 0));
+ testCPU(src,"x86_64_v2", "Win64" ,17,null);
+ };
+
+ @Test
+ public void testFRefFields2() {
+ String src =
+"""
+// A hypothetical scanner class
+struct Scan {
+ int !x;
+ u8[~] buf;
+ // Skip whitespace
+ val skip = { ->
+ while( buf[x] <= ' ' )
+ x++;
+ return self;
+ };
+};
+val s = new Scan{ buf = " q"; };
+return s.skip().x;
+ """;
+
+ try { new CodeGen(src).parse().opto().typeCheck(); fail(); }
+ catch( Exception e ) { assertEquals("Argument #0 isa *Scan {i64 x; *[]u8 buf; { *Scan -> *Scan {i64 !x; *[]u8 buf; {21} skip; } #21} skip; }, but must be a *Scan {i64 !x; *[]u8 buf; ... }",e.getMessage()); }
+ };
+
+
+ @Test
+ public void testMethod() {
+ String src =
+"""
+// A hypothetical scanner class
+struct Scan {
+ int !x;
+ u8[~] buf;
+ // Skip whitespace
+ val skip = { ->
+ while( buf[x] <= ' ' )
+ x++;
+ };
+ val require = { u8 ch ->
+ skip();
+ buf[x++]==ch;
+ };
+};
+Scan !s = new Scan{ buf = " [1,2]"; };
+return s.require('[');
+ """;
+
+ CodeGen code = new CodeGen(src).parse().opto().typeCheck();
+ assertEquals("return (.[]==91);", code._stop.toString());
+ assertEquals("1", Eval2.eval(code, 0));
+ testCPU(src,"x86_64_v2", "Win64" ,16,null);
+ };
+
+
+}