Expressions should work now

This commit is contained in:
Ryan Ward 2020-09-11 23:59:53 -04:00
parent d69c24f4fd
commit feb877ff40
24 changed files with 298 additions and 203 deletions

View File

@ -1,2 +1,3 @@
 LineParserMatchProcess.cpp
F:\VSCWorkspace\DMS\DMS\LineParserMatchProcess.cpp(678): 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.

Binary file not shown.

View File

@ -19,6 +19,8 @@ namespace dms {
struct tokenstream {
std::vector<tokens::token> tokens;
size_t pos = 0;
std::stack<size_t> spos;
std::stack<size_t> stack;
void init(std::vector<tokens::token>* ptr);
tokens::token next();
void prev();
@ -29,10 +31,8 @@ namespace dms {
bool match(tokens::tokentype t1 = tokens::none, tokens::tokentype t2 = tokens::none, tokens::tokentype t3 = tokens::none, tokens::tokentype t4 = tokens::none, tokens::tokentype t5 = tokens::none, tokens::tokentype t6 = tokens::none, tokens::tokentype t7 = tokens::none, tokens::tokentype t8 = tokens::none, tokens::tokentype t9 = tokens::none, tokens::tokentype t10 = tokens::none, tokens::tokentype t11 = tokens::none, tokens::tokentype t12 = tokens::none);
bool match(tokens::tokentype* t1 = nullptr, tokens::tokentype* t2 = nullptr, tokens::tokentype* t3 = nullptr, tokens::tokentype* t4 = nullptr, tokens::tokentype* t5 = nullptr, tokens::tokentype* t6 = nullptr, tokens::tokentype* t7 = nullptr, tokens::tokentype* t8 = nullptr, tokens::tokentype* t9 = nullptr, tokens::tokentype* t10 = nullptr, tokens::tokentype* t11 = nullptr, tokens::tokentype* t12 = nullptr);
bool hasScope(size_t tabs);
bool restore(size_t p) {
pos = p;
return false; // This is a convience for something I will be doing so much
}
void store(chunk* c);
bool restore(cmd* c, chunk* cnk);
};
struct passer {
std::string stream;

View File

@ -9,7 +9,7 @@ namespace dms {
Compound DISP
*/
lastCall.push("MP_disp");
//lastCall.push("MP_disp");
if ((isBlock(bt_block) || isBlock(bt_method)) && stream->match(tokens::newline, tokens::string, tokens::newline)) {
stream->next(); // Standard consumption
std::string msg = stream->next().name;
@ -18,7 +18,7 @@ namespace dms {
c->args.push(buildValue());
c->args.push(buildValue(msg));
current_chunk->addCmd(c); // Add the cmd to the current chunk
lastCall.pop();
//lastCall.pop();
return true;
}
else if ((isBlock(bt_block) || isBlock(bt_method)) && stream->match(tokens::newline, tokens::name, tokens::colon, tokens::string, tokens::newline)) {
@ -34,7 +34,7 @@ namespace dms {
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
lastCall.pop();
//lastCall.pop();
return true;
}
else if ((isBlock(bt_block) || isBlock(bt_method)) && stream->match(tokens::name,tokens::colon,tokens::cbracketo)) {
@ -104,17 +104,17 @@ namespace dms {
// emotion: "path"
// looks like a simple disp command
else if (isBlock(bt_character) && stream->match(tokens::tab, tokens::name, tokens::colon, tokens::string, tokens::newline)) {
lastCall.pop();
//lastCall.pop();
return true;
}
// TODO: We still have to implement the compound disp
lastCall.pop();
//lastCall.pop();
return false;
}
bool LineParser::match_process_assignment(tokenstream* stream) {
// something equals something else lets go
lastCall.push("MP_assignment");
//lastCall.push("MP_assignment");
if (stream->match(tokens::name,tokens::equal)) {
value* var = buildVariable(stream->next().name); // The variable that we will be setting stuff to
stream->next(); // Consume the equal
@ -124,46 +124,47 @@ namespace dms {
if (match_process_expression(stream, var)) {
// Expressions can internally set variables
// We actually need to clean up our cmds
lastCall.pop();
//lastCall.pop();
return true;
}
else if (match_process_function(stream, var)) {
// Functions can internally set variables
// We actually need to clean up our cmds
lastCall.pop();
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();
//lastCall.pop();
return true;
}
else if (stream->match(tokens::False)) {
stream->next();
c->args.push(buildValue(false));
current_chunk->addCmd(c);
lastCall.pop();
//lastCall.pop();
return true;
}
else if (stream->match(tokens::string)) {
c->args.push(buildValue(stream->next().name));
current_chunk->addCmd(c);
lastCall.pop();
//lastCall.pop();
return true;
}
else if (stream->match(tokens::nil)) {
stream->next();
c->args.push(buildValue());
current_chunk->addCmd(c);
lastCall.pop();
//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();
//lastCall.pop();
return true;
}
else if (stream->match(tokens::bracketo, tokens::name, tokens::bracketc)) {
@ -172,20 +173,20 @@ namespace dms {
c->args.push(buildBlock(stream->next().name));
current_chunk->addCmd(c);
stream->next();
lastCall.pop();
//lastCall.pop();
return true;
}
else if (stream->match(tokens::name)) {
c->args.push(buildVariable(stream->next().name));
current_chunk->addCmd(c);
lastCall.pop();
//lastCall.pop();
return true;
}
else if (stream->match(tokens::newline)) {
stream->next();
}
}
lastCall.pop();
//lastCall.pop();
return false;
}
bool LineParser::match_process_debug(tokenstream* stream) {
@ -212,7 +213,7 @@ namespace dms {
return false;
}
bool LineParser::match_process_choice(tokenstream* stream) {
lastCall.push("MP_choice");
//lastCall.push("MP_choice");
token temp = stream->peek();
if (temp.raw == codes::CHOI && stream->match(tokens::control,tokens::string)) {
// Let's parse choice blocks.
@ -302,10 +303,10 @@ namespace dms {
delete cc;
if (hasfunc)
buildLabel(str);
lastCall.pop();
//lastCall.pop();
return true;
}
lastCall.pop();
//lastCall.pop();
return false;
}
@ -314,7 +315,7 @@ namespace dms {
delete[] v; // We didn't need it, lets clean it up!
}
bool LineParser::match_process_function(tokenstream* stream, value* v, bool nested) {
lastCall.push("MP_function");
//lastCall.push("MP_function");
/*
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!
@ -373,11 +374,17 @@ namespace dms {
tokenstream tempstream;
// This is a balanced consuming method (()(()))
std::vector<token> t = stream->next(tokens::parao, tokens::parac); // Consume and get tokens
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(end);
tempstream.init(&t); // Turn tokens we consumed into a tokenstream
value* tempval;
token tok;
// 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
print("> ", tempstream.peek());
tempval = buildVariable();
tok = tempstream.peek();
if (tempstream.match(tokens::seperator)) {
@ -385,6 +392,9 @@ namespace dms {
tempstream.next(); // Consume it
cleanup(tempval); // We don't need it
}
else if (match_process_expression(&tempstream, tempval)) {
c->args.push(tempval);
}
else if (tempstream.match(tokens::string)) {
cleanup(tempval);
tempval = buildValue(tempstream.next().name); // Get the string
@ -408,9 +418,11 @@ namespace dms {
tempval = buildValue(false);
c->args.push(tempval);
tempstream.next();
}
else if (match_process_expression(&tempstream, tempval)) {
// We have an expression and its been handled Whoo!!!
} else if (tempstream.match(tokens::nil)){
cleanup(tempval);
tempval = buildValue();
c->args.push(tempval);
tempstream.next();
}
// Final match this could be a function it might also be an expression
else if (match_process_function(&tempstream, tempval)) {
@ -432,7 +444,7 @@ namespace dms {
cleanup(tempval);
tempstream.next();
current_chunk->addCmd(c); // We push this onto the chunk after all dependants if any have been handled
lastCall.pop();
//lastCall.pop();
return true;
}
else {
@ -441,7 +453,7 @@ namespace dms {
}
}
}
lastCall.pop();
//lastCall.pop();
return false;
}
bool LineParser::match_process_goto(tokenstream* stream) {
@ -493,14 +505,20 @@ namespace dms {
bool LineParser::match_process_IFFF(tokenstream* stream) {
return false; // TODO finish this
}
void reset(value*& l,codes::op& op, value*& r) {
l = nullptr;
op = codes::NOOP;
r = nullptr;
}
bool LineParser::match_process_expression(tokenstream* stream, value* v) {
return false;
// I will have to consume for this to work so we need to keep track of what was incase we return false!
size_t start_pos = stream->pos;
stream->store(current_chunk);
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
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
token t = stream->peek();
cmd* c = new cmd;
/*
* We have a few built-in methods we will have to handle
@ -511,25 +529,151 @@ namespace dms {
* POW val v1 v2
* MOD val v1 v2
*/
token left; // lefthand
token op; // opperator
token right; // righthand
value* wv = nullptr;
value* left; // lefthand
codes::op op; // opperator
value* right; // righthand
reset(left, op, right);
size_t loops = 0;
bool hasOP = false;
while (stream->peek().type != tokens::none) {
if (t.type == tokens::parao) {
print(stream->peek());
if (stream->match(tokens::parao)) {
tokenstream temp;
temp.init(&(stream->next(tokens::parao, tokens::parac))); // Balanced match!
value* tmpvalue = buildVariable();
match_process_expression(&temp,tmpvalue);
if (match_process_expression(&temp, tmpvalue)) {
if (left == nullptr)
left = tmpvalue;
else if (right == nullptr)
right = tmpvalue;
else
badSymbol();
}
// We have a number
else if (t.type == tokens::number) {
else {
badSymbol();
}
// Take that temp value and set it to left or right TODO finish this
}
else if (stream->match(tokens::plus)) {
hasOP = true;
if (op == codes::NOOP)
op = codes::ADD;
else
badSymbol();
stream->next();
}
else if (stream->match(tokens::minus)) {
hasOP = true;
if (left == nullptr) {
left = buildValue(0); // -5 is the same as 0-5 right? Also -(5+5) is the same as 0-(5+5) So we good
}
if (op == codes::NOOP)
op = codes::SUB;
else
badSymbol();
stream->next();
}
else if (stream->match(tokens::multiply)) {
hasOP = true;
if (op == codes::NOOP)
op = codes::MUL;
else
badSymbol();
stream->next();
}
else if (stream->match(tokens::divide)) {
hasOP = true;
if (op == codes::NOOP)
op = codes::DIV;
else
badSymbol();
stream->next();
}
else if (stream->match(tokens::percent)) {
hasOP = true;
if (op == codes::NOOP)
op = codes::MOD;
else
badSymbol();
stream->next();
}
else if (stream->match(tokens::caret)) {
hasOP = true;
if (op == codes::NOOP)
op = codes::POW;
else
badSymbol();
stream->next();
}
else if (stream->match(tokens::name,tokens::parao)) {
//Function template ^^^ If we encounter an issue the method should push an error, incase it misses something we will!
value* tmpvalue = buildVariable();
if (match_process_function(stream,tmpvalue)) {
if (left == nullptr)
left = tmpvalue;
else if (right == nullptr)
right = tmpvalue;
else
badSymbol();
}
else {
badSymbol();
}
}
else if (stream->match(tokens::number)) {
double num = std::stod(stream->next().name);
if (left == nullptr)
left = buildValue(num);
else if (right == nullptr)
right = buildValue(num);
else
badSymbol();
}
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!
if (left == nullptr)
left = buildVariable(stream->next().name);
else if (right == nullptr)
right = buildVariable(stream->next().name);
else
badSymbol();
}
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;
cc->opcode = codes::ASGN;
cc->args.push(v);
cc->args.push(wv);
current_chunk->addCmd(cc);
if (stream->match(tokens::newline) || stream->match(tokens::parac))
stream->next();
// We done!
return true;
}
if (left != nullptr && right != nullptr && op != codes::NOOP) {
cmd* c = new cmd;
c->opcode = op;
if (wv == nullptr) {
value* temp = buildVariable();
c->args.push(temp);
wv = temp;
}
else {
wv = buildVariable();
c->args.push(wv);
}
c->args.push(left);
c->args.push(right);
current_chunk->addCmd(c);
reset(left, op, right);
left = wv;
}
}
}
else {
return stream->restore(start_pos); // Always return false and restores the position in stream!
return stream->restore(lastcmd, current_chunk); // Always return false and restores the position in stream!
}
}
}

View File

@ -16,6 +16,21 @@ namespace dms {
void tokenstream::prev() {
pos--;
}
void tokenstream::store(chunk* c) {
stack.push(c->cmds.size());
spos.push(pos);
}
bool tokenstream::restore(cmd* c, chunk* cnk) {
pos = spos.top();
spos.pop();
size_t temp = stack.top();
stack.pop();
if (temp == cnk->cmds.size())
return false;
//cnk->cmds.erase(cnk->cmds.begin()+temp, cnk->cmds.end());
return false;
}
std::vector<token> tokenstream::next(tokentype to, tokentype tc) {
std::vector<token> tok;
size_t open = 0;

View File

@ -36,5 +36,11 @@ const std::string dms::codes::list[] = {
"DACT",
"WAIT",
"APND",
"SSPK"
"SSPK",
"ADD",
"SUB",
"MUL",
"DIV",
"POW",
"MOD"
};

View File

@ -38,7 +38,13 @@ namespace dms::codes {
DACT,
WAIT,
APND,
SSPK
SSPK,
ADD,
SUB,
MUL,
DIV,
POW,
MOD
};
extern const std::string list[];
static bool isControl(const op code) {

Binary file not shown.

View File

@ -33,177 +33,113 @@ Line <9>NOOP name main
Line <9>NOOP bracketc
Line <9>NOOP newline
Line <9>NOOP newline
Line <10>NOOP string hello?
Line <10>NOOP name a
Line <10>NOOP equal
Line <10>NOOP number 100
Line <10>NOOP plus
Line <10>NOOP name test
Line <10>NOOP parao
Line <10>NOOP number 1
Line <10>NOOP seperator
Line <10>NOOP number 2
Line <10>NOOP parac
Line <10>NOOP minus
Line <10>NOOP parao
Line <10>NOOP name test2
Line <10>NOOP parao
Line <10>NOOP number 52
Line <10>NOOP plus
Line <10>NOOP name re
Line <10>NOOP seperator
Line <10>NOOP number 44
Line <10>NOOP minus
Line <10>NOOP name ee
Line <10>NOOP divide
Line <10>NOOP name test
Line <10>NOOP parao
Line <10>NOOP number 1
Line <10>NOOP seperator
Line <10>NOOP number 3
Line <10>NOOP parac
Line <10>NOOP seperator
Line <10>NOOP number 55
Line <10>NOOP minus
Line <10>NOOP number 23
Line <10>NOOP parac
Line <10>NOOP divide
Line <10>NOOP number 100
Line <10>NOOP parac
Line <10>NOOP newline
Line <10>NOOP newline
Line <11>NOOP name var1
Line <11>NOOP equal
Line <11>NOOP name func
Line <11>NOOP parao
Line <11>NOOP number 1
Line <11>NOOP seperator
Line <11>NOOP string string
Line <11>NOOP seperator
Line <11>NOOP name test
Line <11>NOOP parao
Line <11>NOOP number 1
Line <11>NOOP seperator
Line <11>NOOP number 2
Line <11>NOOP parac
Line <11>NOOP seperator
Line <11>NOOP name test2
Line <11>NOOP parao
Line <11>NOOP parac
Line <11>NOOP parac
Line <11>NOOP string Break for your eyes ;)
Line <11>NOOP newline
Line <11>NOOP newline
Line <12>NOOP name a
Line <12>NOOP name tes
Line <12>NOOP equal
Line <12>NOOP number 100
Line <12>NOOP plus
Line <12>NOOP name func
Line <12>NOOP parao
Line <12>NOOP number 1
Line <12>NOOP seperator
Line <12>NOOP string string
Line <12>NOOP seperator
Line <12>NOOP number 2
Line <12>NOOP plus
Line <12>NOOP number 5
Line <12>NOOP parac
Line <12>NOOP plus
Line <12>NOOP number 100
Line <12>NOOP newline
Line <12>NOOP newline
Line <13>NOOP name func
Line <13>NOOP parao
Line <13>NOOP number 1
Line <13>NOOP seperator
Line <13>NOOP string string
Line <13>NOOP seperator
Line <13>NOOP number 2
Line <13>NOOP plus
Line <13>NOOP number 5
Line <13>NOOP parac
Line <13>NOOP name gg
Line <13>NOOP equal
Line <13>NOOP true true
Line <13>NOOP newline
Line <13>NOOP newline
Line <14>NOOP label mylabel
Line <14>NOOP name temp
Line <14>NOOP equal
Line <14>NOOP name func
Line <14>NOOP parao
Line <14>NOOP number 123
Line <14>NOOP plus
Line <14>NOOP name test
Line <14>NOOP parao
Line <14>NOOP number 1
Line <14>NOOP seperator
Line <14>NOOP number 2
Line <14>NOOP parac
Line <14>NOOP seperator
Line <14>NOOP string TEST
Line <14>NOOP parac
Line <14>NOOP newline
Line <14>NOOP newline
Line <15>NOOP newline
Line <15>NOOP newline
Line <16>CHOI control
Line <16>NOOP string Pick one:
Line <16>NOOP cbracketo
Line <16>NOOP bracketo
Line <16>NOOP name Bob
Line <16>NOOP colon
Line <16>NOOP name char
Line <16>NOOP bracketc
Line <16>NOOP newline
Line <16>NOOP newline
Line <17>NOOP string first
Line <17>NOOP name func
Line <17>NOOP parao
Line <17>NOOP number 1
Line <17>NOOP seperator
Line <17>NOOP number 2
Line <17>NOOP seperator
Line <17>NOOP number 3
Line <17>NOOP parac
Line <17>NOOP name age
Line <17>NOOP equal
Line <17>NOOP number 24
Line <17>NOOP newline
Line <17>NOOP newline
Line <18>NOOP string second
Line <18>NOOP name func
Line <18>NOOP parao
Line <18>NOOP true true
Line <18>NOOP seperator
Line <18>NOOP false false
Line <18>NOOP parac
Line <18>NOOP name money
Line <18>NOOP equal
Line <18>NOOP number 100
Line <18>NOOP newline
Line <18>NOOP newline
Line <19>NOOP string third
Line <19>NOOP name func
Line <19>NOOP parao
Line <19>NOOP string hehe
Line <19>NOOP parac
Line <19>NOOP newline
Line <19>NOOP newline
Line <20>NOOP string forth
Line <20>NOOP name func
Line <20>NOOP bracketo
Line <20>NOOP name newblock
Line <20>NOOP colon
Line <20>NOOP name function
Line <20>NOOP parao
Line <20>NOOP string 1
Line <20>NOOP seperator
Line <20>NOOP number 2
Line <20>NOOP seperator
Line <20>NOOP false false
Line <20>NOOP parac
Line <20>NOOP bracketc
Line <20>NOOP newline
Line <20>NOOP newline
Line <21>NOOP string fifth
Line <21>NOOP gotoo
Line <21>NOOP string here
Line <21>NOOP string Test #2
Line <21>NOOP newline
Line <21>NOOP newline
Line <22>NOOP string sixth
Line <22>NOOP gotoo
Line <22>NOOP name name
Line <22>NOOP string Does it parse this part properly?
Line <22>NOOP newline
Line <22>NOOP newline
Line <23>NOOP string sevinth
Line <23>NOOP jump
Line <23>NOOP string there
Line <23>NOOP string huh
Line <23>NOOP newline
Line <23>NOOP newline
Line <24>NOOP string eight
Line <24>NOOP jump
Line <24>NOOP name name
Line <24>NOOP newline
Line <24>NOOP newline
Line <25>NOOP string nine
Line <25>NOOP name exit
Line <25>NOOP newline
Line <25>NOOP newline
Line <26>NOOP string ten
Line <26>NOOP exit
Line <26>NOOP number 0
Line <26>NOOP newline
Line <26>NOOP newline
Line <27>NOOP cbracketc
Line <27>NOOP newline
Line <27>NOOP newline
Line <28>NOOP newline
Line <28>NOOP newline
Line <29>NOOP bracketo
Line <29>NOOP name Bob
Line <29>NOOP colon
Line <29>NOOP name char
Line <29>NOOP bracketc
Line <29>NOOP newline
Line <29>NOOP newline
Line <30>NOOP name age
Line <30>NOOP equal
Line <30>NOOP number 24
Line <30>NOOP newline
Line <30>NOOP newline
Line <31>NOOP name money
Line <31>NOOP equal
Line <31>NOOP number 100
Line <31>NOOP newline
Line <31>NOOP newline
Line <32>NOOP newline
Line <32>NOOP newline
Line <33>NOOP bracketo
Line <33>NOOP name newblock
Line <33>NOOP colon
Line <33>NOOP name function
Line <33>NOOP parao
Line <33>NOOP parac
Line <33>NOOP bracketc
Line <33>NOOP newline
Line <33>NOOP newline
Line <34>NOOP string Test #2
Line <34>NOOP newline
Line <34>NOOP newline
Line <35>NOOP string Does it parse this part properly?
Line <35>NOOP newline
Line <35>NOOP newline
Line <36>NOOP string huh
Line <36>NOOP newline
Line <36>NOOP newline
Line <36>NOOP eof
Line <23>NOOP eof

View File

@ -7,24 +7,11 @@ version 1.2
using extendedDefine
[main]
"hello?"
var1 = func(1,"string",test(1,2),test2())
a = 100 + func(1,"string", 2+5) + 100
func(1,"string", 2+5)
::mylabel::
CHOICE "Pick one:" {
"first" func(1,2,3)
"second" func(true,false)
"third" func("hehe")
"forth" func("1",2,false)
"fifth" goto "here"
"sixth" goto name
"sevinth" jump "there"
"eight" jump name
"nine" exit
"ten" exit 0
}
a = 100 + test(1,2) - (test2(52+re,44-ee/test(1,3),55-23)/100)
"Break for your eyes ;)"
tes = 100 + 5
gg = true
temp = func(123+test(1,2),"TEST")
[Bob:char]
age = 24

Binary file not shown.

Binary file not shown.

Binary file not shown.