代碼生成是Tiny編譯器的最後一項工作,代碼生成的基礎是語法樹和符號表,遍歷語法樹,生成能夠被TM虛擬機執行的指令,其中if語句和repeat語句需要利用emitSkip、emitBackup進行代碼回填,因爲只有全部語句指令生成完成以後才知道跳轉地址。代碼生成的源代碼如下:
#include "globals.h"
#include "symtab.h"
#include "code.h"
#include "cgen.h"
static int tempOffset = 0;
static void cgen(TreeNode* tree);
//產生語句的代碼
static void genStmt(TreeNode* tree)
{
TreeNode *p1, *p2, *p3;
int savedLoc1, savedLoc2, currentLoc;
int loc;
switch(tree->kind.stmt)
{
case IfK:
p1=tree->child[0];
p2=tree->child[1];
p3=tree->child[2];
//邏輯表達式的代碼
cgen(p1);
savedLoc1=emitSkip(1); //回填位置1
//then部分代碼
cgen(p2);
savedLoc2=emitSkip(1);//回填位置2
currentLoc=emitSkip(0);
emitBackup(savedLoc1);
emitRM_Abs("JEQ", ac, currentLoc, "if: jmp to else"); //回填位置1的代碼
emitRestore();
//else部分代碼
cgen(p3);
currentLoc=emitSkip(0);
emitBackup(savedLoc2);
emitRM_Abs("LDA", pc, currentLoc, "jmp to end"); //回填位置2的代碼
emitRestore();
break;
case RepeatK:
p1=tree->child[0];
p2=tree->child[1];
savedLoc1=emitSkip(0);
cgen(p1);