Open LdBeth opened 9 months ago
With minor modification this works with TECO-64
< D .-Z; 0A "D | 1; ' >
Apparently the traditional TECO treats control flow commands as anchor points to go to, where TECO-64 works differently.
"Traditional" TECO treats control flow commands like gotos, just that the jump address/label is determined by some primitive string scanning, relying on no other state. That's why code like this is "safe". In SciTECO, where I have a bit more modern approach to flow control constructs - it does actually drive the parser when looking for its "jump points" and tries to hash them - the construct you quoted will work, but in the exit-case leave the loop open.
Although there must have been some state (stack?) to support nested n<...> constructs. So this might not be entirely clean code, even on "classic" TECOs.
Although there must have been some state (stack?) to support nested n<...> constructs. So this might not be entirely clean code, even on "classic" TECOs.
What I imaging could be used to handle counted loop is allocate an integer cell for each n<
in the macro, and do not worry about free the array until macro execution for the level is completed, because the storage won't grow as program runs. when ever the flow of execution encounters n<
, search the corresponding cell and set the number to n
, and whenever encounters >
search cell for matching <
, and either exits when the counter is 0 or decrement the count and go to the position after n<
.
As I suspected, both TECO for Ultrix and TECOC also use a loop stack internally to keep track of open loops. When repeating a loop they therefore also do not need to scan for <
but perform an immediate jump. And there is hardly any other way you could implement it.
This means that the construct @LdBeth cited should not be considered a canonical way to exit a loop. Because in fact it does NOT exit it. Instead you are practically leaking memory. Also, if you had loops enclosing this construct, you would find that the next >
jumps back into the loop, you supposedly already closed. This is all not relevant for squ.tes.
Instead you are practically leaking memory. Also, if you had loops enclosing this construct, you would find that the next > jumps back into the loop, you supposedly already closed.
If the implementation keeps track of matched open <
and closing >
when restart a loop from >
, this should not be a problem. ITS TECO even has ;
working by tracks <
and >
in the label, find the first unpaired '>' after it, so that !<!>
insides command loop jumps to beginning of the loop, while the !<!
is used to help ;
correctly identifies end of loop, because it took F<
for a totally different meaning.
If the implementation keeps track of matched open
<
and closing>
when restart a loop from>
, this should not be a problem
But they don't. TECO-interpreters do not build syntax trees. And if they did, constructs like the ones used in squ.tes wouldn't be allowed. Because it would be similar to (pseudocode):
while (...) {
...
if is_digit() then }
TECO is not a "typical" language. The code used in your example should still execute in TECO-64 probably, but you should be aware what you are doing.
I think what you mean by your ITS remarks is the same behavior that all TECO interpreters have - except for SciTECO. Some flow control commands will just do a string scan to find their jump destination, requiring you to sometimes add !<!
so that a following >
is ignored by the primitive scanning algorithms (it sees balanced braces). Didn't know they even relied on this idiom to replace F<
!
But they don't. TECO-interpreters do not build syntax trees. And if they did, constructs like the ones used in squ.tes wouldn't be allowed. Because it would be similar to (pseudocode):
Right, that's what I'm wondering is there any special implementation tricks used in the "standard" TECO can get interleaved loop working without get signaled error. It certainly makes sense for languages like HP SystemRPL which can directly manipulates control stream to implement control structures like loops and conditionals.
Although it looks to me the squ macro from TECOC is also copied from somewhere else...
While using interleaved loop construct can be controversial, what now more bothers me is
test1 "E
test2 "E
test3 "E
(test1 && test2 %% test3)
'
or
^AEcho^A | ^Aignored^A '
which should be considered as valid according to what's in the TECO manual (and does not raise error in TECO C) gives parse error.
And some notes related to F|
and F'
: they are quite useless if cannot be used inside command loop
0 "E < 1; F| > | @^A/else/ ' ! print nothing, no error reported !
0 "E < -1; F| > | @^A/else/ ' ! print "else", teco-64 reports ?BNI !
That basically renders F|
and F'
incapable for computed jumps, because they cannot escape multiple layers of conditions.
This might be more of a feature request than bug report.
A interesting phrase I found in
squ.tes
has interleaved loop and conditional constructsand the effect is delete digits from current point until there is no more. (although the
?UTC
would be thrown at run time if noun digit is encountered in TECOC)Apparently the traditional TECO treats control flow commands as anchor points to go to, where TECO-64 works differently.
Consulting the Standard TECO user guide, I was wondering the lack of unconditional exit from loop construct, and if interleave loop with conditional is allow then I would not be surprised the "intentional" omitting of such construct.