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 <iostream>
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()
{
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");
if (!hInst) {
std::cout << "\nCould not load the library!";
@ -19,11 +31,4 @@ int main()
}
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_state.cpp" />
<ClCompile Include="dms_state_interpret.cpp" />
<ClCompile Include="Invoker.cpp" />
<ClCompile Include="LineParserBuilds.cpp" />
<ClCompile Include="LineParserMatchProcess.cpp" />
<ClCompile Include="LineParserParse.cpp" />
@ -174,6 +175,7 @@
<ClInclude Include="cmd.h" />
<ClInclude Include="codes.h" />
<ClInclude Include="dms_state.h" />
<ClInclude Include="Invoker.h" />
<ClInclude Include="string_utils.h" />
<ClInclude Include="dms_exceptions.h" />
<ClInclude Include="errors.h" />

View File

@ -84,6 +84,9 @@
<ClCompile Include="dms_custom.cpp">
<Filter>Source Files\DMS</Filter>
</ClCompile>
<ClCompile Include="Invoker.cpp">
<Filter>Source Files\DMS</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="value.h">
@ -134,5 +137,8 @@
<ClInclude Include="enviroment.h">
<Filter>Header Files\DMS\blocks</Filter>
</ClInclude>
<ClInclude Include="Invoker.h">
<Filter>Header Files\DMS</Filter>
</ClInclude>
</ItemGroup>
</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_wait(tokenstream* stream);
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

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!
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 false;
@ -265,7 +274,27 @@ namespace dms {
return false;
}
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
stream->next(); // Consume the equal
cmd* c = new cmd;
@ -275,12 +304,17 @@ namespace dms {
if (match_process_standard(stream,ref)) {
c->args.push(ref);
current_chunk->addCmd(c);
delete[] v;
return true;
}
else if (stream->match(tokens::newline)) {
stream->next();
}
}
else {
// We should clean up this
delete[] v;
}
return false;
}
bool LineParser::match_process_debug(tokenstream* stream) {
@ -507,7 +541,7 @@ namespace dms {
}
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)) {
std::string name = stream->next().name;
std::vector<token> tok = stream->next(tokens::bracketo, tokens::bracketc);
@ -517,14 +551,25 @@ namespace dms {
tempstream.init(&tok);
value* tempval = buildVariable();
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
if (match_process_standard(&tempstream, tempval)) {
c->args.push(v);
c->args.push(buildBlock(name));
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)) {
nlcount++;
tempstream.next();
}
else {

View File

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

View File

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

View File

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

View File

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

View File

@ -133,7 +133,7 @@ namespace dms {
while (!stop || !halt) {
c = cmds[pos++];
code = c->opcode;
//print("\n(",pos,")> ",*c);
//print("(",pos,")> ",*c);
//wait();
switch (code)
{
@ -174,6 +174,51 @@ namespace dms {
}
return true;
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:
{
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> newline
Line <13> newline
Line <14> string why
Line <14> newline
Line <14> newline
Line <15> name Bob
Line <15> colon :
Line <15> name list
Line <15> equal =
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 <16> name speed
Line <16> number 50
Line <16> newline
Line <16> newline
Line <17> name excited
Line <17> colon :
Line <17> string Hello Mr. `Ryan:lname`,
Line <17> string Contents of list {`list:1`, `list:2`, `list:3`}
Line <17> newline
Line <17> newline
Line <18> string how are `inv:slot2` you doing?
Line <18> newline
Line <18> newline
Line <19> cbracketc }
Line <19> newline
Line <19> newline
Line <20> newline
Line <20> newline
Line <21> name test
Line <21> name hmm
Line <21> equal =
Line <21> name Bob
Line <21> bracketo [
Line <21> string fname
Line <21> bracketc ]
Line <21> name invokeTest
Line <21> parao (
Line <21> string Do I work?
Line <21> parac )
Line <21> newline
Line <21> newline
Line <22> string `Bob`'s First Name is: `test`
Line <22> newline
Line <22> newline
Line <23> string The return of hmm is "`hmm`"
Line <23> newline
Line <23> newline
Line <24> newline
Line <24> newline
Line <25> name Ryan
Line <25> colon :
Line <25> cbracketo {
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 <27> cbracketc }
Line <27> newline
Line <28> newline
Line <28> newline
Line <29> string Waiting ...
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 <31> name Bob
Line <31> colon :
Line <31> cbracketo {
Line <31> name age
Line <31> equal =
Line <31> number 0.24
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 <33> name wait
Line <33> number 0.1
Line <33> name excited
Line <33> colon :
Line <33> string path/to/file
Line <33> newline
Line <33> newline
Line <34> string 1
Line <34> newline
Line <34> newline
Line <35> name wait
Line <35> number 0.1
Line <35> bracketo [
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 <36> string 2
Line <36> string Test #2
Line <36> newline
Line <36> newline
Line <37> name wait
Line <37> number 0.1
Line <37> string Does it parse this part properly?
Line <37> newline
Line <37> newline
Line <38> string 3
Line <38> string huh
Line <38> newline
Line <38> newline
Line <39> name wait
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 <38> eof
Line <1> newline
Line <1> newline
Line <1> flag

View File

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

View File

@ -11,58 +11,23 @@ version 0.2
using extendedDefine
[main]
"why"
Bob: {
speed 50
excited: "Hello Mr. `Ryan:lname`, "
"how are `inv:slot2` you doing?"
}
test = Bob["fname"]
"`Bob`'s First Name is: `test`"
list = {"Hello",2,3}
"Contents of list {`list:1`, `list:2`, `list:3`}"
//Ryan:setNickname(Bob,"Bobby") // Not yet implemeted!
Ryan: {
"Hey `Bob`, I'm good how are you?"
} // Should display Hey Bobby, I'm good how are you?
hmm = invokeTest("Do I work?")
"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]
//fname = "Bob"
//known = true // defaults to false
//lname = "Johnson" // defaults to ""
unknown = "Some Rando"
unknown = "Ya boi"
age = .24
money = 100
excited: "path/to/file"

View File

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

View File

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