Why stops this code
mitgedanken
sara.dolores.tasche at gmail.com
Sat Apr 25 18:59:41 UTC 2026
At ``unittest // ???`` you see what's my problem I don't
understand.
What I already done:
- Removed ``nothrow``
- Using ``try-catch``
```d
module mitgedanken.parser;
import std.typecons : Tuple;
import std.container : Array;
import std.conv : to;
import std.traits : isSomeString;
import std.string;
struct Symbol
{
string str;
@property ulong length() const @safe pure nothrow =>
this.str.length;
@property bool empty() const @safe pure nothrow =>
(this.str.length == 0);
static Symbol asEmpty() @safe pure nothrow
=> Symbol("");
string toString() const @safe pure nothrow
=> this.str;
ulong opDollar()
=> this.length;
T opCast(T : string)() const
=> this.str;
auto opAssign(T)(T value) if (isSomeString!T)
{
this.str = value;
return this;
}
auto opBinary(string op : "~")(string rhs)
{
Symbol symbol = Symbol(this.str ~ rhs);
return symbol;
}
auto opOpAssign(string op = "~=", T)(T value) if
(isSomeString!T)
{
this.str ~= value;
return this;
}
}
alias NodeRef = NullableNodeRef;
alias RootRef = NodeRef;
alias TreeRef = Tree*;
enum Kind : string
{
_Undefined_ = "undefined",
Terminal = "terminal",
Leaf = "leaf",
Root = "root",
}
struct NullableNodeRef
{
private Node* _node;
alias node = _node;
@property bool isNull() const pure @safe nothrow =>
(this._node is null);
@property Node* get() pure @safe nothrow =>
this._node;
@property string getString(const string stringIfNull) const
=> this.isNull ? stringIfNull : this._node.repr();
this (Node node) nothrow
{
this._node = &node;
}
this (Node* nodeRef) nothrow
{
this._node = nodeRef;
}
auto opDispatch(string member)() const
=> mixin("this._node." ~ member);
auto opDispatch(string member)()
=> mixin("this._node." ~ member);
bool opEqual(Object other)
=> *this._node == other;
T opCast(T : Node*)() const
=> this._node;
static nodeRef(ref Node node)
=> NodeRef(node);
}
NullableNodeRef nullableRef(Node node) nothrow
=> NullableNodeRef(node);
NullableNodeRef nullableRef(Node* node) nothrow
=> NullableNodeRef(node);
interface Representable
{
string repr();
}
class Node : Representable
{
private:
int _precedence;
TreeRef _tree;
Kind _kind;
Symbol _symbol;
NodeRef _root;
NodeRef _left;
NodeRef _right;
public:
@property TreeRef tree() @safe pure nothrow =>
this._tree;
@property Symbol symbol() @safe pure nothrow =>
this._symbol;
@property int precedence() @safe pure nothrow =>
this._precedence;
@property NodeRef root() @safe pure nothrow =>
this._root;
@property NodeRef left() @safe pure nothrow =>
this._left;
@property NodeRef right() @safe pure nothrow =>
this._right;
@property Kind kind() @safe pure nothrow =>
this._kind;
@property bool terminates() const @safe pure nothrow =>
!this.isLeaf();
alias parent = root;
@property void root(NodeRef nodeRef) @safe
{
if (!this._root.isNull)
throw new Error("Root node already exists");
this._root = nodeRef;
}
@property void left(NodeRef nodeRef) @safe
{
if (!this._left.isNull)
throw new Error("Left node already exists");
this._left = nodeRef;
}
@property void right(NodeRef nodeRef) @safe
{
if (!this._right.isNull)
throw new Error("Right node already exists");
this._right = nodeRef;
}
this(
TreeRef tree,
Symbol symbol,
int precedence,
NodeRef root,
NodeRef left = NodeRef.init,
NodeRef right = NodeRef.init
)
{
this._tree = tree;
this._symbol = symbol;
this._precedence = precedence;
this._root = root;
this._left = left;
this._right = right;
_setKind();
}
this(TreeRef tree, Symbol symbol, int precedence, NodeRef
root)
{
this._tree = tree;
this._symbol = symbol;
this._precedence = precedence;
this._root = root;
_setKind();
}
this(TreeRef tree, Symbol symbol, int precedence)
{
this._tree = tree;
this._symbol = symbol;
this._precedence = precedence;
_setKind();
}
bool isLeaf() const pure @safe nothrow => this.hasLeft() ||
this.hasRight();
bool isRoot() const pure @safe nothrow => this._root.isNull
&& this.isLeaf();
bool hasParent() const pure @safe nothrow =>
!this._root.isNull;
bool hasLeft() const pure @safe nothrow =>
!this._left.isNull;
bool hasRight() const pure @safe nothrow =>
!this._right.isNull;
alias hasRoot = hasParent;
string repr() const
{
string str = "";
str ~= "\"" ~ this._symbol.str ~ "\"";
str ~= "(";
str ~= "prec=" ~ to!string(this._precedence);
str ~= ", kind=" ~ this._kind;
str ~= ", root=" ~ this._root.getString("<no root>");
str ~= ", left=" ~ this._left.getString("<no left
leaf>");
str ~= ", right=" ~ this._right.getString("<no right
leaf>");
str ~= ")";
return str;
}
private void _setKind() @safe pure nothrow
{
if (this.root.isNull)
this._kind = Kind.Root;
else if (!this._left.isNull || !this._right.isNull)
this._kind = Kind.Leaf;
else
this._kind = Kind.Terminal;
}
//override string toString() const @safe pure nothrow
// => this.repr();
T opCast(T : string)() const
=> this._symbol.str;
T opCast(T : NodeRef)() const
=> nullableRef(this);
auto opBinary(string op : "~")(string rhs)
{
Node node = new Node(
this._tree,
this._symbol ~ rhs,
this._precedence,
this._root,
this._left,
this._right
);
return node;
}
auto opBinary(string op : "~")(Node rhs)
{
Node node = new Node(
this._tree,
this._symbol ~ rhs.symbol.str,
this._precedence,
this._root,
this._left,
this._right
);
return node;
}
auto opBinary(string op : "~")(NodeRef rhs)
{
Node node = new Node(
this._tree,
this._symbol ~ rhs.symbol.str,
this._precedence,
this._root,
this._left,
this._right
);
return NodeRef(node);
}
auto opBinary(string op : "~")(NodeRef rhs)
{
Node node = new Node(
this._tree,
this._symbol ~ rhs.symbol.str,
this._precedence,
this._root,
this._left,
this._right
);
return NodeRef(node);
}
override bool opEquals(Object other) const
{
if (is(other == Node))
return false;
const Node n = cast(Node) other;
return (n.repr() == this.repr());
}
bool opEquals(typeof(null) other) const
=> this._kind != Kind._Undefined_;
}
alias Root = Node;
final class Tree : Representable
{
private NodeRef _root;
private ulong _count;
private NodeRef _current;
@property NodeRef root() @safe pure nothrow => this._root;
@property ulong count() @safe pure nothrow => this._count;
@property void root(NodeRef nodeRef)
{
this._root = nodeRef;
}
void incrementCount(uint byAmountOf = 1)
{
this._count += byAmountOf;
}
this(Node* root)
{
this._root = NodeRef(root);
this._count = 0;
}
this()
{
this._root = NodeRef.init;
this._count = 0;
}
bool hasRoot() => !this._root.isNull;
string repr()
{
import std.stdio;
string tree = "";
Node* curr = this._root.get;
if (curr.isRoot)
return "";
while (!curr.terminates)
{
tree ~= curr.repr();
if (curr.hasLeft())
curr = curr.left.get;
else if (curr.hasRight())
curr = curr.right.get;
}
if (tree == "" || tree == "\n")
return "";
return tree.strip("\n");
}
alias toString = repr;
}
unittest // ???
{
import std.stdio;
Tree tree = new Tree();
TreeRef treeRef = &tree;
Node op = new Node(treeRef, Symbol("+"), 0);
// That's fine, the root is displayed
Node one = new Node(treeRef, Symbol("1"), 0, nullableRef(op));
Node two = new Node(treeRef, Symbol("2"), 0, nullableRef(op));
//(1) Execution ends
op.left = nullableRef(&one);
op.right = nullableRef(&two);
//(2) Execution ends after this, if it is at (1) position
writeln(two.repr());
writeln(one.repr());
writeln(op.repr());
if (!treeRef.hasRoot())
treeRef.root = nullableRef(&op);
//writeln(*treeRef);
writeln(tree.root.get.hasRight());
}
int main(string[] _)
{
return 0;
}
```
More information about the Digitalmars-d-learn
mailing list