/** * 翻译break 语句 * A break statement terminates the execution of associated * switch or loop. * * break is translated into: * goto switch or loop's nextBB * nextBB: * ... */ static void TranslateBreakStatement (AstStatement stmt) { AstBreakStatement brkStmt = AsBreak(stmt); if (brkStmt->target->kind == NK_SwitchStatement) { /* switch 在跳转 */ GenerateJump (AsSwitch(brkStmt->target)->nextBB); } else { /* loop 跳转 */ GenerateJump (AsLoop(brkStmt->target)->nextBB); } StartBBlock (CreateBBlock ()); }
/** * 翻译do 语句 * * do stmt while (expr) is translated into: * loopBB: * stmt * contBB: * if (expr) goto loopBB * nextBB: * ... */ static void TranslateDoStatement (AstStatement stmt) { AstLoopStatement doStmt = AsLoop(stmt); doStmt->loopBB = CreateBBlock (); doStmt->contBB = CreateBBlock (); doStmt->nextBB = CreateBBlock (); /* do 语句先执行循环体 */ StartBBlock (doStmt->loopBB); TranslateStatement (doStmt->stmt); /* 判断条件,分支 */ StartBBlock (doStmt->contBB); TranslateBranch (doStmt->expr, doStmt->loopBB, doStmt->nextBB); StartBBlock (doStmt->nextBB); }
/** * 翻译while 语句 * * while (expr) stmt is translated into: * goto contBB * loopBB: * stmt * contBB: * if (expr) goto loopBB * nextBB: * ... */ static void TranslateWhileStatement (AstStatement stmt) { AstLoopStatement whileStmt = AsLoop(stmt); /* 循环体基本块 */ whileStmt->loopBB = CreateBBlock (); /* 继续判断条件 */ whileStmt->contBB = CreateBBlock (); /* 循环结束后基本块 */ whileStmt->nextBB = CreateBBlock (); /* 条件 */ GenerateJump (whileStmt->contBB); /* 循环体 */ StartBBlock (whileStmt->loopBB); TranslateStatement (whileStmt->stmt); /* 判断条件,分支 */ StartBBlock (whileStmt->contBB); TranslateBranch (whileStmt->expr, whileStmt->loopBB, whileStmt->nextBB); StartBBlock (whileStmt->nextBB); }
static void DumpStatement(AstStatement stmt, int pos) { switch (stmt->kind) { case NK_ExpressionStatement: DumpExpression(AsExpr(stmt)->expr, pos); break; case NK_LabelStatement: fprintf(ASTFile, "(label %s:\n", AsLabel(stmt)->id); LeftAlign(ASTFile, pos + 2); DumpStatement(AsLabel(stmt)->stmt, pos + 2); LeftAlign(ASTFile, pos); fprintf(ASTFile, "end-label)"); break; case NK_CaseStatement: fprintf(ASTFile, "(case "); DumpExpression(AsCase(stmt)->expr, pos + 7); LeftAlign(ASTFile, pos + 2); DumpStatement(AsCase(stmt)->stmt, pos + 2); LeftAlign(ASTFile, pos); fprintf(ASTFile, "end-case)"); break; case NK_DefaultStatement: fprintf(ASTFile, "(default "); DumpStatement(AsDef(stmt)->stmt, pos + 10); LeftAlign(ASTFile, pos); fprintf(ASTFile, "end-default)"); break; case NK_IfStatement: fprintf(ASTFile, "(if "); DumpExpression(AsIf(stmt)->expr, pos + 5); LeftAlign(ASTFile, pos + 2); fprintf(ASTFile, "(then "); LeftAlign(ASTFile, pos + 4); DumpStatement(AsIf(stmt)->thenStmt, pos + 4); LeftAlign(ASTFile, pos + 2); fprintf(ASTFile, "end-then)"); if (AsIf(stmt)->elseStmt != NULL) { LeftAlign(ASTFile, pos + 2); fprintf(ASTFile, "(else "); LeftAlign(ASTFile, pos + 4); DumpStatement(AsIf(stmt)->elseStmt, pos + 4); LeftAlign(ASTFile, pos + 2); fprintf(ASTFile, "end-else)"); } LeftAlign(ASTFile, pos); fprintf(ASTFile, "end-if)"); break; case NK_SwitchStatement: fprintf(ASTFile, "(switch "); DumpExpression(AsSwitch(stmt)->expr, pos + 9); LeftAlign(ASTFile, pos + 2); DumpStatement(AsSwitch(stmt)->stmt, pos + 2); LeftAlign(ASTFile, pos); fprintf(ASTFile, "end-switch)"); break; case NK_WhileStatement: fprintf(ASTFile, "(while "); DumpExpression(AsLoop(stmt)->expr, pos + 8); LeftAlign(ASTFile, pos + 2); DumpStatement(AsLoop(stmt)->stmt, pos + 2); LeftAlign(ASTFile, pos); fprintf(ASTFile, "end-while)"); break; case NK_DoStatement: fprintf(ASTFile, "(do "); DumpExpression(AsLoop(stmt)->expr, pos + 5); LeftAlign(ASTFile, pos + 2); DumpStatement(AsLoop(stmt)->stmt, pos + 2); LeftAlign(ASTFile, pos); fprintf(ASTFile, ")"); break; case NK_ForStatement: fprintf(ASTFile, "(for "); DumpExpression(AsFor(stmt)->initExpr, pos + 6); LeftAlign(ASTFile, pos + 6); DumpExpression(AsFor(stmt)->expr, pos + 6); LeftAlign(ASTFile, pos + 6); DumpExpression(AsFor(stmt)->incrExpr, pos + 6); LeftAlign(ASTFile, pos + 2); DumpStatement(AsFor(stmt)->stmt, pos + 2); LeftAlign(ASTFile, pos); fprintf(ASTFile, "end-for)"); break; case NK_GotoStatement: fprintf(ASTFile, "(goto %s)", AsGoto(stmt)->id); break; case NK_ContinueStatement: fprintf(ASTFile, "(continue)"); break; case NK_BreakStatement: fprintf(ASTFile, "(break)"); break; case NK_ReturnStatement: fprintf(ASTFile, "(ret "); DumpExpression(AsRet(stmt)->expr, pos + 5); fprintf(ASTFile, ")"); break; case NK_CompoundStatement: { AstNode p = ((AstCompoundStatement)stmt)->stmts; fprintf(ASTFile, "{"); while (p != NULL) { LeftAlign(ASTFile, pos + 2); DumpStatement((AstStatement)p, pos + 2); if (p->next != NULL) fprintf(ASTFile, "\n"); p = p->next; } LeftAlign(ASTFile, pos); fprintf(ASTFile, "}"); break; } default: assert(0); } }