Skip to content
Browse files

New opcodes, parser

  • Loading branch information...
1 parent 6047817 commit 3c3c629ad785262ff76c0796e8cc01f5efb78e70 @luk0104 committed Oct 11, 2011
Showing with 191 additions and 104 deletions.
  1. +1 −0 .gitignore
  2. +6 −2 jovita.cpp
  3. +1 −22 machine.h
  4. +62 −12 opcode.cpp
  5. +13 −10 opcode.h
  6. +93 −52 parser.cpp
  7. +14 −5 parser.h
  8. +1 −1 test_opcode.cpp
View
1 .gitignore
@@ -0,0 +1 @@
+*.swp
View
8 jovita.cpp
@@ -28,8 +28,12 @@ main (int argc, char *argv[])
add_history (cmd);
- if (!strncasecmp (cmd, "parse ", 6))
- static_cast<Parser::Parser>(std::string (cmd+6)).nextOPCode ()->execute (cpu);
+ if (!strncasecmp (cmd, "parse ", 6)) {
+ Parser::Parser parser(cmd+6);
+ Machine::OPCode *code;
+ while ( (code = parser.nextOPCode ()) != NULL)
+ code->execute (cpu);
+ }
if (!strcasecmp (cmd, "test_and"))
test_opcode_and (cpu);
View
23 machine.h
@@ -18,14 +18,7 @@
*
* noop
*/
-#define NOOP 0x00
-
-/**
- * Load value
- *
- * lv Rdest, val
- */
-#define LV 0x08
+//#define NOOP 0x00
/**
* Absolute value
@@ -35,13 +28,6 @@
#define ABS 0x01
/**
- * Addition
- *
- * add Rdest, src1, src2
- */
-#define ADD 0x02
-
-/**
* Substract
*
* sub Rdest, src1, src2
@@ -56,13 +42,6 @@
#define NEG 0x04
/**
- * AND
- *
- * and Rdest, src1, src2
- */
-#define AND 0x05
-
-/**
* OR
*
* or Rdest, src1, src2
View
74 opcode.cpp
@@ -28,40 +28,90 @@ namespace Machine {
int Parameter::getValue (void) {
return value;
}
+
+ OPCode::OPCode (OP t) : type(t) {
+
+ }
+
+ OPCode::~OPCode (void) {
- OPCode_AND::OPCode_AND (Parameter p1, Parameter p2, Parameter p3) {
+ }
- params[0] = p1;
- params[1] = p2;
- params[2] = p3;
+#define OP(x) case x: x##_execute (rhs); break
+ void OPCode::execute (CPU& rhs) {
+
+ switch (type)
+ {
+ OP(AND);
+ OP(ADD);
+ OP(LV);
+ }
+#undef OP
}
- OPCode_AND::~OPCode_AND (void) {
+ void OPCode::addParameter (Parameter* rhs) {
+
+ params.push_back (rhs);
}
+
+ void OPCode::ADD_execute (CPU& cpu) {
+
+ int p[2];
- void OPCode_AND::execute (CPU& cpu) {
+ if (params.size () != 3 || !params[0]->isRegister ()) {
+ std::cout << "Not enough parameters!" << std::endl;
+ return ;
+ }
+
+ for (int i = 0; i < 2; ++i)
+ if (params[i+1]->isRegister ())
+ p[i] = cpu.getRegister (params[i+1]->getValue ()).getValue ();
+ else
+ p[i] = params[i+1]->getValue ();
+
+ cpu.getRegister (params[0]->getValue ()).setValue (p[0] + p[1]);
+
+ }
+
+ void OPCode::AND_execute (CPU& cpu) {
int p[2];
- if (!params[0].isRegister ()) {
+ if (params.size () != 3) {
+ std::cout << "Not enough parameters!" << std::endl;
+ return ;
+ }
+
+ if (!params[0]->isRegister ()) {
std::cout << "Error: Param 0 isn't register" << std::endl;
return ;
}
for (int i = 0; i < 2; ++i)
- if (params[i+1].isRegister ()) {
- p[i] = cpu.getRegister (params[i+1].getValue ()).getValue ();
+ if (params[i+1]->isRegister ()) {
+ p[i] = cpu.getRegister (params[i+1]->getValue ()).getValue ();
} else {
- p[i] = params[i+1].getValue ();
+ p[i] = params[i+1]->getValue ();
}
- std::cout << "Debug: AND: [0x" << std::hex << p[0] << ", 0x" << std::hex << p[1] << "]" << std::endl;
+ std::cout << "Debug: AND: [0x" << std::hex << p[0] << ", 0x" << std::hex << p[1] << " reg: 0x" << params[0]->getValue () << "]" << std::endl;
+
+ cpu.getRegister (params[0]->getValue ()).setValue (p[0] & p[1]);
+
+ }
+
+ void OPCode::LV_execute (CPU& cpu) {
+
+ if (params.size () != 2 || !params[0]->isRegister () || params[1]->isRegister ()) {
+ std::cout << "Wrong Parameters!" << std::endl;
+ return ;
+ }
- cpu.getRegister (params[0].getValue ()).setValue (p[0] & p[1]);
+ cpu.getRegister (params[0]->getValue ()).setValue (params[1]->getValue ());
}
View
23 opcode.h
@@ -2,6 +2,7 @@
#define __OPCODE_H
#include <iostream>
+#include <vector>
#include "machine.h"
#include "cpu.h"
@@ -37,22 +38,24 @@ class Parameter {
class OPCode {
public:
- virtual ~OPCode (void) { };
-
- virtual void execute (CPU&) = 0;
-
-};
-
-class OPCode_AND : public OPCode {
+ typedef enum { ADD, AND, LV } OP;
public:
- OPCode_AND (Parameter p1, Parameter p2, Parameter p3);
- ~OPCode_AND (void);
+ OPCode (OP type);
+ ~OPCode (void);
+
+ void addParameter (Parameter* rhs);
void execute (CPU&);
private:
- Parameter params[3];
+ void ADD_execute (CPU& cpu);
+ void AND_execute (CPU& cpu);
+ void LV_execute (CPU& cpu);
+
+private:
+ OP type;
+ std::vector<Parameter *> params;
};
View
145 parser.cpp
@@ -11,23 +11,35 @@ namespace Parser {
}
+#define BEGIN(x,y) \
+ if (!strcasecmp (word.c_str (), #x)) { \
+ std::cout << "Parsing '" << #x << "' opcode" << std::endl; \
+ return parse_opcode (Machine::OPCode::x, y); }
+#define OP(x,y) else BEGIN(x,y)
+#define END() \
+ else { std::cout << "Unknown opcode" << std::endl; break; }
+
Machine::OPCode * Parser::nextOPCode (void) {
char ch;
std::cout << "OPCode: " << str << std::endl;
- while (!isEOS ()) {
+ while (isData ()) {
- std::string str = nextString ();
-
- std::cout << "[" << str << "]" << std::endl;
+ switch (nextToken ())
+ {
+ case Parser::WORD:
+ std::cout << "[" << word << "]" << std::endl;
- if (!strcasecmp (str.c_str (), "and")) {
- std::cout << "Parsing 'AND' opcode" << std::endl;
- return parse_AND ();
- } else {
- std::cout << "Unknown opcode" << std::endl;
- break;
+ BEGIN(AND,3)
+ OP(LV,2)
+ OP(ADD,3)
+ END()
+
+ break;
+
+ case Parser::SEMICOLON:
+ while (isData () && nextToken () != Parser::_NEWLINE) ;
}
}
@@ -36,26 +48,46 @@ namespace Parser {
}
- Machine::OPCode * Parser::parse_AND (void) {
+#undef BEGIN
+#undef OP
+#undef END
- Machine::Parameter *params[3];
+ Machine::OPCode * Parser::parse_opcode (Machine::OPCode op, int params) {
- for (int i = 0; i < 3; ++i) {
-
- params[i] = nextParameter ();
- std::cout << "char: " << *itr << std::endl;
- if (i < 2 && *itr != ',')
+ Machine::Parameter *p[params];
+
+ if (parseParameters (params, p) != params)
+ throw new Error::Parser::SyntaxError ();
+
+ std::cout << "New [?] OPcode" << std::endl;
+ Machine::OPCode * ret = new Machine::OPCode (op);
+ for (int i = 0; i < params; ++i)
+ ret->addParameter (p[i]);
+
+ return ret;
+
+ }
+
+ int Parser::parseParameters (int num, Machine::Parameter* p[]) {
+
+ int i;
+ for (i = 0; i < num; ++i) {
+
+ if (nextToken () != Parser::WORD) {
+ std::cout << "Expected word" << std::endl;
throw new Error::Parser::SyntaxError ();
- ++itr;
+ }
- }
+ p[i] = nextParameter ();
- std::cout << "New AND OPcode" << std::endl;
- Machine::OPCode * ret = new Machine::OPCode_AND (*params[0], *params[1], *params[2]);
- for (int i = 0; i < 3; ++i)
- delete params[i];
+ if (i < num - 1 && nextToken () != Parser::COMMA) {
+ std::cout << "Expected comma" << std::endl;
+ throw new Error::Parser::SyntaxError ();
+ }
- return ret;
+ }
+
+ return i;
}
@@ -64,67 +96,76 @@ namespace Parser {
bool reg = false;
char ch;
unsigned long int val = 0;
+ std::string::iterator i = word.begin ();
- if (tolower (ch = nextChar ()) == 'r') {
+ if (*i == 'r' || *i == 'R') {
reg = true;
- ch = nextChar ();
+ ++i;
}
-
- if (!isdigit (ch)) {
+
+ if (!isdigit (*i)) {
+ std::cout << "Expected digit" << std::endl;
throw new Error::Parser::SyntaxError ();
}
-
- do {
- val = val * 10 + ch - '0';
- ch = nextChar ();
- } while (isdigit (ch));
+
+ while (i < word.end () && isdigit (*i)) {
+ val = val * 10 + *i - '0';
+ ++i;
+ }
std::cout << "New parameter: 0x" << std::hex << val << ", " << reg << std::endl;
- --itr;
return new Machine::Parameter (val, reg);
}
- bool Parser::isEOS (void) {
+ bool Parser::isData (void) {
- return !(itr < str.end ());
+ return (itr < str.end ());
}
void Parser::skipWs (void) {
- while (isspace (*itr))
+ while (isspace (*itr) && isData ())
++itr;
}
- char Parser::nextChar (void) {
-
- skipWs ();
-
- if (itr < str.end ())
- return *itr++;
- else
- return Parser::EOS;
-
- }
-
- std::string Parser::nextString (void) {
+ char Parser::nextToken (void) {
char ch;
std::string ret;
skipWs ();
- while (!isspace (*itr) && itr < str.end ()) {
+ switch (*itr)
+ {
+ case ';':
+ ++itr;
+ return Parser::SEMICOLON;
+
+ case '\n':
+ ++itr;
+ return Parser::_NEWLINE;
+
+ case ',':
+ ++itr;
+ return Parser::COMMA;
+ }
+
+ if (!isalnum (*itr))
+ throw new Error::Parser::SyntaxError ();
+
+ word.clear ();
+ while (isalnum (*itr) && isData ()) {
- ret.push_back (*itr);
+ word.push_back (*itr);
++itr;
}
- return ret;
+ return Parser::WORD;
}
View
19 parser.h
@@ -18,27 +18,36 @@ namespace Error {
namespace Parser {
class Parser {
+
+public:
+ static const char _NEWLINE = 0x1;
+ static const char SEMICOLON = 0x2;
+ static const char WORD = 0x3;
+ static const char COMMA = 0x4;
+protected:
+ static const char EOS = 0x0;
+
public:
Parser (std::string str);
Machine::OPCode * nextOPCode (void);
private:
+ int parseParameters (int num, Machine::Parameter* p[]);
Machine::Parameter * nextParameter (void);
- Machine::OPCode * parse_AND (void);
+ Machine::OPCode * parse_opcode (Machine::OPCode op, int params);
protected:
- static const char EOS = 0x0;
- char nextChar (void);
- std::string nextString (void);
- bool isEOS (void);
+ bool isData (void);
+ char nextToken (void);
private:
void skipWs (void);
private:
std::string str;
std::string::iterator itr;
+ std::string word;
};
View
2 test_opcode.cpp
@@ -4,7 +4,7 @@
void test_opcode_and (Machine::CPU& c)
{
Machine::Parameter p1(0, true), p2(2), p3(6);
- Machine::OPCode *op = new Machine::OPCode_AND (p1, p2, p3);
+ Machine::OPCode *op = new Machine::OPCode (Machine::OPCode::AND);
op->execute (c);
}

0 comments on commit 3c3c629

Please sign in to comment.
Something went wrong with that request. Please try again.