imports and a data structure (any critique welcome)
Jonathan
jdgall84 at gmail.com
Thu Dec 26 16:40:54 PST 2013
I come from Haskell, so please excuse any functional programming
idiosyncracies I have :)
In Haskell, I have a datatype for representing so called terms
which looks like:
data Term = Var Char | Op Char [Term]
i.e. a Term is a variable (denoted by an Int) or an operation
(whose name is also denoted by an int), applied to a list of its
arguments. For example,
f(g(x,y),a(),x) is represented by Op 'f' [Op 'g' [Var 'x',Var
'y'],Op 'a' [], Var 'x]
Now, the reason I am writing in D is twofold. First, I want to
learn the D language, and second I really need pointers to reduce
certain complexities in the operations (Haskell does not have
observable sharing).
Okay, so the first thing I need to do is represent this as a data
structure in D. My choices are to represent the structure as a
class or as a struct. I choose struct because it is simpler (in
terms of what is going on), and because the entire program takes
one struct and makes changes to it.
Here is my first attempt at the datastructure.
struct Term {
enum NodeType
{
Var, Op
}
NodeType node;
union TermBody
{
int VarName;
struct OpSymbol
{
int ConsName;
Term*[] Subterms;
}
OpSymbol terms;
}
TermBody term;
this(int nodeValue)
{
node = NodeType.Var;
term.VarName = nodeValue;
}
this(int OpSymb,Term*[] otherTerms)
{
node = NodeType.Op;
term.terms.ConsName = OpSymb;
term.terms.Subterms = otherTerms;
}
}
I strongly encourage you guys to try to destroy my datastructure
and critique anything and everything about it!!
But for now I will move on. As a sanity check, I want to make
sure I can print this datastructure out.
string termToString(Term* term)
{
if ((*term).node == Term.NodeType.Var)
{
return [convertNum((*term).term.VarName)];
}
else
{
string retString =
[convertNum((*term).term.terms.ConsName),'('];
retString ~= termToString((*term).term.terms.Subterms[0]);
for(size_t i = 1; i < (*term).term.terms.Subterms.length;i++)
{
retString ~= ',';
retString ~= termToString((*term).term.terms.Subterms[i]);
}
retString ~= ')';
return retString;
}
}
For now, convertNum is rather silly,
char convertNum(int x){
switch(x)
{
case 1: return 'x';
case 2: return 'y';
case 3: return 'z';
case 4: return 'f';
case 5: return 'g';
case 6: return 'h';
default: return 'e';
}
}
Okay, here is some code to produce a simple example of a
datastructure:
Term makeExTerm(){
Term var1 = Term(1);//x
Term var2 = Term(2);//y
Term var3 = Term(3);//z
Term fxx = Term(4, [&var1,&var1]);//f(x,x)
Term gfxxy = Term(5, [&fxx,&var2]);//g(f(x,x),y)
Term hzg = Term(6, [&gfxxy,&gfxxy]);//h(g(f(x,x),y),g(f(x,x),y))
return hzg;
}
Using the above, I wrote a test program,
void main(string[] args)
{
Term exTerm = makeExTerm();
string printable = termToString(&exTerm);
writeln(printable);
Term var = Term(219);
(*exTerm.term.terms.Subterms[0]).term.terms.Subterms[0] = &var;
// it is now (and should be) h(g(e,y),g(e,y))
string printable2 = termToString(&exTerm);
writeln(printable2);
}
If I put this in a file, compile it (with ldc or gdc), and run
it, everything works just superbly.
However, if I extract everything except main to a different file
and import that file, compilation passes, but running gives a
segmentation fault. I ran the program in a debugger, and the
first line of main passes no problem, we are able to construct
the term. I checked the memory, and everything seems to work
just fine. However, when I step into the second line of main,
the call to termToString, I get the segfault.
Can anyone tell me what is going on?
More information about the Digitalmars-d-learn
mailing list