I think it's time for me to carefully step through the various editing options that I have created. My system has not been carefully thought through, and the flaws are starting to show up.
This is the simplest of the issues. There's only one way to select a term: click on it and it highlights. In this sense, all terms are the same. They're just operators that do something with the stack. Whether it's an operator or a variable or an intermediate variable, it's the same thing in terms of selection.
This is also quite simple. If you choose to delete a selected item, it and all its arguements are deleted. In its place we put an unspecified token.
This also should be fairly simple, but there is a kicker. If you are in replacement mode, and you select a new operator, there is a bit of confusion if the new operator's arguement list is a mismatch for the original operator's arguement list. What should happen is that the original arguement is wiped out and a new arguement list with unspecified terms is entered in its place. I think, however, that if the number of terms match, I preserve the old arguement list. This is probably a bad idea; what if there's a type mismatch? Perhaps preservation of the old arguement list should happen only when there is also exact type matching. What a headache!
This is a misnomer. It really means "use the selected operator as the first arguement inside the newly chosen operator". I might also call it "Insidify".
This is what we need intermediate variables for. If you select an operator and choose a subsituting intermediate variable, then the substitution should apply to the operator and all its arguements. In terms of the token string, the code should remove the operator and its arguements from the string, replace them with the single token "Push x#", and then insert a string beforehand that includes all the deleted tokens followed by the token "Pop x#". The end result is to add two tokens to the length of the string.
Should I dispense with the replacement mode? It's a mode, for crying out loud. All necessary editing could be carried out with insertion and deletion. The problem comes when you have a big expression and you want to alter something upstream. It sure is a pain losing all the downstream arguements. For example, suppose you have some large expression of Affection[many operators, many more operators], and you wish to replace Affection with Dominance without altering all those big messy arguements. Surely there's got to a better way than starting all over.
My temptation is to eliminate the replacement mode and then make it easier to use a substitution variable. If you want to replace some big hairy expression, cut it down to size first with some substitution variables, then make the kill. Hmm, I don't know.
I wonder if it would be better to use an array of registers rather than x, y, z etc? That would be cleaner to think about, but I think the code would look like hell.
Should the scope of a subsitution variable be nothing more than the next regular pop?
Why not three types of substitution variables: pop-scope, consequence-scope, and role-scope? This would have the advantage that, if you inserted a consequence-scope variable into a weighting equation, the program could be smart enough to look backwards and see if that variable were already defined. If so, it could make the insertion with no further hassles, but if it weren't defined, then it would insert a definition equation. The rule here has to be, there is only one definition of a variable at each level of scope, so that all the definitions must precede the other equations. Hmm, this could be useful. But those different levels of scope could become very confusing. How to differentiate them? Different names? x versus xx versus xxx? Or how about x versus X versus _? Or perhaps we could use colors in this place instead of for data typing. Hmm...