rework StackSizeAnalyzer
This commit is contained in:
@ -1,14 +1,20 @@
|
|||||||
package codegen.analysis;
|
package codegen.analysis;
|
||||||
|
|
||||||
import parser.ast.ASTNode;
|
import parser.ast.ASTNode;
|
||||||
import util.Logger;
|
|
||||||
|
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.Deque;
|
import java.util.Deque;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Simuliert den Laufzeit-Stack während einer Programmausführung.
|
||||||
|
*/
|
||||||
public class StackModel {
|
public class StackModel {
|
||||||
|
|
||||||
private final Deque<ASTNode> stack;
|
private final Deque<ASTNode> stack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Speichert die maximale Stacktiefe während der Ausführung.
|
||||||
|
*/
|
||||||
private int max;
|
private int max;
|
||||||
|
|
||||||
public StackModel() {
|
public StackModel() {
|
||||||
@ -16,22 +22,16 @@ public class StackModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void push(ASTNode root) {
|
public void push(ASTNode root) {
|
||||||
Logger.log("PUSH " + root.getName() + ": " + root.getValue());
|
|
||||||
this.stack.push(root);
|
this.stack.push(root);
|
||||||
this.updateMax();
|
this.updateMax();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ASTNode pop() {
|
public void pop() {
|
||||||
if (this.stack.isEmpty()) {
|
if (this.stack.isEmpty()) {
|
||||||
throw new IllegalStateException("Can't pop empty stack");
|
throw new IllegalStateException("Can't pop empty stack");
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.log("POP " + this.stack.peek().getName() + ": " + this.stack.peek().getValue());
|
this.stack.pop();
|
||||||
return this.stack.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
public ASTNode peek() {
|
|
||||||
return this.stack.peek();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateMax() {
|
private void updateMax() {
|
||||||
|
@ -7,14 +7,18 @@ import java.util.Set;
|
|||||||
|
|
||||||
import static util.Logger.log;
|
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 {
|
public final class StackSizeAnalyzer {
|
||||||
|
|
||||||
private static final Set<String> mod;
|
private static final Set<String> mod;
|
||||||
private static final Set<String> bin;
|
private static final Set<String> binaryOperators;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
mod = Set.of("assignment", "expr", "INTEGER_LIT", "BOOLEAN_LIT", "STRING_LIT", "IDENTIFIER", "print");
|
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() {}
|
private StackSizeAnalyzer() {}
|
||||||
@ -23,6 +27,7 @@ public final class StackSizeAnalyzer {
|
|||||||
log("\nDetermining required stack depth:");
|
log("\nDetermining required stack depth:");
|
||||||
|
|
||||||
final StackModel stack = new StackModel();
|
final StackModel stack = new StackModel();
|
||||||
|
|
||||||
runStackModel(tree.getRoot().getChildren().get(3).getChildren().get(11), stack);
|
runStackModel(tree.getRoot().getChildren().get(3).getChildren().get(11), stack);
|
||||||
|
|
||||||
return stack.getMax();
|
return stack.getMax();
|
||||||
@ -44,15 +49,15 @@ public final class StackSizeAnalyzer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Simulate instructions
|
||||||
|
|
||||||
private static void literal(ASTNode root, StackModel stack) {
|
private static void literal(ASTNode root, StackModel stack) {
|
||||||
log("literal():");
|
|
||||||
stack.push(root);
|
stack.push(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void assignment(ASTNode root, StackModel stack) {
|
private static void assignment(ASTNode root, StackModel stack) {
|
||||||
runStackModel(root.getChildren().get(0), stack);
|
runStackModel(root.getChildren().get(0), stack);
|
||||||
|
|
||||||
log("assignment():");
|
|
||||||
stack.pop();
|
stack.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,29 +66,32 @@ public final class StackSizeAnalyzer {
|
|||||||
|
|
||||||
runStackModel(root.getChildren().get(1).getChildren().get(1), stack);
|
runStackModel(root.getChildren().get(1).getChildren().get(1), stack);
|
||||||
|
|
||||||
log("println():");
|
|
||||||
stack.pop(); // Objectref
|
stack.pop(); // Objectref
|
||||||
stack.pop(); // Argument
|
stack.pop(); // Argument
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void expr(ASTNode root, StackModel stack) {
|
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(0), stack);
|
||||||
runStackModel(root.getChildren().get(1), stack);
|
runStackModel(root.getChildren().get(1), stack);
|
||||||
|
|
||||||
log("expr():");
|
|
||||||
stack.pop(); // Argument
|
stack.pop(); // Argument
|
||||||
stack.pop(); // Argument
|
stack.pop(); // Argument
|
||||||
stack.push(root); // Result
|
stack.push(root); // Result
|
||||||
} else if (root.getChildren().size() == 1 && "NOT".equals(root.getValue())) {
|
} else if (root.getChildren().size() == 1 && "NOT".equals(root.getValue())) {
|
||||||
|
// Expression with NOT
|
||||||
|
|
||||||
runStackModel(root.getChildren().get(0), stack);
|
runStackModel(root.getChildren().get(0), stack);
|
||||||
|
|
||||||
log("expr():");
|
|
||||||
stack.push(new ASTNode("1 (XOR)", 0)); // 1 for xor
|
stack.push(new ASTNode("1 (XOR)", 0)); // 1 for xor
|
||||||
stack.pop(); // xor
|
stack.pop(); // xor
|
||||||
stack.pop(); // xor
|
stack.pop(); // xor
|
||||||
stack.push(root); // result
|
stack.push(root); // result
|
||||||
} else if (root.getChildren().size() == 1) {
|
} else if (root.getChildren().size() == 1) {
|
||||||
|
// Expression with other unary operators
|
||||||
|
|
||||||
runStackModel(root.getChildren().get(0), stack);
|
runStackModel(root.getChildren().get(0), stack);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user