Implemented most of the code for choices

This commit is contained in:
Ryan Ward 2020-08-29 00:41:56 -04:00
parent 8464b62907
commit e6e5311a04
9 changed files with 577 additions and 288 deletions

View File

@ -25,6 +25,7 @@ namespace dms {
void prev(); void prev();
std::vector<tokens::token> next(tokens::tokentype to,tokens::tokentype tc); std::vector<tokens::token> next(tokens::tokentype to,tokens::tokentype tc);
tokens::token peek(); tokens::token peek();
tokens::token last();
std::vector<tokens::token> next(tokens::tokentype tk); std::vector<tokens::token> next(tokens::tokentype tk);
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 = 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 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);
@ -61,16 +62,16 @@ namespace dms {
bool match_process_debug(tokenstream* stream); bool match_process_debug(tokenstream* stream);
bool match_process_disp(tokenstream* stream); bool match_process_disp(tokenstream* stream);
bool match_process_choice(tokenstream* stream); bool match_process_choice(tokenstream* stream);
bool match_process_function(tokenstream* stream, value* v=nullptr); bool match_process_function(tokenstream* stream, value* v=nullptr, bool nested = true);
bool match_process_goto(tokenstream* stream); bool match_process_goto(tokenstream* stream);
bool match_process_jump(tokenstream* stream); bool match_process_jump(tokenstream* stream);
bool match_process_exit(tokenstream* stream); bool match_process_exit(tokenstream* stream);
bool match_process_label(tokenstream* stream); bool match_process_label(tokenstream* stream);
bool match_process_expression(tokenstream* stream); bool match_process_expression(tokenstream* stream, value* v);
bool match_process_IFFF(tokenstream* stream);
// Utils // Utils
bool createBlock(std::string bk_name, blocktype bk_type); bool createBlock(std::string bk_name, blocktype bk_type);
bool isExpression(tokenstream* stream);
bool isBlock(); bool isBlock();
bool isBlock(blocktype bk_type); bool isBlock(blocktype bk_type);
void tolower(std::string &str); void tolower(std::string &str);

View File

@ -49,15 +49,115 @@ namespace dms {
return false; return false;
} }
bool LineParser::match_process_choice(tokenstream* stream) { bool LineParser::match_process_choice(tokenstream* stream) {
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;
print("Prompt: ", prompt);
bool good = true;
std::string option;
cmd* c = new cmd;
// Create a unique label name by using the line number
std::string choicelabel = concat("$CHOI_END_", stream->peek().line_num);
c->opcode = codes::CHOI;
c->args.push(buildValue(prompt));
current_chunk->addCmd(c); // We will keep a reference to this and add to it as we go through the list
bool start = false;
/*
What's going on here might be tough to understand just by looking at the code
The bytecode generated by this code might look something like this:
off op opcodes
0 CHOI "Pick one!" "Choice 1" "Choice 2" "Choice 3" "Choice 4"
1 FUNC print "You picked 1!"
2 GOTO $CHOI_END_1
3 FUNC print "You picked 2!"
4 GOTO $CHOI_END_1
5 JUMP park
6 NOOP
7 GOTO mylabel
8 LABL $CHOI_END_1
The CHOI code tells the vm that we need to process user input. The input we get in a number 0-3
I know we have 4 choices
If the user provides us with a 0 then we need to move to off 1
If the user provides us with a 1 then we need to move to off 3
If the user provides us with a 2 then we need to move to off 5
If the user provides us with a 3 then we need to move to off 7
I'm sure you see the pattern here. 1 (+2) 3 (+2) 5... We only need to jump once then let the vm continue like normal.
The math for this is: [current_pos] + (n*2+1)
n*2+1 (n = 0) = 1
n*2+1 (n = 1) = 3
n*2+1 (n = 2) = 5
n*2+1 (n = 3) = 7
Which is why you see NOOP for the JUMP code. If GOTO wasn't the last choice possible to make there would be a NOOP after that as well.
The NOOP ensures the pattern stays.
If we are provided with a number greater than 3 then we can push an execption.
*/
while (!stream->match(tokens::cbracketc)) {
// We need to match the possible options for a choice block
/*
"option" function()
"option" goto ""
"option" goto var
"option" jump ""
"option" jump var
"option" exit [0]
Exit takes an optional int
*/
if (stream->match(tokens::cbracketo) && !start) {
start = true;
stream->next();
}
else if (stream->match(tokens::cbracketo) && start) {
state->push_error(errors::error{ errors::choice_unknown,concat("Unexpected symbol ",stream->next()),true,stream->peek().line_num });
}
else if (stream->match(tokens::string)) {
std::string name = stream->next().name;
print("Option: ", name);
c->args.push(buildValue(name)); // We append the choice to the first part of the CHOI cmd
// We consumed the option now lets do some matching, note that all of these are one liners in the bytecode!
if (match_process_function(stream,nullptr,false)) { // No returns and also no nesting of functions!
}
else if (match_process_goto(stream)) {
current_chunk->addCmd(new cmd{codes::NOOP }); // Add noop to post-goto command
}
else if (match_process_jump(stream)) {
current_chunk->addCmd(new cmd{ codes::NOOP }); // Add noop to post-jump command
}
else if (match_process_exit(stream)) {
current_chunk->addCmd(new cmd{ codes::NOOP }); // Add noop to post-exit command
}
}
// Last Match
else if (stream->match(tokens::newline)) {
stream->next(); // Consume
}
else if (!stream->match(tokens::cbracketc)) {
state->push_error(errors::error{ errors::choice_unknown,concat("Unexpected symbol ",stream->next()),true,stream->peek().line_num });
}
}
return true;
}
return false; return false;
} }
void cleanup(value* v) {
v->nuke(); // Make sure we clean up the data
delete[] v; // We didn't need it, lets clean it up!
}
/// <summary> /// <summary>
/// Recursively parse through function related tokens /// Recursively parse through function related tokens
/// </summary> /// </summary>
/// <param name="stream"></param> /// <param name="stream"></param>
/// <param name="v"></param> /// <param name="v"></param>
/// <returns></returns> /// <returns></returns>
bool LineParser::match_process_function(tokenstream* stream, value* v) { bool LineParser::match_process_function(tokenstream* stream, value* v, bool nested) {
/* /*
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!
@ -116,34 +216,73 @@ namespace dms {
// Next we add arguments this is where things get interesting // Next we add arguments this is where things get interesting
tokenstream tempstream; tokenstream tempstream;
// This is a balanced consuming method (()(())) // This is a balanced consuming method (()(()))
std::vector<token> t = stream->next(tokens::parao, tokens::parac); std::vector<token> t = stream->next(tokens::parao, tokens::parac); // Consume and get tokens
tempstream.init(&t); tempstream.init(&t); // Turn tokens we consumed into a tokenstream
tokens::token tok; 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 while (tempstream.peek().type != tokens::none) { // End of stream
if (tempstream.match(tokens::string)) { tempval = buildVariable();
// We have a string argument tok = tempstream.peek();
if (tempstream.match(tokens::seperator)) {
// We have a seperator for function arguments
tempstream.next(); // Consume it
cleanup(tempval); // We don't need it
}
else if (tempstream.match(tokens::string)) {
cleanup(tempval);
tempval = buildValue(tempstream.next().name); // Get the string
c->args.push(tempval); // add this argument to the function opcodes
} }
else if (tempstream.match(tokens::number)) { else if (tempstream.match(tokens::number)) {
// This is an interesting one This could be just a number, or an expression with functions n stuff cleanup(tempval);
std::string str = tempstream.next().name;
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
} }
else if (match_process_expression(&tempstream)) { else if (tempstream.match(tokens::True)) {
cleanup(tempval);
tempval = buildValue(true);
c->args.push(tempval);
tempstream.next();
}
else if (tempstream.match(tokens::False)) {
cleanup(tempval);
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!!! // We have an expression and its been handled Whoo!!!
} }
// Final match this could be a function it might also be an expression // Final match this could be a function it might also be an expression
else if (match_process_function(&tempstream, buildVariable(""))) { 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 });
}
print("Nested ok!");
c->args.push(tempval);
} }
else if (tempstream.match(tokens::seperator)) { else if (tempstream.match(tokens::name)) {
// We have a seperator for function arguments cleanup(tempval);
tempstream.next(); // Consume it tempval = buildVariable(tempstream.next().name);
c->args.push(tempval);
}
else if (tempstream.match(tokens::newline)) {
tempstream.next();
}
else if (tempstream.match(tokens::parac)) {
cleanup(tempval);
tempstream.next();
current_chunk->addCmd(c); // We push this onto the chunk after all dependants if any have been handled
return true;
}
else {
cleanup(tempval); // Cleanup
state->push_error(errors::error{ errors::badtoken,concat("Invalid symbol: ",tempstream.peek()),true, tempstream.peek().line_num});
} }
} }
/*std::cout << "---Tokens---" << std::endl;
for (size_t i = 0; i < t.size() - 1; i++) {
std::cout << t[i] << std::endl;
}*/
current_chunk->addCmd(c); // We push this onto the chunk after all dependants if any have been handled
wait();
} }
return false; return false;
} }
@ -159,25 +298,63 @@ namespace dms {
bool LineParser::match_process_label(tokenstream* stream) { bool LineParser::match_process_label(tokenstream* stream) {
return false; return false;
} }
bool LineParser::match_process_expression(tokenstream* stream) { bool LineParser::match_process_IFFF(tokenstream* stream) {
return false;
}
bool LineParser::match_process_expression(tokenstream* stream, value* v) {
return false; // Method isn't done yet, we will get an error without this!
// 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!
size_t start_pos = stream->pos; size_t start_pos = stream->pos;
// 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
token t = stream->peek(); token t = stream->peek();
if (t.type == tokens::parao) { cmd* c = new cmd;
tokenstream temp; /*
temp.init(&(stream->next(tokens::parao, tokens::parac))); // Balanced match! * We have a few built-in methods we will have to handle
return match_process_expression(&temp); // Return true is everything else checks out! * ADD val v1 v2
} * SUB val v1 v2
else if (t.type == tokens::number) { * MUL val v1 v2
* DIV val v1 v2
* POW val v1 v2
* MOD val v1 v2
*/
/* lua code which was actually really compact and works!
if not expr:match("[/%^%+%-%*%%]") then --[[print("No math to do!")]] return expr end
-- handle pharanses
expr=expr:gsub("([%W])(%-%d)",function(b,a)
return b.."(0-"..a:match("%d+")..")"
end)
-- Work on functions
expr = expr:gsub("([_%w]+)(%b())",function(func,args)
local v = gen("$")
local fnwr = {self.current_line[1],self.current_line[2],FWNR,self.current_line[4],v.." = "..func..args}
self:parseFNWR(fnwr)
return v
end)
expr = expr:gsub("(%b())",function(a)
return self:parseExpr(a:sub(2,-2))
end)
return self:chop(expr)
*/
token left; // lefthand
token op; // opperator
token right; // righthand
while (stream->peek().type != tokens::none) {
if (t.type == tokens::parao) {
tokenstream temp;
temp.init(&(stream->next(tokens::parao, tokens::parac))); // Balanced match!
return match_process_expression(&temp,buildVariable("Work On This")); // Return true is everything else checks out!
}
// We have a number
else if (t.type == tokens::number) {
}
} }
} }
else { else {
return stream->restore(start_pos); // Always return false and restores the position in stream! return stream->restore(start_pos); // Always return false and restores the position in stream!
} }
} }
}
} }

View File

@ -53,10 +53,10 @@ namespace dms {
stream.next('\n'); // Seek until you find a newline stream.next('\n'); // Seek until you find a newline
} }
else if (data == '\n') { else if (data == '\n') {
doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer); doCheck(&stream, &t_vec, line-2, isNum, hasDec, &buffer);
t_vec.push_back(token{ tokens::newline,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::newline,codes::NOOP,"",line - 2 });
if (isNum) { if (isNum) {
t_vec.push_back(token{ tokens::number,codes::NOOP,stream.processBuffer(buffer),line }); t_vec.push_back(token{ tokens::number,codes::NOOP,stream.processBuffer(buffer),line - 2 });
buffer.clear(); buffer.clear();
isNum = false; isNum = false;
} }
@ -71,7 +71,7 @@ namespace dms {
stream.next(); stream.next();
} }
else if (data == ':' && stream.peek() == ':' && labelStart) { else if (data == ':' && stream.peek() == ':' && labelStart) {
t_vec.push_back(token{ tokens::label,codes::NOOP,stream.processBuffer(buffer),line }); t_vec.push_back(token{ tokens::label,codes::NOOP,stream.processBuffer(buffer),line - 2 });
buffer.clear(); buffer.clear();
stream.next(); stream.next();
labelStart = false; labelStart = false;
@ -82,9 +82,12 @@ namespace dms {
} }
else if (data == '"' && isStr) { else if (data == '"' && isStr) {
isStr = false; isStr = false;
t_vec.push_back(token{ tokens::string,codes::NOOP,stream.processBuffer(buffer),line }); t_vec.push_back(token{ tokens::string,codes::NOOP,stream.processBuffer(buffer),line - 2 });
buffer.clear(); buffer.clear();
} }
else if (isStr) {
buffer.push_back(data);
}
else if (isdigit(data)) { else if (isdigit(data)) {
isNum = true; isNum = true;
buffer.push_back(data); buffer.push_back(data);
@ -97,153 +100,157 @@ namespace dms {
buffer.push_back(data); buffer.push_back(data);
} }
else if (data == '.' && isNum && hasDec) { else if (data == '.' && isNum && hasDec) {
t_vec.push_back(token{ tokens::number,codes::ERRO,"Malformed number!",line }); t_vec.push_back(token{ tokens::number,codes::ERRO,"Malformed number!",line - 2 });
} }
else if (data == '[') { else if (data == '[') {
doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer); doCheck(&stream, &t_vec, line - 2, isNum, hasDec, &buffer);
t_vec.push_back(token{ tokens::bracketo,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::bracketo,codes::NOOP,"",line - 2 });
} }
else if (data == ']') { else if (data == ']') {
doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer); doCheck(&stream, &t_vec, line - 2, isNum, hasDec, &buffer);
t_vec.push_back(token{ tokens::bracketc,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::bracketc,codes::NOOP,"",line - 2 });
} }
else if (data == '(') { else if (data == '(') {
doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer); doCheck(&stream, &t_vec, line - 2, isNum, hasDec, &buffer);
t_vec.push_back(token{ tokens::parao,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::parao,codes::NOOP,"",line - 2 });
} }
else if (data == ')') { else if (data == ')') {
doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer); doCheck(&stream, &t_vec, line - 2, isNum, hasDec, &buffer);
t_vec.push_back(token{ tokens::parac,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::parac,codes::NOOP,"",line - 2 });
} }
else if (data == ',') { else if (data == ',') {
doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer); doCheck(&stream, &t_vec, line - 2, isNum, hasDec, &buffer);
t_vec.push_back(token{ tokens::seperator,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::seperator,codes::NOOP,"",line - 2 });
} }
else if (data == '.') { else if (data == '.') {
//doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer); //doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer);
t_vec.push_back(token{ tokens::dot,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::dot,codes::NOOP,"",line - 2 });
} }
else if (data == '{') { else if (data == '{') {
doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer); doCheck(&stream, &t_vec, line - 2, isNum, hasDec, &buffer);
t_vec.push_back(token{ tokens::cbracketo,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::cbracketo,codes::NOOP,"",line - 2 });
} }
else if (data == '}') { else if (data == '}') {
doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer); doCheck(&stream, &t_vec, line - 2, isNum, hasDec, &buffer);
t_vec.push_back(token{ tokens::cbracketc,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::cbracketc,codes::NOOP,"",line - 2 });
} }
else if (data == '+') { else if (data == '+') {
doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer); doCheck(&stream, &t_vec, line - 2, isNum, hasDec, &buffer);
t_vec.push_back(token{ tokens::plus,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::plus,codes::NOOP,"",line - 2 });
} }
else if (data == '-') { else if (data == '-') {
doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer); doCheck(&stream, &t_vec, line - 2, isNum, hasDec, &buffer);
t_vec.push_back(token{ tokens::minus,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::minus,codes::NOOP,"",line - 2 });
} }
else if (data == '*') { else if (data == '*') {
doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer); doCheck(&stream, &t_vec, line - 2, isNum, hasDec, &buffer);
t_vec.push_back(token{ tokens::multiply,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::multiply,codes::NOOP,"",line - 2 });
} }
else if (data == '/') { else if (data == '/') {
doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer); doCheck(&stream, &t_vec, line - 2, isNum, hasDec, &buffer);
t_vec.push_back(token{ tokens::divide,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::divide,codes::NOOP,"",line - 2 });
} }
else if (data == '^') { else if (data == '^') {
doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer); doCheck(&stream, &t_vec, line - 2, isNum, hasDec, &buffer);
t_vec.push_back(token{ tokens::pow,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::pow,codes::NOOP,"",line - 2 });
} }
else if (data == '%') { else if (data == '%') {
doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer); doCheck(&stream, &t_vec, line - 2, isNum, hasDec, &buffer);
t_vec.push_back(token{ tokens::mod,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::mod,codes::NOOP,"",line - 2 });
} }
else if (data == '=') { else if (data == '=') {
doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer); doCheck(&stream, &t_vec, line - 2, isNum, hasDec, &buffer);
t_vec.push_back(token{ tokens::equal,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::equal,codes::NOOP,"",line - 2 });
} }
else if (data == ':') { else if (data == ':') {
doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer); doCheck(&stream, &t_vec, line - 2, isNum, hasDec, &buffer);
t_vec.push_back(token{ tokens::colon,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::colon,codes::NOOP,"",line - 2 });
} }
else if (data == ';') { else if (data == ';') {
doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer); doCheck(&stream, &t_vec, line - 2, isNum, hasDec, &buffer);
t_vec.push_back(token{ tokens::newline,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::newline,codes::NOOP,"",line - 2 });
} }
else if (data == '!') { else if (data == '!') {
doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer); doCheck(&stream, &t_vec, line - 2, isNum, hasDec, &buffer);
t_vec.push_back(token{ tokens::Not,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::Not,codes::NOOP,"",line - 2 });
} }
else if (data == '\t') { else if (data == '\t') {
doCheck(&stream, &t_vec, line, isNum, hasDec, &buffer); doCheck(&stream, &t_vec, line - 2, isNum, hasDec, &buffer);
t_vec.push_back(token{ tokens::tab,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::tab,codes::NOOP,"",line - 2 });
} }
if (data == ' ' && !isStr) { // tokens end with a space if (data == ' ' && !isStr) { // tokens end with a space
std::string str = stream.processBuffer(buffer); std::string str = stream.processBuffer(buffer);
tolower(str); tolower(str);
if (str == "enable") { if (str == "enable") {
t_vec.push_back(token{ tokens::flag,codes::ENAB,"",line }); t_vec.push_back(token{ tokens::flag,codes::ENAB,"",line - 2 });
} }
else if (str == "entry") { else if (str == "entry") {
t_vec.push_back(token{ tokens::flag,codes::ENTR,"",line }); t_vec.push_back(token{ tokens::flag,codes::ENTR,"",line - 2 });
} }
else if (str == "loadfile") { else if (str == "loadfile") {
t_vec.push_back(token{ tokens::flag,codes::LOAD,"",line }); t_vec.push_back(token{ tokens::flag,codes::LOAD,"",line - 2 });
} }
else if (str == "version") { else if (str == "version") {
t_vec.push_back(token{ tokens::flag,codes::VERN,"",line }); t_vec.push_back(token{ tokens::flag,codes::VERN,"",line - 2 });
} }
else if (str == "using") { else if (str == "using") {
t_vec.push_back(token{ tokens::flag,codes::USIN,"",line }); t_vec.push_back(token{ tokens::flag,codes::USIN,"",line - 2 });
} }
else if (str == "disable") { else if (str == "disable") {
t_vec.push_back(token{ tokens::flag,codes::DISA,"",line }); t_vec.push_back(token{ tokens::flag,codes::DISA,"",line - 2 });
} }
else if (str == "if") { else if (str == "if") {
t_vec.push_back(token{ tokens::control,codes::IFFF,"",line }); t_vec.push_back(token{ tokens::control,codes::IFFF,"",line - 2 });
} }
else if (str == "elseif") { else if (str == "elseif") {
t_vec.push_back(token{ tokens::control,codes::ELIF,"",line }); t_vec.push_back(token{ tokens::control,codes::ELIF,"",line - 2 });
} }
else if (str == "while") { else if (str == "while") {
t_vec.push_back(token{ tokens::control,codes::WHLE,"",line }); t_vec.push_back(token{ tokens::control,codes::WHLE,"",line - 2 });
} }
else if (str == "true") { else if (str == "true") {
t_vec.push_back(token{ tokens::True,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::True,codes::NOOP,"",line - 2 });
} }
else if (str == "false") { else if (str == "false") {
t_vec.push_back(token{ tokens::False,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::False,codes::NOOP,"",line - 2 });
} }
else if (str == "else") { else if (str == "else") {
t_vec.push_back(token{ tokens::control,codes::ELSE,"",line }); t_vec.push_back(token{ tokens::control,codes::ELSE,"",line - 2 });
} }
else if (str == "and") { else if (str == "and") {
t_vec.push_back(token{ tokens::And,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::And,codes::NOOP,"",line - 2 });
} }
else if (str == "or") { else if (str == "or") {
t_vec.push_back(token{ tokens::Or,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::Or,codes::NOOP,"",line - 2 });
} }
else if (str == "for") { else if (str == "for") {
t_vec.push_back(token{ tokens::For,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::For,codes::NOOP,"",line - 2 });
} }
else if (str == "choice") { else if (str == "choice") {
t_vec.push_back(token{ tokens::control,codes::CHOI,"",line }); t_vec.push_back(token{ tokens::control,codes::CHOI,"",line - 2 });
} }
else if (str == "return") { else if (str == "return") {
t_vec.push_back(token{ tokens::ret,codes::RETN,"",line }); t_vec.push_back(token{ tokens::ret,codes::RETN,"",line - 2 });
} }
else if (str == "nil") { else if (str == "nil") {
t_vec.push_back(token{ tokens::nil,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::nil,codes::NOOP,"",line - 2 });
} }
else if (str == "goto") { else if (str == "goto") {
t_vec.push_back(token{ tokens::gotoo,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::gotoo,codes::NOOP,"",line - 2 });
} }
else if (str == "jump") { else if (str == "jump") {
t_vec.push_back(token{ tokens::jump,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::jump,codes::NOOP,"",line - 2 });
} }
else if (str == "exit") { else if (str == "exit") {
t_vec.push_back(token{ tokens::exit,codes::NOOP,"",line }); t_vec.push_back(token{ tokens::exit,codes::NOOP,"",line - 2 });
}
else if (utils::isNum(str) && str.size()!=0) {
t_vec.push_back(token{ tokens::number,codes::NOOP,stream.processBuffer(buffer),line - 2 });
isNum = false;
} }
else if (utils::isalphanum(str) && str.size() > 0) { else if (utils::isalphanum(str) && str.size() > 0) {
t_vec.push_back(token{ tokens::name,codes::NOOP,stream.processBuffer(buffer),line }); t_vec.push_back(token{ tokens::name,codes::NOOP,stream.processBuffer(buffer),line - 2 });
} }
else { else {
// Unknown command! // Unknown command!
@ -255,7 +262,7 @@ namespace dms {
} }
data = stream.next(); data = stream.next();
} }
t_vec.push_back(token{ tokens::eof,codes::NOOP,"",line + 1 }); t_vec.push_back(token{ tokens::eof,codes::NOOP,"",line - 1 });
std::ofstream outputFile("dump.txt"); std::ofstream outputFile("dump.txt");
outputFile << "Token Dump:" << std::endl; outputFile << "Token Dump:" << std::endl;
for (size_t i = 0; i < t_vec.size(); i++) { for (size_t i = 0; i < t_vec.size(); i++) {
@ -376,100 +383,11 @@ namespace dms {
} }
// Control Handle all controls here // Control Handle all controls here
if (stream.match(tokens::control)) { if (stream.match(tokens::control)) {
token control = stream.next(); //token control = stream.next();
if (control.raw == codes::CHOI && stream.peek().type == tokens::string) { if (match_process_choice(&stream)) {
// Let's parse choice blocks. // Handle choice stuff
std::string prompt = stream.next().name;
print("Prompt: ", prompt);
bool good = true;
std::string option;
cmd* c = new cmd;
// Create a unique label name by using the line number
std::string choicelabel = concat("$CHOI_END_", stream.peek().line_num);
wait();
c->opcode = codes::CHOI;
c->args.push(buildValue(prompt));
current_chunk->addCmd(c); // We will keep a reference to this and add to it as we go through the list
bool start = false;
/*
What's going on here might be tough to understand just by looking at the code
The bytecode generated by this code might look something like this:
off op opcodes
0 CHOI "Pick one!" "Choice 1" "Choice 2" "Choice 3" "Choice 4"
1 FUNC print "You picked 1!"
2 GOTO $CHOI_END_1
3 FUNC print "You picked 2!"
4 GOTO $CHOI_END_1
5 JUMP park
6 NOOP
7 GOTO mylabel
8 LABL $CHOI_END_1
The CHOI code tells the vm that we need to process user input. The input we get in a number 0-3
I know we have 4 choices
If the user provides us with a 0 then we need to move to off 1
If the user provides us with a 1 then we need to move to off 3
If the user provides us with a 2 then we need to move to off 5
If the user provides us with a 3 then we need to move to off 7
I'm sure you see the pattern here. 1 (+2) 3 (+2) 5... We only need to jump once then let the vm continue like normal.
The math for this is: [current_pos] + (n*2+1)
n*2+1 (n = 0) = 1
n*2+1 (n = 1) = 3
n*2+1 (n = 2) = 5
n*2+1 (n = 3) = 7
Which is why you see NOOP for the JUMP code. If GOTO wasn't the last choice possible to make there would be a NOOP after that as well.
The NOOP ensures the pattern stays.
If we are provided with a number greater than 3 then we can push an execption.
*/
while (!stream.match(tokens::cbracketc)) {
// We need to match the possible options for a choice block
/*
"option" function()
"option" goto ""
"option" goto var
"option" jump ""
"option" jump var
"option" exit [0]
Exit takes an optional int
*/
if (stream.match(tokens::cbracketo) && !start) {
start = true;
stream.next();
}
else if (stream.match(tokens::cbracketo) && start) {
state->push_error(errors::error{ errors::choice_unknown,concat("Unexpected symbol ",stream.next()),true,stream.peek().line_num });
}
else if (stream.match(tokens::string)) {
std::string name = stream.next().name;
print("Option: ", name);
c->args.push(buildValue(name)); // We append the choice to the first part of the CHOI cmd
// We consumed the option now lets do some matching, note that all of these are one liners in the bytecode!
if (match_process_function(&stream)) {
}
else if (match_process_goto(&stream)) {
}
else if (match_process_jump(&stream)) {
}
else if (match_process_exit(&stream)) {
}
}
// Last Match
else if (stream.match(tokens::newline)) {
stream.next(); // Consume
}
else if (!stream.match(tokens::cbracketc)) {
state->push_error(errors::error{ errors::choice_unknown,concat("Unexpected symbol ",stream.next()),true,stream.peek().line_num });
}
}
} }
else if (control.raw == codes::IFFF) { else if (match_process_IFFF(&stream)) {
// This will probably be the toughest one of them all // This will probably be the toughest one of them all
} }
} }

View File

@ -6,6 +6,9 @@ namespace dms {
void tokenstream::init(std::vector<token>* ptr) { void tokenstream::init(std::vector<token>* ptr) {
this->tokens = *ptr; this->tokens = *ptr;
} }
token tokenstream::last() {
return this->tokens[pos-1];
}
token tokenstream::next() { token tokenstream::next() {
if (pos > this->tokens.size()) if (pos > this->tokens.size())
return token{ tokentype::none,codes::NOOP,"EOS",0 }; return token{ tokentype::none,codes::NOOP,"EOS",0 };

View File

@ -1,128 +1,309 @@
Token Dump: Token Dump:
Line <18446744073709551615>NOOP newline
Line <0>NOOP newline
Line <1>ENTR flag
Line <1>NOOP name main
Line <1>NOOP newline Line <1>NOOP newline
Line <2>ENAB flag
Line <2>NOOP name warnings
Line <2>NOOP newline Line <2>NOOP newline
Line <3>NOOP bracketo Line <3>DISA flag
Line <3>NOOP name default Line <3>NOOP name omniscient
Line <3>NOOP colon
Line <3>NOOP name char
Line <3>NOOP bracketc
Line <3>NOOP newline Line <3>NOOP newline
Line <4>NOOP newline Line <4>NOOP newline
Line <5>NOOP name money
Line <5>NOOP equal
Line <5>NOOP number 0
Line <5>NOOP newline Line <5>NOOP newline
Line <6>VERN flag
Line <6>NOOP number 1.2
Line <6>NOOP newline Line <6>NOOP newline
Line <7>NOOP bracketo Line <7>USIN flag
Line <7>NOOP name Ryan Line <7>NOOP name extendedDefine
Line <7>NOOP colon
Line <7>NOOP name char
Line <7>NOOP bracketc
Line <7>NOOP newline Line <7>NOOP newline
Line <8>NOOP name age
Line <8>NOOP equal
Line <8>NOOP number 21
Line <8>NOOP newline Line <8>NOOP newline
Line <9>NOOP name money Line <9>NOOP bracketo
Line <9>NOOP equal Line <9>NOOP name main
Line <9>NOOP number 1000 Line <9>NOOP bracketc
Line <9>NOOP cbracketo
Line <9>NOOP newline Line <9>NOOP newline
Line <10>NOOP name Ryan
Line <10>NOOP colon
Line <10>NOOP string This works!
Line <10>NOOP newline Line <10>NOOP newline
Line <11>NOOP name calm Line <11>NOOP name DEBUG
Line <11>NOOP colon Line <11>NOOP string What's up
Line <11>NOOP string ./path/to/file
Line <11>NOOP newline Line <11>NOOP newline
Line <12>NOOP name excited Line <12>NOOP name Ryan
Line <12>NOOP colon Line <12>NOOP colon
Line <12>NOOP string ./path/to/file Line <12>NOOP cbracketo
Line <12>NOOP newline Line <12>NOOP newline
Line <13>NOOP name speed
Line <13>NOOP number 100
Line <13>NOOP mod
Line <13>NOOP newline Line <13>NOOP newline
Line <14>NOOP bracketo Line <13>NOOP name calm
Line <14>NOOP name step Line <13>NOOP string Hello Bob,
Line <14>NOOP colon Line <13>NOOP newline
Line <14>NOOP name function Line <14>NOOP name wait
Line <14>NOOP parao Line <14>NOOP number 0.455
Line <14>NOOP name a
Line <14>NOOP seperator
Line <14>NOOP name b
Line <14>NOOP seperator
Line <14>NOOP name c
Line <14>NOOP parac
Line <14>NOOP bracketc
Line <14>NOOP newline Line <14>NOOP newline
Line <15>NOOP string Testing... Line <15>NOOP name excited
Line <15>NOOP string how are you doing?
Line <15>NOOP newline Line <15>NOOP newline
Line <16>NOOP name d
Line <16>NOOP equal
Line <16>NOOP parao
Line <16>NOOP name 100
Line <16>NOOP number
Line <16>NOOP plus
Line <16>NOOP name b
Line <16>NOOP parac
Line <16>NOOP divide
Line <16>NOOP name c
Line <16>NOOP newline Line <16>NOOP newline
Line <17>NOOP name e Line <17>NOOP cbracketc
Line <17>NOOP equal
Line <17>NOOP string somestring
Line <17>NOOP newline Line <17>NOOP newline
Line <18>NOOP name e
Line <18>NOOP equal
Line <18>NOOP nil nil
Line <18>NOOP newline Line <18>NOOP newline
Line <19>NOOP name g Line <19>NOOP name tester
Line <19>NOOP equal Line <19>NOOP equal
Line <19>NOOP false false Line <19>NOOP string Hello
Line <19>NOOP newline Line <19>NOOP newline
Line <20>RETN ret Line <20>NOOP name food
Line <20>NOOP name d Line <20>NOOP equal
Line <20>NOOP number 3
Line <20>NOOP newline Line <20>NOOP newline
Line <21>NOOP name a
Line <21>NOOP equal
Line <21>NOOP name list
Line <21>NOOP bracketo
Line <21>NOOP number 1
Line <21>NOOP bracketc
Line <21>NOOP newline Line <21>NOOP newline
Line <22>NOOP bracketo
Line <22>NOOP name inventory
Line <22>NOOP colon
Line <22>NOOP name env
Line <22>NOOP bracketc
Line <22>NOOP newline Line <22>NOOP newline
Line <23>NOOP name slot1 Line <23>IFFF control
Line <23>NOOP number Line <23>NOOP name statment
Line <23>NOOP equal Line <23>NOOP cbracketo
Line <23>NOOP string
Line <23>NOOP newline Line <23>NOOP newline
Line <24>NOOP name slot2 Line <24>NOOP string test
Line <24>NOOP number
Line <24>NOOP equal
Line <24>NOOP string
Line <24>NOOP newline Line <24>NOOP newline
Line <25>NOOP name slot3 Line <25>NOOP cbracketc
Line <25>NOOP number Line <25>ELIF control
Line <25>NOOP equal Line <25>NOOP name statement
Line <25>NOOP string Line <25>NOOP cbracketo
Line <25>NOOP newline Line <25>NOOP newline
Line <26>NOOP name slot4 Line <26>NOOP string test
Line <26>NOOP number
Line <26>NOOP equal
Line <26>NOOP string
Line <26>NOOP newline Line <26>NOOP newline
Line <27>NOOP name slot5 Line <27>NOOP cbracketc
Line <27>NOOP number Line <27>IFFF control
Line <27>NOOP equal Line <27>NOOP name statement
Line <27>NOOP string Line <27>NOOP cbracketo
Line <27>NOOP newline Line <27>NOOP newline
Line <28>NOOP name slot6 Line <28>NOOP string test
Line <28>NOOP number
Line <28>NOOP equal
Line <28>NOOP string
Line <28>NOOP newline Line <28>NOOP newline
Line <29>NOOP name slot7 Line <29>NOOP string test
Line <29>NOOP number
Line <29>NOOP equal
Line <29>NOOP string
Line <29>NOOP newline Line <29>NOOP newline
Line <30>NOOP name slot8 Line <30>IFFF control
Line <30>NOOP number Line <30>NOOP name statement
Line <30>NOOP equal Line <30>NOOP cbracketo
Line <30>NOOP string
Line <30>NOOP newline Line <30>NOOP newline
Line <32>NOOP eof Line <31>NOOP string test
Line <31>NOOP newline
Line <32>NOOP cbracketc
Line <32>ELSE control
Line <32>NOOP cbracketo
Line <32>NOOP newline
Line <33>NOOP string test
Line <33>NOOP newline
Line <34>NOOP cbracketc
Line <34>NOOP newline
Line <35>NOOP cbracketc
Line <35>ELIF control
Line <35>NOOP name statement
Line <35>NOOP cbracketo
Line <35>NOOP newline
Line <36>NOOP string test
Line <36>NOOP newline
Line <37>NOOP cbracketc
Line <37>ELSE control
Line <37>NOOP cbracketo
Line <37>NOOP newline
Line <38>NOOP string test
Line <38>NOOP newline
Line <39>NOOP cbracketc
Line <39>NOOP newline
Line <40>NOOP newline
Line <41>NOOP gotoo
Line <41>NOOP string somewhere
Line <41>NOOP newline
Line <42>NOOP jump
Line <42>NOOP string overhere
Line <42>NOOP newline
Line <43>NOOP newline
Line <44>NOOP name hungry
Line <44>NOOP equal
Line <44>NOOP parao
Line <44>NOOP minus
Line <44>NOOP number 2
Line <44>NOOP plus
Line <44>NOOP number 4
Line <44>NOOP minus
Line <44>NOOP parao
Line <44>NOOP parao
Line <44>NOOP number 5
Line <44>NOOP multiply
Line <44>NOOP number 5
Line <44>NOOP parac
Line <44>NOOP divide
Line <44>NOOP name sqrt
Line <44>NOOP parao
Line <44>NOOP number 144
Line <44>NOOP plus
Line <44>NOOP number 5
Line <44>NOOP parac
Line <44>NOOP parac
Line <44>NOOP parac
Line <44>NOOP pow
Line <44>NOOP number 2
Line <44>NOOP multiply
Line <44>NOOP number 2
Line <44>NOOP plus
Line <44>NOOP number 2
Line <44>NOOP newline
Line <45>NOOP name list
Line <45>NOOP bracketo
Line <45>NOOP number 1
Line <45>NOOP bracketc
Line <45>NOOP equal
Line <45>NOOP string Hello
Line <45>NOOP newline
Line <46>NOOP name var1
Line <46>NOOP number
Line <46>NOOP equal
Line <46>NOOP name func
Line <46>NOOP parao
Line <46>NOOP number 1
Line <46>NOOP seperator
Line <46>NOOP string string
Line <46>NOOP seperator
Line <46>NOOP number 2
Line <46>NOOP plus
Line <46>NOOP number 5
Line <46>NOOP parac
Line <46>NOOP newline
Line <47>NOOP name a
Line <47>NOOP equal
Line <47>NOOP number 100
Line <47>NOOP plus
Line <47>NOOP name func
Line <47>NOOP parao
Line <47>NOOP number 1
Line <47>NOOP seperator
Line <47>NOOP string string
Line <47>NOOP seperator
Line <47>NOOP number 2
Line <47>NOOP plus
Line <47>NOOP number 5
Line <47>NOOP parac
Line <47>NOOP plus
Line <47>NOOP number 100
Line <47>NOOP newline
Line <48>NOOP name func
Line <48>NOOP parao
Line <48>NOOP number 1
Line <48>NOOP seperator
Line <48>NOOP string string
Line <48>NOOP seperator
Line <48>NOOP number 2
Line <48>NOOP plus
Line <48>NOOP number 5
Line <48>NOOP parac
Line <48>NOOP newline
Line <49>NOOP label label
Line <49>NOOP newline
Line <50>NOOP newline
Line <51>NOOP newline
Line <52>CHOI control
Line <52>NOOP string Pick one:
Line <52>NOOP cbracketo
Line <52>NOOP newline
Line <53>NOOP string first
Line <53>NOOP name func
Line <53>NOOP parao
Line <53>NOOP number 1
Line <53>NOOP seperator
Line <53>NOOP number 2
Line <53>NOOP seperator
Line <53>NOOP number 3
Line <53>NOOP parac
Line <53>NOOP newline
Line <54>NOOP string second
Line <54>NOOP name func
Line <54>NOOP parao
Line <54>NOOP true true
Line <54>NOOP seperator
Line <54>NOOP false false
Line <54>NOOP seperator
Line <54>NOOP name func
Line <54>NOOP parao
Line <54>NOOP string heehee
Line <54>NOOP parac
Line <54>NOOP parac
Line <54>NOOP newline
Line <55>NOOP string third
Line <55>NOOP name func
Line <55>NOOP parao
Line <55>NOOP string hehe
Line <55>NOOP parac
Line <55>NOOP newline
Line <56>NOOP string forth
Line <56>NOOP name func
Line <56>NOOP parao
Line <56>NOOP string 1
Line <56>NOOP seperator
Line <56>NOOP number 2
Line <56>NOOP seperator
Line <56>NOOP false false
Line <56>NOOP parac
Line <56>NOOP newline
Line <57>NOOP string fifth
Line <57>NOOP gotoo
Line <57>NOOP string here
Line <57>NOOP newline
Line <58>NOOP string sixth
Line <58>NOOP gotoo
Line <58>NOOP name name
Line <58>NOOP newline
Line <59>NOOP string sevinth
Line <59>NOOP jump
Line <59>NOOP string there
Line <59>NOOP newline
Line <60>NOOP string eight
Line <60>NOOP jump
Line <60>NOOP name name
Line <60>NOOP newline
Line <61>NOOP string nine
Line <61>NOOP name exit
Line <61>NOOP newline
Line <62>NOOP cbracketc
Line <62>NOOP newline
Line <63>NOOP cbracketc
Line <63>NOOP newline
Line <64>NOOP newline
Line <65>NOOP newline
Line <66>NOOP newline
Line <67>NOOP bracketo
Line <67>NOOP name Bob
Line <67>NOOP colon
Line <67>NOOP name char
Line <67>NOOP bracketc
Line <67>NOOP newline
Line <68>NOOP name age
Line <68>NOOP equal
Line <68>NOOP number 24
Line <68>NOOP newline
Line <69>NOOP name money
Line <69>NOOP equal
Line <69>NOOP number 100
Line <69>NOOP newline
Line <70>NOOP newline
Line <71>NOOP bracketo
Line <71>NOOP name newblock
Line <71>NOOP colon
Line <71>NOOP name function
Line <71>NOOP parao
Line <71>NOOP parac
Line <71>NOOP bracketc
Line <71>NOOP newline
Line <72>NOOP string Test #2
Line <72>NOOP newline
Line <73>NOOP string Does it parse this part properly?
Line <73>NOOP newline
Line <75>NOOP eof

View File

@ -5,11 +5,12 @@ namespace dms::errors {
unknown, unknown,
string_out_of_bounds, string_out_of_bounds,
invalid_arguments, invalid_arguments,
invalie_type, invalid_type,
array_out_of_bounds, array_out_of_bounds,
badtoken, badtoken,
block_already_defined, block_already_defined,
choice_unknown choice_unknown,
nested_function
}; };
struct error { struct error {
errortype code=unknown; errortype code=unknown;

View File

@ -2,7 +2,7 @@ entry main
enable warnings enable warnings
disable omniscient disable omniscient
//enable debugging //enable debugging
loadfile "loadtest.dms" //loadfile "loadtest.dms"
version 1.2 version 1.2
using extendedDefine using extendedDefine
@ -51,7 +51,7 @@ using extendedDefine
CHOICE "Pick one:" { CHOICE "Pick one:" {
"first" func(1,2,3) "first" func(1,2,3)
"second" func(true,false) "second" func(true,false,func("heehee"))
"third" func("hehe") "third" func("hehe")
"forth" func("1",2,false) "forth" func("1",2,false)
"fifth" goto "here" "fifth" goto "here"
@ -63,6 +63,7 @@ using extendedDefine
} }
[Bob:char] [Bob:char]
age = 24 age = 24
money = 100 money = 100

View File

@ -33,6 +33,12 @@ namespace dms {
value* buildValue() { value* buildValue() {
return new value; return new value;
} }
size_t count = 0;
value* buildVariable() {
count++;
std::string val = utils::concat("$",count);
return buildVariable(val);
}
value* buildVariable(std::string str) { value* buildVariable(std::string str) {
value* val = new value{}; value* val = new value{};
val->set(buildString(str)); val->set(buildString(str));

View File

@ -85,6 +85,7 @@ namespace dms {
}; };
value* buildValue(); value* buildValue();
value* buildVariable(std::string str); value* buildVariable(std::string str);
value* buildVariable();
value* buildValue(std::string str); value* buildValue(std::string str);
value* buildValue(double dbl); value* buildValue(double dbl);
value* buildValue(int i); value* buildValue(int i);