Better error handling

This commit is contained in:
Ryan Ward 2020-12-06 23:45:16 -05:00
parent 0bbb14dc06
commit 31da0b35eb
11 changed files with 293 additions and 181 deletions

View File

@ -5,7 +5,7 @@ using namespace dms::utils;
namespace dms { namespace dms {
bool LineParser::match_process_standard(tokenstream* stream, value& v) { bool LineParser::match_process_standard(tokenstream* stream, value& v) {
stream->chomp(newline); stream->chomp(newline);
utils::debug(stream->peek()); //utils::debug(stream->peek());
if (stream->peek().type == tokens::none) { if (stream->peek().type == tokens::none) {
return false; return false;
} }
@ -593,16 +593,22 @@ namespace dms {
else if (stream->match(tokens::string)) { else if (stream->match(tokens::string)) {
std::string name = stream->next().name; std::string name = stream->next().name;
c->args.push(value(name)); // We append the choice to the first part of the CHOI cmd c->args.push(value(name)); // We append the choice to the first part of the CHOI cmd
if (match_process_goto(stream)) {}
value val = value();
if (match_process_function(stream,val,false)) { // No returns and also no nesting of functions!
// We cannot have a nested function here, but if we dont have that then we add our goto
hasfunc = true;
buildGoto(choicelabel);
}
else if (match_process_goto(stream)) {}
else if (match_process_jump(stream)) {} else if (match_process_jump(stream)) {}
else if (match_process_exit(stream)) {} else if (match_process_exit(stream)) {}
else if (match_process_scope(stream)) {
buildGoto(choicelabel);
}
else {
badSymbol(stream);
}
//value val = value();
//if (match_process_function(stream,val,false)) { // No returns and also no nesting of functions!
// // We cannot have a nested function here, but if we dont have that then we add our goto
// hasfunc = true;
//
//}
} }
// Last Match // Last Match
else if (stream->match(tokens::newline)) { else if (stream->match(tokens::newline)) {
@ -612,12 +618,11 @@ namespace dms {
badSymbol(stream); badSymbol(stream);
} }
} }
buildGoto(choicelabel);
cmd* cc = current_chunk->cmds.back(); // Delete last element cmd* cc = current_chunk->cmds.back(); // Delete last element
current_chunk->cmds.pop_back(); current_chunk->cmds.pop_back();
delete cc; delete cc;
if (hasfunc)
buildLabel(choicelabel); buildLabel(choicelabel);
stream->next(); // Remove the last bracket!
return true; return true;
} }
return false; return false;
@ -919,10 +924,7 @@ namespace dms {
} }
return false; return false;
} }
/*
We need to match {...}
This doesn't pass any varaible. It should be used to match and process program flow
*/
bool LineParser::match_process_scope(tokenstream* stream) { bool LineParser::match_process_scope(tokenstream* stream) {
if (stream->match(cbracketo)) { if (stream->match(cbracketo)) {
size_t last_line = stream->last().line_num; size_t last_line = stream->last().line_num;
@ -1095,7 +1097,7 @@ namespace dms {
std::vector<value> temp; std::vector<value> temp;
codes::op o; codes::op o;
while (ts.can()) { while (ts.can()) {
utils::debug(ts.peek()); //utils::debug(ts.peek());
if (ts.match(tokens::string)) { if (ts.match(tokens::string)) {
temp.push_back(value(ts.next().name)); temp.push_back(value(ts.next().name));
} }

View File

@ -348,6 +348,7 @@ namespace dms {
token current = token{tokentype::newline,codes::NOOP}; token current = token{tokentype::newline,codes::NOOP};
cmd* flagcmd = new cmd; cmd* flagcmd = new cmd;
value nil; value nil;
size_t last_pos = SIZE_MAX;
while (stream->peek().type != tokens::none) { while (stream->peek().type != tokens::none) {
if (stop) return false; if (stop) return false;
debugInvoker(stream); debugInvoker(stream);
@ -490,7 +491,8 @@ namespace dms {
} }
} }
// Control Handle all controls here // Control Handle all controls here
manageCount(match_process_while(stream),count,current_count); manageCount(match_process_choice(stream), count, current_count);
manageCount(match_process_while(stream), count, current_count);
manageCount(match_process_for(stream), count, current_count); manageCount(match_process_for(stream), count, current_count);
manageCount(match_process_IFFF(stream), count, current_count); manageCount(match_process_IFFF(stream), count, current_count);
// Let's handle function stuff! // Let's handle function stuff!
@ -521,9 +523,14 @@ namespace dms {
if (count != 0 && current_count == count) { if (count != 0 && current_count == count) {
return true; // We got what we came for, we exit and consume no more! return true; // We got what we came for, we exit and consume no more!
} }
if(stream->match(newline) || stream->match(eof)) if (last_pos == stream->pos) {
badSymbol(stream);
}
last_pos = stream->pos;
if (stream->match(newline) || stream->match(eof)) {
current = stream->next(); current = stream->next();
utils::debug(stream->peek()); }
} }
} }
void LineParser::_Parse(tokenstream* stream) { void LineParser::_Parse(tokenstream* stream) {

View File

@ -1,6 +1,37 @@
#include "dms_state.h" #include "dms_state.h"
#include "Handlers.h" #include "Handlers.h"
namespace dms { namespace dms {
value dms::blockInvoke(void* self, dms_state* state, dms_args* args) {
std::string func = state->call_stack.top();
if (state->functionExists(func)) {
state->call_stack.pop();
value ret;
state->pushMem();
memory* Fmem = state->getMem();
// Only the nil argument
if (args->args.size())
for (int i = 0; i < state->chunks[func]->params.args.size(); i++)
(*Fmem)[state->chunks[func]->params.args.at(i).getPrintable()] = args->args.at(i).resolve(state);
if (!state->run(func, Fmem)) {
std::vector<value> err = Fmem->examine(datatypes::error);
if (err.size() > 0)
state->push_error(errors::error{ errors::unknown ,err[0].s });
else
state->push_error(errors::error{ errors::unknown ,"Function Returned an error!" });
state->popMem();// We need to restore the stack
return value("Function returned an error", datatypes::error);
}
ret = state->return_stack.top();
state->return_stack.pop();
state->popMem();
return ret;
}
return value();
}
void dms_state::init() { void dms_state::init() {
if (init_init || stop) if (init_init || stop)
return; return;
@ -43,24 +74,6 @@ namespace dms {
void dms_state::popMem() { void dms_state::popMem() {
mem_stack.pop(); mem_stack.pop();
} }
value dms::blockInvoke(void* self, dms_state* state, dms_args* args) {
std::string func = state->call_stack.top();
if (state->functionExists(func)) {
state->call_stack.pop();
value ret;
state->pushMem();
memory* Fmem = state->getMem();
for (int i = 0; i < state->chunks[func]->params.args.size(); i++) {
(*Fmem)[state->chunks[func]->params.args[i].getPrintable()] = args->args[i].resolve(state);
}
state->run(func, Fmem);
ret = state->return_stack.top();
state->return_stack.pop();
state->popMem();
return ret;
}
return value();
}
dms_state::dms_state() { dms_state::dms_state() {
// We should define the defaults for the enables // We should define the defaults for the enables
pushMem(); // Main memory pushMem(); // Main memory
@ -127,6 +140,11 @@ namespace dms {
} }
bool dms_state::assign(value var, value val) { bool dms_state::assign(value var, value val) {
if (val.type == datatypes::error) {
(*getMem())[var.getPrintable()] = val;
push_error(errors::error{ errors::unknown ,val.s });
return false;
}
(*getMem())[var.getPrintable()] = val; (*getMem())[var.getPrintable()] = val;
return true; return true;
} }
@ -141,6 +159,8 @@ namespace dms {
chunks.insert_or_assign(s, c); chunks.insert_or_assign(s, c);
} }
void dms_state::push_error(errors::error err) { void dms_state::push_error(errors::error err) {
if (stop)
return;
if (err.linenum != 0) { if (err.linenum != 0) {
std::cout << err.err_msg << " On Line <" << err.linenum << ">" << std::endl; std::cout << err.err_msg << " On Line <" << err.linenum << ">" << std::endl;
} }

View File

@ -191,14 +191,20 @@ namespace dms {
value cmp = c->args.args[0]; value cmp = c->args.args[0];
if (cmp.resolve(this).type == datatypes::boolean || cmp.resolve(this).isNil()) { if (cmp.resolve(this).type == datatypes::boolean || cmp.resolve(this).isNil()) {
if (!cmp.resolve(this).b || cmp.resolve(this).isNil()) { if (!cmp.resolve(this).b || cmp.resolve(this).isNil()) {
assign(cmp, value(true)); if(!assign(cmp, value(true))) {
} return false;
else {
assign(cmp, value(false));
} }
} }
else { else {
assign(cmp, value(false)); if(!assign(cmp, value(false))) {
return false;
}
}
}
else {
if(!assign(cmp, value(false))) {
return false;
}
} }
break; break;
} }
@ -266,7 +272,9 @@ namespace dms {
if (ret.type == datatypes::error) if (ret.type == datatypes::error)
return false; return false;
if (assn.type != datatypes::nil) { if (assn.type != datatypes::nil) {
assign(assn, ret); if(!assign(assn, ret)) {
return false;
}
} }
} }
break; break;
@ -290,7 +298,9 @@ namespace dms {
if (ret.type == datatypes::error) if (ret.type == datatypes::error)
return false; return false;
if (assn.type != datatypes::nil) { if (assn.type != datatypes::nil) {
assign(assn, ret); if(!assign(assn, ret)) {
return false;
}
} }
} }
break; break;
@ -320,7 +330,7 @@ namespace dms {
} }
else if (env.type == datatypes::custom) { else if (env.type == datatypes::custom) {
env.c->NewIndex(indx, assn); env.c->NewIndex(indx, assn);
//assign( assn, env->c->Index(indx)); //if(!assign( assn, env->c->Index(indx));
// Call the method within the custom data // Call the method within the custom data
} }
break; break;
@ -330,8 +340,10 @@ namespace dms {
value assn = c->args.args[0]; value assn = c->args.args[0];
value o1 = c->args.args[1]; value o1 = c->args.args[1];
value o2 = c->args.args[2]; value o2 = c->args.args[2];
value ret = value(o1.resolve(this)+o2.resolve(this)); value ret = o1.resolve(this)+o2.resolve(this);
assign(assn, ret); if(!assign(assn, ret)) {
return false;
}
} }
break; break;
case SUB: case SUB:
@ -339,8 +351,10 @@ namespace dms {
value assn = c->args.args[0]; value assn = c->args.args[0];
value o1 = c->args.args[1]; value o1 = c->args.args[1];
value o2 = c->args.args[2]; value o2 = c->args.args[2];
value ret = value(o1.resolve(this) - o2.resolve(this)); value ret = o1.resolve(this) - o2.resolve(this);
assign(assn, ret); if(!assign(assn, ret)) {
return false;
}
} }
break; break;
case MUL: case MUL:
@ -348,8 +362,10 @@ namespace dms {
value assn = c->args.args[0]; value assn = c->args.args[0];
value o1 = c->args.args[1]; value o1 = c->args.args[1];
value o2 = c->args.args[2]; value o2 = c->args.args[2];
value ret = value(o1.resolve(this) * o2.resolve(this)); value ret = o1.resolve(this) * o2.resolve(this);
assign(assn, ret); if(!assign(assn, ret)) {
return false;
}
} }
break; break;
case DIV: case DIV:
@ -357,8 +373,10 @@ namespace dms {
value assn = c->args.args[0]; value assn = c->args.args[0];
value o1 = c->args.args[1]; value o1 = c->args.args[1];
value o2 = c->args.args[2]; value o2 = c->args.args[2];
value ret = value(o1.resolve(this) / o2.resolve(this)); value ret = o1.resolve(this) / o2.resolve(this);
assign(assn, ret); if(!assign(assn, ret)) {
return false;
}
} }
break; break;
case POW: case POW:
@ -366,8 +384,10 @@ namespace dms {
value assn = c->args.args[0]; value assn = c->args.args[0];
value o1 = c->args.args[1]; value o1 = c->args.args[1];
value o2 = c->args.args[2]; value o2 = c->args.args[2];
value ret = value(pow(o1.resolve(this).n, o2.resolve(this).n)); value ret = pow(o1.resolve(this).n, o2.resolve(this).n);
assign(assn, ret); if(!assign(assn, ret)) {
return false;
}
} }
break; break;
case MOD: case MOD:
@ -375,8 +395,10 @@ namespace dms {
value assn = c->args.args[0]; value assn = c->args.args[0];
value o1 = c->args.args[1]; value o1 = c->args.args[1];
value o2 = c->args.args[2]; value o2 = c->args.args[2];
value ret = value(std::fmod(o1.resolve(this).n,o2.resolve(this).n)); value ret = std::fmod(o1.resolve(this).n,o2.resolve(this).n);
assign(assn, ret); if(!assign(assn, ret)) {
return false;
}
} }
break; break;
case INDX: case INDX:
@ -392,11 +414,15 @@ namespace dms {
else if (characters.count(env.getPrintable())) { else if (characters.count(env.getPrintable())) {
e = characters[env.getPrintable()]; e = characters[env.getPrintable()];
} }
assign( assn, e->values[indx.getPrintable()]); if(!assign( assn, e->values[indx.getPrintable()])) {
return false;
}
} }
else if (env.type == datatypes::env) { else if (env.type == datatypes::env) {
if (indx.type == datatypes::number) { if (indx.type == datatypes::number) {
assign( assn, env.e->getValue(indx)); if(!assign( assn, env.e->getValue(indx))) {
return false;
}
} }
else { else {
push_error(errors::error{ errors::invalid_type ,concat("Expected a number value got ",datatype[indx.type]) }); push_error(errors::error{ errors::invalid_type ,concat("Expected a number value got ",datatype[indx.type]) });
@ -404,7 +430,9 @@ namespace dms {
} }
} }
else if (env.type == datatypes::custom) { else if (env.type == datatypes::custom) {
assign( assn, env.c->Index(indx)); if(!assign( assn, env.c->Index(indx))) {
return false;
}
// Call the method within the custom data // Call the method within the custom data
} }
} }
@ -417,7 +445,9 @@ namespace dms {
env->hpart["$size"] = c->args.args[1]; env->hpart["$size"] = c->args.args[1];
value val = new value; value val = new value;
val.set(env); val.set(env);
assign(c->args.args[0], val); if(!assign(c->args.args[0], val)) {
return false;
}
} }
break; break;
case INST: case INST:
@ -434,31 +464,43 @@ namespace dms {
value right = c->args.args[3].resolve(this); value right = c->args.args[3].resolve(this);
switch (cmp) { switch (cmp) {
case comp::eq: { case comp::eq: {
assign(assn, value(left == right)); if(!assign(assn, value(left == right))) {
return false;
}
break; break;
} }
case comp::gt: { case comp::gt: {
if (left.isNil() || right.isNil()) {push_error(errors::error{ errors::unknown ,"Attempt to compare a nil value!" });return false;} if (left.isNil() || right.isNil()) {push_error(errors::error{ errors::unknown ,"Attempt to compare a nil value!" });return false;}
assign(assn, value(left > right)); if(!assign(assn, value(left > right))) {
return false;
}
break; break;
} }
case comp::gteq: { case comp::gteq: {
if (left.isNil() || right.isNil()) { push_error(errors::error{ errors::unknown ,"Attempt to compare a nil value!" }); return false; } if (left.isNil() || right.isNil()) { push_error(errors::error{ errors::unknown ,"Attempt to compare a nil value!" }); return false; }
assign(assn, value(left >= right)); if(!assign(assn, value(left >= right))) {
return false;
}
break; break;
} }
case comp::lt: { case comp::lt: {
if (left.isNil() || right.isNil()) { push_error(errors::error{ errors::unknown ,"Attempt to compare a nil value!" }); return false; } if (left.isNil() || right.isNil()) { push_error(errors::error{ errors::unknown ,"Attempt to compare a nil value!" }); return false; }
assign(assn, value(left < right)); if(!assign(assn, value(left < right))) {
return false;
}
break; break;
} }
case comp::lteq: { case comp::lteq: {
if (left.isNil() || right.isNil()) { push_error(errors::error{ errors::unknown ,"Attempt to compare a nil value!" }); return false; } if (left.isNil() || right.isNil()) { push_error(errors::error{ errors::unknown ,"Attempt to compare a nil value!" }); return false; }
assign(assn, value(left <= right)); if(!assign(assn, value(left <= right))) {
return false;
}
break; break;
} }
case comp::nteq: { case comp::nteq: {
assign(assn, value(left != right)); if(!assign(assn, value(left != right))) {
return false;
}
break; break;
} }
} }
@ -504,7 +546,9 @@ namespace dms {
return false; return false;
break; break;
case ASGN: case ASGN:
assign(c->args.args[0], c->args.args[1]); if(!assign(c->args.args[0], c->args.args[1])) {
return false;
}
break; break;
case LINE: case LINE:
cur_line = (size_t)c->args.args[0].n; cur_line = (size_t)c->args.args[0].n;

Binary file not shown.

View File

@ -36,172 +36,172 @@ Line <12> name main
Line <12> bracketc ] Line <12> bracketc ]
Line <12> newline Line <12> newline
Line <12> newline Line <12> newline
Line <13> name a Line <13> control
Line <13> equal = Line <13> string New Choice Test
Line <13> number 0 Line <13> cbracketo {
Line <13> newline Line <13> newline
Line <13> newline Line <13> newline
Line <14> name while Line <14> string Option 1
Line <14> name print
Line <14> parao ( Line <14> parao (
Line <14> true true Line <14> name fact
Line <14> parao (
Line <14> string Hi!
Line <14> parac )
Line <14> parac ) Line <14> parac )
Line <14> newline Line <14> newline
Line <14> newline Line <14> newline
Line <15> name asm Line <15> string Option 2
Line <15> cbracketo { Line <15> gotoo
Line <15> string test
Line <15> newline Line <15> newline
Line <15> newline Line <15> newline
Line <16> name add Line <16> string Option 3
Line <16> mod % Line <16> cbracketo {
Line <16> name a
Line <16> mod %
Line <16> name a
Line <16> number 1
Line <16> newline Line <16> newline
Line <16> newline Line <16> newline
Line <17> name func
Line <17> mod %
Line <17> name print Line <17> name print
Line <17> nil Line <17> parao (
Line <17> mod % Line <17> string Yes this works!
Line <17> name a Line <17> parac )
Line <17> nil nil
Line <17> newline Line <17> newline
Line <17> newline Line <17> newline
Line <18> cbracketc } Line <18> name print
Line <18> parao (
Line <18> string Are you happy?
Line <18> parac )
Line <18> newline Line <18> newline
Line <18> newline Line <18> newline
Line <19> name while Line <19> cbracketc }
Line <19> parao (
Line <19> true true
Line <19> parac )
Line <19> cbracketo {
Line <19> newline Line <19> newline
Line <19> newline Line <19> newline
Line <20> name a Line <20> cbracketc }
Line <20> equal =
Line <20> name a
Line <20> plus +
Line <20> number 1
Line <20> newline Line <20> newline
Line <20> newline Line <20> newline
Line <21> name print Line <21> gotoo
Line <21> parao ( Line <21> string end
Line <21> name a
Line <21> parac )
Line <21> newline Line <21> newline
Line <21> newline Line <21> newline
Line <22> cbracketc } Line <22> label test
Line <22> newline Line <22> newline
Line <22> newline Line <22> newline
Line <23> name print
Line <23> parao (
Line <23> string Here!
Line <23> parac )
Line <23> newline Line <23> newline
Line <23> newline Line <23> newline
Line <24> bracketo [ Line <24> label end
Line <24> name fact
Line <24> colon :
Line <24> name function
Line <24> parao (
Line <24> name n
Line <24> parac )
Line <24> bracketc ]
Line <24> newline Line <24> newline
Line <24> newline Line <24> newline
Line <25> name if
Line <25> parao (
Line <25> name n
Line <25> equal =
Line <25> equal =
Line <25> number 1
Line <25> or
Line <25> name n
Line <25> equal =
Line <25> equal =
Line <25> number 0
Line <25> parac )
Line <25> newline Line <25> newline
Line <25> newline Line <25> newline
Line <26> ret Line <26> bracketo [
Line <26> number 1 Line <26> name fact
Line <26> colon :
Line <26> name function
Line <26> parao (
Line <26> name n
Line <26> parac )
Line <26> bracketc ]
Line <26> newline Line <26> newline
Line <26> newline Line <26> newline
Line <27> name else 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 <27> newline Line <27> newline
Line <28> ret Line <28> ret
Line <28> name n
Line <28> multiply *
Line <28> name fact
Line <28> parao (
Line <28> name n
Line <28> minus -
Line <28> number 1 Line <28> number 1
Line <28> parac )
Line <28> newline Line <28> newline
Line <28> newline Line <28> newline
Line <29> name else
Line <29> newline Line <29> newline
Line <29> newline Line <29> newline
Line <30> bracketo [ Line <30> ret
Line <30> name this Line <30> name n
Line <30> colon : Line <30> multiply *
Line <30> name function Line <30> name fact
Line <30> parao ( Line <30> parao (
Line <30> name n
Line <30> minus -
Line <30> number 1
Line <30> parac ) Line <30> parac )
Line <30> bracketc ]
Line <30> newline Line <30> newline
Line <30> newline Line <30> newline
Line <31> name print
Line <31> parao (
Line <31> string This
Line <31> parac )
Line <31> newline Line <31> 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> newline Line <32> newline
Line <32> newline Line <32> newline
Line <33> bracketo [ Line <33> name print
Line <33> name that
Line <33> colon :
Line <33> name function
Line <33> parao ( Line <33> parao (
Line <33> string This
Line <33> parac ) Line <33> parac )
Line <33> bracketc ]
Line <33> newline Line <33> newline
Line <33> newline Line <33> newline
Line <34> name print
Line <34> parao (
Line <34> string That
Line <34> parac )
Line <34> newline Line <34> newline
Line <34> newline Line <34> newline
Line <35> bracketo [
Line <35> name that
Line <35> colon :
Line <35> name function
Line <35> parao (
Line <35> parac )
Line <35> bracketc ]
Line <35> newline Line <35> newline
Line <35> newline Line <35> newline
Line <36> bracketo [ Line <36> name print
Line <36> name Bob Line <36> parao (
Line <36> colon : Line <36> string That
Line <36> name char Line <36> parac )
Line <36> bracketc ]
Line <36> newline Line <36> newline
Line <36> newline Line <36> newline
Line <37> 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 <38> newline
Line <39> newline Line <39> newline
Line <40> name unknown
Line <40> equal =
Line <40> string Some Random Guy
Line <40> newline Line <40> newline
Line <40> newline
Line <41> name age
Line <41> equal =
Line <41> number 0.24
Line <41> newline Line <41> newline
Line <41> newline Line <42> name unknown
Line <42> name money
Line <42> equal = Line <42> equal =
Line <42> number 100 Line <42> string Some Random Guy
Line <42> newline Line <42> newline
Line <42> newline Line <42> newline
Line <43> name excited Line <43> name age
Line <43> colon : Line <43> equal =
Line <43> string path/to/file Line <43> number 0.24
Line <43> newline Line <43> newline
Line <43> newline Line <43> newline
Line <43> eof 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

View File

@ -1,9 +1,22 @@
#include "memory.h" #include "memory.h"
#include <vector>
#include <iostream> #include <iostream>
#include "utils.h"
namespace dms { namespace dms {
value& memory::operator[](std::string str) { value& memory::operator[](std::string str) {
return mem[str]; return mem[str];
} }
std::vector<value> memory::examine(datatypes dt)
{
std::vector<value> arr;
for (const auto& p : mem)
{
if (p.second.type == dt) {
arr.push_back(p.second);
}
}
return arr;
}
size_t memory::count(std::string str) { size_t memory::count(std::string str) {
return mem.count(str); return mem.count(str);
} }

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include <unordered_map> #include <unordered_map>
#include <string> #include <string>
#include <vector>
#include "value.h" #include "value.h"
namespace dms { namespace dms {
struct memory struct memory
@ -8,6 +9,7 @@ namespace dms {
size_t count(std::string); size_t count(std::string);
void erase(std::string); void erase(std::string);
value& operator[](std::string); value& operator[](std::string);
std::vector<value> examine(datatypes dt);
private: private:
std::unordered_map<std::string, value> mem; std::unordered_map<std::string, value> mem;
}; };

View File

@ -10,12 +10,18 @@ enable savestate
version 0.2 version 0.2
using extendedDefine using extendedDefine
[main] [main]
a=0 choice "New Choice Test" {
while(true) "Option 1" print(fact("Hi!"))
asm { "Option 2" goto "test"
add %a %a 1 "Option 3" {
func %print nil %a nil print("Yes this works!")
print("Are you happy?")
} }
}
goto "end"
::test::
print("Here!")
::end::
[fact:function(n)] [fact:function(n)]
if(n==1 or n==0) if(n==1 or n==0)

View File

@ -79,6 +79,8 @@ namespace dms {
case datatypes::variable: case datatypes::variable:
s = other.s; s = other.s;
break; break;
case datatypes::error:
s = other.s;
default: default:
break; break;
} }
@ -116,6 +118,8 @@ namespace dms {
case datatypes::variable: case datatypes::variable:
s = other.s; s = other.s;
break; break;
case datatypes::error:
s = other.s;
default: default:
break; break;
} }
@ -159,6 +163,8 @@ namespace dms {
case datatypes::variable: case datatypes::variable:
s = other.s; s = other.s;
break; break;
case datatypes::error:
s = other.s;
default: default:
break; break;
} }
@ -170,7 +176,10 @@ namespace dms {
return lhs.getPrintable() == rhs.getPrintable(); return lhs.getPrintable() == rhs.getPrintable();
} }
value operator+(const value& lhs, const value& rhs) { value operator+(const value& lhs, const value& rhs) {
if (lhs.type == datatypes::number && rhs.type == datatypes::number) { if (lhs.type == datatypes::nil || rhs.type == datatypes::nil) {
return value("Attempt to concat a nil value!",datatypes::error);
}
else if (lhs.type == datatypes::number && rhs.type == datatypes::number) {
return value(lhs.n + rhs.n); return value(lhs.n + rhs.n);
} }
else if (lhs.type == datatypes::boolean && rhs.type == datatypes::boolean) { else if (lhs.type == datatypes::boolean && rhs.type == datatypes::boolean) {
@ -180,7 +189,7 @@ namespace dms {
return lhs.getPrintable() + rhs.getPrintable(); return lhs.getPrintable() + rhs.getPrintable();
} }
else { else {
return "Invalid use of '+'"; return value("Invalid use of '+'!", datatypes::error);
} }
} }
value operator-(const value& lhs, const value& rhs) { value operator-(const value& lhs, const value& rhs) {
@ -188,7 +197,10 @@ namespace dms {
return value(lhs.n - rhs.n); return value(lhs.n - rhs.n);
} }
else { else {
return value(datatypes::error); if(lhs.type!=datatypes::number)
return value(utils::concat("Attempted to perform arithmetic on a ", datatype[lhs.type] ," value!"),datatypes::error);
else
return value(utils::concat("Attempted to perform arithmetic on a ", datatype[rhs.type], " value!"), datatypes::error);
} }
} }
value operator/(const value& lhs, const value& rhs) { value operator/(const value& lhs, const value& rhs) {
@ -196,7 +208,10 @@ namespace dms {
return value(lhs.n / rhs.n); return value(lhs.n / rhs.n);
} }
else { else {
return value(datatypes::error); if (lhs.type != datatypes::number)
return value(utils::concat("Attempted to perform arithmetic on a ", datatype[lhs.type], " value!"), datatypes::error);
else
return value(utils::concat("Attempted to perform arithmetic on a ", datatype[rhs.type], " value!"), datatypes::error);
} }
} }
value operator*(const value& lhs, const value& rhs) { value operator*(const value& lhs, const value& rhs) {
@ -207,7 +222,10 @@ namespace dms {
return value((bool)(lhs.b * rhs.b)); return value((bool)(lhs.b * rhs.b));
} }
else { else {
return value(datatypes::error); if (lhs.type != datatypes::number)
return value(utils::concat("Attempted to perform arithmetic on a ", datatype[lhs.type], " value!"), datatypes::error);
else
return value(utils::concat("Attempted to perform arithmetic on a ", datatype[rhs.type], " value!"), datatypes::error);
} }
} }
bool operator!=(const value& lhs, const value& rhs) { bool operator!=(const value& lhs, const value& rhs) {

View File

@ -3,8 +3,8 @@ The Dialogue Management Script's goal is to provide a nice and simple way to hav
# Todo # Todo
- [X] ~~Implement bytecode for if/else if/else statements~~ - [X] ~~Implement bytecode for if/else if/else statements~~
- [ ] Implement bytecode for for/~~while~~ loops - [X] ~~Implement bytecode for for/while loops~~
- [X] ~~Implement bytecode for concatenation~~ - [X] ~~Implement bytecode for concatenation~~
- [ ] Interpert all the bytecode - [X] ~~Interpert all the bytecode~~
- [ ] Finish implementing custom datatype - [ ] Finish implementing custom datatype
- [ ] Speed up interperter - [ ] Speed up interperter