Implemented Character objects, todo add handler for displaying text

This commit is contained in:
Ryan Ward 2020-09-24 22:56:11 -04:00
parent edc67a0f4f
commit 9dc8a90ecd
15 changed files with 240 additions and 87 deletions

13
DMS/Character.h Normal file
View File

@ -0,0 +1,13 @@
#pragma once
#include <string>
#include <unordered_map>
#include "value.h"
namespace dms {
struct character {
std::string fname = "";
std::string lname = "";
bool seen = false;
std::unordered_map<std::string, std::string> paths;
std::unordered_map<std::string, value*> values;
};
}

View File

@ -27,6 +27,6 @@ int main()
std::cout << e.what() << '\n'; std::cout << e.what() << '\n';
return -1; return -1;
} }
state->dump(); //state->dump();
state->run(); state->run();
} }

View File

@ -160,6 +160,7 @@
<ClCompile Include="value.cpp" /> <ClCompile Include="value.cpp" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="Character.h" />
<ClInclude Include="Handlers.h" /> <ClInclude Include="Handlers.h" />
<ClInclude Include="chunk.h" /> <ClInclude Include="chunk.h" />
<ClInclude Include="cmd.h" /> <ClInclude Include="cmd.h" />

View File

@ -113,5 +113,8 @@
<ClInclude Include="Handlers.h"> <ClInclude Include="Handlers.h">
<Filter>Header Files</Filter> <Filter>Header Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Character.h">
<Filter>Header Files\DMS</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -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! 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 true;
} }
return false; return false;
@ -143,8 +142,20 @@ namespace dms {
c->opcode = codes::DISP; c->opcode = codes::DISP;
c->args.push(buildValue(msg)); c->args.push(buildValue(msg));
current_chunk->addCmd(c); // Add the cmd to the current chunk current_chunk->addCmd(c); // Add the cmd to the current chunk
current_chunk->addCmd(new cmd{ codes::HALT });
return true; 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)) { 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 // We might have to handle scope here
// Here we match 'Ryan: "This guy said this!"' Note the colon is needed! // Here we match 'Ryan: "This guy said this!"' Note the colon is needed!
@ -160,7 +171,7 @@ namespace dms {
c->opcode = codes::DISP; c->opcode = codes::DISP;
c->args.push(buildValue(msg)); c->args.push(buildValue(msg));
current_chunk->addCmd(c); // Add the cmd to the current chunk 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; return true;
} }
else if ((isBlock(bt_block) || isBlock(bt_method)) && stream->match(tokens::name,tokens::colon,tokens::cbracketo)) { else if ((isBlock(bt_block) || isBlock(bt_method)) && stream->match(tokens::name,tokens::colon,tokens::cbracketo)) {
@ -229,6 +240,7 @@ namespace dms {
} }
} }
stream->next(); stream->next();
current_chunk->addCmd(new cmd{ codes::HALT });
return true; return true;
} }
// emotion: "path" // emotion: "path"

View File

@ -44,5 +44,6 @@ const std::string dms::codes::list[] = {
"POW", "POW",
"MOD", "MOD",
"LIST", "LIST",
"LINE" "LINE",
"HALT"
}; };

View File

@ -46,7 +46,8 @@ namespace dms::codes {
POW, POW,
MOD, MOD,
LIST, LIST,
LINE LINE,
HALT,
}; };
extern const std::string list[]; extern const std::string list[];
static bool isControl(const op code) { static bool isControl(const op code) {

View File

@ -18,6 +18,12 @@ namespace dms {
push_chunk("$END", c); push_chunk("$END", c);
setChoiceHandler(new choiceHandler); // Use the default implementation 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) { void dms_state::enable(std::string flag) {
enables[flag] = true; enables[flag] = true;
} }

View File

@ -11,12 +11,15 @@
#include <thread> #include <thread>
#include <mutex> #include <mutex>
#include <chrono> #include <chrono>
#include "Character.h"
namespace dms { namespace dms {
struct dms_state struct dms_state
{ {
void* choi = nullptr; void* choi = nullptr;
std::unordered_map<std::string, value*> memory; std::unordered_map<std::string, value*> memory;
std::vector<value*> garbage;
std::map<std::string, chunk*> chunks; std::map<std::string, chunk*> chunks;
std::map<std::string, character*> characters;
std::string entry = "$undefined"; std::string entry = "$undefined";
std::map<std::string, bool> enables; std::map<std::string, bool> enables;
const double Iversion = 1.0; const double Iversion = 1.0;
@ -36,6 +39,11 @@ namespace dms {
void disable(std::string flag); void disable(std::string flag);
bool isEnabled(std::string flag); bool isEnabled(std::string flag);
void setChoiceHandler(void* choi); 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(); bool run();
private: private:
// From what I gathered // From what I gathered

View File

@ -1,6 +1,7 @@
#include "dms_state.h" #include "dms_state.h"
#include "utils.h" #include "utils.h"
#include "Handlers.h" #include "Handlers.h"
#include <iostream>
using namespace dms::utils; using namespace dms::utils;
using namespace dms::exceptions; using namespace dms::exceptions;
using namespace dms::codes; using namespace dms::codes;
@ -9,6 +10,63 @@ namespace dms {
void dms_state::setChoiceHandler(void* choi) { void dms_state::setChoiceHandler(void* choi) {
this->choi = 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<cmd*> 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<cmd*>& cmds) { void dms_state::init(chunk* chunk, size_t& pos, size_t& max, std::vector<cmd*>& cmds) {
pos = 0; pos = 0;
max = chunk->cmds.size(); max = chunk->cmds.size();
@ -16,7 +74,7 @@ namespace dms {
} }
// Instance, multiple instances can allow different code to work side by side // Instance, multiple instances can allow different code to work side by side
bool dms_state::run(std::string instance) { bool dms_state::run(std::string instance) {
codes::op code; //codes::op code;
//Spawn thread and run //Spawn thread and run
return true; return true;
} }
@ -36,10 +94,12 @@ namespace dms {
//TODO: parse the cmds and do stuff //TODO: parse the cmds and do stuff
// If this is running in a thread then stop will force this loop to stop // If this is running in a thread then stop will force this loop to stop
size_t ln = 0; size_t ln = 0;
character* speaker = nullptr;
std::string temp;
while (!stop || !halt) { while (!stop || !halt) {
c = cmds[pos++]; c = cmds[pos++];
code = c->opcode; code = c->opcode;
utils::print("> ",*c); //utils::print("> ",*c);
//utils::wait(); //utils::wait();
switch (code) switch (code)
{ {
@ -64,20 +124,52 @@ namespace dms {
// How we add modules into the code. This is the code that actually loads that data! // How we add modules into the code. This is the code that actually loads that data!
break; break;
// Flags handled // 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: case LINE:
ln = c->args.args[0]->n->getValue(); ln = c->args.args[0]->n->getValue();
break; break;
case NOOP: case NOOP:
break; break;
case CHOI: case CHOI:
if (utils::valueassertall(c->args, memory, datatypes::string)) { //Because we are using void* we must cast our pointers
//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*"
//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);
pos += 2*(*(choiceHandler*)choi).manageChoice(this, c->args);
}
break; break;
case JUMP: case JUMP:
value* v1;
// Value assert resolves the data so a variable must eventually equal a string // Value assert resolves the data so a variable must eventually equal a string
if (utils::valueassert(c->args, memory, datatypes::string)) { if (utils::valueassert(c->args, memory, datatypes::string)) {
std::string block = c->args.args[0]->resolve(memory)->s->getValue(); std::string block = c->args.args[0]->resolve(memory)->s->getValue();
@ -103,7 +195,6 @@ namespace dms {
break; break;
} }
} }
END:
return true; return true;
} }

Binary file not shown.

View File

@ -149,43 +149,48 @@ Line <37> name char
Line <37> bracketc ] Line <37> bracketc ]
Line <37> newline Line <37> newline
Line <37> newline Line <37> newline
Line <38> name age Line <38> name fname
Line <38> equal = Line <38> equal =
Line <38> number .24 Line <38> string Bob
Line <38> newline Line <38> newline
Line <38> newline Line <38> newline
Line <39> name money
Line <39> equal =
Line <39> number 100
Line <39> newline Line <39> newline
Line <39> newline Line <40> name age
Line <40> name excited Line <40> equal =
Line <40> colon : Line <40> number .24
Line <40> string path/to/file
Line <40> name function
Line <40> newline Line <40> newline
Line <40> newline Line <40> newline
Line <41> name money
Line <41> equal =
Line <41> number 100
Line <41> newline Line <41> newline
Line <41> newline Line <41> newline
Line <42> bracketo [ Line <42> name excited
Line <42> name newblock
Line <42> colon : Line <42> colon :
Line <42> name function Line <42> string path/to/file
Line <42> parao (
Line <42> parac )
Line <42> bracketc ]
Line <42> newline Line <42> newline
Line <42> newline Line <42> newline
Line <43> string Test #2
Line <43> newline Line <43> newline
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 <44> newline Line <44> newline
Line <45> string huh Line <45> string Test #2
Line <45> newline Line <45> newline
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> newline Line <1> newline
Line <1> bracketo [ Line <1> bracketo [
@ -225,112 +230,117 @@ Line <8> equal =
Line <8> number 1000 Line <8> number 1000
Line <8> newline Line <8> newline
Line <8> newline Line <8> newline
Line <9> name lname
Line <9> equal =
Line <9> string Ward
Line <9> newline
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 <10> newline Line <11> name calm
Line <11> name excited
Line <11> colon : Line <11> colon :
Line <11> string ./path/to/file Line <11> string ./path/to/file
Line <11> newline Line <11> newline
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 <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 <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 <14> newline
Line <15> name d Line <14> newline
Line <15> equal = Line <15> string Testing...
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 <15> newline Line <15> newline
Line <15> newline Line <16> name d
Line <16> name e
Line <16> equal = 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 <16> newline Line <16> newline
Line <17> name e Line <17> name e
Line <17> equal = Line <17> equal =
Line <17> nil nil Line <17> string somestring
Line <17> newline Line <17> newline
Line <17> newline Line <17> newline
Line <18> name g Line <18> name e
Line <18> equal = Line <18> equal =
Line <18> false false Line <18> nil nil
Line <18> newline Line <18> newline
Line <18> newline Line <18> newline
Line <19> ret Line <19> name g
Line <19> name d Line <19> equal =
Line <19> false false
Line <19> newline Line <19> newline
Line <19> newline Line <19> newline
Line <20> ret
Line <20> name d
Line <20> newline Line <20> newline
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 <21> newline Line <21> newline
Line <22> name slot1 Line <22> bracketo [
Line <22> equal = Line <22> name inventory
Line <22> string Line <22> colon :
Line <22> name env
Line <22> bracketc ]
Line <22> newline Line <22> newline
Line <22> newline Line <22> newline
Line <23> name slot2 Line <23> name slot1
Line <23> equal = Line <23> equal =
Line <23> string Line <23> string
Line <23> newline Line <23> newline
Line <23> newline Line <23> newline
Line <24> name slot3 Line <24> name slot2
Line <24> equal = Line <24> equal =
Line <24> string Line <24> string
Line <24> newline Line <24> newline
Line <24> newline Line <24> newline
Line <25> name slot4 Line <25> name slot3
Line <25> equal = Line <25> equal =
Line <25> string Line <25> string
Line <25> newline Line <25> newline
Line <25> newline Line <25> newline
Line <26> name slot5 Line <26> name slot4
Line <26> equal = Line <26> equal =
Line <26> string Line <26> string
Line <26> newline Line <26> newline
Line <26> newline Line <26> newline
Line <27> name slot6 Line <27> name slot5
Line <27> equal = Line <27> equal =
Line <27> string Line <27> string
Line <27> newline Line <27> newline
Line <27> newline Line <27> newline
Line <28> name slot7 Line <28> name slot6
Line <28> equal = Line <28> equal =
Line <28> string Line <28> string
Line <28> newline Line <28> newline
Line <28> newline Line <28> newline
Line <29> name slot8 Line <29> name slot7
Line <29> equal = Line <29> equal =
Line <29> string Line <29> string
Line <29> newline Line <29> newline
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

View File

@ -6,6 +6,7 @@
[Ryan:char] [Ryan:char]
age = 21 age = 21
money = 1000 money = 1000
lname = "Ward"
// Inside a character block this syntax defines animation/image file for an emotion // Inside a character block this syntax defines animation/image file for an emotion
calm: "./path/to/file" calm: "./path/to/file"
excited: "./path/to/file" excited: "./path/to/file"

View File

@ -35,9 +35,11 @@ using extendedDefine
"hehe" "hehe"
[Bob:char] [Bob:char]
fname = "Bob"
//lname = ""
age = .24 age = .24
money = 100 money = 100
excited: "path/to/file" | function excited: "path/to/file"
[newblock:function()] [newblock:function()]
"Test #2" "Test #2"

View File

@ -10,7 +10,11 @@
namespace dms::utils { namespace dms::utils {
template<class... Args> template<class... Args>
void print(Args... args) { void print(Args... args) {
(std::cout << ... << args) << "\n"; (std::cout << ... << args) << std::endl;
}
template<class... Args>
void write(Args... args) {
(std::cout << ... << args);
} }
template<class... Args> template<class... Args>
std::string concat(Args... args) { std::string concat(Args... args) {