⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 virtualmachine.cpp

📁 袖珍型的pascal编译器
💻 CPP
📖 第 1 页 / 共 2 页
字号:

void CVirtualMachine::STOP()
{
	m_ST = MS_STOP;
}

// Error instruction

void CVirtualMachine::ERR()
{
	m_IE = AD(m_NI+VM_ICSIZE);
	m_ST = MS_ERROR;
	m_NI += VM_ICSIZE;
}

// The input instruction

void CVirtualMachine::INP()
{
	BYTE what = m_pbMem[m_NI+VM_ICSIZE];
	m_SP += SE_SIZE;
	SE(m_SP).m_nType = what;
	switch (what)
	{
	case SE_CHAR:	// Read a character
		CHAR c;
		c=getchar();
		CV_CHAR(SE(m_SP).m_Info) = c;
		break;
	case SE_INTEGER:
		INTEGER n;
		scanf("%d",&n);
		
		c=getchar(); // read enter from the buffer

		CV_INTEGER(SE(m_SP).m_Info) = n;
		break;
	case SE_REAL:
		REAL x;
		scanf("%f",&x);

		c=getchar(); // read enter from the buffer
		CV_REAL(SE(m_SP).m_Info) = x;
		break;
	default:
		m_ST = MS_ERROR;
	}
	m_NI += VM_ICSIZE + 1; // BYTE size = 1
}

// The output instruction

void CVirtualMachine::OUTP()
{
	switch (SE(m_SP).m_nType)
	{
	case SE_CHAR:	// Print a character
		printf("%c",CV_CHAR(SE(m_SP).m_Info));
		break;
	case SE_INTEGER:
		printf("%d",CV_INTEGER(SE(m_SP).m_Info));
		break;
	case SE_REAL:
		printf("%f",CV_REAL(SE(m_SP).m_Info));
		break;
	default:
		m_ST = MS_ERROR;
	}
	m_SP -= SE_SIZE;
	m_NI += VM_ICSIZE ; 
}

// The AND logical instruction

void CVirtualMachine::AND()
{
	m_SP -= SE_SIZE;
	if (SE(m_SP).m_nType != SE(m_SP + SE_SIZE).m_nType) 
		m_ST = MS_ERROR;
	else
		SE(m_SP).m_Info = SE(m_SP).m_Info && SE(m_SP + SE_SIZE).m_Info;
	m_NI += VM_ICSIZE;
}

// The OR logical instruction

void CVirtualMachine::OR()
{
	m_SP -= SE_SIZE;
	if (SE(m_SP).m_nType != SE(m_SP + SE_SIZE).m_nType) 
		m_ST = MS_ERROR;
	else
		SE(m_SP).m_Info = SE(m_SP).m_Info || SE(m_SP + SE_SIZE).m_Info;
	m_NI += VM_ICSIZE;
}


///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 5/25/99 1:43:13 PM
// Function name	: CVirtualMachine::LoadMemoryContent
// Description	    : This function Loads the memory content for the VM
// Return type		: void 
// Argument         : REGISTER addrTo - The address of the VM Where the data is loaded
// Argument         : BYTE *from - pointer to the buffer where the data is
// Argument         : int count -  length of the data
///////////////////////////////////////////////////////////////

void CVirtualMachine::LoadMemoryContent(REGISTER addrTo, BYTE *from, int count)
{
	int addrEnd = (addrTo + count < m_nMemSize) ? addrTo + count : m_nMemSize;
	for (int i = addrTo; i<addrEnd ; i++)	// copy the memory content, can be optimized using memcpy
		m_pbMem[i] = from[i-addrTo];
}


///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 5/25/99 2:01:15 PM
// Function name	: CVirtualMachine::NOP
// Description	    : The No Operation Instruction
// Return type		: void 
///////////////////////////////////////////////////////////////

void CVirtualMachine::NOP()
{
	m_NI += VM_ICSIZE;
}


///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 5/27/99 11:00:08 AM
// Function name	: CVirtualMachine::ENTER
// Description	    : Enter instruction This is support for advanced
//					: programming languages, Like Pasca
// Return type		: void 
///////////////////////////////////////////////////////////////

void CVirtualMachine::ENTER()
{
	// Parameter the entry level for procedure/function
	BYTE level = m_pbMem[m_NI+VM_ICSIZE];
	
	// Parameter the number of local variables alocated
	REGISTER locals = AD(m_NI+VM_ICSIZE+1);


	// Save the CALee's StackFrame pointer to the stack

	m_SP += SE_SIZE;
	SE(m_SP).m_nType = SE_ADDRESS;		
	CV_ADDRESS(SE(m_SP).m_Info) = m_FP;
	
	REGISTER tmp = m_SP;
		
	// Save the superior level Stack pointers to the stack
	
	for (int i=0; i<level-1; i+=SE_SIZE)
	{
		m_SP+=SE_SIZE;
		SE(m_SP) = SE(m_FP + (i+1) * SE_SIZE);
	}
	 
	// Put own Stack Frame
	m_SP += SE_SIZE;
	SE(m_SP).m_nType = SE_ADDRESS;		
	CV_ADDRESS(SE(m_SP).m_Info) = tmp;


	
	m_FP = tmp;	// Set the new Frame Pointer 
	m_CFP = m_FP;
	
	// Alloc local variables

	m_SP += locals * SE_SIZE;

	// increase the program counter
	m_NI += VM_ICSIZE+VM_BYTES + 1;
}


///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 5/27/99 11:10:33 AM
// Function name	: CVirtualMachine::LEAVE
// Description	    : Leave function / procedure , clears the display from the stack
// Return type		: void 
///////////////////////////////////////////////////////////////

void CVirtualMachine::LEAVE()
{
	// Leaves the bullshit function or procedure
	
	// free the stack
	m_SP = m_FP - SE_SIZE;
	m_FP = CV_ADDRESS(SE(m_FP).m_Info);
	m_CFP = m_FP;
	// increase the program counter
	m_NI += VM_ICSIZE;
}


///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 5/27/99 1:37:32 PM
// Function name	: CVirtualMachine::CHGSFR
// Description	    : This function is just changing the current frame pointer
//					: To the level specified relatively, takes the FP from the current FP
// Return type		: void 
// Argument         : void
///////////////////////////////////////////////////////////////

void CVirtualMachine::CHGSFP(void)
{
	// Parameter the entry level for procedure/function
	BYTE level = m_pbMem[m_NI+VM_ICSIZE];
	
	//now taking setting the FP
	m_FP = CV_ADDRESS(SE(m_FP + level * SE_SIZE).m_Info);
	// increase the program counter
	m_NI += VM_ICSIZE+ 1;

}


///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 5/27/99 1:37:35 PM
// Function name	: CVirtualMachine::RSTSFR
// Description	    : Restores the FP to the current FP
// Return type		: void 
///////////////////////////////////////////////////////////////

void CVirtualMachine::RSTSFP()
{
	// restores FP
	m_FP = m_CFP;
	// increase the program counter
	m_NI += VM_ICSIZE;
}


///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 5/28/99 12:58:01 PM
// Function name	: CVirtualMachine::LODA
// Description	    : Load address to the stack offset relative
// Return type		: void 
///////////////////////////////////////////////////////////////

void CVirtualMachine::LODA()
{
	m_SP += SE_SIZE;
	StackEntry entry;
	entry.m_nType = SE_ADDRESS;
	CV_ADDRESS(entry.m_Info) = m_FP + SE_SIZE * OFFS(m_NI+VM_ICSIZE);
	SE(m_SP) = entry;
	m_NI += VM_ICSIZE + VM_BYTES;
}


///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 5/28/99 1:01:26 PM
// Function name	: CVirtualMachine::LODAX
// Description	    : THe same as loda but relative to RX register
// Return type		: void 
///////////////////////////////////////////////////////////////

void CVirtualMachine::LODAX()
{
	m_SP += SE_SIZE;
	StackEntry entry;
	entry.m_nType = SE_ADDRESS;
	CV_ADDRESS(entry.m_Info) = m_FP + SE_SIZE * (m_RX+ OFFS(m_NI+VM_ICSIZE));
	SE(m_SP) = entry;
	m_NI += VM_ICSIZE + VM_BYTES;
}


///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 5/28/99 1:46:36 PM
// Function name	: CVirtualMachine::LODEA
// Description	    : Loads the element pointed by the value pointed by the FP + offset
// Return type		: void 
///////////////////////////////////////////////////////////////

void CVirtualMachine::LODEA()
{
	m_SP += SE_SIZE;
	SE(m_SP) = SE( CV_ADDRESS(SE(m_FP + SE_SIZE * OFFS(m_NI+VM_ICSIZE)).m_Info));
	m_NI += VM_ICSIZE + VM_BYTES;
}



///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 6/1/99 2:20:58 PM
// Function name	: CVirtualMachine::PUSH
// Description	    : Pushes the specified register into the stack
// Return type		: void 
///////////////////////////////////////////////////////////////

void CVirtualMachine::PUSH()
{
	BYTE reg = m_pbMem[m_NI+VM_ICSIZE];
	m_SP += SE_SIZE;
	SE(m_SP) = m_SREG[reg];
	m_NI += VM_ICSIZE+1;
}


///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 6/1/99 2:21:28 PM
// Function name	: CVirtualMachine::POP
// Description	    : Pops the TOS into the specified register
// Return type		: void 
///////////////////////////////////////////////////////////////

void CVirtualMachine::POP()
{
	BYTE reg = m_pbMem[m_NI+VM_ICSIZE];
	m_SREG[reg] = SE(m_SP);
	m_SP -= SE_SIZE;
	m_NI += VM_ICSIZE+1;
}


///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 6/2/99 11:14:39 AM
// Function name	: CVirtualMachine::USTO
// Description	    : Put's the value pointed by the address in the Top of stack
//					: in the top of stack
// Return type		: void 
///////////////////////////////////////////////////////////////

void CVirtualMachine::USTO()
{
	SE(m_SP) = SE(CV_ADDRESS(SE(m_SP).m_Info));
	m_NI += VM_ICSIZE;
}


///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 6/3/99 5:13:10 PM
// Function name	: CVirtualMachine::Continue
// Description	    : This function continues the execution of the machine
// Return type		: void 
///////////////////////////////////////////////////////////////

REGISTER CVirtualMachine::Continue()
{
	return Start (m_NI,m_SP);
}


///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 6/4/99 3:45:25 PM
// Function name	: CVirtualMachine::GetMem
// Description	    : Returns a pointer to the Virtual machine's memory
// Return type		: BYTE * 
///////////////////////////////////////////////////////////////

BYTE * CVirtualMachine::GetMem()
{
	return m_pbMem;
}


///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 6/4/99 9:50:11 AM
// Function name	: CVirtualMachine::LoadMemoryContent
// Description	    : Load Memory content from a file
// Return type		: int 
// Argument         : REGISTER addrTo
// Argument         : CFile *from
// Argument         : int count
///////////////////////////////////////////////////////////////

int CVirtualMachine::LoadMemoryContent(REGISTER addrTo, CFile *from, int count)
{
	return from->Read( &m_pbMem[addrTo], count);
}


///////////////////////////////////////////////////////////////
// Programmer		: Zoly Farkas
// Creation Date	: 6/8/99 1:33:55 PM
// Function name	: CVirtualMachine::NFJP
// Description	    : this is the oposite instruction to FJP, it jumps when Flag is FALSE
// Return type		: void 
///////////////////////////////////////////////////////////////

void CVirtualMachine::NFJP()
{
	if (!CV_BOOLEAN(SE(m_SP).m_Info))
		m_NI = AD(m_NI+VM_ICSIZE);
	else
		m_NI += VM_ICSIZE + VM_BYTES;
	m_SP -= SE_SIZE;

}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -