Пример #1
0
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);
}
Пример #2
0
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;
}