diff --git a/DMS/DMS.cpp b/DMS/DMS.cpp index 5f1ca91..3747d08 100644 --- a/DMS/DMS.cpp +++ b/DMS/DMS.cpp @@ -2,10 +2,22 @@ //#include #include using namespace dms; -typedef void(*FNPTR)(); +//typedef void(*FNPTR)(); +value* invokeTest(dms_state* state, dms_args* args) { + utils::print(args->args[0]->getPrintable()); + return buildValue("I work!"); +} int main() { + LineParser parser = LineParser("test.dms"); + dms_state* state = parser.Parse(); + state->invoker.registerFunction("invokeTest", invokeTest); + state->dump(); + state->run(); + utils::print("Exitcode: ",state->exitcode); + + /*HINSTANCE hInst = LoadLibrary(L"C:\\Users\\rayam\\Desktop\\test.dll"); if (!hInst) { std::cout << "\nCould not load the library!"; @@ -19,11 +31,4 @@ int main() } 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 0494afa..41a94eb 100644 --- a/DMS/DMS.vcxproj +++ b/DMS/DMS.vcxproj @@ -156,6 +156,7 @@ + @@ -174,6 +175,7 @@ + diff --git a/DMS/DMS.vcxproj.filters b/DMS/DMS.vcxproj.filters index 961a267..d07c084 100644 --- a/DMS/DMS.vcxproj.filters +++ b/DMS/DMS.vcxproj.filters @@ -84,6 +84,9 @@ Source Files\DMS + + Source Files\DMS + @@ -134,5 +137,8 @@ Header Files\DMS\blocks + + Header Files\DMS + \ No newline at end of file diff --git a/DMS/Invoker.cpp b/DMS/Invoker.cpp new file mode 100644 index 0000000..c72f722 --- /dev/null +++ b/DMS/Invoker.cpp @@ -0,0 +1,28 @@ +#include "Invoker.h" +#include "dms_state.h" +namespace dms { + bool Invoker::registerFunction(std::string str, value* (*f)(dms_state*, dms_args*)) { + if (preventOverwriting && funcs.count(str)) { + return false; + } + funcs.insert_or_assign(str, f); + return true; + } + bool Invoker::registerFunction(std::string str, value* (*f)(dms_state*, dms_args*), bool preventoverride) { + if (preventoverride && funcs.count(str)) { + return false; + } + funcs.insert_or_assign(str, f); + return true; + } + value* Invoker:: Invoke(std::string str, dms_state* state, dms_args* args) { + if (funcs.count(str)) { + for (int i = 0; i < args->args.size() - 1; i++) { + args->args[i] = args->args[i]->resolve(state->memory); + } + return funcs[str](state, args); + } + state->push_error(errors::error{ errors::non_existing_function, "Attempt to call a nil value!" }); + return buildNil(); + } +} \ No newline at end of file diff --git a/DMS/Invoker.h b/DMS/Invoker.h new file mode 100644 index 0000000..d6712d2 --- /dev/null +++ b/DMS/Invoker.h @@ -0,0 +1,14 @@ +#pragma once +#include "errors.h" +#include +namespace dms { + struct dms_state; + class Invoker { + std::unordered_mapfuncs; + public: + bool preventOverwriting = true; + bool registerFunction(std::string str, value* (*f)(dms_state*, dms_args*)); + bool registerFunction(std::string str, value* (*f)(dms_state*, dms_args*), bool preventoverride); + value* Invoke(std::string str, dms_state* state, dms_args* args); + }; +} diff --git a/DMS/LineParser.h b/DMS/LineParser.h index 199df2a..9114ad1 100644 --- a/DMS/LineParser.h +++ b/DMS/LineParser.h @@ -74,7 +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); + bool match_process_index(tokenstream* stream,value* v = nullptr, bool leftside = false); // Build diff --git a/DMS/LineParserMatchProcess.cpp b/DMS/LineParserMatchProcess.cpp index a593007..4c293c7 100644 --- a/DMS/LineParserMatchProcess.cpp +++ b/DMS/LineParserMatchProcess.cpp @@ -134,6 +134,15 @@ 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! + c = new cmd; + c->opcode = codes::INST; + c->args.push(v); + c->args.push(buildNil()); + if (dict != nullptr) { + c->args.push(dict); + dict = nullptr; + } + current_chunk->addCmd(c); return true; } return false; @@ -265,7 +274,27 @@ namespace dms { return false; } bool LineParser::match_process_assignment(tokenstream* stream) { - if (stream->match(tokens::name,tokens::equal)) { + value* v = buildVariable(); + v->set(); + if (match_process_index(stream, v, true)) { + cmd* c = current_chunk->cmds.back(); + value* ref = buildVariable(); + if (stream->peek().type == tokens::equal) { + stream->next(); + } + else { + badSymbol(stream); + return false; + } + if (match_process_standard(stream, ref)) { + c->args.push(ref); + return true; + } + else if (stream->match(tokens::newline)) { + stream->next(); + } + } + else if (stream->match(tokens::name,tokens::equal)) { value* var = buildVariable(stream->next().name); // The variable that we will be setting stuff to stream->next(); // Consume the equal cmd* c = new cmd; @@ -275,12 +304,17 @@ namespace dms { if (match_process_standard(stream,ref)) { c->args.push(ref); current_chunk->addCmd(c); + delete[] v; return true; } else if (stream->match(tokens::newline)) { stream->next(); } } + else { + // We should clean up this + delete[] v; + } return false; } bool LineParser::match_process_debug(tokenstream* stream) { @@ -507,7 +541,7 @@ namespace dms { } return false; } - bool LineParser::match_process_index(tokenstream* stream, value* v) { + bool LineParser::match_process_index(tokenstream* stream, value* v, bool leftside) { if (stream->match(tokens::name,tokens::bracketo)) { std::string name = stream->next().name; std::vector tok = stream->next(tokens::bracketo, tokens::bracketc); @@ -517,14 +551,25 @@ namespace dms { tempstream.init(&tok); value* tempval = buildVariable(); cmd* c = new cmd; - c->opcode = codes::INDX; + if (leftside) { + c->opcode = codes::ASID; + } + else { + c->opcode = codes::INDX; + } + int nlcount = 0; while (tempstream.peek().type != tokens::none) { // Keep going until we hit the end if (match_process_standard(&tempstream, tempval)) { c->args.push(v); c->args.push(buildBlock(name)); c->args.push(tempval); } + else if (nlcount) { + state->push_error(errors::error{ errors::badtoken,concat("Unexpected symbol '",tempstream.last().toString(),"' Expected ']' to close list (line: ",tempstream.last().line_num,") Indexing must be done on one line?"),true,tempstream.last().line_num,current_chunk }); + return false; + } else if (tempstream.match(tokens::newline)) { + nlcount++; tempstream.next(); } else { diff --git a/DMS/codes.cpp b/DMS/codes.cpp index 8203645..700bd18 100644 --- a/DMS/codes.cpp +++ b/DMS/codes.cpp @@ -47,5 +47,6 @@ const std::string dms::codes::list[] = { "LINE", "HALT", "FILE", - "GC" + "GC", + "ASID" }; \ No newline at end of file diff --git a/DMS/codes.h b/DMS/codes.h index 43b6191..f5bc641 100644 --- a/DMS/codes.h +++ b/DMS/codes.h @@ -49,7 +49,8 @@ namespace dms::codes { LINE, HALT, FILE, - GC + GC, + ASID }; extern const std::string list[]; static bool isControl(const op code) { diff --git a/DMS/dms.h b/DMS/dms.h index 95f02bb..14c889b 100644 --- a/DMS/dms.h +++ b/DMS/dms.h @@ -13,4 +13,5 @@ #include "token.h" #include "utils.h" #include "value.h" +#include "Invoker.h" diff --git a/DMS/dms_state.h b/DMS/dms_state.h index 3aee9a0..520140e 100644 --- a/DMS/dms_state.h +++ b/DMS/dms_state.h @@ -4,6 +4,7 @@ #include #include +#include "Invoker.h" #include "errors.h" #include "chunk.h" #include "dms_exceptions.h" @@ -15,6 +16,7 @@ namespace dms { { Handler* handler = nullptr; bool hasFirst = false; + Invoker invoker; std::unordered_map memory; std::vector garbage; std::unordered_map chunks; diff --git a/DMS/dms_state_interpret.cpp b/DMS/dms_state_interpret.cpp index d0a0bc1..14dbdbc 100644 --- a/DMS/dms_state_interpret.cpp +++ b/DMS/dms_state_interpret.cpp @@ -133,7 +133,7 @@ namespace dms { while (!stop || !halt) { c = cmds[pos++]; code = c->opcode; - //print("\n(",pos,")> ",*c); + //print("(",pos,")> ",*c); //wait(); switch (code) { @@ -174,6 +174,51 @@ namespace dms { } return true; break; + case FUNC: + { + std::string funcname = c->args.args[0]->getPrintable(); + value* assn = c->args.args[1]; + dms_args args; + for (int i = 2; i < c->args.args.size(); i++) { + args.push(c->args.args[i]); + } + value* ret = invoker.Invoke(funcname, this, &args); + if (assn->type != datatypes::nil) { + assign(mem, assn, ret); + } + } + break; + case ASID: + { + value* env = c->args.args[1]; + value* indx = c->args.args[2]->resolve(*mem); + value* assn = c->args.args[3]->resolve(*mem); + if (env->type == datatypes::block && blockExists(env->getPrintable())) { // If this is a block let's handle this + enviroment* e = nullptr; + if (enviroments.count(env->getPrintable())) { + e = enviroments[env->getPrintable()]; + } + else if (characters.count(env->getPrintable())) { + e = characters[env->getPrintable()]; + } + e->values[indx->getPrintable()] = assn; + } + else if (env->type == datatypes::env) { + if (indx->type == datatypes::number) { + env->e->pushValue(assn); + } + else { + push_error(errors::error{ errors::invalid_type ,concat("Expected a number value got ",datatype[indx->type]) }); + return false; + } + } + else if (env->type == datatypes::custom) { + env->c->NewIndex(indx, assn); + //assign(mem, assn, env->c->Index(indx)); + // Call the method within the custom data + } + break; + } case INDX: { value* assn = c->args.args[0]; diff --git a/DMS/dump.bin b/DMS/dump.bin index d26b7a2..ab98c9a 100644 Binary files a/DMS/dump.bin and b/DMS/dump.bin differ diff --git a/DMS/dump.txt b/DMS/dump.txt index 3b399d2..5956716 100644 --- a/DMS/dump.txt +++ b/DMS/dump.txt @@ -42,247 +42,97 @@ Line <13> name main Line <13> bracketc ] Line <13> newline Line <13> newline -Line <14> string why Line <14> newline Line <14> newline -Line <15> name Bob -Line <15> colon : +Line <15> name list +Line <15> equal = Line <15> cbracketo { +Line <15> string Hello +Line <15> seperator , +Line <15> number 2 +Line <15> seperator , +Line <15> number 3 +Line <15> cbracketc } Line <15> newline Line <15> newline -Line <16> name speed -Line <16> number 50 Line <16> newline Line <16> newline -Line <17> name excited -Line <17> colon : -Line <17> string Hello Mr. `Ryan:lname`, +Line <17> string Contents of list {`list:1`, `list:2`, `list:3`} Line <17> newline Line <17> newline -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> name test +Line <21> name hmm Line <21> equal = -Line <21> name Bob -Line <21> bracketo [ -Line <21> string fname -Line <21> bracketc ] +Line <21> name invokeTest +Line <21> parao ( +Line <21> string Do I work? +Line <21> parac ) Line <21> newline Line <21> newline -Line <22> string `Bob`'s First Name is: `test` Line <22> newline Line <22> newline +Line <23> string The return of hmm is "`hmm`" +Line <23> newline Line <23> newline 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 Hey `Bob`, I'm good how are you? +Line <26> bracketo [ +Line <26> name Bob +Line <26> colon : +Line <26> name char +Line <26> bracketc ] Line <26> newline Line <26> newline -Line <27> cbracketc } Line <27> newline Line <28> newline -Line <28> newline -Line <29> string Waiting ... -Line <29> newline Line <29> newline +Line <30> name unknown +Line <30> equal = +Line <30> string Ya boi Line <30> newline Line <30> newline -Line <31> name Bob -Line <31> colon : -Line <31> cbracketo { +Line <31> name age +Line <31> equal = +Line <31> number 0.24 Line <31> newline Line <31> newline -Line <32> string I am great thanks! I want to show you that I can count! - +Line <32> name money +Line <32> equal = +Line <32> number 100 Line <32> newline Line <32> newline -Line <33> name wait -Line <33> number 0.1 +Line <33> name excited +Line <33> colon : +Line <33> string path/to/file Line <33> newline Line <33> newline -Line <34> string 1 - Line <34> newline Line <34> newline -Line <35> name wait -Line <35> number 0.1 +Line <35> bracketo [ +Line <35> name newblock +Line <35> colon : +Line <35> name function +Line <35> parao ( +Line <35> parac ) +Line <35> bracketc ] Line <35> newline Line <35> newline -Line <36> string 2 - +Line <36> string Test #2 Line <36> newline Line <36> newline -Line <37> name wait -Line <37> number 0.1 +Line <37> string Does it parse this part properly? Line <37> newline Line <37> newline -Line <38> string 3 - +Line <38> string huh Line <38> newline Line <38> newline -Line <39> name wait -Line <39> number 0.1 -Line <39> newline -Line <39> newline -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> string 5 - -Line <42> newline -Line <42> newline -Line <43> cbracketc } -Line <43> newline -Line <43> newline -Line <44> newline -Line <44> newline -Line <45> control -Line <45> string What do you want to do? -Line <45> cbracketo { -Line <45> newline -Line <45> newline -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 2 -Line <47> jump -Line <47> string test -Line <47> newline -Line <47> newline -Line <48> string option 3 -Line <48> jump -Line <48> name there -Line <48> newline -Line <48> newline -Line <49> string option 4 -Line <49> gotoo -Line <49> string o3 -Line <49> newline -Line <49> newline -Line <50> string option 5 -Line <50> gotoo -Line <50> name here -Line <50> newline -Line <50> newline -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> newline -Line <53> newline -Line <54> bracketo [ -Line <54> name test -Line <54> bracketc ] -Line <54> newline -Line <54> newline -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 This continues from the last message! -Line <56> newline -Line <56> newline -Line <57> pipe | -Line <57> string Keeps code readable. This does not cause a new line! -Line <57> newline -Line <57> newline -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> newline -Line <60> newline -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> newline -Line <65> name unknown -Line <65> equal = -Line <65> string Some Rando -Line <65> newline -Line <65> newline -Line <66> name age -Line <66> equal = -Line <66> number 0.24 -Line <66> newline -Line <66> newline -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> newline -Line <69> newline -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 Test #2 -Line <71> newline -Line <71> newline -Line <72> string Does it parse this part properly? -Line <72> newline -Line <72> newline -Line <73> string huh -Line <73> newline -Line <73> newline -Line <73> eof +Line <38> eof Line <1> newline Line <1> newline Line <1> flag diff --git a/DMS/errors.h b/DMS/errors.h index 2f47810..5929814 100644 --- a/DMS/errors.h +++ b/DMS/errors.h @@ -14,7 +14,8 @@ namespace dms::errors { nested_function, disp_unknown, non_existing_block, - incompatible_version + incompatible_version, + non_existing_function }; struct error { errortype code=unknown; diff --git a/DMS/test.dms b/DMS/test.dms index 3375ca3..fdc1a41 100644 --- a/DMS/test.dms +++ b/DMS/test.dms @@ -11,58 +11,23 @@ version 0.2 using extendedDefine [main] - "why" - Bob: { - speed 50 - excited: "Hello Mr. `Ryan:lname`, " - "how are `inv:slot2` you doing?" - } - test = Bob["fname"] - "`Bob`'s First Name is: `test`" + list = {"Hello",2,3} + + "Contents of list {`list:1`, `list:2`, `list:3`}" + //Ryan:setNickname(Bob,"Bobby") // Not yet implemeted! - Ryan: { - "Hey `Bob`, I'm good how are you?" - } // Should display Hey Bobby, I'm good how are you? + hmm = invokeTest("Do I work?") - "Waiting ..." - - Bob: { - "I am great thanks! I want to show you that I can count!\n" - wait .1 - "1\n" - wait .1 - "2\n" - wait .1 - "3\n" - wait .1 - "4\n" - wait .1 - "5\n" - } + "The return of hmm is \"`hmm`\"" - choice "What do you want to do?" { - "option 1" test2("testing",{1,2,3}) - "option 2" jump "test" - "option 3" jump there - "option 4" goto "o3" - "option 5" goto here - "option 6" test("here") - } - -[test] - Ryan: "We are here now!" - |"This continues from the last message!" - |"Keeps code readable. This does not cause a new line!" - Ryan: "This does trigger a new line tho!" - "This also will cause a new line!" [Bob:char] //fname = "Bob" //known = true // defaults to false //lname = "Johnson" // defaults to "" - unknown = "Some Rando" + unknown = "Ya boi" age = .24 money = 100 excited: "path/to/file" diff --git a/DMS/value.cpp b/DMS/value.cpp index d175bbf..6fb5211 100644 --- a/DMS/value.cpp +++ b/DMS/value.cpp @@ -1,5 +1,6 @@ #include "value.h" #include "dms_state.h" +#include "utils.h" namespace dms { const std::string datatype[] = { "escape","nil", "number", "boolean", "env", "string", "custom", "variable", "block" }; std::vector _VALUES; @@ -19,6 +20,9 @@ namespace dms { void dms_args::push(value* val) { args.push_back(val); } + size_t dms_args::size() { + return args.size(); + } std::string dms_string::getValue(dms_state* state) { std::stringstream temp; std::stringstream var; @@ -60,8 +64,14 @@ namespace dms { temp << "nil"; } } + else if (v->resolve(state->memory)->type == datatypes::env) { + if(v->resolve(state->memory)->e->ipart.size()> std::stoi(index)) + temp << v->resolve(state->memory)->e->ipart[std::stoi(index)-1]->getPrintable(); + else + temp << "nil"; + } else { - temp << v->getPrintable(); + temp << v->resolve(state->memory)->getPrintable(); } } else { @@ -206,6 +216,11 @@ namespace dms { val->type = variable; return val; } + value* buildValue(char const* s) { + value* val = new value{}; + val->set(buildString(s)); + return val; + } value* buildValue(std::string str) { value* val = new value{}; val->set(buildString(str)); diff --git a/DMS/value.h b/DMS/value.h index 7876912..213e484 100644 --- a/DMS/value.h +++ b/DMS/value.h @@ -117,6 +117,7 @@ namespace dms { }; }; value* buildValue(); + value* buildValue(char const* s); value* buildNil(); value* buildVariable(std::string str); value* buildVariable(); @@ -129,6 +130,7 @@ namespace dms { struct dms_args { std::vector args; void push(value* val); + size_t size(); friend std::ostream& operator << (std::ostream& out, const dms_args& c) { for (size_t i=0; i < c.args.size(); i++) { if(i==c.args.size()-1)