summaryrefslogtreecommitdiffstats
path: root/main.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'main.hpp')
-rw-r--r--main.hpp152
1 files changed, 84 insertions, 68 deletions
diff --git a/main.hpp b/main.hpp
index 58a7337..1794b7a 100644
--- a/main.hpp
+++ b/main.hpp
@@ -1,8 +1,52 @@
#include <vector>
#include <queue>
#include <string>
+#include <sstream>
+#include <iostream>
+#include <fstream>
+#include <regex>
namespace ov {
using namespace std;
+ struct NotImplemented : public exception {
+ const char * what () const throw () {
+ return "Not implemented.";
+ }
+ } NotImplemented;
+ struct NotAvailable : public exception {
+ const char * what () const throw () {
+ return "I/O is currently not available. You can try again.";
+ }
+ } NotAvailable;
+ struct BufferingRequired : public exception {
+ const char * what () const throw () {
+ return "I/O buffering must be enabled for this function, but it's not.";
+ }
+ } BufferingRequired;
+ struct NotAligned : public exception {
+ const char * what () const throw () {
+ return "Byte count can't be deserialized without remainder.";
+ }
+ } NotAligned;
+ struct AssemblerFatal : public exception {
+ const char * what () const throw () {
+ return "Fatal error in assembler.";
+ }
+ } AssemblerFatal;
+ struct SyntaxError : AssemblerFatal {
+ const char * what () const throw () {
+ return "Fatal syntax error in assembler.";
+ }
+ } SyntaxError;
+ struct EndlessArgument : public SyntaxError {
+ const char * what () const throw () {
+ return "Some builtin preprocessor command does not have enough arguments.";
+ }
+ } EndlessArgument;
+ struct EndlessBlock : public SyntaxError {
+ const char * what () const throw () {
+ return "Some builtin preprocessor block %* is not terminated with %end*.";
+ }
+ } EndlessBlock;
enum opts { // opts are pas-1 bits aftr last ram ptr (2**ras)-1 and can be w/r from prg
DEFAULT,
BUFOUT, // output from program in VM is always possible and no blocks
@@ -28,34 +72,10 @@ namespace ov {
bool i = 0; // instruction
bool p = 0; // enobitni padding, lahko za metainštrukcije, pri COPY je že
}; // privzeto inicializiran na NOOP inštrukcijo
- template<typename value_type, typename index_type, class Memory> class Mmu {
- private:
- class Cell {
- private:
- friend class Mmu;
- Mmu & mmu;
- index_type index;
- Cell (Mmu & mmu, index_type index)
- : mmu(mmu), index(index) {}
- public:
- operator value_type (void) {
- return mmu.memory.peek(index);
- }
- value_type operator= (value_type value) {
- mmu.memory.poke(index, value);
- return value;
- }
- };
- public:
- Memory & memory;
- Mmu (Memory & memory) : memory(memory) {}
- Cell operator[] (index_type index) {
- return Cell(*this, index);
- }
- value_type & operator() (index_type index) {
- return memory.peek(index);
- }
- };
+ struct def {
+ vector<string> args;
+ string body("");
+ }
class Ov;
template<typename value_type, typename index_type> class Ram {
private:
@@ -79,67 +99,60 @@ namespace ov {
template<typename value_type, typename index_type> class Program {
private:
public:
+ index_type hiaddr;
vector<value_type> storage;
+ const struct instr empty;
Ov * ov;
value_type & peek (index_type addr) {
+ if (addr > hiaddr) {
+ hiaddr = addr;
+ storage.resize(hiaddr+1, empty);
+ }
return storage[addr];
}
void poke (index_type addr, value_type val) {
+ if (addr > hiaddr) {
+ hiaddr = addr;
+ storage.resize(hiaddr+1, empty /* avoid leaking memory */);
+ }
storage[addr] = val;
}
- Program (Ov *);
+ index_type length () {
+ return hiaddr+1;
+ }
+ Program (Ov * ov) : ov(ov) {
+ hiaddr = 0;
+ storage.push_back(empty); // we don't want to leak memory contents
+ }
};
class Ov {
private:
public:
queue<bool> inbuf;
queue<bool> outbuf;
-#define IS2RAS(is) ((is*8-2)/2)
- class ras { // IS
- private: // IT
- public: // REALLY
- unsigned short int & is; // THIS
- operator unsigned short int (void) { // HARD
- return IS2RAS(is); // TO
- } // DEFINE
- ras (class Ov * ov) : is(ov->is) {} // A
- }; // GETTER
- ras ras{this}; // FUNCTION
- class rs {
- private:
- public:
- unsigned short int & is;
- operator unsigned int (void) {
- return 1 << IS2RAS(is);
- }
- rs (class Ov * ov) : is(ov->is) {}
- };
- rs rs{this};
- class ps {
- private:
- public:
- unsigned short int & pas;
- operator unsigned int (void) {
- return 1 << pas;
- }
- ps (class Ov * ov) : pas(ov->pas) {}
- };
- ps ps{this};
+ unsigned int ras (void) {
+ return (is*8-2)/2;
+ }
+ unsigned int rs (void) {
+ return 1 << ras();
+ }
+ unsigned int ps (void) {
+ return 1 << pas;
+ }
unsigned short int is;
unsigned short int pas;
bool io[IOLEN];
bool opts[OPTSLEN];
unsigned int pc = 0; /* where the program starts --- at zero or where? */
- Ram<bool, unsigned int> rstor{this};
- Mmu<bool, unsigned int, class Ram<bool, unsigned int>> ram{rstor};
- Program<struct instr, unsigned int> pstor{this};
- Mmu<struct instr, unsigned, class Program<struct instr, unsigned>> pm{pstor};
- Ov (unsigned short int is = 2, unsigned short int pas = 16)
- : is(is), pas(pas) { // add bound checks
+ Ram<bool, unsigned int> r{this};
+ Program<struct instr, unsigned int> p{this};
+ Ov (unsigned short int is = 2, unsigned short int pas = 16) :
+ is(is), pas(pas) { // TODO: check
for (int i = 0; i < OPTSLEN; i++)
opts[i] = 0;
- for (int i = 0; i < IOLEN; i++)
+ for (int i = 0; i < IOLEN; i++) {
io[i] = 0;
+ }
}
void step (void);
bool out (void);
@@ -148,7 +161,10 @@ namespace ov {
void inc (char);
struct instr deserialize (const char [sizeof(struct instr)]);
void deserialize (istream &, unsigned int);
- string serialize (struct instr * i, unsigned int);
+ void deserialize (string, unsigned int);
+ string serialize (struct instr *, unsigned int);
+ string serialize (struct instr);
void pd (ostream &);
};
+ vector<struct instr> assembler (string);
}