示例#1
0
/*
***************************************************************************************************************
*	createCallStack:
*		fun: The ASTNode of the function for which call stack has to pushed into the stack.
*	This function subtracts the width of the function(which includes the temporaries too) from the current 
*	stack pointer. Thus creating space for local and temporaries in the call stack.
****************************************************************************************************************
*/
void createCallStack(ASTNode* fun){
	FunctionNode* funNode = (FunctionNode*)malloc(sizeof(FunctionNode));
	funNode->funTok = fun->token;
	funNode = ((FunctionNode*)get(FUNCTION_TABLE.hashTable,funNode));
	generate(createInstruction(SUB,RSP,IMM,0,0,funNode->width+funNode->tempCount));
	if(GLOBAL_WIDTH!=0){
		InstructionList* globalIns = createInstruction(MOV,RCX,-1,-1,-1,-1);
		strcpy(globalIns->label,data[GLOBAL]);
		generate(globalIns);
	}
}
示例#2
0
//Screens are always stored in the data folder.
//However, the FileIO object passed has all the necessary information.
void ScreenType::parseScreenFile(FileIO* file)
{
   std::string tempInput;
   std::vector <std::string> parserOutput;

   //file -> textOpenFile(screenFileName, false);
   //No longer needed.

   stringFunc stringParcer;

   if (file -> readLine(&tempInput)){
      parserOutput = stringParcer.parseAllTokens(tempInput, "\\");
   }
   else
   {
      //Wut? Broken
   }

   botX = atoi(parserOutput.at(0).c_str()); botY = atoi(parserOutput.at(1).c_str());
   topX = atoi(parserOutput.at(2).c_str()); topY = atoi(parserOutput.at(3).c_str());

   screenID = parserOutput.at(4);


while (file -> readLine(&tempInput)){
   //Empty lines are skipped.
   if (tempInput.empty()){
      continue;
   }

   //Lines with a pound at the beginning are ignored, these are comments.
   if (tempInput.at(0) == '#'){
      //cout << "Read comment: " << tempInput << endl;
      continue;
   }


   if (createInstruction(tempInput)){
      //cout << tempInput << endl;
      continue;
   }

//Something bad happened.
}

isGood = true;
file -> closeFile();
}
示例#3
0
文件: main.c 项目: teohoch/LP
void loadInstructions(instruction *instru, char * location)
{
	int n;
	FILE * file;
	file = fopen(location,"r");
	char buffer[10];
	fgets ( buffer, sizeof buffer, file );
	n = atoi(buffer);
	int i;

	createInstruction(instru,n);

	for(i=0;i<n;i++)
	{
		fgets ( buffer, sizeof buffer, file );
		strcpy(instru->data[i],buffer);
	}
	fclose(file);
}
示例#4
0
/*
*****************************************************************************************************************
*	codeGenerator:
*		child 		: The ASTNode for which the code has to be generated.
*		funInfo 	: This has the FunctionNode(see astDef.h for details) for the function 
*				  	  which has the 'child'.
*		currLabel	: Possible label which can be assigned to the current instruction.
*		parentLabel : The label of the parent node in AST.
*	This function simply does the post order traversal of a function and generates code for that function.
*	In our case it works only for the main function.
*****************************************************************************************************************
*/
void codeGenerator(ASTNode* child,FunctionNode* funInfo,Label* currLabel, int parentLabel){
	if(child==NULL){
		return;
	}
	int tempCount = funInfo->width;
	int tempLabel = currLabel->labelNum;
	InstructionList* funLabel = NULL;
	ASTNode* ifChild = NULL;
	int ifFlag=0;
	TokenName tokenName = child->token->tokenName;
	switch(tokenName){
		case TK_MAIN: funLabel = createLabel(1,0);
					  strcpy(funLabel->label,"main");
					  generate(funLabel);
					  createCallStack(child);
					  break;
		case TK_ASSIGNOP:	generateArithmeticExpression(child,funInfo->funTok,&tempCount);
							break;
		case TK_IF: currLabel->labelNum += 2;
					generateBooleanExpression(child->child,funInfo->funTok,addLabel(1,tempLabel),addLabel(0,tempLabel),currLabel,&tempCount);
					generate(createLabel(1,tempLabel));
					break;
		case TK_ELSE: generate(createInstruction(JMP,-1,-1,parentLabel+1,1,0));
					  generate(createLabel(0,parentLabel));
					  break;
		case TK_READ: generateScanf(child->child,funInfo);
					  break;
		case TK_WRITE: generatePrintf(child->child,funInfo);
						break;
		case TK_WHILE: generate(createLabel(1,currLabel->labelNum));
					   currLabel->labelNum += 2;
					   generateBooleanExpression(child->child,funInfo->funTok,addLabel(1,tempLabel+1),addLabel(0,tempLabel),currLabel,&tempCount);
					   generate(createLabel(1,tempLabel+1));
					   break;
	}
	if(tokenName==TK_IF)
		codeGenerator(child->child,funInfo,currLabel, tempLabel);
	else
		codeGenerator(child->child,funInfo,currLabel, parentLabel);
	switch(tokenName){
		case TK_MAIN:  generate(createInstruction(ADD,RSP,IMM,0,0,funInfo->width+funInfo->tempCount));
						generate(createInstruction(RET,-1,-1,-1,-1,-1));
						break;
		case TK_WHILE:  generate(createInstruction(JMP,-1,-1,tempLabel,1,0));
						generate(createLabel(0,tempLabel));
					  break;	
		case TK_IF:		generate(createLabel(1,tempLabel+1));
						ifChild = child->child;
						while(ifChild!=NULL){
							if(ifChild->token->tokenName==TK_ELSE){
								ifFlag = 1;
								break;
							}
							ifChild = ifChild->next;
						}
						if(!ifFlag)
						generate(createLabel(0,tempLabel));
						break;
	}
	codeGenerator(child->next,funInfo,currLabel, parentLabel);	
}
示例#5
0
/*
*****************************************************************************************************************
*	generatePrintf:
*		child 		: The ASTNode of the id which has to be printed.
*		funInfo 	: This has the FunctionNode(see astDef.h for details) for the function 
*				  	  which has the 'write' function.
*	This function simply creates instruction to write the identifier specified.
*	It handles record types too.
*****************************************************************************************************************
*/
void generatePrintf(ASTNode* child,FunctionNode* funInfo){
	int localOffset = 0;
	if(child->token->tokenName==TK_ID){
		ASTNode* field = NULL;
		if(child->child!=NULL){
			field = child->child;
		}
		VariableNode* var = createVarNode(child->token,funInfo->funTok,NULL,INT,0,&localOffset);
		VariableNode* freeVar = var;
		var = (VariableNode*)get(SYMBOL_TABLE.hashTable,var);
		if(var==NULL){
			var = freeVar;
			var->isGlobal = 1;
			var = (VariableNode*)get(SYMBOL_TABLE.hashTable,var);
		}
		free(freeVar);
		if(var->type==RECORD && field!=NULL){
			FieldList* head = var->recordPtr->fields;
			int tempOffset = var->offset;
			for(;head!=NULL;tempOffset+=head->width,head=head->next){
				if(strcmp(field->token->lexemeName,head->token->lexemeName)==0){
					generate(createInstruction(MOV,RSI,IMM,0,0,0));
					generate(createInstruction(MOV,ESI,MEM,tempOffset,var->isGlobal,0));
					InstructionList* label = createInstruction(MOV,RDI,-1,-1,-1,-1);
					strcpy(label->label,data[FORMAT_OUT_NEWLINE]);
					generate(label);
					generate(createInstruction(PUSH,RAX,NONE,0,0,0));
					generate(createInstruction(PUSH,RCX,NONE,0,0,0));
					generate(createInstruction(MOV,RAX,IMM,0,0,0));
					InstructionList* call = createInstruction(CALL,-1,-1,-1,-1,-1);
					strcpy(call->label,"printf");
					generate(call);
					generate(createInstruction(POP,RCX,NONE,0,0,0));	
					generate(createInstruction(POP,RAX,NONE,0,0,0));
				}
			}
		}
		else if(var->type==RECORD){
			FieldList* head = var->recordPtr->fields;
			int tempOffset = var->offset;
			for(;head!=NULL;tempOffset+=head->width,head=head->next){
				generate(createInstruction(MOV,RSI,IMM,0,0,0));
				generate(createInstruction(MOV,ESI,MEM,tempOffset,var->isGlobal,0));
				InstructionList* label = createInstruction(MOV,RDI,-1,-1,-1,-1);
				strcpy(label->label,data[FORMAT_OUT_SPACE]);
				generate(label);
				generate(createInstruction(PUSH,RAX,NONE,0,0,0));
				generate(createInstruction(PUSH,RCX,NONE,0,0,0));
				generate(createInstruction(MOV,RAX,IMM,0,0,0));
				InstructionList* call = createInstruction(CALL,-1,-1,-1,-1,-1);
				strcpy(call->label,"printf");
				generate(call);
				generate(createInstruction(POP,RCX,NONE,0,0,0));	
				generate(createInstruction(POP,RAX,NONE,0,0,0));
			}

		}
		else{				
				generate(createInstruction(MOV,RSI,IMM,0,0,0));
				generate(createInstruction(MOV,ESI,MEM,var->offset,var->isGlobal,0));
				InstructionList* label = createInstruction(MOV,RDI,-1,-1,-1,-1);
				strcpy(label->label,data[FORMAT_OUT_NEWLINE]);
				generate(label);
				generate(createInstruction(PUSH,RAX,NONE,0,0,0));
				generate(createInstruction(PUSH,RCX,NONE,0,0,0));
				generate(createInstruction(MOV,RAX,IMM,0,0,0));
				InstructionList* call = createInstruction(CALL,-1,-1,-1,-1,-1);
				strcpy(call->label,"printf");
				generate(call);
				generate(createInstruction(POP,RCX,NONE,0,0,0));	
				generate(createInstruction(POP,RAX,NONE,0,0,0));	
		}
	}

}
示例#6
0
/*
*****************************************************************************************************************
*	generateBooleanExpression:
*		child 		: The ASTNode of the expression for which code has to be generated.
*		funTok 	    : This has the Token(see lexerDef.h for Token details) for the function 
*				  	  which has the expression.
*		trueLabel	: The code will jump to this label if the current subtree represented 
*					  by 'child' evaluates to true.
*		falseLabel  : The code will jump to this label if the current subtree represented
*					  by 'child' evaluates to false.
*		tempCount 	: This is the total space occupied by all the temporary variables used while generating
*					  code for the given boolean expression.
*	This function recurses and creates the code for left and right subtree of the expression and then combines
*	them.
*****************************************************************************************************************
*/
VariableNode* generateBooleanExpression(ASTNode* child,Token* funTok,Label* trueLabel,Label* falseLabel,Label* currLabel,int* tempCount){
	int localOffset = 0;
	if(child->token->tokenName==TK_ID){
		ASTNode* field = NULL;
		if(child->child!=NULL){
			field = child->child;
		}
		VariableNode* var = createVarNode(child->token,funTok,NULL,INT,0,&localOffset);
		VariableNode* freeVar = var;
		var = (VariableNode*)get(SYMBOL_TABLE.hashTable,var);
		if(var==NULL){
			var = freeVar;
			var->isGlobal = 1;
			var = (VariableNode*)get(SYMBOL_TABLE.hashTable,var);
		}
		free(freeVar);
		if(var->type==RECORD && field!=NULL){
			FieldList* head = var->recordPtr->fields;
			for(;head!=NULL;head=head->next){
				if(strcmp(field->token->lexemeName,head->token->lexemeName)==0){
					return createVarNode(NULL,funTok,NULL,head->type,0,&localOffset);
				}
			}
		}
		return var;
	}
	if(child->token->tokenName==TK_NOT){
		VariableNode* notVariable = generateBooleanExpression(child->child,funTok,falseLabel,trueLabel,currLabel,tempCount);
		return NULL;

	}
	ASTNode* leftChild = child->child;
	ASTNode* rightChild = leftChild->next;
	Type leftType=-1,rightType=-1;
	VariableNode* leftNode = NULL;
	VariableNode* rightNode = NULL;
	if(leftChild!=NULL){
		leftType = (leftChild->token->tokenName==TK_NUM)? INT:-1;
		leftType = (leftChild->token->tokenName==TK_RNUM)?REAL:leftType;
	}
	if(rightChild!=NULL){
		rightType = (rightChild->token->tokenName==TK_NUM)?INT:-1;
		rightType = (rightChild->token->tokenName==TK_RNUM)?REAL:rightType;
	}
	if(leftType!=-1){
		generate(createInstruction(MOV,MEM,IMM,*tempCount,0,leftChild->token->value.intValue));
		leftNode = createVarNode(NULL,funTok,NULL,leftType,0,tempCount);
	}
	if(rightType!=-1){
		generate(createInstruction(MOV,MEM,IMM,*tempCount,0,rightChild->token->value.intValue));
		rightNode = createVarNode(NULL,funTok,NULL,rightType,0,tempCount);
	}
	if(child->token->tokenName==TK_AND){
		Label* ANDLabel = addLabel(1,currLabel->labelNum);
		currLabel->labelNum = currLabel->labelNum +1;
		currLabel->labelType = 1;
		generateBooleanExpression(leftChild,funTok,ANDLabel,falseLabel,currLabel,tempCount);
		generate(createLabel(1,ANDLabel->labelNum));
		generateBooleanExpression(rightChild,funTok, trueLabel, falseLabel, currLabel,tempCount);
		return NULL;
	}
	if(child->token->tokenName==TK_OR){
		Label* ORLabel = addLabel(0,currLabel->labelNum);
		currLabel->labelNum = currLabel->labelNum +1;
		currLabel->labelType = 0;
		generateBooleanExpression(leftChild,funTok,trueLabel,ORLabel, currLabel,tempCount);
		generate(createLabel(0,ORLabel->labelNum));
		generateBooleanExpression(rightChild,funTok, trueLabel, falseLabel, currLabel,tempCount);
		return NULL;
	}
	if(leftNode==NULL){
		leftNode = generateBooleanExpression(leftChild,funTok,trueLabel,falseLabel,currLabel,tempCount);
	}
	if(rightNode==NULL){
		rightNode = generateBooleanExpression(rightChild,funTok,trueLabel,falseLabel,currLabel,tempCount);
	}
	switch(child->token->tokenName){
		case TK_LT:	generate(createInstruction(MOV,EAX,MEM,leftNode->offset,leftNode->isGlobal,0));
					generate(createInstruction(CMP,EAX,MEM,rightNode->offset,rightNode->isGlobal,0));
					generate(createInstruction(JL,-1,-1,trueLabel->labelNum,trueLabel->labelType,0));
					generate(createInstruction(JGE,-1,-1,falseLabel->labelNum,falseLabel->labelType,0));	
					break;
		case TK_GT:	generate(createInstruction(MOV,EAX,MEM,leftNode->offset,leftNode->isGlobal,0));
					generate(createInstruction(CMP,EAX,MEM,rightNode->offset,rightNode->isGlobal,0));
					generate(createInstruction(JG,-1,-1,trueLabel->labelNum,trueLabel->labelType,0));
					generate(createInstruction(JLE,-1,-1,falseLabel->labelNum,falseLabel->labelType,0));	
					break;
		case TK_LE:	generate(createInstruction(MOV,EAX,MEM,leftNode->offset,leftNode->isGlobal,0));
					generate(createInstruction(CMP,EAX,MEM,rightNode->offset,rightNode->isGlobal,0));
					generate(createInstruction(JLE,-1,-1,trueLabel->labelNum,trueLabel->labelType,0));
					generate(createInstruction(JG,-1,-1,falseLabel->labelNum,falseLabel->labelType,0));	
					break;
		case TK_GE:	generate(createInstruction(MOV,EAX,MEM,leftNode->offset,leftNode->isGlobal,0));
					generate(createInstruction(CMP,EAX,MEM,rightNode->offset,rightNode->isGlobal,0));
					generate(createInstruction(JGE,-1,-1,trueLabel->labelNum,trueLabel->labelType,0));
					generate(createInstruction(JL,-1,-1,falseLabel->labelNum,falseLabel->labelType,0));	
					break;
		case TK_EQ:	generate(createInstruction(MOV,EAX,MEM,leftNode->offset,leftNode->isGlobal,0));
					generate(createInstruction(CMP,EAX,MEM,rightNode->offset,rightNode->isGlobal,0));
					generate(createInstruction(JE,-1,-1,trueLabel->labelNum,trueLabel->labelType,0));
					generate(createInstruction(JNE,-1,-1,falseLabel->labelNum,falseLabel->labelType,0));	
					break;
		case TK_NE:	generate(createInstruction(MOV,EAX,MEM,leftNode->offset,leftNode->isGlobal,0));
					generate(createInstruction(CMP,EAX,MEM,rightNode->offset,rightNode->isGlobal,0));
					generate(createInstruction(JNE,-1,-1,trueLabel->labelNum,trueLabel->labelType,0));
					generate(createInstruction(JE,-1,-1,falseLabel->labelNum,falseLabel->labelType,0));	
					break;
	}
	return NULL;
}
示例#7
0
/*
*****************************************************************************************************************
*	generateArithmeticExpression:
*		child 		: The ASTNode of the expression for which code has to be generated.
*		funTok 	    : This has the Token(see lexerDef.h for Token details) for the function 
*				  	  which has the expression.
*		tempCount 	: This is the total space occupied by all the temporary variables used while generating
*					  code for the given arithmetic expression.
*	This function recurses and creates the code for left and right subtree of the expression and then combines
*	them.
*****************************************************************************************************************
*/
VariableNode* generateArithmeticExpression(ASTNode* child,Token* funTok,int *tempCount){
	int localOffset = 0;
	if(child->token->tokenName==TK_ID){
		ASTNode* field = NULL;
		if(child->child!=NULL){
			field = child->child;
		}
		VariableNode* var = createVarNode(child->token,funTok,NULL,INT,0,&localOffset);
		VariableNode* freeVar = var;
		var = (VariableNode*)get(SYMBOL_TABLE.hashTable,var);
		if(var==NULL){
			var = freeVar;
			var->isGlobal = 1;
			var = (VariableNode*)get(SYMBOL_TABLE.hashTable,var);
		}
		free(freeVar);
		if(var->type==RECORD && field!=NULL){
			FieldList* head = var->recordPtr->fields;
			int recordOffset = var->offset;
			for(;head!=NULL;head=head->next){
				if(strcmp(field->token->lexemeName,head->token->lexemeName)==0){
					return createVarNode(NULL,funTok,NULL,head->type,0,&recordOffset);
				}
				recordOffset += head->width;
			}
		}
		return var;
	}
	ASTNode* leftChild = child->child;
	ASTNode* rightChild = leftChild->next;
	Type leftType=-1,rightType=-1;
	VariableNode* leftNode = NULL;
	VariableNode* rightNode = NULL;
	leftType = (leftChild->token->tokenName==TK_NUM)? INT:-1;
	leftType = (leftChild->token->tokenName==TK_RNUM)?REAL:leftType;
	rightType = (rightChild->token->tokenName==TK_NUM)?INT:-1;
	rightType = (rightChild->token->tokenName==TK_RNUM)?REAL:rightType;
	if(leftType!=-1){
		generate(createInstruction(MOV,MEM,IMM,*tempCount,0,leftChild->token->value.intValue));
		leftNode = createVarNode(NULL,funTok,NULL,leftType,0,tempCount);
	}
	if(rightType!=-1){
		generate(createInstruction(MOV,MEM,IMM,*tempCount,0,rightChild->token->value.intValue));
		rightNode = createVarNode(NULL,funTok,NULL,rightType,0,tempCount);
	}
	if(	child->token->tokenName==TK_PLUS||
		child->token->tokenName==TK_MINUS||
		child->token->tokenName==TK_MUL||
		child->token->tokenName==TK_DIV||
		child->token->tokenName==TK_ASSIGNOP
	  ){
	  	if(leftType==-1)
			leftNode = generateArithmeticExpression(leftChild,funTok,tempCount);
		if(rightType==-1)
			rightNode = generateArithmeticExpression(rightChild,funTok,tempCount);
		if(leftType==-1 && leftNode!=NULL)
			leftType = leftNode->type;
		if(rightType==-1 && rightNode!=NULL)
			rightType = rightNode->type;
	}
	if(child->token->tokenName==TK_ASSIGNOP){

		if(leftType!=RECORD){
			generate(createInstruction(MOV, EAX, MEM, rightNode->offset,rightNode->isGlobal,0));
			generate(createInstruction(MOV, MEM, EAX, leftNode->offset,leftNode->isGlobal,0));
		}
		else{
			FieldList* field = leftNode->recordPtr->fields;
			int leftRecordOffset = leftNode->offset;
			int rightRecordOffset = rightNode->offset;
			for(;field!=NULL;field=field->next){
				generate(createInstruction(MOV, EAX, MEM, rightRecordOffset,rightNode->isGlobal,0));
				//int temp = leftRecordOffset;
				generate(createInstruction(MOV, MEM, EAX, leftRecordOffset,leftNode->isGlobal,0));								
				rightRecordOffset+=(field->width);
				leftRecordOffset+=field->width;
				//leftRecordOffset = temp + field->width;
			}
			return NULL;
		}
	}
	if(leftType==rightType && leftType!=RECORD){

		switch(child->token->tokenName){
			case TK_PLUS:	generate(createInstruction(MOV, EAX, MEM, leftNode->offset,leftNode->isGlobal,0));
							generate(createInstruction(ADD, EAX, MEM, rightNode->offset,rightNode->isGlobal,0));
							generate(createInstruction(MOV, MEM, EAX, *tempCount,0,0));
							break;
			case TK_MINUS:	generate(createInstruction(MOV, EAX, MEM, leftNode->offset,leftNode->isGlobal,0));
							generate(createInstruction(SUB, EAX, MEM, rightNode->offset,rightNode->isGlobal,0));
							generate(createInstruction(MOV, MEM, EAX, *tempCount,0,0));
							break;
			case TK_MUL:	generate(createInstruction(MOV, EAX, MEM, leftNode->offset,leftNode->isGlobal,0));
							generate(createInstruction(IMUL, MEM, NONE, rightNode->offset,rightNode->isGlobal,0));
							generate(createInstruction(MOV, MEM, EAX, *tempCount,0,0));
							break;
			case TK_DIV:	generate(createInstruction(MOV, EAX, MEM, leftNode->offset,leftNode->isGlobal,0));
							generate(createInstruction(MOV, EDX, IMM, 0,0,0));
							generate(createInstruction(IDIV, MEM, NONE, rightNode->offset,rightNode->isGlobal,0));
							generate(createInstruction(MOV, MEM, EAX, *tempCount,0,0));
							break;
		}
		localOffset = *tempCount;
		*tempCount = *tempCount + ((leftType==INT)?INT_WIDTH:REAL_WIDTH);
		return createVarNode(NULL,funTok,NULL,leftType,0,&localOffset);
	}
	else if(leftType==rightType){
		int leftRecordOffset = leftNode->offset;
		int rightRecordOffset = rightNode->offset;
		FieldList* field = leftNode->recordPtr->fields;
		localOffset = *tempCount;
		switch(child->token->tokenName){

			case TK_PLUS:	for(;field!=NULL;field=field->next){
								generate(createInstruction(MOV, EAX, MEM, leftRecordOffset,leftNode->isGlobal,0));
								generate(createInstruction(ADD, EAX, MEM, rightRecordOffset,rightNode->isGlobal,0));
								generate(createInstruction(MOV, MEM, EAX, *tempCount,0,0));
								leftRecordOffset+=field->width;
								rightRecordOffset+=field->width;
								*tempCount += field->width;
							}
							break;
			case TK_MINUS:	for(;field!=NULL;field=field->next){
								generate(createInstruction(MOV, EAX, MEM, leftRecordOffset,leftNode->isGlobal,0));
								generate(createInstruction(SUB, EAX, MEM, rightRecordOffset,rightNode->isGlobal,0));
								generate(createInstruction(MOV, MEM, EAX, *tempCount,0,0));
								leftRecordOffset+=field->width;
								rightRecordOffset+=field->width;
								*tempCount += field->width;
							}
							break;
		}
		return createVarNode(NULL,funTok,leftNode->recordPtr->recTok,leftType,0,&localOffset);
	}
	else{
		int recordOffset = (leftType==INT||leftType==REAL)?rightNode->offset:leftNode->offset;
		int scalarOffset = (leftType==INT||leftType==REAL)?leftNode->offset:rightNode->offset;
		int isGlobal = (leftType==INT||leftType==REAL)?rightNode->isGlobal:leftNode->isGlobal;
		FieldList* field = (leftType==INT||leftType==REAL)?rightNode->recordPtr->fields:leftNode->recordPtr->fields;
		RecordNode* recordPtr = (leftType==INT||leftType==REAL)?rightNode->recordPtr:leftNode->recordPtr;
		localOffset = *tempCount;
		switch(child->token->tokenName){

			case TK_MUL:	for(;field!=NULL;field=field->next){
								generate(createInstruction(MOV, EAX, MEM, recordOffset,isGlobal,0));
								generate(createInstruction(IMUL, MEM, NONE, scalarOffset,0,0));
								generate(createInstruction(MOV, MEM, EAX, *tempCount,0,0));
								recordOffset+=field->width;
								*tempCount += field->width;
							}
							break;
			case TK_DIV:	for(;field!=NULL;field=field->next){
								generate(createInstruction(MOV, EAX, MEM, recordOffset, isGlobal,0));
								generate(createInstruction(MOV, EDX, IMM, 0,0,0));
								generate(createInstruction(IDIV, MEM, NONE, scalarOffset,0,0));
								generate(createInstruction(MOV, MEM, EAX, *tempCount, 0,0));
								recordOffset+=field->width;
								*tempCount += field->width;
							}
							break;
		}
		return createVarNode(NULL,funTok,recordPtr->recTok,leftType,0,&localOffset);
	}
}
示例#8
0
/*
***************************************************************************************************************
*	createLabel:
*		labelType: This represents the type of label (0 or 1). 0---> F(False label) 1--->T(True label).
*		labelNum : This gives a number to the label.
*	This function is used to create labels in the code.The labels are of form T<labelNum> or F<labelNum>.
*	It stores labels in form of three address code i.e. Instruction List type.
****************************************************************************************************************
*/
InstructionList* createLabel(int labelType,int labelNum){
	InstructionList* newIns = createInstruction(-1,-1,-1,-1,-1,-1);
	newIns->isLabel = 1;
	(labelType)? sprintf(newIns->label,"T%d",labelNum):sprintf(newIns->label,"F%d",labelNum);
	return newIns;
}
示例#9
0
/* ------------------------------------------------------------------------------------------ */
void checkInstruction(ins *p){
	reg *rz=NULL;
	reg *rx=NULL;
	reg *ry=NULL;
	reg *rt=NULL;	// temporary register (may or not be used)
	ins *ip=NULL;	// auxiliary instruction pointer (for other registers)
	ins *ti=NULL;	// temporary instruction pointer (to be used with the temporary register)
	ins *mi=NULL;	// main instruction pointer (used with the final instruction)


	/*
	 *  >> input: rz = rx <op> ry
	 *
	 *
	 *	rx = ARP + lookup(rx->value)
	 *    	rx = * rx
	 *    	ry = ARP + lookup(ry->value)
	 *    	ry = * ry
	 *    	rt = rx <op> ry
	 *    	rz = ARP + lookup(rz->value)
	 *	*rz = rt
	 */


	if(p == NULL)
		return;

	#ifdef VERBOSE
		printf("\n");
		table_print(registers);
		printf("[checkInstruction] ");
		printInstruction(p);
	#endif



// :: -------------------------------- ::   THE ALGORITHM   ::

// 1st step:  ensure that 'rx' and 'ry' have register
// --

	// checking 'rx'
	if((p->src1[0] != '\0') && !isNumeric(p->src1)){
		rx=reg_search(p->src1);
		if(rx==NULL){
	
			// allocates register
			rx=reg_ensure(p->src1);
			if(isVar(p->src1)){
				
				// loading the local variable from memory
				load(p->src1);
				
				ip = createInstruction(idx++);
				copy(ip->dst, rx->name);
				ip->arp=true;
				ip->offset=lookup(p->src1);
				append(ip);

				ip = createInstruction(idx++);
				copy(ip->dst, rx->name);
				ip->ops1='*';
				copy(ip->src1, rx->name);
				append(ip);
			}
			if(rx!=NULL){
				// set properties for register
				rx->dist=distance(p, rx->value);
				rx->dirty=false;
			}
		}
	} else rx=NULL;

	// checking 'ry'
	if((p->src2[0] != '\0') && !isNumeric(p->src2)){
		ry=reg_search(p->src2);
		if(ry==NULL){

			// allocates register
			ry=reg_ensure(p->src2);
			if(isVar(p->src2)){
				
				// loading the local variable 'ry' from memory
				load(p->src2);
				
				// loading the local variable 'ry' from memory
				ip = createInstruction(idx++);
				copy(ip->dst, ry->name);
				ip->arp=true;
				ip->offset=lookup(p->src2);
				append(ip);
	
				ip = createInstruction(idx++);
				copy(ip->dst, ry->name);
				ip->ops1='*';
				copy(ip->src1, ry->name);
				append(ip);
			}
			if(ry!=NULL){
				// set properties for register
				ry->dist=distance(p, ry->value);
				ry->dirty=true;
			}
		}
	} else ry=NULL;

// 2nd step: allocate the 'rt' temporary register; creates the 'ti' temporary instruction
// --

	ti = createInstruction(idx++);

	// get 'rx'
	if(isNumeric(p->src1))
		copy(ti->src1, p->src1);  // found a constant
	else if(rx!=NULL)
		copy(ti->src1, rx->name); // got the 'rx'

	// get the operator
	ti->ops2=p->ops2;

	// get 'ry'
	if(isNumeric(p->src2))
		copy(ti->src2, p->src2);  // found a constant
	else if(ry!=NULL)
		copy(ti->src2, ry->name); // got the 'ry'

	if((p->dst[0] != '\0') && !isNumeric(p->dst)){

		// allocate the 'rt' register ("r0" by default)
		rt=reg_search("store");
//		rt=reg_get();
		if(rt!=NULL)
			rt->dirty=false;
	} else rt=NULL; // this could lead to an error
	if(rt!=NULL)
		copy(ti->dst, rt->name);

	append(ti);

// 3rd step: frees if possible frees 'rx' and 'ry'
// --

	// free 'rx'
	if((rx!=NULL) && (rx->dist==MAXDIST || rx->dist==-2))
		reg_free(rx);
	// free 'ry'
	if((ry!=NULL) && (ry->dist==MAXDIST || ry->dist==-2))
		reg_free(ry);

// 4th step: allocate the 'rz' register and create the main instruction 'mi'
// --

	mi = createInstruction(idx++);

	// allocate the 'rz' register
	if((p->dst[0] != '\0') && !isNumeric(p->dst)){

		// store
		store(p->dst);
		rz=reg_search(p->dst);
		if(rz==NULL){
			
			// allocates register
			rz=reg_ensure(p->dst);

			if(isVar(p->dst)){
				// loads the local variable for store operation
				ip = createInstruction(idx++);
				copy(ip->dst, rz->name);
				ip->arp=true;
				ip->offset=lookup(p->dst);
				append(ip);
			}
			if(rz!=NULL){
				// set properties for register
				rz->dist=distance(p, rz->value);
				rz->dirty=false;
			}
		}
	} else rz=NULL; // this would be an error
	if(rz!=NULL)
		copy(mi->dst, rz->name);
	if(rt!=NULL)
		copy(mi->src1, rt->name);
	if(isVar(p->dst))
		mi->opd='*';
	append(mi);


// 5th step: frees 'rt'; if possible frees 'rz'
// --

	#ifdef VERBOSE
		if(rt!=NULL) printf(" [rt] store: %s :: (%s)\n", rt->name, rt->value);
		else printf(" [rt] is null\n");
		if(rz!=NULL) printf(" [rz] store: %s :: (%s)\n", rz->name, rz->value);
		else printf(" [rz] is null\n");
	#endif
	// free 'rt'
	if(rt!=NULL) reg_free(rt);
	// free 'rz'
	if((rz!=NULL) && (rz->dist==MAXDIST || rz->dist<0))
		reg_free(rz);

// 6th step: set the dirty property for the registers
// --
	// check 'rx'
	if(rx!=NULL)
		rx->dirty=true;
	// check 'ry'
	if(ry!=NULL)
		ry->dirty=true;
	// check 'rt'
	if(rt!=NULL)
		rt->dirty=true;
	// check 'rz'
	if(rz!=NULL)
		rz->dirty=false;

// nota: um registo e' dirty apenas quando o seu conteudo e' manipulado na memoria !!!!
//      (confirmar e corrigir se necessario o 6o passo)
//      mudar os valores de dirty para oposto:  'false' <-> 'true'

// :: -------------------------------- ::   THE END   ::

	#ifdef VERBOSE
		table_print(registers);
		printf("\n");
	#endif
	return;
}
示例#10
0
/* ------------------------------------------------------------------------------ */
void readInstructionsFromFile(char *fname){
  int i;
  ins *ip;
  FILE *fp;
  char tk[4]={' ', '\t', '\n', '\0'};
  char str[80];
  char *s1, *s2, *s3, *s4, *s5;

  i = 0;
  fp = fopen(fname,"r");
  if(fp == NULL){
    printf(" *** Error: Cannot open (%s) as instruction input file \n",fname);
    Code = NULL;
    return;
  } 

  Code = createBasicBlock(0);

  while(fgets(str,79,fp) != NULL){

#ifdef DEBUG 
// printf("read::: %s", str);
#endif

    s1 = (char*)strtok(str, tk);
    if(s1 == NULL){
      break;
    }
    s2 = (char*)strtok(NULL, tk);
    if(s2[0] != '='){
      printf(" *** Error: Could not locate '=' operator in instruction as second field of input\n");
      continue;
    }
    s3 = (char*)strtok(NULL, tk);

    s4 = (char*)strtok(NULL, tk);
    if(s4 != NULL){
      s5 = (char*)strtok(NULL, tk);
    } else {
      s5 = NULL;
    }
#ifdef DEBUG
//    printf(" parsed::: %s  %s  %s  %s  %s\n",s1, s2, s3, s4, s5);
#endif

    ip = createInstruction(i);

    if(s1[0] == '*'){
      setInstructionDestOperand(ip,'*');
      setInstructionDest(ip, &s1[1]);
    } else {
      setInstructionDest(ip, &s1[0]);
    }
    if((s3[0] == '*') || (s3[0] == '-')){
      setInstructionSource1Operand(ip, s3[0]);
      setInstructionSource1(ip, &s3[1]);
    } else {
      setInstructionSource1(ip, &s3[0]);
    }
    if(s4 != NULL){
      setInstructionSource2Operand(ip, s4[0]);
      if(s5 != NULL){
        setInstructionSource2(ip, s5);
      } else {
	printf(" *** Error: Was expecting a second operand in instruction %d (remove infix operand)\n",i);
        setInstructionSource2Operand(ip,' ');
      }
    }

    appendInstruction(Code,ip); 
#ifdef DEBUG 
//    printf("  ...dumping instruction::\n");
//      dumpInstruction(ip);
//    printf("\n");
#endif

    i++;
  }

#ifdef DEBUG 
 // printf(" Read %d instructions \n",i);
 // printBasicBlock(Code);
#endif

  fclose(fp);
}