boeckmann / asm6502

Small but useful 6502 assembler in ~3K lines of ANSI C code.
MIT License
5 stars 2 forks source link

Implement .if .. .else .. .endif #14

Closed boeckmann closed 1 year ago

boeckmann commented 1 year ago

This is implemented by e1ad8da5e4c2b8fafd000acae4313c8fb5f9a26c.

The condition in the if directive may NOT evaluate to an undefined value in pass 1. So the following will not work if PET is not defined.

.if PET
.endif

The following will work:

PET = 0
.if PET
.endif

Nested if statements are supported.

boeckmann commented 1 year ago

Further, labels may not preceed conditional statemens, because they are handled differently than normal statements.

boeckmann commented 1 year ago

The lines excluded by conditional assembly are marked with an exclamation mark in the listings instead of the colon after the line numbers:

3: .if C64
4:   .echo "Assembling for the Commodore 64"
5:   SCREEN_WIDTH = 40
6: .else
7!   .echo "Assembling for the Commodore PET series"
8!   SCREEN_WIDTH = 80
9: .endif
waltje commented 1 year ago

Yeah, I did these, too.  if/ifdef/ifndef, else and endif.

The .echo could indeed be useful, will add that as well.

Fred

On Monday, April 17, 2023 at 11:03:45 AM EDT, Bernd Böckmann @.***> wrote:

The lines excluded by conditional assembly are marked with an exclamation mark in the listings instead of the colon after the line numbers: 3: .if C64 4:   .echo "Assembling for the Commodore 64" 5:   SCREEN_WIDTH = 40 6: .else 7!   .echo "Assembling for the Commodore PET series" 8!   SCREEN_WIDTH = 80 9: .endif

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you are subscribed to this thread.Message ID: @.***>

waltje commented 1 year ago

In my implementation, I still have one problem:

  .ifndef FOO      FOO = 100   .endif

This works, of course, but: in the listing, it will show the "FOO =" line as excluded, because by the time we get to pass 2, the symbol (FOO) is defined... GAK!

--fred

On Monday, April 17, 2023 at 11:03:45 AM EDT, Bernd Böckmann @.***> wrote:

The lines excluded by conditional assembly are marked with an exclamation mark in the listings instead of the colon after the line numbers: 3: .if C64 4:   .echo "Assembling for the Commodore 64" 5:   SCREEN_WIDTH = 40 6: .else 7!   .echo "Assembling for the Commodore PET series" 8!   SCREEN_WIDTH = 80 9: .endif

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you are subscribed to this thread.Message ID: @.***>

waltje commented 1 year ago

Why?

This is what I do:


do_if(char **p, int pass) {     value_t v;

    / Get the value of the expression. /     skip_white(p);     v = eval(p);     if ((pass == 2) && UNDEFINED(v))

ifdef ALLOW_UNDEFINED_IF

        v.v = 0;

else

        error(ERR_UNDEF, NULL);

endif

    if (iflevel < MAX_IFLEVEL) {         ifstack[iflevel++] = ifstate;         newifstate = !!v.v;     } else         error(ERR_TOODEEP, NULL); }

So, I accept undefined variables, and will assume them to be 0.

Fred

On Monday, April 17, 2023 at 10:00:36 AM EDT, Bernd Böckmann @.***> wrote:

This is implemented by e1ad8da.

The condition in the if directive may NOT evaluate to an undefined value in pass 1. So the following will not work if PET is not defined. .if PET .endif

The following will work: PET = 0 .if PET .endif

Nested if statements are supported.

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you are subscribed to this thread.Message ID: @.***>

boeckmann commented 1 year ago

Puh, there are a few traps if you allow this. How do you prevent something like this:

.ifdef SIZE
.fill SIZE
.endif
SIZE = 100

Would lead to a phase mismatch between pass 1 and 2. Have you implemented some means to detect this?

boeckmann commented 1 year ago

In my implementation, I still have one problem: .ifndef FOO FOO = 100 .endif This works, of course, but: in the listing, it will show the "FOO =" line as excluded, because by the time we get to pass 2, the symbol (FOO) is defined... GAK!

Yes, if it gets defined via the conditional in the first pass your programm in fact behaves correctly if the listing is generated in pass 2. I don't know if its the right term, but this is what I would call a "phase mismatch". Have to think about it how this can be solved.

waltje commented 1 year ago

Correct.  Technically, its not a phase error, because the symbol itself does not change values and/or types, it simply goes from "undefined" in p1, to "defined" in p2.  But, yes, the result is a phase error as far as the listing (which is done in p2) is concerned :P

I have a temporary workaround, but it needs more thought- I save the pass number in the symbol to indicate when it was "unknown".  So, for the

  .ifndef FOO

case, if FOO is not known, it will be aquired in p1, and it will note that it was aquired in p1. If its (still) unknown in p2, we have an error.

The ifndef pseudo thus checks is the symbol is known. If not, good. If it is known, we check in what pass it was aquired- if p1, consider it an unknown.

Fred

On Monday, April 17, 2023 at 06:01:19 PM EDT, Bernd Böckmann @.***> wrote:

   In my implementation, I still have one problem: .ifndef FOO FOO = 100 .endif This works, of course, but: in the listing, it will show the "FOO =" line as excluded, because by the time we get to pass 2, the symbol (FOO) is defined... GAK! …

Yes, if it gets defined via the conditional in the first pass your programm in fact behaves correctly if the listing is generated in pass 2. I don't know if its the right term, but this is what I would call a "phase mismatch". Have to think about it how this can be solved.

— Reply to this email directly, view it on GitHub, or unsubscribe. You are receiving this because you commented.Message ID: @.***>