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

📄 cgen.c

📁 1.小型编译器 2。支持整数
💻 C
📖 第 1 页 / 共 4 页
字号:
			
      		if(level == 0){
				//数组
				if(tree->child[0]){
					if(tree->type.type == Double){
						emitRM(opADD,ac1,ac1,gp, "op: add ixa");
						if(addrFlag){
		  					emitRM(opLDA,ac,loc,ac1,"array assign: store double addr");
							emitRM(opPUSH, ac, 0, 0, "array assign: push double addr");
						} else {
							emitRM(opLD,ac,loc,ac1,"array assign: store double value",sizeofdouble);
							emitRM(opPUSH, ac, 0, 0, "array assign: push double value",sizeofdouble);
						}
					}else if(tree->type.type == Integer){
						emitRM(opADD,ac1,ac1,gp, "op: add ixa");
						if(addrFlag){
							emitRM(opLDA,ac,loc,ac1,"array assign: store addr");
							emitRM(opPUSH, ac, 0, 0, "array assign: push addr");
						} else {
							emitRM(opLD,ac,loc,ac1,"array assign: store value");
							emitRM(opPUSH, ac, 0, 0, "array assign: push value");
						}
					}else if(tree->type.type == Char){
						emitRM(opADD,ac1,ac1,gp, "op: add ixa");
						if(addrFlag){
							emitRM(opLDA,ac,loc,ac1,"array assign: store char addr");
							emitRM(opPUSH, ac, 0, 0, "array assign: push char addr");
						} else {
							emitRM(opLD,ac,loc,ac1,"array assign: store char value",sizeofchar);
							emitRM(opPUSH, ac, 0, 0, "array assign: push char value",sizeofchar);
						}
					}
				}else if(tree->type.type == Double){
					if(addrFlag){
      					emitRM(opLDA,ac,loc,gp,"load id double addr",sizeofint, flag);
						emitRM(opPUSH, ac, 0, 0, "assign: push double addr");
					} else {
						emitRM(opLD,ac,loc,gp,"load id double value",sizeofdouble, flag);
						emitRM(opPUSH, ac, 0, 0, "assign: push double value", sizeofdouble);
					}
				} else if(tree->type.type == Integer){
					if(addrFlag){
						emitRM(opLDA,ac,loc,gp,"load id addr");
						emitRM(opPUSH, ac, 0, 0, "assign: push addr");
					}else{
						emitRM(opLD,ac,loc,gp,"load id value");
						emitRM(opPUSH, ac, 0, 0, "assign: push value");
					}
				} else if(tree->type.type == Char || tree->type.type == String){
					if(addrFlag){
						emitRM(opLDA,ac,loc,gp,"load id addr");
						emitRM(opPUSH, ac, 0, 0, "assign: push addr");
					}else{
						emitRM(opLD,ac,loc,gp,"load id char value", sizeofchar);
						emitRM(opPUSH, ac, 0, 0, "assign: push char value", sizeofchar);
					}
				} else if(tree->type.type == Struct){
					if(addrFlag){
						emitRM(opLDA,ac,loc,gp,"load id struct addr");
						emitRM(opPUSH, ac, 0, 0, "assign: push struct addr");
					}
				}
      		} else {
      			//数组
      			if(tree->child[0]){
					emitRM(opLDA,bp,base[level-1],sp,"load base top");
					if(tree->type.type == Double){
						emitRM(opADD,ac1,ac1,bp, "op: add ixa");
						if(addrFlag){
		  					emitRM(opLDA,ac,loc,ac1,"array assign: store double add");
							emitRM(opPUSH, ac, 0, 0, "array assign: push double addr");
						} else {
							emitRM(opLD,ac,loc,ac1,"array assign: store double value",sizeofdouble);
							emitRM(opPUSH, ac, 0, 0, "array assign: push double value",sizeofdouble);
						}
					}else if(tree->type.type == Integer){
						emitRM(opADD,ac1,ac1,bp, "op: add ixa");
						if(addrFlag){
							emitRM(opLDA,ac,loc,ac1,"array assign: store addr");
							emitRM(opPUSH, ac, 0, 0, "array assign: push addr");
						} else {
							emitRM(opLD,ac,loc,ac1,"array assign: store value");
							emitRM(opPUSH, ac, 0, 0, "array assign: push value");
						}
					}else if(tree->type.type == Char){
						emitRM(opADD,ac1,ac1,bp, "op: add ixa");
						if(addrFlag){
							emitRM(opLDA,ac,loc,ac1,"array assign: store char addr");
							emitRM(opPUSH, ac, 0, 0, "array assign: push char addr");
						} else {
							emitRM(opLD,ac,loc,ac1,"array assign: store char value",sizeofchar);
							emitRM(opPUSH, ac, 0, 0, "array assign: push char value",sizeofchar);
						}
					}
				}else if(tree->type.type == Double){
					emitRM(opLDA,bp,base[level-1],sp,"load base top");
					printf("flag:%d\n", flag);
					if(addrFlag){
						emitRM(opLDA,ac,loc,bp,"load id double addr",sizeofint, flag);
						emitRM(opPUSH, ac, 0, 0, "assign: push double addr");
					} else {
						emitRM(opLD,ac,loc,bp,"load id double value",sizeofdouble, flag);
						emitRM(opPUSH, ac, 0, 0, "assign: push double value",sizeofdouble);
					}
				} else if(tree->type.type == Integer){
					emitRM(opLDA,bp,base[level-1],sp,"load base top");
					if(addrFlag){
						emitRM(opLDA,ac,loc,bp,"load id addr");
						emitRM(opPUSH, ac, 0, 0, "assign: push addr");
					} else {
						emitRM(opLD,ac,loc,bp,"load id value");
						emitRM(opPUSH, ac, 0, 0, "assign: push value");
					}
				} else if(tree->type.type == Char || tree->type.type == String){
					emitRM(opLDA,bp,base[level-1],sp,"load base top");
					if(addrFlag){
						emitRM(opLDA,ac,loc,bp,"load id char addr");
						emitRM(opPUSH, ac, 0, 0, "assign: push char addr");
					} else {
						emitRM(opLD,ac,loc,bp,"load id char value",sizeofchar);
						emitRM(opPUSH, ac, 0, 0, "assign: push char value",sizeofchar);
					}
				} else if(tree->type.type == Struct){
					emitRM(opLDA,bp,base[level-1],sp,"load base top");
					if(addrFlag){
						emitRM(opLDA,ac,loc,bp,"load id struct addr");
						emitRM(opPUSH, ac, 0, 0, "assign: push struct addr");
					} 
				}
      		}			
      		if (TraceCode)  
				emitComment("<- Id") ;
      	break; /* IdK */

    	case OpK :
         	if (TraceCode) 
				emitComment("-> Op") ;
         	p1 = tree->child[0];
         	p2 = tree->child[1];
         	/* gen code for ac = left arg */
        	cGen(p1);
						
         	/* gen code for ac = right operand */
         	cGen(p2);
			
			type = getType(p1);
			type2 = getType(p2);
			
			if(type == Double){
         		emitRM(opPOP,ac,0,0,"op: pop double right",sizeofdouble);
				emitRM(opPOP,ac1,0,0,"op: pop double left",sizeofdouble);
			}else if(type == Integer){
				emitRM(opPOP,ac,0,0,"op: pop right");
				emitRM(opPOP,ac1,0,0,"op: pop left");
			}else if(type == Char){
				emitRM(opPOP,ac,0,0,"op: pop right",sizeofchar);
				emitRM(opPOP,ac1,0,0,"op: pop left",sizeofchar);
			}
         	switch (tree->attr.op) {
        		case PLUS :
					if((type == Double)||(type2 == Double))
	           			emitRO(opADD,ac,ac1,ac,"op +",sizeofdouble);
					else
						emitRO(opADD,ac,ac1,ac,"op +");
	           		break;
        		case SUB :
					if((type == Double)||(type2 == Double))
	           			emitRO(opSUB,ac,ac1,ac,"op -",sizeofdouble);
					else
						emitRO(opSUB,ac,ac1,ac,"op -");
	           		break;
        		case MUT :
					if((type == Double)||(type2 == Double))
	           			emitRO(opMUL,ac,ac1,ac,"op *",sizeofdouble);
					else
						emitRO(opMUL,ac,ac1,ac,"op *");
	          		break;
        		case DIV :
					if((type == Double)||(type2 == Double))
           				emitRO(opDIV,ac,ac1,ac,"op /",sizeofdouble);
					else
						emitRO(opDIV,ac,ac1,ac,"op /");
           			break;
        		case LT :
					if((type == Double)||(type2 == Double))
           				emitRO(opLT,ac,ac1,ac,"op <",sizeofdouble) ;
					else if((type == Integer)||(type2 == Integer))
						emitRO(opLT,ac,ac1,ac,"op <") ;
					else if((type == Char)||(type2 == Char))
						emitRO(opLT,ac,ac1,ac,"op <",sizeofchar) ;
           			break;
        		case LE :
					if((type == Double)||(type2 == Double))
           				emitRO(opLE,ac,ac1,ac,"op <=",sizeofdouble) ;
					else if((type == Integer)||(type2 == Integer))
						emitRO(opLE,ac,ac1,ac,"op <=") ;
					else if((type == Char)||(type2 == Char))
						emitRO(opLE,ac,ac1,ac,"op <=",sizeofchar) ;
              		break;
				case GT :
					if((type == Double)||(type2 == Double))
	               		emitRO(opGT,ac,ac1,ac,"op >",sizeofdouble) ;
					else if((type == Integer)||(type2 == Integer))
						emitRO(opGT,ac,ac1,ac,"op >") ;
					else if((type == Char)||(type2 == Char))
						emitRO(opGT,ac,ac1,ac,"op >",sizeofchar) ;
	                break;
				case GE :
					if((type == Double)||(type2 == Double))
	               		emitRO(opGE,ac,ac1,ac,"op >=",sizeofdouble) ;
					else if((type == Integer)||(type2 == Integer))
						emitRO(opGE,ac,ac1,ac,"op >=") ;
					else if((type == Char)||(type2 == Char))
						emitRO(opGE,ac,ac1,ac,"op >=",sizeofchar) ;
	                break;
				case EQ :
					if((type == Double)||(type2 == Double))
	               		emitRO(opEQ,ac,ac1,ac,"op ==",sizeofdouble) ;
					else if((type == Integer)||(type2 == Integer))
						emitRO(opEQ,ac,ac1,ac,"op ==") ;
					else if((type == Char)||(type2 == Char))
						emitRO(opEQ,ac,ac1,ac,"op ==",sizeofchar) ;
	                break;
				case NEQ :
					if((type == Double)||(type2 == Double))
	               		emitRO(opNEQ,ac,ac1,ac,"op !=",sizeofdouble) ;
					else if((type == Integer)||(type2 == Integer))
						emitRO(opNEQ,ac,ac1,ac,"op !=") ;
					else if((type == Char)||(type2 == Char))
						emitRO(opNEQ,ac,ac1,ac,"op !=",sizeofchar) ;
	                break;
				case AND :
	               	emitRO(opAND,ac,ac1,ac,"op and") ;
	                break;
				case OR :
	               	emitRO(opOR,ac,ac1,ac,"op or") ;
	                break;
				case NOT :
               		emitRO(opNOT,ac,0,ac,"op not") ;
                  	break;
            	default:
               		emitComment("BUG: Unknown operator");
               		break;
         	} /* case op */

			if((type == Double)&&(tree->attr.op == PLUS || tree->attr.op == SUB
				|| tree->attr.op == MUT || tree->attr.op == DIV))
				emitRM(opPUSH, ac, 0, 0, "op: push double result",sizeofdouble);
			else
				emitRM(opPUSH, ac, 0, 0, "op: push result");
         	if (TraceCode)  
				emitComment("<- Op") ;
         	break; /* OpK */

    	default:
      		break;
	}
} /* genExp */

/* Procedure cGen recursively generates code by
 * tree traversal
 */
static void cGen( TreeNode * tree, int addrFlag)
{ 
	while(tree != NULL)
  	{ 
  		switch (tree->nodekind) {
			case DecK:
				genDec(tree, addrFlag);
				break;
	      	case StmtK:
	        	genStmt(tree, addrFlag);
	        	break;
	      	case ExpK:
	        	genExp(tree, addrFlag);
	        	break;
	      	default:
	        	break;
    	}
		tree = tree->sibling;
  	}
}

/**********************************************/
/* the primary function of the code generator */
/**********************************************/
/* Procedure codeGen generates code to a code
 * file by traversal of the syntax tree. The
 * second parameter (codefile) is the file name
 * of the code file, and is used to print the
 * file name as a comment in the code file
 */
void codeGen(TreeNode * syntaxTree, char * codefile)
{  
	int	loc;
	emitLoc = 0;
	char *s = (char*)malloc(strlen(codefile)+7);
   	strcpy(s,"File: ");
   	strcat(s,codefile);
  	emitComment("TINY Compilation to TM Code");
   	emitComment(s);
   	/* generate standard prelude */
   	emitComment("Standard prelude:");
   	emitRM(opLD,gp,0,ac,"set location gp");
	emitRM(opLDA,sp,0,gp,"copy gp to sp");
	nGlobalTop = DADDR_SIZE - pTable->memloc;
	printf("nGlobalTop: %d\n", nGlobalTop);
	emitRM(opLDC,tp,nGlobalTop,0,"set tp");
   	emitRM(opST,ac,0,ac,"clear location ac");
	emitRM(opST,mp,0,ac,"load maxaddress from location 0");
   	emitComment("End of standard prelude.");
   	/* generate code for TINY program */
   	cGen(syntaxTree);
   	/* finish */
   	emitComment("End of execution.");
   	emitRO(opHALT,0,0,0,"");
};

/********************************************/
static STEPRESULT stepTM ()
{ 
	INSTRUCTION currentinstruction;
	char	c, c2;
  	int 	pcindex,r,s,t,m,ok,iNum,iNum2,n;
	double	dNum,dNum2;

  	pcindex = reg[PC_REG] ;
	//printf("pcindex:%d\n", pcindex);
  	if ( (pcindex < 0) || (pcindex > IADDR_SIZE)  )
    	return srIMEM_ERR ;
  	reg[PC_REG] = pcindex + 1 ;
  	currentinstruction = iMem[pcindex] ;
  	switch (opClass(currentinstruction.iop) )
  	{ 
  		case opclRR :
    		/***********************************/
      		r = currentinstruction.iarg1 ;
      		s = currentinstruction.iarg2 ;
      		t = currentinstruction.iarg3 ;
      		break;

    	case opclRM :
    		/***********************************/
      		r = currentinstruction.iarg1 ;
      		s = currentinstruction.iarg3 ;
			m = currentinstruction.iarg2 + reg[s] ;
      		if ( (m < 0) || (m > DADDR_SIZE))
         		return srDMEM_ERR ;
      		break;

    	case opclRA :
    		/***********************************/
      		r = currentinstruction.iarg1 ;
      		s = currentinstruction.iarg3 ;
      		m = currentinstruction.iarg2 + reg[s] ;
      		break;
  	} /* case */

  	switch ( currentinstruction.iop)
  	{ 
  		/* RR instructions */
    	case opHALT :
    		/***********************************/
      		printf("HALT: %1d,%1d,%1d\n",r,s,t);
      		return srHALT ;
      		/* break; */

		case opSYSCALL:
			//read
			if(s == ReadC){
				getInput();
				printf("in_Line: %s\n", in_Line);
				if(currentinstruction.isize == sizeofdouble){
					dNum = atof(in_Line);
					memcpy((BYTE*)&dreg[ac1],&dNum,sizeofdouble);
					printf("double read %f %f\n", dNum, reg[r]);
				} else if(currentinstruction.isize == sizeofint){
					iNum = atoi(in_Line);
					memcpy((BYTE*)&reg[ac1],&iNum,sizeofint);
					printf("integer read %d %d\n", iNum, reg[r]);
				} else if(currentinstruction.isize == sizeofchar){
					iNum = atoi(in_Line);
					c = (char)iNum;
					memcpy((BYTE*)&reg[ac1],&c,sizeofchar);
					printf("char read %c %c\n", c, reg[r]);
				}
			}
			//write
			else if(s == WriteC){
				if(currentinstruction.isize == sizeofdouble){
					printf("double write: %f\n", dreg[r]);
				}else if(currentinstruction.isize == sizeofint) {
					memcpy(&iNum,(BYTE*)&reg[r],sizeofint);
					printf("integer write: %d\n", iNum);
				}else if(currentinstruction.isize == sizeofchar) {
					memcpy(&c,(BYTE*)&reg[r],sizeofchar);
					printf("char write: %c\n", c);
				}else if(currentinstruction.isize == typestring) {
					printf("string write: ");
					m = reg[r];
					memcpy(&c,(BYTE*)&dMem[m],sizeofchar);
					while(c != '\0'){
						printf("%c", c);
						memcpy(&c,(BYTE*)&dMem[++m],sizeofchar);
					}
					printf("\n");
				}
			}
			//abs
			else if(s == AbsC){
				iNum = reg[ac];
				printf("before abs %d\n", iNum);
				
				if(iNum <0){
					iNum = - iNum;
					memcpy((BYTE*)&reg[ac],&iNum,sizeofint);
				}
				printf("after abs %d\n", reg[ac]);
			}
			//floor
			else if(s == FloorC){
				printf("before FloorC %f\n", dreg[ac]);
				memcpy((BYTE*)&dNum,&dreg[ac],sizeofdouble);
				dNum = floor(dNum);
				printf("after FloorC %f\n", dNum);
				memcpy((BYTE*)&dreg[ac],&dNum,sizeofdouble);
			}
			//ceil
			else if(s == CeilC){
				printf("before CeilC %f\n", dreg[ac]);
				memcpy((BYTE*)&dNum,&dreg[ac],sizeofdouble);
				dNum = ceil(dNum);
				printf("after CeilC %f\n", dNum);
				memcpy((BYTE*)&dreg[ac],&dNum,sizeofdouble);
			}
			//fabs
			else if(s == FAbsC){
				memcpy((BYTE*)&dNum,&dreg[ac],sizeofdouble);
				printf("before fabs %f\n", dNum);
				
				if(dNum <0){
					dNum = - dNum;
					memcpy((BYTE*)&dreg[ac],&dNum,sizeofdouble);
				}
				printf("after fabs %f\n", dreg[ac]);
			}
			//fmod
			else if(s == FModC){
				memcpy((BYTE*)&dNum,&dreg[ac1],sizeofdouble);
				memcpy((BYTE*)&dNum2,&dreg[ac],sizeofdouble);
				printf("before fabs %f %f\n", dNum, dNum2);
				dNum = fmod(dNum, dNum2);
				memcpy((BYTE*)&dreg[ac],&dNum,sizeofdouble);				
				printf("after fabs %f\n", dreg[ac]);
			}
			//strcmp
			else if(s == StrCmpC){
				m = reg[ac];
				n = reg[ac1];
				for(;;){
					memcpy(&c,(BYTE*)&dMem[m++],sizeofchar);
					memcpy(&c2,(BYTE*)&dMem[n++],sizeofchar);
					if(c != c2)
						break;
				}
				if(c > c2)
					iNum = 1;
				else if(c == c2)
					iNum = 0;
				else
					iNum = -1;
				memcpy((BYTE*)&reg[ac],&iNum,sizeofint);
			}
			//strcat
			else if(s == StrCatC){
				
			}
			//strcpy

⌨️ 快捷键说明

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