summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--chapter23/src/test/java/com/seaofnodes/simple/Chapter11Test.java2
-rw-r--r--chapter24/src/main/java/com/seaofnodes/simple/Parser.java159
-rw-r--r--chapter24/src/test/java/com/seaofnodes/simple/Chapter11Test.java287
-rw-r--r--chapter24/src/test/java/com/seaofnodes/simple/Chapter24Test.java133
-rw-r--r--chapter24/src/test/java/com/seaofnodes/simple/progs/stacked_r_3.smp2
5 files changed, 133 insertions, 450 deletions
diff --git a/chapter23/src/test/java/com/seaofnodes/simple/Chapter11Test.java b/chapter23/src/test/java/com/seaofnodes/simple/Chapter11Test.java
index f6539ac4..4f70913d 100644
--- a/chapter23/src/test/java/com/seaofnodes/simple/Chapter11Test.java
+++ b/chapter23/src/test/java/com/seaofnodes/simple/Chapter11Test.java
@@ -20,7 +20,7 @@ while(---- -arg) {
}
}
{
- int kzEl_r7EYz=3*----0!=-arg<(37*--97!=0/arg==arg)<=-(--arg!=0);
+ int kzEl_r7EYz = (3*----0!=-arg) < (37*--97!=0/arg==arg) <= -(--arg!=0);
while(kzEl_r7EYz<---1) {
kzEl_r7EYz=kzEl_r7EYz+kzEl_r7EYz*arg>=24;
if(7) continue;
diff --git a/chapter24/src/main/java/com/seaofnodes/simple/Parser.java b/chapter24/src/main/java/com/seaofnodes/simple/Parser.java
index 95d178f0..43908685 100644
--- a/chapter24/src/main/java/com/seaofnodes/simple/Parser.java
+++ b/chapter24/src/main/java/com/seaofnodes/simple/Parser.java
@@ -533,47 +533,6 @@ public class Parser {
return parseTrinary(pred,"else");
}
- /**
- * Handles a conditional expression needed for chaining operators.
- * a < x < b the bounded var is x here</>
- * @return a {@link Node}, never {@code null}
- */
- private Node make_and_conditional(Node lhs, Node ext,boolean swap, Node bounded_var) {
- lhs.keep();
- ext.keep();
-
- Node ifNode = new IfNode(ctrl(), lhs).peephole();
-
- Node ifT = new CProjNode(ifNode. keep(), 0, "True" ).peephole().keep();
- Node ifF = new CProjNode(ifNode.unkeep(), 1, "False").peephole().keep();
-
- ScopeNode fScope = _scope.dup();
-
- // true
- ctrl(ifT.unkeep());
- _scope.addGuards(ifT,lhs,false);
- Node rhs = parseShift();
- _scope.removeGuards(ifT);
- fScope.balanceIf(_scope);
- ScopeNode tScope = _scope;
- _scope = fScope;
- ctrl(ifF.unkeep());
- _scope.addGuards(ifF,lhs,true);
- _scope.removeGuards(ifF);
-
- _scope = tScope;
- tScope.balanceIf(fScope);
- ext.setDef(swap ? 2: 1, bounded_var);
- ext.setDef(swap ? 1 :2, rhs);
- ext.peephole();
-
- RegionNode r = ctrl(tScope.mergeScopes(fScope, loc()));
- Node ret = peep(new PhiNode("",ext._type.meet(lhs._type).glb(false),r,ext.unkeep(),lhs.unkeep()));
-
- r.peephole();
- return ret;
- }
-
// Parse a conditional expression, merging results.
private Node parseTrinary( Node pred, String fside ) {
// IfNode takes current control and predicate
@@ -1072,86 +1031,98 @@ public class Parser {
}
private Node parseBitwise() {
- Node lhs = parseComparison();
+ Node lhs = parseEquality();
while( true ) {
if( false ) ;
else if( matchOp('&') ) lhs = new AndNode(loc(),lhs,null);
else if( matchOp('|') ) lhs = new OrNode(loc(),lhs,null);
else if( match ("^") ) lhs = new XorNode(loc(),lhs,null);
else break;
- lhs.setDef(2,parseComparison());
+ lhs.setDef(2,parseEquality());
lhs = peep(lhs);
}
return lhs;
}
+
+
+ /**
+ * Parse an eq/ne expression
+ */
+ private Node parseEquality() {
+ Node lhs = parseComparison();
+ while( true ) {
+ boolean eq = false;
+ if( match("==") ) eq = true;
+ else if( !match("!=") ) break;
+ lhs = peep(new BoolNode.EQ(lhs,parseComparison()));
+ if( !eq ) lhs = peep(new NotNode(lhs));
+ }
+ return lhs;
+ }
+
/**
* Parse an expression of the form:
*
* <pre>
- * expr : additiveExpr op additiveExpr
+ * expr : shiftExpr < shiftExpr <= shiftExpr...
+ * expr : shiftExpr > shiftExpr >= shiftExpr...
* </pre>
* @return an comparator expression {@link Node}, never {@code null}
*/
private Node parseComparison() {
- var lhs = parseShift();
- Node bound_var = null;
- boolean found_bl = false;
+ Node lhs = parseShift();
+ int dir = 0;
while( true ) {
- int idx=0; boolean negate=false;
- // Test for any local nodes made, and "keep" lhs during peepholes
- // chain operators
+ int dir0;
if( false ) ;
- else if( match("==") ) {
- if(found_bl) {
- return make_and_conditional(lhs, new BoolNode.EQ(null, null), false, bound_var);
- }
- idx=2; lhs = new BoolNode.EQ(lhs, null);
- }
- else if( match("!=") ) {
- if(found_bl) {
- return make_and_conditional(lhs, peep(new NotNode(new BoolNode.EQ(null, null))), false, bound_var);
- }
- idx=2; lhs = new BoolNode.EQ(lhs, null); negate=true;
- }
- else if( match("<=") ) {
- if(found_bl) {
- return make_and_conditional(lhs, new BoolNode.LE(null, null), false, bound_var);
- }
- idx=2; lhs = new BoolNode.LE(lhs, null);
- }
- else if( match("<" ) ) {
- if(found_bl) {
- return make_and_conditional(lhs, new BoolNode.LT(null, null), false, bound_var);
- }
- idx=2; lhs = new BoolNode.LT(lhs, null);
- }
- else if( match(">=") ) {
- if(found_bl) {
- return make_and_conditional(lhs, new BoolNode.LE(null, null), true, bound_var);
- }
- idx=1; lhs = new BoolNode.LE(null, lhs);
- }
- else if( match(">" ) ) {
- if(found_bl) {
- return make_and_conditional(lhs, new BoolNode.LT(null, null), true, bound_var);
- }
- idx=1; lhs = new BoolNode.LT(null, lhs);
- }
+ else if( match("<=" ) ) dir0 = -1;
+ else if( match(">=" ) ) dir0 = -2;
+ else if( match("<" ) ) dir0 = 1;
+ else if( match(">" ) ) dir0 = 2;
else break;
- // Peepholes can fire, but lhs is already "hooked", kept alive
- lhs.setDef(idx,parseShift());
- found_bl = true;
- bound_var = lhs.in(idx);
- lhs = peep(lhs.widen());
- if( negate ) // Extra negate for !=
- lhs = peep(new NotNode(lhs));
+ // Check and record direction
+ if( dir==0 ) {
+ dir = Math.abs(dir0);
+ Node rhs = parseShift();
+ lhs = makeCompBool(dir0,lhs,rhs); // Convert to a bool
+ } else if( dir == Math.abs(dir0) ) {
+ // e0 < lhs < ???
+ lhs.keep();
+ Node ifNode = new IfNode(ctrl(), lhs).peephole();
+ Node ifT = new CProjNode(ifNode. keep(), 0, "True" ).peephole();
+ Node ifF = new CProjNode(ifNode.unkeep(), 1, "False").peephole();
+ // False side does nothing
+ ScopeNode fScope = _scope.dup();
+ fScope.ctrl(ifF);
+ // True side executes next part of range
+ ctrl(ifT);
+ _scope.addGuards(ifT,lhs,false);
+ Node rhs = parseShift();
+ _scope.removeGuards(ifT); // TODO: I think should remain true as long as possible
+ Node next = makeCompBool(dir0, lhs, rhs).keep();
+ // Merge result
+ RegionNode r = ctrl(_scope.mergeScopes(fScope, loc()));
+ assert next._type.meet(lhs._type).isa( TypeInteger.BOOL );
+ lhs = peep(new PhiNode("",TypeInteger.BOOL,r,next.unkeep(),lhs.unkeep()));
+ r.peephole();
+ } else {
+ throw error("Mixing relational directions in a chained relational test");
+ }
}
- found_bl = false;
return lhs;
}
+ private Node makeCompBool( int dir0, Node lhs, Node rhs ) {
+ // Convert to a bool
+ if( Math.abs(dir0)==2 ) // Swap direction
+ { Node tmp = lhs; lhs = rhs; rhs = tmp; }
+ lhs = peep(dir0 < 0 ? new BoolNode.LE(lhs,rhs) : new BoolNode.LT(lhs,rhs));
+ return peep(lhs.widen());
+ }
+
+
/**
* Parse an additive expression
*
diff --git a/chapter24/src/test/java/com/seaofnodes/simple/Chapter11Test.java b/chapter24/src/test/java/com/seaofnodes/simple/Chapter11Test.java
index f6539ac4..99aa9579 100644
--- a/chapter24/src/test/java/com/seaofnodes/simple/Chapter11Test.java
+++ b/chapter24/src/test/java/com/seaofnodes/simple/Chapter11Test.java
@@ -6,293 +6,6 @@ import static org.junit.Assert.assertEquals;
public class Chapter11Test {
- // A placeholder test used to rapidly rotate through fuzzer produced issues
- @Test
- public void testFuzzer() {
- CodeGen code = new CodeGen(
-"""
-while(---- -arg) {
- while(-arg) {
- while(-----arg*---0) {
- int N=--false==false<--arg;
- while(N<-4==N) {
- N=N+N;
- }
- }
- {
- int kzEl_r7EYz=3*----0!=-arg<(37*--97!=0/arg==arg)<=-(--arg!=0);
- while(kzEl_r7EYz<---1) {
- kzEl_r7EYz=kzEl_r7EYz+kzEl_r7EYz*arg>=24;
- if(7) continue;
- kzEl_r7EYz=false;
- if(-kzEl_r7EYz+arg<-3) continue;
- else {
- while(kzEl_r7EYz) continue;
- arg=----3;
- kzEl_r7EYz=-(-----arg*1>-kzEl_r7EYz);
- int v2uF_4ba=9;
- }
- }
- }
- int pjcp7rv=arg;
- {
- int m2ya3=--arg-pjcp7rv;
- while(m2ya3<-----pjcp7rv>=pjcp7rv+--pjcp7rv!=---pjcp7rv!=-arg<---(-m2ya3)>m2ya3<=-----true>14!=--m2ya3) {
- m2ya3=m2ya3+-(--0<=false<pjcp7rv/arg<=-true);
- while((--m2ya3)<--arg<-----arg*false!=arg<pjcp7rv*arg) {
- pjcp7rv=-3+-arg;
- break;
- }
- while(-3) {
- while(67+0-61) m2ya3=m2ya3;
- if(----pjcp7rv==---(---arg)) pjcp7rv=0!=-23;
- else pjcp7rv=----89;
- while(m2ya3!=m2ya3<pjcp7rv) m2ya3=1;
- while(--arg<=pjcp7rv) pjcp7rv=-32<=-m2ya3+62;
- }
- break;
- }
- }
- {
- int arg=-1<-9!=(-arg>=-pjcp7rv>=arg<=arg);
- while(arg<-arg) {
- arg=arg+--arg;
- {
- while((--93)--pjcp7rv*-pjcp7rv+arg) arg=0-(6>=(--(---41/(0))!=--pjcp7rv)>=---2*33);
- pjcp7rv=11;
- int c=pjcp7rv;
- if(--107) break;
- else break;
- }
- }
- }
- pjcp7rv=pjcp7rv;
- int aR0Wkua=-pjcp7rv==pjcp7rv;
- {
- if(-0!=-0) while(-true) break;
- else {
- while(aR0Wkua) pjcp7rv=-0/pjcp7rv;
- pjcp7rv=pjcp7rv;
- }
- }
- }
- if(-arg) {
- {
- int Isdlt0fr91=0!=arg;
- while(Isdlt0fr91<-Isdlt0fr91==-Isdlt0fr91+true) {
- Isdlt0fr91=Isdlt0fr91+-1!=true;
- if(-arg) if(--arg<=Isdlt0fr91) Isdlt0fr91=-Isdlt0fr91;
- int i=---arg<---arg!=--40;
- {
- int jVX43Ln4Dm=-(6)==-Isdlt0fr91/----0;
- while(jVX43Ln4Dm<--(3-3)) {
- jVX43Ln4Dm=jVX43Ln4Dm+-0<25;
- i=24<--(jVX43Ln4Dm);
- }
- }
- i=(arg!=----false>=7);
- int Te=5>-arg;
- break;
- }
- }
- arg=arg!=--true/arg;
- {
- int UX=arg;
- while(UX<-3*arg) {
- UX=UX+arg/-1;
- arg=-3--(-UX- -47<arg==--arg==arg)/arg- -UX>=-arg;
- if(---12) while(-UX) break;
- break;
- }
- }
- continue;
- }
- if(arg) arg=--0;
- else if(1) continue;
- int DtTlhjYq=19==arg;
- {
- arg=--DtTlhjYq<=(DtTlhjYq/---DtTlhjYq<=-DtTlhjYq);
- if(---arg) continue;
- else {
- int Zsl=40;
- while(Zsl<--Zsl--false>((Zsl))==Zsl!=--DtTlhjYq-DtTlhjYq-DtTlhjYq) {
- Zsl=Zsl+arg;
- }
- }
- if((arg)) if(-DtTlhjYq) {
- }
- else while(((2)==3*arg/DtTlhjYq)<=0==---arg) return false;
- else {
- int lwbF=arg>=0;
- while(lwbF<57) {
- lwbF=lwbF+--(-arg+lwbF)>=-2>=arg!=arg;
- arg=----0+0;
- while(49) break;
- if(true) DtTlhjYq=-----arg;
- DtTlhjYq=0!=-----(0);
- }
- }
- arg=---arg!=DtTlhjYq/--0;
- DtTlhjYq=-DtTlhjYq/(--arg<arg);
- if(32) {
- int q=-DtTlhjYq;
- while(q<arg*(0*q)/0) {
- q=q+DtTlhjYq;
- DtTlhjYq=arg;
- }
- }
- else if(--arg) if(15) break;
- else arg=0==arg<=-55>DtTlhjYq;
- else {
- }
- DtTlhjYq=-0;
- {
- while((0)<-arg) DtTlhjYq=-DtTlhjYq;
- }
- if(30/--(arg)>=0) DtTlhjYq=-0>=arg;
- else {
- int Y2wcIQJ=--DtTlhjYq*---11;
- if(arg==arg) {
- Y2wcIQJ=-----Y2wcIQJ;
- Y2wcIQJ=Y2wcIQJ<7;
- if(DtTlhjYq) arg=arg;
- else break;
- while(-arg!=-31==(false<=-15>=-DtTlhjYq+--6*-----Y2wcIQJ<=---arg!=-Y2wcIQJ<=---0<-arg*--Y2wcIQJ)) DtTlhjYq=arg!=3;
- }
- continue;
- }
- arg=DtTlhjYq;
- arg=--3/(---arg)>=80>=-DtTlhjYq<=DtTlhjYq;
- arg=51+---(-true)!=arg!=----1==-DtTlhjYq;
- if(11<=arg) if((arg)+79<32+(-arg)) continue;
- else if(true==DtTlhjYq) break;
- break;
- }
-}
-if(arg!=62==arg) {
- while(---arg) {
- {
- int bhmDacPM=arg/arg;
- while(bhmDacPM<arg) {
- bhmDacPM=bhmDacPM+80*((-bhmDacPM)/---bhmDacPM>1)<bhmDacPM-2!=7;
- arg=-0;
- arg=bhmDacPM>=-arg+-arg;
- break;
- }
- }
- int arg=true;
- arg=arg<=arg;
- {
- int KlC=30;
- while(KlC<-2) {
- KlC=KlC+-1!=25<=-KlC>KlC>----0;
- int Ij=arg>=-arg<=---10;
- {
- int LAbgurVa2R=-arg!=Ij;
- while(LAbgurVa2R<-true) {
- LAbgurVa2R=LAbgurVa2R+Ij;
- KlC=-LAbgurVa2R;
- Ij=42*(-Ij>true);
- while(Ij) arg=KlC;
- KlC=-----7>-(--KlC<--7)==-LAbgurVa2R;
- }
- }
- int a=Ij<=-KlC;
- if(Ij) {
- int r1W=a!=-false;
- }
- else {
- arg=56>=Ij;
- while(54) break;
- arg=8>=-(a<--Ij)/a>=-a-KlC;
- }
- int Yt_T=KlC;
- arg=KlC;
- }
- }
- if(----false/--arg/12+-----0) if(-9+-arg) while(arg!=(arg)) arg=--1>=-71-arg!=---(--arg*11+102)/--arg;
- else if(----arg) continue;
- if(-arg-arg) {
- arg=-(-arg)*--(-3)<(-7==-arg----arg);
- {
- int arg=arg;
- while(arg<-0>arg==-arg-(-arg>1+11)) {
- arg=arg+6-arg!=--0>---30>=---arg<=arg/(3)+---arg;
- }
- }
- arg=-arg+arg;
- arg=--47+-arg<1>arg*(-arg==-arg- -0>3);
- arg=(----arg)!=arg+--59;
- arg=- -4+arg==-(arg)-arg;
- }
- else {
- while(--true-----true*-25+-18>arg>=-----(-arg)---13) {
- arg=-0+--true<false;
- continue;
- }
- arg=true<=arg;
- break;
- }
- arg=arg*22<--(0+-arg);
- {
- continue;
- }
- }
- arg=1*---((3<=true)==---2);
- arg=7+-(-1);
- return arg+--true;
-}
-else {
- int o3ypEsewxM=-(---arg);
- int vzXB=(-(---11<=--o3ypEsewxM>=--0))<=-0/-arg;
- int L=-arg;
- int B4mHcrf=---vzXB;
- int oZWGdzZl=-o3ypEsewxM;
- int K6tQqa1=11;
- while(0!=--L) {
- int sdZfTM=vzXB*true+K6tQqa1;
- while(sdZfTM<false) {
- sdZfTM=sdZfTM+arg;
- sdZfTM=oZWGdzZl;
- K6tQqa1=-K6tQqa1;
- arg=---K6tQqa1;
- while((3+-K6tQqa1)<oZWGdzZl) {
- if(-----(-1)) sdZfTM=-false;
- {}
- }
- K6tQqa1=vzXB!=-(B4mHcrf+-7>false);
- sdZfTM=vzXB;
- }
- }
- L=false;
- while(31) B4mHcrf=arg;
- oZWGdzZl=-0<--oZWGdzZl<=--2;
- if(K6tQqa1>=20<=46) {
- if(-1+-L) if(oZWGdzZl) {
- int wmhv=-----0;
- }
- int arg=0;
- o3ypEsewxM=---(oZWGdzZl);
- return -oZWGdzZl/0;
- }
- else if(arg) {
- int yKk5=B4mHcrf>=4>K6tQqa1<-B4mHcrf/o3ypEsewxM;
- return -K6tQqa1;
- }
- else {
- if(---0) {
- {}
- {}
- }
- return o3ypEsewxM;
- }
-}
-""");
- code.parse().opto().typeCheck().GCM();
- assertEquals("return 9;", code.print());
- }
-
-
@Test
public void testPrimes() {
CodeGen code = new CodeGen(
diff --git a/chapter24/src/test/java/com/seaofnodes/simple/Chapter24Test.java b/chapter24/src/test/java/com/seaofnodes/simple/Chapter24Test.java
index 1970a228..dcb7216f 100644
--- a/chapter24/src/test/java/com/seaofnodes/simple/Chapter24Test.java
+++ b/chapter24/src/test/java/com/seaofnodes/simple/Chapter24Test.java
@@ -14,8 +14,7 @@ public class Chapter24Test {
@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"));
+ String src = "int v0=0; v0 = arg && 0== 0 !=0;";
testCPU(src,"x86_64_v2", "Win64" ,-1,null);
testCPU(src,"riscv" , "SystemV",-1,null);
testCPU(src,"arm" , "SystemV",-1,null);
@@ -73,11 +72,11 @@ public class Chapter24Test {
@Test
public void testAndPtr() throws IOException {
String src =
- """
- struct S { S? fld; };
- val ptr = arg == 1 ? null : new S{fld = arg==1 ? null : new S{fld = null;};};
- return ptr && ptr.fld ? "true" : "false";
- """;
+"""
+struct S { S? fld; };
+val ptr = arg == 1 ? null : new S{fld = arg==1 ? null : new S{fld = null;};};
+return ptr && ptr.fld ? "true" : "false";
+""";
CodeGen code = new CodeGen(src).parse().opto().typeCheck();
assertEquals("[97-117][ 116,114,117,101]", Eval2.eval(code, 0));
@@ -197,17 +196,17 @@ public class Chapter24Test {
@Test
public void testStack3() throws IOException {
- TestC.runS("stacked_r_3","In range",3);
+ TestC.runS("stacked_r_3","In range",5);
// Evaluate on RISC5 emulator
- EvalRisc5 R5 = TestRisc5.build("stacked_r_3", 0, 3, false);
+ EvalRisc5 R5 = TestRisc5.build("stacked_r_3", 0, 5, false);
int trap = R5.step(100);
assertEquals(0,trap);
assertEquals(0,R5.regs[riscv.A0]);
assertEquals("In range",R5._stdout.toString());
// Evaluate on ARM emulator
- EvalArm64 arm = TestArm64.build("stacked_r_3", 0, 3, false);
+ EvalArm64 arm = TestArm64.build("stacked_r_3", 0, 5, false);
int trap_1 = arm.step(100);
assertEquals(0,trap_1);
assertEquals(0,arm.regs[0]);
@@ -235,17 +234,17 @@ public class Chapter24Test {
@Test
public void testStack5() throws IOException {
- TestC.runS("stacked_r_5","In range",3);
+ TestC.runS("stacked_r_5","In range",5);
// Evaluate on RISC5 emulator
- EvalRisc5 R5 = TestRisc5.build("stacked_r_5", 0, 5, false);
+ EvalRisc5 R5 = TestRisc5.build("stacked_r_5", 0, 7, false);
int trap = R5.step(100);
assertEquals(0,trap);
assertEquals(0,R5.regs[riscv.A0]);
assertEquals("In range",R5._stdout.toString());
// Evaluate on ARM emulator
- EvalArm64 arm = TestArm64.build("stacked_r_5", 0, 5, false);
+ EvalArm64 arm = TestArm64.build("stacked_r_5", 0, 7, false);
trap = arm.step(100);
assertEquals(0,trap);
assertEquals(0,arm.regs[0]);
@@ -256,27 +255,27 @@ public class Chapter24Test {
@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');
- """;
+"""
+// 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());
@@ -287,21 +286,21 @@ public class Chapter24Test {
@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;
- """;
+"""
+// 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()); }
@@ -311,24 +310,24 @@ public class Chapter24Test {
@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('[');
- """;
+"""
+// 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());
diff --git a/chapter24/src/test/java/com/seaofnodes/simple/progs/stacked_r_3.smp b/chapter24/src/test/java/com/seaofnodes/simple/progs/stacked_r_3.smp
index 43d7c3ac..27fe15ea 100644
--- a/chapter24/src/test/java/com/seaofnodes/simple/progs/stacked_r_3.smp
+++ b/chapter24/src/test/java/com/seaofnodes/simple/progs/stacked_r_3.smp
@@ -7,4 +7,4 @@ int score = 5;
val str = (sq(2) <= score < sq(3)) ? "In range" : "Out of range";
sys.io.p(str);
-return 0; \ No newline at end of file
+return 0;