📄 compiler.c
字号:
fprintf(file, "\t%s\n", "fucompp"); fprintf(file, "\t%s\n", "fnstsw %ax"); fprintf(file, "\t%s\n", "testb $69, %ah"); fprintf(file, "\t%s%d\n", "je TRUElabel", booll); } if(strcmp(tree->value, ">=")==0){ //fprintf(file, "\t%s\n", "fxch"); fprintf(file, "\t%s\n", "fucompp"); fprintf(file, "\t%s\n", "fnstsw %ax"); fprintf(file, "\t%s\n", "testb $5, %ah"); fprintf(file, "\t%s%d\n", "je TRUElabel", booll); } if(strcmp(tree->value, "<")==0){ fprintf(file, "\t%s\n", "fxch"); fprintf(file, "\t%s\n", "fucompp"); fprintf(file, "\t%s\n", "fnstsw %ax"); fprintf(file, "\t%s\n", "testb $69, %ah"); fprintf(file, "\t%s%d\n", "je TRUElabel", booll); } if(strcmp(tree->value, "<=")==0){ fprintf(file, "\t%s\n", "fxch"); fprintf(file, "\t%s\n", "fucompp"); fprintf(file, "\t%s\n", "fnstsw %ax"); fprintf(file, "\t%s\n", "testb $5, %ah"); fprintf(file, "\t%s%d\n", "je TRUElabel", booll); } if(strcmp(tree->value, "==")==0){ //fprintf(file, "\t%s\n", "fxch"); fprintf(file, "\t%s\n", "fucompp"); fprintf(file, "\t%s\n", "fnstsw %ax"); fprintf(file, "\t%s\n", "andb $69, %ah"); fprintf(file, "\t%s\n", "cmpb $64, %ah"); fprintf(file, "\t%s%d\n", "je TRUElabel", booll); } if(strcmp(tree->value, "!=")==0){ //fprintf(file, "\t%s\n", "fxch"); fprintf(file, "\t%s\n", "fucompp"); fprintf(file, "\t%s\n", "fnstsw %ax"); fprintf(file, "\t%s\n", "andb $69, %ah"); fprintf(file, "\t%s\n", "xorb $64, %ah"); fprintf(file, "\t%s%d\n", "jne TRUElabel", booll); } fprintf(file, "\t%s\n","movl $0, %eax"); fprintf(file, "\t%s%d\n", "jmp ENDBOOL", booll); fprintf(file, "%s%d%s\n", "TRUElabel", booll,":"); /* true label */ fprintf(file, "\t%s\n", "movl $1, %eax"); fprintf(file, "%s%d%s\n", "ENDBOOL", booll,":"); /* end label */ } }void gen_if(FILE *file, symnode *tree){ if(tree==NULL) return; int ifl; gen_assign(file, tree->sibling->next); //fprintf(file, "\t%s\n","popl %eax"); fprintf(file, "\t%s\n","cmpl $0, (%esp)"); ifl=IFlabel; if(strcmp(tree->value,"ifelse")==0) fprintf(file, "\t%s%d\n", "je ELSElabel", ifl); else fprintf(file, "\t%s%d\n", "je ENDIFlabel", ifl); IFlabel++; gen_func_content(file, tree->sibling->sibling->next); if(strcmp(tree->value,"ifelse")==0){ fprintf(file, "\t%s%d\n", "jmp ENDIFlabel",ifl); fprintf(file, "%s%d:\n", "ELSElabel",ifl); gen_func_content(file, tree->sibling->sibling->sibling->next); //fprintf(file, "\t%s%d\n", "jmp ENDIFlabel",ifl); } fprintf(file, "%s%d:\n", "ENDIFlabel",ifl); }void gen_switch(FILE *file, symnode *tree){ if(tree==NULL) return; int switchl; symnode caselist; switchl=SWITCHlabel; SWITCHlabel++; CASElabel=0; gen_assign(file, tree->sibling->next); // the returned value is at top of stack fprintf(file, "\t%s\n", "popl %eax"); gen_case_condition(file, tree->sibling->sibling->next); CASElabel=0; gen_case(file, tree->sibling->sibling->next); fprintf(file, "%s%d:\n", "ENDSWITCHlabel",switchl); return;}void gen_case_condition(FILE *file, symnode *tree){ if(tree==NULL) return; gen_case_condition(file, tree->next); gen_case_condition(file, tree->sibling); if(strcmp(tree->name, "case")==0){ int casel; casel = CASElabel; fprintf(file,"\t%s%s, %s\n","cmpl $", tree->sibling->next->value, "%eax"); fprintf(file, "\t%s%d%s%d\n", "je S", SWITCHlabel-1, "CASElabel",casel); CASElabel=casel; CASElabel++; return; } if(strcmp(tree->name, "default")==0){ fprintf(file, "\t%s%d\n", "jmp DEFAULT", SWITCHlabel-1); return; }}void gen_case(FILE *file, symnode *tree){ if (tree==NULL) return; gen_case(file, tree->next); gen_case(file, tree->sibling); if(strcmp(tree->name, "break")==0){ gen_break(file); return; } if(strcmp(tree->name, "case")==0){ int casel; casel = CASElabel; fprintf(file, "%s%d%s%d:\n", "S", SWITCHlabel-1, "CASElabel", casel); gen_func_content(file, tree->sibling->sibling->next); CASElabel=casel; CASElabel++; return; } if(strcmp(tree->name, "default")==0){ fprintf(file, "%s%d:\n", "DEFAULT", SWITCHlabel-1); gen_func_content(file, tree->sibling->next); return; }}void gen_for(FILE *file, symnode *tree){ if(tree==NULL) return; int forl; forl=FORlabel; FORlabel++; if(tree->sibling->next!=NULL) gen_assign(file, tree->sibling->next); fprintf(file, "%s%d:\n", "FORlabel",forl); if(tree->sibling->sibling->next!=NULL){ gen_assign(file, tree->sibling->sibling->next); fprintf(file, "\t%s\n","popl %eax"); fprintf(file, "\t%s\n","cmpl $0, %eax"); fprintf(file, "\t%s%d\n", "je ENDFORlabel", forl); } if(strcmp(tree->sibling->sibling->sibling->name, "stmt")==0){ gen_func_content(file, tree->sibling->sibling->sibling->next); }else gen_func_content(file, tree->sibling->sibling->sibling->sibling->next); fprintf(file, "%s%d:\n", "FOR_COUNT", forl); if(strcmp(tree->sibling->sibling->sibling->name, "exp")==0) gen_assign(file, tree->sibling->sibling->sibling->next); fprintf(file, "\t%s%d\n", "jmp FORlabel", forl); fprintf(file, "%s%d:\n", "ENDFORlabel", forl); return;}void gen_while(FILE *file, symnode *tree){ if(tree==NULL) return; int whilel; whilel=WHILElabel; WHILElabel++; fprintf(file, "%s%d:\n", "WHILElabel",whilel); gen_assign(file, tree->sibling->next); fprintf(file, "\t%s\n","popl %eax"); fprintf(file, "\t%s\n","cmpl $0, %eax"); fprintf(file, "\t%s%d\n", "je ENDWHILElabel", whilel); gen_func_content(file, tree->sibling->sibling->next); fprintf(file, "\t%s%d\n", "jmp WHILElabel",whilel); fprintf(file, "%s%d:\n", "ENDWHILElabel",whilel); }void gen_dowhile(FILE *file, symnode *tree){ if(tree==NULL) return; int dol; dol=DOlabel; DOlabel++; fprintf(file, "%s%d:\n", "DOlabel",dol); gen_func_content(file, tree->sibling->next); gen_assign(file, tree->sibling->sibling->next); fprintf(file, "\t%s\n","popl %eax"); fprintf(file, "\t%s\n","cmpl $0, %eax"); fprintf(file, "\t%s%d\n", "jne DOlabel", dol); fprintf(file, "%s%d:\n", "ENDDOlabel",dol);}void gen_break(FILE *file){ switch (loopType){ case 1: fprintf(file, "\t%s%d\n", "jmp ENDWHILElabel",WHILElabel-1); break; case 2: fprintf(file, "\t%s%d\n", "jmp ENDDOlabel",DOlabel-1); break; case 3: fprintf(file, "\t%s%d\n", "jmp ENDFORlabel",FORlabel-1); break; case 4: fprintf(file, "\t%s%d\n", "jmp ENDSWITCHlabel",SWITCHlabel-1); break; default: printf("--compiling error: \"break\" only used within loops(for, while) or \"switch\"\n"); exit(1); } }void gen_continue(FILE *file){ switch (loopType){ case 1: fprintf(file, "\t%s%d\n", "jmp WHILElabel",WHILElabel-1); break; case 2: fprintf(file, "\t%s%d\n", "jmp DOlabel",DOlabel-1); break; case 3: fprintf(file, "\t%s%d\n", "jmp FOR_COUNT",FORlabel-1); break; default: printf("--compiling error: \"continue\" only used with loops(for, while)\n"); exit(1); } } void gen_println(FILE *file, symnode *tree){ int type; if(tree == NULL) return; //printf("%s\n",tree->name); if(strcmp(tree->name, "offset")==0){ gen_OffsetIDAddress( file, tree); type=tree->sibling->symTab->type; //printf("type: %d\n", type); if(type==5){ int size; type = getMemberType(tree->sibling->symTab->structtype, tree->sibling->value); size = getMemberSize(tree->sibling->symTab->structtype, tree->sibling->value); //printf("size: %d\n", size); if(size>1 && strcmp(tree->sibling->name, "exp")!=0){ fprintf(file, "\t%s\n", "popl %eax"); print_char_array(file, size ); return; } } fprintf(file, "\t%s\n", "popl %ebx"); fprintf(file, "\t%s\n", "movl (%ebx), %eax"); switch(type){ case 0: fprintf(file, "\t%s\n", "call cshow"); break; case 1: fprintf(file, "\t%s\n", "call ishow"); break; case 2: fprintf(file, "\t%s\n", "fld (%ebx)"); fprintf(file, "\t%s\n", "call fshow"); break; } return; } if(strcmp(tree->name, "-")==0 || strcmp(tree->name, "OP")==0 || strcmp(tree->name, "cast")==0 || strcmp(tree->name, "ASSIGN")==0 || ( strcmp(tree->name, "ID")==0 && tree->symTab->nameType==1)){ empty(); gen_assign(file, tree); int a; a = pop(); switch(a){ case 0: fprintf(file, "\t%s\n", "popl %eax"); fprintf(file, "\t%s\n", "call cshow\t\t# call cshow function"); break; case 1: fprintf(file, "\t%s\n", "popl %eax"); fprintf(file, "\t%s\n", "call ishow\t\t# call ishow function"); break; case 2: fprintf(file, "\t%s\n", "flds (%esp)"); fprintf(file, "\t%s\n", "call fshow"); fprintf(file, "\t%s\n", "addl $4, %esp"); break; } return; } gen_println(file, tree->next); if(strcmp(tree->name,"STRING")==0){ fprintf(file, "\t%s\n", "movl $SYS_write, %eax\t# load the write call number"); fprintf(file, "\t%s\n", "movl $STDOUT, %ebx\t\t# get the output channel"); fprintf(file, "\t%s%d,%s\n", "movl $literal",tree->strIndex, "%ecx\t\t# get the literal string"); fprintf(file, "\t%s%d,%s\n", "movl $len",tree->strIndex, "%edx\t\t# string length"); fprintf(file, "\t%s\n", "int $0x80"); return; } if(strcmp(tree->name,"INT_V")==0){ fprintf(file, "\t%s $%s,%s\n", "movl",tree->value, "%eax\t\t# get the integer"); fprintf(file, "\t%s\n", "call ishow\t\t# call ishow function"); return ; } if(strcmp(tree->name,"CHAR_V")==0){ fprintf(file, "\t%s $%s,%s\n", "movl",tree->value, "%eax\t\t# pass the char"); fprintf(file, "\t%s\n", "call cshow\t\t# call cshow function"); return; } if(strcmp(tree->name,"FLT_V")==0){ //float f; //f=atof(tree->value); //printf("FLT: %f\n",f); fprintf(file, "\t%s\n", "subl $4, %esp"); fprintf(file, "\t%s $%s, %s\n", "movl", tree->value, "(%esp)"); fprintf(file, "\t%s\n", "flds (%esp)"); fprintf(file, "\t%s\n", "call fshow"); fprintf(file, "\t%s\n", "addl $4, %esp"); return; } if(strcmp(tree->name,"ID")==0){ if(tree->symTab->nameType==0){ // if the id is a variable symrec *tmp = tree->symTab; char addr[20]; getIDAddr(tmp,addr); if(tree->symTab->isArray==1){ int len; len = tree->symTab->numArray; fprintf(file, "\t%s%s, %s\n", "leal ", addr, "%eax"); print_char_array(file, len); return; } if(tree->symTab->type==0){ //if it is a char type fprintf(file, "\t%s %s,%s\n", "movl",addr, "%eax\t\t# pass the char"); fprintf(file, "\t%s\n", "call cshow"); return; } if(tree->symTab->type==1){ fprintf(file, "\t%s %s,%s\n", "movl",addr, "%eax\t\t# get the integer value of the ID"); fprintf(file, "\t%s\n", "call ishow"); return ; } if(tree->symTab->type==2){ //fprintf(file, "\t%s %s,%s\n", "movl",addr, "%eax\t\t# get the float value of the ID"); fprintf(file, "\t%s%s\n", "flds ", addr); fprintf(file, "\t%s\n", "call fshow"); return ; } } } gen_println(file, tree->sibling);}void print_char_array(FILE *file, int len){ int i; //fprintf(file, "\t%s%s,%s\n", "movl ",addr, "%ecx"); fprintf(file, "\t%s%d, %s\n", "subl $",len, "%esp"); for(i=0;i<len;i++){ fprintf(file, "\t%s\n", "movb (%eax), %bl"); fprintf(file, "\t%s%d%s\n", "movb %bl, ", i,"(%esp)"); fprintf(file, "\t%s\n", "addl $4, %eax"); } fprintf(file, "\t%s\n", "movl $SYS_write, %eax\t\t# print a char array"); fprintf(file, "\t%s\n", "movl $STDOUT, %ebx"); fprintf(file, "\t%s\n", "movl %esp, %ecx"); fprintf(file, "\t%s%d,%s\n", "movl $",len, "%edx"); fprintf(file, "\t%s\n", "int $0x80"); fprintf(file, "\t%s%d, %s\n", "addl $",len, "%esp"); }void print_nl(FILE *file){ fprintf(file, "\t%s\n", "call newline"); /* fprintf(file, "\t%s\n", "movl $SYS_write, %eax\t\t# print a \"newline\""); fprintf(file, "\t%s\n", "movl $STDOUT, %ebx"); fprintf(file, "\t%s\n", "movl $newline, %ecx"); fprintf(file, "\t%s\n", "movl $nl_length, %edx"); fprintf(file, "\t%s\n", "int $0x80"); */}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -