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 "dms_state.h"
#include "utils.h"
namespace dms {
bool Invoker::registerFunction(std::string str, value* (*f)(void*, dms_state*, dms_args*)) {
if (preventOverwriting && funcs.count(str)) {
@ -18,11 +19,11 @@ namespace dms {
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);
args->args[i] = args->args[i]->resolve(state);
}
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;
}
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);
void _init(void* ref);
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();
// 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);

View File

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

View File

@ -273,6 +273,31 @@ namespace dms {
}
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) {
value* v = buildVariable();
v->set();

View File

@ -489,9 +489,9 @@ namespace dms {
// 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
if (stream->match(tokens::newline,tokens::label)) { // Match and process labels
stream->next();
buildLabel(stream->next().name);

View File

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

View File

@ -17,6 +17,12 @@ namespace dms {
chunks["$INIT"]->addCmd(c);
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;
@ -28,13 +34,44 @@ namespace dms {
if (!handler->OnStateInit(this))
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() {
// We should define the defaults for the enables
enables.insert_or_assign("leaking",false);
enables.insert_or_assign("debugging",false);
enables.insert_or_assign("warnings",false); //
enables.insert_or_assign("statesave",true); // Allows you to save state
enables.insert_or_assign("omniscient",false); // Allows you to know who's who when you first meet them
pushMem(&memory);
enables.insert_or_assign("leaking", false);
enables.insert_or_assign("debugging", false);
enables.insert_or_assign("warnings", false); //
enables.insert_or_assign("statesave", true); // Allows you to save state
enables.insert_or_assign("omniscient", false); // Allows you to know who's who when you first meet them
enables.insert_or_assign("fullname", true);
chunk* c = new chunk;
c->name = "$END";
@ -45,6 +82,7 @@ namespace dms {
c->addCmd(cc);
push_chunk("$END", c);
setHandler(new Handler); // Use the default implementation
invoker.registerFunction("$BlockInvoke$", blockInvoke);
}
bool dms_state::typeAssert(value* val, datatypes type) {
if (val->type != type) {
@ -59,6 +97,9 @@ namespace dms {
bool dms_state::environmentExists(std::string bk_name) {
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) {
return (chunks.count(bk_name));
}

View File

@ -3,21 +3,24 @@
#include <string>
#include <iostream>
#include <unordered_map>
#include "Invoker.h"
#include "errors.h"
#include "chunk.h"
#include "dms_exceptions.h"
#include "Character.h"
#include "enviroment.h"
#include <stack>
namespace dms {
struct Handler;
value* blockInvoke(void*, dms_state*, dms_args*);
struct dms_state
{
Handler* handler = nullptr;
bool hasFirst = false;
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::unordered_map<std::string, chunk*> chunks;
std::unordered_map<std::string, character*> characters;
@ -37,7 +40,6 @@ namespace dms {
void push_error(errors::error err);
void push_warning(errors::error err);
void push_chunk(std::string s, chunk* c);
bool run(std::string instance);
double version = 1.0;
void enable(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);
bool characterExists(std::string bk_name);
bool environmentExists(std::string bk_name);
bool functionExists(std::string bk_name);
bool blockExists(std::string bk_name);
bool typeAssert(value* val, datatypes type);
std::unordered_map<std::string, value*>* getMem();
void pushMem();
void popMem();
value* func();
bool run();
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!
void init();
bool hasError();
private:
// From what I gathered
//std::mutex memory_mutex;
std::unordered_map<std::string, value*> memory;
void pushMem(std::unordered_map<std::string, value*>*);
bool stop = false;
bool init_init = false;
void init(chunk* chunk, size_t &pos,size_t &max, std::vector<cmd*>& cmds);

View File

@ -177,6 +177,14 @@ namespace dms {
}
return true;
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:
{
std::string obj = c->args.args[0]->getPrintable();
@ -207,22 +215,30 @@ namespace dms {
std::string funcname = c->args.args[0]->getPrintable();
value* assn = c->args.args[1];
dms_args args;
value* ret = nullptr;
for (int i = 2; i < c->args.args.size(); 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);
}
if (ret == nullptr)
return false;
if (assn->type != datatypes::nil) {
assign(mem, assn, ret);
assign(getMem(), 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);
value* indx = c->args.args[2]->resolve(this);
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
enviroment* e = nullptr;
if (environments.count(env->getPrintable())) {
@ -249,11 +265,65 @@ namespace dms {
}
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:
{
value* assn = c->args.args[0];
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
enviroment* e = nullptr;
if (environments.count(env->getPrintable())) {
@ -347,7 +417,7 @@ namespace dms {
std::string prompt = c->args.args[0]->s->getValue();
std::string fn = c->args.args[1]->s->getValue();
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 nnpos = seek(concat("CHOI_", fn, "_", npos),cmds,LABL,npos);
if (!nnpos) {
@ -361,8 +431,8 @@ namespace dms {
break;
case JUMP:
// Value assert resolves the data so a variable must eventually equal a string
if (utils::valueassert(c->args, *mem, datatypes::string)) {
std::string block = c->args.args[0]->resolve(*mem)->s->getValue();
if (utils::valueassert(c->args, this, datatypes::string)) {
std::string block = c->args.args[0]->resolve(this)->s->getValue();
if (chunks[block] == NULL) {
push_error(errors::error{ errors::non_existing_block ,utils::concat("Attempted to Jump to a non existing block [",block,"]") });
return false;
@ -376,7 +446,7 @@ namespace dms {
}
}
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 });
return false;
}

Binary file not shown.

View File

@ -22,6 +22,9 @@ Line <6> name fullname
Line <6> newline
Line <6> newline
Line <7> newline
Line <8> flag
Line <8> name debugging
Line <8> newline
Line <8> newline
Line <9> flag
Line <9> string loadtest.dms
@ -42,113 +45,87 @@ Line <13> name main
Line <13> bracketc ]
Line <13> newline
Line <13> newline
Line <14> string Time to test function calls!
Line <14> newline
Line <14> newline
Line <15> name list
Line <15> name val
Line <15> equal =
Line <15> cbracketo {
Line <15> string Hello
Line <15> name newblock
Line <15> parao (
Line <15> number 1
Line <15> seperator ,
Line <15> number 2
Line <15> seperator ,
Line <15> number 3
Line <15> cbracketc }
Line <15> parac )
Line <15> newline
Line <15> newline
Line <16> string val = `val`
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 <18> bracketo [
Line <18> name Bob
Line <18> colon :
Line <18> name char
Line <18> bracketc ]
Line <18> newline
Line <18> newline
Line <19> string Ryan's name is `Ryan`
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 <21> string Ryan's name is `Ryan`
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 <23> name age
Line <23> equal =
Line <23> number 0.24
Line <23> newline
Line <23> newline
Line <24> name money
Line <24> equal =
Line <24> number 100
Line <24> newline
Line <24> newline
Line <25> name hmm
Line <25> equal =
Line <25> name invokeTest
Line <25> parao (
Line <25> string Do I work?
Line <25> parac )
Line <25> name excited
Line <25> colon :
Line <25> string path/to/file
Line <25> newline
Line <25> 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 <28> string Func Arguments: a = `a`, b = `b`, c = `c`
Line <28> newline
Line <28> newline
Line <29> string Time to return
Line <29> newline
Line <29> newline
Line <30> bracketo [
Line <30> name Bob
Line <30> colon :
Line <30> name char
Line <30> bracketc ]
Line <30> ret
Line <30> name a
Line <30> plus +
Line <30> name b
Line <30> plus +
Line <30> name c
Line <30> newline
Line <30> newline
Line <31> newline
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 <30> eof
Line <1> newline
Line <1> newline
Line <1> flag

View File

@ -5,38 +5,26 @@ enable forseelabels
enable savestate
disable fullname
//enable leaking
//enable debugging
enable debugging
loadfile "loadtest.dms"
version 0.2
using extendedDefine
[main]
list = {"Hello",2,3}
"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`\""
"Time to test function calls!"
val = newblock(1,2,3)
"val = `val`"
[Bob:char]
//fname = "Bob"
//known = true // defaults to false
//lname = "Johnson" // defaults to ""
unknown = "Ya boi"
unknown = "Some Random Guy"
age = .24
money = 100
excited: "path/to/file"
[newblock:function()]
"Test #2"
"Does it parse this part properly?"
"huh"
[newblock:function(a,b,c)]
"Func Arguments: a = `a`, b = `b`, c = `c`"
"Time to return"
return a+b+c

View File

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

View File

@ -41,31 +41,31 @@ namespace dms::utils {
std::generate_n(str.begin(), length, randchar);
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();
datatypes types[12] = { t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12 };
if (size >= 4)
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;
}
else
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 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();
if (size >= 4)
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;
}
else
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 true;

View File

@ -27,8 +27,8 @@ namespace dms::utils {
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_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 valueassertall(dms_args args, std::unordered_map<std::string, value*> memory, datatypes t1);
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, 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);
bool isalphanum(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"
// At the end we actually delete them!
}
value* value::resolve(std::unordered_map<std::string, value*> memory) {
if (type == datatypes::variable && this!=memory[this->s->getValue()]) {
return memory[s->getValue()]->resolve(memory); // Variable types return the value
value* value::copy() {
value* newVal = new 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;
}
@ -39,8 +59,8 @@ namespace dms {
ind.clear();
varStart = false;
indStart = false;
if (state->memory.count(lookup)) {
value* v = state->memory[lookup];
if (state->getMem()->count(lookup)) {
value* v = (*state->getMem())[lookup];
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) {
character* cha = state->getCharacter(v->s->getValue());
@ -64,14 +84,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 if (v->resolve(state)->type == datatypes::env) {
if(v->resolve(state)->e->ipart.size()> std::stoi(index))
temp << v->resolve(state)->e->ipart[std::stoi(index)-1]->getPrintable();
else
temp << "nil";
}
else {
temp << v->resolve(state->memory)->getPrintable();
temp << v->resolve(state)->getPrintable();
}
}
else {
@ -100,8 +120,8 @@ namespace dms {
var.str("");
var.clear();
varStart = false;
if (state->memory.count(lookup)) {
value* v = state->memory[lookup];
if (state->getMem()->count(lookup)) {
value* v = (*state->getMem())[lookup];
if (v->type == datatypes::block) {
if (state->getCharacter(v->s->getValue())) {
temp << state->characters[v->s->getValue()]->getName();
@ -111,7 +131,7 @@ namespace dms {
}
}
else {
temp << v->resolve(state->memory)->getPrintable();
temp << v->resolve(state)->getPrintable();
}
}
else {

View File

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