⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gencode.h

📁 一个简单的C语言子集的编译器,一个简单的C语言子集的编译器
💻 H
字号:
#ifndef GENCODE_H_
#define GENCODE_H_

#include <string>
#include "global.h"
#include "symtable.h"
#include "code.h"
using namespace std;

extern int nestlevel;
int tmpOffset=0;
void genCode(TreeNode *t);
void cGen(TreeNode *t,int);

#define stack 8
//emit code for temp result
//result is pre-saved in ac
void emitTemp(int tmpR)
{
	if(tmpR>=1 && tmpR<=6){
		emitRM("LDA",tmpR,0,ac);
	}
	else if(tmpR==stack){
		emitRM("ST",ac,0,mp);
		emitRM("LDA",mp,1,mp);
	}
	return;
}
//emit code for io of variable
//loc(fp): variable replacement
//bAddr: get address OR get value
//    1: get address
//    0: get value
//Address or value is saved in ac
void emitRefer(int location,int bAddr)
{
	if(bAddr){
		emitRM("LDA",ac,location,fp);
	}
	else{
		emitRM("LD",ac,location,fp);
	}
}
// tempR: Register for temp result
//   0-6: R0-R6
//     8: On stack
//    -1: Abandon
void cGen(TreeNode *t,int tempR)
{
	TreeNode *ttemp;
	SymbolRecord *s;
	int saveLoc1,saveLoc2,currentLoc;
	int i;
	if (t != NULL)
	{
		switch(t->kind)
		{
		case DECLAR:
			if(t->childkind.declarK==FUNC_DECLAR)
			{
				FuncName=t->name;
				s=st_lookup(t->name);
				emitComment("Enter function");
				s->location=emitSkip(0);
				emitRM("ST",fp,0,mp);//save ofp
				emitRM("LDA",fp,1,mp);//update fp
				emitRM("LDA",mp,s->localAlloc+1,mp);//update mp,+1 for ofp
				cGen(t->pChild[1],-1);
				emitComment("Leave function");
				emitRM("LDC",ac,0,0);//return 0 by default
				//emitRM("LDA",mp,-(s->localAlloc+1),mp); //restore mp
				emitRM("LDA",mp,-1,fp); //restore mp
				emitRM("LD",temp,-2,fp);//temp=ret
				emitRM("LD",fp,-1,fp);//fp=ofp
				emitRM("LDA",pc,0,temp);//pc=ret(jump back)
				FuncName="";
				nestlevel=0;
			}
			break;
		case CSTMT:
			emitComment("Compound statement start");
			st_addon(t->pBucketList);
			cGen(t->pChild[1],-1);
			st_takeoff();
			emitComment("Compound statement end");
			break;
		case OP:
			cGen(t->pChild[0],stack);
			cGen(t->pChild[1],ac1);
			emitRM("LD",ac,-1,mp);
			emitRM("LDA",mp,-1,mp);
			switch(t->tokenT)
			{
			case PLUS:
				emitRO("ADD",ac,ac,ac1);
				break;
			case MINUS:
				emitRO("SUB",ac,ac,ac1);
				break;
			case MUL:
				emitRO("MUL",ac,ac,ac1);
				break;
			case DIV:
				emitRO("DIV",ac,ac,ac1);
				break;
			}
			emitTemp(tempR);
			break;
		case RELOP:
			cGen(t->pChild[0],stack);
			cGen(t->pChild[1],ac1);
			emitRM("LD",ac,-1,mp);
			emitRM("LDA",mp,-1,mp);
			emitRO("SUB",ac,ac,ac1);
			switch(t->tokenT)
			{
			case LT:
				emitRM("JLT",ac,2,pc);
				break;
			case LTEQ:
				emitRM("JLE",ac,2,pc);
				break;
			case GT:
				emitRM("JGT",ac,2,pc);
				break;
			case GTEQ:
				emitRM("JGE",ac,2,pc);
				break;
			case EQ:
				emitRM("JEQ",ac,2,pc);
				break;
			case NEQ:
				emitRM("JNE",ac,2,pc);
				break;
			}
			emitRM("LDC",ac,0,0);
			emitRM("LDA",pc,1,pc);
			emitRM("LDC",ac,1,0);
			emitTemp(tempR);
			break;
		case STMT:
			switch(t->childkind.stmtK)
			{
			case IF_STMT:
				emitComment("If statement start");
				cGen(t->pChild[0],ac);
				saveLoc1=emitSkip(1); //jump to else when false(ac=0)
				cGen(t->pChild[1],-1);
				saveLoc2=emitSkip(1); //jump to end
				currentLoc=emitSkip(0);
				emitBackup(saveLoc1);
				emitRM("JEQ",ac,currentLoc-saveLoc1-1,pc);
				emitRestore();
				cGen(t->pChild[2],-1);
				currentLoc=emitSkip(0);
				emitBackup(saveLoc2);
				emitRM_Abs("LDA",pc,currentLoc);
				emitRestore();
				emitComment("If statement end");
				break;
			case WHILE_STMT:
				emitComment("While statement start");
				currentLoc=emitSkip(0);
				cGen(t->pChild[0],ac);
				saveLoc1=emitSkip(1); //jump out
				cGen(t->pChild[1],-1);
				emitRM_Abs("LDA",pc,currentLoc);
				currentLoc=emitSkip(0);
				emitBackup(saveLoc1);
				emitRM("JEQ",ac,currentLoc-saveLoc1-1,pc);
				emitRestore();
				emitComment("While statement end");
				break;
			case RETURN_STMT:
				emitComment("Return statement start");
				s=st_lookup(FuncName);
				cGen(t->pChild[0],stack);
				if(t->pChild[0]!=NULL){
					emitRM("LD",ac,-1,mp);
				}
				emitRM("LDA",mp,-1,fp);//restore mp, -1 for ofp
				emitRM("LD",temp,-2,fp);//temp=ret
				emitRM("LD",fp,-1,fp); //fp=ofp
				emitRM("LDA",pc,0,temp);//pc=ret(jump back)
				emitComment("Return statement end");
				break;
			}
			break;
		case REFER:
			emitComment(string("Reference of ")+t->name);
			s=st_lookup(t->name);
			i=s->nestlevel;
			cGen(t->pChild[0],ac1);
			if(t->pChild[0]!=NULL){
				if(s->symboltype==ARRAYADDR_SYMBOL)
					emitRM("LD",ac,s->location,i?fp:gp);
				else emitRM("LDA",ac,s->location,i?fp:gp);
				emitRO("ADD",ac,ac,ac1);
				emitRM("LD",ac,0,ac);
			}
			else{
				if(s->symboltype==ARRAY_SYMBOL){
					emitRM("LDA",ac,s->location,i?fp:gp);
				}
				else
					emitRM("LD",ac,s->location,i?fp:gp);
			}
			emitTemp(tempR);
			break;
		case CALL:
			emitComment(string("Call ")+t->name);
			if(t->name=="output") {
				cGen(t->pChild[0],ac);
				emitRO("OUT",ac,0,0);
			}
			else if(t->name=="input") {
				emitRO("IN",ac,0,0);
				emitTemp(tempR);
			}
			else{
				s=st_lookup(t->name);
				ttemp=t->pChild[0];
				while(ttemp!=NULL){
					if(ttemp->pNext==NULL)
						break;
					ttemp=ttemp->pNext;
				}
				t->pChild[0]=ttemp;
				while(ttemp!=NULL)
				{
					ttemp->pNext=ttemp->pPrev;
					ttemp=ttemp->pPrev;
				}
				cGen(t->pChild[0],stack);
				emitRM("LDA",ac,3,pc);
				emitRM("ST",ac,0,mp);
				emitRM("LDA",mp,1,mp);
				emitRM_Abs("LDA",pc,s->location);
				emitRM("LDA",mp,-(s->paramAlloc+1),mp); //+1 for ret
				emitTemp(tempR);
			}
			break;
		case EXP:
			switch(t->childkind.expK)
			{
			case ASSIGN_EXP:
				emitComment("Assignment start: "+t->name);
				s=st_lookup(t->name);
				i=s->nestlevel;
				cGen(t->pChild[1],stack);
				cGen(t->pChild[0],ac);
				if(t->pChild[0]!=NULL){
					if(s->symboltype==ARRAYADDR_SYMBOL)
						emitRM("LD",ac1,s->location,i?fp:gp);
					else emitRM("LDA",ac1,s->location,i?fp:gp);
					emitRO("ADD",ac1,ac,ac1);
					emitRM("LD",ac,-1,mp);
					emitRM("LDA",mp,-1,mp);
					emitRM("ST",ac,0,ac1);
				}
				else{
					emitRM("LD",ac,-1,mp);
					emitRM("LDA",mp,-1,mp);
					emitRM("ST",ac,s->location,i?fp:gp);
				}
				emitTemp(tempR);
				break;
			}
			break;
		case NUM:
			emitComment(string("Literal number: ")+t->name);
			emitRM("LDC",ac,atoi(t->name.c_str()),0);
			emitTemp(tempR);
			break;	
		}
		cGen(t->pNext,tempR);
	}
}
void genCode(TreeNode *t)
{
	int jmainLoc;
	SymbolRecord *s=st_lookup(string("main"));
	if(s==NULL)
		GenError("Entrypoint 'main' not found");
	emitRM("LDA",mp,globalAlloc+1,mp); //+1 for ret
	emitRM("LDA",ac,2,pc);
	emitRM("ST",ac,-1,mp);
	jmainLoc=emitSkip(1);
	emitRM("LDA",mp,-(globalAlloc+1),mp); //+1 for ret
	emitRO("HALT",0,0,0);
	cGen(t->pNext->pNext,-1); //ignore input&output
	emitBackup(jmainLoc);
	emitRM_Abs("LDA",pc,s->location);
	emitRestore();
}
#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -