package com.seaofnodes.simple; import com.seaofnodes.simple.evaluator.Evaluator; import com.seaofnodes.simple.node.StopNode; import org.junit.Test; import static org.junit.Assert.assertEquals; import static org.junit.Assert.fail; public class Chapter16Test { @Test public void testJig() { Parser parser = new Parser( """ return 3.14; """); StopNode stop = parser.parse().iterate(); assertEquals("return 3.14;", stop.toString()); assertEquals(3.14, Evaluator.evaluate(stop, 0)); } @Test public void testMulti0() { Parser parser = new Parser( """ int x, y; return x+y; """); StopNode stop = parser.parse().iterate(); assertEquals("return 0;", stop.toString()); assertEquals(0L, Evaluator.evaluate(stop, 0)); } @Test public void testMulti1() { Parser parser = new Parser( """ int x=2, y=x+1; return x+y; """); StopNode stop = parser.parse().iterate(); assertEquals("return 5;", stop.toString()); assertEquals(5L, Evaluator.evaluate(stop, 0)); } @Test public void testConstruct0() { Parser parser = new Parser(""" struct X { int x=3; }; X z = new X; return z.x; """); StopNode stop = parser.parse().iterate(); assertEquals("return 3;", stop.toString()); assertEquals(3L, Evaluator.evaluate(stop, 0)); } @Test public void testConstruct2() { Parser parser = new Parser(""" struct X { int x=3; }; X z = new X { x = 4; }; return z.x; """); StopNode stop = parser.parse().iterate(); assertEquals("return 4;", stop.toString()); assertEquals(4L, Evaluator.evaluate(stop, 0)); } @Test public void testLinkedList1() { Parser parser = new Parser( """ struct LLI { !LLI? !next; int i; }; !LLI? !head = null; while( arg ) { head = new LLI { next=head; i=arg; }; arg = arg-1; } if( !head ) return 0; LLI? next = head.next; if( !next ) return 1; return next.i; """); StopNode stop = parser.parse().iterate(); assertEquals("Stop[ return 0; return 1; return .i; ]", stop.toString()); assertEquals(0L, Evaluator.evaluate(stop, 0)); assertEquals(1L, Evaluator.evaluate(stop, 1)); assertEquals(2L, Evaluator.evaluate(stop, 3)); } @Test public void testLinkedList2() { Parser parser = new Parser( """ struct LLI { !LLI? !next; int i; }; !LLI? !head = null; while( arg ) { head = new LLI { next=head; // Any old code in the constructor int !tmp=arg; while( arg > 10 ) { tmp = tmp + arg; arg = arg - 1; } i=tmp; }; arg = arg-1; } if( !head ) return 0; LLI? next = head.next; if( !next ) return 1; return next.i; """); StopNode stop = parser.parse().iterate(); assertEquals("Stop[ return 0; return 1; return .i; ]", stop.toString()); assertEquals(0L, Evaluator.evaluate(stop, 0)); assertEquals(1L, Evaluator.evaluate(stop, 1)); assertEquals(2L, Evaluator.evaluate(stop, 11)); } @Test public void testSquare() { Parser parser = new Parser( """ struct Square { flt !side = arg; // Newtons approximation to the square root, computed in a constructor. // The actual allocation will copy in this result as the initial // value for 'diag'. flt !diag = arg*arg/2; while( 1 ) { flt next = (side/diag + diag)/2; if( next == diag ) break; diag = next; } }; return new Square; """); StopNode stop = parser.parse().iterate(); assertEquals("return Square;", stop.toString()); assertEquals("Obj{side=3.0,diag=1.7320508075688772}", Evaluator.evaluate(stop, 3).toString()); assertEquals("Obj{side=4.0,diag=2.0}", Evaluator.evaluate(stop, 4).toString()); } static final String CONSTRUCTOR_MEMORY = """ struct S { int x; int y; }; struct T { int z=arg+40; }; !T !t = new T; !S !a = new S { x=11; y=7; }; !S !b = new S { x=22; y=9; }; !S !p=a; if (arg) p=b; int before=p.x; !S !c = new S { x=p.x+1; { int i=0; while (i<2) { p.y=p.y+1; i=i+1; } } y=p.y; }; p.x=33; return before*10000+c.x*100+c.y+t.z; """; @Test public void testConstructorMemory() { StopNode stop = new Parser(CONSTRUCTOR_MEMORY).parse().iterate(); assertEquals(111249L,Evaluator.evaluate(stop,0)); assertEquals(222352L,Evaluator.evaluate(stop,1)); } }