package net.yak.stalk;

import net.yak.stalk.Talk.Terp;
import net.yak.stalk.Talk.Terp.Frame;
import junit.framework.TestCase;

public class ExprTest extends TestCase {
	Terp t;
	Frame f;

	protected void setUp() throws Exception {
		super.setUp();
		t = new Terp();
		f = t.newFrame(null, null, null);
	}

	public void testLit888() {
		Expr e = Parser.parse(t, " 888 ");
		Pro obj = e.eval(f);
		assertEquals(888.0, obj.asNum().num);
	}
	public void testLitString() {
		Expr e = Parser.parse(t, " 'foo''bar' ");
		Pro obj = e.eval(f);
		assertEquals("foo'bar", obj.asStr().str);
	}
	public void testTwoStmts() {
		Expr e = Parser.parse(t, " . 23 . 42 . . . ");
		assertEquals(42.0, e.eval(f).asNum().num);
	}
	public void testUnaryNeg() {
		Expr e = Parser.parse(t, " . 23 . 42 neg . . . ");
		assertEquals(-42.0, e.eval(f).asNum().num);
	}
	public void testUnaryNegSgn() {
		Expr e = Parser.parse(t, " . 23 . 42 neg sgn ");
		assertEquals(-1.0, e.eval(f).asNum().num);
	}
	public void testPlusTwoNums() {
		Expr e = Parser.parse(t, " 23 pl: 42  ");
		assertEquals(65.0, e.eval(f).asNum().num);
	}
	public void testPlusTwoNumsWithNeg() {
		Expr e = Parser.parse(t, " 23 pl: 42 neg  ");
		assertEquals(-19.0, e.eval(f).asNum().num);
	}
	public void testPlusTwoNumsWithOtherNeg() {
		Expr e = Parser.parse(t, " 23 neg pl: 42  ");
		assertEquals(19.0, e.eval(f).asNum().num);
	}
	public void testStoreAndFetch() {
		Expr e = Parser.parse(t, " n/ 23 pl: 42 . 13 . n  ");
		assertEquals(65.0, e.eval(f).asNum().num);
	}
	public void testStoreAndFetchWithGlobalAndLocal() {
		Expr e = Parser.parse(t, " /X/ 4 pl: 4 . j/ 5 pl: 5 . /X pl: j ");
		assertEquals(18.0, e.eval(f).asNum().num);
	}
	public void testBlock() {
		Expr e = Parser.parse(t, " [ 23 pl: 42 . ] run  ");
		assertEquals(65.0, e.eval(f).asNum().num);
	}
	public void testYesNoToTrue() {
		Expr e = Parser.parse(t, " /t ye: [ e/ 42 ] . /t no: [ e/ 13 ] . e");
		assertEquals(42.0, e.eval(f).asNum().num);
	}
	public void testYesNoToFalse() {
		Expr e = Parser.parse(t, " /f ye: [ a/ 42 ] . /f no: [ a/ 13 ] . a");
		assertEquals(13.0, e.eval(f).asNum().num);
	}
	public void testDefiningUsrSubclass() {
		Expr e = Parser.parse(t, " /Usr subc: 'Foo' . /Foo new cls nam");
		assertEquals("Foo", e.eval(f).asStr().str);
	}
	public void testDefiningUsrMethod() {
		Expr e = Parser.parse(t, " /Usr subc: 'Foo' . /Foo meth: 'xyz' as: '888' . /Foo new xyz ");
		assertEquals(888.0, e.eval(f).asNum().num);
	}
}
