Initial commit
This commit is contained in:
156
P2/ChainingHashTable.cpp
Normal file
156
P2/ChainingHashTable.cpp
Normal file
@@ -0,0 +1,156 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "ChainingHashTable.h"
|
||||
#include "Process.h"
|
||||
|
||||
ChainingHashTable::ChainingHashTable(int size)
|
||||
{
|
||||
processList = new std::vector<Process *>[size];
|
||||
maxCount = size;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
ChainingHashTable::~ChainingHashTable()
|
||||
{
|
||||
for (int i = 0; i < maxCount; i++)
|
||||
{
|
||||
for (int j = 0; j < processList[i].size(); j++)
|
||||
{
|
||||
delete processList[i][j];
|
||||
}
|
||||
}
|
||||
|
||||
delete[] processList;
|
||||
}
|
||||
|
||||
/// @brief Insert a process into the hash table
|
||||
/// @param p the process to insert
|
||||
/// @return true if insertion was successful, false otherwise
|
||||
bool ChainingHashTable::Insert(Process *p)
|
||||
{
|
||||
if (count >= maxCount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
int hashedIndex = p->getPid() % maxCount;
|
||||
|
||||
int indexSize = processList[hashedIndex].size();
|
||||
|
||||
if (indexSize == 0)
|
||||
{
|
||||
processList[hashedIndex].emplace_back(p);
|
||||
count++;
|
||||
return true;
|
||||
}
|
||||
|
||||
// attempt to insert in the middle of the vector
|
||||
for (int i = 0; i < indexSize; i++)
|
||||
{
|
||||
if (processList[hashedIndex][i]->getPid() == p->getPid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// store in descending order (9, 8, 7,...)
|
||||
if (processList[hashedIndex][i]->getPid() < p->getPid())
|
||||
{
|
||||
processList[hashedIndex].insert(processList[hashedIndex].begin() + i, p);
|
||||
count++;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// insert at the end of the vector if we have to
|
||||
processList[hashedIndex].emplace_back(p);
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @brief Search the hash table for the PID
|
||||
/// @param PID the PID to search the hash table for
|
||||
/// @return the index if in the hash table, or -1 otherwise
|
||||
int ChainingHashTable::Search(unsigned int PID)
|
||||
{
|
||||
int hashedIndex = PID % maxCount;
|
||||
|
||||
int indexSize = processList[hashedIndex].size();
|
||||
|
||||
for (int i = 0; i < indexSize; i++)
|
||||
{
|
||||
if (processList[hashedIndex][i]->getPid() == PID)
|
||||
{
|
||||
return hashedIndex;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// @brief Get a pointer to the process with PID
|
||||
/// @param PID the PID to look for
|
||||
/// @return a pointer to the process, or nullptr if the process does not exist
|
||||
Process *ChainingHashTable::Get(unsigned int PID)
|
||||
{
|
||||
int hashedIndex = PID % maxCount;
|
||||
|
||||
int indexSize = processList[hashedIndex].size();
|
||||
|
||||
for (int i = 0; i < indexSize; i++)
|
||||
{
|
||||
if (processList[hashedIndex][i]->getPid() == PID)
|
||||
{
|
||||
return processList[hashedIndex][i];
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// @brief Remove a process from the hash table with a given PID
|
||||
/// @param PID the PID of the process to remove
|
||||
/// @return true if the process was removed, false otherwise
|
||||
bool ChainingHashTable::Remove(unsigned int PID)
|
||||
{
|
||||
int hashedIndex = PID % maxCount;
|
||||
|
||||
int indexSize = processList[hashedIndex].size();
|
||||
|
||||
for (int i = 0; i < indexSize; i++)
|
||||
{
|
||||
if (processList[hashedIndex][i]->getPid() == PID)
|
||||
{
|
||||
delete processList[hashedIndex][i];
|
||||
processList[hashedIndex].erase(processList[hashedIndex].begin() + i);
|
||||
count--;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// @brief Print out the value of the chain at index m
|
||||
/// @param m the index to print the chain of
|
||||
void ChainingHashTable::Print(unsigned int m)
|
||||
{
|
||||
if (m >= maxCount)
|
||||
{
|
||||
std::cout << "chain is empty" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
int indexSize = processList[m].size();
|
||||
|
||||
for (int i = 0; i < indexSize; i++)
|
||||
{
|
||||
if (i != 0)
|
||||
std::cout << " ";
|
||||
|
||||
std::cout << processList[m][i]->getPid();
|
||||
}
|
||||
|
||||
if (indexSize < 1)
|
||||
{
|
||||
std::cout << "chain is empty";
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
}
|
||||
23
P2/ChainingHashTable.h
Normal file
23
P2/ChainingHashTable.h
Normal file
@@ -0,0 +1,23 @@
|
||||
#ifndef CHAININGHASHTABLE_H
|
||||
#define CHAININGHASHTABLE_H
|
||||
|
||||
#include <vector>
|
||||
#include "Process.h"
|
||||
#include "HashTable.h"
|
||||
|
||||
class ChainingHashTable : public HashTable
|
||||
{
|
||||
public:
|
||||
bool Insert(Process *p);
|
||||
int Search(unsigned int PID);
|
||||
Process *Get(unsigned int PID);
|
||||
bool Remove(unsigned int PID);
|
||||
void Print(unsigned int m);
|
||||
|
||||
ChainingHashTable(int size);
|
||||
~ChainingHashTable();
|
||||
|
||||
private:
|
||||
std::vector<Process *> *processList;
|
||||
};
|
||||
#endif
|
||||
177
P2/DoubleHashTable.cpp
Normal file
177
P2/DoubleHashTable.cpp
Normal file
@@ -0,0 +1,177 @@
|
||||
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
|
||||
#include "DoubleHashTable.h"
|
||||
#include "Process.h"
|
||||
|
||||
DoubleHashTable::DoubleHashTable(int size)
|
||||
{
|
||||
processList = new Process *[size];
|
||||
maxCount = size;
|
||||
count = 0;
|
||||
|
||||
for (int i = 0; i < size; i++)
|
||||
{
|
||||
processList[i] = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
DoubleHashTable::~DoubleHashTable()
|
||||
{
|
||||
for (int i = 0; i < maxCount; i++)
|
||||
{
|
||||
if (processList[i] != nullptr)
|
||||
delete processList[i];
|
||||
}
|
||||
|
||||
delete[] processList;
|
||||
}
|
||||
|
||||
/// @brief Insert a process into the hash table
|
||||
/// @param p pointer to the process to insert
|
||||
/// @return true if successful, false otherwise
|
||||
bool DoubleHashTable::Insert(Process *p)
|
||||
{
|
||||
if (count >= maxCount)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Continually hash until we have reached a nullpointer, -1, or the end
|
||||
int emptyIndex = -1;
|
||||
for (int i = 0; i < maxCount; i++)
|
||||
{
|
||||
unsigned int hashedIndex = HashIndex(p->getPid(), i);
|
||||
|
||||
// If we have reached a nullptr, and have not seen any empty slots before
|
||||
if (processList[hashedIndex] == nullptr && emptyIndex == -1)
|
||||
{
|
||||
// Replace the nullpointer with the process
|
||||
processList[hashedIndex] = p;
|
||||
return true;
|
||||
}
|
||||
// If we have reached a nullpointer and have seen an empty slot before
|
||||
else if (processList[hashedIndex] == nullptr && emptyIndex != -1)
|
||||
{
|
||||
// Replace the -1 with the process
|
||||
hashedIndex = HashIndex(p->getPid(), emptyIndex);
|
||||
delete processList[hashedIndex];
|
||||
processList[hashedIndex] = p;
|
||||
return true;
|
||||
}
|
||||
// If we find a process with the same PID already, exit
|
||||
else if (processList[hashedIndex]->getPid() == p->getPid())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
// If we have found a slot of -1
|
||||
else if (processList[hashedIndex]->getStartingIndex() == -1 && emptyIndex == -1)
|
||||
{
|
||||
// If we can insert in the empty slot (have reached the end)
|
||||
emptyIndex = i;
|
||||
if (!(i + 1 < maxCount))
|
||||
{
|
||||
delete processList[hashedIndex];
|
||||
processList[hashedIndex] = p;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Insert into the empty slot - theoretically we do not need the code in the if statement of the last else if clause, but it works...
|
||||
if (emptyIndex != -1)
|
||||
{
|
||||
unsigned int hashedIndex = HashIndex(p->getPid(), emptyIndex);
|
||||
delete processList[hashedIndex];
|
||||
processList[hashedIndex] = p;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// @brief Search the hash table for the given PID
|
||||
/// @param PID the pid to search for
|
||||
/// @return the index of the process, or -1 if the process does not exist
|
||||
int DoubleHashTable::Search(unsigned int PID)
|
||||
{
|
||||
for (int i = 0; i < maxCount; i++)
|
||||
{
|
||||
int hashedIndex = HashIndex(PID, i);
|
||||
|
||||
if (hashedIndex >= maxCount || processList[hashedIndex] == nullptr)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if (processList[hashedIndex]->getPid() == PID)
|
||||
{
|
||||
return hashedIndex;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/// @brief Search the hash table for the given PID, and return a pointer to the process object
|
||||
/// @param PID the pid to search for
|
||||
/// @return A valid process object if it exists, or a nullpointer otherwise
|
||||
Process *DoubleHashTable::Get(unsigned int PID)
|
||||
{
|
||||
for (int i = 0; i < maxCount; i++)
|
||||
{
|
||||
int hashedIndex = HashIndex(PID, i);
|
||||
|
||||
if (hashedIndex >= maxCount || processList[hashedIndex] == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
else if (processList[hashedIndex]->getPid() == PID)
|
||||
{
|
||||
return processList[hashedIndex];
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// @brief Remove a process object from the hash table
|
||||
/// @param PID the PID of the process to remove
|
||||
/// @return true if the process was successfully removed, false otherwise
|
||||
bool DoubleHashTable::Remove(unsigned int PID)
|
||||
{
|
||||
for (int i = 0; i < maxCount; i++)
|
||||
{
|
||||
int hashedIndex = HashIndex(PID, i);
|
||||
|
||||
if (hashedIndex >= maxCount || processList[hashedIndex] == nullptr)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if (processList[hashedIndex]->getPid() == PID)
|
||||
{
|
||||
delete processList[hashedIndex];
|
||||
processList[hashedIndex] = new Process(0, -1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// @brief Compute the hash of k and i.
|
||||
/// @param k the k value to hash (PID)
|
||||
/// @param i the i value to hash (index)
|
||||
/// @return the hashed value
|
||||
int DoubleHashTable::HashIndex(unsigned int k, int i)
|
||||
{
|
||||
unsigned int h1 = k % maxCount;
|
||||
unsigned int h2 = (int)std::floor(k / maxCount) % maxCount;
|
||||
|
||||
if (h2 % 2 == 0)
|
||||
h2++;
|
||||
|
||||
return (h1 + i * h2) % maxCount;
|
||||
}
|
||||
|
||||
void DoubleHashTable::Print(unsigned int m)
|
||||
{
|
||||
// Not implemented
|
||||
}
|
||||
24
P2/DoubleHashTable.h
Normal file
24
P2/DoubleHashTable.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef DOUBLEHASHTABLE_H
|
||||
#define DOUBLEHASHTABLE_H
|
||||
|
||||
#include <vector>
|
||||
#include "Process.h"
|
||||
#include "HashTable.h"
|
||||
|
||||
class DoubleHashTable : public HashTable
|
||||
{
|
||||
public:
|
||||
bool Insert(Process *p);
|
||||
int Search(unsigned int PID);
|
||||
Process *Get(unsigned int PID);
|
||||
bool Remove(unsigned int PID);
|
||||
void Print(unsigned int m);
|
||||
|
||||
DoubleHashTable(int size);
|
||||
~DoubleHashTable();
|
||||
|
||||
private:
|
||||
Process **processList;
|
||||
int HashIndex(unsigned int k, int i);
|
||||
};
|
||||
#endif
|
||||
20
P2/HashTable.h
Normal file
20
P2/HashTable.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef HASHTABLE_H
|
||||
#define HASHTABLE_H
|
||||
|
||||
#include <vector>
|
||||
#include "Process.h"
|
||||
|
||||
class HashTable
|
||||
{
|
||||
public:
|
||||
virtual bool Insert(Process *p) = 0;
|
||||
virtual int Search(unsigned int PID) = 0;
|
||||
virtual Process *Get(unsigned int PID) = 0;
|
||||
virtual bool Remove(unsigned int PID) = 0;
|
||||
virtual void Print(unsigned int m) = 0;
|
||||
|
||||
protected:
|
||||
int maxCount;
|
||||
int count;
|
||||
};
|
||||
#endif
|
||||
2
P2/Makefile
Normal file
2
P2/Makefile
Normal file
@@ -0,0 +1,2 @@
|
||||
all: test.cpp ChainingHashTable.cpp DoubleHashTable.cpp Process.cpp VirtualMemory.cpp
|
||||
g++ -std=c++11 test.cpp ChainingHashTable.cpp DoubleHashTable.cpp Process.cpp VirtualMemory.cpp
|
||||
17
P2/Process.cpp
Normal file
17
P2/Process.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "Process.h"
|
||||
|
||||
Process::Process(unsigned int PID, int startingIndex)
|
||||
{
|
||||
this->PID = PID;
|
||||
this->startingIndex = startingIndex;
|
||||
}
|
||||
|
||||
unsigned int Process::getPid()
|
||||
{
|
||||
return this->PID;
|
||||
}
|
||||
|
||||
int Process::getStartingIndex()
|
||||
{
|
||||
return this->startingIndex;
|
||||
}
|
||||
16
P2/Process.h
Normal file
16
P2/Process.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef PROCESS_H
|
||||
#define PROCESS_H
|
||||
|
||||
class Process
|
||||
{
|
||||
public:
|
||||
unsigned int getPid();
|
||||
int getStartingIndex();
|
||||
|
||||
Process(unsigned int PID, int startingIndex);
|
||||
|
||||
private:
|
||||
unsigned int PID;
|
||||
int startingIndex;
|
||||
};
|
||||
#endif
|
||||
136
P2/VirtualMemory.cpp
Normal file
136
P2/VirtualMemory.cpp
Normal file
@@ -0,0 +1,136 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "VirtualMemory.h"
|
||||
#include "ChainingHashTable.h"
|
||||
#include "DoubleHashTable.h"
|
||||
|
||||
VirtualMemory::VirtualMemory(int n, int p, bool chaining)
|
||||
{
|
||||
if (chaining)
|
||||
{
|
||||
ht = new ChainingHashTable(n / p);
|
||||
}
|
||||
else
|
||||
{
|
||||
ht = new DoubleHashTable(n / p);
|
||||
}
|
||||
|
||||
this->chaining = chaining;
|
||||
this->memorySize = n;
|
||||
this->pageSize = p;
|
||||
this->memory = new int[n];
|
||||
|
||||
// push the indices onto the free memory
|
||||
for (int i = 0; i < n / p; i++)
|
||||
{
|
||||
freeMemory.push_back(i);
|
||||
}
|
||||
}
|
||||
|
||||
VirtualMemory::~VirtualMemory()
|
||||
{
|
||||
if (chaining)
|
||||
{
|
||||
delete (ChainingHashTable *)ht;
|
||||
}
|
||||
else
|
||||
{
|
||||
delete (DoubleHashTable *)ht;
|
||||
}
|
||||
|
||||
delete[] memory;
|
||||
}
|
||||
|
||||
/// @brief Allocate memory for process PID
|
||||
/// @param PID the PID to allocate memory for
|
||||
/// @return true if successful, false otherwise
|
||||
bool VirtualMemory::Insert(unsigned int PID)
|
||||
{
|
||||
if (freeMemory.size() <= 0)
|
||||
return false;
|
||||
|
||||
int memoryIndex = freeMemory.back();
|
||||
freeMemory.pop_back();
|
||||
|
||||
Process *p = new Process(PID, memoryIndex);
|
||||
if (!ht->Insert(p))
|
||||
{
|
||||
delete p;
|
||||
freeMemory.push_back(memoryIndex);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @brief Search the hash table for the index of PID
|
||||
/// @param PID the PID of the process to search for
|
||||
/// @return the index of the process object, -1 if the object does not exist
|
||||
int VirtualMemory::Search(unsigned int PID)
|
||||
{
|
||||
return ht->Search(PID);
|
||||
}
|
||||
|
||||
/// @brief Write to a process's memory
|
||||
/// @param PID The PID of the memory to write to
|
||||
/// @param addr The virtual address of the memory to write to
|
||||
/// @param x The value to write into memory
|
||||
/// @return true if successful, false otherwise
|
||||
bool VirtualMemory::Write(unsigned int PID, int addr, int x)
|
||||
{
|
||||
if (addr >= pageSize || addr < 0)
|
||||
return false;
|
||||
|
||||
Process *p = ht->Get(PID);
|
||||
|
||||
// if we do not have any memory allocated to PID
|
||||
if (p == nullptr)
|
||||
return false;
|
||||
|
||||
memory[p->getStartingIndex() * pageSize + addr] = x;
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @brief Read the memory
|
||||
/// @param PID The PID of the process to read memory of
|
||||
/// @param addr The virtual address of memory to read from
|
||||
void VirtualMemory::Read(unsigned int PID, int addr)
|
||||
{
|
||||
if (addr >= pageSize)
|
||||
{
|
||||
std::cout << "failure" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
Process *p = ht->Get(PID);
|
||||
// if we do not have any memory allocated to PID
|
||||
if (p == nullptr)
|
||||
{
|
||||
std::cout << "failure" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
std::cout << addr << " " << memory[p->getStartingIndex() * pageSize + addr] << std::endl;
|
||||
}
|
||||
|
||||
/// @brief Deallocate memory from process PID.
|
||||
/// @param PID The PID of the process to dealocate memory from
|
||||
/// @return true if successful, false otherwise
|
||||
bool VirtualMemory::Delete(unsigned int PID)
|
||||
{
|
||||
Process *p = ht->Get(PID);
|
||||
|
||||
if (p == nullptr)
|
||||
return false;
|
||||
|
||||
freeMemory.push_back(p->getStartingIndex());
|
||||
|
||||
return ht->Remove(PID);
|
||||
}
|
||||
|
||||
/// @brief Print the chain of the hash table at index m
|
||||
/// @param m the index of the chain to print
|
||||
void VirtualMemory::Print(int m)
|
||||
{
|
||||
ht->Print(m);
|
||||
}
|
||||
30
P2/VirtualMemory.h
Normal file
30
P2/VirtualMemory.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef VIRTUALMEMORY_H
|
||||
#define VIRTUALMEMORY_H
|
||||
|
||||
#include "Process.h"
|
||||
#include "HashTable.h"
|
||||
|
||||
class VirtualMemory
|
||||
{
|
||||
public:
|
||||
VirtualMemory(int n, int p, bool chaining);
|
||||
~VirtualMemory();
|
||||
|
||||
bool Insert(unsigned int PID);
|
||||
int Search(unsigned int PID);
|
||||
|
||||
bool Write(unsigned int PID, int addr, int x);
|
||||
void Read(unsigned int PID, int addr);
|
||||
|
||||
bool Delete(unsigned int PID);
|
||||
void Print(int m);
|
||||
|
||||
private:
|
||||
HashTable *ht;
|
||||
int memorySize;
|
||||
int pageSize;
|
||||
int *memory;
|
||||
std::vector<int> freeMemory;
|
||||
bool chaining;
|
||||
};
|
||||
#endif
|
||||
103
P2/test.cpp
Normal file
103
P2/test.cpp
Normal file
@@ -0,0 +1,103 @@
|
||||
#include <iostream>
|
||||
|
||||
#include "VirtualMemory.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
string cmd;
|
||||
VirtualMemory *vm = nullptr;
|
||||
bool chaining = true;
|
||||
|
||||
while (cin >> cmd)
|
||||
{
|
||||
if (cmd == "OPEN")
|
||||
{
|
||||
chaining = false;
|
||||
}
|
||||
else if (cmd == "ORDERED")
|
||||
{
|
||||
chaining = true;
|
||||
}
|
||||
if (cmd == "M")
|
||||
{
|
||||
int N;
|
||||
int P;
|
||||
cin >> N;
|
||||
cin >> P;
|
||||
|
||||
vm = new VirtualMemory(N, P, chaining);
|
||||
|
||||
cout << "success" << endl;
|
||||
}
|
||||
else if (cmd == "INSERT")
|
||||
{
|
||||
unsigned int PID;
|
||||
cin >> PID;
|
||||
|
||||
if (vm->Insert(PID))
|
||||
cout << "success" << endl;
|
||||
else
|
||||
cout << "failure" << endl;
|
||||
}
|
||||
else if (cmd == "SEARCH")
|
||||
{
|
||||
unsigned int PID;
|
||||
cin >> PID;
|
||||
|
||||
int ret = vm->Search(PID);
|
||||
if (ret == -1)
|
||||
cout << "not found" << endl;
|
||||
else
|
||||
cout << "found " << PID << " in " << ret << endl;
|
||||
}
|
||||
else if (cmd == "WRITE")
|
||||
{
|
||||
unsigned int PID;
|
||||
int ADDR;
|
||||
int x;
|
||||
|
||||
cin >> PID;
|
||||
cin >> ADDR;
|
||||
cin >> x;
|
||||
|
||||
if (vm->Write(PID, ADDR, x))
|
||||
cout << "success" << endl;
|
||||
else
|
||||
cout << "failure" << endl;
|
||||
}
|
||||
else if (cmd == "READ")
|
||||
{
|
||||
unsigned int PID;
|
||||
int ADDR;
|
||||
|
||||
cin >> PID;
|
||||
cin >> ADDR;
|
||||
|
||||
vm->Read(PID, ADDR);
|
||||
}
|
||||
else if (cmd == "DELETE")
|
||||
{
|
||||
unsigned int PID;
|
||||
cin >> PID;
|
||||
|
||||
if (vm->Delete(PID))
|
||||
cout << "success" << endl;
|
||||
else
|
||||
cout << "failure" << endl;
|
||||
}
|
||||
else if (cmd == "PRINT")
|
||||
{
|
||||
int m;
|
||||
cin >> m;
|
||||
|
||||
vm->Print(m);
|
||||
}
|
||||
else if (cmd == "END")
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
delete vm;
|
||||
}
|
||||
Reference in New Issue
Block a user