forked from MarkusEble/Compilerbau25
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathASTSwitchStmtNode.java
More file actions
93 lines (76 loc) · 3.54 KB
/
ASTSwitchStmtNode.java
File metadata and controls
93 lines (76 loc) · 3.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package com.compiler.ast;
import com.compiler.*;
import com.compiler.instr.*;
import java.io.OutputStreamWriter;
import java.util.ArrayList;
import java.util.List;
public class ASTSwitchStmtNode extends ASTStmtNode {
ASTExprNode m_expression;
ASTCaseListNode m_caseList;
int evaluatedExpression;
public ASTSwitchStmtNode(ASTExprNode expression, ASTCaseListNode caseList) {
m_expression = expression;
m_caseList = caseList;
}
@Override
public void execute(OutputStreamWriter out) {
evaluatedExpression = m_expression.eval();
m_caseList.m_caseList.forEach(caseItem-> caseItem.expressionValue = evaluatedExpression);
m_caseList.execute(out);
}
@Override
public void codegen(CompileEnvIntf env) {
InstrBlock headBlock = env.createBlock(env.createUniqueSymbol("Switch_Head").m_name);
env.addInstr(new InstrJump(headBlock));
env.setCurrentBlock(headBlock);
InstrBlock exitBlock = env.createBlock(env.createUniqueSymbol("Switch_Exit").m_name);
if(m_caseList.m_caseList.isEmpty()){
env.addInstr(new InstrJump(exitBlock));
env.setCurrentBlock(exitBlock);
return;
}
InstrIntf switchExpression = m_expression.codegen(env);
Symbol switchExpressionSymbol = env.createUniqueSymbol("switch");
InstrIntf assignSwitchExpression = new InstrAssign(switchExpressionSymbol, switchExpression);
env.addInstr(assignSwitchExpression);
//Body Block Loop
List<InstrBlock> bodyBlocks = new ArrayList<>();
for (int i = 0; i < m_caseList.m_caseList.size(); i++) {
InstrBlock bodyBlock = env.createBlock(env.createUniqueSymbol("CaseExecute" + i).m_name);
bodyBlocks.add(bodyBlock);
env.setCurrentBlock(bodyBlock);
m_caseList.m_caseList.get(i).m_stmtList.codegen(env);
env.addInstr(new InstrJump(exitBlock));
}
//Check Block Loop
List<InstrBlock> checkBlocks = new ArrayList<>();
List<InstrIntf> equalInstrs = new ArrayList<>();
for (int i = 0; i < m_caseList.m_caseList.size(); i++) {
InstrBlock caseBlock = env.createBlock(env.createUniqueSymbol("CaseCheck" + i).m_name);
checkBlocks.add(caseBlock);
env.setCurrentBlock(caseBlock);
InstrIntf switchValue = new InstrVariableExpr(switchExpressionSymbol);
env.addInstr(switchValue);
InstrIntf caseLiteral = m_caseList.m_caseList.get(i).m_value.codegen(env);
InstrIntf equals = new InstrCompare(TokenIntf.Type.EQUAL, switchValue, caseLiteral);
equalInstrs.add(equals);
env.addInstr(equals);
}
for (int i = 0; i < checkBlocks.size() - 1; i++) {
env.setCurrentBlock(checkBlocks.get(i));
env.addInstr(new InstrCondJump(equalInstrs.get(i), bodyBlocks.get(i), checkBlocks.get(i+1)));
}
env.setCurrentBlock(checkBlocks.get(checkBlocks.size()-1));
env.addInstr(new InstrCondJump(equalInstrs.get(checkBlocks.size()-1), bodyBlocks.get(checkBlocks.size()-1), exitBlock));
env.setCurrentBlock(headBlock);
env.addInstr(new InstrJump(checkBlocks.get(0)));
env.setCurrentBlock(exitBlock);
}
@Override
public void print(OutputStreamWriter outStream, String indent) throws Exception {
outStream.write(indent);
outStream.write("ASTSwitchStmtNode\n");
m_expression.print(outStream, indent + " ");
m_caseList.print(outStream, indent + " ");
}
}