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?

Reply via email to