Commit 5eec3405 authored by 徐世桐's avatar 徐世桐
Browse files

sx119: finished constant evaluation

parent 20b2cbe6
#!/bin/bash
VALID_EXAMPLE_DIR="./src/test/examples/valid/"
VALID_EXAMPLES=(
"/constantPropagation/evaluation/"
)
VALID_EXAMPLE_LOG="./log/const_eval.log"
> $VALID_EXAMPLE_LOG
TEST_DIR="$VALID_EXAMPLE_DIR$VALID_EXAMPLES"
# counters to represent the total number of test files to be processed
TOTAL_COUNT=$(find "$VALID_EXAMPLE_DIR${VALID_EXAMPLES[@]}" -name "*.wacc" | wc -l)
COUNTER=0
for folder in "$VALID_EXAMPLE_DIR${VALID_EXAMPLES[@]}"; do
for file in $(find "$folder" -name "*.wacc"); do
FILE_NAME=$(basename "${file%.*}")
./compile -o1 -t $file 2> $VALID_EXAMPLE_LOG
ret=$?
echo "exit status: " $ret
if [ $ret -ne 0 ]; then
echo $file
echo "status code incorrect: " $ret
exit 1
fi
if diff "$TEST_DIR${FILE_NAME}.log" $VALID_EXAMPLE_LOG > temp; then
echo $FILE_NAME
echo "optimise differ from expected result: "
exit 1
fi
(( COUNTER += 1 ))
echo "$COUNTER / $(($TOTAL_COUNT)) finished"
echo ""
done
echo "========================================================================================"
echo "Test Folder" $folder "has been processed" "($COUNTER / $(($TOTAL_COUNT)))"
echo "========================================================================================"
done
\ No newline at end of file
......@@ -66,23 +66,17 @@ public class Compiler {
int optimise_cmd_index = cmd_ops.indexOf("--optimise");
String optimise_level = cmd_ops.get(optimise_cmd_index + 1);
System.out.println(optimise_level);
switch (optimise_level) {
case "0":
break;
case "1":
NodeVisitor<Node> constPropOptimiser = new ConstantPropagation();
program = constPropOptimiser.visit(program);
System.out.println("optimising");
break;
default:
System.out.println("unsupported optimisation level: " + optimise_level);
}
for (String cmd : cmd_ops) {
System.out.println(cmd);
}
/* print optimised ast tree */
if (cmd_ops.contains("--print_ast")) {
ASTPrinter painter = new ASTPrinter();
......
......@@ -70,8 +70,7 @@ public class BinopNode extends ExprNode {
return visitor.visitBinopNode(this);
}
@Override
public boolean isImmediate() {
return expr1.isImmediate() && expr2.isImmediate();
}
/* should not overwrite is immediate,
* since even if both child are immediate, it means evaluator failed to simplify it,
* calling getCast val on it will cause error */
}
......@@ -37,7 +37,6 @@ public abstract class ExprNode implements Node {
/* if the expr contain value that does not depend on variable
* i.e if expr is int, char, bool*/
public boolean isImmediate() {
System.out.println("in is imm" + this.getClass());
return false;
}
......@@ -46,7 +45,7 @@ public abstract class ExprNode implements Node {
* int return value
* bool return 1 if true, 0 if false */
public int getCastedVal() {
throw new IllegalArgumentException("calling getVal on type not immediate");
throw new IllegalArgumentException("calling getVal on type not immediate, this type is " + this.getClass().getName());
}
}
......@@ -35,7 +35,6 @@ public class ConstantPropagation implements NodeVisitor<Node> {
public Node visitBinopNode(BinopNode node) {
ExprNode expr1 = visit(node.getExpr1()).asExprNode();
ExprNode expr2 = visit(node.getExpr2()).asExprNode();
System.out.println("checking binop");
/* if either of the nodes is not immediate, stop constant propagation
* return a node with so far the simplified form */
......@@ -45,17 +44,15 @@ public class ConstantPropagation implements NodeVisitor<Node> {
/* apply arithmetic evaluation */
if (arithmeticApplyMap.containsKey(node.getOperator())) {
int val = arithmeticApplyMap.get(node.getOperator()).apply(
ExprNode simpChild = arithmeticApplyMap.get(node.getOperator()).apply(
expr1.getCastedVal(),
expr2.getCastedVal());
System.out.println("visiting arithmetic");
return new IntegerNode(val);
return simpChild == null ? new BinopNode(expr1, expr2, node.getOperator()) : simpChild;
}
/* otherwise, have to be binop covered by cmpMap key */
assert cmpMap.containsKey(node.getOperator());
System.out.println("visiting cmp");
boolean val = cmpMap.get(node.getOperator()).apply(expr1.getCastedVal(), expr2.getCastedVal());
return new BoolNode(val);
}
......@@ -114,8 +111,6 @@ public class ConstantPropagation implements NodeVisitor<Node> {
@Override
public Node visitUnopNode(UnopNode node) {
System.out.println("checking unop");
if (!node.isImmediate()) {
return node;
}
......@@ -124,8 +119,10 @@ public class ConstantPropagation implements NodeVisitor<Node> {
/* visit expr first, ensure child expr have already been simplified */
ExprNode expr = visit(node.getExpr()).asExprNode();
System.out.println("entered unop");
return unopApplyMap.get(node.getOperator()).apply(expr);
ExprNode simpChild = unopApplyMap.get(node.getOperator()).apply(expr);
return simpChild == null ?
new UnopNode(expr, node.getOperator()) :
simpChild;
}
@Override
......@@ -237,7 +234,6 @@ public class ConstantPropagation implements NodeVisitor<Node> {
/* explicit call visitFuncNode, can call cast */
functions.put(entry.getKey(), (FuncNode) visitFuncNode(entry.getValue()));
}
System.out.println("optimising body");
StatNode body = visit(node.getBody()).asStatNode();
return new ProgramNode(functions, body);
}
......
WARNING: arithmetic on -14 and 2147483600 will cause overflow
WARNING: arithmetic on -14 and 2147483600 will cause overflow
{scope
INTEGER a = 0
BOOLEAN b = false
a (4) = 3
a (4) = 0
a (4) = 3
a (4) = -280000
a (4) = -14 MUL 2147483600
a (4) = -14 MUL 2147483600 MINUS 512
b (5) = false
b (5) = false
b (5) = true
b (5) = true
b (5) = false
b (5) = true
b (5) = false
b (5) = true
b (5) = false
b (5) = true
b (5) = true
b (5) = false
b (5) = true
b (5) = true
}
Assembly file created!
Assembly has been written to the file!
begin
int a = 0;
bool b = false;
a = 1 + 2;
a = (1 / 2) * (3 % 4);
a = (3 % 4);
a = (1 - 2) * (2 + (3 * 4)) * 20000;
# this line is used to test overflow
a = (1 - 2) * (2 + (3 * 4)) * 2147483600;
#if one side cannot be simplify, the other branch should still be evaluated
a = (1 - 2) * (2 + (3 * 4)) * 2147483600 - (1 * 2048) / 4;
b = 1 > 3;
b = 1 >= 3;
b = 1 <= 3;
b = 1 < 3;
b = 1 == 3;
b = 1 != 3;
b = 'a' > 'b';
b = 'a' <= 'b';
b = 'a' == 'b';
b = 'a' != 'b';
b = true != false;
b = true && false;
b = false || false;
b = (1 >= 3) || (true != true) && 'a' > ' '
end
\ No newline at end of file
begin
int a = 0;
bool b = false;
char c = ' ';
b = !true;
b = !false;
a = -(+2);
a = -(-2147483648);
a = ord 'a';
c = chr 97
end
WARNING: arithmetic on 0 and -2147483648 will cause overflow
{scope
INTEGER a = 0
BOOLEAN b = false
CHAR c = <char:32>
b (5) = false
b (5) = true
a (4) = -2
a (4) = MINUS-2147483648
a (4) = 97
c (6) = <char:97>
}
Assembly file created!
Assembly has been written to the file!
......@@ -90,12 +90,12 @@ public class Utils {
'\\', '\\'
);
public static final Map<Binop, BinaryOperator<Integer>> arithmeticApplyMap = Map.of(
Binop.PLUS, Integer::sum,
Binop.MINUS, ((Integer x, Integer y) -> x - y),
Binop.MUL, ((Integer x, Integer y) -> x * y),
Binop.DIV, ((Integer x, Integer y) -> x / y),
Binop.MOD, ((Integer x, Integer y) -> x % y)
public static final Map<Binop, BiFunction<Integer, Integer, ExprNode>> arithmeticApplyMap = Map.of(
Binop.PLUS, ((x, y) -> arithmeticWithCheck(x, y, Math::addExact)),
Binop.MINUS, ((x, y) -> arithmeticWithCheck(x, y, Math::subtractExact)),
Binop.MUL, ((x, y) -> arithmeticWithCheck(x, y, Math::multiplyExact)),
Binop.DIV, ((x, y) -> new IntegerNode(x / y)),
Binop.MOD, ((x, y) -> new IntegerNode(x % y))
);
public static final Map<Binop, BiFunction<Integer, Integer, Boolean>> cmpMap = Map.of(
......@@ -110,13 +110,23 @@ public class Utils {
);
public static final Map<Unop, Function<ExprNode, ExprNode>> unopApplyMap = Map.of(
Unop.MINUS, (x -> new UnopNode(x, Unop.MINUS)),
Unop.MINUS, (x -> arithmeticWithCheck(0, x.getCastedVal(), Math::subtractExact)),
Unop.NOT, (x -> new BoolNode(x.getCastedVal() != 1)),
Unop.LEN, (x -> new IntegerNode(x.getCastedVal())),
Unop.ORD, (x -> new IntegerNode(x.getCastedVal())),
Unop.CHR, (x -> new CharNode((char) x.getCastedVal()))
);
private static ExprNode arithmeticWithCheck(int a, int b, BinaryOperator<Integer> exactOperator) {
try {
return new IntegerNode(exactOperator.apply(a, b));
} catch (ArithmeticException e) {
System.out.println("WARNING: arithmetic " + " on " + a + " and " + b + " will cause overflow");
}
/* return null, inform upper caller to return the original node */
return null;
}
/* error code used in ErrorHandlers */
public static final int SYNTAX_ERROR_CODE = 100;
public static final int SEMANTIC_ERROR_CODE = 200;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment