11package com .compiler .ast ;
22
3+ import com .compiler .*;
4+ import com .compiler .instr .*;
5+
36import java .io .OutputStreamWriter ;
7+ import java .util .ArrayList ;
8+ import java .util .List ;
49
510public class ASTSwitchStmtNode extends ASTStmtNode {
611
@@ -21,6 +26,63 @@ public void execute(OutputStreamWriter out) {
2126 m_caseList .execute (out );
2227 }
2328
29+ @ Override
30+ public void codegen (CompileEnvIntf env ) {
31+ InstrBlock headBlock = env .createBlock (env .createUniqueSymbol ("Switch_Head" ).m_name );
32+ env .addInstr (new InstrJump (headBlock ));
33+ env .setCurrentBlock (headBlock );
34+ InstrBlock exitBlock = env .createBlock (env .createUniqueSymbol ("Switch_Exit" ).m_name );
35+
36+ if (m_caseList .m_caseList .isEmpty ()){
37+ env .addInstr (new InstrJump (exitBlock ));
38+ env .setCurrentBlock (exitBlock );
39+ return ;
40+ }
41+
42+ InstrIntf switchExpression = m_expression .codegen (env );
43+ Symbol switchExpressionSymbol = env .createUniqueSymbol ("switch" );
44+ InstrIntf assignSwitchExpression = new InstrAssign (switchExpressionSymbol , switchExpression );
45+ env .addInstr (assignSwitchExpression );
46+
47+ //Body Block Loop
48+ List <InstrBlock > bodyBlocks = new ArrayList <>();
49+ for (int i = 0 ; i < m_caseList .m_caseList .size (); i ++) {
50+ InstrBlock bodyBlock = env .createBlock (env .createUniqueSymbol ("CaseExecute" + i ).m_name );
51+ bodyBlocks .add (bodyBlock );
52+ env .setCurrentBlock (bodyBlock );
53+ m_caseList .m_caseList .get (i ).m_stmtList .codegen (env );
54+ env .addInstr (new InstrJump (exitBlock ));
55+ }
56+
57+ //Check Block Loop
58+ List <InstrBlock > checkBlocks = new ArrayList <>();
59+ List <InstrIntf > equalInstrs = new ArrayList <>();
60+ for (int i = 0 ; i < m_caseList .m_caseList .size (); i ++) {
61+ InstrBlock caseBlock = env .createBlock (env .createUniqueSymbol ("CaseCheck" + i ).m_name );
62+ checkBlocks .add (caseBlock );
63+ env .setCurrentBlock (caseBlock );
64+ InstrIntf switchValue = new InstrVariableExpr (switchExpressionSymbol );
65+ env .addInstr (switchValue );
66+ InstrIntf caseLiteral = m_caseList .m_caseList .get (i ).m_value .codegen (env );
67+ InstrIntf equals = new InstrCompare (TokenIntf .Type .EQUAL , switchValue , caseLiteral );
68+ equalInstrs .add (equals );
69+ env .addInstr (equals );
70+ }
71+
72+ for (int i = 0 ; i < checkBlocks .size () - 1 ; i ++) {
73+ env .setCurrentBlock (checkBlocks .get (i ));
74+ env .addInstr (new InstrCondJump (equalInstrs .get (i ), bodyBlocks .get (i ), checkBlocks .get (i +1 )));
75+ }
76+
77+ env .setCurrentBlock (checkBlocks .get (checkBlocks .size ()-1 ));
78+ env .addInstr (new InstrCondJump (equalInstrs .get (checkBlocks .size ()-1 ), bodyBlocks .get (checkBlocks .size ()-1 ), exitBlock ));
79+
80+ env .setCurrentBlock (headBlock );
81+ env .addInstr (new InstrJump (checkBlocks .get (0 )));
82+
83+ env .setCurrentBlock (exitBlock );
84+ }
85+
2486 @ Override
2587 public void print (OutputStreamWriter outStream , String indent ) throws Exception {
2688 outStream .write (indent );
0 commit comments