Implemented math, dms functions now working, todo conditions, implement all opcodes
This commit is contained in:
parent
e738dae0c9
commit
d91ee2b662
@ -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() {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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();
|
||||
|
||||
@ -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);
|
||||
|
||||
60
DMS/codes.h
60
DMS/codes.h
@ -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) {
|
||||
|
||||
@ -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,8 +34,39 @@ 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
|
||||
pushMem(&memory);
|
||||
enables.insert_or_assign("leaking", false);
|
||||
enables.insert_or_assign("debugging", false);
|
||||
enables.insert_or_assign("warnings", false); //
|
||||
@ -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));
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
BIN
DMS/dump.bin
BIN
DMS/dump.bin
Binary file not shown.
121
DMS/dump.txt
121
DMS/dump.txt
@ -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
|
||||
|
||||
30
DMS/test.dms
30
DMS/test.dms
@ -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
|
||||
|
||||
@ -49,7 +49,7 @@ namespace dms::tokens {
|
||||
dollar,
|
||||
ampersand,
|
||||
nil,
|
||||
pipe
|
||||
pipe,
|
||||
};//stream, t_vec, line, isNum, buffer
|
||||
struct token {
|
||||
tokentype type = noop;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user