The original intent of the code, when faced with something like
.MACRO A
.MACRO B
.ENDM A
is to terminate the outer macro definition immediately.
However some macros redefine themselves, and that broke.
For now, detect self-redefinition and disable the early
end if there is one.
Since this does not match what's described on page 7-3,
this will change if it doesn't break my test cases.
The code for nested and unnested strings was mixed, thereby being too
simple for the nested case. I separated them, which is simpler than
the fixed combined version.
Detected by the macro call
..EMIT <$FAC=^D<fb$rea>>
Also, to make Kermit sources work, only increase the local symbol block
counter if there actually was a local symbol used in the block.
This way, conditional inclusions (which include source text only in the
first pass) will have less potential for de-synchronisation between the
passes. After all, if the generated internal local symbol names do
not match, phase errors will result (showing themselves as strange label
redefinition problems).
Local symbols like 32768$ (and such long ones can be generated
automatically by macros) are suffixed with the "local symbol block number"
to make different labels in different local symbol blocks:
32768$12345.
However, this becomes longer than the regular symbol length (6).
So, to avoid changing these labels, they are not truncated at this length.
The listing code is updated to deal with the longest symbol name lengt
it encounters in the symbol table.
Normally listing is suppressed during the first pass, because there are
many unresolved symbols, which will be better in pass 2.
Errors are also suppressed because most of them are spurious.
With the -yl1 option, listing during pass 1 is not suppressed.
If you give the option twice, you also get the error messages.
at least the one of RSX M+ 4.6.
Inconsistent flags given to .PSECT seem to be simply combined, with
nothing special done after pass 1 when re-reading for 2. The situation
at the end of pass 2 wins.
Given the following conditional inclusion, as seen in RSX Kermit-11
sources:
.if ndf, K11INC
.ift
.include /IN:K11MAC.MAC/
.include /IN:K11DEF.MAC/
.endc
macros defined in K11MAC.MAC are unknown when used later on.
The assembler keeps a running count of the line number (stmtno) and
stores it in the macro definition. In the second pass, it tries to avoid
cases of use-before-defined, because it doesn't really forget the
macros.
However, in this case, the second pass has fewer lines, because there
was some conditional inclusion... so when the macro is used in the
second pass, its running line number (including the skipped inclusions)
is lower than the line number where the macro was defined...
The line number check would also interfere when the /PASS:1 and /PASS:2
input file modifiers would be implemented.
It seems to me that in most normal cases, a use-before-defined is
already detected in the first pass, so the check is not really needed.
Therefore I have simply removed it.
evaluate() would not-quite-copy the original tree, which often would
get freed afterward. Including the shared parts.
Also fixed the case where evaluate() would turn a EX_NEG node into an
EX_COM node.