summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chapter22/src/main/java/com/seaofnodes/simple/Parser.java25
-rw-r--r--chapter22/src/test/java/com/seaofnodes/simple/Chapter22Test.java4
-rw-r--r--chapter22/src/test/java/com/seaofnodes/simple/progs/jig.smp92
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;