A few more opcodes to finish

This commit is contained in:
Ryan Ward 2020-09-17 00:12:29 -04:00
parent 1465805a82
commit 36aeb4f85e
32 changed files with 451 additions and 286 deletions

View File

@ -147,6 +147,7 @@
<ClCompile Include="codes.cpp" /> <ClCompile Include="codes.cpp" />
<ClCompile Include="DMS.cpp" /> <ClCompile Include="DMS.cpp" />
<ClCompile Include="dms_state.cpp" /> <ClCompile Include="dms_state.cpp" />
<ClCompile Include="dms_state_interpret.cpp" />
<ClCompile Include="LineParserBuilds.cpp" /> <ClCompile Include="LineParserBuilds.cpp" />
<ClCompile Include="LineParserMatchProcess.cpp" /> <ClCompile Include="LineParserMatchProcess.cpp" />
<ClCompile Include="LineParserParse.cpp" /> <ClCompile Include="LineParserParse.cpp" />

View File

@ -63,6 +63,9 @@
<ClCompile Include="LineParserBuilds.cpp"> <ClCompile Include="LineParserBuilds.cpp">
<Filter>Source Files\DMS</Filter> <Filter>Source Files\DMS</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="dms_state_interpret.cpp">
<Filter>Source Files\DMS</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="value.h"> <ClInclude Include="value.h">

View File

@ -1,3 +1,21 @@
 LineParserMatchProcess.cpp  DMS.cpp
F:\VSCWorkspace\DMS\DMS\LineParserMatchProcess.cpp(803): warning C4715: 'dms::LineParser::match_process_expression': not all control paths return a value dms_state.cpp
dms_state_interpret.cpp
LineParserBuilds.cpp
LineParserMatchProcess.cpp
LineParserParse.cpp
string_utils.cpp
F:\VSCWorkspace\DMS\DMS\string_utils.cpp(9,45): warning C4244: 'initializing': conversion from 'double' to 'unsigned int', possible loss of data
F:\VSCWorkspace\DMS\DMS\string_utils.cpp(36,17): warning C4244: 'initializing': conversion from 'double' to 'size_t', possible loss of data
F:\VSCWorkspace\DMS\DMS\string_utils.cpp(37,16): warning C4244: 'initializing': conversion from 'double' to 'size_t', possible loss of data
F:\VSCWorkspace\DMS\DMS\string_utils.cpp(93,22): warning C4018: '<': signed/unsigned mismatch
F:\VSCWorkspace\DMS\DMS\string_utils.cpp(134,22): warning C4018: '<': signed/unsigned mismatch
F:\VSCWorkspace\DMS\DMS\string_utils.cpp(135,25): warning C4018: '<': signed/unsigned mismatch
LineParserUtils.cpp
number_utils.cpp
F:\VSCWorkspace\DMS\DMS\number_utils.cpp(21,21): warning C4018: '<': signed/unsigned mismatch
utils.cpp
value.cpp
Generating Code...
F:\VSCWorkspace\DMS\DMS\LineParserMatchProcess.cpp(773): warning C4715: 'dms::LineParser::match_process_expression': not all control paths return a value
DMS.vcxproj -> F:\VSCWorkspace\DMS\Debug\DMS.exe DMS.vcxproj -> F:\VSCWorkspace\DMS\Debug\DMS.exe

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,13 +1,14 @@
#include "LineParser.h" #include "LineParser.h"
using namespace dms::tokens; using namespace dms::tokens;
using namespace dms::utils; using namespace dms::utils;
// TODO: process if elseif else statements, for loops and while loops
namespace dms { namespace dms {
bool LineParser::match_process_standard(tokenstream* stream, value* v) { bool LineParser::match_process_standard(tokenstream* stream, value* v) {
if (match_process_expression(stream,v)) { if (match_process_expression(stream,v)) {
return true; // Nothing todo return true;
} }
else if (match_process_function(stream, v)) { else if (match_process_function(stream, v)) {
return true; // Nothing todo return true;
} }
else if (match_process_list(stream, v)) { else if (match_process_list(stream, v)) {
return true; return true;
@ -56,51 +57,66 @@ namespace dms {
bool LineParser::match_process_list(tokenstream* stream, value* v) { bool LineParser::match_process_list(tokenstream* stream, value* v) {
if (stream->match(tokens::cbracketo)) { if (stream->match(tokens::cbracketo)) {
token start = stream->peek(); token start = stream->peek();
token ancor = start;
std::vector<token> t = stream->next(tokens::cbracketo, tokens::cbracketc); std::vector<token> t = stream->next(tokens::cbracketo, tokens::cbracketc);
tokenstream tempstream; tokenstream tempstream;
tempstream.init(&t); tempstream.init(&t);
value* ref = buildVariable(); value* ref = buildVariable();
value* length = new value; value* length = new value;
value* dict = nullptr;
size_t count = 0; size_t count = 0;
cmd* c = new cmd; cmd* c = new cmd;
c->opcode = codes::LIST; c->opcode = codes::LIST;
c->args.push(v); c->args.push(v);
c->args.push(length); c->args.push(length);
current_chunk->addCmd(c); current_chunk->addCmd(c);
bool ready = true;
while (tempstream.peek().type != tokens::none) { while (tempstream.peek().type != tokens::none) {
print(tempstream.peek());
if (tempstream.match(tokens::cbracketc)) { if (tempstream.match(tokens::cbracketc)) {
ready = true;
c = new cmd; c = new cmd;
c->opcode = codes::INST; c->opcode = codes::INST;
c->args.push(v); c->args.push(v);
c->args.push(ref); c->args.push(ref);
if (dict != nullptr) {
c->args.push(dict);
dict = nullptr;
}
current_chunk->addCmd(c); current_chunk->addCmd(c);
break; break;
} }
// Match Dict
else if (tempstream.match(tokens::name,tokens::colon)) {
dict = buildVariable(tempstream.next().name);
tempstream.next();
if (!match_process_standard(&tempstream,ref)) {
badSymbol();
}
}
// This will modify the ref!!! // This will modify the ref!!!
else if (match_process_standard(&tempstream, ref)) { else if (match_process_standard(&tempstream, ref)) {
count++; count++;
print(">>",tempstream.peek()); if (ready) {
ancor = tempstream.last();
// TODO: make sure each statement is properly seperated by a comma n such ready = false;
}
/*if (tempstream.match(tokens::seperator) || tempstream.match(tokens::newline,tokens::seperator)) { else
print("Good!"); state->push_error(errors::error{ errors::badtoken,concat("Unexpected symbol '",ancor.toString(),"' Expected '}' to close list (line: ",start.line_num,") Did you forget a comma?"),true,ancor.line_num,current_chunk });
}*/
/*if (!(tempstream.match(tokens::seperator) || tempstream.match(tokens::cbracketc) || tempstream.match(tokens::newline))) {
state->push_error(errors::error{ errors::badtoken,concat("Unexpected symbol '",tempstream.next().toString(),"' Expected '}' to close list at ",start.line_num),true,tempstream.peek().line_num,current_chunk });
return false;
}*/
} }
else if (tempstream.match(tokens::newline)) { else if (tempstream.match(tokens::newline)) {
tempstream.next(); // this is fine tempstream.next(); // this is fine
} }
else if (tempstream.match(tokens::seperator)) { else if (tempstream.match(tokens::seperator)) {
// Handle the next piece // Handle the next piece
ready = true;
c = new cmd; c = new cmd;
c->opcode = codes::INST; c->opcode = codes::INST;
c->args.push(v); c->args.push(v);
c->args.push(ref); c->args.push(ref);
if (dict != nullptr) {
c->args.push(dict);
dict = nullptr;
}
current_chunk->addCmd(c); current_chunk->addCmd(c);
// Build new value // Build new value
ref = buildVariable(); ref = buildVariable();
@ -120,22 +136,13 @@ namespace dms {
return false; return false;
} }
bool LineParser::match_process_disp(tokenstream* stream) { bool LineParser::match_process_disp(tokenstream* stream) {
/*
DISP, "msg"
DISP, "msg" speaker
Compound DISP
*/
//lastCall.push("MP_disp");
if ((isBlock(bt_block) || isBlock(bt_method)) && stream->match(tokens::newline, tokens::string, tokens::newline)) { if ((isBlock(bt_block) || isBlock(bt_method)) && stream->match(tokens::newline, tokens::string, tokens::newline)) {
stream->next(); // Standard consumption stream->next(); // Standard consumption
std::string msg = stream->next().name; std::string msg = stream->next().name;
cmd* c = new cmd; cmd* c = new cmd;
c->opcode = codes::DISP; c->opcode = codes::DISP;
//c->args.push(buildValue());
c->args.push(buildValue(msg)); c->args.push(buildValue(msg));
current_chunk->addCmd(c); // Add the cmd to the current chunk current_chunk->addCmd(c); // Add the cmd to the current chunk
//lastCall.pop();
return true; return true;
} }
else if ((isBlock(bt_block) || isBlock(bt_method)) && stream->match(tokens::newline, tokens::name, tokens::colon, tokens::string, tokens::newline)) { else if ((isBlock(bt_block) || isBlock(bt_method)) && stream->match(tokens::newline, tokens::name, tokens::colon, tokens::string, tokens::newline)) {
@ -151,26 +158,18 @@ namespace dms {
current_chunk->addCmd(c); current_chunk->addCmd(c);
c = new cmd; c = new cmd;
c->opcode = codes::DISP; c->opcode = codes::DISP;
//c->args.push(buildValue());
c->args.push(buildValue(msg)); c->args.push(buildValue(msg));
current_chunk->addCmd(c); // Add the cmd to the current chunk current_chunk->addCmd(c); // Add the cmd to the current chunk
// We might have to consume a newline... Depends on what's next // We might have to consume a newline... Depends on what's next
//lastCall.pop();
return true; return true;
} }
else if ((isBlock(bt_block) || isBlock(bt_method)) && stream->match(tokens::name,tokens::colon,tokens::cbracketo)) { else if ((isBlock(bt_block) || isBlock(bt_method)) && stream->match(tokens::name,tokens::colon,tokens::cbracketo)) {
std::string name = stream->next().name; std::string name = stream->next().name;
// Command to set the speaker
cmd* c = new cmd; cmd* c = new cmd;
c->opcode = codes::SSPK; c->opcode = codes::SSPK;
c->args.push(buildVariable(name)); c->args.push(buildVariable(name));
current_chunk->addCmd(c); current_chunk->addCmd(c);
// Reset the display for the new speaker. Append can be used!
//c = new cmd;
//c->opcode = codes::DISP;
//c->args.push(buildValue());
//c->args.push(buildValue(std::string("")));
//current_chunk->addCmd(c);
// Command to set the speaker
stream->next(); stream->next();
stream->next(); stream->next();
while (stream->peek().type != tokens::cbracketc) { while (stream->peek().type != tokens::cbracketc) {
@ -235,74 +234,21 @@ namespace dms {
// emotion: "path" // emotion: "path"
// looks like a simple disp command // looks like a simple disp command
else if (isBlock(bt_character) && stream->match(tokens::tab, tokens::name, tokens::colon, tokens::string, tokens::newline)) { else if (isBlock(bt_character) && stream->match(tokens::tab, tokens::name, tokens::colon, tokens::string, tokens::newline)) {
//lastCall.pop();
return true; return true;
} }
// TODO: We still have to implement the compound disp
//lastCall.pop();
return false; return false;
} }
bool LineParser::match_process_assignment(tokenstream* stream) { bool LineParser::match_process_assignment(tokenstream* stream) {
// something equals something else lets go
//lastCall.push("MP_assignment");
if (stream->match(tokens::name,tokens::equal)) { if (stream->match(tokens::name,tokens::equal)) {
value* var = buildVariable(stream->next().name); // The variable that we will be setting stuff to value* var = buildVariable(stream->next().name); // The variable that we will be setting stuff to
stream->next(); // Consume the equal stream->next(); // Consume the equal
cmd* c = new cmd; cmd* c = new cmd;
c->opcode = codes::ASGN; c->opcode = codes::ASGN;
c->args.push(var); c->args.push(var);
if (match_process_list(stream, var)) { value* ref = buildVariable();
return true; print(stream->peek());
} if (match_process_standard(stream,ref)) {
else if (match_process_expression(stream, var)) { c->args.push(ref);
// Expressions can internally set variables
// We actually need to clean up our cmds
return true;
}
else if (match_process_function(stream, var)) {
// Functions can internally set variables
// We actually need to clean up our cmds
return true;
}
else if (stream->match(tokens::True)) {
stream->next();
c->args.push(buildValue(true));
current_chunk->addCmd(c);
return true;
}
else if (stream->match(tokens::False)) {
stream->next();
c->args.push(buildValue(false));
current_chunk->addCmd(c);
return true;
}
else if (stream->match(tokens::string)) {
c->args.push(buildValue(stream->next().name));
current_chunk->addCmd(c);
return true;
}
else if (stream->match(tokens::nil)) {
stream->next();
c->args.push(buildValue());
current_chunk->addCmd(c);
return true;
}
else if (stream->match(tokens::number)) {
c->args.push(buildValue(std::stod(stream->next().name)));
current_chunk->addCmd(c);
return true;
}
else if (stream->match(tokens::bracketo, tokens::name, tokens::bracketc)) {
// We are assigning a block as a variable
stream->next();
c->args.push(buildBlock(stream->next().name));
current_chunk->addCmd(c);
stream->next();
return true;
}
else if (stream->match(tokens::name)) {
c->args.push(buildVariable(stream->next().name));
current_chunk->addCmd(c); current_chunk->addCmd(c);
return true; return true;
} }
@ -336,7 +282,6 @@ namespace dms {
return false; return false;
} }
bool LineParser::match_process_choice(tokenstream* stream) { bool LineParser::match_process_choice(tokenstream* stream) {
//lastCall.push("MP_choice");
token temp = stream->peek(); token temp = stream->peek();
if (temp.raw == codes::CHOI && stream->match(tokens::control,tokens::string)) { if (temp.raw == codes::CHOI && stream->match(tokens::control,tokens::string)) {
// Let's parse choice blocks. // Let's parse choice blocks.
@ -383,7 +328,6 @@ namespace dms {
The NOOP ensures the pattern stays. The NOOP ensures the pattern stays.
If we are provided with a number greater than 3 then we can push an execption. If we are provided with a number greater than 3 then we can push an execption.
*/ */
std::string str = concat("$",stream->peek().line_num);
while (!stream->match(tokens::cbracketc)) { while (!stream->match(tokens::cbracketc)) {
if (stream->match(tokens::cbracketo) && !start) { if (stream->match(tokens::cbracketo) && !start) {
start = true; start = true;
@ -400,7 +344,7 @@ namespace dms {
if (match_process_function(stream,nullptr,false)) { // No returns and also no nesting of functions! if (match_process_function(stream,nullptr,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 // We cannot have a nested function here, but if we dont have that then we add our goto
hasfunc = true; hasfunc = true;
buildGoto(str); buildGoto(choicelabel);
} }
else if (match_process_goto(stream)) { else if (match_process_goto(stream)) {
buildNoop(); // Add noop to post-goto command buildNoop(); // Add noop to post-goto command
@ -424,11 +368,9 @@ namespace dms {
current_chunk->cmds.pop_back(); current_chunk->cmds.pop_back();
delete cc; delete cc;
if (hasfunc) if (hasfunc)
buildLabel(str); buildLabel(choicelabel);
//lastCall.pop();
return true; return true;
} }
//lastCall.pop();
return false; return false;
} }
@ -437,7 +379,6 @@ namespace dms {
delete[] v; // We didn't need it, lets clean it up! delete[] v; // We didn't need it, lets clean it up!
} }
bool LineParser::match_process_function(tokenstream* stream, value* v, bool nested) { bool LineParser::match_process_function(tokenstream* stream, value* v, bool nested) {
//lastCall.push("MP_function");
/* /*
Functions should be able to handle function calls as arguments, Functions should be able to handle function calls as arguments,
HOWEVER functions cannot be passed as values since they aren't values like they are in other languages! HOWEVER functions cannot be passed as values since they aren't values like they are in other languages!
@ -504,9 +445,9 @@ namespace dms {
tempstream.init(&t); // Turn tokens we consumed into a tokenstream tempstream.init(&t); // Turn tokens we consumed into a tokenstream
value* tempval; value* tempval;
token tok; token tok;
value* ref = buildVariable();
// This part we add values to the opcodes for the bytecode FUNC val a1 a2 a3 ... an // 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 while (tempstream.peek().type != tokens::none) { // End of stream
print("> ", tempstream.peek());
tempval = buildVariable(); tempval = buildVariable();
tok = tempstream.peek(); tok = tempstream.peek();
if (tempstream.match(tokens::seperator)) { if (tempstream.match(tokens::seperator)) {
@ -576,7 +517,6 @@ namespace dms {
} }
} }
} }
//lastCall.pop();
return false; return false;
} }
bool LineParser::match_process_goto(tokenstream* stream) { bool LineParser::match_process_goto(tokenstream* stream) {
@ -637,21 +577,10 @@ namespace dms {
// I will have to consume for this to work so we need to keep track of what was incase we return false! // I will have to consume for this to work so we need to keep track of what was incase we return false!
stream->store(current_chunk); stream->store(current_chunk);
cmd* lastcmd = nullptr; cmd* lastcmd = nullptr;
/*if(!current_chunk->cmds.empty())
lastcmd = current_chunk->cmds.back();*/
// It has to start with one of these 3 to even be considered an expression // It has to start with one of these 3 to even be considered an expression
if (stream->match(tokens::number) || stream->match(tokens::name) || stream->match(tokens::parao)) { if (stream->match(tokens::number) || stream->match(tokens::name) || stream->match(tokens::parao)) {
// What do we know, math expressions can only be on a single line. We know where to stop looking if we have to // What do we know, math expressions can only be on a single line. We know where to stop looking if we have to
cmd* c = new cmd; cmd* c = new cmd;
/*
* We have a few built-in methods we will have to handle
* ADD val v1 v2
* SUB val v1 v2
* MUL val v1 v2
* DIV val v1 v2
* POW val v1 v2
* MOD val v1 v2
*/
value* wv = nullptr; value* wv = nullptr;
value* left; // lefthand value* left; // lefthand
codes::op op; // opperator codes::op op; // opperator
@ -761,7 +690,7 @@ namespace dms {
else else
badSymbol(stream); badSymbol(stream);
} }
else if (/*stream->match(tokens::newline) || */stream->match(tokens::parac) || stream->match(tokens::seperator)) { else if (stream->match(tokens::newline) || stream->match(tokens::parac) || stream->match(tokens::seperator)) {
if (wv == nullptr) if (wv == nullptr)
return stream->restore(lastcmd, current_chunk); // Always return false and restores the position in stream! return stream->restore(lastcmd, current_chunk); // Always return false and restores the position in stream!
cmd* cc = new cmd; cmd* cc = new cmd;
@ -769,7 +698,8 @@ namespace dms {
cc->args.push(v); cc->args.push(v);
cc->args.push(wv); cc->args.push(wv);
current_chunk->addCmd(cc); current_chunk->addCmd(cc);
stream->next(); if(stream->match(tokens::parac))
stream->next();
// We done! // We done!
int t=0; int t=0;
return true; return true;

View File

@ -131,8 +131,17 @@ namespace dms {
t_vec.push_back(token{ tokens::seperator,codes::NOOP,",",line }); t_vec.push_back(token{ tokens::seperator,codes::NOOP,",",line });
} }
else if (data == '.') { else if (data == '.') {
//doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer); // If a number starts with a .## then we need to ensure that we create the value properly
t_vec.push_back(token{ tokens::dot,codes::NOOP,".",line }); if (std::isdigit(stream.peek()) && buffer.size()==0) {
// If the buffer has data then something isn't right
isNum = true;
buffer.push_back('0');
buffer.push_back('.');
}
else {
doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer);
t_vec.push_back(token{ tokens::dot,codes::NOOP,".",line });
}
} }
else if (data == '{') { else if (data == '{') {
doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer); doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer);
@ -296,7 +305,6 @@ namespace dms {
} }
t_vec.push_back(token{ tokens::eof,codes::NOOP,"",line - 1 }); t_vec.push_back(token{ tokens::eof,codes::NOOP,"",line - 1 });
tokenDump(&t_vec); tokenDump(&t_vec);
print("Running tokenizer");
// Tokens build let's parse // Tokens build let's parse
tokenizer(state, t_vec); tokenizer(state, t_vec);
return state; return state;
@ -321,8 +329,9 @@ namespace dms {
} }
void LineParser::_Parse(tokenstream* stream) { void LineParser::_Parse(tokenstream* stream) {
token current = stream->next(); token current = stream->next();
createBlock("$INIT", blocktype::bt_block);
cmd* flagcmd = new cmd;
while (stream->peek().type != tokens::eof) { while (stream->peek().type != tokens::eof) {
print(current);
if (current.type == tokens::flag) { if (current.type == tokens::flag) {
temp = stream->next(tokens::newline); temp = stream->next(tokens::newline);
stream->prev(); // Unconsume the newline piece stream->prev(); // Unconsume the newline piece
@ -333,33 +342,51 @@ namespace dms {
tokens::tokentype tok = temp[0].type; tokens::tokentype tok = temp[0].type;
if (code == codes::ENAB && tok == tokens::name) { if (code == codes::ENAB && tok == tokens::name) {
tolower(temp[0].name); tolower(temp[0].name);
state->enables.insert_or_assign(temp[0].name, true); state->enable(temp[0].name);
flagcmd->opcode = code;
flagcmd->args.push(buildValue(temp[0].name));
current_chunk->addCmd(flagcmd);
flagcmd = new cmd;
} }
else if (code == codes::ENTR && tok == tokens::name) { else if (code == codes::ENTR && tok == tokens::name) {
state->entry = temp[0].name; state->entry = temp[0].name;
flagcmd->opcode = code;
flagcmd->args.push(buildValue(temp[0].name));
current_chunk->addCmd(flagcmd);
flagcmd = new cmd;
} }
else if (code == codes::DISA && tok == tokens::name) { else if (code == codes::DISA && tok == tokens::name) {
tolower(temp[0].name); tolower(temp[0].name);
state->enables.insert_or_assign(temp[0].name, false); state->disable(temp[0].name);
flagcmd->opcode = code;
flagcmd->args.push(buildValue(temp[0].name));
current_chunk->addCmd(flagcmd);
flagcmd = new cmd;
} }
else if (code == codes::VERN && tok == tokens::number) { else if (code == codes::VERN && tok == tokens::number) {
state->version = std::stod(temp[0].name); state->version = std::stod(temp[0].name);
flagcmd->opcode = code;
flagcmd->args.push(buildValue(std::stod(temp[0].name)));
current_chunk->addCmd(flagcmd);
flagcmd = new cmd;
} }
else if (code == codes::USIN && tok == tokens::name) { else if (code == codes::USIN && tok == tokens::name) {
// TODO add usings, kinda useless atm since everything will be packed in. Perhaps extensions? // TODO add usings, kinda useless atm since everything will be packed in. Perhaps extensions?
} }
else if (code == codes::LOAD && tok == tokens::string) { else if (code == codes::LOAD && tok == tokens::string) {
flagcmd->opcode = code;
flagcmd->args.push(buildValue(temp[0].name));
current_chunk->addCmd(flagcmd);
flagcmd = new cmd;
LineParser parser = LineParser(); LineParser parser = LineParser();
parser.Parse(state, temp[0].name);// Load another file parser.Parse(state, temp[0].name);// Load another file
} }
else { else {
std::stringstream str; state->push_error(errors::error{ errors::badtoken,concat("Expected <FLAG IDENTIFIER> got: ", current, temp[0]),true,line,current_chunk });
str << "Expected <FLAG IDENTIFIER> " << " got: " << current << temp[0];
state->push_error(errors::error{ errors::badtoken,str.str(),true,line,current_chunk });
} }
} }
// Default block // Default block
if (stream->match(tokens::newline,tokens::bracketo, tokens::name, tokens::bracketc)) { if (stream->match(tokens::newline,tokens::bracketo, tokens::name, tokens::bracketc,tokens::newline)) {
stream->next(); stream->next();
stream->next(); stream->next();
std::string name = stream->next().name; std::string name = stream->next().name;
@ -449,6 +476,6 @@ namespace dms {
match_process_function(stream); // Naked Function match_process_function(stream); // Naked Function
current = stream->next(); current = stream->next();
} }
createBlock("$END$", bt_block); createBlock("$END", blocktype::bt_block);// Runs code that ensures that last user block is processed into the chunks array. Yes, I could have simply added in the lines of code at the end, but I didn't want to rewrite code again!
} }
} }

View File

@ -217,21 +217,59 @@ namespace dms {
} }
bool LineParser::createBlock(std::string bk_name, blocktype bk_type) { bool LineParser::createBlock(std::string bk_name, blocktype bk_type) {
if (current_chunk != nullptr) { if (current_chunk != nullptr) {
if (!state->chunks.count(current_chunk->name)) if (state->chunks.count(bk_name)==0 && bk_name!="$END")
state->push_chunk(current_chunk->name, current_chunk); state->push_chunk(current_chunk->name, current_chunk);
else else
{ {
std::stringstream str; if (bk_name == "$INIT") {
str << "Block <" << current_chunk->name << "> already defined!"; current_chunk = state->chunks["$INIT"];
state->push_error(errors::error{ errors::block_already_defined,str.str(),true,line,current_chunk }); return true;
return false; }
else if (bk_name == "$END") {
cmd* c = new cmd;
c->opcode = codes::JUMP;
c->args.push(buildVariable("$END"));
current_chunk->addCmd(c);
state->push_chunk(current_chunk->name, current_chunk);
current_chunk = state->chunks["$END"];
return true;
}
else {
std::stringstream str;
str << "Block <" << current_chunk->name << "> already defined!";
state->push_error(errors::error{ errors::block_already_defined,str.str(),true,line,current_chunk });
return false;
}
} }
} }
if (state->isEnabled("leaking") && (current_chunk != nullptr && current_chunk->name != "$INIT")) {
cmd* c = new cmd;
c->opcode = codes::JUMP;
c->args.push(buildVariable(bk_name));
current_chunk->addCmd(c);
}
if (current_chunk!= nullptr && current_chunk->name == "$INIT") {
cmd* c = new cmd;
c->opcode = codes::JUMP;
if(state->entry!="$undefined")
c->args.push(buildVariable(state->entry));
else
c->args.push(buildVariable(bk_name));
current_chunk->addCmd(c);
}
if (current_chunk != nullptr && current_chunk->name == "$END") {
cmd* c = new cmd;
c->opcode = codes::EXIT;
if (state->entry != "$undefined")
c->args.push(buildValue(0));
else
c->args.push(buildVariable(bk_name));
current_chunk->addCmd(c);
}
current_chunk = new chunk; current_chunk = new chunk;
current_chunk->name = bk_name; current_chunk->name = bk_name;
chunk_type = bk_type; chunk_type = bk_type;
current_chunk->type = bk_type; current_chunk->type = bk_type;
return true; return true;
} }
void LineParser::tokenizer(dms_state* state,std::vector<token> &toks) { void LineParser::tokenizer(dms_state* state,std::vector<token> &toks) {

View File

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

View File

@ -7,6 +7,20 @@ namespace dms {
enables.insert_or_assign("warnings",false); // enables.insert_or_assign("warnings",false); //
enables.insert_or_assign("statesave",true); // Allows you to save state enables.insert_or_assign("statesave",true); // Allows you to save state
enables.insert_or_assign("omniscient",true); // Allows you to know who's who when you first meet them enables.insert_or_assign("omniscient",true); // Allows you to know who's who when you first meet them
chunk* c = new chunk;
c->name = "$END";
c->type = blocktype::bt_block;
cmd* cc = new cmd;
cc->opcode = codes::EXIT;
cc->args.push(buildValue(0));
c->addCmd(cc);
push_chunk("$END", c);
}
void dms_state::enable(std::string flag) {
enables[flag] = true;
}
void dms_state::disable(std::string flag) {
enables[flag] = false;
} }
bool dms_state::isEnabled(std::string flag) { bool dms_state::isEnabled(std::string flag) {
if (enables.count(flag)) { if (enables.count(flag)) {
@ -41,12 +55,13 @@ namespace dms {
} }
void dms_state::push_error(errors::error err) { void dms_state::push_error(errors::error err) {
std::cout << err.err_msg << " On Line <" << err.linenum << ">" << std::endl; std::cout << err.err_msg << " On Line <" << err.linenum << ">" << std::endl;
this->err = err;
if (err.crash) if (err.crash)
std::exit(err.code); stop = true;
} }
void dms_state::push_warning(errors::error err) { void dms_state::push_warning(errors::error err) {
err.crash = false; // Force code to not crash then push the error err.crash = false; // Force code to not crash then push the error
if(enables.count("warnings")) if(isEnabled("warnings"))
push_error(err); push_error(err);
} }
} }

View File

@ -5,20 +5,27 @@
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <map> #include <map>
#include <unordered_map>
namespace dms { namespace dms {
class dms_state struct dms_state
{ {
public: std::unordered_map<std::string, value*> memory;
std::map<std::string, chunk*> chunks;
std::string entry = "$undefined";
std::map<std::string, bool> enables;
errors::error err;
bool stop = false;
dms_state(); dms_state();
void dump(errors::error err); void dump(errors::error err);
void dump(); void dump();
void push_error(errors::error err); void push_error(errors::error err);
void push_warning(errors::error err); void push_warning(errors::error err);
void push_chunk(std::string s, chunk* c); void push_chunk(std::string s, chunk* c);
bool run(std::string instance = "Main");
double version=1.0; double version=1.0;
std::map<std::string, chunk*> chunks; void enable(std::string flag);
std::string entry = "start"; void disable(std::string flag);
std::map<std::string, bool> enables;
bool isEnabled(std::string flag); bool isEnabled(std::string flag);
}; };
} }

View File

@ -0,0 +1,18 @@
#include "dms_state.h"
namespace dms {
// Instance, multiple instances can allow different code to work side by side
bool dms_state::run(std::string instance) {
codes::op code;
//TODO: parse the cmds and do stuff
/*switch (code)
{
case codes::NOOP:
break;
default:
break;
}*/
return true;
}
}

Binary file not shown.

View File

@ -2,8 +2,7 @@ Token Dump:
Line <1> newline Line <1> newline
Line <1> newline Line <1> newline
Line <1> flag Line <1> flag
Line <1> name main Line <1> name test
Line <1> newline
Line <1> newline Line <1> newline
Line <2> flag Line <2> flag
Line <2> name warnings Line <2> name warnings
@ -14,65 +13,70 @@ Line <3> name omniscient
Line <3> newline Line <3> newline
Line <3> newline Line <3> newline
Line <4> flag Line <4> flag
Line <4> name debugging Line <4> name leaking
Line <4> newline Line <4> newline
Line <4> newline Line <4> newline
Line <5> flag
Line <5> name debugging
Line <5> newline
Line <5> newline Line <5> newline
Line <6> flag Line <6> flag
Line <6> number 1.2 Line <6> string loadtest.dms
Line <6> newline Line <6> newline
Line <6> newline Line <6> newline
Line <7> flag Line <7> flag
Line <7> name extendedDefine Line <7> number 1.2
Line <7> newline Line <7> newline
Line <7> newline Line <7> newline
Line <8> flag
Line <8> name extendedDefine
Line <8> newline Line <8> newline
Line <8> newline Line <8> newline
Line <9> bracketo [
Line <9> name main
Line <9> bracketc ]
Line <9> newline Line <9> newline
Line <9> newline Line <9> newline
Line <10> string Testing Line <10> bracketo [
Line <10> name main
Line <10> bracketc ]
Line <10> newline Line <10> newline
Line <10> newline Line <10> newline
Line <11> name Bob Line <11> string Testing
Line <11> colon :
Line <11> cbracketo {
Line <11> newline Line <11> newline
Line <11> newline Line <11> newline
Line <12> name speed Line <12> name Bob
Line <12> number 50 Line <12> colon :
Line <12> cbracketo {
Line <12> newline Line <12> newline
Line <12> newline Line <12> newline
Line <13> name excited Line <13> name speed
Line <13> colon : Line <13> number 50
Line <13> string Hello Ryan!
Line <13> newline Line <13> newline
Line <13> newline Line <13> newline
Line <14> name wait Line <14> name excited
Line <14> number 200 Line <14> colon :
Line <14> string Hello Ryan!
Line <14> newline Line <14> newline
Line <14> newline Line <14> newline
Line <15> string How are you doing? Line <15> name wait
Line <15> number 200
Line <15> newline Line <15> newline
Line <15> newline Line <15> newline
Line <16> cbracketc } Line <16> string How are you doing?
Line <16> newline Line <16> newline
Line <16> newline Line <16> newline
Line <17> cbracketc }
Line <17> newline Line <17> newline
Line <17> newline Line <17> newline
Line <18> name Ryan
Line <18> colon :
Line <18> cbracketo {
Line <18> newline Line <18> newline
Line <18> newline Line <18> newline
Line <19> string Hey Bob I'm good how are you? Line <19> name Ryan
Line <19> colon :
Line <19> cbracketo {
Line <19> newline Line <19> newline
Line <19> newline Line <19> newline
Line <20> cbracketc } Line <20> string Hey Bob I'm good how are you?
Line <20> newline Line <20> newline
Line <20> newline Line <20> newline
Line <21> cbracketc }
Line <21> newline Line <21> newline
Line <21> newline Line <21> newline
Line <22> name Bob Line <22> name Bob
@ -82,135 +86,239 @@ Line <22> newline
Line <22> newline Line <22> newline
Line <23> newline Line <23> newline
Line <23> newline Line <23> newline
Line <24> name list Line <24> control
Line <24> equal = Line <24> string What do you want to do?
Line <24> cbracketo { Line <24> cbracketo {
Line <24> newline Line <24> newline
Line <24> newline Line <24> newline
Line <25> string Hello Line <25> string option 0
Line <25> seperator , Line <25> name test2
Line <25> parao (
Line <25> string testing
Line <25> parac )
Line <25> newline Line <25> newline
Line <25> newline Line <25> newline
Line <26> true true Line <26> string option 1
Line <26> seperator , Line <26> jump
Line <26> string here
Line <26> newline Line <26> newline
Line <26> newline Line <26> newline
Line <27> nil nil Line <27> string option 2
Line <27> seperator , Line <27> jump
Line <27> name there
Line <27> newline Line <27> newline
Line <27> newline Line <27> newline
Line <28> parao ( Line <28> string option 3
Line <28> number 1000 Line <28> gotoo
Line <28> plus + Line <28> string o3
Line <28> newline Line <28> newline
Line <28> newline Line <28> newline
Line <29> number 342 Line <29> string option 4
Line <29> parac ) Line <29> gotoo
Line <29> divide / Line <29> name here
Line <29> name hi
Line <29> seperator ,
Line <29> false false
Line <29> seperator ,
Line <29> newline Line <29> newline
Line <29> newline Line <29> newline
Line <30> string option 5
Line <30> name test Line <30> name test
Line <30> parao ( Line <30> parao (
Line <30> number 1 Line <30> string here
Line <30> seperator ,
Line <30> number 2
Line <30> parac ) Line <30> parac )
Line <30> seperator ,
Line <30> newline Line <30> newline
Line <30> newline Line <30> newline
Line <31> cbracketo { Line <31> cbracketc }
Line <31> newline Line <31> newline
Line <31> newline Line <31> newline
Line <32> number 1
Line <32> seperator ,
Line <32> newline Line <32> newline
Line <32> newline Line <32> newline
Line <33> false false Line <33> bracketo [
Line <33> seperator , Line <33> name Bob
Line <33> colon :
Line <33> name char
Line <33> bracketc ]
Line <33> newline Line <33> newline
Line <33> newline Line <33> newline
Line <34> nil nil Line <34> name age
Line <34> equal =
Line <34> number .24
Line <34> newline Line <34> newline
Line <34> newline Line <34> newline
Line <35> cbracketc } Line <35> name money
Line <35> equal =
Line <35> number 100
Line <35> newline Line <35> newline
Line <35> newline Line <35> newline
Line <36> cbracketc } Line <36> name excited
Line <36> colon :
Line <36> string path/to/file
Line <36> name function
Line <36> newline Line <36> newline
Line <36> newline Line <36> newline
Line <37> newline Line <37> newline
Line <37> newline Line <37> newline
Line <38> name test Line <38> bracketo [
Line <38> name newblock
Line <38> colon :
Line <38> name function
Line <38> parao ( Line <38> parao (
Line <38> parac )
Line <38> bracketc ]
Line <38> newline Line <38> newline
Line <38> newline Line <38> newline
Line <39> cbracketo { Line <39> string Test #2
Line <39> newline Line <39> newline
Line <39> newline Line <39> newline
Line <40> number 1 Line <40> string Does it parse this part properly?
Line <40> seperator ,
Line <40> newline Line <40> newline
Line <40> newline Line <40> newline
Line <41> number 2 Line <41> string huh
Line <41> seperator ,
Line <41> newline Line <41> newline
Line <41> newline Line <41> newline
Line <42> number 3 Line <41> eof
Line <42> newline Line <1> newline
Line <42> newline Line <1> newline
Line <43> cbracketc } Line <1> bracketo [
Line <43> newline Line <1> name default
Line <43> newline Line <1> colon :
Line <44> parac ) Line <1> name char
Line <44> newline Line <1> bracketc ]
Line <44> newline Line <1> newline
Line <45> newline Line <1> newline
Line <45> newline Line <2> newline
Line <46> bracketo [ Line <3> name money
Line <46> name Bob Line <3> equal =
Line <46> colon : Line <3> number 0
Line <46> name char Line <3> newline
Line <46> bracketc ] Line <3> newline
Line <46> newline Line <4> name test
Line <46> newline Line <4> equal =
Line <47> name age Line <4> nil nil
Line <47> equal = Line <4> newline
Line <47> number 24 Line <4> newline
Line <47> newline Line <5> newline
Line <47> newline Line <5> newline
Line <48> name money Line <6> bracketo [
Line <48> equal = Line <6> name Ryan
Line <48> number 100 Line <6> colon :
Line <48> newline Line <6> name char
Line <48> newline Line <6> bracketc ]
Line <49> name excited Line <6> newline
Line <49> colon : Line <6> newline
Line <49> string path/to/file Line <7> name age
Line <49> name function Line <7> equal =
Line <49> newline Line <7> number 21
Line <49> newline Line <7> newline
Line <50> newline Line <7> newline
Line <50> newline Line <8> name money
Line <51> bracketo [ Line <8> equal =
Line <51> name newblock Line <8> number 1000
Line <51> colon : Line <8> newline
Line <51> name function Line <8> newline
Line <51> parao ( Line <9> newline
Line <51> parac ) Line <10> name calm
Line <51> bracketc ] Line <10> colon :
Line <51> newline Line <10> string ./path/to/file
Line <51> newline Line <10> newline
Line <52> string Test #2 Line <10> newline
Line <52> newline Line <11> name excited
Line <52> newline Line <11> colon :
Line <53> string Does it parse this part properly? Line <11> string ./path/to/file
Line <53> newline Line <11> newline
Line <53> newline Line <11> newline
Line <54> string huh Line <12> newline
Line <54> newline Line <12> newline
Line <54> newline Line <13> bracketo [
Line <54> eof Line <13> name step
Line <13> colon :
Line <13> name function
Line <13> parao (
Line <13> name a
Line <13> seperator ,
Line <13> name b
Line <13> seperator ,
Line <13> name c
Line <13> parac )
Line <13> bracketc ]
Line <13> newline
Line <13> newline
Line <14> string Testing...
Line <14> newline
Line <15> name d
Line <15> equal =
Line <15> parao (
Line <15> number 100
Line <15> plus +
Line <15> name b
Line <15> parac )
Line <15> divide /
Line <15> name c
Line <15> newline
Line <15> newline
Line <16> name e
Line <16> equal =
Line <16> string somestring
Line <16> newline
Line <16> newline
Line <17> name e
Line <17> equal =
Line <17> nil nil
Line <17> newline
Line <17> newline
Line <18> name g
Line <18> equal =
Line <18> false false
Line <18> newline
Line <18> newline
Line <19> ret
Line <19> name d
Line <19> newline
Line <19> newline
Line <20> newline
Line <20> newline
Line <21> bracketo [
Line <21> name inventory
Line <21> colon :
Line <21> name env
Line <21> bracketc ]
Line <21> newline
Line <21> newline
Line <22> name slot1
Line <22> equal =
Line <22> string
Line <22> newline
Line <22> newline
Line <23> name slot2
Line <23> equal =
Line <23> string
Line <23> newline
Line <23> newline
Line <24> name slot3
Line <24> equal =
Line <24> string
Line <24> newline
Line <24> newline
Line <25> name slot4
Line <25> equal =
Line <25> string
Line <25> newline
Line <25> newline
Line <26> name slot5
Line <26> equal =
Line <26> string
Line <26> newline
Line <26> newline
Line <27> name slot6
Line <27> equal =
Line <27> string
Line <27> newline
Line <27> newline
Line <28> name slot7
Line <28> equal =
Line <28> string
Line <28> newline
Line <28> newline
Line <29> name slot8
Line <29> equal =
Line <29> string
Line <29> newline
Line <29> newline
Line <29> eof

View File

@ -1,8 +1,9 @@
entry main entry test // Will either start the first block seen or the block supplied by you!
enable warnings enable warnings
disable omniscient disable omniscient
enable leaking
enable debugging enable debugging
//loadfile "loadtest.dms" loadfile "loadtest.dms"
version 1.2 version 1.2
using extendedDefine using extendedDefine
@ -18,33 +19,19 @@ using extendedDefine
Ryan: { Ryan: {
"Hey Bob I'm good how are you?" "Hey Bob I'm good how are you?"
} }
Bob: "Testing..." Bob: "Testing..."
list = { choice "What do you want to do?" {
"Hello", "option 0" test2("testing")
true, "option 1" jump "here"
nil, "option 2" jump there
(1000+ "option 3" goto "o3"
342)/hi,false, "option 4" goto here
test(1,2), "option 5" test("here")
{
1,
false,
nil
}
} }
test(
{
1,
2,
3
}
)
[Bob:char] [Bob:char]
age = 24 age = .24
money = 100 money = 100
excited: "path/to/file" | function excited: "path/to/file" | function

View File

@ -1,10 +1,23 @@
#include "value.h" #include "value.h"
#include "utils.h" #include "utils.h"
#include "string" #include "string"
#include <sstream>
#include <map>
#include <vector>
namespace dms { namespace dms {
std::vector<value*> _VALUES;
value::value() {
_VALUES.push_back(this); // Used for the interperter! In the end everything is a value
// We need to clean up this stuff when it all comes crashing.
// We also might clean things while the code is running.
// Values at runtime aren't "Deleted, they are set to nil"
// At the end we actually delete them!
}
value* value::resolve(std::unordered_map<std::string, value*> map, value* v) {
if (v != nullptr) {
if (this->type == datatypes::variable) {
return resolve(map, map[this->s->getValue()]); // Variable types return the value
}
}
return this;
}
void dms_args::push(value* val) { void dms_args::push(value* val) {
args.push_back(val); args.push_back(val);
} }

View File

@ -3,6 +3,7 @@
#include <sstream> #include <sstream>
#include <vector> #include <vector>
#include <unordered_map> #include <unordered_map>
#include <map>
namespace dms { namespace dms {
struct dms_env; struct dms_env;
@ -41,15 +42,14 @@ namespace dms {
dms_boolean* buildBool(bool b); dms_boolean* buildBool(bool b);
dms_number* buildNumber(double num); dms_number* buildNumber(double num);
struct value { struct value {
/*~value() {
nuke();
}*/
datatypes type = nil; datatypes type = nil;
dms_boolean* b = nullptr; dms_boolean* b = nullptr;
dms_number* n = nullptr; dms_number* n = nullptr;
dms_string* s = nullptr; dms_string* s = nullptr;
dms_env* e = nullptr; dms_env* e = nullptr;
dms_custom* c = nullptr; dms_custom* c = nullptr;
value();
value* resolve(std::unordered_map<std::string,value*> map,value* v=nullptr);
void nuke(); void nuke();
void set(dms_string* str); void set(dms_string* str);
void set(dms_boolean* bo); void set(dms_boolean* bo);

Binary file not shown.

Binary file not shown.

Binary file not shown.