Added list support

This commit is contained in:
Ryan Ward 2020-09-14 00:03:21 -04:00
parent 88c73f0a29
commit 1465805a82
25 changed files with 328 additions and 84 deletions

View File

@ -1,8 +1,3 @@
 DMS.cpp
LineParserBuilds.cpp
LineParserMatchProcess.cpp
LineParserParse.cpp
LineParserUtils.cpp
Generating Code...
F:\VSCWorkspace\DMS\DMS\LineParserMatchProcess.cpp(693): warning C4715: 'dms::LineParser::match_process_expression': not all control paths return a value
 LineParserMatchProcess.cpp
F:\VSCWorkspace\DMS\DMS\LineParserMatchProcess.cpp(803): warning C4715: 'dms::LineParser::match_process_expression': not all control paths return a value
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.

View File

@ -24,7 +24,8 @@ namespace dms {
void init(std::vector<tokens::token>* ptr);
tokens::token next();
void prev();
std::vector<tokens::token> next(tokens::tokentype to,tokens::tokentype tc);
std::vector<tokens::token> next(tokens::tokentype to, tokens::tokentype tc);
std::vector<tokens::token> next(tokens::tokentype to, tokens::tokentype tc, bool nonewline);
tokens::token peek();
tokens::token last();
std::vector<tokens::token> next(tokens::tokentype tk);
@ -70,6 +71,10 @@ namespace dms {
bool match_process_expression(tokenstream* stream, value* v);
bool match_process_IFFF(tokenstream* stream);
bool match_process_assignment(tokenstream* stream);
bool match_process_list(tokenstream* stream, value* v = nullptr);
bool match_process_standard(tokenstream* stream, value* v = nullptr); // All types that are matchable are handled here!
// Build
void buildGoto(std::string g, bool v = false);
void buildNoop();

View File

@ -2,6 +2,123 @@
using namespace dms::tokens;
using namespace dms::utils;
namespace dms {
bool LineParser::match_process_standard(tokenstream* stream, value* v) {
if (match_process_expression(stream,v)) {
return true; // Nothing todo
}
else if (match_process_function(stream, v)) {
return true; // Nothing todo
}
else if (match_process_list(stream, v)) {
return true;
}
else if (stream->match(tokens::True)) {
v->set(buildBool(true));
stream->next();
return true;
}
else if (stream->match(tokens::False)) {
v->set(buildBool(false));
stream->next();
return true;
}
else if (stream->match(tokens::number)) {
v->set(buildNumber(std::stod(stream->next().name)));
return true;
}
else if (stream->match(tokens::string)) {
v->set(buildString(stream->next().name));
return true;
}
else if (stream->match(tokens::name)) {
v->set(buildString(stream->next().name));
v->type = datatypes::variable;
return true;
}
else if (stream->match(tokens::nil)) {
stream->next();
v->set();
return true;
}
else if (stream->match(tokens::bracketo, tokens::name, tokens::bracketc)) {
// We are assigning a block as a variable
stream->next();
v->set(buildString(stream->next().name));
v->type = datatypes::block;
stream->next();
return true;
}
else if (stream->match(tokens::newline)) {
return false;
}
return false;
}
bool LineParser::match_process_list(tokenstream* stream, value* v) {
if (stream->match(tokens::cbracketo)) {
token start = stream->peek();
std::vector<token> t = stream->next(tokens::cbracketo, tokens::cbracketc);
tokenstream tempstream;
tempstream.init(&t);
value* ref = buildVariable();
value* length = new value;
size_t count = 0;
cmd* c = new cmd;
c->opcode = codes::LIST;
c->args.push(v);
c->args.push(length);
current_chunk->addCmd(c);
while (tempstream.peek().type != tokens::none) {
print(tempstream.peek());
if (tempstream.match(tokens::cbracketc)) {
c = new cmd;
c->opcode = codes::INST;
c->args.push(v);
c->args.push(ref);
current_chunk->addCmd(c);
break;
}
// This will modify the ref!!!
else if (match_process_standard(&tempstream, ref)) {
count++;
print(">>",tempstream.peek());
// TODO: make sure each statement is properly seperated by a comma n such
/*if (tempstream.match(tokens::seperator) || tempstream.match(tokens::newline,tokens::seperator)) {
print("Good!");
}*/
/*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)) {
tempstream.next(); // this is fine
}
else if (tempstream.match(tokens::seperator)) {
// Handle the next piece
c = new cmd;
c->opcode = codes::INST;
c->args.push(v);
c->args.push(ref);
current_chunk->addCmd(c);
// Build new value
ref = buildVariable();
tempstream.next();
}
else if (tempstream.match(tokens::cbracketo)) {
tempstream.next();
}
else {
badSymbol(&tempstream);
}
}
length->set(buildNumber(count)); // the second argument is the length of the list! This should be modified if lists are changed at runtime!
return true;
}
return false;
}
bool LineParser::match_process_disp(tokenstream* stream) {
/*
DISP, "msg"
@ -15,7 +132,7 @@ namespace dms {
std::string msg = stream->next().name;
cmd* c = new cmd;
c->opcode = codes::DISP;
c->args.push(buildValue());
//c->args.push(buildValue());
c->args.push(buildValue(msg));
current_chunk->addCmd(c); // Add the cmd to the current chunk
//lastCall.pop();
@ -34,7 +151,7 @@ namespace dms {
current_chunk->addCmd(c);
c = new cmd;
c->opcode = codes::DISP;
c->args.push(buildValue());
//c->args.push(buildValue());
c->args.push(buildValue(msg));
current_chunk->addCmd(c); // Add the cmd to the current chunk
// We might have to consume a newline... Depends on what's next
@ -48,16 +165,15 @@ namespace dms {
c->args.push(buildVariable(name));
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);
//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();
while (stream->peek().type != tokens::cbracketc) {
print(stream->peek());
if (stream->match(tokens::name)) {
std::string mode = stream->next().name;
if (mode == "speed") {
@ -113,7 +229,7 @@ namespace dms {
return false;
}
}
print(stream->next());
stream->next();
return true;
}
// emotion: "path"
@ -136,50 +252,45 @@ namespace dms {
cmd* c = new cmd;
c->opcode = codes::ASGN;
c->args.push(var);
if (match_process_expression(stream, var)) {
if (match_process_list(stream, var)) {
return true;
}
else if (match_process_expression(stream, var)) {
// Expressions can internally set variables
// We actually need to clean up our cmds
//lastCall.pop();
return true;
}
else if (match_process_function(stream, var)) {
// Functions can internally set variables
// We actually need to clean up our cmds
print("> assign consumed!");
//lastCall.pop();
return true;
}
else if (stream->match(tokens::True)) {
stream->next();
c->args.push(buildValue(true));
current_chunk->addCmd(c);
//lastCall.pop();
return true;
}
else if (stream->match(tokens::False)) {
stream->next();
c->args.push(buildValue(false));
current_chunk->addCmd(c);
//lastCall.pop();
return true;
}
else if (stream->match(tokens::string)) {
c->args.push(buildValue(stream->next().name));
current_chunk->addCmd(c);
//lastCall.pop();
return true;
}
else if (stream->match(tokens::nil)) {
stream->next();
c->args.push(buildValue());
current_chunk->addCmd(c);
//lastCall.pop();
return true;
}
else if (stream->match(tokens::number)) {
c->args.push(buildValue(std::stod(stream->next().name)));
current_chunk->addCmd(c);
//lastCall.pop();
return true;
}
else if (stream->match(tokens::bracketo, tokens::name, tokens::bracketc)) {
@ -188,20 +299,17 @@ namespace dms {
c->args.push(buildBlock(stream->next().name));
current_chunk->addCmd(c);
stream->next();
//lastCall.pop();
return true;
}
else if (stream->match(tokens::name)) {
c->args.push(buildVariable(stream->next().name));
current_chunk->addCmd(c);
//lastCall.pop();
return true;
}
else if (stream->match(tokens::newline)) {
stream->next();
}
}
//lastCall.pop();
return false;
}
bool LineParser::match_process_debug(tokenstream* stream) {
@ -232,7 +340,6 @@ namespace dms {
token temp = stream->peek();
if (temp.raw == codes::CHOI && stream->match(tokens::control,tokens::string)) {
// Let's parse choice blocks.
print(stream->peek());
stream->next();
std::string prompt = stream->next().name;
bool good = true;
@ -407,6 +514,9 @@ namespace dms {
tempstream.next(); // Consume it
cleanup(tempval); // We don't need it
}
else if (match_process_list(&tempstream, tempval)) {
c->args.push(tempval);
}
else if (match_process_expression(&tempstream, tempval)) {
c->args.push(tempval);
}
@ -418,7 +528,6 @@ namespace dms {
else if (tempstream.match(tokens::number)) {
cleanup(tempval);
std::string str = tempstream.next().name;
print(str);
tempval = buildValue(std::stod(str)); // Get the number and convert it to a double then build a value
c->args.push(tempval); // add this argument to the function opcodes
}
@ -442,7 +551,6 @@ namespace dms {
// Final match this could be a function it might also be an expression
else if (match_process_function(&tempstream, tempval)) {
if (!nested) {
print("No nested!");
state->push_error(errors::error{ errors::nested_function,"Nested functions are not allowed in this context!",true, tempstream.peek().line_num });
}
c->args.push(tempval);
@ -464,7 +572,7 @@ namespace dms {
}
else {
cleanup(tempval); // Cleanup
badSymbol(stream);
badSymbol(&tempstream);
}
}
}
@ -552,7 +660,6 @@ namespace dms {
size_t loops = 0;
bool hasOP = false;
while (stream->peek().type != tokens::none) {
print(stream->peek());
if (stream->match(tokens::parao)) {
tokenstream temp;
temp.init(&(stream->next(tokens::parao, tokens::parac))); // Balanced match!
@ -563,10 +670,10 @@ namespace dms {
else if (right == nullptr)
right = tmpvalue;
else
badSymbol();
badSymbol(stream);
}
else {
badSymbol();
badSymbol(stream);
}
// Take that temp value and set it to left or right TODO finish this
}
@ -575,7 +682,7 @@ namespace dms {
if (op == codes::NOOP)
op = codes::ADD;
else
badSymbol();
badSymbol(stream);
stream->next();
}
else if (stream->match(tokens::minus)) {
@ -586,7 +693,7 @@ namespace dms {
if (op == codes::NOOP)
op = codes::SUB;
else
badSymbol();
badSymbol(stream);
stream->next();
}
else if (stream->match(tokens::multiply)) {
@ -594,7 +701,7 @@ namespace dms {
if (op == codes::NOOP)
op = codes::MUL;
else
badSymbol();
badSymbol(stream);
stream->next();
}
else if (stream->match(tokens::divide)) {
@ -602,7 +709,7 @@ namespace dms {
if (op == codes::NOOP)
op = codes::DIV;
else
badSymbol();
badSymbol(stream);
stream->next();
}
else if (stream->match(tokens::percent)) {
@ -610,7 +717,7 @@ namespace dms {
if (op == codes::NOOP)
op = codes::MOD;
else
badSymbol();
badSymbol(stream);
stream->next();
}
else if (stream->match(tokens::caret)) {
@ -618,7 +725,7 @@ namespace dms {
if (op == codes::NOOP)
op = codes::POW;
else
badSymbol();
badSymbol(stream);
stream->next();
}
else if (stream->match(tokens::name,tokens::parao)) {
@ -630,10 +737,10 @@ namespace dms {
else if (right == nullptr)
right = tmpvalue;
else
badSymbol();
badSymbol(stream);
}
else {
badSymbol();
badSymbol(stream);
}
}
else if (stream->match(tokens::number)) {
@ -643,7 +750,7 @@ namespace dms {
else if (right == nullptr)
right = buildValue(num);
else
badSymbol();
badSymbol(stream);
}
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!
@ -652,9 +759,9 @@ namespace dms {
else if (right == nullptr)
right = buildVariable(stream->next().name);
else
badSymbol();
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)
return stream->restore(lastcmd, current_chunk); // Always return false and restores the position in stream!
cmd* cc = new cmd;
@ -662,11 +769,17 @@ namespace dms {
cc->args.push(v);
cc->args.push(wv);
current_chunk->addCmd(cc);
if (stream->match(tokens::newline) || stream->match(tokens::parac))
stream->next();
stream->next();
// We done!
int t=0;
return true;
}
else if (stream->match(tokens::newline)) {
stream->next();
}
else {
return stream->restore(lastcmd, current_chunk);
}
if (left != nullptr && right != nullptr && op != codes::NOOP) {
cmd* c = new cmd;
c->opcode = op;

View File

@ -446,6 +446,7 @@ namespace dms {
match_process_assignment(stream);
match_process_debug(stream);
match_process_goto(stream);
match_process_function(stream); // Naked Function
current = stream->next();
}
createBlock("$END$", bt_block);

View File

@ -28,7 +28,7 @@ namespace dms {
if (temp == cnk->cmds.size())
return false;
//cnk->cmds.erase(cnk->cmds.begin()+temp, cnk->cmds.end());
cnk->cmds.erase(cnk->cmds.begin()+temp, cnk->cmds.end());
return false;
}
std::vector<token> tokenstream::next(tokentype to, tokentype tc) {
@ -47,6 +47,24 @@ namespace dms {
}
return tok;
}
std::vector<token> tokenstream::next(tokentype to, tokentype tc, bool nonewline) {
std::vector<token> tok;
size_t open = 0;
if (peek().type == to) {
open++;
next(); // Consume
while (open != 0) {
if (peek().type == to)
open++;
else if (peek().type == tc)
open--;
else if (peek().type == tokens::newline)
return std::vector<token>();
tok.push_back(next());
}
}
return tok;
}
token tokenstream::peek() {
if (pos > this->tokens.size())
return token{ tokentype::none,codes::NOOP,"EOS",0 };
@ -180,10 +198,10 @@ namespace dms {
state->push_error(errors::error{ err,concat("Unexpected symbol '",stream->next().toString(),"'"),true,stream->peek().line_num,current_chunk });
}
void LineParser::badSymbol(tokenstream* stream) {
state->push_error(errors::error{ errors::unknown,concat("Unexpected symbol '",stream->next().toString(),"' RAW:",stream->last()),true,stream->peek().line_num,current_chunk });
state->push_error(errors::error{ errors::unknown,concat("Unexpected symbol '",stream->peek().toString(),"'"),true,stream->next().line_num,current_chunk });
}
void LineParser::badSymbol() {
state->push_error(errors::error{ errors::unknown,concat("Unexpected symbol '",_stream->next().toString(),"'"),true,_stream->peek().line_num,current_chunk });
state->push_error(errors::error{ errors::unknown,concat("Unexpected symbol '",_stream->peek().toString(),"'"),true,_stream->next().line_num,current_chunk });
}
void LineParser::buildSpeed(double s) {
cmd* c = new cmd;
@ -214,9 +232,6 @@ namespace dms {
chunk_type = bk_type;
current_chunk->type = bk_type;
cmd* c = new cmd;
c->opcode = codes::NOOP;
current_chunk->addCmd(c);
return true;
}
void LineParser::tokenizer(dms_state* state,std::vector<token> &toks) {

View File

@ -42,5 +42,6 @@ const std::string dms::codes::list[] = {
"MUL",
"DIV",
"POW",
"MOD"
"MOD",
"LIST"
};

View File

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

Binary file not shown.

View File

@ -46,7 +46,7 @@ Line <12> number 50
Line <12> newline
Line <12> newline
Line <13> name excited
Line <13> multiply *
Line <13> colon :
Line <13> string Hello Ryan!
Line <13> newline
Line <13> newline
@ -82,47 +82,135 @@ Line <22> newline
Line <22> newline
Line <23> newline
Line <23> newline
Line <24> bracketo [
Line <24> name Bob
Line <24> colon :
Line <24> name char
Line <24> bracketc ]
Line <24> name list
Line <24> equal =
Line <24> cbracketo {
Line <24> newline
Line <24> newline
Line <25> name age
Line <25> equal =
Line <25> number 24
Line <25> string Hello
Line <25> seperator ,
Line <25> newline
Line <25> newline
Line <26> name money
Line <26> equal =
Line <26> number 100
Line <26> true true
Line <26> seperator ,
Line <26> newline
Line <26> newline
Line <27> name excited
Line <27> colon :
Line <27> string path/to/file
Line <27> name function
Line <27> nil nil
Line <27> seperator ,
Line <27> newline
Line <27> newline
Line <28> parao (
Line <28> number 1000
Line <28> plus +
Line <28> newline
Line <28> newline
Line <29> bracketo [
Line <29> name newblock
Line <29> colon :
Line <29> name function
Line <29> parao (
Line <29> number 342
Line <29> parac )
Line <29> bracketc ]
Line <29> divide /
Line <29> name hi
Line <29> seperator ,
Line <29> false false
Line <29> seperator ,
Line <29> newline
Line <29> newline
Line <30> string Test #2
Line <30> name test
Line <30> parao (
Line <30> number 1
Line <30> seperator ,
Line <30> number 2
Line <30> parac )
Line <30> seperator ,
Line <30> newline
Line <30> newline
Line <31> string Does it parse this part properly?
Line <31> cbracketo {
Line <31> newline
Line <31> newline
Line <32> string huh
Line <32> number 1
Line <32> seperator ,
Line <32> newline
Line <32> newline
Line <32> eof
Line <33> false false
Line <33> seperator ,
Line <33> newline
Line <33> newline
Line <34> nil nil
Line <34> newline
Line <34> newline
Line <35> cbracketc }
Line <35> newline
Line <35> newline
Line <36> cbracketc }
Line <36> newline
Line <36> newline
Line <37> newline
Line <37> newline
Line <38> name test
Line <38> parao (
Line <38> newline
Line <38> newline
Line <39> cbracketo {
Line <39> newline
Line <39> newline
Line <40> number 1
Line <40> seperator ,
Line <40> newline
Line <40> newline
Line <41> number 2
Line <41> seperator ,
Line <41> newline
Line <41> newline
Line <42> number 3
Line <42> newline
Line <42> newline
Line <43> cbracketc }
Line <43> newline
Line <43> newline
Line <44> parac )
Line <44> newline
Line <44> newline
Line <45> newline
Line <45> newline
Line <46> bracketo [
Line <46> name Bob
Line <46> colon :
Line <46> name char
Line <46> bracketc ]
Line <46> newline
Line <46> newline
Line <47> name age
Line <47> equal =
Line <47> number 24
Line <47> newline
Line <47> newline
Line <48> name money
Line <48> equal =
Line <48> number 100
Line <48> newline
Line <48> newline
Line <49> name excited
Line <49> colon :
Line <49> string path/to/file
Line <49> name function
Line <49> newline
Line <49> newline
Line <50> newline
Line <50> newline
Line <51> bracketo [
Line <51> name newblock
Line <51> colon :
Line <51> name function
Line <51> parao (
Line <51> parac )
Line <51> bracketc ]
Line <51> newline
Line <51> newline
Line <52> string Test #2
Line <52> newline
Line <52> newline
Line <53> string Does it parse this part properly?
Line <53> newline
Line <53> newline
Line <54> string huh
Line <54> newline
Line <54> newline
Line <54> eof

View File

@ -21,6 +21,28 @@ using extendedDefine
Bob: "Testing..."
list = {
"Hello",
true,
nil,
(1000+
342)/hi,false,
test(1,2),
{
1,
false,
nil
}
}
test(
{
1,
2,
3
}
)
[Bob:char]
age = 24
money = 100

View File

@ -69,7 +69,10 @@ namespace dms {
out << (char)c.type << "nil";
}
else if (c.type == boolean) {
out << (char)c.type << c.b->getValue();
if(c.b->getValue())
out << (char)c.type << "true";
else
out << (char)c.type << "false";
}
else if (c.type == env) {
out << (char)c.type << "Env: " << c;

Binary file not shown.

Binary file not shown.

Binary file not shown.