From 1cb8279a64f4f79615ac8358927b11237df29bf2 Mon Sep 17 00:00:00 2001 From: Cliff Click Date: Wed, 12 Aug 2026 11:20:14 -0700 Subject: Real argc/argv args Beef up BubbleSort error handling --- .../java/com/seaofnodes/simple/Chapter25Test.java | 31 +++++++++++++++++++--- .../src/test/java/com/seaofnodes/simple/TestC.java | 26 +++++++++++++++++- 2 files changed, 52 insertions(+), 5 deletions(-) (limited to 'chapter25/src/test/java/com/seaofnodes') diff --git a/chapter25/src/test/java/com/seaofnodes/simple/Chapter25Test.java b/chapter25/src/test/java/com/seaofnodes/simple/Chapter25Test.java index 313ae1cf..8f1c7285 100644 --- a/chapter25/src/test/java/com/seaofnodes/simple/Chapter25Test.java +++ b/chapter25/src/test/java/com/seaofnodes/simple/Chapter25Test.java @@ -47,6 +47,13 @@ public class Chapter25Test { assertEquals("1",Eval2.eval(code,0)); } + @Test + public void testCharacterEscapes() { + CodeGen code = new CodeGen("return '\\n'==10 && '\\t'==9 && '\\r'==13;") + .driver(CodeGen.Phase.TypeCheck); + assertEquals("1",Eval2.eval(code,0)); + } + @Test @Ignore public void testModule0() throws IOException { @@ -243,7 +250,7 @@ public class Chapter25Test { String syms = run(new String[]{"nm",obj}); assertTrue(syms, syms.contains(" U sys.io.p_noInline")); - String out = run(new String[]{"gcc",obj,sys_file.toString(),"-lm","-g","-o",exe}); + String out = run(new String[]{"gcc",obj,sys_file.toString(),TestC.runtimeObject(),"-lm","-g","-o",exe}); assertEquals("",out); String rez = run(new String[]{exe}); assertEquals(expected,rez); @@ -278,9 +285,25 @@ return rez < buf# ? 0 : sys.libc._exit(-2); File sys_file = buildTestSys(false); assertTrue("Missing "+sys_file+"; testBubbles depends on testSys building it", sys_file.exists()); String src = Files.readString( Path.of("docs/examples/BubbleSort.smp")); - TestC.run(src,"BubbleSort",new Ary<>(new String[]{SYS_BLDDIR}), - TestC.CALL_CONVENTION, null, null, - "[3, 2,-17, 999 ] ", "[-17, 2, 3, 999]", -1); + TestC.runArgs(src,"BubbleSort",new Ary<>(new String[]{SYS_BLDDIR}), + TestC.CALL_CONVENTION,"-17, 2, 3, 999\n",-1, + "[3, 2,-17, 999 ]"); + + String obj = "build/objs/BubbleSort.o"; + String exe = "build/objs/BubbleSort"+(TestC.OS.startsWith("Windows") ? ".exe" : ""); + Ary libs = new Ary<>(new String[]{sys_file.toString()}); + assertEquals("1, 2, 3, 4, 4, 5\n", + TestC.gcc(obj,null,null,null,libs,exe,"[4, 5, 3, 1, 4, 2]")); + assertEquals("1, 2, 3, 4, 5\n", + TestC.gcc(obj,null,null,null,libs,exe,"[1, 2, 3, 4, 5]")); + assertEquals("1, 2, 3, 4, 5, 6, 7, 8, 9\n", + TestC.gcc(obj,null,null,null,libs,exe,"[9, 8, 7, 6, 5, 4, 3, 2, 1]")); + + String usage = "Usage: please provide a list of at least two integers to sort in the format \"[1, 2, 3, 4, 5]\"\n"; + assertEquals(usage,TestC.gcc(obj,null,null,null,libs,exe)); + assertEquals(usage,TestC.gcc(obj,null,null,null,libs,exe,"")); + assertEquals(usage,TestC.gcc(obj,null,null,null,libs,exe,"[1]")); + assertEquals(usage,TestC.gcc(obj,null,null,null,libs,exe,"[4 5 3]")); } } diff --git a/chapter25/src/test/java/com/seaofnodes/simple/TestC.java b/chapter25/src/test/java/com/seaofnodes/simple/TestC.java index 7177f765..2f737579 100644 --- a/chapter25/src/test/java/com/seaofnodes/simple/TestC.java +++ b/chapter25/src/test/java/com/seaofnodes/simple/TestC.java @@ -8,6 +8,7 @@ import com.seaofnodes.simple.util.Utils; import java.io.File; import java.io.IOException; import java.nio.file.Files; +import java.nio.file.Path; import java.util.concurrent.TimeUnit; import static org.junit.Assert.*; @@ -26,6 +27,12 @@ public abstract class TestC { public static final String CPU_ABI = CPU_PORT+"_"+CALL_CONVENTION; public static final String RELEASE_SYS_DIR = "build/release/"+CPU_ABI; + public static String runtimeObject() { + String home = System.getenv("SIMPLE_HOME"); + String root = home==null || home.isEmpty() ? "build/release" : home; + return Path.of(root,CPU_ABI,"simple_crt.o").toString(); + } + public static final String C_DRIVERS_DIR = "src/test/java/com/seaofnodes/simple/progs/"; /** @@ -80,7 +87,17 @@ public abstract class TestC { run(src, base, externPaths, simple_conv, c_conv, cfile, null, expected, spills); } + public static void runArgs( String src, String base, Ary externPaths, String simple_conv, + String expected, int spills, String... programArgs ) throws IOException { + run0(src,base,externPaths,simple_conv,null,null,null,expected,spills,programArgs); + } + public static void run( String src, String base, Ary externPaths, String simple_conv, String c_conv, String cfile, String stdin, String expected, int spills ) throws IOException { + run0(src,base,externPaths,simple_conv,c_conv,cfile,stdin,expected,spills,new String[0]); + } + + private static void run0( String src, String base, Ary externPaths, String simple_conv, String c_conv, + String cfile, String stdin, String expected, int spills, String[] programArgs ) throws IOException { // Simple file base-name example: // foo.smp -> // build/objs/foo.o - object file @@ -93,7 +110,10 @@ public abstract class TestC { CodeGen code = new CodeGen(null,"build/objs",externPaths,base,src,126L,TypeInteger.BOT); code.driver( CPU_PORT, simple_conv, false, cfile==null ); - String result = gcc(obj, c_conv, cfile, stdin, linkObjs(externPaths), exe ); + String[] execArgs = new String[programArgs.length+1]; + execArgs[0] = exe; + System.arraycopy(programArgs,0,execArgs,1,programArgs.length); + String result = gcc(obj, c_conv, cfile, stdin, linkObjs(externPaths), execArgs ); assertEquals(expected,result); // Allocation quality not degraded @@ -135,6 +155,10 @@ public abstract class TestC { params.add("gcc"); if( cfile!=null ) params.add(cfile); // Associated C driver, usually has a `main` params.add(obj); + // Standalone Simple programs export `simple_main`; the small C + // runtime owns the native main symbol and converts argc/argv into a + // normal Simple array before making the ABI-qualified call. + if( cfile==null ) params.add(runtimeObject()); if( linkObjs != null ) params.addAll(linkObjs.asAry()); params.addAll(new String[] { -- cgit v1.2.3