Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
602b665
Merge pull request #2 from dutils-official/master
RubyTheRoobster Aug 11, 2022
bda28a7
Merge pull request #8 from dutils-official/master
RubyTheRoobster Aug 18, 2022
b9b3b47
Merge branch 'master' of https://github.com/dutils-official/dutils in…
RubyTheRoobster Sep 13, 2022
d77dbce
Merge pull request #15 from dutils-official/master
RubyTheRoobster Mar 5, 2023
d68d05f
Dummy Function, add docs
RubyTheRoobster Mar 7, 2023
48e8971
Add precision, some headway
RubyTheRoobster Mar 7, 2023
b3d6679
Final commit of the day: Make some more headway
RubyTheRoobster Mar 7, 2023
8cc8574
Add operator comparison
RubyTheRoobster Mar 9, 2023
63a890e
Add dummy loop and fix some simple, but stupid bugs
RubyTheRoobster Mar 9, 2023
c1caec1
Make some headway in adding constants to the verification function, t…
RubyTheRoobster Mar 14, 2023
62767f7
Fixed the bug: forgetting to increment i at the end of the case
RubyTheRoobster Mar 14, 2023
3198322
Implemented constants in function execution, getting a range violation
RubyTheRoobster Mar 19, 2023
80687ad
Fixed one bug, but there is yet another to contend with
RubyTheRoobster Mar 20, 2023
fc32b64
It works, I forgot to exclude % signs from operators
RubyTheRoobster Mar 22, 2023
4c7383d
remove debug output
RubyTheRoobster Mar 22, 2023
7dfce9f
Implement main loop and make an adjustment to the definition of an op…
RubyTheRoobster Mar 24, 2023
b0ce161
Fix some bugs, begin to write unittest, new bug discovered.
RubyTheRoobster May 3, 2023
7c85f8c
Bug fixed, but the main loop hangs.
RubyTheRoobster May 3, 2023
f4400d6
Discarding summations, as they are too hard to impliment. Will imple…
RubyTheRoobster Jul 16, 2023
4e8a4a7
Make headway with the logarithm, rework opList
RubyTheRoobster Jul 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
183 changes: 172 additions & 11 deletions source/dutils/math/core.d
Original file line number Diff line number Diff line change
Expand Up @@ -169,9 +169,89 @@ bool validateFunction(in dstring func, in dstring def) @trusted
do
{
tempNum = ""d;
dstring val3;
dstring val;
switch(def[i])
{
case d('('):
case d('%'): //Constants
debug import std.stdio;
if(isOperand && !isOp)
return false;
isOperand = true;
++i;
do
{
val ~= def[i];
++i;
if(i == def.length)
return false;
}
while(def[i] != d('('));
++i;
do
{
val3 ~= def[i];
++i;
if(i == def.length)
return false;
}
while(def[i] != d(')'));
++i;

static foreach(type; typel)
{
mixin(type ~ " " ~ type ~ "painConstant = new " ~ type ~ "();");
}

static foreach(type; typel)
{
if(type == val)
{
try
{
mixin(type ~ "painConstant.fromDstring(val3);");
}
catch(Exception e)
{
return false;
}
goto endf;
}
}
endf:

if(isOp)
{
static foreach(type; typel)
{
if(currOperand == type)
{
static foreach(type2; typel)
{
if(type2 == val)
{
mixin("if(!" ~ type ~ "painConstant.applyOp(currOp, " ~ type2 ~ "painConstant))
{
return false;
}");
goto endf2;
}
}
}
}
endf2:
isOp = false;
currOperand = val;
}

if(def[i] != d('%'))
{
return false;
}
++i;

break;
case d('('):
++indentation;
++i;
break;
Expand Down Expand Up @@ -445,10 +525,10 @@ bool validateFunction(in dstring func, in dstring def) @trusted
do
{
tempstr ~= def[i];
if(((def[i] != d('x')) && (def[i] != d('\\'))) && (def[i] != d('(') && def[i] != d(' ')))
if(((def[i] != d('x')) && (def[i] != d('\\'))) && (def[i] != d('(') && def[i] != d(' ')) && def[i] != d('%'))
++i;
}
while((def[i] != d('x') && def[i] != d('\\')) && (def[i] != d('(') && def[i] != d(' ')));
while((def[i] != d('x') && def[i] != d('\\')) && (def[i] != d('(') && def[i] != d(' ')) && def[i] != d('%'));

/+if(def[i] != d('(')) // Operators+/
currOp = tempstr.idup;
Expand Down Expand Up @@ -525,6 +605,10 @@ bool validateFunction(in dstring func, in dstring def) @trusted
def = "x1*x2"d;
func = "(Number,Number)(Number)"d;
assert(registerFunction("f"d, func, def));

// Issue 16
def = "x1*x2*%Number(5+0i)%"d;
assert(validateFunction(func, def));
//Functions within functions were too hard to implement, so we removed them.
//def = "x1* f(x1,x2)(Number)"d;
//assert(validateFunction(func, def));
Expand Down Expand Up @@ -579,7 +663,7 @@ import std.typecons : Tuple;

/***********************************************************
* Executes a function.
*
* TODO: Constants
*
* Params:
* func =
Expand Down Expand Up @@ -607,10 +691,23 @@ Return executeFunction(Return, Mtypes...)(in dstring func, in Tuple!(Mtypes) arg
size_t indentation = 0;
size_t[size_t] parenNum;
parenNum[0] = 0;
bool bruhx = false;
for(size_t i = 0; i < funcList[func].length; ++i) // Organize the function into parentheses groups.
{
switch(funcList[func][i])
{
case d('%'): // Bug-free
do
{
parens[indentation][parenNum[indentation]] ~= funcList[func][i];
++i;
if(i >= funcList[func].length)
break;
}
while(funcList[func][i] != d(')'));
parens[indentation][parenNum[indentation]] ~= ")%"d;
++i;
break;
case d('('):
++indentation;
if(indentation !in parens)
Expand Down Expand Up @@ -664,24 +761,82 @@ Return executeFunction(Return, Mtypes...)(in dstring func, in Tuple!(Mtypes) arg
}
foreach(ref key; keys2)
key.sort!"b > a";


foreach_reverse(key; keys)
{
debug import std.stdio;
size_t currParen = 0;
foreach(key2; keys2[key])
{
dstring currOp = ""d;
dstring currType = ""d;
bool firstOperand = false;
size_t currParen = 0;
for(size_t i = 0; i < parens[key][key2].length; i++)
{
//Get to work executing the function.
// Get to work executing the function.
switch(parens[key][key2][i])
{
case d('('): //Parentheses, also known as a pain in the ass.
case d('%'): // Constants (Issue #16)
dstring tempType = ""d;
++i;
do
{
tempType ~= parens[key][key2][i];
++i;
}
while(parens[key][key2][i] != d('('));

dstring val = ""d;
++i;
do
{
val ~= parens[key][key2][i];
++i;
}
while(parens[key][key2][i] != d(')'));
++i;

if(!firstOperand)
{
firstOperand = true;
static foreach(type; typel)
{
if(type == tempType)
{
mixin("temp" ~ type ~ "[key][key2] = new " ~ type ~ "();");
mixin("temp" ~ type ~ "[key][key2].fromDstring(val);");
}
}
currType = tempType;
}
else
{
bool c;
static foreach(type2; typel)
{
if(type2 == tempType)
{
mixin(type2 ~ " constant = new " ~ type2 ~ "();");
constant.fromDstring(val);
static foreach(type; typel)
{
if(type == currType)
{
mixin("c = temp" ~ type ~ "[key][key2].applyOp(currOp, constant);");
}
}
}
}
assert(c);
currOp = ""d;
}
break;
case d('('): // Parentheses, also known as a pain in the ass.
static foreach(type; typel)
{
mixin("if(temp" ~ type ~ "[key+1][currParen] !is null)
mixin("
if(temp" ~ type ~ "[key+1][currParen] !is null)
{
currType = type;
if(!firstOperand)
Expand Down Expand Up @@ -766,8 +921,6 @@ Return executeFunction(Return, Mtypes...)(in dstring func, in Tuple!(Mtypes) arg
--i;
currOp = ""d;
break;
case d('\\'): //Operators, such as derivatives, sums, and integrals.
break;
default: //Type specific operators.
do
{
Expand All @@ -777,7 +930,7 @@ Return executeFunction(Return, Mtypes...)(in dstring func, in Tuple!(Mtypes) arg
break;
}
while(parens[key][key2][i] != d('\\') && parens[key][key2][i] != d('x') && parens[key][key2][i]
!= d('('));
!= d('(') && parens[key][key2][i] != d('%'));
--i;
}
}
Expand Down Expand Up @@ -841,4 +994,12 @@ Return executeFunction(Return, Mtypes...)(in dstring func, in Tuple!(Mtypes) arg
assert(registerFunction("ree"d, func, def));
i = executeFunction!(Number, Number, Number, Number, Number)("ree(Number,Number,Number,Number)(Number)"d, b);
assert(i.toDstring == "6+0i"d, cast(char[])i.toDstring.dup);
assert(removeFunction("ree"d, func));

// Issue 16

def ~= "+%Number(5+0i)%"d;
assert(registerFunction("ree"d, func, def));
i = executeFunction!(Number, Number, Number, Number, Number)("ree(Number,Number,Number,Number)(Number)"d, b);
assert(i.toDstring == "11+0i"d, cast(char[])i.toDstring.dup);
}
62 changes: 46 additions & 16 deletions source/dutils/math/def.d
Original file line number Diff line number Diff line change
Expand Up @@ -65,34 +65,61 @@ abstract class Mtype(T) if(__traits(hasMember, T, "precision"))
{
this.contained = num;
}
protected:
package:
T contained;
}

/// Define an Operator as used by dutils.math.
alias Operator = dstring function(dstring[]) @safe;
/// Trying to workaround it being impossible to have varying template params.
package import std.variant;

package struct _variant
{
Variant var;
dstring hash;
}

/// Container for the list of all operators.
struct Oplist
/// Container for the operator list:
struct OpList
{
Operator opIndex(dstring op) pure @safe const shared
Variant opIndex(dstring hash)
{
return this.ops[op];
Variant ret = false;
foreach(op; ops)
{
if(op.hash == hash)
return op.var;
}
return ret;
}
auto opBinaryRight(string op)(dstring key) pure @safe const shared if(op == "in" || op == "!in")
bool opBinaryRight(string op)(inout(dchar)[] key) @trusted if(op == "in" || op == "!in")
{
mixin("return key " ~ op ~ " ops;");
static if(op == "in")
const k = true;
else
const k = false;
foreach(op; ops)
{
if(op.hash == cast(dstring)key)
return k;
}
return !k;
}
auto keys() @safe
auto keys() const @trusted @property
{
return this.ops.keys;
dstring[] _keys;
foreach(op; ops)
{
_keys ~= op.hash;
}
return _keys;
}
package:
Operator[dstring] ops;
_variant[] ops;
}

/// The list of all operators.
package shared Oplist opList;
/// The list of all special functions/operators.
package OpList opList;


/// Container for the function list.
struct Funclist
Expand All @@ -105,7 +132,7 @@ struct Funclist
{
mixin("return cast(dstring)key " ~ op ~ " funcs;");
}
auto keys()
auto keys() pure nothrow @safe
{
return this.funcs.keys;
}
Expand All @@ -119,4 +146,7 @@ package shared Funclist funcList;
package import dutils.math.number; // I'm not sure why this line is here, but I'm too scared to touch it.

/// The list of all types, that has to be kept here and continously updated.
enum dstring[] typel = ["Number"]; // Too bad that complete modular programming is impossible in D.
enum dstring[] typel = ["Number"d]; // Too bad that complete modular programming is impossible in D.

/// The list of all types, that has to be kept here and continously updated (string version):
enum string[] typels = ["Number"];
Loading