diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..953aa7c --- /dev/null +++ b/.editorconfig @@ -0,0 +1,5 @@ +# Rules in this file were initially inferred by Visual Studio IntelliCode from the F:\VSCWorkspace\DMS codebase based on best match to current usage at 10/3/2020 +# You can modify the rules from these initially generated values to suit your own policies +# You can learn more about editorconfig here: https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference +[*.cs] + diff --git a/DMS/DMS.cpp b/DMS/DMS.cpp index 6dd3c35..b641f58 100644 --- a/DMS/DMS.cpp +++ b/DMS/DMS.cpp @@ -1,11 +1,29 @@ #include "dms.h" +#include #include using namespace dms; +typedef void(*FNPTR)(); + int main() { + /*HINSTANCE hInst = LoadLibrary(L"C:\\Users\\rayam\\Desktop\\test.dll"); + if (!hInst) { + std::cout << "\nCould not load the library!"; + return EXIT_FAILURE; + } + + FNPTR fn = (FNPTR)GetProcAddress(hInst, "_init"); + if (!fn) { + std::cout << "\nCould not load function from library!"; + return EXIT_FAILURE; + } + + fn();*/ + LineParser parser = LineParser("test.dms"); dms_state* state = parser.Parse(); state->dump(); state->run(); utils::print("Exitcode: ",state->exitcode); + } \ No newline at end of file diff --git a/DMS/DMS.vcxproj b/DMS/DMS.vcxproj index 6a11778..36c5bd0 100644 --- a/DMS/DMS.vcxproj +++ b/DMS/DMS.vcxproj @@ -134,6 +134,7 @@ NDEBUG;_CONSOLE;%(PreprocessorDefinitions) true stdcpp17 + MaxSpeed Console @@ -144,6 +145,7 @@ + diff --git a/DMS/DMS.vcxproj.filters b/DMS/DMS.vcxproj.filters index b5fd767..961a267 100644 --- a/DMS/DMS.vcxproj.filters +++ b/DMS/DMS.vcxproj.filters @@ -81,6 +81,9 @@ Source Files\DMS\blocks + + Source Files\DMS + diff --git a/DMS/Handlers.cpp b/DMS/Handlers.cpp index ac8421f..73e845e 100644 --- a/DMS/Handlers.cpp +++ b/DMS/Handlers.cpp @@ -35,10 +35,12 @@ namespace dms { } // Simple one conn event + bool Handler::OnEnviromentCreated(dms_state* state, enviroment* env) const { + return true; + } bool Handler::OnSpeakerCreated(dms_state* state, character* chara) const { return true; } - bool Handler::OnStateInit(dms_state* state) const { return true; } diff --git a/DMS/Handlers.h b/DMS/Handlers.h index 031a334..877b063 100644 --- a/DMS/Handlers.h +++ b/DMS/Handlers.h @@ -10,9 +10,9 @@ namespace dms { virtual bool handleSpeaker(dms_state* state, character* chara) const; virtual bool handleMessageDisplay(dms_state* state, std::string msg) const; virtual bool handleMessageAppend(dms_state* state, std::string msg) const; - //virtual bool manageMessage(dms_state* state, value* msg) const; // Simple Events: only one connector! + virtual bool OnEnviromentCreated(dms_state* state, enviroment* env) const; virtual bool OnSpeakerCreated(dms_state* state, character* chara) const; virtual bool OnStateInit(dms_state* state) const; }; diff --git a/DMS/LineParser.h b/DMS/LineParser.h index a1a4a24..199df2a 100644 --- a/DMS/LineParser.h +++ b/DMS/LineParser.h @@ -74,6 +74,7 @@ namespace dms { bool match_process_list(tokenstream* stream, value* v = nullptr); bool match_process_wait(tokenstream* stream); bool match_process_standard(tokenstream* stream, value* v = nullptr); // All types that are matchable are handled here! + bool match_process_index(tokenstream* stream,value* v = nullptr); // Build diff --git a/DMS/LineParserMatchProcess.cpp b/DMS/LineParserMatchProcess.cpp index 9600f3c..fbeff3a 100644 --- a/DMS/LineParserMatchProcess.cpp +++ b/DMS/LineParserMatchProcess.cpp @@ -547,7 +547,15 @@ namespace dms { } return false; } + bool LineParser::match_process_index(tokenstream* stream, value* v) { + if (stream->match(tokens::name,tokens::bracketo)) { + // Todo implement this + } + return false; + } bool LineParser::match_process_jump(tokenstream* stream) { + if (current_chunk->type == blocktype::bt_character || current_chunk->type == blocktype::bt_env) + return false; if (stream->match(tokens::jump, tokens::name) || stream->match(tokens::jump, tokens::string)) { cmd* c = new cmd; c->opcode = codes::JUMP; diff --git a/DMS/LineParserUtils.cpp b/DMS/LineParserUtils.cpp index 62437c6..82cbc97 100644 --- a/DMS/LineParserUtils.cpp +++ b/DMS/LineParserUtils.cpp @@ -240,12 +240,12 @@ namespace dms { return true; } else if (bk_name == "$END") { - cmd* c = new cmd; + /*cmd* c = new cmd; c->opcode = codes::JUMP; c->args.push(buildValue("$END")); current_chunk->addCmd(c); state->push_chunk(current_chunk->name, current_chunk); - current_chunk = state->chunks["$END"]; + current_chunk = state->chunks["$END"];*/ return true; } else { diff --git a/DMS/Nadia.ogg b/DMS/Nadia.ogg deleted file mode 100644 index 92dcbeb..0000000 Binary files a/DMS/Nadia.ogg and /dev/null differ diff --git a/DMS/character.cpp b/DMS/character.cpp index a2d6427..d729d01 100644 --- a/DMS/character.cpp +++ b/DMS/character.cpp @@ -2,17 +2,20 @@ #include "utils.h" namespace dms { std::string character::getName() { - if (values.count("nickname")) { + if (has("nickname")) { return values["nickname"]->getPrintable(); } - if (seen && values.count("lname")) { + if (seen && has("fname") && has("lname")) { return utils::concat(values["fname"]->getPrintable()," ", values["lname"]->getPrintable()); } - else if (seen) { + else if (seen && has("fname")) { return utils::concat(values["fname"]->getPrintable()); } - else { + else if (!seen && has("unknown")) { return values["unknown"]->getPrintable(); } + else { + return "unknown"; + } } } \ No newline at end of file diff --git a/DMS/dms_custom.cpp b/DMS/dms_custom.cpp new file mode 100644 index 0000000..36664f9 --- /dev/null +++ b/DMS/dms_custom.cpp @@ -0,0 +1,61 @@ +#include "value.h" +#include "utils.h" +//Implement the defaults +namespace dms { + // These are pointers to other data that should not be deleted. + const value* perNIL = new value; + void dms_custom::_del() { + state = nullptr; + self = nullptr; + } + void dms_custom::_set(value* v) { + self = v; + } + void dms_custom::Init(dms_state* state) { + this->state = state; + } + value* dms_custom::Index(value* data) { + state->push_error(errors::error{ errors::unknown,"Attempting to index a non enviroment!" }); + return nullptr; + } + bool dms_custom::NewIndex(value* var, value* val) { + state->push_error(errors::error{ errors::unknown,"Attempting to create a new index on a non enviroment!" }); + return false; + } + value* dms_custom::Call(dms_args* args) { + state->push_error(errors::error{errors::unknown,"Attempting to call a non function value!"}); + return nullptr; + } + value* dms_custom::ToString() { + return buildValue(utils::concat("Custom: ",this)); + } + value* dms_custom::ADD(value* left, value* right) { + state->push_error(errors::error{ errors::unknown,"Attempting to add a non number value!" }); + return nullptr; + } + value* dms_custom::SUB(value* left, value* right) { + state->push_error(errors::error{ errors::unknown,"Attempting to subtract a non number value!" }); + return nullptr; + } + value* dms_custom::MUL(value* left, value* right) { + state->push_error(errors::error{ errors::unknown,"Attempting to multiply a non number value!" }); + return nullptr; + } + value* dms_custom::DIV(value* left, value* right) { + state->push_error(errors::error{ errors::unknown,"Attempting to divide a non number value!" }); + return nullptr; + } + value* dms_custom::POW(value* left, value* right) { + state->push_error(errors::error{ errors::unknown,"Attempting to raise a non number value!" }); + return nullptr; + } + value* dms_custom::EQUAL(value* left, value* right) { + return buildValue(left->getPrintable() == right->getPrintable()); + } + value* dms_custom::LESS_THAN(value* left, value* right) { + return buildValue(left->getPrintable() < right->getPrintable()); + } + value* dms_custom::LESS_THAN_EQUAL(value* left, value* right) { + return buildValue(left->getPrintable() <= right->getPrintable()); + } +} \ No newline at end of file diff --git a/DMS/dms_state.cpp b/DMS/dms_state.cpp index 539a5f2..d9cfc14 100644 --- a/DMS/dms_state.cpp +++ b/DMS/dms_state.cpp @@ -7,7 +7,7 @@ namespace dms { init_init = true; cmd* c = new cmd; for (const auto& [key, val] : chunks) { - if (val->type == blocktype::bt_character) { + if (val->type == blocktype::bt_character || val->type == blocktype::bt_env) { value* v = buildVariable(); v->set(buildString(key)); v->type = datatypes::block; @@ -36,6 +36,7 @@ namespace dms { enables.insert_or_assign("warnings",false); // enables.insert_or_assign("statesave",true); // Allows you to save state enables.insert_or_assign("omniscient",false); // Allows you to know who's who when you first meet them + enables.insert_or_assign("fullname", true); chunk* c = new chunk; c->name = "$END"; c->type = blocktype::bt_block; @@ -92,20 +93,20 @@ namespace dms { return false; } - bool dms_state::assign(value* var, value* val) { - if (memory.count(var->s->getValue()) == 0) { - memory.insert_or_assign(var->s->getValue(), val); + bool dms_state::assign(std::unordered_map* mem, value* var, value* val) { + if (mem->count(var->s->getValue()) == 0) { + mem->insert_or_assign(var->s->getValue(), val); return true; } else { - value* temp = memory[var->s->getValue()]; + value* temp = (*mem)[var->s->getValue()]; if (temp->type != datatypes::variable) { temp->set(); // Set the removed value to nil - garbage.push_back(memory[var->s->getValue()]); + garbage.push_back((*mem)[var->s->getValue()]); } else utils::print("> so we have a variable"); // This print should be a reminder for me to do something about this. - memory[var->s->getValue()] = val; + (*mem)[var->s->getValue()] = val; } } void dms_state::dump(bool print) { diff --git a/DMS/dms_state.h b/DMS/dms_state.h index a21f733..3aee9a0 100644 --- a/DMS/dms_state.h +++ b/DMS/dms_state.h @@ -1,16 +1,12 @@ #pragma once -#include "errors.h" -#include "chunk.h" -#include "dms_exceptions.h" #include #include #include -#include #include -// Threading Stuff -#include -#include -#include + +#include "errors.h" +#include "chunk.h" +#include "dms_exceptions.h" #include "Character.h" #include "enviroment.h" namespace dms { @@ -21,12 +17,12 @@ namespace dms { bool hasFirst = false; std::unordered_map memory; std::vector garbage; - std::map chunks; - std::map characters; - std::map enviroments; - std::map labels; + std::unordered_map chunks; + std::unordered_map characters; + std::unordered_map enviroments; + std::unordered_map labels; std::string entry = "$undefined"; - std::map enables; + std::unordered_map enables; std::size_t cur_line=0; int exitcode = 0; const double Iversion = 1.0; @@ -53,12 +49,13 @@ namespace dms { character* getCharacter(std::string c); enviroment* getEnviroment(std::string c); - bool assign(value* var, value* val); + bool assign(std::unordered_map* mem,value* var, value* val); size_t seek(std::string label,std::vector cmds ,codes::op code, size_t pos); bool characterExists(std::string bk_name); bool blockExists(std::string bk_name); bool typeAssert(value* val, datatypes type); bool run(); + bool run(std::string ent,std::unordered_map* mem); // This is called once and once only. Dynamically loading code is not a thing! void init(); diff --git a/DMS/dms_state_interpret.cpp b/DMS/dms_state_interpret.cpp index ce02cd7..057f17e 100644 --- a/DMS/dms_state_interpret.cpp +++ b/DMS/dms_state_interpret.cpp @@ -11,77 +11,68 @@ namespace dms { void dms_state::setHandler(Handler* hand) { this->handler = hand; } - enviroment* dms_state::getEnviroment(std::string c) { + void checkCharacter(character* cc,std::string index, datatypes type) { + value* val = cc->get(index); + if (val==nullptr) { + if (type == datatypes::string) + cc->values[index] = buildValue(""); + else if (type == datatypes::boolean) { + cc->values[index] = buildValue(false); + } + } + else if (val != nullptr) { + if (val->type != type) { + cc->values.erase(index); + } + } + } + enviroment* dms_state::getEnviroment(std::string env) { + if (enviroments.count(env)) { + return enviroments[env]; + } + else { + if (blockExists(env)) { + enviroment* e = new enviroment; + if (!run(env, &e->values)) { + return nullptr; + } + enviroments.insert_or_assign(env, e); + handler->OnEnviromentCreated(this, e); + return e; + } + else { + push_error(errors::error{ errors::non_existing_block ,utils::concat("Attempted to index a non existing enviroment block!") }); + return nullptr; + } + } return nullptr; } character* dms_state::getCharacter(std::string cha) { if (characters.count(cha)) { + characters[cha]->seen = true; return characters[cha]; } else { if (blockExists(cha)) { character* cc = new character; - cc->values.insert_or_assign("fname", buildValue(cha)); - cc->values.insert_or_assign("lname", buildValue("")); - 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); + cc->set("fname", buildValue(cha)); + cc->set("lname", buildValue("")); + cc->set("unknown", buildValue("Unknown")); + cc->set("known", buildValue(false)); if (isEnabled("omniscient")) { cc->seen = true; } else { cc->seen = false; } - 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") { - if(!typeAssert(c->args.args[1],datatypes::string)) - return nullptr; - cc->values.insert_or_assign("fname", c->args.args[1]); - } - else if (c->args.args[0]->s->getValue() == "lname") { - if (!typeAssert(c->args.args[1], datatypes::string)) - return nullptr; - cc->values.insert_or_assign("lname", c->args.args[1]); - } - else if (c->args.args[0]->s->getValue() == "unknown") { - if (!typeAssert(c->args.args[1], datatypes::string)) - return nullptr; - cc->values.insert_or_assign("unknown", c->args.args[1]); - } - else if (c->args.args[0]->s->getValue() == "known") { - if (!typeAssert(c->args.args[1], datatypes::boolean)) - return nullptr; - cc->seen = c->args.args[1]->b->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; - } + if (run(cha,&cc->values)) { + checkCharacter(cc, "fname",datatypes::string); + checkCharacter(cc, "lname", datatypes::string); + checkCharacter(cc, "unknown", datatypes::string); + checkCharacter(cc, "known", datatypes::boolean); + } + else { + return nullptr; } characters.insert_or_assign(cha, cc); // Call Character event! @@ -114,17 +105,20 @@ namespace dms { return true; } bool dms_state::run() { + if (chunks[entry] == NULL) { + push_error(errors::error{ errors::non_existing_block ,utils::concat("Attempted to Jump to a non existing block [",entry,"]") }); + return false; + } + return run("$INIT",&memory); + } + bool dms_state::run(std::string ent, std::unordered_map* mem) { codes::op code; cmd* c = nullptr; bool halt = false; size_t pos=0; size_t max = 0; std::vector cmds; - if (chunks[entry] == NULL) { - push_error(errors::error{errors::non_existing_block ,utils::concat("Attempted to Jump to a non existing block [",entry,"]")}); - return false; - } - init(chunks["$INIT"],pos,max,cmds); + init(chunks[ent],pos,max,cmds); //TODO: parse the cmds and do stuff // If this is running in a thread then stop will force this loop to stop @@ -182,22 +176,22 @@ namespace dms { env->hpart.insert_or_assign("$size", c->args.args[1]); value* val = new value; val->set(env); - assign(c->args.args[0], val); + assign(mem,c->args.args[0], val); } break; case INST: { - value* list = memory[c->args.args[0]->s->getValue()]; + value* list = (*mem)[c->args.args[0]->s->getValue()]; list->e->pushValue(c->args.args[1]); } break; case HALT: //wait(); - std::this_thread::sleep_for(std::chrono::milliseconds(700)); + sleep(700); std::cout << std::endl; break; case WAIT: - std::this_thread::sleep_for(std::chrono::milliseconds((int)(c->args.args[0]->n->getValue()*1000))); + sleep((int)(c->args.args[0]->n->getValue()*1000)); break; case DSPD: if (speaker == nullptr) { @@ -229,7 +223,7 @@ namespace dms { return false; break; case ASGN: - assign(c->args.args[0], c->args.args[1]); + assign(mem,c->args.args[0], c->args.args[1]); break; case LINE: cur_line = c->args.args[0]->n->getValue(); @@ -243,7 +237,7 @@ namespace dms { std::string prompt = c->args.args[0]->s->getValue(); std::string fn = c->args.args[1]->s->getValue(); for (size_t i = 2; i < c->args.args.size(); i++) - args.push_back(c->args.args[i]->resolve(memory)->s->getValue()); + args.push_back(c->args.args[i]->resolve(*mem)->s->getValue()); size_t npos = handler->handleChoice(this, prompt, args); size_t nnpos = seek(concat("CHOI_", fn, "_", npos),cmds,LABL,npos); if (!nnpos) { @@ -257,8 +251,8 @@ namespace dms { break; case JUMP: // 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(); + if (utils::valueassert(c->args, *mem, datatypes::string)) { + std::string block = c->args.args[0]->resolve(*mem)->s->getValue(); if (chunks[block] == NULL) { push_error(errors::error{ errors::non_existing_block ,utils::concat("Attempted to Jump to a non existing block [",block,"]") }); return false; @@ -272,7 +266,7 @@ namespace dms { } } else { - datatypes set = c->args.args[0]->resolve(memory)->type; + datatypes set = c->args.args[0]->resolve(*mem)->type; push_error(errors::error{ errors::invalid_arguments, utils::concat("String expected got ",datatype[set]), true,ln }); return false; } diff --git a/DMS/dump.bin b/DMS/dump.bin index 5cf501d..622d965 100644 Binary files a/DMS/dump.bin and b/DMS/dump.bin differ diff --git a/DMS/dump.txt b/DMS/dump.txt index dca5448..e3df3cc 100644 --- a/DMS/dump.txt +++ b/DMS/dump.txt @@ -17,267 +17,264 @@ Line <5> flag Line <5> name savestate Line <5> newline Line <5> newline +Line <6> flag +Line <6> name fullname +Line <6> newline Line <6> newline Line <7> newline -Line <8> flag -Line <8> string loadtest.dms -Line <8> newline Line <8> newline Line <9> flag -Line <9> number 0.2 +Line <9> string loadtest.dms Line <9> newline Line <9> newline Line <10> flag -Line <10> name extendedDefine +Line <10> number 0.2 Line <10> newline Line <10> newline +Line <11> flag +Line <11> name extendedDefine Line <11> newline Line <11> newline -Line <12> bracketo [ -Line <12> name main -Line <12> bracketc ] Line <12> newline Line <12> newline -Line <13> string why +Line <13> bracketo [ +Line <13> name main +Line <13> bracketc ] Line <13> newline Line <13> newline -Line <14> name Bob -Line <14> colon : -Line <14> cbracketo { +Line <14> string why Line <14> newline Line <14> newline -Line <15> name speed -Line <15> number 50 +Line <15> name Bob +Line <15> colon : +Line <15> cbracketo { Line <15> newline Line <15> newline -Line <16> name excited -Line <16> colon : -Line <16> string Hello Mr. `Ryan:lname`, +Line <16> name speed +Line <16> number 50 Line <16> newline Line <16> newline -Line <17> string how are you doing? +Line <17> name excited +Line <17> colon : +Line <17> string Hello Mr. `Ryan:lname`, Line <17> newline Line <17> newline -Line <18> cbracketc } +Line <18> string how are `inv:slot2` you doing? Line <18> newline Line <18> newline +Line <19> cbracketc } Line <19> newline Line <19> newline Line <20> newline +Line <20> newline Line <21> newline -Line <21> newline -Line <22> name Ryan -Line <22> colon : -Line <22> cbracketo { Line <22> newline Line <22> newline -Line <23> string Hey `Bob`, I'm good how are you? Line <23> newline -Line <23> newline -Line <24> cbracketc } Line <24> newline +Line <24> newline +Line <25> name Ryan +Line <25> colon : +Line <25> cbracketo { Line <25> newline Line <25> newline -Line <26> string Waiting ... +Line <26> string Hey `Bob`, I'm good how are you? Line <26> newline Line <26> newline +Line <27> cbracketc } Line <27> newline -Line <27> newline -Line <28> exit -Line <28> number 1 Line <28> newline Line <28> newline +Line <29> string Waiting ... Line <29> newline Line <29> newline -Line <30> name Bob -Line <30> colon : -Line <30> cbracketo { Line <30> newline Line <30> newline -Line <31> string I am great thanks! I want to show you that I can count! - +Line <31> name Bob +Line <31> colon : +Line <31> cbracketo { Line <31> newline Line <31> newline -Line <32> name wait -Line <32> number 1 +Line <32> string I am great thanks! I want to show you that I can count! + Line <32> newline Line <32> newline -Line <33> string 1 - +Line <33> name wait +Line <33> number 0.1 Line <33> newline Line <33> newline -Line <34> name wait -Line <34> number 1 +Line <34> string 1 + Line <34> newline Line <34> newline -Line <35> string 2 - +Line <35> name wait +Line <35> number 0.1 Line <35> newline Line <35> newline -Line <36> name wait -Line <36> number 1 +Line <36> string 2 + Line <36> newline Line <36> newline -Line <37> string 3 - +Line <37> name wait +Line <37> number 0.1 Line <37> newline Line <37> newline -Line <38> name wait -Line <38> number 1 +Line <38> string 3 + Line <38> newline Line <38> newline -Line <39> string 4 - +Line <39> name wait +Line <39> number 0.1 Line <39> newline Line <39> newline -Line <40> name wait -Line <40> number 1 -Line <40> newline -Line <40> newline -Line <41> string 5 +Line <40> string 4 +Line <40> newline +Line <40> newline +Line <41> name wait +Line <41> number 0.1 Line <41> newline Line <41> newline -Line <42> cbracketc } +Line <42> string 5 + Line <42> newline Line <42> newline +Line <43> cbracketc } Line <43> newline Line <43> newline -Line <44> control -Line <44> string What do you want to do? -Line <44> cbracketo { Line <44> newline Line <44> newline -Line <45> string option 1 -Line <45> name test2 -Line <45> parao ( -Line <45> string testing -Line <45> seperator , +Line <45> control +Line <45> string What do you want to do? Line <45> cbracketo { -Line <45> number 1 -Line <45> seperator , -Line <45> number 2 -Line <45> seperator , -Line <45> number 3 -Line <45> cbracketc } -Line <45> parac ) Line <45> newline Line <45> newline -Line <46> string option 2 -Line <46> jump -Line <46> string test +Line <46> string option 1 +Line <46> name test2 +Line <46> parao ( +Line <46> string testing +Line <46> seperator , +Line <46> cbracketo { +Line <46> number 1 +Line <46> seperator , +Line <46> number 2 +Line <46> seperator , +Line <46> number 3 +Line <46> cbracketc } +Line <46> parac ) Line <46> newline Line <46> newline -Line <47> string option 3 +Line <47> string option 2 Line <47> jump -Line <47> name there +Line <47> string test Line <47> newline Line <47> newline -Line <48> string option 4 -Line <48> gotoo -Line <48> string o3 +Line <48> string option 3 +Line <48> jump +Line <48> name there Line <48> newline Line <48> newline -Line <49> string option 5 +Line <49> string option 4 Line <49> gotoo -Line <49> name here +Line <49> string o3 Line <49> newline Line <49> newline -Line <50> string option 6 -Line <50> name test -Line <50> parao ( -Line <50> string here -Line <50> parac ) +Line <50> string option 5 +Line <50> gotoo +Line <50> name here Line <50> newline Line <50> newline -Line <51> cbracketc } +Line <51> string option 6 +Line <51> name test +Line <51> parao ( +Line <51> string here +Line <51> parac ) Line <51> newline Line <51> newline +Line <52> cbracketc } Line <52> newline Line <52> newline -Line <53> bracketo [ -Line <53> name test -Line <53> bracketc ] Line <53> newline Line <53> newline -Line <54> name Ryan -Line <54> colon : -Line <54> string We are here now! +Line <54> bracketo [ +Line <54> name test +Line <54> bracketc ] Line <54> newline Line <54> newline -Line <55> pipe | -Line <55> string This continues from the last message! +Line <55> name Ryan +Line <55> colon : +Line <55> string We are here now! Line <55> newline Line <55> newline Line <56> pipe | -Line <56> string Keeps code readable. This does not cause a new line! +Line <56> string This continues from the last message! Line <56> newline Line <56> newline -Line <57> name Ryan -Line <57> colon : -Line <57> string This does trigger a new line tho! +Line <57> pipe | +Line <57> string Keeps code readable. This does not cause a new line! Line <57> newline Line <57> newline -Line <58> string This also will cause a new line! +Line <58> name Ryan +Line <58> colon : +Line <58> string This does trigger a new line tho! Line <58> newline Line <58> newline +Line <59> string This also will cause a new line! Line <59> newline Line <59> newline -Line <60> bracketo [ -Line <60> name Bob -Line <60> colon : -Line <60> name char -Line <60> bracketc ] Line <60> newline Line <60> newline -Line <61> name fname -Line <61> equal = -Line <61> string Bob +Line <61> bracketo [ +Line <61> name Bob +Line <61> colon : +Line <61> name char +Line <61> bracketc ] Line <61> newline Line <61> newline Line <62> newline Line <63> newline -Line <64> name unknown -Line <64> equal = -Line <64> string Some Rando Line <64> newline -Line <64> newline -Line <65> name age +Line <65> name unknown Line <65> equal = -Line <65> number 0.24 +Line <65> string Some Rando Line <65> newline Line <65> newline -Line <66> name money +Line <66> name age Line <66> equal = -Line <66> number 100 +Line <66> number 0.24 Line <66> newline Line <66> newline -Line <67> name excited -Line <67> colon : -Line <67> string path/to/file +Line <67> name money +Line <67> equal = +Line <67> number 100 Line <67> newline Line <67> newline +Line <68> name excited +Line <68> colon : +Line <68> string path/to/file Line <68> newline Line <68> newline -Line <69> bracketo [ -Line <69> name newblock -Line <69> colon : -Line <69> name function -Line <69> parao ( -Line <69> parac ) -Line <69> bracketc ] Line <69> newline Line <69> newline -Line <70> string Test #2 +Line <70> bracketo [ +Line <70> name newblock +Line <70> colon : +Line <70> name function +Line <70> parao ( +Line <70> parac ) +Line <70> bracketc ] Line <70> newline Line <70> newline -Line <71> string Does it parse this part properly? +Line <71> string Test #2 Line <71> newline Line <71> newline -Line <72> string huh +Line <72> string Does it parse this part properly? Line <72> newline Line <72> newline -Line <72> eof +Line <73> string huh +Line <73> newline +Line <73> newline +Line <73> eof Line <1> newline Line <1> newline Line <1> flag @@ -397,7 +394,7 @@ Line <23> newline Line <24> newline Line <24> newline Line <25> bracketo [ -Line <25> name inventory +Line <25> name inv Line <25> colon : Line <25> name env Line <25> bracketc ] diff --git a/DMS/loadtest.dms b/DMS/loadtest.dms index b3a00aa..49039b6 100644 --- a/DMS/loadtest.dms +++ b/DMS/loadtest.dms @@ -22,7 +22,7 @@ disable hello g = false return d -[inventory:env] +[inv:env] slot1 = "S1" slot2 = "S2" slot3 = "S3" diff --git a/DMS/test.dll b/DMS/test.dll new file mode 100644 index 0000000..7ec1033 Binary files /dev/null and b/DMS/test.dll differ diff --git a/DMS/test.dms b/DMS/test.dms index 0fcfce9..d436642 100644 --- a/DMS/test.dms +++ b/DMS/test.dms @@ -3,6 +3,7 @@ entry main // Will either start the first block seen or the block supplied by yo disable omniscient enable forseelabels enable savestate +disable fullname //enable leaking //enable debugging loadfile "loadtest.dms" @@ -14,9 +15,11 @@ using extendedDefine Bob: { speed 50 excited: "Hello Mr. `Ryan:lname`, " - "how are you doing?" + "how are `inv:slot2` you doing?" } + //test = Bob[here] + //Ryan:setNickname(Bob,"Bobby") // Not yet implemeted! Ryan: { @@ -25,19 +28,17 @@ using extendedDefine "Waiting ..." - exit 1 - Bob: { "I am great thanks! I want to show you that I can count!\n" - wait 1 + wait .1 "1\n" - wait 1 + wait .1 "2\n" - wait 1 + wait .1 "3\n" - wait 1 + wait .1 "4\n" - wait 1 + wait .1 "5\n" } @@ -58,7 +59,7 @@ using extendedDefine "This also will cause a new line!" [Bob:char] - fname = "Bob" + //fname = "Bob" //known = true // defaults to false //lname = "Johnson" // defaults to "" unknown = "Some Rando" diff --git a/DMS/utils.cpp b/DMS/utils.cpp index 34f4e35..f54e457 100644 --- a/DMS/utils.cpp +++ b/DMS/utils.cpp @@ -1,5 +1,10 @@ #include "utils.h" namespace dms::utils { + void sleep(unsigned int mseconds) + { + clock_t goal = mseconds + clock(); + while (goal > clock()); + } bool isalphanum(std::string str) { for (size_t i = 0; i < str.size(); i++) { if (!isalnum(str[i]) && str[i]!='_') diff --git a/DMS/utils.h b/DMS/utils.h index c6bff24..01d98a8 100644 --- a/DMS/utils.h +++ b/DMS/utils.h @@ -7,6 +7,7 @@ #include "value.h" #include #include "dms_state.h" +#include namespace dms::utils { template void print(Args... args) { @@ -22,6 +23,7 @@ namespace dms::utils { (str << ... << args); return str.str(); } + void sleep(unsigned int mseconds); std::string random_string(size_t length); bool typeassert(dms_args args, datatypes t1=nil, datatypes t2 = nil, datatypes t3 = nil, datatypes t4 = nil, datatypes t5 = nil, datatypes t6 = nil, datatypes t7 = nil, datatypes t8 = nil, datatypes t9 = nil, datatypes t10 = nil, datatypes t11 = nil, datatypes t12 = nil); //Type asserting is mostly an internal thing for build in methods. It's not needed for dms code! bool typeassert(dms_state* state, dms_args args, datatypes t1 = nil, datatypes t2 = nil, datatypes t3 = nil, datatypes t4 = nil, datatypes t5 = nil, datatypes t6 = nil, datatypes t7 = nil, datatypes t8 = nil, datatypes t9 = nil, datatypes t10 = nil, datatypes t11 = nil, datatypes t12 = nil); diff --git a/DMS/value.cpp b/DMS/value.cpp index 363ac9f..42aef5e 100644 --- a/DMS/value.cpp +++ b/DMS/value.cpp @@ -1,8 +1,7 @@ #include "value.h" -#include "utils.h" -#include "string" +#include "dms_state.h" namespace dms { - const std::string datatype[] = { "nil", "number", "boolean", "env", "string", "custom", "variable", "block" }; + const std::string datatype[] = { "escape","nil", "number", "boolean", "env", "string", "custom", "variable", "block" }; std::vector _VALUES; value::value() { _VALUES.push_back(this); // Used for the interperter! In the end everything is a value @@ -39,7 +38,7 @@ namespace dms { if (state->memory.count(lookup)) { value* v = state->memory[lookup]; if (v->type == datatypes::block) { - if (state->getCharacter(v->s->getValue())!=nullptr) { + if ((state->chunks.count(v->s->getValue()) && state->chunks[v->s->getValue()]->type == blocktype::bt_character) && state->getCharacter(v->s->getValue())!=nullptr) { character* cha = state->getCharacter(v->s->getValue()); if (cha->values.count(index)) { temp << cha->values[index]->getPrintable(); @@ -48,6 +47,15 @@ namespace dms { temp << cha->getName(); } } + else if ((state->chunks.count(v->s->getValue()) && state->chunks[v->s->getValue()]->type == blocktype::bt_env) && state->getEnviroment(v->s->getValue()) != nullptr) { + enviroment* env = state->getEnviroment(v->s->getValue()); + if (env->values.count(index)) { + temp << env->values[index]->getPrintable(); + } + else { + temp << env; + } + } else { temp << "nil"; } @@ -175,10 +183,13 @@ namespace dms { value* buildValue() { return new value; } + value* buildNil() { + return new value; + } size_t count = 0; value* buildVariable() { count++; - std::string val = utils::concat("$",count); + std::string val = "$"+count; return buildVariable(val); } value* buildBlock(std::string str) { @@ -214,6 +225,8 @@ namespace dms { return val; } void value::nuke() { + if (type == datatypes::custom) + c->_del(); delete[] s; delete[] b; delete[] n; @@ -249,6 +262,12 @@ namespace dms { e = en; type = env; } + void dms::value::set(dms_custom* cus) { + nuke(); + c = cus; + c->_set(this); + type = custom; + } void value::set() { nuke(); type = nil; diff --git a/DMS/value.h b/DMS/value.h index 0ba69ba..7876912 100644 --- a/DMS/value.h +++ b/DMS/value.h @@ -10,7 +10,7 @@ namespace dms { struct value; struct dms_args; extern const std::string datatype[]; - enum datatypes { escape, nil, number, boolean, env, string, custom, variable, block }; + enum datatypes { escape, nil, number, boolean, env, string, custom, variable, block, error }; struct dms_number { double val; double getValue() { return val; } @@ -42,6 +42,10 @@ namespace dms { }; // Custom data that you can work with by overriding this code struct dms_custom { + void Init(dms_state* state); + void _set(value* v); + void _del(); + virtual value* Index(value* data); virtual bool NewIndex(value* var, value* val); virtual value* Call(dms_args* args); @@ -53,12 +57,16 @@ namespace dms { virtual value* POW(value* left, value* right); virtual value* EQUAL(value* left, value* right); virtual value* LESS_THAN(value* left, value* right); - virtual value* GREATER_THAN(value* left, value* right); + virtual value* LESS_THAN_EQUAL(value* left, value* right); + private: + dms_state* state=nullptr; + value* self; }; dms_string* buildString(std::string str); dms_boolean* buildBool(bool b); dms_number* buildNumber(double num); struct value { + public: datatypes type = nil; dms_boolean* b = nullptr; dms_number* n = nullptr; @@ -72,6 +80,7 @@ namespace dms { void set(dms_boolean* bo); void set(dms_number* num); void set(dms_env* en); + void set(dms_custom* cus); void set(); bool typeMatch(const value* o) const; std::string getPrintable() const; @@ -108,6 +117,7 @@ namespace dms { }; }; value* buildValue(); + value* buildNil(); value* buildVariable(std::string str); value* buildVariable(); value* buildValue(std::string str);