s390guy / SATK

Toolkit for creating baremetal programs targeting mainframe compatible systems
GNU General Public License v3.0
40 stars 6 forks source link

Unwanted multiple blank removal in macro generated assembler statements #35

Open Fish-Git opened 1 year ago

Fish-Git commented 1 year ago

How can I align my macro generated assembler statements exactly the way I code them in ASMA?

Here's a simple repro test case that illustrates the problem:

                MACRO
                NODOTS
SIE_V           DS   X            Intervention requests
SIE_V_WAIT      EQU  X'10'          Wait/Run bit
SIE_V_EXTCALL   EQU  X'08'          External call pending
SIE_V_STOP      EQU  X'04'          SIE Stop control
SIE_V_IO        EQU  X'02'          I/O Interrupt pending
SIE_V_EXT       EQU  X'01'          EXT Interrupt pending
                MEND
*
                MACRO
                DOTS
SIE_V.          DS   X            Intervention requests
SIE_V_WAIT.     EQU  X'10'          Wait/Run bit
SIE_V_EXTCALL.  EQU  X'08'          External call pending
SIE_V_STOP.     EQU  X'04'          SIE Stop control
SIE_V_IO.       EQU  X'02'          I/O Interrupt pending
SIE_V_EXT.      EQU  X'01'          EXT Interrupt pending
                MEND
                EJECT
                NODOTS
                EJECT
                DOTS
                END

Which produces:

ASMA Ver. 0.2.1                                                                                     30 Apr 2023 18:15:51  Page     2

  LOC        OBJECT CODE       ADDR1     ADDR2    STMT

                                                    21                 NODOTS
00000000  00                                        22+SIE_V    DS    X                  Intervention requests
                              00000010  00000001    23+SIE_V_WAIT EQU X'10'                Wait/Run bit
                              00000008  00000001    24+SIE_V_EXTCALL EQU X'08'             External call pending
                              00000004  00000001    25+SIE_V_STOP EQU X'04'                SIE Stop control
                              00000002  00000001    26+SIE_V_IO EQU   X'02'                I/O Interrupt pending
                              00000001  00000001    27+SIE_V_EXT EQU  X'01'                EXT Interrupt pending
ASMA Ver. 0.2.1                                                                                     30 Apr 2023 18:15:51  Page     3

  LOC        OBJECT CODE       ADDR1     ADDR2    STMT

                                                    29                 DOTS
00000001  00                                        30+SIE_V.   DS    X                  Intervention requests
                              00000010  00000001    31+SIE_V_WAIT. EQU X'10'               Wait/Run bit
                              00000008  00000001    32+SIE_V_EXTCALL. EQU X'08'            External call pending
                              00000004  00000001    33+SIE_V_STOP. EQU X'04'               SIE Stop control
                              00000002  00000001    34+SIE_V_IO. EQU  X'02'                I/O Interrupt pending
                              00000001  00000001    35+SIE_V_EXT. EQU X'01'                EXT Interrupt pending
                                                    36                 END

  As you can see, it appears ASMA's macro handling is reducing multiple blanks down to a single blank when it generates (outputs) a non-macro assembler statement, which screws up my desired statement alignment.

Is there some magical ASMA option or syntax that I am unaware of that will do what I want to do? I checked the manual but could not find anything anywhere covering this topic/situation.

Thanks.

s390guy commented 1 year ago

You can't. You can with symbols that are eight or less but not with symbols of greater length, no. When macro model statements are generated, ASMA aims for the operation field to start in column 10 and operands in columns 16. If you end up using more than that, the generated statement simply inserts a blank between the parsed fields (which looks like gobbling spaces to you) so that the assembler can parse the separate fields.

ASMA focuses on field preservation during macro model statement generation, not input column preservation.

I am labeling this issue as an enhancement. Will need to look into the code to determine the details.

Macros are converted to an internal representation that result in a sequence of Python objects that are "executed" when the macro is expanded. The actual input statement is long gone by the time the model statement is generated.

Fish-Git commented 1 year ago

You can't. You can with symbols that are eight or less but not with symbols of greater length, no. When macro model statements are generated, ASMA aims for the operation field to start in column 10 and operands in columns 16. If you end up using more than that, the generated statement simply inserts a blank between the parsed fields (which looks like gobbling spaces to you) ...

Confirmed!

                MACRO
                LIM8TST
L               EQU  1            Symbol length 1
LL              EQU  2            Symbol length 2
LLL             EQU  3            Symbol length 3
LLLL            EQU  4            Symbol length 4
LLLLL           EQU  5            Symbol length 5
LLLLLL          EQU  6            Symbol length 6
LLLLLLL         EQU  7            Symbol length 7
LLLLLLLL        EQU  8            Symbol length 8
LLLLLLLLL       EQU  9            Symbol length 9
LLLLLLLLLL      EQU  10           Symbol length 10
LLLLLLLLLLL     EQU  11           Symbol length 11
LLLLLLLLLLLL    EQU  12           Symbol length 12
LLLLLLLLLLLLL   EQU  13           Symbol length 13
LLLLLLLLLLLLLL  EQU  14           Symbol length 14
LLLLLLLLLLLLLLL EQU  15           Symbol length 15
                MEND
                EJECT
                LIM8TST
                END

Results in:

ASMA Ver. 0.2.1                                                                                     01 May 2023 13:31:21  Page     2

  LOC        OBJECT CODE       ADDR1     ADDR2    STMT

                                                    20                 LIM8TST
                              00000001  00000001    21+L        EQU   1                  Symbol length 1
                              00000002  00000001    22+LL       EQU   2                  Symbol length 2
                              00000003  00000001    23+LLL      EQU   3                  Symbol length 3
                              00000004  00000001    24+LLLL     EQU   4                  Symbol length 4
                              00000005  00000001    25+LLLLL    EQU   5                  Symbol length 5
                              00000006  00000001    26+LLLLLL   EQU   6                  Symbol length 6
                              00000007  00000001    27+LLLLLLL  EQU   7                  Symbol length 7
                              00000008  00000001    28+LLLLLLLL EQU   8                  Symbol length 8
                              00000009  00000001    29+LLLLLLLLL EQU  9                  Symbol length 9
                              0000000A  00000001    30+LLLLLLLLLL EQU 10                 Symbol length 10
                              0000000B  00000001    31+LLLLLLLLLLL EQU 11                Symbol length 11
                              0000000C  00000001    32+LLLLLLLLLLLL EQU 12               Symbol length 12
                              0000000D  00000001    33+LLLLLLLLLLLLL EQU 13              Symbol length 13
                              0000000E  00000001    34+LLLLLLLLLLLLLL EQU 14             Symbol length 14
                              0000000F  00000001    35+LLLLLLLLLLLLLLL EQU 15            Symbol length 15
                                                    36                 END

  Notice that, for every statement, even though the operation field for each statement starts in column 17 and the operands field starts in column 22, the resulting ASMA generated statement always has the operation field in column 10 and the operands field in column 16 (instead of leaving them exactly where they originally were).

What's even more interesting is that the column the comment field begins in IS preserved! The comment for each statement always starts in column 35, and for each ASMA macro generated statement, the comment field starts in ......... column 35!

Which is totally unexpected!

If one field (the comment field) can have its starting column preserved, why can't the other fields (operation and operands fields) have their starting column preserved as well?

It doesn't make any sense to me!

... so that the assembler can parse the separate fields.

Then, respectfully, your parsing logic sucks.   ;-)

ASMA focuses on field preservation during macro model statement generation, not input column preservation.

Input field preservation has nothing to do with input column preservation. The two are completely different things. One preserves a field's value, whereas the other preserves a field's column.

Will need to look into the code to determine the details.

Here's a quick temporary fix: if the statement doesn't contain any '&' substitution variables in it, output an exact copy of the original statement as-is.

The proper fix of course would be to save (remember) the starting column of both the operations and operands fields, and, when generating (constructing) the output statement, append the appropriate number of blanks to reach the saved target (original) column.

Personally I can't see how doing that would be too terribly difficult to do either. (It sounds to me like you have the operation and operands field columns hard coded at 10 and 16, which, IMHO, they shouldn't be. They should be variable.)

Anyway... Good luck with fixing this bug, ... er, ... I mean, with "implementing this enhancement".   >;-)

Anything you can manage to do would of course be greatly appreciated.

Thanks Harold.


p.s. I'm trying to develop a set of macros and code to support running stand alone tests in SIE mode, which means I need to be able to define a DSECT for the SIE State Block, and I'm using Hercules's existing SIE1BK and SIE2BK structs, which is why the field names are longer than 8 characters. I really don't want to have to define a whole new set of field names! That would be a PITA!

Fish-Git commented 1 year ago

For what it's worth, IBM's DOS/VS and z/VM assemblers work as expected:

I didn't bother testing MVS's or z/OS's, etc, but I suspect they behave the same way with respect to field column preservation.

Now before you say it, I know ASMA was never meant to be an IBM assembler clone or behave the same as any other assembler. It's allowed to behave in its own way.

But I suspect most mainframe assembler programmers expect the simple/basic things (such as field column preservation) to behave the same as what they're used to.

Other things, sure. They can be unique to ASMA. But something as simple/basic as statement alignment? Sheesh!   :)

Feel free to swear and cuss at me. I know I'm being a bastard about this and deserve it (and I apologize for that). But readability is important to me (and I would like to think for other programmers as well). Sloppy hard to read programs breed hard to find bugs. Easy to read programs much less so.

s390guy commented 1 year ago

Your points are worth considering and I do agree this should be looked at. Almost NOTHING in ASMA is as simple as you think it is. I will do that when I can. But, ASMA is operating as designed, perhaps not how you would design it, so I look at this as a cosmetic enhancement. Feel free to swear or cuss at me back. LOL.

Note the comment will actually move as well provided the model statement operands when expanded force it to do so. Your case simply did not force that situation.

It is not clear why you are using a macro. A COPY operation might work just as well and the issue you are experiencing with generated macro model statements goes away. COPY will preserve your readability and allow the structure to be reused in other programs. Just a thought.

s390guy commented 1 year ago

Your suggestion related to the & character is also worth looking at. Testing a statement for an & is trivial in Python. Recognizing that no symbol variable substitution is happening could save a ton of processing during macro generation. That too is worth a look. Again, a performance enhancement as far as I am concerned.

Fish-Git commented 1 year ago

Note the comment will actually move as well provided the model statement operands when expanded force it to do so.

Which is exactly my point! You obviously already have logic that preserves the column where the COMMENT FIELD starts (as well as logic to move it further to the right if/when needed). That exact same logic (handling) should be applied to the operation and operands fields as well (and not just to the comment field only).

How hard can that be? The infrastructure obviously already exists to preserve the starting column for the comment field (i.e. you must be passing the comment field's starting column number down to the rest of your code to reach the logic that eventually outputs the generated statement), so how hard can it be to add 2 new values/variables (operations field start column and operands field start column) and invoke the same logic for those two fields as as you're already doing for the comment field?!

I understand "Almost NOTHING in ASMA is as simple as you think it is." I get that. But it certainly SEEMS it should be fairly trivial to do given that you're already doing it for one field! (the comment field!) How hard can it be to do the same thing for the other two fields?!

Or am I missing something?

It is not clear why you are using a macro. A COPY operation might work just as well and the issue you are experiencing with generated macro model statements goes away. COPY will preserve your readability and allow the structure to be reused in other programs. Just a thought.

Not a half bad idea! I'm so used to using macros (and so rarely use COPY) that I failed to consider that as a viable temporary workaround! Thanks!

I still would prefer to use a macro however, since I'm likely(?) going to be needing to use macros to generate other SIE handling code besides just SIE State Block DSECT generation.

Anyway, I guess we can leave this as a low priority Enhancement request, given that this is a special case situation. In 99%+ of most all other situations, field names are always only 8 characters or less. This situation is unlikely to occur in 99%+ of most normal situations, so looking into it whenever you get the time is fine. No rush. It's just in my nature to want things fixed right away. Little shit like this just bugs the hell out of me. It gets in the way and distracts you from the bigger, more important shit, you know? I mean, just look at the listing I provided in my original problem report! Now imagine several pages of that! Not exactly easy to read, is it?!

Anyway.... Do whenever you get around to it. No rush. As always, THANK YOU for providing us with such a great product. You know I'm your biggest fan, right?   :)