How do you use macros?

One suite to code them all. An complete IDE and assembler for all your z80 projects!

Moderators: benryves, kv83

Post Reply
User avatar
benryves
Maxcoderz Staff
Posts: 3080
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

How do you use macros?

Post by benryves »

Brass 2 will, naturally, have to support bcall(label) style functionality.

The way I see it, that's a function, and so you can currently do this:

Code: Select all

.function bcall(label)
    rst rBR_CALL
    .dw label
.endfunction
The way macros are currently handled in Brass 1 are crude string replacement techniques. Brass 2 calls each function as if it was a complete piece of assembly code in its own right, temporarily switching into its own module so that you don't get label conflicts. (Brass 1 expands a macro "call" into a string; Brass 2 will use the same mechanism as it does for #including other source files).

There is a slight style problem here. In TASM/Brass 1 you can do this:

Code: Select all

#define bcall(label) rst rBR_CALL \ .dw label
Due to the way Brass 2 breaks up code, this is impossible to handle without a hack. That's seen as two isolated commands.

The other use of macros I know of are run-time switches. As in:

Code: Select all

#define Debug

#ifdef Debug
    call xyz
#endif
What I might do is provide a #define that works purely as a text replacement system, using regular expressions.

Thoughts?
User avatar
Timendus
Calc King
Posts: 1729
Joined: Sun 23 Jan, 2005 12:37 am
Location: Netherlands
Contact:

Post by Timendus »

I use macros in the API to make it possible for people to "transparently include" bits of code. The special thing about the API is not that it is a big pile of routines, but that you can use those routines without worrying about how to properly include them, and how not to include too much. I think it would be nice to be able to do something similar with Brass 2.

All my other uses are either one of your two examples.
http://clap.timendus.com/ - The Calculator Link Alternative Protocol
http://api.timendus.com/ - Make your life easier, leave the coding to the API
http://vera.timendus.com/ - The calc lover's OS
User avatar
benryves
Maxcoderz Staff
Posts: 3080
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Post by benryves »

That's just alerted me to a flaw in my system, then. Because functions aren't built using string replacement, something like:

Code: Select all

.function load(reg, val)
    ld reg,val
.endfunction
...will not work as reg is a string value.

The current way functions are handled is that when the function is called, Brass goes through the list of arguments, evaluates them, and sets labels to those values. So, in the above case:

Code: Select all

.function load(reg, val)
    ld reg,val
.endfunction

load(hl, 10)
...is evaluated as:

Code: Select all

.module _func_0_ ; Restrict labels to local scope
    ; Set up arguments
    reg = hl
    val = 10
    ; Evaluate function
    ld reg,val
.endmodule
This clearly won't work. Now, a workaround might be this sort of thing:

Code: Select all

.function load(token reg, value val)
    ld reg,val
.endfunction
...in which Brass associates a particular type with each argument. For "value" types (which would be the default) new labels are created as above. For "token" types, the token passed in to the function would be replaced, much like TASM does by string replacement. If this doesn't make sense, I'll try and explain it better.

You could make it more explicit (there are a number of different token types - eg string tokens or operator tokens).

Yes, thinking about it, that's more the way to go (types on the arguments).

Bear in mind that none of this functionality is handled by Brass itself, and is actually handled by an external plugin, so you can write your own run-time function declaration system if you so wish. In fact, for the API, or any API-like project, you could be better off writing dedicated function plugins that do advanced optimisations (you could write this in C#, VB, PHP - any .NET language - freeing you from the constraints of the assembler's scripting) and still provide the TASM macros as an option for those using TASM. Or, indeed, just have a plugin that adds a #define/#defcont system (via a preprocessor and/or directive plugin) that simulates TASM's behaviour.
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

or you could just make it so that

Code: Select all

.module _func_0_ ; Restrict labels to local scope
    ; Set up arguments
    reg = hl
    val = 10
    ; Evaluate function
    ld reg,val
.endmodule
would be the same as

Code: Select all

ld hl,10
which it is, but Brass doesn't know that?
"reg" = "hl" -> "ld reg" = "ld hl"
Couldn't Brass just assign strings to labels?
User avatar
Timendus
Calc King
Posts: 1729
Joined: Sun 23 Jan, 2005 12:37 am
Location: Netherlands
Contact:

Post by Timendus »

Hmm, you have a good point there. I'll consider it, though I don't expect to be doing much with the API in the near future.
http://clap.timendus.com/ - The Calculator Link Alternative Protocol
http://api.timendus.com/ - Make your life easier, leave the coding to the API
http://vera.timendus.com/ - The calc lover's OS
User avatar
benryves
Maxcoderz Staff
Posts: 3080
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Post by benryves »

King Harold wrote:or you could just make it so that
...
would be the same as

Code: Select all

ld hl,10
which it is, but Brass doesn't know that?
That's the point - it isn't. In fact, even defining the function would cause a parse error as Brass wouldn't know what "ld reg,10" meant as the assembler plugin would complain that "reg" wasn't a valid register name.

Labels have two values associated with them; an integer (page number) and a double (the actual value). When you say

Code: Select all

reg = hl
...the expression parser kicks in and tries to evaluate hl. If that's "hl" it would return the numeric value (defined in this case as 'l'+256*'h'), otherwise it'll look up a label name hl.

I'll have to see what I can come up with. This is a little out-of-date but explains the way tokens work.


EDIT:
Timendus wrote:Hmm, you have a good point there. I'll consider it, though I don't expect to be doing much with the API in the near future.
I'm just bouncing ideas around. :) I don't want to make too many bad decisions.

EDIT 2:

There's another topic to reconsider, a documentation parser (reading documentation from comments). :D
King Harold
Calc King
Posts: 1513
Joined: Sat 05 Aug, 2006 7:22 am

Post by King Harold »

That's the point - it isn't.
ofcourse it is, but with the parser working this way, Brass will not realize that.

"reg" = "hl" -> "ld reg" = "ld hl"
it's the same as saying:
a = b -> c+a = c+b
which is very true, but since Brass wile try to evaluate stuff, it will go all weird and ignore the fact that it was intended to be a string value instead of an expression.

a documentation parser sounds very cool though
User avatar
benryves
Maxcoderz Staff
Posts: 3080
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Post by benryves »

Thinking more about it, you could probably get away with direct substitution of tokens anyway, unless someone passes in something that is clearly a numeric expression (eg if someone passed in hl+0, that couldn't possibly be a register so would try to get evaluated). The only concern is that shoe-horning in new tokens might break any precalculations or cached data. I'll let you know how I get on. :)
User avatar
Timendus
Calc King
Posts: 1729
Joined: Sun 23 Jan, 2005 12:37 am
Location: Netherlands
Contact:

Post by Timendus »

benryves wrote:There's another topic to reconsider, a documentation parser (reading documentation from comments). :D
Yes, that old idea... We've been pushing that away far too long ;)
We really should once and for all define a unified commenting system, if you ask me.
http://clap.timendus.com/ - The Calculator Link Alternative Protocol
http://api.timendus.com/ - Make your life easier, leave the coding to the API
http://vera.timendus.com/ - The calc lover's OS
User avatar
benryves
Maxcoderz Staff
Posts: 3080
Joined: Thu 16 Dec, 2004 10:06 pm
Location: Croydon, England
Contact:

Post by benryves »

I'm more into it this time as, like everything else, Brass will only have to do the job of collecting the comments. As far as formatting/generating the output goes, that'll be up to a plugin author - but I'll probably write some bare-bones XML-ish thing that could be used by Latenite.
Post Reply