| |
Taskmaster Account closed
Registered: Feb 2018 Posts: 22 |
KickAssembler macro expansion ...
I want to do something like this but it's eluding me in KickAssembler:
.macro AllocString( _name_ )
{
_name_:
.fill 100,32
.byte 0
}
AllocString( string1 )
AllocString( string2 )
My hope would be that this code would be generated:
string1:
.fill 100,32
.byte 0
string2:
.fill 100,32
.byte 0
But instead I get errors about "_name_" is being redefined ...
Is this sort of thing not possible in Kick? Just curious if it's possible to generate code like that ... |
|
| |
0xDB
Registered: Aug 2015 Posts: 27 |
Any labels put inside a scope are not visible from outside that scope. Macro calls are encapsulated in a scope, so what you are trying to do would not work even if Kick Assembler supported turning the parameter into a label because you can not access the label from outside the scope.
The error you are getting about "_name_" being redefined is because "_name_" is a parameter of the macro and then you try to redefine it as a label.
You could still achieve something similar to what you are trying to do by using a hashtable ( http://theweb.dk/KickAssembler/webhelp/content/ch06s04.html ) where you put the name of the string as key and the current program counter as value.
e.g. like this:
.var stringtable = Hashtable()
.macro AllocString( _name_ )
{
.eval stringtable.put( _name_, *)
.fill 100,32
.byte 0
}
* = $0800
AllocString( "string1" )
AllocString( "string2" )
.var keys = stringtable.keys()
.for (var i=0; i<keys.size(); i++)
{
.var k = keys.get(i)
.print k + " is at $" + toHexString(stringtable.get(k),4)
}
Personally I would not do that though as it makes the code less readable. Instead I'd change the macro to allow setting a size and clear character via parameters and then just write the definitions like this:
string1: newString(100, ' ')
string2: newString(50, '@')
Since you have to type out the names of the strings anyway with or without support for having them turned into a unique label, having the name as a parameter of a macro would not make writing the code any less tedious. |
| |
Taskmaster Account closed
Registered: Feb 2018 Posts: 22 |
Thanks for the reply ... String was probably a bad choice of example code, I apologize. It's just what I was working on at the time. :)
Good point about the scoping. Blah.
I guess macros in Kick aren't going to work the way I want them to.
What I'm trying to do is generalize a system where I can use a form of code snippets.
Like, here's a piece of code I use a lot. The only differences are that some of the label names used inside change to suit the situation. I want some way in Kick to drop in these snippets, replace the label names inside that need replacing, and insert the finished snippet into the code before compilation.
I had this in my home brew assembler and I fear it's something I've come to rely on but maybe nobody else supports... heh. |
| |
Stone
Registered: Oct 2006 Posts: 172 |
ca65 supports label generation from macros. The simple way:
.macro AllocString name
name:
.res 100,32
.byte 0
.endmacro
lda #<str1
ldy #>str1
jsr $ab1e
...
AllocString str1
and through strings or concatenation of strings:
.macro AllocString2 name
.ident(name):
.res 100,32
.ident(.concat(name, "_end")):
.ident(.concat(name, "_len")) = .ident(.concat(name, "_end")) - .ident(name)
.endmacro
ldy #0
loop:
lda str2,y
beq done
jsr $ffd2
iny
cpy #str2_len
bne loop
done:
...
AllocString2 "str2"
or even
.macro AllocString3 name
AllocString2 .string(name)
.endmacro
AllocString3 str3
|
| |
Taskmaster Account closed
Registered: Feb 2018 Posts: 22 |
Yeah, that's what I'm looking for ... maybe Kick was the wrong choice for my workflow. :)
Thanks, I'll poke around ca65 and maybe a few others... |
| |
Frantic
Registered: Mar 2003 Posts: 1648 |
If you're looking for purely textual stuff when you talk about macro expansion, you could use a separate general purpose preprocessor I guess?
I really have no idea what to use, and I haven't tried it myself, but maybe something like this would work in that case?
http://boldinventions.com/index.php?option=com_content&view=art.. |
| |
Mr. SID
Registered: Jan 2003 Posts: 424 |
If you want a generic pre-processor (like C/C++) then k2asm has one called k2pp that is python-based, so you can also embed python code to emit labels/data into your source-code.
http://k2devel.sourceforge.net[/url]
Your example would roughly look like this (with a variable length):
#pybegin
def allocString(name, length):
print "%s: .buf %d,32" % (name, length)
print ".byte 0"
#pyend
;....
#pybegin
allocString("str1", 100)
allocString("str2", 8)
#pyend
After pre-processing, this would look like:
str1: .buf 100,32
.byte 0
str2: .buf 8,32
.byte 0
|
| |
Slammer
Registered: Feb 2004 Posts: 416 |
In Kick Assembler you would normally access labels inside the macro by putting a label infront of the macro execution:
*=$1000
start: inc c1.color
dec c2.color
c1: :setColor()
c2: :setColor()
jmp start
.macro setColor() {
.label color = *+1
lda #0
sta $d020
}
In a similar way you can access for-loops and if's. Read about it here: http://theweb.dk/KickAssembler/webhelp/content/ch09s07.html
Don't know if it helps your code snippets case. |