diff --git a/DMS/Character.h b/DMS/Character.h new file mode 100644 index 0000000..0e2256d --- /dev/null +++ b/DMS/Character.h @@ -0,0 +1,13 @@ +#pragma once +#include +#include +#include "value.h" +namespace dms { + struct character { + std::string fname = ""; + std::string lname = ""; + bool seen = false; + std::unordered_map paths; + std::unordered_map values; + }; +} \ No newline at end of file diff --git a/DMS/DMS.cpp b/DMS/DMS.cpp index ee99ff3..d026c87 100644 --- a/DMS/DMS.cpp +++ b/DMS/DMS.cpp @@ -27,6 +27,6 @@ int main() std::cout << e.what() << '\n'; return -1; } - state->dump(); + //state->dump(); state->run(); } \ No newline at end of file diff --git a/DMS/DMS.vcxproj b/DMS/DMS.vcxproj index 40ae047..e9f7214 100644 --- a/DMS/DMS.vcxproj +++ b/DMS/DMS.vcxproj @@ -160,6 +160,7 @@ + diff --git a/DMS/DMS.vcxproj.filters b/DMS/DMS.vcxproj.filters index d4ba9eb..71b05d2 100644 --- a/DMS/DMS.vcxproj.filters +++ b/DMS/DMS.vcxproj.filters @@ -113,5 +113,8 @@ Header Files + + Header Files\DMS + \ No newline at end of file diff --git a/DMS/LineParserMatchProcess.cpp b/DMS/LineParserMatchProcess.cpp index 7336930..71e64f3 100644 --- a/DMS/LineParserMatchProcess.cpp +++ b/DMS/LineParserMatchProcess.cpp @@ -130,7 +130,6 @@ namespace dms { } } length->set(buildNumber(count)); // the second argument is the length of the list! This should be modified if lists are changed at runtime! - return true; } return false; @@ -143,8 +142,20 @@ namespace dms { c->opcode = codes::DISP; c->args.push(buildValue(msg)); current_chunk->addCmd(c); // Add the cmd to the current chunk + current_chunk->addCmd(new cmd{ codes::HALT }); return true; } + else if (isBlock(bt_character) && stream->match(tokens::newline, tokens::name, tokens::colon, tokens::string, tokens::newline)) { + stream->next(); // Standard consumption + std::string name = stream->next().name; + stream->next(); // That colon + std::string msg = stream->next().name; + cmd* c = new cmd; + c->opcode = codes::STAT; + c->args.push(buildVariable(name)); + c->args.push(buildValue(msg)); + current_chunk->addCmd(c); // Add the cmd to the current chunk + } else if ((isBlock(bt_block) || isBlock(bt_method)) && stream->match(tokens::newline, tokens::name, tokens::colon, tokens::string, tokens::newline)) { // We might have to handle scope here // Here we match 'Ryan: "This guy said this!"' Note the colon is needed! @@ -160,7 +171,7 @@ namespace dms { c->opcode = codes::DISP; c->args.push(buildValue(msg)); current_chunk->addCmd(c); // Add the cmd to the current chunk - // We might have to consume a newline... Depends on what's next + current_chunk->addCmd(new cmd{ codes::HALT }); return true; } else if ((isBlock(bt_block) || isBlock(bt_method)) && stream->match(tokens::name,tokens::colon,tokens::cbracketo)) { @@ -229,6 +240,7 @@ namespace dms { } } stream->next(); + current_chunk->addCmd(new cmd{ codes::HALT }); return true; } // emotion: "path" diff --git a/DMS/codes.cpp b/DMS/codes.cpp index 8895a8d..cbe7b44 100644 --- a/DMS/codes.cpp +++ b/DMS/codes.cpp @@ -44,5 +44,6 @@ const std::string dms::codes::list[] = { "POW", "MOD", "LIST", - "LINE" + "LINE", + "HALT" }; \ No newline at end of file diff --git a/DMS/codes.h b/DMS/codes.h index 7353057..16c7b32 100644 --- a/DMS/codes.h +++ b/DMS/codes.h @@ -46,7 +46,8 @@ namespace dms::codes { POW, MOD, LIST, - LINE + LINE, + HALT, }; extern const std::string list[]; static bool isControl(const op code) { diff --git a/DMS/dms_state.cpp b/DMS/dms_state.cpp index 5d9e6d4..9298e69 100644 --- a/DMS/dms_state.cpp +++ b/DMS/dms_state.cpp @@ -18,6 +18,12 @@ namespace dms { push_chunk("$END", c); setChoiceHandler(new choiceHandler); // Use the default implementation } + bool dms_state::characterExists(std::string bk_name) { + return (chunks.count(bk_name) && chunks[bk_name]->type == blocktype::bt_character); + } + bool dms_state::blockExists(std::string bk_name) { + return (chunks.count(bk_name)); + } void dms_state::enable(std::string flag) { enables[flag] = true; } diff --git a/DMS/dms_state.h b/DMS/dms_state.h index d839805..1c57c5e 100644 --- a/DMS/dms_state.h +++ b/DMS/dms_state.h @@ -11,12 +11,15 @@ #include #include #include +#include "Character.h" namespace dms { struct dms_state { void* choi = nullptr; std::unordered_map memory; + std::vector garbage; std::map chunks; + std::map characters; std::string entry = "$undefined"; std::map enables; const double Iversion = 1.0; @@ -36,6 +39,11 @@ namespace dms { void disable(std::string flag); bool isEnabled(std::string flag); void setChoiceHandler(void* choi); + + // Gets or creates a character + character* getCharacter(std::string c); + bool characterExists(std::string bk_name); + bool blockExists(std::string bk_name); bool run(); private: // From what I gathered diff --git a/DMS/dms_state_interpret.cpp b/DMS/dms_state_interpret.cpp index 493e985..fbd143a 100644 --- a/DMS/dms_state_interpret.cpp +++ b/DMS/dms_state_interpret.cpp @@ -1,6 +1,7 @@ #include "dms_state.h" #include "utils.h" #include "Handlers.h" +#include using namespace dms::utils; using namespace dms::exceptions; using namespace dms::codes; @@ -9,6 +10,63 @@ namespace dms { void dms_state::setChoiceHandler(void* choi) { this->choi = choi; } + character* dms_state::getCharacter(std::string cha) { + if (characters.count(cha)) { + return characters[cha]; + } + else { + if (blockExists(cha)) { + character* cc = new character; + cc->fname = cha; + codes::op code; + cmd* c = nullptr; + bool halt = false; + size_t pos = 0; + size_t max = 0; + std::vector cmds; + init(chunks[cha], pos, max, cmds); + while (true) { + c = cmds[pos++]; + code = c->opcode; + + switch (code) + { + // Handle flags here + case STAT: + if(c->args.args[0]->type == datatypes::variable && c->args.args[1]->type == datatypes::string) + cc->paths.insert_or_assign(c->args.args[0]->s->getValue(), c->args.args[1]->s->getValue()); + else + push_error(errors::error{ errors::invalid_type ,utils::concat("Expected variable: string! Got: ",datatype[c->args.args[0]->type],": ",datatype[c->args.args[1]->type]) }); + break; + case ASGN: + if (c->args.args[0]->s->getValue() == "fname") { + cc->fname = c->args.args[1]->s->getValue(); + } + else if (c->args.args[0]->s->getValue() == "lname") { + cc->lname = c->args.args[1]->s->getValue(); + } + else { + cc->values.insert_or_assign(c->args.args[0]->s->getValue(), c->args.args[1]); + } + break; + default: + break; + } + + if (pos == max) { + // How did we get here? The end of a block? + break; + } + } + return cc; + } + else { + push_error(errors::error{ errors::non_existing_block ,utils::concat("Attempted to index a non existing character!") }); + return nullptr; + } + } + return nullptr; + } void dms_state::init(chunk* chunk, size_t& pos, size_t& max, std::vector& cmds) { pos = 0; max = chunk->cmds.size(); @@ -16,7 +74,7 @@ namespace dms { } // Instance, multiple instances can allow different code to work side by side bool dms_state::run(std::string instance) { - codes::op code; + //codes::op code; //Spawn thread and run return true; } @@ -36,10 +94,12 @@ namespace dms { //TODO: parse the cmds and do stuff // If this is running in a thread then stop will force this loop to stop size_t ln = 0; + character* speaker = nullptr; + std::string temp; while (!stop || !halt) { c = cmds[pos++]; code = c->opcode; - utils::print("> ",*c); + //utils::print("> ",*c); //utils::wait(); switch (code) { @@ -64,20 +124,52 @@ namespace dms { // How we add modules into the code. This is the code that actually loads that data! break; // Flags handled + case HALT: + wait(); + break; + case SSPK: + if (characterExists(c->args.args[0]->s->getValue())){ + speaker = getCharacter(c->args.args[0]->s->getValue()); + if (speaker->lname != "") { + utils::write(speaker->fname, " ", speaker->lname, ": "); + } + else { + utils::write(speaker->fname, ": "); + } + } + break; + case APND: + utils::write(c->args.args[0]->s->getValue()); + break; + case DISP: + utils::write(c->args.args[0]->s->getValue()); + break; + case ASGN: + if (memory.count(c->args.args[0]->s->getValue()) == 0) { + memory.insert_or_assign(c->args.args[0]->s->getValue(), c->args.args[1]); + } + else { + value* temp = memory[c->args.args[0]->s->getValue()]; + if (temp->type != datatypes::variable) { + temp->set(); // Set the removed value to nil + garbage.push_back(memory[c->args.args[0]->s->getValue()]); + } + else + print("> so we have a variable"); + memory[c->args.args[0]->s->getValue()] = c->args.args[1]; + } + break; case LINE: ln = c->args.args[0]->n->getValue(); break; case NOOP: break; case CHOI: - if (utils::valueassertall(c->args, memory, datatypes::string)) { - //Because we are using void* we must cast our pointers - //The implementation of this however should mean that you only ever have to deal with one "ChoiceHandler. One annoying void*" - pos += 2*(*(choiceHandler*)choi).manageChoice(this, c->args); - } + //Because we are using void* we must cast our pointers + //The implementation of this however should mean that you only ever have to deal with one "ChoiceHandler. One annoying void*" + pos += 2* (*(choiceHandler*)choi).manageChoice(this, c->args); break; case JUMP: - value* v1; // Value assert resolves the data so a variable must eventually equal a string if (utils::valueassert(c->args, memory, datatypes::string)) { std::string block = c->args.args[0]->resolve(memory)->s->getValue(); @@ -103,7 +195,6 @@ namespace dms { break; } } - END: return true; } diff --git a/DMS/dump.bin b/DMS/dump.bin index de4b2b7..165b563 100644 Binary files a/DMS/dump.bin and b/DMS/dump.bin differ diff --git a/DMS/dump.txt b/DMS/dump.txt index 936e482..32da11e 100644 --- a/DMS/dump.txt +++ b/DMS/dump.txt @@ -149,43 +149,48 @@ Line <37> name char Line <37> bracketc ] Line <37> newline Line <37> newline -Line <38> name age +Line <38> name fname Line <38> equal = -Line <38> number .24 +Line <38> string Bob Line <38> newline Line <38> newline -Line <39> name money -Line <39> equal = -Line <39> number 100 Line <39> newline -Line <39> newline -Line <40> name excited -Line <40> colon : -Line <40> string path/to/file -Line <40> name function +Line <40> name age +Line <40> equal = +Line <40> number .24 Line <40> newline Line <40> newline +Line <41> name money +Line <41> equal = +Line <41> number 100 Line <41> newline Line <41> newline -Line <42> bracketo [ -Line <42> name newblock +Line <42> name excited Line <42> colon : -Line <42> name function -Line <42> parao ( -Line <42> parac ) -Line <42> bracketc ] +Line <42> string path/to/file Line <42> newline Line <42> newline -Line <43> string Test #2 Line <43> newline Line <43> newline -Line <44> string Does it parse this part properly? +Line <44> bracketo [ +Line <44> name newblock +Line <44> colon : +Line <44> name function +Line <44> parao ( +Line <44> parac ) +Line <44> bracketc ] Line <44> newline Line <44> newline -Line <45> string huh +Line <45> string Test #2 Line <45> newline Line <45> newline -Line <45> eof +Line <46> string Does it parse this part properly? +Line <46> newline +Line <46> newline +Line <47> string huh +Line <47> newline +Line <47> newline +Line <47> eof Line <1> newline Line <1> newline Line <1> bracketo [ @@ -225,112 +230,117 @@ Line <8> equal = Line <8> number 1000 Line <8> newline Line <8> newline +Line <9> name lname +Line <9> equal = +Line <9> string Ward +Line <9> newline Line <9> newline -Line <10> name calm -Line <10> colon : -Line <10> string ./path/to/file Line <10> newline -Line <10> newline -Line <11> name excited +Line <11> name calm Line <11> colon : Line <11> string ./path/to/file Line <11> newline Line <11> newline +Line <12> name excited +Line <12> colon : +Line <12> string ./path/to/file Line <12> newline Line <12> newline -Line <13> bracketo [ -Line <13> name step -Line <13> colon : -Line <13> name function -Line <13> parao ( -Line <13> name a -Line <13> seperator , -Line <13> name b -Line <13> seperator , -Line <13> name c -Line <13> parac ) -Line <13> bracketc ] Line <13> newline Line <13> newline -Line <14> string Testing... +Line <14> bracketo [ +Line <14> name step +Line <14> colon : +Line <14> name function +Line <14> parao ( +Line <14> name a +Line <14> seperator , +Line <14> name b +Line <14> seperator , +Line <14> name c +Line <14> parac ) +Line <14> bracketc ] Line <14> newline -Line <15> name d -Line <15> equal = -Line <15> parao ( -Line <15> number 100 -Line <15> plus + -Line <15> name b -Line <15> parac ) -Line <15> divide / -Line <15> name c +Line <14> newline +Line <15> string Testing... Line <15> newline -Line <15> newline -Line <16> name e +Line <16> name d Line <16> equal = -Line <16> string somestring +Line <16> parao ( +Line <16> number 100 +Line <16> plus + +Line <16> name b +Line <16> parac ) +Line <16> divide / +Line <16> name c Line <16> newline Line <16> newline Line <17> name e Line <17> equal = -Line <17> nil nil +Line <17> string somestring Line <17> newline Line <17> newline -Line <18> name g +Line <18> name e Line <18> equal = -Line <18> false false +Line <18> nil nil Line <18> newline Line <18> newline -Line <19> ret -Line <19> name d +Line <19> name g +Line <19> equal = +Line <19> false false Line <19> newline Line <19> newline +Line <20> ret +Line <20> name d Line <20> newline Line <20> newline -Line <21> bracketo [ -Line <21> name inventory -Line <21> colon : -Line <21> name env -Line <21> bracketc ] Line <21> newline Line <21> newline -Line <22> name slot1 -Line <22> equal = -Line <22> string +Line <22> bracketo [ +Line <22> name inventory +Line <22> colon : +Line <22> name env +Line <22> bracketc ] Line <22> newline Line <22> newline -Line <23> name slot2 +Line <23> name slot1 Line <23> equal = Line <23> string Line <23> newline Line <23> newline -Line <24> name slot3 +Line <24> name slot2 Line <24> equal = Line <24> string Line <24> newline Line <24> newline -Line <25> name slot4 +Line <25> name slot3 Line <25> equal = Line <25> string Line <25> newline Line <25> newline -Line <26> name slot5 +Line <26> name slot4 Line <26> equal = Line <26> string Line <26> newline Line <26> newline -Line <27> name slot6 +Line <27> name slot5 Line <27> equal = Line <27> string Line <27> newline Line <27> newline -Line <28> name slot7 +Line <28> name slot6 Line <28> equal = Line <28> string Line <28> newline Line <28> newline -Line <29> name slot8 +Line <29> name slot7 Line <29> equal = Line <29> string Line <29> newline Line <29> newline -Line <29> eof +Line <30> name slot8 +Line <30> equal = +Line <30> string +Line <30> newline +Line <30> newline +Line <30> eof diff --git a/DMS/loadtest.dms b/DMS/loadtest.dms index 14296e9..260081e 100644 --- a/DMS/loadtest.dms +++ b/DMS/loadtest.dms @@ -6,6 +6,7 @@ [Ryan:char] age = 21 money = 1000 + lname = "Ward" // Inside a character block this syntax defines animation/image file for an emotion calm: "./path/to/file" excited: "./path/to/file" diff --git a/DMS/test.dms b/DMS/test.dms index efa4ecf..1150a56 100644 --- a/DMS/test.dms +++ b/DMS/test.dms @@ -35,9 +35,11 @@ using extendedDefine "hehe" [Bob:char] + fname = "Bob" + //lname = "" age = .24 money = 100 - excited: "path/to/file" | function + excited: "path/to/file" [newblock:function()] "Test #2" diff --git a/DMS/utils.h b/DMS/utils.h index c0d249a..c6bff24 100644 --- a/DMS/utils.h +++ b/DMS/utils.h @@ -10,7 +10,11 @@ namespace dms::utils { template void print(Args... args) { - (std::cout << ... << args) << "\n"; + (std::cout << ... << args) << std::endl; + } + template + void write(Args... args) { + (std::cout << ... << args); } template std::string concat(Args... args) {