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

📄 compiler.c

📁 一个编译器的例子,基于c语言,在linux下开发 现在了简单的c语言例子
💻 C
📖 第 1 页 / 共 4 页
字号:
     if(strcmp(tree->value, "+O")==0){    // if it's ++id        if(a!=2.0){     		fprintf(file, "\t%s\n","incl (%eax)"); 		fprintf(file, "\t%s\n","push (%eax)");	}else{		fprintf(file, "\t%s\n", "fld1");		fprintf(file, "\t%s\n", "flds (%eax)");		fprintf(file, "\t%s\n", "faddp %st, %st(1)");		fprintf(file, "\t%s\n", "fstps (%eax)");		fprintf(file, "\t%s\n", "push (%eax)");	}		       }     if(strcmp(tree->value, "-O")==0){    // if it's --id        if(a!=2.0){      		fprintf(file, "\t%s\n","decl (%eax)");		fprintf(file, "\t%s\n","push (%eax)"); 	}else{		fprintf(file, "\t%s\n", "fld1");	  	fprintf(file, "\t%s\n", "flds (%eax)");		fprintf(file, "\t%s\n", "fsubp %st, %st(1)");		fprintf(file, "\t%s\n", "fstps (%eax)");                	fprintf(file, "\t%s\n", "push (%eax)");	}      }     push(a);              }void gen_assign(FILE *file, symnode *tree){   if(tree==NULL) return;   if(strcmp(tree->name, "ASSIGN")==0){      // LHS should be the address, RHS is the value	gen_assign_op(file,tree);  //already push ecx onto the stack	//fprintf(file, "\t%s\n", "pushl %eax");		return ;   }      if(strcmp(tree->name, "offset")==0){         gen_OffsetIDAddress( file, tree);	 fprintf(file, "\t%s\n", "popl %eax");	 fprintf(file, "\t%s\n", "pushl (%eax)");	 int a;	 a=pop();	 //printf("offset : %d\n",a);	 push(a);	 return;   }   if(strcmp(tree->name, "unaryOp")==0){         gen_unary_op(file, tree);	 return;   }        gen_assign(file, tree->next);   gen_assign(file, tree->sibling);     if(strcmp(tree->name,"INT_V")==0){	fprintf(file, "\t%s%s\n", "pushl $",tree->value);	push(1.0);	return;   }      if(strcmp(tree->name,"FLT_V")==0){	fprintf(file, "\t%s%s\n", "pushl $",tree->value);	push(2.0);	return;   }         if(strcmp(tree->name,"CHAR_V")==0){	fprintf(file, "\t%s%s\n", "pushl $",tree->value);	push(0.0);	return;   }      if(strcmp(tree->name,"-")==0){        float a;	a=pop();	if(a==2.0){		fprintf(file, "\t%s\n", "xorl $-2147483648, (%esp)");		push(2.0);	}else{         		fprintf(file, "\t%s\n", "negl  (%esp)");		push(1.0);	}	return;	    }   if(strcmp(tree->name,"!")==0){   	float a;	a=pop();	if(a==2){		printf("--compiling messege (line %d): \"!\" operation not support float at the moment\n", tree->line);		exit(0);	}	fprintf(file,"\t%s\n","cmpl $0, (%esp)");	fprintf(file,"\t%s\n","sete %al");	fprintf(file,"\t%s\n","movzbl %al, %eax");	fprintf(file,"\t%s\n","movl %eax, (%esp)");	push(1);	return;	   }   if(strcmp(tree->name,"cast")==0){              float a;	      a = pop();	                    if(strcmp(tree->value,"char")==0){	          if(a==2.0){		       printf("--compiling messege (line %d): Cannot cast from float to char\n", tree->line);		       exit(0);		  }		  		  push(0.0);	      }              if(strcmp(tree->value,"int")==0){	          if(a==2.0){		 	fprintf(file, "\t%s\n", "flds (%esp)");		        fprintf(file, "\t%s\n", "subl $4, %esp");			fprintf(file, "\t%s\n", "fnstcw (%esp)\t\t# save the cast flag");			fprintf(file, "\t%s\n", "movw (%esp), %cx");			fprintf(file, "\t%s\n", "movb $12, %ch");			fprintf(file, "\t%s\n", "movw %cx,  2(%esp)");			fprintf(file, "\t%s\n", "fldcw 2(%esp)\t\t# set the new cast flag");						fprintf(file, "\t%s\n", "fistpl 4(%esp)");			fprintf(file, "\t%s\n", "fldcw (%esp)\t\t# restore the cast flag as before");			fprintf(file, "\t%s\n", "addl $4, %esp");			//fprintf(file, "\t%s\n",  "fistpl (%esp)");		  }		  push(1.0); 	      }              if(strcmp(tree->value,"float")==0){	               if(a==2.0){		                 printf("--compiling messege (line %d): Cannot cast from float to char\n", tree->line);		                 exit(0);		       }	      	                if(a==1.0 ){		        	fprintf(file, "\t%s\n", "fildl (%esp)");				fprintf(file, "\t%s\n", "fstps (%esp)");		       }		       push(2.0);	      }              if(strcmp(tree->value,"double")==0){	      }              if(strcmp(tree->value,"struct")==0){	      }	      return;   }               if(strcmp(tree->name,"ID")==0){      if(tree->symTab->nameType ==0){                   //if is a variable         char addr[20];	 getIDAddr(tree->symTab, addr);	 if((tree->symTab->type==5) || (tree->symTab->isArray==1)){	    fprintf(file, "\t%s %s, %s\n", "leal",  addr, "%eax\t\t# operand is array or structure");	    //if(tree->symTab->type=5)	    	push(1.0);            //  save the type in stack	    //else	    	//push(tree->symTab->type);	 }else{	    float type;            fprintf(file,"\t%s%s\n","pushl ",addr);	    type=(float)(tree->symTab->type);        // save the type in stack	    //if(type == 0.0) type = 1.0;	    push(type);	    return;	    }      }      else{ 	fprintf(file, "\t%s %s\t\t# call function to get result to return\n", "call", tree->symTab->name);	int i;	for(i=0;i<tree->symTab->numArgs;i++){	    fprintf(file, "\t%s\n", "pop %edx\t\t# release pushed arguments memory after call");	    pop();    // pop the saved types	}	push((float)(tree->symTab->type));    // save the returned  value type      }      fprintf(file, "\t%s\n", "pushl %eax");      return;   }      if(strcmp(tree->name, "CMP")==0){        gen_relation_code(file, tree);	fprintf(file, "\t%s\n", "pushl %eax");	push(1.0);	return;     }   if(strcmp(tree->name, "&&")==0){        gen_logic_and(file); 	fprintf(file, "\t%s\n", "pushl %eax");	return;     }         if(strcmp(tree->name, "||")==0){        gen_logic_or(file);	fprintf(file, "\t%s\n", "pushl %eax");	return;     }                if(strcmp(tree->name,"OP")==0){        fprintf(file, "\t%s\n", "\t\t\t# arithmetic calculate");        gen_operation(file, tree);             return;   }}void getOperator(const char* opType, char * operator){    //if(opType==NULL) return ;    if(strcmp(opType,"+")==0)  strcpy(operator, "addl");    if(strcmp(opType,"-")==0)  strcpy(operator, "subl");    if(strcmp(opType,"*")==0)  strcpy(operator, "imull");    //if(strcmp(opType,"/")==0)  strcpy(operator, "idivl");         //if(strcmp(opType,"<<")==0)  strcpy(operator, "sall");                //if(strcmp(opType,"<<")==0)  strcpy(operator, "sarl");    if(strcmp(opType,"&")==0)  strcpy(operator, "andl");    if(strcmp(opType,"|")==0)  strcpy(operator, "orl");    if(strcmp(opType,"^")==0)  strcpy(operator, "xorl");}void gen_operation(FILE *file, symnode *tree){       char operator[20];       float a, b; 	b=pop();	a=pop();               if(strcmp(tree->value, "/")==0){    // divide always uses FPU to calculate		if((b==1.0 || b==0.0)  && (a==0.0 || a==1.0)){			fprintf(file, "\t%s\n", "popl %ebx");			fprintf(file, "\t%s\n", "popl %eax");  			fprintf(file, "\tcltd\n");			fprintf(file, "\t%s\n","idivl %ebx");			fprintf(file, "\t%s\n", "pushl %eax");			push(1.0);		}else{			if(b==2.0)				fprintf(file, "\t%s\n", "fld (%esp)");			else				fprintf(file, "\t%s\n", "fildl (%esp)");			if(a==2.0)				fprintf(file, "\t%s\n", "fld 4(%esp)");			else				fprintf(file, "\t%s\n", "fildl 4(%esp)");						fprintf(file, "\t%s\n", "fdivp %st, %st(1)");			fprintf(file, "\t%s\n", "fstps 4(%esp)");			fprintf(file, "\t%s\n", "addl $4, %esp");						push(2.0);		}                        return;	            }       	if(strcmp(tree->value, "%")==0){        	if((b==1.0 || b==0.0)  && (a==0.0 || a==1.0)){				fprintf(file, "\t%s\n", "popl %ebx");			fprintf(file, "\t%s\n", "popl %eax");  				fprintf(file, "\tcltd\n");			fprintf(file, "\t%s\n","idivl %ebx");			fprintf(file, "\t%s\n","movl %edx, %eax");			fprintf(file, "\t%s\n", "pushl %eax");			push(1.0);			return;		}	}		if(strcmp(tree->value, "<<")==0){        	if(b==1.0 && a==1.0){				fprintf(file, "\t%s\n", "popl %ecx");			fprintf(file, "\t%s\n", "popl %eax");  							fprintf(file, "\t%s\n","sall %cl, %eax");			fprintf(file, "\t%s\n", "pushl %eax");			push(1.0);			return;		}	}	if(strcmp(tree->value, ">>")==0){		if(b==1.0 && a==1.0){			fprintf(file, "\t%s\n", "popl %ecx");			fprintf(file, "\t%s\n", "popl %eax");  							fprintf(file, "\t%s\n","sarl %cl, %eax");			fprintf(file, "\t%s\n", "pushl %eax");			push(1.0);			return;		}	}        if((b==1.0 || b==0.0)  && (a==0.0 || a==1.0)){				fprintf(file, "\t%s\n", "popl %ebx");		  				getOperator(tree->value, operator);		if(strcmp(tree->value,"+")==0 || strcmp(tree->value,"-")==0){			fprintf(file, "\t%s %s, %s\n",operator, "%ebx", "(%esp)");		}else{			fprintf(file, "\t%s\n", "popl %eax");			fprintf(file, "\t%s %s, %s\n",operator, "%ebx", "%eax");			fprintf(file, "\t%s\n", "pushl %eax");		}		push(1.0);		return;	}else{		if(b==2.0)			fprintf(file, "\t%s\n", "flds (%esp)");		else			fprintf(file, "\t%s\n", "fildl (%esp)");		if(a==2.0)			fprintf(file, "\t%s\n", "flds 4(%esp)");		else			fprintf(file, "\t%s\n", "fildl 4(%esp)");					if(strcmp(tree->value, "+")==0){		        fprintf(file, "\t%s\n", "faddp %st, %st(1)");		}		if(strcmp(tree->value, "-")==0){		        fprintf(file, "\t%s\n", "fsubp %st, %st(1)");		}		if(strcmp(tree->value, "*")==0){		        fprintf(file, "\t%s\n", "fmulp %st, %st(1)");		}		fprintf(file, "\t%s\n", "fstps 4(%esp)");		fprintf(file, "\t%s\n", "addl $4, %esp");				push(2.0);			}	}void gen_assign_op(FILE *file, symnode *tree){        if(tree==NULL) return;	//printf("node:%s  value:%s  n-name:%s s-name:%s\n", tree->name,tree->value,tree->next->name,tree->sibling->name);	if(strcmp(tree->next->name, "ID")==0 && strcmp(tree->value, "=")==0 && 		(strcmp(tree->sibling->name, "CHAR_V")==0|| strcmp(tree->sibling->name, "INT_V")==0 ||			 strcmp(tree->sibling->name, "FLT_V")==0 )){		//printf("hehehehe\n");		char addr[40];		pop();		pop();		getIDAddr(tree->next->symTab, addr);		if( (tree->next->symTab->type==0 && strcmp(tree->sibling->name, "FLT_V")!=0) ||		    (tree->next->symTab->type==1 && strcmp(tree->sibling->name, "FLT_V")!=0) ||		    (tree->next->symTab->type==2 && strcmp(tree->sibling->name, "FLT_V")==0)  ){						fprintf(file, "\t%s%s, %s\n", "movl $", tree->sibling->value, addr);						fprintf(file, "\t%s\n", "pushl %eax");			push(1.0);	     			return;		}	}				float a,b;	gen_OffsetIDAddress(file, tree->next);	a=pop(); 	gen_assign(file, tree->sibling);	b=pop();		//printf("ass: a:%f, b:%f\n",a,b);	if(strcmp(tree->value,"=")==0){	         if( ((a==0.0 || a==1.0) && (b==0.0 || b==1.0)) || (a==2.0 && b==2.0)){			fprintf(file, "\t%s\n","popl %ebx"); 			fprintf(file, "\t%s\n","popl %eax"); 				fprintf(file, "\t%s\n", "movl %ebx, (%eax)");   			fprintf(file, "\t%s\n", "pushl (%eax)");			if(a==1.0) push(1.0);			if(a==2.0) push(2.0);		 }		 if((a==0.0 || a==1.0) && b==2.0){		 	fprintf(file, "\t%s\n", "flds (%esp)");			fprintf(file, "\t%s\n", "popl %ebx");			fprintf(file, "\t%s\n", "popl %eax");					        fprintf(file, "\t%s\n", "subl $4, %esp");			fprintf(file, "\t%s\n", "fnstcw (%esp)\t\t# save the cast flag");			fprintf(file, "\t%s\n", "movw (%esp), %cx");			fprintf(file, "\t%s\n", "movb $12, %ch");			fprintf(file, "\t%s\n", "movw %cx,  2(%esp)");			fprintf(file, "\t%s\n", "fldcw 2(%esp)\t\t# set the new cast flag");						fprintf(file, "\t%s\n", "fistpl (%eax)");			fprintf(file, "\t%s\n", "fldcw (%esp)\t\t# restore the cast flag as before");			fprintf(file, "\t%s\n", "addl $4, %esp");			fprintf(file, "\t%s\n", "push (%eax)");			push(1.0);		 }		 if(a==2.0 && (b==0.0 || b==1.0)){		 	fprintf(file, "\t%s\n", "fildl (%esp)");			fprintf(file, "\t%s\n", "movl 4(%esp), %eax");			fprintf(file, "\t%s\n", "fstps (%eax)");			fprintf(file, "\t%s\n", "popl %ebx");			fprintf(file, "\t%s\n", "popl %ebx");			fprintf(file, "\t%s\n", "push (%eax)");			push(2.0);		 }		 		 return;	}	if(strcmp(tree->value,"+=")==0){        	if((b==1.0 || b==0.0)  && (a==0.0 || a==1.0)){					fprintf(file, "\t%s\n","popl %ebx"); 			fprintf(file, "\t%s\n","popl %eax"); 				fprintf(file, "\t%s\n", "addl %ebx, (%eax)");			fprintf(file, "\t%s\n", "pushl (%eax)");			push(1.0);			return;		}				if(b==2.0)			fprintf(file, "\t%s\n", "flds (%esp)");		else			fprintf(file, "\t%s\n", "fildl (%esp)");					fprintf(file, "\t%s\n", "popl %ebx");		fprintf(file, "\t%s\n", "popl %eax");						if(a==2.0)			fprintf(file, "\t%s\n", "flds (%eax)");		else			fprintf(file, "\t%s\n", "fildl (%eax)");				fprintf(file, "\t%s\n", "faddp %st, %st(1)");		 if( a==2.0){				fprintf(file, "\t%s\n", "fstps (%eax)");

⌨️ 快捷键说明

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