check 'if' condition type, mark functions constant, improved tests

This commit is contained in:
User 2017-11-28 16:45:15 +01:00
parent eae3c68b51
commit 68093f96e9
12 changed files with 77 additions and 21 deletions

View File

@ -180,6 +180,7 @@ public class BoppiChecker extends BoppiBaseVisitor<Type> {
FunctionType type = new FunctionType(returnType, parameterTypes);
Variable<Type> func = an.symbols.put(ctx.name.getText(), type);
func.setConstant(true);
func.assign();
an.variables.put(ctx, func);
@ -207,7 +208,8 @@ public class BoppiChecker extends BoppiBaseVisitor<Type> {
@Override
public Type visitIf(IfContext ctx) {
return an.symbols.withScope(() -> {
visit(ctx.cond);
checkConstraint(visit(ctx.cond), SimpleType.BOOL, ctx.cond);
if (ctx.onFalse != null) {
Type trueType = an.symbols.withScope(() -> visit(ctx.onTrue));
Type falseType = an.symbols.withScope(() -> visit(ctx.onFalse));

View File

@ -16,7 +16,6 @@ stat
declareStat
: DECLARE CONSTANT? type IDENTIFIER #declare
| FUNCTION (result=type)? name=IDENTIFIER PAROPEN parameters? PARCLOSE body=expr #declareFunction
| LAMBDA IDENTIFIER+ ARROW expr #lambda
;
assignStat
@ -36,6 +35,7 @@ expr
| OUT PAROPEN expr (LISTDELIM expr)* PARCLOSE #write
| IFOPEN cond=stats IFTRUE onTrue=stats (IFFALSE onFalse=stats)? IFCLOSE #if
| WHILEOPEN cond=stats WHILETRUE onTrue=stats WHILECLOSE #while
| LAMBDA IDENTIFIER+ ARROW expr #lambda
| variable PAROPEN (expr (LISTDELIM expr)*)? PARCLOSE #call
| variable #getVariable
| LITERAL10 #literalInteger

View File

@ -17,7 +17,6 @@ public class ArrayTest {
@Test
public void correctArrayParsing() {
BoppiTests.parseFile("simpleArray.boppi");
BoppiTests.log.forEach((l)->System.out.println(l.getMessage()));
assertThat(BoppiTests.log, empty());
}

View File

@ -35,6 +35,21 @@ public class ConditionalTest {
assertThat(BoppiTests.log, is(empty()));
}
/**
* Wrong if-else and loop use
*/
@Test
public void wrongConditionalChecking() {
BoppiTests.checkString("if 5 then 0 fi");
assertThat(BoppiTests.log, hasSize(1));
BoppiTests.checkString("5 + if true then 3 fi");
assertThat(BoppiTests.log, hasSize(1));
BoppiTests.checkString("while 'a' do 1+1 od");
assertThat(BoppiTests.log, hasSize(1));
}
/**
* Correct evaluation of basic programs
*/

View File

@ -8,6 +8,8 @@ import java.util.logging.Level;
import org.apache.commons.lang3.StringUtils;
import org.junit.Test;
import pp.s1184725.boppi.util.RegisterPool;
/**
* Test cases for the basic expression language.
*
@ -82,14 +84,16 @@ public class ExpressionTest {
public void correctExpressionGeneration() {
BoppiTests.compileAndRunFile("simpleExpression.boppi");
assertThat(BoppiTests.log, is(empty()));
assertThat(BoppiTests.out, is(arrayContaining("1", "1", "3", "A", "false")));
int n = 12;
String expression = StringUtils.repeat("1+(", n) + "1" + StringUtils.repeat(")", n);
int n = RegisterPool.RECOMMENDED_REGISTER_COUNT+3;
String expression = StringUtils.repeat("1+(", n) + "0" + StringUtils.repeat(")", n);
BoppiTests.withWarnings(() -> {
BoppiTests.compileAndRunString("print(" + expression + ")", "" + n);
assertThat(BoppiTests.log, hasSize(1));
assertThat(BoppiTests.log.get(0).getLevel(), is(Level.WARNING));
assertThat(BoppiTests.out, is(arrayContaining(Integer.toString(n))));
});
}

View File

@ -106,7 +106,6 @@ public class ILOCAllocatorTest {
*/
@Test
public void simpleMallocFree() {
// Simulator.DEBUG = true;
sim(malloc(11, obj1));
assertThat(vm.getInterrupt(), is(0));
assertThat(vm.load(FIRSTPTR), is(not(FIRSTSLOT)));

View File

@ -16,6 +16,12 @@ public class SimpleFunctionTest {
*/
@Test
public void correctFunctionParsing() {
BoppiTests.parseString("function constantProcedure() 0; 1");
assertThat(BoppiTests.log, is(empty()));
BoppiTests.parseString("function procedure(int a) a; 1");
assertThat(BoppiTests.log, is(empty()));
BoppiTests.parseString("function int id(int a) a; 1");
assertThat(BoppiTests.log, is(empty()));
@ -40,9 +46,12 @@ public class SimpleFunctionTest {
*/
@Test
public void wrongFunctionParsing() {
BoppiTests.parseString("function char add(int a, int b);");
BoppiTests.parseString("function char add(int a, int b); 'c'");
assertThat(BoppiTests.log, hasSize(1));
BoppiTests.parseString("function char add(a, b); 1");
assertThat(BoppiTests.log, is(not(empty())));
BoppiTests.parseString("function int add(int a, int b) a+b; add(4,)");
assertThat(BoppiTests.log, hasSize(1));
}
@ -69,6 +78,9 @@ public class SimpleFunctionTest {
BoppiTests.checkString("function int factorial(int n) {if (n > 1) then n*factorial(n-1) else 1 fi}; 0");
assertThat(BoppiTests.log, is(empty()));
BoppiTests.checkString("var int a; a := 1; function int id(int a) a; 1");
assertThat(BoppiTests.log, is(empty()));
}
/**
@ -76,6 +88,9 @@ public class SimpleFunctionTest {
*/
@Test
public void wrongFunctionChecking() {
BoppiTests.checkString("var int add; add := 1; add(4, 2)");
assertThat(BoppiTests.log, hasSize(1));
BoppiTests.checkString("function int add(int a, char b) a+b; print(add(4, 'T')+1)");
assertThat(BoppiTests.log, hasSize(1));
@ -84,6 +99,15 @@ public class SimpleFunctionTest {
BoppiTests.checkString("function int add(int a, int b) a+b; print(add(4, 'T')+1)");
assertThat(BoppiTests.log, hasSize(1));
BoppiTests.checkString("function int id(int a) a; print(id(4, 2)+1)");
assertThat(BoppiTests.log, hasSize(1));
BoppiTests.checkString("function nothing(int a) a; print(nothing(2))");
assertThat(BoppiTests.log, hasSize(1));
BoppiTests.checkString("function int add(int a, int b) a+b; print(add(4)+1)");
assertThat(BoppiTests.log, hasSize(1));
}
/**
@ -104,6 +128,10 @@ public class SimpleFunctionTest {
assertThat(BoppiTests.log, is(empty()));
assertThat(BoppiTests.out, is(arrayContaining("1")));
BoppiTests.compileAndRunString("var int a; a := 1; function int id(int a) a; print(id(4))");
assertThat(BoppiTests.log, is(empty()));
assertThat(BoppiTests.out, is(arrayContaining("4")));
BoppiTests.compileAndRunString("function int add(int a, int b) a+b; print(add(4, 5)+1)");
assertThat(BoppiTests.log, is(empty()));
assertThat(BoppiTests.out, is(arrayContaining("10")));

View File

@ -126,7 +126,10 @@ public class SimpleVariableTest {
@Test
public void correctVariableGeneration() {
BoppiTests.compileAndRunFile("simpleVariable.boppi");
BoppiTests.log.forEach((l)->System.out.println(l.getMessage()));
assertThat(BoppiTests.log, is(empty()));
BoppiTests.compileAndRunFile("simpleScope.boppi");
assertThat(BoppiTests.out, is(arrayContaining("9", "4", "true")));
assertThat(BoppiTests.log, is(empty()));
}

View File

@ -28,7 +28,8 @@ function (int,int)->int logCalls((int,int)->int f) {
return
};
add := logCalls(add);
var add add_;
add_ := logCalls(add);
print(add(1,6), add(10,5));
print(add_(1,6), add_(10,5));
print(getCalls());

View File

@ -20,9 +20,10 @@ function int main1() {
return
};
add := logCalls(add);
var add add_;
add_ := logCalls(add);
print(add(1,6), add(10,5));
print(add_(1,6), add_(10,5));
print(getCalls());
};

View File

@ -2,13 +2,7 @@
var int n;
function int fib(int n) {
if n < 2 then
1
else
fib(n-1)+fib(n-2)
fi
};
var (int)->int fib;
function fib memoize(fib f) {
var [50]int memo;
@ -33,7 +27,15 @@ function fib memoize(fib f) {
memoFib
};
fib := memoize(fib);
function int fib_(int n) {
if n < 2 then
1
else
fib(n-1)+fib(n-2) //has to call `fib` instead of `fib_` because `fib_` is constant
fi
};
fib := memoize(fib_);
read(n);

View File

@ -32,4 +32,6 @@ myBool := {
99 + (myInt := 100);
};
otherInt > 3;
}
};
print(otherInt, myInt, myBool);