Ejemplo n.º 1
0
static void eval(Node *p) {
    int i, lbl1, lbl2;
    char *name;

    if (p == 0) return;
    switch(p->attrib) {
    case INTEGER:
        fprintf(out, pfIMM, p->value.i);	/* push an integer immediate */
        break;
    case STRING:
	/* generate the string */
	fprintf(out, pfRODATA);			/* strings are DATA readonly  */
	fprintf(out, pfALIGN);			/* make sure we are aligned   */
	fprintf(out, pfLABEL, mklbl(lbl1 = ++lbl));	/* name the string    */
	fprintf(out, pfSTR, p->value.s);	/* output string characters   */
	/* make the call */
	fprintf(out, pfTEXT);			/* return to the TEXT segment */
	fprintf(out, pfADDR, mklbl(lbl1));	/* the string to be printed   */
	fprintf(out, pfCALL, "_prints");	/* call the print rotine      */
	fprintf(out, pfCALL, "_println");	/* print a newline	      */
	fprintf(out, pfTRASH, sizeof(regint));		/* remove the string address: 4/8 bytes    */
        break;
    case VARIABLE:
	if (IDfind(p->value.s, 0) >= 0) {
	  fprintf(out, pfADDR, p->value.s);
	  fprintf(out, pfLOAD);
	}
	break;
    case WHILE:
	fprintf(out, pfLABEL, mklbl(lbl1 = ++lbl));
	eval(p->SUB(0));
	fprintf(out, pfJZ, mklbl(lbl2 = ++lbl));
	eval(p->SUB(1));
	fprintf(out, pfJMP, mklbl(lbl1));
	fprintf(out, pfLABEL, mklbl(lbl2));
	break;
    case IF:
	eval(p->SUB(0));
	fprintf(out, pfJZ, mklbl(lbl1 = ++lbl));
	eval(p->SUB(1));
	if (p->value.sub.num > 2) { /* if else */
	    fprintf(out, pfJMP, mklbl(lbl2 = ++lbl));
	    fprintf(out, pfLABEL, mklbl(lbl1));
	    eval(p->SUB(2));
	    lbl1 = lbl2;
	}
	fprintf(out, pfLABEL, mklbl(lbl1));
	break;
    case READ:
	if (IDfind(p->value.s, 0) >= 0) {
	  fprintf(out, pfCALL, "_readi");
	  fprintf(out, pfPUSH);
	  fprintf(out, pfADDR, p->value.s);
	  fprintf(out, pfSTORE);
	}
	break;
    case PRINT:
	eval(p->SUB(0));			/* determine the value        */
	fprintf(out, pfCALL, "_printi");	/* call the print function    */
	fprintf(out, pfCALL, "_println");	/* print a newline	      */
	fprintf(out, pfTRASH, sizeof(regint));		/* remove the printed value: 4/8 bytes   */
	break;
    case ';':
	for (i = 0; i < p->value.sub.num; i++)
	  eval(p->SUB(i));
	break;
    case '=':
	name = p->SUB(0)->value.s;
	if (IDfind(name, (int*)IDtest) == -1) { /* variable not found ?       */
	  fprintf(out, pfDATA);			/* variables are DATA         */
	  fprintf(out, pfALIGN);		/* make sure we are aligned   */
	  fprintf(out, pfLABEL, name);		/* name variable location     */
#ifdef _64bits_
	  fprintf(out, pfLONG, 0LL);		/* initialize it to 0 (zero)  */
#else
	  fprintf(out, pfINTEGER, 0);		/* initialize it to 0 (zero)  */
#endif
	  fprintf(out, pfTEXT);			/* return to the TEXT segment */
	  IDnew(INTEGER, name, 0);		/* put in the symbol table    */
	}
	eval(p->SUB(1));			/* determine the new value    */
	fprintf(out, pfADDR, name);		/* where to store the value   */
	fprintf(out, pfSTORE);			/* store the value at address */
	break;
    case UMINUS:
	eval(p->SUB(0));			/* determine the value	      */
	fprintf(out, pfNEG);			/* make the 2-compliment      */
	break;
    default:
	eval(p->SUB(0));			/* evaluate first argument    */
	eval(p->SUB(1));			/* evaluate second argument   */
	switch(p->attrib) {			/* make the operation ...     */
	case '+':   fprintf(out, pfADD); break;
	case '-':   fprintf(out, pfSUB); break;
	case '*':   fprintf(out, pfMUL); break;
	case '/':   fprintf(out, pfDIV); break;
	case '%':   fprintf(out, pfMOD); break;
	case '<':   fprintf(out, pfLT); break;
	case '>':   fprintf(out, pfGT); break;
	case GE:    fprintf(out, pfGE); break;
	case LE:    fprintf(out, pfLE); break;
	case NE:    fprintf(out, pfNE); break;
	case EQ:    fprintf(out, pfEQ); break;
	default:    printf("unknown %d\n", p->attrib);
	}
    }
}
Ejemplo n.º 2
0
static void eval(Node *p){

	int i, lbl1, lbl2, size, temp = 0, attrib = 1;
	char *name;

	if (p == 0) return;
	switch(p->attrib){

		case CONTINUE:
		/* JMP cond*/
			break;		
		case BREAK:
		/* JMP fim */
			break;		
		case ELIF:
		
			break;

		case FOR:
			eval(p->SUB(0));
			fprintf(out, pfLABEL, mklbl(lbl1 = ++lbl));
			eval(p->SUB(1));
			fprintf(out, pfJZ, mklbl(lbl2 = ++lbl));
			IDpush();
			eval(p->SUB(3));
			eval(p->SUB(2));
			IDpop();
			fprintf(out, pfJMP, mklbl(lbl1));
			fprintf(out, pfLABEL, mklbl(lbl2));
			break;

		case ALLOCA:
			eval(p->SUB(1));
			fprintf(out, pfALLOC);
			fprintf(out, pfSP);
			eval(p->SUB(0));
			fprintf(out, pfSTORE);
			break;

		case EXTERN:						/* extern declarations        */
			for (i = 0; i < p->value.sub.num; i++){
				name = p->SUB(i)->SUB(0)->value.s;
				IDnew(EXTERN, name, p->SUB(i)->value.sub.num);
				fprintf(out, pfEXTRN, name);
			}
			break;
		case INIT:
			name = p->SUB(0)->SUB(0)->value.s;
			IDnew(INIT, name, p->SUB(1)->value.sub.num);
			fprintf(out, pfDATA);
			fprintf(out, pfALIGN);				/* make sure we are aligned   */
			
			fprintf(out, pfGLOBL, name, pfOBJ);
			fprintf(out, pfLABEL, name);
			for(i = 0; i < p->SUB(1)->value.sub.num; i++){
				fprintf(out, pfCONST, p->SUB(1)->SUB(i)->value.i);
			}
			fprintf(out, pfTEXT);
			fprintf(out, pfALIGN);				/* make sure we are aligned   */
			break;
		case CONST:
			fprintf(out, pfRODATA);
			fprintf(out, pfALIGN);

			name = p->SUB(0)->SUB(0)->value.s;
			IDnew(CONST, name, p->SUB(1)->value.sub.num);				
			fprintf(out, pfLABEL, name);			/* name variable location     */
			for (temp = 0; temp < p->SUB(1)->value.sub.num; temp++)
				fprintf(out, pfCONST, p->SUB(1)->SUB(temp)->value.i);
			fprintf(out, pfTEXT);
			fprintf(out, pfALIGN);
			break;
			
		case LVALUE2:
			for (i = 0; i < p->value.sub.num; i++)
				eval(p->SUB(i));
			break;
		case LVALUE:
  			name = p->SUB(0)->SUB(0)->value.s;

			if(p->SUB(0)->SUB(0)->attrib == IDLVALUE)
				IDnew(INT_NUMBER, name, offset);
			else if (p->SUB(0)->SUB(0)->attrib == IDARRAY)
				IDnew(ARRAY, name, offset);
			else{
				name = p->SUB(0)->SUB(0)->SUB(0)->value.s;
				offset -= 4 * p->SUB(0)->SUB(1)->value.i;
				IDnew(ARRAYINDEX, name, offset);
				break;
			}
			offset -= 4;
			break;
		case VAR:
			for (i = 0; i < p->value.sub.num; i++){
				eval(p->SUB(i));
			}
			break;

		case ARRAYINDEX:
			eval(p->SUB(1));
			if (p->SUB(1)->attrib != INT_NUMBER)
				fprintf(out, pfLOAD);
			fprintf(out, pfINT, 4);				/* push an integer	      */
			fprintf(out, pfMUL);
			eval(p->SUB(0));
			fprintf(out, pfADD);

			break;
		case ARRAY:
			eval(p->SUB(0));	
			break;

		case FNNAME:
			name = p->SUB(0)->SUB(0)->value.s;
			if(p->value.sub.num == 2)
				temp = p->SUB(1)->value.sub.num;
			IDnew(FNNAME, name, temp);
			IDpush();
			IDnew(INT_NUMBER, name, -4);
			
			offset = -8;
			fprintf(out, pfTEXT);
			fprintf(out, pfALIGN);
			fprintf(out, pfGLOBL, name, pfFUNC);
			fprintf(out, pfLABEL, name);
			fprintf(out, pfENTER, args + 4);
			break;
		case FUNCTION:
			args = count_args(p);
			for (i = 0; i < p->value.sub.num; i++)
	  			eval(p->SUB(i));
			fprintf(out, pfLOCAL, -4);
			fprintf(out, pfLOAD);
			fprintf(out, pfPOP);
			fprintf(out, pfLEAVE);
			fprintf(out, pfRET);
			IDpop();
			break;

		case INT_NUMBER:
			fprintf(out, pfINT, p->value.i);		/* push an integer	      */
			break;
		case ID:						/* */
			name = p->SUB(0)->value.s;
			switch(p->SUB(0)->attrib){
				case IDLVALUE:
				case IDARRAY:
				case IDARRAYINDEX:
					temp = IDfind(name, &attrib);
					fprintf(out, pfLOCAL, attrib);
					break;
				default:
					fprintf(out, pfADDR, name);
					break;
			}
			break;	
		case DO:
			fprintf(out, pfLABEL, mklbl(lbl1 = ++lbl));
			IDpush();
			eval(p->SUB(0));
			IDpop();
			fprintf(out, pfLABEL, mklbl(lbl2 = ++lbl));
			eval(p->SUB(1));
			fprintf(out, pfJNZ, mklbl(lbl1));
			if (p->value.sub.num > 2){			/* do else 			*/
				IDpush();
				eval(p->SUB(2));
				IDpop();
			}
			break;		
		case WHILE:
			fprintf(out, pfLABEL, mklbl(lbl1 = ++lbl));
			eval(p->SUB(0));
			fprintf(out, pfJZ, mklbl(lbl2 = ++lbl));
			IDpush();
			eval(p->SUB(1));
			IDpop();
			fprintf(out, pfJMP, mklbl(lbl1));
			fprintf(out, pfLABEL, mklbl(lbl2));
			if (p->value.sub.num > 2){			/* while else 			*/
				IDpush();
				eval(p->SUB(2));
				IDpop();
			}
			break;
		case CALL:
			name = p->SUB(0)->value.s;
			if(p->value.sub.num == 2) {	
				for(i = p->SUB(1)->value.sub.num; i > 0; i--){
					eval(p->SUB(i));		/* evaluate argument	      */
					if (p->SUB(i)->attrib != INT_NUMBER)
						fprintf(out, pfLOAD);
				}
			}
			fprintf(out, pfCALL, name);
			fprintf(out, pfTRASH, i);			/* remove the return value    */
			fprintf(out, pfPUSH);
			break;	

		case STR:						/* generate the string	      */			 
			fprintf(out, pfRODATA);				/* strings are DATA readonly  */
			fprintf(out, pfALIGN);				/* make sure we are aligned   */
			fprintf(out, pfLABEL, mklbl(lbl1 = ++lbl));	/* give the string a name     */
			fprintf(out, pfSTR, p->value.s); 		/* output string characters   */
				/* make the call */
			fprintf(out, pfTEXT);				/* return to the TEXT segment */
			fprintf(out, pfALIGN);				/* make sure we are aligned   */
			fprintf(out, pfADDR, mklbl(lbl1));
			break;

		case PRINTSTUFF:
			eval(p->SUB(0));
			if(p->SUB(0)->attrib == ID){
				fprintf(out, pfLOAD);
				fprintf(out, pfCALL, "printi");		/* call the print function    */
			}
			else if(p->SUB(0)->attrib == STR){
				fprintf(out, pfCALL, "prints");		/* call the print function    */
			}
			else if(p->SUB(0)->attrib == INT_NUMBER){
				fprintf(out, pfCALL, "printi");		/* call the print function    */
			}
			print = 0;
			break;
		case '!':
			print = 1;
			eval(p->SUB(0));				/* determine the value        */
			fprintf(out, pfTRASH, 4);			/* delete the printed value   */
			break;		
		case OUT:
			print = 1;
			eval(p->SUB(0));				/* determine the value        */
			fprintf(out, pfCALL, "println");		/* print a newline	      */
			fprintf(out, pfTRASH, 4);			/* delete the printed value   */
			break;
		case IF:
			eval(p->SUB(0));
			if (p->SUB(0)->attrib != INT_NUMBER)
				fprintf(out, pfLOAD);
			fprintf(out, pfJZ, mklbl(lbl1 = ++lbl));
			IDpush();
			eval(p->SUB(1));
			IDpop();
			if (p->value.sub.num > 2){			/* if else 			*/
				fprintf(out, pfJMP, mklbl(lbl2 = ++lbl));
				fprintf(out, pfLABEL, mklbl(lbl1));
				IDpush();
				eval(p->SUB(2));
				IDpop();
				lbl1 = lbl2;
			}
			fprintf(out, pfLABEL, mklbl(lbl1));
			break;

		case BONUS:
			for (i = 0; i < p->value.sub.num; i++)
	  			eval(p->SUB(i));
			break;	
		case COMPOUND_STAT:
			for (i = 0; i < p->value.sub.num; i++)
	  			eval(p->SUB(i));
			break;
		case CONST_LIST:
			for (i = 0; i < p->value.sub.num; i++)
	  			eval(p->SUB(i));
			break;	
		case DECL_VAR_LIST:
			for (i = 0; i < p->value.sub.num; i++)
	  			eval(p->SUB(i));
			break;	
		case EXPRESSION_LIST:
			for (i = 0; i < p->value.sub.num; i++)
	  			eval(p->SUB(i));
			break;
		case EXTRA_STAT_LIST:
			for (i = 0; i < p->value.sub.num; i++)
	  			eval(p->SUB(i));
			break;
		case NUM_LIST:
			for (i = 0; i < p->value.sub.num; i++)
	  			eval(p->SUB(i));
			break;	
		case PROGRAM:
			for (i = 0; i < p->value.sub.num; i++)
	  			eval(p->SUB(i));
			break;
		case STATEMENT:
			for (i = 0; i < p->value.sub.num; i++)
	  			eval(p->SUB(i));
			break;
		case STATEMENT_LIST:
			for (i = 0; i < p->value.sub.num; i++)
	  			eval(p->SUB(i));
			break;
		case ULTRA:
			for (i = 0; i < p->value.sub.num; i++)
	  			eval(p->SUB(i));
			break;		

		case AND_OP:
			eval(p->SUB(0));				/* evaluate first argument    */
			if (p->SUB(0)->attrib != INT_NUMBER)
				fprintf(out, pfLOAD);
			fprintf(out, pfDUP);
			fprintf(out, pfJZ, mklbl(lbl1 = ++lbl));
			fprintf(out, pfTRASH, 4);
			eval(p->SUB(1));				/* evaluate second argument   */
			if (p->SUB(0)->attrib != INT_NUMBER)
				fprintf(out, pfLOAD);
			fprintf(out, pfLABEL, mklbl(lbl1));
			break;
		case OR_OP:
			eval(p->SUB(0));				/* evaluate first argument    */
			if (p->SUB(0)->attrib != INT_NUMBER)
				fprintf(out, pfLOAD);
			fprintf(out, pfDUP);
			fprintf(out, pfJNZ, mklbl(lbl1 = ++lbl));
			fprintf(out, pfTRASH, 4);
			eval(p->SUB(1));				/* evaluate second argument   */
			if (p->SUB(0)->attrib != INT_NUMBER)
				fprintf(out, pfLOAD);
			fprintf(out, pfLABEL, mklbl(lbl1));
			break;
		case NOT:
			eval(p->SUB(0));				/* evaluate argument	      */
			if (p->SUB(0)->attrib != INT_NUMBER)
				fprintf(out, pfLOAD);
			fprintf(out, pfINT, 0);
			fprintf(out, pfEQ);
			break;
		case '?':
			fprintf(out, pfCALL, "readi");
			fprintf(out, pfPUSH);
			eval(p->SUB(0));
			fprintf(out, pfSTORE);
			break;
		case '=':
			eval(p->SUB(1));				/* determine the new value    */
			if(p->SUB(1)->attrib == '='){
				eval(p->SUB(1)->SUB(0));
				fprintf(out, pfLOAD);
			}
			eval(p->SUB(0));	 			/* determine the new address  */
			fprintf(out, pfSTORE);				/* store the value at address */
			break;
		case '@':
			eval(p->SUB(0));				/* evaluate argument	      */
			break;
		case SIMETRIC:
			eval(p->SUB(0));				/* evaluate argument	      */
			if (p->SUB(0)->attrib != INT_NUMBER)
				fprintf(out, pfLOAD);
			fprintf(out, pfNEG);				/* make the 2-compliment      */
			break;
		case INC:
			eval(p->SUB(0));				/* evaluate argument	      */
			fprintf(out, pfINCR, 1);
			break;		
		case DEC:
			eval(p->SUB(0));				/* evaluate argument	      */
			fprintf(out, pfDECR, 1);
			break;
		case ADDEDATTRIB:
			eval(p->SUB(0));
			fprintf(out, pfLOAD);
			eval(p->SUB(1));
			if (p->SUB(1)->attrib != INT_NUMBER)
				fprintf(out, pfLOAD);
			fprintf(out, pfADD);

			eval(p->SUB(0));				/* determine the new address  */
			fprintf(out, pfSTORE);				/* store the value at address */			
			break;

/*		case MINUSATTRIB:
			eval(p->SUB(0));
			fprintf(out, pfLOAD);
			eval(p->SUB(1));
			if (p->SUB(1)->attrib != INT_NUMBER)
				fprintf(out, pfLOAD);
			fprintf(out, pfSUB);

			eval(p->SUB(0));	 			
			fprintf(out, pfSTORE);							
			break;

		case MULATTRIB:
			eval(p->SUB(0));
			fprintf(out, pfLOAD);
			eval(p->SUB(1));
			if (p->SUB(1)->attrib != INT_NUMBER)
				fprintf(out, pfLOAD);
			fprintf(out, pfMUL);

			eval(p->SUB(0));	 			
			fprintf(out, pfSTORE);							
			break;

		case DIVATTRIB:
			eval(p->SUB(0));
			fprintf(out, pfLOAD);
			eval(p->SUB(1));
			if (p->SUB(1)->attrib != INT_NUMBER)
				fprintf(out, pfDIV);
			fprintf(out, pfADD);

			eval(p->SUB(0));	 			
			fprintf(out, pfSTORE);							
			break;

		case MODATTRIB:
			eval(p->SUB(0));
			fprintf(out, pfLOAD);
			eval(p->SUB(1));
			if (p->SUB(1)->attrib != INT_NUMBER)
				fprintf(out, pfLOAD);
			fprintf(out, pfMOD);

			eval(p->SUB(0));	 			
			fprintf(out, pfSTORE);							
			break;

		case EXPATTRIB:
			eval(p->SUB(0));
			fprintf(out, pfLOAD);
			eval(p->SUB(1));
			if (p->SUB(1)->attrib != INT_NUMBER)
				fprintf(out, pfLOAD);
			pow_flag = 1;
			fprintf(out, pfCALL, "power");
			fprintf(out, pfTRASH, 8);
			fprintf(out, pfPUSH);

			eval(p->SUB(0));	 			
			fprintf(out, pfSTORE);							
			break;
*/
		default:	
			if(print){
				if(p->attrib == '+'){
					for (i = 0; i < p->value.sub.num; i++){
	  					eval(p->SUB(i));

						if(p->SUB(i)->attrib == ID){
							fprintf(out, pfLOAD);
							fprintf(out, pfCALL, "printi");		/* call the print function    */
						}
						else if(p->SUB(i)->attrib == INT_NUMBER){
							fprintf(out, pfCALL, "printi");		/* call the print function    */
						}
	  					else if (p->SUB(i)->attrib == STR){
							fprintf(out, pfCALL, "prints");			/* call the print function    */
						}
						else if(p->SUB(i)->attrib == '*'){
							eval(p->SUB(i)->SUB(1));				/* determine the value        */
							if (p->SUB(i)->SUB(1)->attrib != INT_NUMBER)
								fprintf(out, pfLOAD);

							eval(p->SUB(i)->SUB(0));				/* determine the value        */

							printer_flag = 1;
							fprintf(out, pfCALL, "printer");		/* print a newline	      */
							fprintf(out, pfTRASH, 4);			/* remove the return value    */	
						}
					}
				}
				else{
					eval(p->SUB(1));				/* determine the value        */
					if (p->SUB(1)->attrib != INT_NUMBER)
						fprintf(out, pfLOAD);

					eval(p->SUB(0));				/* determine the value        */

					printer_flag = 1;
					fprintf(out, pfCALL, "printer");		/* print a newline	      */
					fprintf(out, pfTRASH, 4);			/* remove the return value    */	
				}
			}
			else{

				eval(p->SUB(1));				/* evaluate first argument    */
				if (p->SUB(1)->attrib != INT_NUMBER)
					fprintf(out, pfLOAD);

				switch(p->attrib){	 			/* make the operation ...     */
					case '+':
						eval(p->SUB(0));				/* determine the new value    */
						if (verif(p->SUB(0)))
							fprintf(out, pfLOAD);				
			
						fprintf(out, pfADD);
						break;
					case '-':	
						eval(p->SUB(0));				/* determine the new value    */
						if (p->SUB(0)->attrib != INT_NUMBER && p->SUB(0)->attrib != '-')
							fprintf(out, pfLOAD);	

						fprintf(out, pfSUB); 
						break;
					case '*':
						eval(p->SUB(0));				/* determine the new value    */
						if (p->SUB(0)->attrib != INT_NUMBER && p->SUB(0)->attrib != '*')
							fprintf(out, pfLOAD);		

						fprintf(out, pfMUL);
						break;
					case '/':
						eval(p->SUB(0));				/* determine the new value    */
						if (p->SUB(0)->attrib != INT_NUMBER && p->SUB(0)->attrib != '/')
							fprintf(out, pfLOAD);	

						fprintf(out, pfDIV);
						break;
					case '%':
						eval(p->SUB(0));				/* determine the new value    */
						if (p->SUB(0)->attrib != INT_NUMBER && p->SUB(0)->attrib != '%')
							fprintf(out, pfLOAD);	

						fprintf(out, pfMOD);
						break;
					case EXP:
						eval(p->SUB(0));				/* determine the new value    */
						if (p->SUB(0)->attrib != INT_NUMBER && p->SUB(0)->attrib != EXP)
							fprintf(out, pfLOAD);	

						pow_flag = 1;
						fprintf(out, pfCALL, "power");
						fprintf(out, pfTRASH, 8);
						fprintf(out, pfPUSH);
						break;
					case '<':
						fprintf(out, pfLT); break;
					case '>':
						fprintf(out, pfGT); break;
					case GE_OP:
						fprintf(out, pfGE); break;
					case LE_OP:
						fprintf(out, pfLE); break;
					case NE_OP:
						fprintf(out, pfNE); break;
					case EQ_OP:
						fprintf(out, pfEQ); break;
					case IMPLICA:
						eval(p->SUB(0));
						fprintf(out, pfNOT);
						eval(p->SUB(1));
						fprintf(out, pfOR);
						break;

					default:
						printf("WTF? Unknown %d ('%c') !\n", p->attrib, p->attrib);
				}
			}
	}
}