rework StackSizeAnalyzer
This commit is contained in:
@ -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() {
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user