leftside dict/list, host method calling implemeted Todo, dms functions

This commit is contained in:
Ryan Ward 2020-10-18 23:24:01 -04:00
parent 4e092ad8b6
commit 52774b72cd
18 changed files with 236 additions and 253 deletions

View File

@ -2,10 +2,22 @@
//#include <windows.h> //#include <windows.h>
#include <iostream> #include <iostream>
using namespace dms; using namespace dms;
typedef void(*FNPTR)(); //typedef void(*FNPTR)();
value* invokeTest(dms_state* state, dms_args* args) {
utils::print(args->args[0]->getPrintable());
return buildValue("I work!");
}
int main() int main()
{ {
LineParser parser = LineParser("test.dms");
dms_state* state = parser.Parse();
state->invoker.registerFunction("invokeTest", invokeTest);
state->dump();
state->run();
utils::print("Exitcode: ",state->exitcode);
/*HINSTANCE hInst = LoadLibrary(L"C:\\Users\\rayam\\Desktop\\test.dll"); /*HINSTANCE hInst = LoadLibrary(L"C:\\Users\\rayam\\Desktop\\test.dll");
if (!hInst) { if (!hInst) {
std::cout << "\nCould not load the library!"; std::cout << "\nCould not load the library!";
@ -19,11 +31,4 @@ int main()
} }
fn();*/ fn();*/
LineParser parser = LineParser("test.dms");
dms_state* state = parser.Parse();
state->dump();
state->run();
utils::print("Exitcode: ",state->exitcode);
} }

View File

@ -156,6 +156,7 @@
<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="dms_state_interpret.cpp" />
<ClCompile Include="Invoker.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" />
@ -174,6 +175,7 @@
<ClInclude Include="cmd.h" /> <ClInclude Include="cmd.h" />
<ClInclude Include="codes.h" /> <ClInclude Include="codes.h" />
<ClInclude Include="dms_state.h" /> <ClInclude Include="dms_state.h" />
<ClInclude Include="Invoker.h" />
<ClInclude Include="string_utils.h" /> <ClInclude Include="string_utils.h" />
<ClInclude Include="dms_exceptions.h" /> <ClInclude Include="dms_exceptions.h" />
<ClInclude Include="errors.h" /> <ClInclude Include="errors.h" />

View File

@ -84,6 +84,9 @@
<ClCompile Include="dms_custom.cpp"> <ClCompile Include="dms_custom.cpp">
<Filter>Source Files\DMS</Filter> <Filter>Source Files\DMS</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="Invoker.cpp">
<Filter>Source Files\DMS</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="value.h"> <ClInclude Include="value.h">
@ -134,5 +137,8 @@
<ClInclude Include="enviroment.h"> <ClInclude Include="enviroment.h">
<Filter>Header Files\DMS\blocks</Filter> <Filter>Header Files\DMS\blocks</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Invoker.h">
<Filter>Header Files\DMS</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

28
DMS/Invoker.cpp Normal file
View File

@ -0,0 +1,28 @@
#include "Invoker.h"
#include "dms_state.h"
namespace dms {
bool Invoker::registerFunction(std::string str, value* (*f)(dms_state*, dms_args*)) {
if (preventOverwriting && funcs.count(str)) {
return false;
}
funcs.insert_or_assign(str, f);
return true;
}
bool Invoker::registerFunction(std::string str, value* (*f)(dms_state*, dms_args*), bool preventoverride) {
if (preventoverride && funcs.count(str)) {
return false;
}
funcs.insert_or_assign(str, f);
return true;
}
value* Invoker:: Invoke(std::string str, dms_state* state, dms_args* args) {
if (funcs.count(str)) {
for (int i = 0; i < args->args.size() - 1; i++) {
args->args[i] = args->args[i]->resolve(state->memory);
}
return funcs[str](state, args);
}
state->push_error(errors::error{ errors::non_existing_function, "Attempt to call a nil value!" });
return buildNil();
}
}

14
DMS/Invoker.h Normal file
View File

@ -0,0 +1,14 @@
#pragma once
#include "errors.h"
#include <unordered_map>
namespace dms {
struct dms_state;
class Invoker {
std::unordered_map<std::string, value* (*)(dms_state*, dms_args*)>funcs;
public:
bool preventOverwriting = true;
bool registerFunction(std::string str, value* (*f)(dms_state*, dms_args*));
bool registerFunction(std::string str, value* (*f)(dms_state*, dms_args*), bool preventoverride);
value* Invoke(std::string str, dms_state* state, dms_args* args);
};
}

View File

@ -74,7 +74,7 @@ namespace dms {
bool match_process_list(tokenstream* stream, value* v = nullptr); bool match_process_list(tokenstream* stream, value* v = nullptr);
bool match_process_wait(tokenstream* stream); bool match_process_wait(tokenstream* stream);
bool match_process_standard(tokenstream* stream, value* v = nullptr); // All types that are matchable are handled here! bool match_process_standard(tokenstream* stream, value* v = nullptr); // All types that are matchable are handled here!
bool match_process_index(tokenstream* stream,value* v = nullptr); bool match_process_index(tokenstream* stream,value* v = nullptr, bool leftside = false);
// Build // Build

View File

@ -134,6 +134,15 @@ namespace dms {
} }
} }
length->set(buildNumber(count)); // the second argument is the length of the list! This should be modified if lists are changed at runtime! length->set(buildNumber(count)); // the second argument is the length of the list! This should be modified if lists are changed at runtime!
c = new cmd;
c->opcode = codes::INST;
c->args.push(v);
c->args.push(buildNil());
if (dict != nullptr) {
c->args.push(dict);
dict = nullptr;
}
current_chunk->addCmd(c);
return true; return true;
} }
return false; return false;
@ -265,7 +274,27 @@ namespace dms {
return false; return false;
} }
bool LineParser::match_process_assignment(tokenstream* stream) { bool LineParser::match_process_assignment(tokenstream* stream) {
if (stream->match(tokens::name,tokens::equal)) { value* v = buildVariable();
v->set();
if (match_process_index(stream, v, true)) {
cmd* c = current_chunk->cmds.back();
value* ref = buildVariable();
if (stream->peek().type == tokens::equal) {
stream->next();
}
else {
badSymbol(stream);
return false;
}
if (match_process_standard(stream, ref)) {
c->args.push(ref);
return true;
}
else if (stream->match(tokens::newline)) {
stream->next();
}
}
else 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;
@ -275,12 +304,17 @@ namespace dms {
if (match_process_standard(stream,ref)) { if (match_process_standard(stream,ref)) {
c->args.push(ref); c->args.push(ref);
current_chunk->addCmd(c); current_chunk->addCmd(c);
delete[] v;
return true; return true;
} }
else if (stream->match(tokens::newline)) { else if (stream->match(tokens::newline)) {
stream->next(); stream->next();
} }
} }
else {
// We should clean up this
delete[] v;
}
return false; return false;
} }
bool LineParser::match_process_debug(tokenstream* stream) { bool LineParser::match_process_debug(tokenstream* stream) {
@ -507,7 +541,7 @@ namespace dms {
} }
return false; return false;
} }
bool LineParser::match_process_index(tokenstream* stream, value* v) { bool LineParser::match_process_index(tokenstream* stream, value* v, bool leftside) {
if (stream->match(tokens::name,tokens::bracketo)) { if (stream->match(tokens::name,tokens::bracketo)) {
std::string name = stream->next().name; std::string name = stream->next().name;
std::vector<token> tok = stream->next(tokens::bracketo, tokens::bracketc); std::vector<token> tok = stream->next(tokens::bracketo, tokens::bracketc);
@ -517,14 +551,25 @@ namespace dms {
tempstream.init(&tok); tempstream.init(&tok);
value* tempval = buildVariable(); value* tempval = buildVariable();
cmd* c = new cmd; cmd* c = new cmd;
c->opcode = codes::INDX; if (leftside) {
c->opcode = codes::ASID;
}
else {
c->opcode = codes::INDX;
}
int nlcount = 0;
while (tempstream.peek().type != tokens::none) { // Keep going until we hit the end while (tempstream.peek().type != tokens::none) { // Keep going until we hit the end
if (match_process_standard(&tempstream, tempval)) { if (match_process_standard(&tempstream, tempval)) {
c->args.push(v); c->args.push(v);
c->args.push(buildBlock(name)); c->args.push(buildBlock(name));
c->args.push(tempval); c->args.push(tempval);
} }
else if (nlcount) {
state->push_error(errors::error{ errors::badtoken,concat("Unexpected symbol '",tempstream.last().toString(),"' Expected ']' to close list (line: ",tempstream.last().line_num,") Indexing must be done on one line?"),true,tempstream.last().line_num,current_chunk });
return false;
}
else if (tempstream.match(tokens::newline)) { else if (tempstream.match(tokens::newline)) {
nlcount++;
tempstream.next(); tempstream.next();
} }
else { else {

View File

@ -47,5 +47,6 @@ const std::string dms::codes::list[] = {
"LINE", "LINE",
"HALT", "HALT",
"FILE", "FILE",
"GC" "GC",
"ASID"
}; };

View File

@ -49,7 +49,8 @@ namespace dms::codes {
LINE, LINE,
HALT, HALT,
FILE, FILE,
GC GC,
ASID
}; };
extern const std::string list[]; extern const std::string list[];
static bool isControl(const op code) { static bool isControl(const op code) {

View File

@ -13,4 +13,5 @@
#include "token.h" #include "token.h"
#include "utils.h" #include "utils.h"
#include "value.h" #include "value.h"
#include "Invoker.h"

View File

@ -4,6 +4,7 @@
#include <iostream> #include <iostream>
#include <unordered_map> #include <unordered_map>
#include "Invoker.h"
#include "errors.h" #include "errors.h"
#include "chunk.h" #include "chunk.h"
#include "dms_exceptions.h" #include "dms_exceptions.h"
@ -15,6 +16,7 @@ namespace dms {
{ {
Handler* handler = nullptr; Handler* handler = nullptr;
bool hasFirst = false; bool hasFirst = false;
Invoker invoker;
std::unordered_map<std::string, value*> memory; std::unordered_map<std::string, value*> memory;
std::vector<value*> garbage; std::vector<value*> garbage;
std::unordered_map<std::string, chunk*> chunks; std::unordered_map<std::string, chunk*> chunks;

View File

@ -133,7 +133,7 @@ namespace dms {
while (!stop || !halt) { while (!stop || !halt) {
c = cmds[pos++]; c = cmds[pos++];
code = c->opcode; code = c->opcode;
//print("\n(",pos,")> ",*c); //print("(",pos,")> ",*c);
//wait(); //wait();
switch (code) switch (code)
{ {
@ -174,6 +174,51 @@ namespace dms {
} }
return true; return true;
break; break;
case FUNC:
{
std::string funcname = c->args.args[0]->getPrintable();
value* assn = c->args.args[1];
dms_args args;
for (int i = 2; i < c->args.args.size(); i++) {
args.push(c->args.args[i]);
}
value* ret = invoker.Invoke(funcname, this, &args);
if (assn->type != datatypes::nil) {
assign(mem, assn, ret);
}
}
break;
case ASID:
{
value* env = c->args.args[1];
value* indx = c->args.args[2]->resolve(*mem);
value* assn = c->args.args[3]->resolve(*mem);
if (env->type == datatypes::block && blockExists(env->getPrintable())) { // If this is a block let's handle this
enviroment* e = nullptr;
if (enviroments.count(env->getPrintable())) {
e = enviroments[env->getPrintable()];
}
else if (characters.count(env->getPrintable())) {
e = characters[env->getPrintable()];
}
e->values[indx->getPrintable()] = assn;
}
else if (env->type == datatypes::env) {
if (indx->type == datatypes::number) {
env->e->pushValue(assn);
}
else {
push_error(errors::error{ errors::invalid_type ,concat("Expected a number value got ",datatype[indx->type]) });
return false;
}
}
else if (env->type == datatypes::custom) {
env->c->NewIndex(indx, assn);
//assign(mem, assn, env->c->Index(indx));
// Call the method within the custom data
}
break;
}
case INDX: case INDX:
{ {
value* assn = c->args.args[0]; value* assn = c->args.args[0];

Binary file not shown.

View File

@ -42,247 +42,97 @@ Line <13> name main
Line <13> bracketc ] Line <13> bracketc ]
Line <13> newline Line <13> newline
Line <13> newline Line <13> newline
Line <14> string why
Line <14> newline Line <14> newline
Line <14> newline Line <14> newline
Line <15> name Bob Line <15> name list
Line <15> colon : Line <15> equal =
Line <15> cbracketo { Line <15> cbracketo {
Line <15> string Hello
Line <15> seperator ,
Line <15> number 2
Line <15> seperator ,
Line <15> number 3
Line <15> cbracketc }
Line <15> newline Line <15> newline
Line <15> newline Line <15> newline
Line <16> name speed
Line <16> number 50
Line <16> newline Line <16> newline
Line <16> newline Line <16> newline
Line <17> name excited Line <17> string Contents of list {`list:1`, `list:2`, `list:3`}
Line <17> colon :
Line <17> string Hello Mr. `Ryan:lname`,
Line <17> newline Line <17> newline
Line <17> newline Line <17> newline
Line <18> string how are `inv:slot2` you doing?
Line <18> newline Line <18> newline
Line <18> newline Line <18> newline
Line <19> cbracketc }
Line <19> newline
Line <19> newline Line <19> newline
Line <20> newline Line <20> newline
Line <20> newline Line <20> newline
Line <21> name test Line <21> name hmm
Line <21> equal = Line <21> equal =
Line <21> name Bob Line <21> name invokeTest
Line <21> bracketo [ Line <21> parao (
Line <21> string fname Line <21> string Do I work?
Line <21> bracketc ] Line <21> parac )
Line <21> newline Line <21> newline
Line <21> newline Line <21> newline
Line <22> string `Bob`'s First Name is: `test`
Line <22> newline Line <22> newline
Line <22> newline Line <22> newline
Line <23> string The return of hmm is "`hmm`"
Line <23> newline
Line <23> newline Line <23> newline
Line <24> newline Line <24> newline
Line <24> newline Line <24> newline
Line <25> name Ryan
Line <25> colon :
Line <25> cbracketo {
Line <25> newline Line <25> newline
Line <25> newline Line <25> newline
Line <26> string Hey `Bob`, I'm good how are you? Line <26> bracketo [
Line <26> name Bob
Line <26> colon :
Line <26> name char
Line <26> bracketc ]
Line <26> newline Line <26> newline
Line <26> newline Line <26> newline
Line <27> cbracketc }
Line <27> newline Line <27> newline
Line <28> newline Line <28> newline
Line <28> newline
Line <29> string Waiting ...
Line <29> newline
Line <29> newline Line <29> newline
Line <30> name unknown
Line <30> equal =
Line <30> string Ya boi
Line <30> newline Line <30> newline
Line <30> newline Line <30> newline
Line <31> name Bob Line <31> name age
Line <31> colon : Line <31> equal =
Line <31> cbracketo { Line <31> number 0.24
Line <31> newline Line <31> newline
Line <31> newline Line <31> newline
Line <32> string I am great thanks! I want to show you that I can count! Line <32> name money
Line <32> equal =
Line <32> number 100
Line <32> newline Line <32> newline
Line <32> newline Line <32> newline
Line <33> name wait Line <33> name excited
Line <33> number 0.1 Line <33> colon :
Line <33> string path/to/file
Line <33> newline Line <33> newline
Line <33> newline Line <33> newline
Line <34> string 1
Line <34> newline Line <34> newline
Line <34> newline Line <34> newline
Line <35> name wait Line <35> bracketo [
Line <35> number 0.1 Line <35> name newblock
Line <35> colon :
Line <35> name function
Line <35> parao (
Line <35> parac )
Line <35> bracketc ]
Line <35> newline Line <35> newline
Line <35> newline Line <35> newline
Line <36> string 2 Line <36> string Test #2
Line <36> newline Line <36> newline
Line <36> newline Line <36> newline
Line <37> name wait Line <37> string Does it parse this part properly?
Line <37> number 0.1
Line <37> newline Line <37> newline
Line <37> newline Line <37> newline
Line <38> string 3 Line <38> string huh
Line <38> newline Line <38> newline
Line <38> newline Line <38> newline
Line <39> name wait Line <38> eof
Line <39> number 0.1
Line <39> newline
Line <39> newline
Line <40> string 4
Line <40> newline
Line <40> newline
Line <41> name wait
Line <41> number 0.1
Line <41> newline
Line <41> newline
Line <42> string 5
Line <42> newline
Line <42> newline
Line <43> cbracketc }
Line <43> newline
Line <43> newline
Line <44> newline
Line <44> newline
Line <45> control
Line <45> string What do you want to do?
Line <45> cbracketo {
Line <45> newline
Line <45> newline
Line <46> string option 1
Line <46> name test2
Line <46> parao (
Line <46> string testing
Line <46> seperator ,
Line <46> cbracketo {
Line <46> number 1
Line <46> seperator ,
Line <46> number 2
Line <46> seperator ,
Line <46> number 3
Line <46> cbracketc }
Line <46> parac )
Line <46> newline
Line <46> newline
Line <47> string option 2
Line <47> jump
Line <47> string test
Line <47> newline
Line <47> newline
Line <48> string option 3
Line <48> jump
Line <48> name there
Line <48> newline
Line <48> newline
Line <49> string option 4
Line <49> gotoo
Line <49> string o3
Line <49> newline
Line <49> newline
Line <50> string option 5
Line <50> gotoo
Line <50> name here
Line <50> newline
Line <50> newline
Line <51> string option 6
Line <51> name test
Line <51> parao (
Line <51> string here
Line <51> parac )
Line <51> newline
Line <51> newline
Line <52> cbracketc }
Line <52> newline
Line <52> newline
Line <53> newline
Line <53> newline
Line <54> bracketo [
Line <54> name test
Line <54> bracketc ]
Line <54> newline
Line <54> newline
Line <55> name Ryan
Line <55> colon :
Line <55> string We are here now!
Line <55> newline
Line <55> newline
Line <56> pipe |
Line <56> string This continues from the last message!
Line <56> newline
Line <56> newline
Line <57> pipe |
Line <57> string Keeps code readable. This does not cause a new line!
Line <57> newline
Line <57> newline
Line <58> name Ryan
Line <58> colon :
Line <58> string This does trigger a new line tho!
Line <58> newline
Line <58> newline
Line <59> string This also will cause a new line!
Line <59> newline
Line <59> newline
Line <60> newline
Line <60> newline
Line <61> bracketo [
Line <61> name Bob
Line <61> colon :
Line <61> name char
Line <61> bracketc ]
Line <61> newline
Line <61> newline
Line <62> newline
Line <63> newline
Line <64> newline
Line <65> name unknown
Line <65> equal =
Line <65> string Some Rando
Line <65> newline
Line <65> newline
Line <66> name age
Line <66> equal =
Line <66> number 0.24
Line <66> newline
Line <66> newline
Line <67> name money
Line <67> equal =
Line <67> number 100
Line <67> newline
Line <67> newline
Line <68> name excited
Line <68> colon :
Line <68> string path/to/file
Line <68> newline
Line <68> newline
Line <69> newline
Line <69> newline
Line <70> bracketo [
Line <70> name newblock
Line <70> colon :
Line <70> name function
Line <70> parao (
Line <70> parac )
Line <70> bracketc ]
Line <70> newline
Line <70> newline
Line <71> string Test #2
Line <71> newline
Line <71> newline
Line <72> string Does it parse this part properly?
Line <72> newline
Line <72> newline
Line <73> string huh
Line <73> newline
Line <73> newline
Line <73> eof
Line <1> newline Line <1> newline
Line <1> newline Line <1> newline
Line <1> flag Line <1> flag

View File

@ -14,7 +14,8 @@ namespace dms::errors {
nested_function, nested_function,
disp_unknown, disp_unknown,
non_existing_block, non_existing_block,
incompatible_version incompatible_version,
non_existing_function
}; };
struct error { struct error {
errortype code=unknown; errortype code=unknown;

View File

@ -11,58 +11,23 @@ version 0.2
using extendedDefine using extendedDefine
[main] [main]
"why"
Bob: {
speed 50
excited: "Hello Mr. `Ryan:lname`, "
"how are `inv:slot2` you doing?"
}
test = Bob["fname"] list = {"Hello",2,3}
"`Bob`'s First Name is: `test`"
"Contents of list {`list:1`, `list:2`, `list:3`}"
//Ryan:setNickname(Bob,"Bobby") // Not yet implemeted! //Ryan:setNickname(Bob,"Bobby") // Not yet implemeted!
Ryan: { hmm = invokeTest("Do I work?")
"Hey `Bob`, I'm good how are you?"
} // Should display Hey Bobby, I'm good how are you?
"Waiting ..." "The return of hmm is \"`hmm`\""
Bob: {
"I am great thanks! I want to show you that I can count!\n"
wait .1
"1\n"
wait .1
"2\n"
wait .1
"3\n"
wait .1
"4\n"
wait .1
"5\n"
}
choice "What do you want to do?" {
"option 1" test2("testing",{1,2,3})
"option 2" jump "test"
"option 3" jump there
"option 4" goto "o3"
"option 5" goto here
"option 6" test("here")
}
[test]
Ryan: "We are here now!"
|"This continues from the last message!"
|"Keeps code readable. This does not cause a new line!"
Ryan: "This does trigger a new line tho!"
"This also will cause a new line!"
[Bob:char] [Bob:char]
//fname = "Bob" //fname = "Bob"
//known = true // defaults to false //known = true // defaults to false
//lname = "Johnson" // defaults to "" //lname = "Johnson" // defaults to ""
unknown = "Some Rando" unknown = "Ya boi"
age = .24 age = .24
money = 100 money = 100
excited: "path/to/file" excited: "path/to/file"

View File

@ -1,5 +1,6 @@
#include "value.h" #include "value.h"
#include "dms_state.h" #include "dms_state.h"
#include "utils.h"
namespace dms { namespace dms {
const std::string datatype[] = { "escape","nil", "number", "boolean", "env", "string", "custom", "variable", "block" }; const std::string datatype[] = { "escape","nil", "number", "boolean", "env", "string", "custom", "variable", "block" };
std::vector<value*> _VALUES; std::vector<value*> _VALUES;
@ -19,6 +20,9 @@ namespace dms {
void dms_args::push(value* val) { void dms_args::push(value* val) {
args.push_back(val); args.push_back(val);
} }
size_t dms_args::size() {
return args.size();
}
std::string dms_string::getValue(dms_state* state) { std::string dms_string::getValue(dms_state* state) {
std::stringstream temp; std::stringstream temp;
std::stringstream var; std::stringstream var;
@ -60,8 +64,14 @@ namespace dms {
temp << "nil"; temp << "nil";
} }
} }
else if (v->resolve(state->memory)->type == datatypes::env) {
if(v->resolve(state->memory)->e->ipart.size()> std::stoi(index))
temp << v->resolve(state->memory)->e->ipart[std::stoi(index)-1]->getPrintable();
else
temp << "nil";
}
else { else {
temp << v->getPrintable(); temp << v->resolve(state->memory)->getPrintable();
} }
} }
else { else {
@ -206,6 +216,11 @@ namespace dms {
val->type = variable; val->type = variable;
return val; return val;
} }
value* buildValue(char const* s) {
value* val = new value{};
val->set(buildString(s));
return val;
}
value* buildValue(std::string str) { value* buildValue(std::string str) {
value* val = new value{}; value* val = new value{};
val->set(buildString(str)); val->set(buildString(str));

View File

@ -117,6 +117,7 @@ namespace dms {
}; };
}; };
value* buildValue(); value* buildValue();
value* buildValue(char const* s);
value* buildNil(); value* buildNil();
value* buildVariable(std::string str); value* buildVariable(std::string str);
value* buildVariable(); value* buildVariable();
@ -129,6 +130,7 @@ namespace dms {
struct dms_args { struct dms_args {
std::vector<value*> args; std::vector<value*> args;
void push(value* val); void push(value* val);
size_t size();
friend std::ostream& operator << (std::ostream& out, const dms_args& c) { friend std::ostream& operator << (std::ostream& out, const dms_args& c) {
for (size_t i=0; i < c.args.size(); i++) { for (size_t i=0; i < c.args.size(); i++) {
if(i==c.args.size()-1) if(i==c.args.size()-1)