nurpax / c64jasm

C64 6502 assembler in TypeScript
51 stars 14 forks source link

Cryptic message: should be unreachable? #83

Closed micheldebree closed 3 years ago

micheldebree commented 3 years ago

I am trying to convert my existing code to c64jasm to evaluate if I can switch over from Kickass to c64jasm. I am working through the error messages one by one, but am a bit stuck by this one (it does not follow the standard error format either):

npx c64jasm "big_angry_sprite.asm" --out "big_angry_sprite.prg"

Compiling big_angry_sprite.asm should be unreachable?

The code can be found here: https://github.com/micheldebree/big_angry_sprite/tree/c64jasm

nurpax commented 3 years ago

Definitely looks like a bug in c64jasm. "should be unreachable" seems looks like an internal compiler error. I'll take a look this weekend.

Or if you're curious, you can try to look into it yourself too. See https://github.com/nurpax/c64jasm/blob/master/DEVELOPMENT.md and run c64jasm directly from git with npm run asm big_angry_sprite.asm --disasm --out /dev/null

micheldebree commented 3 years ago

Thanks. Somehow I need to do

node build/src/cli.js ../big_angry_sprite/big_angry_sprite.asm --disasm --out /dev/null to get results. The parameters seem to get mangled when run through the npm script. Anyway, this is what I get:

/Users/michel/dev/github/c64jasm/build/src/asm.js:1318
                throw err;
                ^

Error: should be unreachable?
    at Assembler.evalExpr (/Users/michel/dev/github/c64jasm/build/src/asm.js:735:15)
    at Assembler.evalExpr (/Users/michel/dev/github/c64jasm/build/src/asm.js:629:43)
    at Assembler.evalExprType (/Users/michel/dev/github/c64jasm/build/src/asm.js:446:26)
    at Assembler.evalExprToInt (/Users/michel/dev/github/c64jasm/build/src/asm.js:502:21)
    at Assembler.checkAbs (/Users/michel/dev/github/c64jasm/build/src/asm.js:774:25)
    at /Users/michel/dev/github/c64jasm/build/src/asm.js:1286:26
    at withMarkAsInsn (/Users/michel/dev/github/c64jasm/build/src/asm.js:1245:13)
    at Assembler.assembleLine (/Users/michel/dev/github/c64jasm/build/src/asm.js:1250:13)
    at assemble (/Users/michel/dev/github/c64jasm/build/src/asm.js:1178:22)
    at Assembler.assembleLines (/Users/michel/dev/github/c64jasm/build/src/asm.js:1202:16)

If I log the value of node at the point where the exception is thrown, it is:

{
  type: 'qualified-ident',
  path: [ 'music' ],
  absolute: false,
  loc: {
    start: { offset: 2918, line: 141, column: 13 },
    end: { offset: 2923, line: 141, column: 18 },
    source: '../big_angry_sprite/big_angry_sprite.asm'
  }
}

Ah, it seems like this is the culprit:

!segment music(start=$4000, end=$9fff)

!let music = sid("terminator-vfx.sid")

If I use another name for the segment, the error does not occur. Seems like I can't use the same name for !segment and !let.

nurpax commented 3 years ago

Yup.. seems like an error handling bug in c64jasm. Thanks for reporting and digging into it!

Segments, variables, macros and labels are all in the same namespace, so same symbol names are not allowed in the same scope. But apparently error handling to check this is incomplete.

Allowing same symbols for different types of things would be possible, but IIRC it leads to some confusing bugs. Like it will not be obvious whether some symbol name resolves to a label or a variable if both are in scope.

The same thing applies to for example C++:

test.cpp:

int foo = 3;

namespace foo {
  int a = 0;
};
$ g++ test.cpp
test.cpp:3:11: error: ‘namespace foo { }’ redeclared as different kind of entity
    3 | namespace foo {
      |           ^~~
test.cpp:1:5: note: previous declaration ‘int foo’
    1 | int foo = 3;
      |     ^~~
micheldebree commented 3 years ago

I don't mind using different names, but a clear error message would certainly help.

nurpax commented 3 years ago

This seems to trigger an error just fine:

!segment music(start=$4000, end=$9fff)
!let music = 0 ; duplicate symbol 'music' not allowed

Produces:

test/errors/segment7.input.asm:2:1: error: Variable 'music' already defined

But this triggers the bug:

!segment music(start=$4000, end=$9fff)
!let music = { init: $2000 } ; duplicate symbol 'music' not allowed

    lda #music.init