[m-dev.] add goal path at external ports

Peter Schachte schachte at cs.mu.OZ.AU
Fri Jan 29 12:07:16 AEDT 1999


On Thu, Jan 28, 1999 at 09:40:46PM +1100, Fergus Henderson wrote:
> > Fergus Henderson writes:
> > > The compiler should generate line numbers in the debug info
> > > (specifically, in the MR_Stack_Layout_Entry_Struct).
> 
> For each event, it would give the current line number at the time of that
> event.  For call events, for example, that would be the line number
> of the called procedure.

I would argue that the current line number at the time of a call is
in the body of the *calling* procedure.  Certainly that's what a
source-linked debugger would want to show:  you want to decide what to
do at a call port when you're looking at the call, not when you're
already looking at the code of the predicate you're about to call!

Anyway, which line in the calling procedure would a call refer you to?
Given a call append([1,2], [3], X), would this show the line number of
the first clause for append or the head of the first matching clause
(the second clause, in this case)?  Probably the latter makes the most
sense, but I expect you mean the former.

> However, the stack tracing code gives you the ability to find
> out the MR_Stack_Layout_Entry_Struct for each of your ancestors.
> That would give you the line number for the caller.

Ok, as long as you can *always* get the right caller.  But what about
funny cases, like invocations of user-defined unification or invoking
predicates through a type class.  How about invoking user-defined
unification polymorphically (e.g. calling append(in,in,in) on three
lists of sets-represented-as-lists-with-user-defined-unification)?

Also, this might be a good time to remind you that just a line number
isn't really good enough.  People *do* sometimes put more than one
goal on a line.  Ultimately, you're going to want a column number as
well.  In fact, even that isn't really good enough for source linking.
Given a goal like

	p(f(X) + g(X), f(X) - g(X))

(where f/1, g/1, +/1 and -/1 are functions) when the call position is
on the first f, you don't know whether you're calling the f or the +.
A better solution is to have a "front" and "back" position for each
goal or function call, allowing you to highlight precisely the thing
being executed.  This would also be good for error reporting.

If you're concerned about wasting too much space by having column
numbers everywhere, it's pretty easy to just keep a character position
(byte offset from the beginning of the file).  If you must have line
and column numbers, you can keep an array of the character positions
of the line breaks in each file, and do a binary search of this array
for each character position.  If you're really concerned about space,
you could pack both front and back positions into a single 32 bit int
by allocating, say, 20 bits to the front position and 12 bits to
back-front (if you're willing to limit source files to 1 meg and
individual goals to 4K).  This would almost always be enough.


-- 
Peter Schachte                     Life is what happens to you when you're
mailto:schachte at cs.mu.OZ.AU        busy making other plans.
http://www.cs.mu.oz.au/~schachte/      -- John Lennon 
PGP: finger schachte at 128.250.37.3  



More information about the developers mailing list