rework StackSizeAnalyzer

This commit is contained in:
ChUrl
2021-01-31 16:40:20 +01:00
parent 228a0221ac
commit bdf1376675
2 changed files with 25 additions and 17 deletions

View File

@ -1,14 +1,20 @@
package codegen.analysis;
import parser.ast.ASTNode;
import util.Logger;
import java.util.ArrayDeque;
import java.util.Deque;
/**
* Simuliert den Laufzeit-Stack während einer Programmausführung.
*/
public class StackModel {
private final Deque<ASTNode> stack;
/**
* Speichert die maximale Stacktiefe während der Ausführung.
*/
private int max;
public StackModel() {
@ -16,22 +22,16 @@ public class StackModel {
}
public void push(ASTNode root) {
Logger.log("PUSH " + root.getName() + ": " + root.getValue());
this.stack.push(root);
this.updateMax();
}
public ASTNode pop() {
public void pop() {
if (this.stack.isEmpty()) {
throw new IllegalStateException("Can't pop empty stack");
}
Logger.log("POP " + this.stack.peek().getName() + ": " + this.stack.peek().getValue());
return this.stack.pop();
}
public ASTNode peek() {
return this.stack.peek();
this.stack.pop();
}
private void updateMax() {

View File

@ -7,14 +7,18 @@ import java.util.Set;
import static util.Logger.log;
/**
* Ermittelt die maximal benötigte Stacktiefe für ein Programm.
* Das Programm wird übergeben als {@link AST}.
*/
public final class StackSizeAnalyzer {
private static final Set<String> mod;
private static final Set<String> bin;
private static final Set<String> binaryOperators;
static {
mod = Set.of("assignment", "expr", "INTEGER_LIT", "BOOLEAN_LIT", "STRING_LIT", "IDENTIFIER", "print");
bin = Set.of("AND", "OR", "ADD", "SUB", "MUL", "DIV", "MOD", "LESS", "LESS_EQUAL", "GREATER", "GREATER_EQUAL", "EQUAL", "NOT_EQUAL");
binaryOperators = Set.of("AND", "OR", "ADD", "SUB", "MUL", "DIV", "MOD", "LESS", "LESS_EQUAL", "GREATER", "GREATER_EQUAL", "EQUAL", "NOT_EQUAL");
}
private StackSizeAnalyzer() {}
@ -23,6 +27,7 @@ public final class StackSizeAnalyzer {
log("\nDetermining required stack depth:");
final StackModel stack = new StackModel();
runStackModel(tree.getRoot().getChildren().get(3).getChildren().get(11), stack);
return stack.getMax();
@ -44,15 +49,15 @@ public final class StackSizeAnalyzer {
}
}
// Simulate instructions
private static void literal(ASTNode root, StackModel stack) {
log("literal():");
stack.push(root);
}
private static void assignment(ASTNode root, StackModel stack) {
runStackModel(root.getChildren().get(0), stack);
log("assignment():");
stack.pop();
}
@ -61,29 +66,32 @@ public final class StackSizeAnalyzer {
runStackModel(root.getChildren().get(1).getChildren().get(1), stack);
log("println():");
stack.pop(); // Objectref
stack.pop(); // Argument
}
private static void expr(ASTNode root, StackModel stack) {
if (root.getChildren().size() == 2 && bin.contains(root.getValue())) {
if (root.getChildren().size() == 2 && binaryOperators.contains(root.getValue())) {
// Expression with binary operator
runStackModel(root.getChildren().get(0), stack);
runStackModel(root.getChildren().get(1), stack);
log("expr():");
stack.pop(); // Argument
stack.pop(); // Argument
stack.push(root); // Result
} else if (root.getChildren().size() == 1 && "NOT".equals(root.getValue())) {
// Expression with NOT
runStackModel(root.getChildren().get(0), stack);
log("expr():");
stack.push(new ASTNode("1 (XOR)", 0)); // 1 for xor
stack.pop(); // xor
stack.pop(); // xor
stack.push(root); // result
} else if (root.getChildren().size() == 1) {
// Expression with other unary operators
runStackModel(root.getChildren().get(0), stack);
}
}