Skip to content

Commit c4b79b7

Browse files
authored
Add files via upload
Fixed a bug in retf and reverted return val of pop(), added examples.
1 parent 312773f commit c4b79b7

File tree

2 files changed

+108
-45
lines changed

2 files changed

+108
-45
lines changed

smex2.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#include <iostream>
2+
#include <vector>
3+
#include "stackmachine.hpp"
4+
using namespace std;
5+
6+
7+
int main() {
8+
vector<string> program = {
9+
"push 7",
10+
"show",
11+
"push 1",
12+
"sub",
13+
"jmpnz 1",
14+
"halt"
15+
};
16+
vector<string> program2 = {
17+
"push 7",
18+
"push 3",
19+
"cmpeq",
20+
"jmpnz 7",
21+
"cmpl",
22+
"jmpnz 10",
23+
"halt",
24+
"push 13",
25+
"show",
26+
"retf",
27+
"push 21",
28+
"show",
29+
"retf"
30+
};
31+
StackMachine sm(true);
32+
sm.run(program2);
33+
return 0;
34+
}

stackmachine.hpp

Lines changed: 74 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,3 @@
1-
/*
2-
3-
MIT License
4-
5-
Copyright (c) 2023 Max Goren
6-
7-
Permission is hereby granted, free of charge, to any person obtaining a copy
8-
of this software and associated documentation files (the "Software"), to deal
9-
in the Software without restriction, including without limitation the rights
10-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11-
copies of the Software, and to permit persons to whom the Software is
12-
furnished to do so, subject to the following conditions:
13-
14-
The above copyright notice and this permission notice shall be included in all
15-
copies or substantial portions of the Software.
16-
17-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23-
SOFTWARE.
24-
25-
*/
26-
271
#ifndef STACKMACHINE_HPP
282
#define STACKMACHINE_HPP
293
#include <iostream>
@@ -34,6 +8,7 @@ typedef int OPSTAT;
348
const OPSTAT OP_SUCCESS = 1;
359
const OPSTAT OP_ERROR = -1;
3610
const OPSTAT OP_BRANCH = 2;
11+
const OPSTAT OP_HALT = 3;
3712

3813
class StackMachine {
3914
private:
@@ -48,7 +23,7 @@ class StackMachine {
4823
int rets[255]; //return stack
4924
OPSTAT pushr();
5025
OPSTAT popr();
51-
//alu
26+
//arithmetic logic unit.
5227
OPSTAT ALU(string op, string arg);
5328
int tosr; //top of stack register
5429
OPSTAT cmpl();
@@ -71,13 +46,18 @@ class StackMachine {
7146
OPSTAT jmpz(int addr); //jump to addr if top of stack IS zero
7247
OPSTAT call(); //call to
7348
OPSTAT retf(); //return from
74-
void halt(); //end program.
49+
OPSTAT halt(); //end program.
50+
OPSTAT nop(); //no operation (you'd be surprised)
7551
vector<string> smtokenizer(string expr, char DELIM);
7652
int programCounter;
7753
int memoryAddrReg;
7854
int randomAccessMemory[255];
55+
bool debugMode;
56+
bool stepping;
7957
public:
80-
StackMachine() {
58+
StackMachine(bool dbmode = false, bool smode = false) {
59+
debugMode = dbmode;
60+
stepping = smode;
8161
top = 0;
8262
tosr = 0;
8363
rtop = 0;
@@ -88,15 +68,21 @@ class StackMachine {
8868
};
8969

9070
OPSTAT StackMachine::cmpl() {
91-
return push(data[top-2] < data[top - 1]);
71+
if (data[top-1] < data[top - 2])
72+
return push(1);
73+
return push(0);
9274
}
9375

9476
OPSTAT StackMachine::cmpg() {
95-
return push(data[top-2] > data[top - 1]);
77+
if (data[top-1] > data[top - 2])
78+
return push(1);
79+
return push(0);
9680
}
9781

9882
OPSTAT StackMachine::cmpeq() {
99-
return push(data[top-2] == data[top - 1]);
83+
if (data[top-2] == data[top - 1])
84+
return push(1);
85+
return push(0);
10086
}
10187

10288
/// @brief bitwise AND top two items on data stack
@@ -173,7 +159,7 @@ OPSTAT StackMachine::store() {
173159
/// @return
174160
OPSTAT StackMachine::jmpnz(int addr) {
175161
if (data[top-1] != 0) {
176-
push(programCounter); //put current address on data stack
162+
push(programCounter+1); //put address of next instruction (ret addr) on data stack
177163
pushr(); //move address from data stack to return stack
178164
programCounter = addr; //set to jump point
179165
return OP_BRANCH; //signal next instruction is result of branching.
@@ -185,12 +171,11 @@ OPSTAT StackMachine::jmpnz(int addr) {
185171
/// Opposite behavior to above.
186172
OPSTAT StackMachine::jmpz(int addr) {
187173
if (data[top-1] == 0) {
188-
push(programCounter); //put current address on data stack
174+
push(programCounter+1); //put current address on data stack
189175
pushr(); //move address from data stack to return stack
190176
programCounter = addr; //set to jump point
191177
return OP_BRANCH; //signal next instruction is result of branching.
192178
}
193-
tosr = data[top-1]; //Otherwise proceed as normal
194179
return pop();
195180
}
196181

@@ -211,6 +196,14 @@ OPSTAT StackMachine::retf() {
211196
return OP_BRANCH;
212197
}
213198

199+
OPSTAT StackMachine::halt() {
200+
return OP_HALT;
201+
}
202+
203+
OPSTAT StackMachine::nop() {
204+
return OP_SUCCESS;
205+
}
206+
214207
/// @brief converts string to int and pushes onto data stack
215208
/// @param arg
216209
/// @return
@@ -235,14 +228,28 @@ int StackMachine::pop() {
235228

236229
/// @brief pops data stack and pushes result to return stack
237230
/// @return
238-
OPSTAT StackMachine::pushr() {
231+
OPSTAT StackMachine::pushr() {
232+
if (debugMode) {
233+
cout<<"["<<programCounter<<"] pushr Stack: [";
234+
for (int i = top-1; i >= 0; i--) cout<<data[i]<<" ";
235+
cout<<"] raddr Stack: [";
236+
for (int i = rtop-1; i >= 0; i--) cout<<rets[i]<<" ";
237+
cout<<"]\n";
238+
}
239239
rets[rtop++] = pop();
240240
return OP_SUCCESS;
241241
}
242242

243243
/// @brief pops data of return stack and pushes result to data stack
244244
/// @return
245-
OPSTAT StackMachine::popr() {
245+
OPSTAT StackMachine::popr() {
246+
if (debugMode) {
247+
cout<<"["<<programCounter<<"] popr Stack: [";
248+
for (int i = top-1; i >= 0; i--) cout<<data[i]<<" ";
249+
cout<<"] raddr Stack: [";
250+
for (int i = rtop-1; i >= 0; i--) cout<<rets[i]<<" ";
251+
cout<<"]\n";
252+
}
246253
return push(rets[--rtop]);
247254
}
248255

@@ -299,7 +306,7 @@ OPSTAT StackMachine::mod() {
299306

300307
//show top item on stack.
301308
OPSTAT StackMachine::show() {
302-
cout<<"[TOP]"<<data[top-1]<<"\n";
309+
cout<<"[-]"<<data[top-1]<<"\n";
303310
return OP_SUCCESS;
304311
}
305312

@@ -323,6 +330,15 @@ int StackMachine::ALU(string op, string arg) {
323330
return over();
324331
}
325332

333+
//equality
334+
if (op == "cmpl") {
335+
return cmpl();
336+
} else if (op == "cmpg") {
337+
return cmpg();
338+
} else if (op == "cmpeq") {
339+
return cmpeq();
340+
}
341+
326342
//bitwise ops
327343
if (op == "AND") {
328344
return bwAnd();
@@ -360,6 +376,10 @@ int StackMachine::ALU(string op, string arg) {
360376
return jmpnz(atoi(arg.c_str()));
361377
} else if (op == "jmpz") {
362378
return jmpz(atoi(arg.c_str()));
379+
} else if (op == "halt") {
380+
return halt();
381+
} else if (op == "nop") {
382+
return nop();
363383
}
364384

365385
return OP_ERROR;
@@ -374,23 +394,32 @@ void StackMachine::run(vector<string>& program) {
374394
vector<string> tokens = smtokenizer(instr, ' '); //break the expression
375395
op = tokens[0]; //down into operation and argument
376396
arg = (tokens.size() > 1) ? tokens[1]:"";
377-
//for debugging:
378-
cout<<"["<<programCounter<<"] "<<op<<" "<<arg<<"\n";
397+
if (debugMode) {
398+
cout<<"["<<programCounter<<"] "<<op<<" "<<arg<<", Stack: [";
399+
for (int i = top-1; i >= 0; i--) cout<<data[i]<<" ";
400+
cout<<"]\n";
401+
}
379402
//pass the instruction to the arithmetic and logic unit
380403
OPSTAT stat = ALU(op, arg);
381404
switch (stat) {
382405
case OP_SUCCESS:
383406
programCounter += 1;
384407
break;
408+
case OP_HALT:
409+
programCounter = program.size() + 1;
410+
break;
385411
case OP_BRANCH:
386-
cout<<"["<<stat<<"] [BRANCHING TO: "<<programCounter<<"]\n";
412+
if (debugMode)
413+
cout<<"["<<stat<<"] [BRANCHING TO: "<<programCounter<<"]\n";
387414
break;
388415
case OP_ERROR:
389416
default:
390-
cout<<"["<<stat<<"] ";
391-
cout<<"[LAST INSTRUCTION FAILED.]\n";
417+
if (debugMode)
418+
cout<<"["<<stat<<"] [LAST INSTRUCTION FAILED.]\n";
392419
programCounter += 1;
393-
}
420+
}
421+
char k;
422+
if (stepping) cin>>k;
394423
}
395424
}
396425

@@ -414,4 +443,4 @@ vector<string> StackMachine::smtokenizer(string expr, char DELIM) {
414443
return tokens;
415444
}
416445

417-
#endif
446+
#endif

0 commit comments

Comments
 (0)