Programming-Language-Compiler / edu / ufl / cise / plc / test / Assignment5TestStarter.java
Assignment5TestStarter.java
Raw
package edu.ufl.cise.plc.test;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.IOException;

import org.junit.jupiter.api.Test;

//import edu.ufl.cise.plc.CodeGenVisitor;
import edu.ufl.cise.plc.CompilerComponentFactory;
import edu.ufl.cise.plc.IParser;
//import edu.ufl.cise.plc.ImageResources;
import edu.ufl.cise.plc.TypeCheckException;
import edu.ufl.cise.plc.TypeCheckVisitor;
import edu.ufl.cise.plc.ast.ASTNode;
import edu.ufl.cise.plc.ast.ASTVisitor;
import edu.ufl.cise.plc.ast.Program;
//import edu.ufl.cise.plc.runtime.ColorTuple;
import edu.ufl.cise.plc.runtime.ConsoleIO;
import edu.ufl.cise.plc.runtime.javaCompilerClassLoader.DynamicClassLoader;
import edu.ufl.cise.plc.runtime.javaCompilerClassLoader.DynamicCompiler;

class Assignment5TestStarter {
	
	//Default package name for generated code
	String packageName = "cop4020sp22Package";

	boolean VERBOSE = true;

	private void show(Object obj) {
		if (VERBOSE)
			System.out.println(obj);
	}


	static final float DELTA = .001f;

	String getName(ASTNode ast) throws Exception {
		if (ast instanceof Program) {
			return ((Program) ast).getName();
		} else
			throw new Exception("bug--expected ast was program");
	}

	String getReturnType(ASTNode ast) throws Exception {
		if (ast instanceof Program) {
			return ((Program) ast).getReturnType().toString();
		} else
			throw new Exception("bug--expected ast was program");
	}


	void checkResult(String input, Object expectedResult) throws Exception {
		checkResult(input, null, expectedResult);
	}

	void checkResult(String input, Object[] params, Object expectedResult) throws Exception {
		Object result = exec(input, params);
		show("result = " + result);
		assertEquals(expectedResult, result);
	}

	
	Object exec(String input, Object[] params) throws Exception {
		//Lex and parse, to get AST
		ASTNode ast = CompilerComponentFactory.getParser(input).parse();
		//Type check and decorate AST with declaration and type info
		ast.visit(CompilerComponentFactory.getTypeChecker(), null);
		//Generate Java code
		String className = ((Program) ast).getName();
		String fullyQualifiedName = packageName != "" ? packageName + '.' + className : className;
		String javaCode = (String) ast.visit(CompilerComponentFactory.getCodeGenerator(packageName), null);
		show(javaCode);
		//Invoke Java compiler to obtain bytecode
		byte[] byteCode = DynamicCompiler.compile(fullyQualifiedName, javaCode);
		//Load generated classfile and execute its apply method.
		Object result = DynamicClassLoader.loadClassAndRunMethod(byteCode, fullyQualifiedName, "apply", params);
		return result;
	}


	private void displayResult(String input, Object[] params) throws Exception {
		Object result = exec(input,params);
		show(result);
	}
	
	// need separate method to check floats due to DELTA.  Note in simple cases, just use normal check.  
	void checkFloatResult(String input,  float expectedResult) throws Exception {
		checkFloatResult(input,  null, expectedResult);
	}

	void checkFloatResult(String input, Object[] params, float expectedResult) throws Exception {
		Object result = exec(input, params);
		show("result = " + result);
		assertEquals(expectedResult, (float) result, DELTA);
	}

	/* The first group of test return literal values of various types */

	@Test
	void test1() throws Exception {
		String input = "int y() ^42;";
		checkResult(input,  null, 42);
	}

	@Test
	void test2() throws Exception {
		String input = """
				string y() ^ "hello";
				""";
		checkResult(input,  null, "hello");
	}

	@Test
	void test3() throws Exception {
		String input = "float f() ^ 1.2;";
		checkResult(input,  null, 1.2f);
	}

	@Test
	void test4() throws Exception {
		String input = "boolean f() ^ false;";
		checkResult(input,  null, false);
	}


	/* declares and initializes variable in declaration. returns variable */
	@Test
	void test6() throws Exception {
		String input = "int f() int x = 55; ^ x;";
		checkResult(input,  null, 55);
	}

	@Test
	void test7() throws Exception {
		String input = "string f() string x = \"this is a string\"; ^ x;";
		checkResult(input,  null, "this is a string");
	}

	@Test
	void test8() throws Exception {
		String input = "boolean f() boolean x = true; ^ x;";
		checkResult(input, null, true);
	}



	/* Declares variable, initializes in assignment statement, returns */
	@Test
	void test10() throws Exception {
		String input = "int f() int x; x = 33; ^ x;";
		checkResult(input, 33);
	}

	/* Declared variable, initializes in assignment statement, returns */
	@Test
	void test11() throws Exception {
		String input = "float f() float x; x = 56.67; ^ x;";
		checkFloatResult(input,  56.67f);
	}


	/* binary expressions */
	@Test
	void test15() throws Exception {
		String input = """
				int f()
				int a = 3;
				int b = 4;
				^ a+b;
				""";
		checkResult(input,  7);
	}

	@Test
	void test16() throws Exception {
		String input = """
				int f()
				int a = 20;
				int b = 15;
				^ a-b;
				""";
		checkResult(input,  20 - 15);
	}


	@Test
	void test20() throws Exception {
		String input = """
				float f()
				float a = 3.2;
				float b = 4.8;
				^ a+b;
				""";
		checkResult(input,  3.2f + 4.8f);
	}


	@Test
	void testParams1() throws Exception {
		String input = """
				int a(int b, int c)
				^ b+c;
				""";
		int b = 42;
		int c = 64;
		Object[] params = { b, c };
		checkResult(input, params, b + c);
	}

	@Test
	void testParams2() throws Exception {
		String input = """
				float a(float b, float c)
				^ b/c;
				""";
		float b = 42f;
		float c = 64f;
		Object[] params = { b, c };
		checkFloatResult(input, params, b / c);
	}



	@Test
	void testBinaryExpr0() throws Exception {
		String input = """
				int binary(int a, int b, int c)
				^ a + b *2 + c;
				""";
		int a = 33;
		int b = 24;
		int c = 50;
		Object[] params = { a, b, c };
		checkResult(input, params, a + (b * 2) + c);
	}

	@Test
	//This test reads from the console.  The tester should see that displayed result is same as entered.
	void testReadInt0() throws Exception {
		String input = """
				int testRead0()
				int x;
				x <- console;
				^ x;
				         """;
		displayResult(input, null);
	}


	@Test
	void testMultipleConsoleIO() throws Exception {
		String input = """
				int testMultipleWrites()
				int x0 = 34;
				int x1 = 56;
				write x0 + x1 -> console;
				int x3 ;
				x3 <- console;
				write "x3="-> console;
				write x3 -> console;
				int x4 = x0;
				x4 = (x4 + x1)/3;
				write "  x4="-> console;
				write x4 -> console;
				^x4;
				""";
		checkResult(input, (34+56)/3);
	}

	@Test
void unaryExp1() throws Exception {
  String input = """
        int unaryExp1(int a, int b)
        int x = a + -b;
        ^ x;
        """;
  int a = 33;
  int b = 24;
  Object[] params = { a, b};
  checkResult(input, params, a - b);
}

@Test
void unaryExp2() throws Exception {
  String input = """
        int unaryExp2(int a, int b, int c)
        int x = a - -b + -c;
        ^ x;
        """;
  int a = 33;
  int b = 24;
  int c = 2;
  Object[] params = { a, b, c};
  checkResult(input, params, a + b - c);
}

@Test
void unaryExp3() throws Exception {
  String input = """
        int unaryExp3()
        int a = 33;
        int b = 24;
        int c = 2;
        int x = a - -b + -c;
        ^ x;
        """;
  checkResult(input, null, 55);
}

@Test
void testConditional1() throws Exception {
  String input = """
        int testConditional1(int a, int b)
        int x = a+b;
        ^ if (x > 0) a else b fi;
        """;
  int a = 33;
  int b = 24;
  Object[] params = { a, b};
  checkResult(input, params, a);
}

@Test
void testConditional2() throws Exception {
  String input = """
        boolean testConditional1()
        boolean x = false;
        ^ if (!x) true else false fi;
        """;
  checkResult(input, null, true);
}


@Test
void testFloat() throws Exception {
  String input = "float y() ^42.0;";
  checkResult(input,  null, 42f);
}

@Test
void testConditional3() throws Exception {
  String input = """
      int f()
         int a = 3;
         int b = 4;
        int c =
        if (a == 4)
             2
          else
            5
         fi;
      ^c;
      """;
  checkResult(input,  5);
}

@Test
void testReturnInCondition4() throws Exception {
  String input = """
      float f()
         int a = 3;
         int b = (8 * 3) + a;
         float c =
         if (b == 27)
            2.5
         else
            6.5
         fi;
        
        ^c;
      """;
  checkResult(input,  2.5f);
}

@Test
void testCast() throws Exception {//a and d should be cast to a float type
  String input = """
      float f()
         int a = 3;
         float b = 4.2;
         int d = 2;
        float c =  (a + b) + d;
       
      ^c;
      """;
  checkResult(input,  9.2f);
}




	@Test
	void testp1() throws Exception {
	  String input = """
	  		int a()
	  		int c = (5.1+5);
	  		^ c;
	  		""";
	  checkResult(input,  null, 10);
	}

	@Test
	void testp2() throws Exception {
	  String input = """
	  		int a()
	  		int c = if (5>6) 5.1 else 4.1 fi;	  		^ c;

	  		""";
	  checkResult(input,  null, 4);
	}
	
	
	
	@Test
	void testp3() throws Exception {
	  String input = """
	  		int a()
	  		int c = -5.1;
	  		^ c;
	  		""";
	  checkResult(input,  null, -5);
	}
	
	@Test
	void testp4() throws Exception {
	  String input = """
	  		float a()
	  		float c = 5+(if (5<6) 5.1 else 4.1 fi);
	  		^ c;
	  		""";
	  checkResult(input,  null, 10.1f);
	}

	@Test
	void testp5() throws Exception {
	  String input = """
	  		int a()
	  		int c = (if (5<6) 5 else 4 fi)*6;
	  		^ c;
	  		""";
	  checkResult(input,  null, 30);
	}

	@Test
	void testCoerce() throws Exception {
	String input = """
		int a()
		boolean x = false;
		int y;
		float c = 5.2;
		float b = 3.7;
		int d;
		d = c + b;
		float z = if (!x) d else 5 fi;
		y = z;    
		^ y;
		""";
	checkResult(input,  null, 8);
	}

	@Test
	void testStringNotEquals() throws Exception{
		String input = """
				boolean a(string b)
				^ (b != "Test");
				""";
		String b = new String("test");
		Object params[] = {b};
		checkResult(input, params, true);
	}


	@Test
	void testStringEquals() throws Exception{
		String input = """
				boolean a(string b)
				^ (b == "test");
				""";
		String b = new String("test");
		Object params[] = {b};
		checkResult(input, params, true);
	}


	@Test
	void testMany() throws Exception{
		String input = """
				boolean a(int b, float c, string d)
				boolean e;
				e <- console;
				write "e = " -> console;
				write e -> console;
				boolean f = if (b >= c) e else false fi;
				write "\nf = " -> console;
				write f -> console;
				string g = "test";
				boolean h = if (d == g) b >= c else b < c fi;
				^ h;
				""";
		int b = 42;
		float c = 42.0f;
		String d = new String("test");
		Object params[] = {b, c, d};
		checkResult(input, params, true);
	}

	@Test
	void testStringNotEquals2() throws Exception{
		String input = """
				boolean a(string b)
				^ (b != "Test");
				""";
		String b = new String("Test");
		Object params[] = {b};
		checkResult(input, params, false);
	}

	@Test
	void binTest() throws Exception {
		String input = """
				int foo()
				int a = 11 / 5.0;
				^a;
				""";
		checkResult(input,2);

	}
	@Test
	void params() throws Exception {

		String input = """
				boolean foo(string a, string b)
				^ !(a == b);
				""";
		String a = "hello";
		String b = "hello";
		Object params[] = {a,b};
		checkResult(input, params,false);
	}
	@Test
	void binMany() throws Exception {
		String input = """
				int foo()
				int a = 10 * 2.5 / 5 + 3 % 4.5 + 0.5;
				^a;
				""";
		checkResult(input,8);

	}

}