check 'if' condition type, mark functions constant, improved tests
This commit is contained in:
parent
eae3c68b51
commit
68093f96e9
|
@ -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));
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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))));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -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)));
|
||||
|
|
|
@ -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")));
|
||||
|
|
|
@ -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()));
|
||||
}
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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());
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -32,4 +32,6 @@ myBool := {
|
|||
99 + (myInt := 100);
|
||||
};
|
||||
otherInt > 3;
|
||||
}
|
||||
};
|
||||
|
||||
print(otherInt, myInt, myBool);
|
||||
|
|
Loading…
Reference in New Issue