diff options
Diffstat (limited to 'main.hpp')
-rw-r--r-- | main.hpp | 152 |
1 files changed, 84 insertions, 68 deletions
@@ -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); } |