diff options
Diffstat (limited to 'chapter22')
3 files changed, 22 insertions, 99 deletions
diff --git a/chapter22/src/main/java/com/seaofnodes/simple/Parser.java b/chapter22/src/main/java/com/seaofnodes/simple/Parser.java index d0ef5d49..23e9ddee 100644 --- a/chapter22/src/main/java/com/seaofnodes/simple/Parser.java +++ b/chapter22/src/main/java/com/seaofnodes/simple/Parser.java @@ -643,7 +643,7 @@ public class Parser { throw error("Cannot reassign final '"+name+"'"); // Lift expression, based on type - Node lift = liftExpr(expr.keep(), def.type(), def._final); + Node lift = liftExpr(expr.keep(), def.type(), def._final, true); // Update _scope.update(name,lift); // Return un-lifted expr @@ -652,7 +652,7 @@ public class Parser { // Make finals deep; widen ints to floats; narrow wide int types. // Early error if types do not match variable. - private Node liftExpr( Node expr, Type t, boolean xfinal ) { + private Node liftExpr( Node expr, Type t, boolean xfinal, boolean isLoad ) { if( expr._type instanceof TypeMemPtr tmp && tmp.isFRef() ) throw error("Must define forward ref "+tmp._obj._name); // Final is deep on ptrs @@ -660,16 +660,21 @@ public class Parser { t = tmp.makeRO(); expr = peep(new ReadOnlyNode(expr)); } - // Auto-widen array to i64 + // Auto-widen array to i64 (cast ptr to raw int bits) if( t == TypeInteger.BOT && expr._type instanceof TypeMemPtr tmp && tmp._obj.isAry() ) expr = peep(new AddNode(peep(new CastNode(t,ctrl(),expr)),con(tmp._obj.aryBase()))); // Auto-widen int to float expr = widenInt( expr, t ); - // Auto-narrow wide ints to narrow ints - expr = zsMask(expr,t); + // Auto-narrow wide ints to narrow ints. For loads, emit code to force + // the loaded value to match the declared sign/zero bits. For stores, + // just force the type, acting "as if" the store silently truncates. + Type et = expr._type; + if( isLoad ) { expr = zsMask(expr,t); et = expr._type; } + else if( et instanceof TypeInteger && t instanceof TypeInteger ) et=t; + // Type is sane - if( expr._type!=Type.BOTTOM && !expr._type.shallowISA(t) ) - throw error("Type " + expr._type.str() + " is not of declared type " + t.str()); + if( et!=Type.BOTTOM && !et.shallowISA(t) ) + throw error("Type " + et.str() + " is not of declared type " + t.str()); return expr; } @@ -758,7 +763,7 @@ public class Parser { } // Lift expression, based on type - Node lift = liftExpr(expr, t, xfinal); + Node lift = liftExpr(expr, t, xfinal, true); if( xfinal && t instanceof TypeMemPtr tmp ) t = tmp.makeRO(); @@ -1175,7 +1180,7 @@ public class Parser { }; // Convert to float ops, or narrow int types; error if not declared type. // Also, if postfix LHS is still keep() - return liftExpr(peep(op.widen()),t,false); + return liftExpr(peep(op.widen()),t,false,true); } @@ -1368,7 +1373,7 @@ public class Parser { // Disambiguate "obj.fld==x" boolean test from "obj.fld=x" field assignment if( matchOpx('=','=') ) { Node val = parseAsgn().keep(); - Node lift = liftExpr( val, tf, f._final ); + Node lift = liftExpr( val, tf, f._final, false ); Node st = new StoreNode(loc(), name, f._alias, tf, memAlias(f._alias), expr, off.unkeep(), lift, false); // Arrays include control, as a proxy for a safety range check. diff --git a/chapter22/src/test/java/com/seaofnodes/simple/Chapter22Test.java b/chapter22/src/test/java/com/seaofnodes/simple/Chapter22Test.java index 4823dff8..bfb20705 100644 --- a/chapter22/src/test/java/com/seaofnodes/simple/Chapter22Test.java +++ b/chapter22/src/test/java/com/seaofnodes/simple/Chapter22Test.java @@ -15,8 +15,8 @@ public class Chapter22Test { @Test @Ignore 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")); + 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); diff --git a/chapter22/src/test/java/com/seaofnodes/simple/progs/jig.smp b/chapter22/src/test/java/com/seaofnodes/simple/progs/jig.smp index 70f45717..fd3e7b9c 100644 --- a/chapter22/src/test/java/com/seaofnodes/simple/progs/jig.smp +++ b/chapter22/src/test/java/com/seaofnodes/simple/progs/jig.smp @@ -1,88 +1,6 @@ // -*- mode: java; -*- - -val _exit = { u8[~] msg -> - sys.io.p(msg); - sys.libc._exit(1); -}; -val usage = { -> _exit("stdin must look like [4, 3, 2, 1]"); }; - -// Scanner -struct Scan { - int !x; - u8[~] buf; -}; - -// Skip whitespace -val skip = { Scan s -> - while( s.buf[s.x] <= 32 ) - s.x++; -}; - -// Require specific syntax or usage -val require = { Scan s, u8 c -> - skip(s); - if( s.buf[s.x++] != c ) - usage(); -}; - -val peek = { Scan s, u8 c -> - skip(s); - if( s.buf[s.x] != c ) return false; - s.x++; - return true; -}; - -val number = { Scan s -> - skip(s); - i32 n = 0; - while( '0' <= s.buf[s.x] & s.buf[s.x] <= '9' ) - n = n*10 + (s.buf[s.x++] - '0'); - return n; -}; - - -// Read from stdin a line of the form "[ 4, 3, 2, 1]" and print it sorted. -val main = { -> - Scan !s = new Scan{ buf = sys.io.stdin(); }; - require(s,'['); - // Array of parsed results - int[] !ns = new int[16]; - i32 num = 0; - // Parse a list of numbers - if( !peek(s,']') ) { // Handle the empty list - // Parse "123, " until a something else - while( s.x < s.buf# ) { - int n = number(s); - i32 q=n; - ns[num++] = n; - if( !peek(s,',') ) - break; - }; - require(s,']'); // Close the list - } - - // Print a list of numbers - sys.io.p("[ "); - u8[] !buf = new u8[20]; - for( int i=0; i<num; i++ ) { - int x = ns[i]; - if( !x ) { sys.io.p("0, "); continue; } - - u32 log=0, q=x; - while( q>0 ) - { q/=10; log++; } - i32 raw=log; - sys.libc._exit(raw); - // for( int j=0, a=x; j<log; j++ ) { - // q = x/10; - // buf[log-j] = '0'+(x-q*10); - // x = q; - // } - // int raw = buf; - // sys.libc.write(1,raw,log); - // sys.io.p(", "); - } - sys.io.p("]"); - - return num; -}; +// Should fold away sign extend +struct Person { i8 age;}; +Person !p = new Person; +p.age = (arg<<48)>>48; +return 0; |
