Page 2 of 2

Posted: Mon Jul 11, 2011 11:39 pm
by Near
Well, like I tell others, if // for comments bothers you that much, change it or use something else.

I abhor :less labels because that makes any error compile as valid code.

Code: Select all

clx  //should've been clc, but now it's a label named clx
adc $2100
And with :, block separators on labels become unreadable:

Code: Select all

loop: : dec : beq end : inx : bra loop : end: : rts

Code: Select all

loop:; dec; beq end; inx; bra loop; end:; rts
Defines have both start and close markers so that they are not ambiguous with labels, opcodes and directives, and can concatenate.

Try and specify define x, then define y, then the letter z.

Code: Select all

{x}{y}z
<- very clear purpose

Code: Select all

!x!yz
<- !x + !yz

Code: Select all

xyz
<- is it an opcode? A define named xyz? A label?

Otherwise, I would certainly like markerless defines. It'd basically be a true table assembler at that point.
define clc = db $18 //or whatever clc is
define adc #n = db $69,{n}
define add n = clc; adc {n}
add #$24 //clc; adc #$24

But well, whatever. The code is extremely clean. It's not at all hard to change this stuff. Given how obscure SPC700 ASM code is, just include the assembler source with your SPC700 source.

Or don't worry about minor semantics issues ;)

Posted: Tue Jul 12, 2011 5:24 am
by tepples
byuu wrote:I abhor :less labels because that makes any error compile as valid code.
Same here.
And with :, block separators on labels become unreadable:

Code: Select all

loop: : dec : beq end : inx : bra loop : end: : rts

Code: Select all

loop:; dec; beq end; inx; bra loop; end:; rts
I don't put multiple instructions on one line in my own code, instead choosing to edit in a narrower window and use a newline and two spaces between instructions. But one could decide that when the label separator and the instruction separator are set to the same, a label may appear only in the first position on a line.

Code: Select all

loop: dec : beq end : inx : bra loop
end: rts
This would be a compromise between detecting incorrect 'clx : ' and allowing the more familiar syntax.
Defines have both start and close markers so that they are not ambiguous with labels, opcodes and directives, and can concatenate.

Try and specify define x, then define y, then the letter z.

Code: Select all

{x}{y}z
<- very clear purpose
Or as the C preprocessor puts it: x ## y ## z

Posted: Tue Jul 12, 2011 6:03 am
by Shiru
byuu, how can you explain this?

This does not compile, gives both 'unknown token' and 'unrecognized token' errors on the line where the macro used:

Code: Select all

define dspa reg
	sti {ADDR},#{reg}
	sta {DATA}
enddef

..

{dspa {DSP_ADSR1}}
This compiles. Obviously does not work, I just tried it at random after ran out of ideas why seemingly correct code just don't want to compile (as compiler does not provide too much info in the error messages, I had to exclude bits of code to find what exactly causes the problem):

Code: Select all

define dspa reg
	sta {DATA}
	sti {ADDR},#{reg}
enddef

..

{dspa {DSP_ADSR1}}

Posted: Tue Jul 12, 2011 8:04 am
by Near
A bug, was seeing the first '}' as the end of a define. That was prior to me adding arguments to defines. Unfortunately nobody tested it, sorry.

Please replace Bass::evalDefines with the below function in eval.cpp:

Code: Select all

void Bass::evalDefines(string &line) {
  unsigned length = line.length();
  for(unsigned x = 0; x < length; x++) {
    if(line[x] == '{') {
      signed counter = 1;
      for(unsigned y = x + 1; y < length; y++) {
        if(line[y] == '{') counter++;
        if(line[y] == '}') counter--;
        if(line[y] == '}' && counter == 0) {
          string name = substr(line, x + 1, y - x - 1);
          if(!name.position("::")) name = { activeNamespace, "::", name };

          lstring header, args;
          header.split<1>(" ", name);
          if(header[1] != "") args.split(",", header[1]);

          foreach(define, defines) {
            if(header[0] == define.name && args.size() == define.args.size()) {
              string result;
              evalParams(result, define, args);
              line = string(substr(line, 0, x), result, substr(line, y + 1));
              defineExpandCounter++;
              return evalDefines(line);
            }
          }
          break;
        }
      }
    }
  }
}
Also, it's odd code that seems to assume A already has the value you want to write. I assume that was your intention.
But one could decide that when the label separator and the instruction separator are set to the same, a label may appear only in the first position on a line.
That would break my macro expansions (it turns each line feed into a separator, so that error messages are on the same line# and I only have to replace data on the currently selected line block), and it would also require a specialized parsing grammar instead of just qsplit(";", line);

Posted: Tue Jul 12, 2011 8:39 am
by Shiru
Thanks for the fix, it works.

Other problem, maybe a minor one, but can make some headache - no errors if an undefined label is used in a beq. I.e., no label anywhere: is defined, bra anywhere makes a error, while beq anywhere shows no error.

Posted: Tue Jul 12, 2011 10:17 am
by Near
Here's a fixed version for the define and beq issues. Also added -overwrite option to forcefully overwrite existing files.

Code: Select all

http://byuu.org/files/bass_v02.tar.bz2
Sorry again that you're effectively the beta tester here, but I appreciate the bug reports at any rate.