Implemented math, dms functions now working, todo conditions, implement all opcodes

This commit is contained in:
Ryan Ward 2020-10-24 15:26:21 -04:00
parent e738dae0c9
commit d91ee2b662
17 changed files with 301 additions and 168 deletions

View File

@ -1,5 +1,6 @@
#include "Invoker.h" #include "Invoker.h"
#include "dms_state.h" #include "dms_state.h"
#include "utils.h"
namespace dms { namespace dms {
bool Invoker::registerFunction(std::string str, value* (*f)(void*, dms_state*, dms_args*)) { bool Invoker::registerFunction(std::string str, value* (*f)(void*, dms_state*, dms_args*)) {
if (preventOverwriting && funcs.count(str)) { if (preventOverwriting && funcs.count(str)) {
@ -18,11 +19,11 @@ namespace dms {
value* Invoker::Invoke(std::string str, dms_state* state, dms_args* args) { value* Invoker::Invoke(std::string str, dms_state* state, dms_args* args) {
if (funcs.count(str)) { if (funcs.count(str)) {
for (int i = 0; i < args->args.size() - 1; i++) { for (int i = 0; i < args->args.size() - 1; i++) {
args->args[i] = args->args[i]->resolve(state->memory); args->args[i] = args->args[i]->resolve(state);
} }
return funcs[str](self, state, args); return funcs[str](self, state, args);
} }
state->push_error(errors::error{ errors::non_existing_function, "Attempt to call a nil value!" }); state->push_error(errors::error{ errors::non_existing_function, utils::concat("Attempt to call '",str,"' a nil value!") });
return nullptr; return nullptr;
} }
std::unordered_map<std::string, value* (*)(void*, dms_state*, dms_args*)> Invoker::Export() { std::unordered_map<std::string, value* (*)(void*, dms_state*, dms_args*)> Invoker::Export() {

View File

@ -12,6 +12,7 @@ namespace dms {
bool registerFunction(std::string str, value* (*f)(void*, dms_state*, dms_args*), bool preventoverride); bool registerFunction(std::string str, value* (*f)(void*, dms_state*, dms_args*), bool preventoverride);
void _init(void* ref); void _init(void* ref);
value* Invoke(std::string str, dms_state* state, dms_args* args); value* Invoke(std::string str, dms_state* state, dms_args* args);
// Exports the methods from an Invoker object
std::unordered_map<std::string, value* (*)(void*, dms_state*, dms_args*)> Export(); std::unordered_map<std::string, value* (*)(void*, dms_state*, dms_args*)> Export();
// Imports methods from another Invoker, this will add and overwrite any method with the same name // Imports methods from another Invoker, this will add and overwrite any method with the same name
void Import(std::unordered_map<std::string, value* (*)(void*, dms_state*, dms_args*)> tempf); void Import(std::unordered_map<std::string, value* (*)(void*, dms_state*, dms_args*)> tempf);

View File

@ -75,7 +75,7 @@ namespace dms {
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 leftside = false); bool match_process_index(tokenstream* stream,value* v = nullptr, bool leftside = false);
bool match_process_return(tokenstream* stream);
// Build // Build
void buildGoto(std::string g, bool v = false); void buildGoto(std::string g, bool v = false);

View File

@ -273,6 +273,31 @@ namespace dms {
} }
return false; return false;
} }
bool LineParser::match_process_return(tokenstream* stream) {
// Only handle this inside of a function block!
if (current_chunk->type == blocktype::bt_method) {
if (stream->match(tokens::ret)) {
cmd* c = new cmd;
c->opcode = codes::RETN;
value* ref = buildVariable();
stream->next();
if (match_process_standard(stream, ref)) {
c->args.push(ref);
current_chunk->addCmd(c);
return true;
}
else {
badSymbol();
return false;
}
}
}
else if(stream->match(tokens::ret)) {
stream->next();
badSymbol();
}
return false;
}
bool LineParser::match_process_assignment(tokenstream* stream) { bool LineParser::match_process_assignment(tokenstream* stream) {
value* v = buildVariable(); value* v = buildVariable();
v->set(); v->set();

View File

@ -489,9 +489,9 @@ namespace dms {
// This will probably be the toughest one of them all // This will probably be the toughest one of them all
} }
} }
// Display cmd must be first!!! // Let's handle function stuff!
match_process_return(stream);
match_process_disp(stream); // Match and process dialogue match_process_disp(stream); // Match and process dialogue
if (stream->match(tokens::newline,tokens::label)) { // Match and process labels if (stream->match(tokens::newline,tokens::label)) { // Match and process labels
stream->next(); stream->next();
buildLabel(stream->next().name); buildLabel(stream->next().name);

View File

@ -3,55 +3,55 @@
#include <string> #include <string>
namespace dms::codes { namespace dms::codes {
enum op { enum op {
NOOP, NOOP, // Done
ENTR, ENTR, // Done
ENAB, ENAB, // Done
DISA, DISA, // Done
LOAD, LOAD, // Done
VERN, VERN, // Done
USIN, USIN, // TODO
STAT, STAT,
DISP, DISP, // Done
ASGN, ASGN, // Done
LABL, LABL,
CHOI, CHOI, // Done
OPTN, OPTN,
FORE, FORE,
WHLE, WHLE,
FUNC, FUNC, // Done
IFFF, IFFF,
ELIF, ELIF,
ELSE, ELSE,
DEFN, DEFN,
SKIP, SKIP,
COMP, COMP,
INDX, INDX, // Done
JMPZ, JMPZ,
INST, INST, // Done
ERRO, ERRO,
GOTO, GOTO,
JUMP, JUMP, // Done
RETN, RETN,
EXIT, EXIT, // Done
DEBG, DEBG,
DSPD, DSPD, // Todo
DACT, DACT,
WAIT, WAIT, // Done
APND, APND, // Done
SSPK, SSPK, // Done
ADD, ADD, // Done
SUB, SUB, // Done
MUL, MUL, // Done
DIV, DIV, // Done
POW, POW, // Done
MOD, MOD, // Done
LIST, LIST, // Done
LINE, LINE, // Done
HALT, HALT, // Todo
FILE, FILE,
GC, GC,
ASID, ASID, // Done
OFUN OFUN // Done
}; };
extern const std::string list[]; extern const std::string list[];
static bool isControl(const op code) { static bool isControl(const op code) {

View File

@ -17,6 +17,12 @@ namespace dms {
chunks["$INIT"]->addCmd(c); chunks["$INIT"]->addCmd(c);
c = new cmd; c = new cmd;
} }
else if (val->type == blocktype::bt_method) {
c->opcode = codes::RETN;
c->args.push(buildNil());
val->addCmd(c);
c = new cmd;
}
} }
c->opcode = codes::JUMP; c->opcode = codes::JUMP;
@ -28,8 +34,39 @@ namespace dms {
if (!handler->OnStateInit(this)) if (!handler->OnStateInit(this))
stop = true; stop = true;
} }
std::unordered_map<std::string, value*>* dms_state::getMem() {
return mem_stack.top();
}
void dms_state::pushMem() {
mem_stack.push(new std::unordered_map<std::string, value*>);
}
void dms_state::popMem() {
mem_stack.pop();
}
value* dms::blockInvoke(void* self, dms_state* state, dms_args* args) {
std::string func = state->call_stack.top();
if (state->functionExists(func)) {
state->call_stack.pop();
value* ret = nullptr;
state->pushMem();
std::unordered_map<std::string, value*>* Fmem = state->getMem();
for (int i = 0; i < state->chunks[func]->params.args.size(); i++) {
Fmem->insert_or_assign(state->chunks[func]->params.args[i]->getPrintable(), args->args[i]->resolve(state)->copy());
}
state->run(func, Fmem);
ret = state->return_stack.top();
state->return_stack.pop();
state->popMem();
return ret;
}
return buildNil();
}
void dms_state::pushMem(std::unordered_map<std::string, value*>* m) {
mem_stack.push(m);
}
dms_state::dms_state() { dms_state::dms_state() {
// We should define the defaults for the enables // We should define the defaults for the enables
pushMem(&memory);
enables.insert_or_assign("leaking", false); enables.insert_or_assign("leaking", false);
enables.insert_or_assign("debugging", false); enables.insert_or_assign("debugging", false);
enables.insert_or_assign("warnings", false); // enables.insert_or_assign("warnings", false); //
@ -45,6 +82,7 @@ namespace dms {
c->addCmd(cc); c->addCmd(cc);
push_chunk("$END", c); push_chunk("$END", c);
setHandler(new Handler); // Use the default implementation setHandler(new Handler); // Use the default implementation
invoker.registerFunction("$BlockInvoke$", blockInvoke);
} }
bool dms_state::typeAssert(value* val, datatypes type) { bool dms_state::typeAssert(value* val, datatypes type) {
if (val->type != type) { if (val->type != type) {
@ -59,6 +97,9 @@ namespace dms {
bool dms_state::environmentExists(std::string bk_name) { bool dms_state::environmentExists(std::string bk_name) {
return (chunks.count(bk_name) && chunks[bk_name]->type == blocktype::bt_env); return (chunks.count(bk_name) && chunks[bk_name]->type == blocktype::bt_env);
} }
bool dms_state::functionExists(std::string bk_name) {
return (chunks.count(bk_name) && chunks[bk_name]->type == blocktype::bt_method);
}
bool dms_state::blockExists(std::string bk_name) { bool dms_state::blockExists(std::string bk_name) {
return (chunks.count(bk_name)); return (chunks.count(bk_name));
} }

View File

@ -3,21 +3,24 @@
#include <string> #include <string>
#include <iostream> #include <iostream>
#include <unordered_map> #include <unordered_map>
#include "Invoker.h" #include "Invoker.h"
#include "errors.h" #include "errors.h"
#include "chunk.h" #include "chunk.h"
#include "dms_exceptions.h" #include "dms_exceptions.h"
#include "Character.h" #include "Character.h"
#include "enviroment.h" #include "enviroment.h"
#include <stack>
namespace dms { namespace dms {
struct Handler; struct Handler;
value* blockInvoke(void*, dms_state*, dms_args*);
struct dms_state struct dms_state
{ {
Handler* handler = nullptr; Handler* handler = nullptr;
bool hasFirst = false; bool hasFirst = false;
Invoker invoker; Invoker invoker;
std::unordered_map<std::string, value*> memory; std::stack<std::string> call_stack;
std::stack<value*> return_stack;
std::stack<std::unordered_map<std::string, value*>*> mem_stack;
std::vector<value*> garbage; std::vector<value*> garbage;
std::unordered_map<std::string, chunk*> chunks; std::unordered_map<std::string, chunk*> chunks;
std::unordered_map<std::string, character*> characters; std::unordered_map<std::string, character*> characters;
@ -37,7 +40,6 @@ namespace dms {
void push_error(errors::error err); void push_error(errors::error err);
void push_warning(errors::error err); void push_warning(errors::error err);
void push_chunk(std::string s, chunk* c); void push_chunk(std::string s, chunk* c);
bool run(std::string instance);
double version = 1.0; double version = 1.0;
void enable(std::string flag); void enable(std::string flag);
void disable(std::string flag); void disable(std::string flag);
@ -55,17 +57,24 @@ namespace dms {
size_t seek(std::string label,std::vector<cmd*> cmds ,codes::op code, size_t pos); size_t seek(std::string label,std::vector<cmd*> cmds ,codes::op code, size_t pos);
bool characterExists(std::string bk_name); bool characterExists(std::string bk_name);
bool environmentExists(std::string bk_name); bool environmentExists(std::string bk_name);
bool functionExists(std::string bk_name);
bool blockExists(std::string bk_name); bool blockExists(std::string bk_name);
bool typeAssert(value* val, datatypes type); bool typeAssert(value* val, datatypes type);
std::unordered_map<std::string, value*>* getMem();
void pushMem();
void popMem();
value* func();
bool run(); bool run();
bool run(std::string ent,std::unordered_map<std::string, value*>* mem); bool run(std::string ent,std::unordered_map<std::string, value*>* mem);
bool run(std::string instance);
// This is called once and once only. Dynamically loading code is not a thing! // This is called once and once only. Dynamically loading code is not a thing!
void init(); void init();
bool hasError(); bool hasError();
private: private:
// From what I gathered // From what I gathered
//std::mutex memory_mutex; //std::mutex memory_mutex;
std::unordered_map<std::string, value*> memory;
void pushMem(std::unordered_map<std::string, value*>*);
bool stop = false; bool stop = false;
bool init_init = false; bool init_init = false;
void init(chunk* chunk, size_t &pos,size_t &max, std::vector<cmd*>& cmds); void init(chunk* chunk, size_t &pos,size_t &max, std::vector<cmd*>& cmds);

View File

@ -177,6 +177,14 @@ namespace dms {
} }
return true; return true;
break; break;
case RETN:
{
value* ret = c->args.args[0]->resolve(this)->copy();
//c->args.args[0]->nuke(); // Lets clean this up
return_stack.push(ret);
return true; // We did it, let's return this
}
break;
case OFUN: case OFUN:
{ {
std::string obj = c->args.args[0]->getPrintable(); std::string obj = c->args.args[0]->getPrintable();
@ -207,22 +215,30 @@ namespace dms {
std::string funcname = c->args.args[0]->getPrintable(); std::string funcname = c->args.args[0]->getPrintable();
value* assn = c->args.args[1]; value* assn = c->args.args[1];
dms_args args; dms_args args;
value* ret = nullptr;
for (int i = 2; i < c->args.args.size(); i++) { for (int i = 2; i < c->args.args.size(); i++) {
args.push(c->args.args[i]); args.push(c->args.args[i]);
} }
// If we have a block made function we don't invoke like normal
if (functionExists(funcname)) {
call_stack.push(funcname);
ret = invoker.Invoke("$BlockInvoke$", this, &args);
}
else {
value* ret = invoker.Invoke(funcname, this, &args); value* ret = invoker.Invoke(funcname, this, &args);
}
if (ret == nullptr) if (ret == nullptr)
return false; return false;
if (assn->type != datatypes::nil) { if (assn->type != datatypes::nil) {
assign(mem, assn, ret); assign(getMem(), assn, ret);
} }
} }
break; break;
case ASID: case ASID:
{ {
value* env = c->args.args[1]; value* env = c->args.args[1];
value* indx = c->args.args[2]->resolve(*mem); value* indx = c->args.args[2]->resolve(this);
value* assn = c->args.args[3]->resolve(*mem); value* assn = c->args.args[3]->resolve(this);
if (env->type == datatypes::block && blockExists(env->getPrintable())) { // If this is a block let's handle this if (env->type == datatypes::block && blockExists(env->getPrintable())) { // If this is a block let's handle this
enviroment* e = nullptr; enviroment* e = nullptr;
if (environments.count(env->getPrintable())) { if (environments.count(env->getPrintable())) {
@ -249,11 +265,65 @@ namespace dms {
} }
break; break;
} }
case ADD:
{
value* assn = c->args.args[0];
value* o1 = c->args.args[1];
value* o2 = c->args.args[2];
value* ret = buildValue(o1->resolve(this)->n->getValue()+o2->resolve(this)->n->getValue());
assign(getMem(), assn, ret);
}
break;
case SUB:
{
value* assn = c->args.args[0];
value* o1 = c->args.args[1];
value* o2 = c->args.args[2];
value* ret = buildValue(o1->resolve(this)->n->getValue() - o2->resolve(this)->n->getValue());
assign(getMem(), assn, ret);
}
break;
case MUL:
{
value* assn = c->args.args[0];
value* o1 = c->args.args[1];
value* o2 = c->args.args[2];
value* ret = buildValue(o1->resolve(this)->n->getValue() * o2->resolve(this)->n->getValue());
assign(getMem(), assn, ret);
}
break;
case DIV:
{
value* assn = c->args.args[0];
value* o1 = c->args.args[1];
value* o2 = c->args.args[2];
value* ret = buildValue(o1->resolve(this)->n->getValue() / o2->resolve(this)->n->getValue());
assign(getMem(), assn, ret);
}
break;
case POW:
{
value* assn = c->args.args[0];
value* o1 = c->args.args[1];
value* o2 = c->args.args[2];
value* ret = buildValue(pow(o1->resolve(this)->n->getValue(), o2->resolve(this)->n->getValue()));
assign(getMem(), assn, ret);
}
break;
case MOD:
{
value* assn = c->args.args[0];
value* o1 = c->args.args[1];
value* o2 = c->args.args[2];
value* ret = buildValue(std::fmod(o1->resolve(this)->n->getValue(),o2->resolve(this)->n->getValue()));
assign(getMem(), assn, ret);
}
break;
case INDX: case INDX:
{ {
value* assn = c->args.args[0]; value* assn = c->args.args[0];
value* env = c->args.args[1]; value* env = c->args.args[1];
value* indx = c->args.args[2]->resolve(*mem); value* indx = c->args.args[2]->resolve(this);
if (env->type == datatypes::block && blockExists(env->getPrintable())) { // If this is a block let's handle this if (env->type == datatypes::block && blockExists(env->getPrintable())) { // If this is a block let's handle this
enviroment* e = nullptr; enviroment* e = nullptr;
if (environments.count(env->getPrintable())) { if (environments.count(env->getPrintable())) {
@ -347,7 +417,7 @@ namespace dms {
std::string prompt = c->args.args[0]->s->getValue(); std::string prompt = c->args.args[0]->s->getValue();
std::string fn = c->args.args[1]->s->getValue(); std::string fn = c->args.args[1]->s->getValue();
for (size_t i = 2; i < c->args.args.size(); i++) for (size_t i = 2; i < c->args.args.size(); i++)
args.push_back(c->args.args[i]->resolve(*mem)->s->getValue()); args.push_back(c->args.args[i]->resolve(this)->s->getValue());
size_t npos = handler->handleChoice(this, prompt, args); size_t npos = handler->handleChoice(this, prompt, args);
size_t nnpos = seek(concat("CHOI_", fn, "_", npos),cmds,LABL,npos); size_t nnpos = seek(concat("CHOI_", fn, "_", npos),cmds,LABL,npos);
if (!nnpos) { if (!nnpos) {
@ -361,8 +431,8 @@ namespace dms {
break; break;
case JUMP: case JUMP:
// Value assert resolves the data so a variable must eventually equal a string // Value assert resolves the data so a variable must eventually equal a string
if (utils::valueassert(c->args, *mem, datatypes::string)) { if (utils::valueassert(c->args, this, datatypes::string)) {
std::string block = c->args.args[0]->resolve(*mem)->s->getValue(); std::string block = c->args.args[0]->resolve(this)->s->getValue();
if (chunks[block] == NULL) { if (chunks[block] == NULL) {
push_error(errors::error{ errors::non_existing_block ,utils::concat("Attempted to Jump to a non existing block [",block,"]") }); push_error(errors::error{ errors::non_existing_block ,utils::concat("Attempted to Jump to a non existing block [",block,"]") });
return false; return false;
@ -376,7 +446,7 @@ namespace dms {
} }
} }
else { else {
datatypes set = c->args.args[0]->resolve(*mem)->type; datatypes set = c->args.args[0]->resolve(this)->type;
push_error(errors::error{ errors::invalid_arguments, utils::concat("String expected got ",datatype[set]), true,ln }); push_error(errors::error{ errors::invalid_arguments, utils::concat("String expected got ",datatype[set]), true,ln });
return false; return false;
} }

Binary file not shown.

View File

@ -22,6 +22,9 @@ Line <6> name fullname
Line <6> newline Line <6> newline
Line <6> newline Line <6> newline
Line <7> newline Line <7> newline
Line <8> flag
Line <8> name debugging
Line <8> newline
Line <8> newline Line <8> newline
Line <9> flag Line <9> flag
Line <9> string loadtest.dms Line <9> string loadtest.dms
@ -42,113 +45,87 @@ 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 Time to test function calls!
Line <14> newline Line <14> newline
Line <14> newline Line <14> newline
Line <15> name list Line <15> name val
Line <15> equal = Line <15> equal =
Line <15> cbracketo { Line <15> name newblock
Line <15> string Hello Line <15> parao (
Line <15> number 1
Line <15> seperator , Line <15> seperator ,
Line <15> number 2 Line <15> number 2
Line <15> seperator , Line <15> seperator ,
Line <15> number 3 Line <15> number 3
Line <15> cbracketc } Line <15> parac )
Line <15> newline Line <15> newline
Line <15> newline Line <15> newline
Line <16> string val = `val`
Line <16> newline Line <16> newline
Line <16> newline Line <16> newline
Line <17> string Contents of list {`list:1`, `list:2`, `list:3`}
Line <17> newline Line <17> newline
Line <17> newline Line <17> newline
Line <18> bracketo [
Line <18> name Bob
Line <18> colon :
Line <18> name char
Line <18> bracketc ]
Line <18> newline Line <18> newline
Line <18> newline Line <18> newline
Line <19> string Ryan's name is `Ryan`
Line <19> newline Line <19> newline
Line <19> newline
Line <20> name Ryan
Line <20> dot .
Line <20> name setName
Line <20> parao (
Line <20> string Bryan
Line <20> parac )
Line <20> newline Line <20> newline
Line <20> newline
Line <21> string Ryan's name is `Ryan`
Line <21> newline
Line <21> newline Line <21> newline
Line <22> name unknown
Line <22> equal =
Line <22> string Some Random Guy
Line <22> newline Line <22> newline
Line <22> newline Line <22> newline
Line <23> name age
Line <23> equal =
Line <23> number 0.24
Line <23> newline Line <23> newline
Line <23> newline
Line <24> name money
Line <24> equal =
Line <24> number 100
Line <24> newline Line <24> newline
Line <24> newline Line <24> newline
Line <25> name hmm Line <25> name excited
Line <25> equal = Line <25> colon :
Line <25> name invokeTest Line <25> string path/to/file
Line <25> parao (
Line <25> string Do I work?
Line <25> parac )
Line <25> newline Line <25> newline
Line <25> newline Line <25> newline
Line <26> newline Line <26> newline
Line <26> newline Line <26> newline
Line <27> string The return of hmm is "`hmm`" Line <27> bracketo [
Line <27> name newblock
Line <27> colon :
Line <27> name function
Line <27> parao (
Line <27> name a
Line <27> seperator ,
Line <27> name b
Line <27> seperator ,
Line <27> name c
Line <27> parac )
Line <27> bracketc ]
Line <27> newline Line <27> newline
Line <27> newline Line <27> newline
Line <28> string Func Arguments: a = `a`, b = `b`, c = `c`
Line <28> newline Line <28> newline
Line <28> newline Line <28> newline
Line <29> string Time to return
Line <29> newline Line <29> newline
Line <29> newline Line <29> newline
Line <30> bracketo [ Line <30> ret
Line <30> name Bob Line <30> name a
Line <30> colon : Line <30> plus +
Line <30> name char Line <30> name b
Line <30> bracketc ] Line <30> plus +
Line <30> name c
Line <30> newline Line <30> newline
Line <30> newline Line <30> newline
Line <31> newline Line <30> eof
Line <32> newline
Line <33> newline
Line <34> name unknown
Line <34> equal =
Line <34> string Ya boi
Line <34> newline
Line <34> newline
Line <35> name age
Line <35> equal =
Line <35> number 0.24
Line <35> newline
Line <35> newline
Line <36> name money
Line <36> equal =
Line <36> number 100
Line <36> newline
Line <36> newline
Line <37> name excited
Line <37> colon :
Line <37> string path/to/file
Line <37> newline
Line <37> newline
Line <38> newline
Line <38> newline
Line <39> bracketo [
Line <39> name newblock
Line <39> colon :
Line <39> name function
Line <39> parao (
Line <39> parac )
Line <39> bracketc ]
Line <39> newline
Line <39> newline
Line <40> string Test #2
Line <40> newline
Line <40> newline
Line <41> string Does it parse this part properly?
Line <41> newline
Line <41> newline
Line <42> string huh
Line <42> newline
Line <42> newline
Line <42> eof
Line <1> newline Line <1> newline
Line <1> newline Line <1> newline
Line <1> flag Line <1> flag

View File

@ -5,38 +5,26 @@ enable forseelabels
enable savestate enable savestate
disable fullname disable fullname
//enable leaking //enable leaking
//enable debugging enable debugging
loadfile "loadtest.dms" loadfile "loadtest.dms"
version 0.2 version 0.2
using extendedDefine using extendedDefine
[main] [main]
"Time to test function calls!"
list = {"Hello",2,3} val = newblock(1,2,3)
"val = `val`"
"Contents of list {`list:1`, `list:2`, `list:3`}"
"Ryan's name is `Ryan`"
Ryan.setName("Bryan")
"Ryan's name is `Ryan`"
//Ryan.setNickname(Bob,"Bobby") // Not yet implemeted!
hmm = invokeTest("Do I work?")
"The return of hmm is \"`hmm`\""
[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 = "Ya boi" unknown = "Some Random Guy"
age = .24 age = .24
money = 100 money = 100
excited: "path/to/file" excited: "path/to/file"
[newblock:function()] [newblock:function(a,b,c)]
"Test #2" "Func Arguments: a = `a`, b = `b`, c = `c`"
"Does it parse this part properly?" "Time to return"
"huh" return a+b+c

View File

@ -49,7 +49,7 @@ namespace dms::tokens {
dollar, dollar,
ampersand, ampersand,
nil, nil,
pipe pipe,
};//stream, t_vec, line, isNum, buffer };//stream, t_vec, line, isNum, buffer
struct token { struct token {
tokentype type = noop; tokentype type = noop;

View File

@ -41,31 +41,31 @@ namespace dms::utils {
std::generate_n(str.begin(), length, randchar); std::generate_n(str.begin(), length, randchar);
return str; return str;
} }
bool valueassert(dms_args args, std::unordered_map<std::string, value*> memory, datatypes t1, datatypes t2, datatypes t3, datatypes t4, datatypes t5, datatypes t6, datatypes t7, datatypes t8, datatypes t9, datatypes t10, datatypes t11, datatypes t12) { bool valueassert(dms_args args, dms_state* state, datatypes t1, datatypes t2, datatypes t3, datatypes t4, datatypes t5, datatypes t6, datatypes t7, datatypes t8, datatypes t9, datatypes t10, datatypes t11, datatypes t12) {
size_t size = args.args.size(); size_t size = args.args.size();
datatypes types[12] = { t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12 }; datatypes types[12] = { t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12 };
if (size >= 4) if (size >= 4)
for (size_t i = 0; i < 4; i++) { for (size_t i = 0; i < 4; i++) {
if (args.args[i]->resolve(memory)->type != types[i]) if (args.args[i]->resolve(state)->type != types[i])
return false; return false;
} }
else else
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
if (args.args[i]->resolve(memory)->type != types[i]) if (args.args[i]->resolve(state)->type != types[i])
return false; return false;
} }
return true; return true;
} }
bool valueassertall(dms_args args, std::unordered_map<std::string, value*> memory, datatypes t1) { bool valueassertall(dms_args args, dms_state* state, datatypes t1) {
size_t size = args.args.size(); size_t size = args.args.size();
if (size >= 4) if (size >= 4)
for (size_t i = 0; i < 4; i++) { for (size_t i = 0; i < 4; i++) {
if (args.args[i]->resolve(memory)->type != t1) if (args.args[i]->resolve(state)->type != t1)
return false; return false;
} }
else else
for (size_t i = 0; i < size; i++) { for (size_t i = 0; i < size; i++) {
if (args.args[i]->resolve(memory)->type != t1) if (args.args[i]->resolve(state)->type != t1)
return false; return false;
} }
return true; return true;

View File

@ -27,8 +27,8 @@ namespace dms::utils {
std::string random_string(size_t length); std::string random_string(size_t length);
bool typeassert(dms_args args, datatypes t1=nil, datatypes t2 = nil, datatypes t3 = nil, datatypes t4 = nil, datatypes t5 = nil, datatypes t6 = nil, datatypes t7 = nil, datatypes t8 = nil, datatypes t9 = nil, datatypes t10 = nil, datatypes t11 = nil, datatypes t12 = nil); //Type asserting is mostly an internal thing for build in methods. It's not needed for dms code! bool typeassert(dms_args args, datatypes t1=nil, datatypes t2 = nil, datatypes t3 = nil, datatypes t4 = nil, datatypes t5 = nil, datatypes t6 = nil, datatypes t7 = nil, datatypes t8 = nil, datatypes t9 = nil, datatypes t10 = nil, datatypes t11 = nil, datatypes t12 = nil); //Type asserting is mostly an internal thing for build in methods. It's not needed for dms code!
bool typeassert(dms_state* state, dms_args args, datatypes t1 = nil, datatypes t2 = nil, datatypes t3 = nil, datatypes t4 = nil, datatypes t5 = nil, datatypes t6 = nil, datatypes t7 = nil, datatypes t8 = nil, datatypes t9 = nil, datatypes t10 = nil, datatypes t11 = nil, datatypes t12 = nil); bool typeassert(dms_state* state, dms_args args, datatypes t1 = nil, datatypes t2 = nil, datatypes t3 = nil, datatypes t4 = nil, datatypes t5 = nil, datatypes t6 = nil, datatypes t7 = nil, datatypes t8 = nil, datatypes t9 = nil, datatypes t10 = nil, datatypes t11 = nil, datatypes t12 = nil);
bool valueassert(dms_args args, std::unordered_map<std::string, value*> memory, datatypes t1 = nil, datatypes t2 = nil, datatypes t3 = nil, datatypes t4 = nil, datatypes t5 = nil, datatypes t6 = nil, datatypes t7 = nil, datatypes t8 = nil, datatypes t9 = nil, datatypes t10 = nil, datatypes t11 = nil, datatypes t12 = nil); bool valueassert(dms_args args, dms_state* state, datatypes t1 = nil, datatypes t2 = nil, datatypes t3 = nil, datatypes t4 = nil, datatypes t5 = nil, datatypes t6 = nil, datatypes t7 = nil, datatypes t8 = nil, datatypes t9 = nil, datatypes t10 = nil, datatypes t11 = nil, datatypes t12 = nil);
bool valueassertall(dms_args args, std::unordered_map<std::string, value*> memory, datatypes t1); bool valueassertall(dms_args args, dms_state* state, datatypes t1);
std::string resolveTypes(datatypes t1 = nil, datatypes t2 = nil, datatypes t3 = nil, datatypes t4 = nil, datatypes t5 = nil, datatypes t6 = nil, datatypes t7 = nil, datatypes t8 = nil, datatypes t9 = nil, datatypes t10 = nil, datatypes t11 = nil, datatypes t12 = nil); std::string resolveTypes(datatypes t1 = nil, datatypes t2 = nil, datatypes t3 = nil, datatypes t4 = nil, datatypes t5 = nil, datatypes t6 = nil, datatypes t7 = nil, datatypes t8 = nil, datatypes t9 = nil, datatypes t10 = nil, datatypes t11 = nil, datatypes t12 = nil);
bool isalphanum(std::string str); bool isalphanum(std::string str);
bool isalpha(std::string str); bool isalpha(std::string str);

View File

@ -11,9 +11,29 @@ namespace dms {
// Values at runtime aren't "Deleted, they are set to nil" // Values at runtime aren't "Deleted, they are set to nil"
// At the end we actually delete them! // At the end we actually delete them!
} }
value* value::resolve(std::unordered_map<std::string, value*> memory) { value* value::copy() {
if (type == datatypes::variable && this!=memory[this->s->getValue()]) { value* newVal = new value;
return memory[s->getValue()]->resolve(memory); // Variable types return the value newVal->type = type;
newVal->c = c;
newVal->e = e;
if (type == datatypes::block || type == datatypes::string || type == datatypes::variable) {
newVal->s = buildString(s->getValue());
}
else if (type == datatypes::boolean) {
newVal->b = buildBool(b->getValue());
}
else if (type == datatypes::number) {
newVal->n = buildNumber(n->getValue());
}
else if (type == datatypes::nil) {
delete newVal;
return buildNil();
}
return newVal;
}
value* value::resolve(dms_state* state) {
if (type == datatypes::variable && this!=(*state->getMem())[this->s->getValue()]) {
return (*state->getMem())[s->getValue()]->resolve(state); // Variable types return the value
} }
return this; return this;
} }
@ -39,8 +59,8 @@ namespace dms {
ind.clear(); ind.clear();
varStart = false; varStart = false;
indStart = false; indStart = false;
if (state->memory.count(lookup)) { if (state->getMem()->count(lookup)) {
value* v = state->memory[lookup]; value* v = (*state->getMem())[lookup];
if (v->type == datatypes::block) { if (v->type == datatypes::block) {
if ((state->chunks.count(v->s->getValue()) && state->chunks[v->s->getValue()]->type == blocktype::bt_character) && state->getCharacter(v->s->getValue())!=nullptr) { if ((state->chunks.count(v->s->getValue()) && state->chunks[v->s->getValue()]->type == blocktype::bt_character) && state->getCharacter(v->s->getValue())!=nullptr) {
character* cha = state->getCharacter(v->s->getValue()); character* cha = state->getCharacter(v->s->getValue());
@ -64,14 +84,14 @@ namespace dms {
temp << "nil"; temp << "nil";
} }
} }
else if (v->resolve(state->memory)->type == datatypes::env) { else if (v->resolve(state)->type == datatypes::env) {
if(v->resolve(state->memory)->e->ipart.size()> std::stoi(index)) if(v->resolve(state)->e->ipart.size()> std::stoi(index))
temp << v->resolve(state->memory)->e->ipart[std::stoi(index)-1]->getPrintable(); temp << v->resolve(state)->e->ipart[std::stoi(index)-1]->getPrintable();
else else
temp << "nil"; temp << "nil";
} }
else { else {
temp << v->resolve(state->memory)->getPrintable(); temp << v->resolve(state)->getPrintable();
} }
} }
else { else {
@ -100,8 +120,8 @@ namespace dms {
var.str(""); var.str("");
var.clear(); var.clear();
varStart = false; varStart = false;
if (state->memory.count(lookup)) { if (state->getMem()->count(lookup)) {
value* v = state->memory[lookup]; value* v = (*state->getMem())[lookup];
if (v->type == datatypes::block) { if (v->type == datatypes::block) {
if (state->getCharacter(v->s->getValue())) { if (state->getCharacter(v->s->getValue())) {
temp << state->characters[v->s->getValue()]->getName(); temp << state->characters[v->s->getValue()]->getName();
@ -111,7 +131,7 @@ namespace dms {
} }
} }
else { else {
temp << v->resolve(state->memory)->getPrintable(); temp << v->resolve(state)->getPrintable();
} }
} }
else { else {

View File

@ -74,7 +74,8 @@ namespace dms {
dms_env* e = nullptr; dms_env* e = nullptr;
dms_custom* c = nullptr; dms_custom* c = nullptr;
value(); value();
value* resolve(std::unordered_map<std::string,value*> map); value* resolve(dms_state*);
value* copy();
void nuke(); void nuke();
void set(dms_string* str); void set(dms_string* str);
void set(dms_boolean* bo); void set(dms_boolean* bo);