Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Things that might puzzle you (Part 2)

2 views
Skip to first unread message

Steve Swift

unread,
Mar 9, 2007, 3:56:20 AM3/9/07
to
Here is the second thing in REXX which caused me to waste a day or so
looking in the wrong place:

I had a routine, lets call it "a" and it calls an external subroutine,
lets call it "b".

Routine "a" handles syntax errors, putting out messages such as:

Syntax error at line 23 of c:\temp\test.rex
Arithmetic overflow/underflow
23 *-* Say a/b

Routine "b" doesn't handle syntax errors. Your programming is perfect
and you can see there are no errors (hubris - my speciality).

Suddenly, program "a" produces this:
Syntax error at line 41 of C:\temp\test.rex
Logical value not 0 or 1
41 *-* Call b myname

Que? Where's the logical value in that statement? Might it be something
to do with the variable "Myname"? But that contains "Fish-face". :-)

I spent well over a day working out what was going on here.

The actual syntax error had happened in program "b". That wasn't
trapping syntax errors, so "a"s Syntax handler took the call. It
reported the truthful problem (logical value not 0 or 1) but reported
against its own line of code, the completely innocent call to "b".

Moral of this story: Once you start handling syntax errors (and others,
of course) then it's probably worth doing so even in code that looks
perfect. Don't forget, there's no line of code that can't cause an "out
of memory" condition, and raise syntax. (Well, there probably is, but no
line of code that does anything useful).

--
Steve Swift
http://www.swiftys.org.uk
http://www.ringers.org.uk

Ian Collier

unread,
Mar 9, 2007, 7:07:49 AM3/9/07
to
Probably Steve Swift typed into a real computer:

>The actual syntax error had happened in program "b". That wasn't
>trapping syntax errors, so "a"s Syntax handler took the call. It
>reported the truthful problem (logical value not 0 or 1) but reported
>against its own line of code, the completely innocent call to "b".

This is a thorny issue which I think has been discussed before and I
don't think there's a definite "correct" behaviour which means that
different interpreters may behave differently (I'd be interested to
know what happens on CMS REXX).

I don't think the above behaviour (which is displayed by ooRexx at
least) is the best possible behaviour. I think that external routines
should not inherit the SIGNAL ON setting*, so if there's a syntax error
in it then it should fail and produce a traceback.

TRL doesn't make clear what happens next, but the ANSI standard says
that if the external routine failed for some reason then syntax 40.1
(External routine "<name>" failed) should be raised. This error
would then be trapped by your SIGNAL ON, and you'd at least get a
more understandable error message to go with the value of SIGL that
points to the call to "b".

Object Rexx makes this more complicated by considering each method and
::routine as a little program in itself, meaning that you can't share a
syntax handler across a whole program. To be technically correct, then,
you'd have to put a separate syntax handler inside every method. So I
guess the inheritance of SIGNAL ON was done to mitigate this problem.
On the other hand, it could still be made better; if they are going to
change SIGL to point to the line containing the call then they should
also change RC to indicate an "external routine / method failed"
error.
--
* External routines are separate programs, more or less; TRL says
"the state of internal values starts with their defaults" whereas
the ANSI standard hands the job off to an implementation-defined
"Config_ExternalRoutine" which, one must assume, doesn't have any
access to the current internal state of the interpreter and must
start another instance of it to run your routine).
--
---- Ian Collier : i...@comlab.ox.ac.uk : WWW page (including REXX section):
------ http://users.comlab.ox.ac.uk/ian.collier/imc.shtml

New to this group? Answers to frequently-asked questions can be had from
http://www.rexxla.org/faq.html .

Rick McGuire

unread,
Mar 9, 2007, 7:31:20 AM3/9/07
to

There's no inheritance of SIGNAL ON taking place, what's actually
happening is the full error condition information (and stack trace, btw)
is the error that gets raised and trapped by the callers SIGNAL ON
SYNTAX. From the standpoint of the signal handler, the error occurs at
the location of the call, since that was the instruction within the
local context that was executing at the time the error occurred. That
is, the SIGNAL took place at the call instruction, the SIGL variable
points to that instruction. The error condition is the one raised by
the called routine. This behavior is essentially the same as you'd get
for internal routines if the called routine issues a SIGNAL OFF SYNTAX:


signal on syntax
call fred
exit

syntax:
say "Error" rc "occurred on line" sigl -- reports error 42 on line 3
exit

fred:
signal off syntax
say 1/0

The ooRexx behavior makes handling of errors in external routines closer
to that of internal routines. On CMS, a call to an external routine did
a complete recursive invocation of the interpreter via the CMS EXEC
command. There was no mechanism available to propagate the
error/traceback information across that boundary, so any call to an
external function that had an error just got reported as a generic call
failure.

In ooRexx, calls are handled within the same interpreter context, so the
full error information can be propagated back, including the original
error information and a full error traceback.

Rick

Ian Collier

unread,
Mar 9, 2007, 8:16:55 AM3/9/07
to
A short while ago I became aware that Rick McGuire had written:

>There's no inheritance of SIGNAL ON taking place, what's actually
>happening is the full error condition information (and stack trace, btw)
>is the error that gets raised and trapped by the callers SIGNAL ON
>SYNTAX.

Being trapped by the caller's SIGNAL ON is precisely what I mean by
inheritance. My opinion is that it shouldn't inherit, and therefore
the full error condition information and stack trace should not be
trapped by the caller's SIGNAL ON.

> From the standpoint of the signal handler, the error occurs at
>the location of the call, since that was the instruction within the
>local context that was executing at the time the error occurred. That
>is, the SIGNAL took place at the call instruction, the SIGL variable
>points to that instruction. The error condition is the one raised by
>the called routine.

But that's a mismatch of information; you're taking the SIGL from the
caller but the RC from the called routine, which leads to confusion.

> This behavior is essentially the same as you'd get
>for internal routines if the called routine issues a SIGNAL OFF SYNTAX:

[snip example]

It should not do that. If the called routine issues a SIGNAL OFF SYNTAX
then any syntax condition should stop the program with a traceback. I
believe the standard is clear on that point.

>In ooRexx, calls are handled within the same interpreter context, so the
>full error information can be propagated back, including the original
>error information and a full error traceback.

But I don't see a traceback when I run it, and the "original error
information" that's propagated back doesn't seem to include the line
number of the error.

Rick McGuire

unread,
Mar 9, 2007, 8:24:20 AM3/9/07
to
Ian Collier wrote:
> A short while ago I became aware that Rick McGuire had written:
>> There's no inheritance of SIGNAL ON taking place, what's actually
>> happening is the full error condition information (and stack trace, btw)
>> is the error that gets raised and trapped by the callers SIGNAL ON
>> SYNTAX.
>
> Being trapped by the caller's SIGNAL ON is precisely what I mean by
> inheritance. My opinion is that it shouldn't inherit, and therefore
> the full error condition information and stack trace should not be
> trapped by the caller's SIGNAL ON.
>
>> From the standpoint of the signal handler, the error occurs at
>> the location of the call, since that was the instruction within the
>> local context that was executing at the time the error occurred. That
>> is, the SIGNAL took place at the call instruction, the SIGL variable
>> points to that instruction. The error condition is the one raised by
>> the called routine.
>
> But that's a mismatch of information; you're taking the SIGL from the
> caller but the RC from the called routine, which leads to confusion.
>
>> This behavior is essentially the same as you'd get
>> for internal routines if the called routine issues a SIGNAL OFF SYNTAX:
> [snip example]
>
> It should not do that. If the called routine issues a SIGNAL OFF SYNTAX
> then any syntax condition should stop the program with a traceback. I
> believe the standard is clear on that point.

This is the same behavior that the CMS implementation exhibits for
internal routines. The caller's trap is still enabled, but it doesn't
get triggered until things unwind back to the caller's level. The
location the trap occurs at is the original call at the callers level.


>
>> In ooRexx, calls are handled within the same interpreter context, so the
>> full error information can be propagated back, including the original
>> error information and a full error traceback.
>
> But I don't see a traceback when I run it, and the "original error
> information" that's propagated back doesn't seem to include the line
> number of the error.

The traceback is available in the condition object that's retrieval in
the syntax trap.

Rick


Ian Collier

unread,
Mar 9, 2007, 10:58:29 AM3/9/07
to
Rick McGuire entertained comp.lang.rexx with the following story:

>Ian Collier wrote:
>> A short while ago I became aware that Rick McGuire had written:
>>> This behavior is essentially the same as you'd get
>>> for internal routines if the called routine issues a SIGNAL OFF SYNTAX:
>> [snip example]
>>
>> It should not do that. If the called routine issues a SIGNAL OFF SYNTAX
>> then any syntax condition should stop the program with a traceback. I
>> believe the standard is clear on that point.

>This is the same behavior that the CMS implementation exhibits for
>internal routines. The caller's trap is still enabled, but it doesn't
>get triggered until things unwind back to the caller's level. The
>location the trap occurs at is the original call at the callers level.

You surprise me. Did Mike write that bit? :-)

I'm not sure what the point is of using SIGNAL OFF within a subroutine
if it's still going to get trapped.* This also opens the question of
what happens if a second syntax condition gets triggered (given that
the first one is supposed to turn SIGNAL ON SYNTAX off, but there might
have been a previous caller with it turned on).
--
* OK there's a difference in the level of unwinding (but I always
thought it ought to have been designed to unwind anyway, if the
called subroutine didn't contain an explicit SIGNAL ON or SIGNAL
OFF instruction).

Rick McGuire

unread,
Mar 9, 2007, 11:15:02 AM3/9/07
to
Ian Collier wrote:
> Rick McGuire entertained comp.lang.rexx with the following story:
>> Ian Collier wrote:
>>> A short while ago I became aware that Rick McGuire had written:
>>>> This behavior is essentially the same as you'd get
>>>> for internal routines if the called routine issues a SIGNAL OFF SYNTAX:
>>> [snip example]
>>>
>>> It should not do that. If the called routine issues a SIGNAL OFF SYNTAX
>>> then any syntax condition should stop the program with a traceback. I
>>> believe the standard is clear on that point.
>
>> This is the same behavior that the CMS implementation exhibits for
>> internal routines. The caller's trap is still enabled, but it doesn't
>> get triggered until things unwind back to the caller's level. The
>> location the trap occurs at is the original call at the callers level.
>
> You surprise me. Did Mike write that bit? :-)

Yep, that's from Mike's original implementation.


>
> I'm not sure what the point is of using SIGNAL OFF within a subroutine
> if it's still going to get trapped.* This also opens the question of
> what happens if a second syntax condition gets triggered (given that
> the first one is supposed to turn SIGNAL ON SYNTAX off, but there might
> have been a previous caller with it turned on).

I'm not totally sure I understand the question. When a syntax trap is
taken, it is turned off in the current call context. If a subsequent
syntax error occurs, the current context is terminated, and when the
call stacks are unwound, the caller's SYNTAX trap will still be
effective. This is essentially the same situation as the original
question. The turning off of SYNTAX on the trap is to prevent infinite
syntax loops from occurring. That can't happen in the unwinding case
because each iteration will unwind at least one stack level, and
eventually you'll have an unhandled error.

Ian Collier

unread,
Mar 9, 2007, 5:49:46 PM3/9/07
to
According to Rick McGuire in a posting to comp.lang.rexx:

>I'm not totally sure I understand the question. When a syntax trap is
>taken, it is turned off in the current call context. If a subsequent
>syntax error occurs, the current context is terminated, and when the
>call stacks are unwound, the caller's SYNTAX trap will still be
>effective. This is essentially the same situation as the original
>question. The turning off of SYNTAX on the trap is to prevent infinite
>syntax loops from occurring. That can't happen in the unwinding case
>because each iteration will unwind at least one stack level, and
>eventually you'll have an unhandled error.

True, but it could be confusing. Consider this:

signal on syntax
call test 5
exit
test: procedure
parse arg n
say n 1/n
call test n-1
return
syntax: say "Syntax" rc "occurred at line" sigl
say errortext(rc)
say sourclnie(sigl)

(did you spot the errors? (-:).

In my interpretation of the ANSI standard, that trips the handler
once and then dies with a traceback. In ooRexx it trips it seven
times, despite there being only one "signal on" instruction in the
program!

Gerard Schildberger

unread,
Mar 9, 2007, 6:08:03 PM3/9/07
to
| Ian Collier wrote:

|> Rick McGuire wrote:
|>I'm not totally sure I understand the question. When a syntax trap is
|>taken, it is turned off in the current call context. If a subsequent
|>syntax error occurs, the current context is terminated, and when the
|>call stacks are unwound, the caller's SYNTAX trap will still be
|>effective. This is essentially the same situation as the original
|>question. The turning off of SYNTAX on the trap is to prevent infinite
|>syntax loops from occurring. That can't happen in the unwinding case
|>because each iteration will unwind at least one stack level, and
|>eventually you'll have an unhandled error.

| True, but it could be confusing. Consider this:
|
| signal on syntax
| call test 5
| exit
| test: procedure
| parse arg n
| say n 1/n
| call test n-1
| return
| syntax: say "Syntax" rc "occurred at line" sigl
| say errortext(rc)
| say sourclnie(sigl)
|
| (did you spot the errors? (-:).

Well, for one, you misspelled sourceline. __________Gerard S.

0 new messages