Below is the code I copy and pasted into my linux subsystem to run simpletron
// Exercise 8.16 Solution: ex08_16.cpp - Simpletron Simulator.
// simpletron.cpp
// g++ simpletron.cpp -o simpletron; ./simpletron
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
const size_t SIZE{100};
const int MAX_WORD{9999};
const int MIN_WORD{-9999};
const long SENTINEL{-99999};
enum class Command {READ = 10, WRITE, LOAD = 20, STORE, ADD = 30, SUBTRACT,
DIVIDE, MULTIPLY, BRANCH = 40, BRANCHNEG, BRANCHZERO, HALT};
// prototypes
void load(int* const);
void execute(int* const, int* const, size_t* const, int* const,
size_t* const, size_t* const);
void dump(const int* const, int, size_t, int, size_t, size_t);
bool validWord(int);
void output(string, int, int, bool);
int main() {
int memory[SIZE]{0};
int accumulator{0};
size_t instructionCounter{0};
size_t operationCode{0};
size_t operand{0};
int instructionRegister{0};
load(memory);
execute(memory, &accumulator, &instructionCounter,
&instructionRegister, &operationCode, &operand);
dump(memory, accumulator, instructionCounter, instructionRegister,
operationCode, operand);
}
// load instructions
void load(int* const loadMemory) {
long instruction;
size_t i{0}; // indexing variable
cout << "*** Welcome to Simpletron ***n"
<< "*** Please enter your program one instruction ***n"
<< "*** (or data word) at a time. I will type the ***n"
<< "*** location number and a question mark (?). ***n"
<< "*** You then type the word for that location. ***n"
<< "*** Type the sentinel -99999 to stop entering ***n"
<< "*** your program. ***n"
<< "00 ? ";
cin >> instruction;
while (instruction != SENTINEL) {
if (!validWord(instruction)) {
cout << "Number out of range. Please enter again.n";
}
else {
loadMemory[i++] = instruction;
}
// function setfill sets the padding character for unused
// field widths.
cout << setw(2) << setfill('0') << i << " ? ";
cin >> instruction;
}
}
// carry out the commands
void execute(int* const memory, int* const acPtr, size_t* const icPtr,
int* const irPtr, size_t* const opCodePtr, size_t* const opPtr) {
bool fatal{false};
int temp;
string messages[] = { "Accumulator overflow ***",
"Attempt to divide by zero ***",
"Invalid opcode detected ***" };
string termString =
"n*** Simpletron execution abnormally terminated ***";
string fatalString = "*** FATAL ERROR: ";
cout << "n************START SIMPLETRON EXECUTION************nn";
do
{
*irPtr = memory[*icPtr];
*opCodePtr = *irPtr / 100;
*opPtr = *irPtr % 100;
// switch to determine appropriate action
switch (static_cast<Command>(*opCodePtr)) {
case Command::READ:
cout << "Enter an integer: ";
cin >> temp;
while (!validWord(temp)) {
cout << "Number out of range. Please enter again: ";
cin >> temp;
}
memory[*opPtr] = temp;
++(*icPtr);
break;
case Command::WRITE:
cout << "Contents of " << setw(2) << setfill('0')
<< *opPtr << ": " << memory[*opPtr] << 'n';
++(*icPtr);
break;
case Command::LOAD:
*acPtr = memory[*opPtr];
++(*icPtr);
break;
case Command::STORE:
memory[*opPtr] = *acPtr;
++(*icPtr);
break;
case Command::ADD:
temp = *acPtr + memory[*opPtr];
if (!validWord(temp)) {
cout << fatalString << messages[0] << termString << 'n';
fatal = true;
}
else {
*acPtr = temp;
++(*icPtr);
}
break;
case Command::SUBTRACT:
temp = *acPtr - memory[*opPtr];
if (!validWord(temp))
{
cout << fatalString << messages[0] << termString << 'n';
fatal = true;
}
else
{
*acPtr = temp;
++(*icPtr);
}
break;
case Command::DIVIDE:
if (memory[*opPtr] == 0) {
cout << fatalString << messages[1] << termString << 'n';
fatal = true;
}
else {
*acPtr /= memory[*opPtr];
++(*icPtr);
}
break;
case Command::MULTIPLY:
temp = *acPtr * memory[*opPtr];
if (!validWord(temp)) {
cout << fatalString << messages[0] << termString << 'n';
fatal = true;
}
else {
*acPtr = temp;
++(*icPtr);
}
break;
case Command::BRANCH:
*icPtr = *opPtr;
break;
case Command::BRANCHNEG:
*acPtr < 0 ? *icPtr = *opPtr : ++(*icPtr);
break;
case Command::BRANCHZERO:
*acPtr == 0 ? *icPtr = *opPtr : ++(*icPtr);
break;
case Command::HALT:
cout << "*** Simpletron execution terminated ***n";
break;
default:
cout << fatalString << messages[2] << termString << 'n';
fatal = true;
break;
}
} while (static_cast<Command>(*opCodePtr) != Command::HALT && !fatal);
cout << "n*************END SIMPLETRON EXECUTION*************n";
}
// print out name and content of each register and memory
void dump(const int* const memory, int accumulator,
size_t instructionCounter, int instructionRegister, size_t operationCode,
size_t operand) {
cout << "nREGISTERS:n";
output("accumulator", 5, accumulator, true);
output("instructionCounter", 2, instructionCounter, false);
output("instructionRegister", 5, instructionRegister, true);
output("operationCode", 2, operationCode, false);
output("operand", 2, operand, false);
cout << "nnMEMORY:n";
cout << setfill(' ') << setw(3) << ' ';
// print header
for (int i{0}; i <= 9; ++i) {
cout << setw(5) << i << ' ';
}
for (int i{0}; i < SIZE; ++i) {
if (i % 10 == 0) {
cout << 'n' << setw(2) << i << ' ';
}
cout << internal << setw(5) << setfill('0')
<< memory[i] << ' ' << internal;
}
cout << endl;
}
// validate
bool validWord(int word) {
return word >= MIN_WORD && word <= MAX_WORD;
}
// display result
void output(string label, int width, int value, bool sign) {
// format of "accumulator", etc.
cout << setfill(' ') << left << setw(20) << label << ' ';
// is a +/- sign needed?
if (sign) {
cout << showpos << internal;
}
else {
cout << noshowpos;
}
// setup for displaying accumulator value, etc.
cout << left << setfill('0');
// determine the field widths and display value
if (width == 5) {
cout << setw(width) << value << 'n';
}
else { // width is 2
cout << setfill(' ') << setw(3) << ' ' << setw(width)
<< setfill('0') << value << 'n';
}
// disable sign if it was set
if (sign) {
cout << showpos << internal;
}
else {
cout << noshowpos;
}
}
I needed to code a program that adds 3 variables together,
here is an example of my final run:
00 ? +1007 //reads var. a
01 ? +1008 //reads var. b
02 ? +1009 //reads var. c
03 ? +2007 //loads var b.
04 ? +3008 //adds b to accumulator
05 ? +3009 //adds c to accumulator
06 ? +2110 //stores new word in parameter
07 ? +1110 //writes the parameter
08 ? +4300 //ends code
09 ? +0000 //var. a
10 ? +0000 //var. b
11 ? +0000 //var c.
12 ? +0000 //result
13 ? -99999 //stops entry
This has looked completely reasonable to me and when I run it, I get a fatal error,
************END SIMPLETRON EXECUTION*************
REGISTERS:
accumulator +6000
instructionCounter 70
instructionRegister +1000
operationCode 00
operand 10
3