📄 compiler.c
字号:
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 + -