Date: Tue, 05 Nov 1996 00:16:19 GMT Server: NCSA/1.5 Content-type: text/html Last-modified: Thu, 12 Sep 1996 23:37:55 GMT Content-length: 6101 Glew on High-Level Editting

Glew on High-Level Editting

I have had a long-time interest in higher level editting operations, both for normal programming languages, and for hardware design - HDLs.

E.g. the MIT "Programmer's Apprentice".

This web page will serve as an achor for my own thoughts on the issue, particular for me to record scenarios to which this could apply.

Semantic Split

A common operation involves "spliting" a variable or parameter.

E.g. I need to edit GNU Emacs' dynamic abbreviations package to provide completion to end of line instead of to end of word. Unfortunately, the package presently has a single variable "AbbreviationRegexp" which is using in two different contexts: (1) to dtermine the symbol that you are looking at, and (2) to determine the expansion.

I need to split this regexp so that I can control these capabilities separately. Unfortunately, there is no way to do this without creating a complete copy of a call-tree of several dozen functions. And, of course, if I create this copy, then any changes to the original will not propagate to my copy, unless I succeed in subverting the original implementation, reimplement it in terms of the refined, split, semantics.

Recursive Parameter Application

I noticed this possible HLEO (High Level Editting Operation) while maintaining my "getnumber" package.

This package relies on recursion to provide a context-sensitive number parser that accepts most numeric formats. Each recognizer has only limited knowledge of syntax, but recurses through the top level recognizer to handle variants, thus obtaining modularity and easy extensibility.

Initially, the calling tree looked a bit like:

Dgetnumber
Dgetnumberlist
Numeric formats, like decimal
terminal - no further calls or recursion
Expression formats, like +
Recurses through Dgetnumber_Address
sets TopLevelRecognizer=Dgetnumber_Address when it calls Dgetnumberlist
Dgetnumber
sets TopLevelRecognizer=Dgetnumber when it calls Dgetnumberlist
Dgetnumberlist(with TopLevelRecognizer=Dgetnumber,...)
f(TopLevelRecognizer,...): Numeric formats, like decimal
terminal - no further calls or recursion
f(TopLevelRecognizer,...): Expression formats, like +
Recurses through TopLevelRecognizer, either Dgetnumber depending on usage, to handle the subcomponents of the expression, after the operator has been recognized.

Therefore, the high level editting operation is in this calling tree, take all instances of the explicitly named operation or value X, and make them refer to a parameter that is passed along all paths the calling tree. Similarly, the reverse operation may occasionally be useful. An interactive query framework would help.

Well, I just completed the above edit by hand. It took me more than six (6) hours!!!! It was complicated by the fact that a semantic split of a type needed to be done, and by incomplete type checking of function parameters in the C compiler I was using, but this emphasizes the point: something that was asa simple to describe as above took an excessively long time, because of the attention to detail that could be automated.

Hidden Recursive Parameters

A more specific example of this arose because I wanted to pass "hidden state" that is only useful to one of the lower functions in the calling tree. It is not appropriate to make this extra info an explicit parameter, because the information is only of interest to the upper level function that set it up, and the lower level function that receives it. None of the intervening levels of functions care about what is being passed.

I.e. we want to transparently communicate something between two different levels of the calling hierarchy, without affecting (or minimally affecting) the intermediate layers.

A typical naive solution is to do this with a global variable, but that is not MP safe.

Again, the "best" solution is to pass the hidden information as a parameter through all the intermediate levels. But, in addition to creating the parameter, we also need to create the data types that can hide what is being passed. Furthermore, because it is quite likely that there will need to be multiple, different, such instances of communication, it is desirable to create a generic "data hiding mechanism: or "call-tree message passing mechanism" that can handle several such messages transparently.

All functions in such a calling tree might have a generic parameter "CallingTreeMessageList", which would be a composite object, e.g. a list, of messages with source, destination addresses, etc.

The high level routine might do something like this

    call generic-call-tree placing message to specialized-subfunction-variety
while the receiver might do
    if I need extra info not in standard call parameters 
	    scan CallingTreeMessageList to see  if it is there

$Header: /u/g/l/glew/public/html/RCS/high-level-editting.html,v 1.2 1995/12/31 07:54:17 glew Exp $