diff --git a/DMS/DMS.cpp b/DMS/DMS.cpp index e2dd69d..cbef133 100644 --- a/DMS/DMS.cpp +++ b/DMS/DMS.cpp @@ -4,8 +4,8 @@ #include "utils.h" #include #include "value.h" +#include "enviroment.h" //#include -//#include using namespace dms; //typedef void(*FNPTR)(); //using namespace std::chrono; @@ -15,12 +15,18 @@ using namespace dms; //} value print(void* self, dms_state* state, dms_args* args) { std::string str = ""; - for (size_t i = 0; i < args->args.size()-1; i++) { + for (size_t i = 0; i < args->args.size(); i++) { str += args->args[i].getPrintable() + "\t"; } printf((str + "\n").c_str()); return NULL; } +value type(void* self, dms_state* state, dms_args* args) { + if (args->size() > 0) { + return datatype[args->args[0].type]; + } + return "nil"; +} //value concat(void* self, dms_state* state, dms_args* args) { // std::stringstream str; // for (size_t i = 0; i < args->size() - 1; i++) @@ -33,10 +39,12 @@ int main() system_clock::now().time_since_epoch() ); utils::print(ms.count());*/ - + enviroment* envio = new enviroment; LineParser parser = LineParser("test.dms"); dms_state* state = parser.Parse(); + envio->registerFunction("print", print); state->invoker.registerFunction("print", print); + state->injectEnv("io",envio); state->dump(); state->run(); diff --git a/DMS/DMS.vcxproj b/DMS/DMS.vcxproj index d8d205e..80d8a29 100644 --- a/DMS/DMS.vcxproj +++ b/DMS/DMS.vcxproj @@ -130,6 +130,7 @@ Console true C:\includes\include;%(AdditionalLibraryDirectories) + 4194304 diff --git a/DMS/LineParser.h b/DMS/LineParser.h index 423bba5..dc7b13a 100644 --- a/DMS/LineParser.h +++ b/DMS/LineParser.h @@ -17,6 +17,7 @@ #include "comparisons.h" namespace dms { + struct value; struct tokenstream { tokenstream(); tokenstream(std::vector*); @@ -104,6 +105,7 @@ namespace dms { // Utils std::string random_string(std::size_t length); + value stov(std::string); bool manageCount(bool cond, size_t c,size_t&); bool notBalanced(std::vector ts, size_t last_line, tokenstream* stream, std::string o, std::string c); diff --git a/DMS/LineParserMatchProcess.cpp b/DMS/LineParserMatchProcess.cpp index 40fff82..a1cb41a 100644 --- a/DMS/LineParserMatchProcess.cpp +++ b/DMS/LineParserMatchProcess.cpp @@ -222,7 +222,7 @@ namespace dms { v.type = datatypes::variable; cmd* c = new cmd; c->opcode = codes::COMP; - c->args.push(value((double)cmp)); + c->args.push(value((int)cmp)); c->args.push(var); c->args.push(left); c->args.push(right); @@ -793,8 +793,6 @@ namespace dms { std::vector t = stream->next(tokens::parao, tokens::parac); // Consume and get tokens if (notBalanced(t, last_line, stream, "(", ")")) return false; - t.pop_back(); - tokenstream tempstream(&t); if (t.size() == 1) { // No arg function! current_chunk->addCmd(c); return true; @@ -802,34 +800,42 @@ namespace dms { token end = t.back(); t.pop_back(); t.push_back(token{ tokens::seperator,codes::NOOP,"",t[0].line_num }); - t.push_back(token{ tokens::nil,codes::NOOP,"",t[0].line_num }); + t.push_back(token{ tokens::escape,codes::NOOP,"",t[0].line_num }); t.push_back(end); - tempstream.init(&t); // Turn tokens we consumed into a tokenstream + tokenstream tempstream(&t); value tempval; token tok; value ref = value(datatypes::variable); // This part we add values to the opcodes for the bytecode FUNC val a1 a2 a3 ... an while (tempstream.peek().type != tokens::none) { // End of stream debugInvoker(stream); + //utils::debug(stream->peek()); tempval = value(datatypes::variable); - tok = tempstream.peek(); if (tempstream.match(tokens::seperator)) { // We have a seperator for function arguments tempstream.next(); // Consume it } + else if (tempstream.match(tokens::escape)) { + c->args.push(value(datatypes::escape)); + tempstream.next(); + } else if (match_process_standard(&tempstream, tempval)) { c->args.push(tempval); } else if (tempstream.match(tokens::newline)) { tempstream.next(); } + else if (tempstream.match(tokens::parac)) { + tempstream.next(); + current_chunk->addCmd(c); // We push this onto the chunk after all dependants if any have been handled + return true; + } else { + //utils::debug(tempstream.peek()); badSymbol(&tempstream); + return false; } } - tempstream.next(); - current_chunk->addCmd(c); // We push this onto the chunk after all dependants if any have been handled - //lastCall.pop(); return true; } return false; @@ -913,7 +919,7 @@ namespace dms { c->opcode = codes::EXIT; if (stream->match(tokens::number) || stream->match(tokens::name)) { if(stream->match(tokens::number)){ - c->args.push(value(std::stod(stream->next().name))); + c->args.push(stov(stream->next().name)); } else { c->args.push(value(stream->next().name,datatypes::variable)); @@ -972,6 +978,7 @@ namespace dms { } else { badSymbol(stream); + return false; } } else { @@ -1062,6 +1069,7 @@ namespace dms { } else { badSymbol(stream); + return false; } } } @@ -1070,14 +1078,14 @@ namespace dms { bool LineParser::match_process_number(tokenstream* stream, value& v) { if (stream->match(tokens::number)) { - v.set(std::stod(stream->next().name)); - v.type = datatypes::number; + v.set(stov(stream->next().name)); return true; } else if (stream->match(tokens::minus, tokens::number)) { stream->next(); - v.set(-std::stod(stream->next().name)); - v.type = datatypes::number; + v.set(stov(stream->next().name)); + v.i = -v.i; + v.n = -v.n; return true; } return false; @@ -1102,11 +1110,11 @@ namespace dms { temp.push_back(value(ts.next().name)); } else if (ts.match(tokens::number)) { - temp.push_back(value(std::stod(ts.next().name))); + temp.push_back(stov(stream->next().name)); } else if (ts.match(tokens::minus,tokens::number)) { ts.next(); - temp.push_back(value(-std::stod(ts.next().name))); + temp.push_back(stov(stream->next().name)); } else if (ts.match(tokens::True)) { temp.push_back(value(true)); @@ -1236,6 +1244,7 @@ namespace dms { } else { badSymbol(&ts); + return false; } } if (temp.size() >= 1) { @@ -1340,10 +1349,12 @@ namespace dms { } else { badSymbol(stream); + return false; } } else { badSymbol(stream); + return false; } } return false; // TODO finish this @@ -1401,6 +1412,7 @@ namespace dms { } else { badSymbol(stream); + return false; } } return false; @@ -1454,11 +1466,14 @@ namespace dms { left = tmpvalue; else if (right.isNil()) right = tmpvalue; - else + else { badSymbol(stream); + return false; + } } else { badSymbol(stream); + return false; } // Take that temp value and set it to left or right TODO finish this } @@ -1466,8 +1481,10 @@ namespace dms { hasOP = true; if (op == codes::NOOP) op = codes::ADD; - else + else { badSymbol(stream); + return false; + } stream->next(); } else if (stream->match(tokens::minus)) { @@ -1477,40 +1494,50 @@ namespace dms { } if (op == codes::NOOP) op = codes::SUB; - else + else { badSymbol(stream); + return false; + } stream->next(); } else if (stream->match(tokens::multiply)) { hasOP = true; if (op == codes::NOOP) op = codes::MUL; - else + else { badSymbol(stream); + return false; + } stream->next(); } else if (stream->match(tokens::divide)) { hasOP = true; if (op == codes::NOOP) op = codes::DIV; - else + else { badSymbol(stream); + return false; + } stream->next(); } else if (stream->match(tokens::percent)) { hasOP = true; if (op == codes::NOOP) op = codes::MOD; - else + else { badSymbol(stream); + return false; + } stream->next(); } else if (stream->match(tokens::caret)) { hasOP = true; if (op == codes::NOOP) op = codes::POW; - else + else { badSymbol(stream); + return false; + } stream->next(); } else if (stream->match(tokens::name,tokens::parao)) { @@ -1521,29 +1548,35 @@ namespace dms { left = tmpvalue; else if (right.isNil()) right = tmpvalue; - else + else { badSymbol(stream); + return false; + } } else { badSymbol(stream); + return false; } } else if (stream->match(tokens::number)) { - double num = std::stod(stream->next().name); if (left.isNil()) - left = value(num); + left = stov(stream->next().name); else if (right.isNil()) - right = value(num); - else + right = stov(stream->next().name); + else { badSymbol(stream); + return false; + } } else if (stream->match(tokens::string)) { if (left.isNil()) left = value(stream->next().name,string); else if (right.isNil()) right = value(stream->next().name, string); - else + else { badSymbol(stream); + return false; + } } else if (stream->match(tokens::name)) { // We tested functions already! So if that fails and we have a name then... we have a variable lets handle this! @@ -1551,8 +1584,10 @@ namespace dms { left = value(stream->next().name,datatypes::variable); else if (right.isNil()) right = value(stream->next().name,datatypes::variable); - else + else { badSymbol(stream); + return false; + } } else if (stream->match(tokens::newline) || stream->match(tokens::parac) || stream->match(tokens::seperator)) { if (wv.isNil()) diff --git a/DMS/LineParserUtils.cpp b/DMS/LineParserUtils.cpp index 874d363..57a09ad 100644 --- a/DMS/LineParserUtils.cpp +++ b/DMS/LineParserUtils.cpp @@ -145,6 +145,13 @@ namespace dms { return random_string; } + value LineParser::stov(std::string s) + { + if (s.find('.')<=s.size()) { + return value(std::stod(s)); + } + return value(std::stoi(s)); + } bool LineParser::manageCount(bool cond, size_t c, size_t& count) { if (cond && c!=0) { @@ -263,13 +270,12 @@ namespace dms { if (state->isEnabled("debugging") && stream->peek().type != tokens::newline) { // A very nasty if statement, I won't hide it, this could be made much more readable // This checks if the last cmd is a LINE cmd and if its the same line number as the current one we simply skip it - if (current_chunk->cmds.size() >= 2 && current_chunk->cmds[current_chunk->cmds.size() - 1]!=nullptr && current_chunk->cmds[current_chunk->cmds.size() - 1]->opcode==codes::LINE && (size_t)current_chunk->cmds[current_chunk->cmds.size()-1]->args.args[0].n== (size_t)stream->peek().line_num) { + if (current_chunk->cmds.size() >= 2 && current_chunk->cmds[current_chunk->cmds.size() - 1]!=nullptr && current_chunk->cmds[current_chunk->cmds.size() - 1]->opcode==codes::LINE && (size_t)current_chunk->cmds[current_chunk->cmds.size()-1]->args.args[0].i== (size_t)stream->peek().line_num) { return; } - int current_line = (int)stream->peek().line_num; cmd* ln = new cmd; ln->opcode = codes::LINE; - ln->args.push(value(current_line)); + ln->args.push(stream->peek().line_num); current_chunk->addCmd(ln); } } diff --git a/DMS/dms_state.cpp b/DMS/dms_state.cpp index e0acd86..51405cf 100644 --- a/DMS/dms_state.cpp +++ b/DMS/dms_state.cpp @@ -139,6 +139,21 @@ namespace dms { return false; } + bool dms_state::injectEnv(std::string name, enviroment* env) + { + std::string ename = std::string("$ENV_") + name; + assign(value(name, datatypes::variable), value(ename, datatypes::block)); + environments.insert_or_assign(ename, env); + chunk* c = new chunk; + c->type = bt_env; + c->name = ename; + cmd* cc = new cmd; + cc->opcode = codes::NOOP; + c->addCmd(cc); + push_chunk(ename,c); + return false; + } + bool dms_state::assign(value var, value val) { if (val.type == datatypes::error) { (*getMem())[var.getPrintable()] = val; diff --git a/DMS/dms_state.h b/DMS/dms_state.h index de48ad3..5a221f2 100644 --- a/DMS/dms_state.h +++ b/DMS/dms_state.h @@ -57,6 +57,7 @@ namespace dms { character* getCharacter(std::string c); enviroment* getEnvironment(std::string c); + bool injectEnv(std::string, enviroment*); bool assign(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); diff --git a/DMS/dms_state_interpret.cpp b/DMS/dms_state_interpret.cpp index 96c857c..ca6b182 100644 --- a/DMS/dms_state_interpret.cpp +++ b/DMS/dms_state_interpret.cpp @@ -254,10 +254,14 @@ namespace dms { break; case OFUN: { - std::string obj = c->args.args[0].getPrintable(); + std::string obj = c->args.args[0].resolve(this).getPrintable(); + if (obj=="nil") { + obj = c->args.args[0].getPrintable(); + } std::string funcname = c->args.args[1].getPrintable(); value assn = c->args.args[2]; dms_args args; + for (int i = 3; i < c->args.args.size(); i++) { args.push(c->args.args[i]); } @@ -458,47 +462,47 @@ namespace dms { break; case COMP: { - comp cmp = (comp)c->args.args[0].n; + comp cmp = (comp)c->args.args[0].i; value assn = c->args.args[1]; value left = c->args.args[2].resolve(this); value right = c->args.args[3].resolve(this); switch (cmp) { case comp::eq: { - if(!assign(assn, value(left == right))) { + if(!assign(assn, left == right)) { return false; } break; } case comp::gt: { if (left.isNil() || right.isNil()) {push_error(errors::error{ errors::unknown ,"Attempt to compare a nil value!" });return false;} - if(!assign(assn, value(left > right))) { + if(!assign(assn, left > right)) { return false; } break; } case comp::gteq: { if (left.isNil() || right.isNil()) { push_error(errors::error{ errors::unknown ,"Attempt to compare a nil value!" }); return false; } - if(!assign(assn, value(left >= right))) { + if(!assign(assn, left >= right)) { return false; } break; } case comp::lt: { if (left.isNil() || right.isNil()) { push_error(errors::error{ errors::unknown ,"Attempt to compare a nil value!" }); return false; } - if(!assign(assn, value(left < right))) { + if(!assign(assn, left < right)) { return false; } break; } case comp::lteq: { if (left.isNil() || right.isNil()) { push_error(errors::error{ errors::unknown ,"Attempt to compare a nil value!" }); return false; } - if(!assign(assn, value(left <= right))) { + if(!assign(assn, left <= right)) { return false; } break; } case comp::nteq: { - if(!assign(assn, value(left != right))) { + if(!assign(assn, left != right)) { return false; } break; @@ -551,7 +555,7 @@ namespace dms { } break; case LINE: - cur_line = (size_t)c->args.args[0].n; + cur_line = (size_t)c->args.args[0].i; break; case NOOP: break; diff --git a/DMS/dump.bin b/DMS/dump.bin index b3dcc70..e362c2c 100644 Binary files a/DMS/dump.bin and b/DMS/dump.bin differ diff --git a/DMS/dump.txt b/DMS/dump.txt index 10386fc..a282287 100644 --- a/DMS/dump.txt +++ b/DMS/dump.txt @@ -21,6 +21,9 @@ Line <6> name savestate Line <6> newline Line <6> newline Line <7> newline +Line <8> flag +Line <8> name debugging +Line <8> newline Line <8> newline Line <9> newline Line <10> flag @@ -36,172 +39,131 @@ Line <12> name main Line <12> bracketc ] Line <12> newline Line <12> newline -Line <13> control -Line <13> string New Choice Test -Line <13> cbracketo { +Line <13> name num +Line <13> equal = +Line <13> number 30.0 Line <13> newline Line <13> newline -Line <14> string Option 1 +Line <14> name io +Line <14> dot . Line <14> name print Line <14> parao ( +Line <14> string ! +Line <14> plus + +Line <14> name num +Line <14> plus + +Line <14> string = +Line <14> plus + Line <14> name fact Line <14> parao ( -Line <14> string Hi! +Line <14> name num Line <14> parac ) Line <14> parac ) Line <14> newline Line <14> newline -Line <15> string Option 2 -Line <15> gotoo -Line <15> string test Line <15> newline Line <15> newline -Line <16> string Option 3 -Line <16> cbracketo { +Line <16> bracketo [ +Line <16> name fact +Line <16> colon : +Line <16> name function +Line <16> parao ( +Line <16> name n +Line <16> parac ) +Line <16> bracketc ] Line <16> newline Line <16> newline -Line <17> name print +Line <17> name if Line <17> parao ( -Line <17> string Yes this works! +Line <17> name n +Line <17> equal = +Line <17> equal = +Line <17> number 1 Line <17> parac ) Line <17> newline Line <17> newline -Line <18> name print -Line <18> parao ( -Line <18> string Are you happy? -Line <18> parac ) +Line <18> ret +Line <18> number 1 Line <18> newline Line <18> newline -Line <19> cbracketc } +Line <19> name else Line <19> newline Line <19> newline -Line <20> cbracketc } +Line <20> ret +Line <20> name n +Line <20> multiply * +Line <20> name fact +Line <20> parao ( +Line <20> name n +Line <20> minus - +Line <20> number 1 +Line <20> parac ) Line <20> newline Line <20> newline -Line <21> gotoo -Line <21> string end Line <21> newline Line <21> newline -Line <22> label test +Line <22> bracketo [ +Line <22> name this +Line <22> colon : +Line <22> name function +Line <22> parao ( +Line <22> parac ) +Line <22> bracketc ] Line <22> newline Line <22> newline Line <23> name print Line <23> parao ( -Line <23> string Here! +Line <23> string This Line <23> parac ) Line <23> newline Line <23> newline -Line <24> label end Line <24> newline Line <24> newline +Line <25> bracketo [ +Line <25> name that +Line <25> colon : +Line <25> name function +Line <25> parao ( +Line <25> parac ) +Line <25> bracketc ] Line <25> newline Line <25> newline -Line <26> bracketo [ -Line <26> name fact -Line <26> colon : -Line <26> name function +Line <26> name print Line <26> parao ( -Line <26> name n +Line <26> string That Line <26> parac ) -Line <26> bracketc ] Line <26> newline Line <26> newline -Line <27> name if -Line <27> parao ( -Line <27> name n -Line <27> equal = -Line <27> equal = -Line <27> number 1 -Line <27> or -Line <27> name n -Line <27> equal = -Line <27> equal = -Line <27> number 0 -Line <27> parac ) Line <27> newline Line <27> newline -Line <28> ret -Line <28> number 1 +Line <28> bracketo [ +Line <28> name Bob +Line <28> colon : +Line <28> name char +Line <28> bracketc ] Line <28> newline Line <28> newline -Line <29> name else Line <29> newline -Line <29> newline -Line <30> ret -Line <30> name n -Line <30> multiply * -Line <30> name fact -Line <30> parao ( -Line <30> name n -Line <30> minus - -Line <30> number 1 -Line <30> parac ) -Line <30> newline Line <30> newline Line <31> newline -Line <31> newline -Line <32> bracketo [ -Line <32> name this -Line <32> colon : -Line <32> name function -Line <32> parao ( -Line <32> parac ) -Line <32> bracketc ] +Line <32> name unknown +Line <32> equal = +Line <32> string Some Random Guy Line <32> newline Line <32> newline -Line <33> name print -Line <33> parao ( -Line <33> string This -Line <33> parac ) +Line <33> name age +Line <33> equal = +Line <33> number 0.24 Line <33> newline Line <33> newline +Line <34> name money +Line <34> equal = +Line <34> number 100 Line <34> newline Line <34> newline -Line <35> bracketo [ -Line <35> name that +Line <35> name excited Line <35> colon : -Line <35> name function -Line <35> parao ( -Line <35> parac ) -Line <35> bracketc ] +Line <35> string path/to/file Line <35> newline Line <35> newline -Line <36> name print -Line <36> parao ( -Line <36> string That -Line <36> parac ) -Line <36> newline -Line <36> newline -Line <37> newline -Line <37> newline -Line <38> bracketo [ -Line <38> name Bob -Line <38> colon : -Line <38> name char -Line <38> bracketc ] -Line <38> newline -Line <38> newline -Line <39> newline -Line <40> newline -Line <41> newline -Line <42> name unknown -Line <42> equal = -Line <42> string Some Random Guy -Line <42> newline -Line <42> newline -Line <43> name age -Line <43> equal = -Line <43> number 0.24 -Line <43> newline -Line <43> newline -Line <44> name money -Line <44> equal = -Line <44> number 100 -Line <44> newline -Line <44> newline -Line <45> name excited -Line <45> colon : -Line <45> string path/to/file -Line <45> newline -Line <45> newline -Line <45> eof +Line <35> eof diff --git a/DMS/dump_bin.txt b/DMS/dump_bin.txt deleted file mode 100644 index 421c9a3..0000000 Binary files a/DMS/dump_bin.txt and /dev/null differ diff --git a/DMS/test.dms b/DMS/test.dms index 8ab30d5..231f359 100644 --- a/DMS/test.dms +++ b/DMS/test.dms @@ -5,26 +5,16 @@ enable fullname enable forwardlabels // Do most of your labels exist ahead? enable savestate //enable leaking -//enable debugging +enable debugging //loadfile "loadtest.dms" version 0.2 using extendedDefine [main] - choice "New Choice Test" { - "Option 1" print(fact("Hi!")) - "Option 2" goto "test" - "Option 3" { - print("Yes this works!") - print("Are you happy?") - } - } - goto "end" - ::test:: - print("Here!") - ::end:: + num = 30.0 + io.print("!"+num+" = " + fact(num)) [fact:function(n)] - if(n==1 or n==0) + if(n==1) return 1 else return n * fact(n-1) diff --git a/DMS/value.cpp b/DMS/value.cpp index a25edb0..75b87f2 100644 --- a/DMS/value.cpp +++ b/DMS/value.cpp @@ -2,9 +2,9 @@ #include "dms_state.h" #include "utils.h" namespace dms { - const std::string datatype[] = { "escape", "nil", "number", "boolean", "env", "string", "custom", "variable", "block" , "error"}; + const std::string datatype[] = { "escape", "nil", "number", "int", "boolean", "env", "string", "custom", "variable", "block" , "error"}; value::value() { - // Nothing to do here yet! + // Nothing to do here! } value::value(char const* str, datatypes t) { type = t; @@ -15,13 +15,17 @@ namespace dms { s = str; } value::value(size_t val) { - type = datatypes::number; - n = val; + type = datatypes::int64; + i = val; } value::value(std::string str) { type = datatypes::string; s = str; } + value::value(int64_t n) { + type = datatypes::int64; + i = n; + } value::value(std::string str,datatypes t) { type = t; s = str; @@ -31,8 +35,8 @@ namespace dms { n = d; } value::value(int d) { - type = datatypes::number; - n = d; + type = datatypes::int64; + i = d; } value::value(bool bo) { type = datatypes::boolean; @@ -73,6 +77,9 @@ namespace dms { case datatypes::number: n = other.n; break; + case datatypes::int64: + i = other.i; + break; case datatypes::string: s = other.s; break; @@ -112,6 +119,9 @@ namespace dms { case datatypes::number: n = other.n; break; + case datatypes::int64: + i = other.i; + break; case datatypes::string: s = other.s; break; @@ -128,7 +138,7 @@ namespace dms { // by convention, always return *this return *this; } - bool value::isNil() { + bool value::isNil() const { return type == datatypes::nil; } value& value::operator=(const value& other) { @@ -157,6 +167,9 @@ namespace dms { case datatypes::number: n = other.n; break; + case datatypes::int64: + i = other.i; + break; case datatypes::string: s = other.s; break; @@ -172,6 +185,10 @@ namespace dms { // by convention, always return *this return *this; } + bool value::isNum() const + { + return (type == datatypes::number || type == datatypes::int64); + } bool operator==(const value& lhs, const value& rhs) { return lhs.getPrintable() == rhs.getPrintable(); } @@ -182,6 +199,15 @@ namespace dms { else if (lhs.type == datatypes::number && rhs.type == datatypes::number) { return value(lhs.n + rhs.n); } + else if (lhs.type == datatypes::int64 && rhs.type == datatypes::number) { + return value(lhs.i + rhs.n); + } + else if (lhs.type == datatypes::int64 && rhs.type == datatypes::int64) { + return value(lhs.i + rhs.i); + } + else if (lhs.type == datatypes::number && rhs.type == datatypes::int64) { + return value(lhs.n + rhs.i); + } else if (lhs.type == datatypes::boolean && rhs.type == datatypes::boolean) { return value((bool)(lhs.b + rhs.b)); } @@ -196,6 +222,15 @@ namespace dms { if (lhs.type == datatypes::number && rhs.type == datatypes::number) { return value(lhs.n - rhs.n); } + else if (lhs.type == datatypes::int64 && rhs.type == datatypes::number) { + return value(lhs.i - rhs.n); + } + else if (lhs.type == datatypes::int64 && rhs.type == datatypes::int64) { + return value(lhs.i - rhs.i); + } + else if (lhs.type == datatypes::number && rhs.type == datatypes::int64) { + return value(lhs.n - rhs.i); + } else { if(lhs.type!=datatypes::number) return value(utils::concat("Attempted to perform arithmetic on a ", datatype[lhs.type] ," value!"),datatypes::error); @@ -207,6 +242,15 @@ namespace dms { if (lhs.type == datatypes::number && rhs.type == datatypes::number) { return value(lhs.n / rhs.n); } + else if (lhs.type == datatypes::int64 && rhs.type == datatypes::number) { + return value(lhs.i / rhs.n); + } + else if (lhs.type == datatypes::int64 && rhs.type == datatypes::int64) { + return value(lhs.i / rhs.i); + } + else if (lhs.type == datatypes::number && rhs.type == datatypes::int64) { + return value(lhs.n / rhs.i); + } else { if (lhs.type != datatypes::number) return value(utils::concat("Attempted to perform arithmetic on a ", datatype[lhs.type], " value!"), datatypes::error); @@ -218,6 +262,15 @@ namespace dms { if (lhs.type == datatypes::number && rhs.type == datatypes::number) { return value(lhs.n * rhs.n); } + else if (lhs.type == datatypes::int64 && rhs.type == datatypes::number) { + return value(lhs.i * rhs.n); + } + else if (lhs.type == datatypes::int64 && rhs.type == datatypes::int64) { + return value(lhs.i * rhs.i); + } + else if (lhs.type == datatypes::number && rhs.type == datatypes::int64) { + return value(lhs.n * rhs.i); + } else if (lhs.type == datatypes::boolean && rhs.type == datatypes::boolean) { return value((bool)(lhs.b * rhs.b)); } @@ -235,24 +288,60 @@ namespace dms { if (lhs.type == datatypes::number && rhs.type == datatypes::number) { return lhs.n > rhs.n; } + else if (lhs.type == datatypes::int64 && rhs.type == datatypes::number) { + return lhs.i > rhs.n; + } + else if (lhs.type == datatypes::int64 && rhs.type == datatypes::int64) { + return lhs.i > rhs.i; + } + else if (lhs.type == datatypes::number && rhs.type == datatypes::int64) { + return lhs.n > rhs.i; + } return false; } bool operator<(const value& lhs, const value& rhs) { if (lhs.type == datatypes::number && rhs.type == datatypes::number) { return lhs.n < rhs.n; } + else if (lhs.type == datatypes::int64 && rhs.type == datatypes::number) { + return lhs.i < rhs.n; + } + else if (lhs.type == datatypes::int64 && rhs.type == datatypes::int64) { + return lhs.i < rhs.i; + } + else if (lhs.type == datatypes::number && rhs.type == datatypes::int64) { + return lhs.n < rhs.i; + } return false; } bool operator>=(const value& lhs, const value& rhs) { if (lhs.type == datatypes::number && rhs.type == datatypes::number) { return lhs.n >= rhs.n; } + else if (lhs.type == datatypes::int64 && rhs.type == datatypes::number) { + return lhs.i >= rhs.n; + } + else if (lhs.type == datatypes::int64 && rhs.type == datatypes::int64) { + return lhs.i >= rhs.i; + } + else if (lhs.type == datatypes::number && rhs.type == datatypes::int64) { + return lhs.n >= rhs.i; + } return false; } bool operator<=(const value& lhs, const value& rhs) { if (lhs.type == datatypes::number && rhs.type == datatypes::number) { return lhs.n <= rhs.n; } + else if (lhs.type == datatypes::int64 && rhs.type == datatypes::number) { + return lhs.i <= rhs.n; + } + else if (lhs.type == datatypes::int64 && rhs.type == datatypes::int64) { + return lhs.i <= rhs.i; + } + else if (lhs.type == datatypes::number && rhs.type == datatypes::int64) { + return lhs.n <= rhs.i; + } return false; } value value::resolve(dms_state* state) { @@ -398,6 +487,9 @@ namespace dms { } return temp; } + else if (type == int64) { + return std::to_string(i); + } else if (type == nil) { return "nil"; } @@ -444,6 +536,9 @@ namespace dms { else if (c.type == number) { out << (char)c.type << c.n; } + else if (c.type == int64) { + out << (char)c.type << c.i; + } else if (c.type == nil) { out << (char)c.type << "nil"; } @@ -474,20 +569,14 @@ namespace dms { bool value::typeMatch(const value* o) const { return type == o->type; } - void value::set(value* val) { - if (type == datatypes::number) { - n = val->n; - } - else if (type == datatypes::string || type == datatypes::block || type == datatypes::variable) { - s = val->s; - } - else if (type == datatypes::boolean) { - b = val->b; - } - else { // Handle custom and env - return; - } - type = val->type; + void value::set(value val) { + type = val.type; + s = val.s; + n = val.n; + i = val.i; + b = val.b; + e = val.e; + c = val.c; } void value::set(std::string str) { nuke(); diff --git a/DMS/value.h b/DMS/value.h index 4754f79..8201cdb 100644 --- a/DMS/value.h +++ b/DMS/value.h @@ -11,7 +11,7 @@ namespace dms { struct dms_args; struct dms_state; extern const std::string datatype[]; - enum datatypes { escape, nil, number, boolean, env, string, custom, variable, block, error }; + enum datatypes { escape, nil, number, int64, boolean, env, string, custom, variable, block, error }; struct dms_number { double val; double getValue() { return val; } @@ -55,6 +55,7 @@ namespace dms { datatypes type = datatypes::nil; bool b=false; double n=0; + int64_t i=0; std::string s; dms_list* e = nullptr; dms_custom* c = nullptr; @@ -66,11 +67,13 @@ namespace dms { value(char const*); value(double); value(int); + value(int64_t); value(size_t); value(bool); ~value(); value(const value& other); - bool isNil(); + bool isNil() const; + bool isNum() const; value& operator=(value& other); value& operator=(const value& other); friend bool operator==(const value& lhs, const value& rhs); @@ -86,7 +89,7 @@ namespace dms { friend value operator*(const value& lhs, const value& rhs); value resolve(dms_state*); void nuke(); - void set(value*); + void set(value); void set(std::string str); void set(bool bo); void set(double num); diff --git a/README.md b/README.md index 115d394..5b11a34 100644 --- a/README.md +++ b/README.md @@ -7,4 +7,4 @@ The Dialogue Management Script's goal is to provide a nice and simple way to hav - [X] ~~Implement bytecode for concatenation~~ - [X] ~~Interpert all the bytecode~~ - [ ] Finish implementing custom datatype -- [ ] Speed up interperter \ No newline at end of file +- [ ] Speed up interperter