void CodeText::addFun(const std::string& funString) { std::vector<std::string> vec = CStringManager::split(funString, " "); if (vec.size() < 2) { return; } std::string note = vec[0]; std::string funName = vec[1]; std::string returnNote = ""; std::string returnType = "void"; if (vec.size() >= 4) { returnNote = vec[2]; returnType = vec[3]; } addFun(note, funName, returnNote, returnType); }
int ex(nodeType *p) { int oldx,oldy,lbl1, lbl2,lbl3; int oldoutest; int oldoff = 0; struct dic *tmp; struct arrayDic *arrayTmp; struct dic *oldhead = NULL; struct fun *ftmp; if (!p) return 0; switch(p->type) { case typeCon: // printf("---typeCon---\n"); printf("\tpush\t%d\n", p->con.value); ischar = 0; ++fpoffset; //break; return p->con.value; case typeCha: // printf("---typeCha---\n"); printf("\tpush\t%d\n", p->cha.value); ischar = 1; ++fpoffset;//sad break; case typeString: printf("\tpush\t%s\n", p->strg.value); ++fpoffset; break; case typeId: // printf("---typeId:%s---\n",p->id.id); if(p->id.global) { tmp = findVar(p->id.id,NULL); } else tmp = findVar(p->id.id,head); if(tmp == NULL) { printf("cannot be refer since it does not exist.\n"); exit(1); } if(!isg) printf("\tpush\tfp[%d]\n", tmp->pos); else printf("\tpush\tsb[%d]\n", tmp->pos); ischar = tmp->ischar; ++fpoffset; break; case typeOpr: // printf("---typeOpr---\n"); switch(p->opr.oper) { case BREAK: if(outy!=-1) printf("\tjmp\tL%03d\n",outy); else { printf("break must be inside a loop.\n"); exit(0); } break; case CONTINUE: if(outx!=-1) printf("\tjmp\tL%03d\n",outx); else { printf("continue must be inside a loop.\n"); exit(0); } break; case FOR: lbl1 = lbl++; lbl2 = lbl++; lbl3 = lbl++; oldx = outx; oldy = outy; outx = lbl3; outy = lbl2; ex(p->opr.op[0]); printf("L%03d:\n", lbl1); ex(p->opr.op[1]); printf("\tj0\tL%03d\n", lbl2); --fpoffset; ex(p->opr.op[3]); printf("L%03d:\n", lbl3); ex(p->opr.op[2]); printf("\tjmp\tL%03d\n", lbl1); printf("L%03d:\n", lbl2); outx = oldx; outy = oldy; break; case WHILE: lbl1 = lbl++; lbl2 = lbl++; oldx = outx; oldy = outy; outx = lbl1; outy = lbl2; printf("L%03d:\n", lbl1); ex(p->opr.op[0]); printf("\tj0\tL%03d\n", lbl2); --fpoffset; ex(p->opr.op[1]); printf("\tjmp\tL%03d\n", lbl1); printf("L%03d:\n", lbl2); outx = oldx; outy = oldy; break; case DO: lbl1 = lbl++; lbl2 = lbl++; oldx = outx; oldy = outy; outx = lbl1; outy = lbl2; printf("L%03d:\n",lbl1); ex(p->opr.op[0]); ex(p->opr.op[1]); printf("\tj0\tL%03d\n",lbl2); --fpoffset; printf("\tjmp\tL%03d\n",lbl1); printf("L%03d:\n",lbl2); outx = oldx; outy = oldy; break; case GETI: parsegeti(p->opr.op[0]); break; case GETC: parsegetc(p->opr.op[0]); break; case PUTIN: parseputin(p->opr.op[0]); break; case PUTI: if(p->opr.nops==1) parseputi(p->opr.op[0]); else parseputifm(p->opr.op[0],p->opr.op[1]); break; case PUTCN: parseputcn(p->opr.op[0]); break; case PUTC: if(p->opr.nops==1) parseputc(p->opr.op[0]); else parseputcfm(p->opr.op[0],p->opr.op[1]); break; case PUTSN: parseputsn(p->opr.op[0]); break; case PUTS: if(p->opr.nops==1) parseputs(p->opr.op[0]); // TODO: formatted // else // parseputcfm(p->opr.op[0],p->opr.op[1]); break; case IF: ex(p->opr.op[0]); if (p->opr.nops > 2) { /* if else */ printf("\tj0\tL%03d\n", lbl1 = lbl++); --fpoffset; ex(p->opr.op[1]); printf("\tjmp\tL%03d\n", lbl2 = lbl++); printf("L%03d:\n", lbl1); ex(p->opr.op[2]); printf("L%03d:\n", lbl2); } else { /* if */ printf("\tj0\tL%03d\n", lbl1 = lbl++); --fpoffset; ex(p->opr.op[1]); printf("L%03d:\n", lbl1); } break; case ARRAY: // array declaration; single dimension flag = 0; ++fpoffset; if(p->opr.op[0]->id.global) tmp = findVar(p->opr.op[0]->id.id,NULL); else tmp = findVar(p->opr.op[0]->id.id,head); if (tmp != NULL){ // already declared printf("ERROR: duplicated array declaration: %s\n", p->opr.op[0]->id.id); // execution should stop here so the value of fp is no longer relevant exit(-1); } if(outest) tmp = addVar2Point(p->opr.op[0]->id.id, &global); else tmp = addVar2Point(p->opr.op[0]->id.id, &head); // int dim = p->opr.op[1]->con.value; if(p->opr.nops == 2){ // without initialization // default init value is 0; "type" is 0: the type is not determined yet //tmp->ref = newArray(p->opr.op[0]->id.id, 0, 0, getDims(p->opr.op[1])); tmp->ref = newArray(p->opr.op[0]->id.id, 0, 0, p->opr.op[1]); } else{ // with initialization switch(p->opr.op[3]->con.value){ case 1: // integer array //tmp->ref = newArray(p->opr.op[0]->id.id, p->opr.op[2]->con.value, 1, getDims(p->opr.op[1])); tmp->ref = newArray(p->opr.op[0]->id.id, p->opr.op[2]->con.value, 1, p->opr.op[1]); break; case 2: // char array, i.e. "real string" // tmp->ref = newArray(p->opr.op[0]->id.id, p->opr.op[2]->cha.value, 2, getDims(p->opr.op[1])); tmp->ref = newArray(p->opr.op[0]->id.id, p->opr.op[2]->con.value, 2, p->opr.op[1]); break; } } break; case ACCESS: // VARIABLE '[' expr ']' flag = 0; if(p->opr.op[0]->id.global) tmp = findVar(p->opr.op[0]->id.id,NULL); else tmp = findVar(p->opr.op[0]->id.id,head); if (tmp == NULL){ printf("ERROR: array element referenced before declaration.\n"); exit(1); } ex(p->opr.op[1]); printf("\tpush\t%d\n", tmp->pos); printf("\tadd\n"); printf("\tpop\tin\n"); if(!isg) printf("\tpush\tfp[in]\n"); else printf("\tpush\tsb[in]\n"); // printf("\tpush\tfp[in]\n"); break; //printf("\tpush\tfp[%d]\n", tmp->pos + p->opr.op[1]->con.value); case RETURN: ex(p->opr.op[0]); printf("\tret\n"); break; case READ: flag = 0; if(p->opr.op[0]->id.global) tmp = findVar(p->opr.op[0]->id.id,NULL); else tmp = findVar(p->opr.op[0]->id.id,head); if(tmp == NULL) { if(p->opr.op[0]->id.global&&outest==0) { printf("cannot find that global variable.\n"); exit(1); } else { if(!outest) tmp = addVar2Point(p->opr.op[0]->id.id,&head); else tmp = addVar2Point(p->opr.op[0]->id.id,&global); } } tmp->ischar = 0; if(!flag) { printf("\tgeti\n"); if(!isg) printf("\tpop\tfp[%d]\n",tmp->pos); else printf("\tpop\tsb[%d]\n",tmp->pos); } else { printf("\tpush 0\n"); ++fpoffset; ++tmp->pos; //ex(p->opr.op[0]); printf("\tgeti\n"); if(p->opr.op[0]->id.global) tmp = findVar(p->opr.op[0]->id.id,NULL); else tmp = findVar(p->opr.op[0]->id.id,head); if(!isg) printf("\tpop\tfp[%d]\n",tmp->pos); else printf("\tpop\tsb[%d]\n",tmp->pos); } break; case READC: flag = 0; if(p->opr.op[0]->id.global) tmp = findVar(p->opr.op[0]->id.id,NULL); else tmp = findVar(p->opr.op[0]->id.id,head); if(tmp == NULL) { if(p->opr.op[0]->id.global&&outest==0) { printf("cannot find that global variable.\n"); exit(1); } else { if(!outest) tmp = addVar2Point(p->opr.op[0]->id.id,&head); else tmp = addVar2Point(p->opr.op[0]->id.id,&global); } } tmp->ischar = 1; if(!flag) { printf("\tgetc\n"); if(!isg) printf("\tpop\tfp[%d]\n",tmp->pos); else printf("\tpop\tsb[%d]\n",tmp->pos); } else { printf("\tpush 0\n"); ++fpoffset; ++tmp->pos; //ex(p->opr.op[0]); printf("\tgetc\n"); if(p->opr.op[0]->id.global) tmp = findVar(p->opr.op[0]->id.id,NULL); else tmp = findVar(p->opr.op[0]->id.id,head); if(!isg) printf("\tpop\tfp[%d]\n",tmp->pos); else printf("\tpop\tsb[%d]\n",tmp->pos); } break; case PRINT: ex(p->opr.op[0]); --fpoffset; if (ischar) printf("\tputc\n"); else printf("\tputi\n"); //ischar = 1; break; case PI: if(p->opr.nops==1) // simple ex(p->opr.op[0]); else // formatted ex(p->opr.op[1]); --fpoffset; if(p->opr.nops==1) printf("\tputi\n"); else printf("\tputi %s\n",p->opr.op[0]->strg.value); break; case PIN: ex(p->opr.op[0]); --fpoffset; printf("\tputi_\n"); break; case PC: if(p->opr.nops==1) ex(p->opr.op[0]); else ex(p->opr.op[1]); --fpoffset; if(p->opr.nops==1) printf("\tputc\n"); else printf("\tputc %s\n",p->opr.op[0]->strg.value); break; case PCN: ex(p->opr.op[0]); --fpoffset; printf("\tputc_\n"); break; // added case PS: if(p->opr.nops==1) ex(p->opr.op[0]); else ex(p->opr.op[1]); --fpoffset; if(p->opr.nops==1) printf("\tputs\n"); // TODO: formatted // else // printf("\tputc %s\n",p->opr.op[0]->id.id); break; case PSN: ex(p->opr.op[0]); --fpoffset; printf("\tputs_\n"); break; case '=': //ex(p->opr.op[1]); // RHS value //nodeType *vartmp; //int isArray; if (p->opr.op[0]->type == typeId){ vartmp = p->opr.op[0]; // simple variable isArray = 0; } else{ vartmp = p->opr.op[0]->opr.op[0]; // array element isArray = 1; } // common if(vartmp->id.global) tmp = findVar(vartmp->id.id,NULL); else tmp = findVar(vartmp->id.id,head); if(tmp == NULL) // variable not found { if (isArray == 1){ printf("ERROR: array element referenced before declaration.\n"); exit(1); } if(vartmp->id.global && outest==0) { printf("cannot find that global variable.\n"); exit(1); } else { printf("\tpush\t0\n"); ++fpoffset; if(outest) tmp = addVar2Point(vartmp->id.id, &global); else tmp = addVar2Point(vartmp->id.id, &head); } } if(!flag){ // the variable is not newly created --fpoffset; //var type changed. tmp->ischar = ischar; // Disable and exit if type change is not allowed. } else{ //ex(p->opr.op[1]); //printf("\tpush\t0\n"); --fpoffset; tmp->ischar = ischar; if(vartmp->id.global) tmp = findVar(vartmp->id.id, NULL); else tmp = findVar(vartmp->id.id, head); } ex(p->opr.op[1]); // RHS value if(isArray == 0){ // simple variable if(tmp->ref != NULL){ printf("TYPE ERROR: cannot assign an array\n"); exit(1); } if(!isg) printf("\tpop\tfp[%d]\n",tmp->pos); else printf("\tpop\tsb[%d]\n",tmp->pos); } else{ // array element if (tmp->ref == NULL){ printf("TYPE ERROR: %s is not an array\n", tmp->name); exit(1); } ex(p->opr.op[0]->opr.op[1]); printf("\tpush\t%d\n", tmp->pos); printf("\tadd\n"); printf("\tpop\tin\n"); if(!isg) printf("\tpop\tfp[in]\n"); else printf("\tpop\tsb[in]\n"); } break; case FUNCALL: ex(p->opr.op[1]); ftmp = findFun(p->opr.op[0]->id.id); printf("\tcall L%03d,%d\n",ftmp->no,ftmp->para_num); break; case FUNDCLR: oldoutest = outest; outest = 0; oldoff = fpoffset; fpoffset = 0; lbl1 = lbl++; oldhead = head; head = NULL; printf("\tjmp L%03d\n",lbl1); ftmp = findFun(p->opr.op[0]->id.id); if(ftmp!=NULL) { printf("Has been declared;\n"); exit(1); } ftmp = addFun(p->opr.op[0]->id.id); ftmp->no = lbl++; printf("L%03d:\n",ftmp->no); if(p->opr.op[1]==NULL) { } else { nodeType *ptmp = p->opr.op[1]; para = 1; while(ptmp->type==typeOpr) { addVar2Point(ptmp->opr.op[1]->id.id,&head); ptmp = ptmp->opr.op[0]; para++; } addVar2Point(ptmp->id.id,&head); para = addPara(p->opr.op[1]); } int itmp = 0; for(tmp = head;tmp!=NULL;tmp = tmp->next) { tmp->pos -= (3+itmp); itmp++; } ftmp->para_num = para; ex(p->opr.op[2]); printf("L%03d:\n",lbl1); outest = oldoutest; head = oldhead; fpoffset = oldoff; break; case UMINUS: ex(p->opr.op[0]); ischar = 0; printf("\tneg\n"); break; default: ex(p->opr.op[0]); // deleted: int aischar = ischar; ex(p->opr.op[1]); int charopr = ischar; ischar = 0; switch(p->opr.oper) { case ',': if(p->opr.op[2]->con.value == 1) para++; break; case '+': printf("\tadd\n"); --fpoffset; break; case '-': printf("\tsub\n"); --fpoffset; break; case '*': printf("\tmul\n"); --fpoffset;break; case '/': printf("\tdiv\n"); --fpoffset;break; case '%': printf("\tmod\n"); --fpoffset;break; case '<': printf("\tcomplt\n"); --fpoffset;break; case '>': printf("\tcompgt\n"); --fpoffset;break; case GE: printf("\tcompge\n"); --fpoffset;break; case LE: printf("\tcomple\n"); --fpoffset;break; case NE: printf("\tcompne\n"); --fpoffset;break; case EQ: printf("\tcompeq\n"); --fpoffset;break; case AND: printf("\tand\n"); --fpoffset;break; case OR: printf("\tor\n"); --fpoffset;break; } } } return 0; }