Is there a way to replace substrings in macros with parameters instead of full words?

Flenser

Senior Member
Does anyone know of a technique I can use to get the parameters to replace substrings inside macros instead of complete words?

I had two instances were I would have liked to do this.

1) To generate two different labels for each macro using just one parameter:

Code:
#MACRO macro#1(label, variable)
if variable > 1 then goto label_1
	<some code>
	goto label_2
label_1:
	<some more code>
label_2:
##ENDMACRO
This macro would then be invoked as:
Code:
macro#1(case1, b0)
If you call this macro twice the compilation fails because of duplicate labels named "label_1:" and "label_2:"

2) So that I could use symbols for byte and bit variables in my macro instead of hard coding the byte or bit variable names

Code:
symbol TEMP_BYTE_B0	= b0			; B0 is used as a global TEMP variable
symbol TEMP_BYTE_B0.5	= bit5

#MACRO macro#2(label, variable, )
if variable.5 > 1 then goto label
	variable = variable * 2
label:
##ENDMACRO
This macro would then be invoked as:
Code:
macro#2(bit5_check1, TEMP_BYTE_B0)
 

hippy

Technical Support
Staff member
There is no way to do what you would like. But you could simply use block IF-THEN-ELSE-ENDIF statements which would avoid the problem, would not need labels to be be used.
 

Flenser

Senior Member
Hippy, thanks for the reply, I didn't hold out a lot of hope but I thought I'd ask on the forum anyway.

The two pieces of code are artificial examples only made up to demonstrate my issue.

Flenser
 

inglewoodpete

Senior Member
With good structuring of your code you will not need to use internal labels anywhere in your program. Just NEVER use the GoTo command! I think it is an abomination for good programming practice. (and now the arguments start...:))

The only place I use a label is the entry point of a subroutine.
 

techElder

Well-known member
Flenser, the easiest way to develop a #macro is to develop the code first without the #macro wrapper.

I'm afraid you're thinking of a macro as a function. It is only a programming convenience with some added and useful twists.
 

hippy

Technical Support
Staff member
With good structuring of your code you will not need to use internal labels anywhere in your program.
I would agree with that, though where a command has a timeout label that can be a little awkward because that needs a label somewhere. The usual solution is to pass label names into the MACRO.

I missed the part about concatenation to achieve "variable.5" and similar. The usual solution there would be to move "variable" into 'b0' and then use 'bit5', like ...

Code:
#Macro Test( variable )
  b0 = variable
  If bit5 = 1 Then
 

Flenser

Senior Member
The usual solution there would be to move "variable" into 'b0' and then use 'bit5',
Hippy, thanks for the suggestion but this particular bit of code is a part of some efforts to improve the performance of a program. I am using the same code snippet at multiple places in this program so to make it easier to maintain I've moved that code snippet into a macro. Having that extra command to copy the parameter into a variable in the macro adds extra time to the code path in multiple places, extra time that I do do not want to pay. I didn't use a subroutine for the same reason, I do not want to pay the extra time to do the subroutine call/return every time this code snippet executes.
 

hippy

Technical Support
Staff member
Perhaps post your actual code and it may be possible to advise on how best to approach that.

It may be that having the code all in-line is the most optimal for speed; trying to optimise that, make it more readable or more maintainable may work against that. There may be other approaches which can help improve things which don't impact on speed or only in an insignificant manner.

It may be worth explaining what the application does and where the need for speed arises. It may be that speed is essential in some places but not so much in others allowing code to be refactored with that in mind.
 

hippy

Technical Support
Staff member
I don't know how representative your example code is of what you actually have, but there are often mathematical tricks which can be used to achieve the same end results as an IF statement. For example ...

Code:
#MACRO macro#2( label, variable )
  if variable.5 [b]= 1[/b] then goto label
    variable = variable * 2
  label:
#ENDMACRO
Could perhaps become ...

Code:
#MACRO macro#2( variable )
  variable = variable / 32 ^ 1 * variable + variable
#ENDMACRO
I don't know if that actually implements what's intended or would actually be faster or not. It would greatly depend on the context and what functionality was required.

If you were just moving a bit through a variable and wanted to stop when bit 5 were set, you could use ...

Code:
#MACRO macro#2( variable )
  variable = variable + variable Max 32
#ENDMACRO
I haven't actually checked if an addition is faster than a multiplication by two. A shift left by one would probably be fastest.

Or you could read from EEPROM or TABLE if you weren't otherwise using that.
 
Last edited:

Flenser

Senior Member
Hippy,

The two code examples I gave are completely artificial. Everyone pls don't spend any more time recommending how they could be coded differently.

The only question I had was the one I posed in the subject line, which you have already answered.

I wrote the two simple code examples only to demonstrate the two situations where I would have liked to use this feature. Sorry for any confusion.
 

AllyCat

Senior Member
Hi,

I haven't actually checked if an addition is faster than a multiplication by two.
Yes it is (by around 10 - 20%), probably because + is a faster operation than * . I've not measured << 2 but suspect a negligible difference from +.

In my experience the IF .. THEN construct is nearly always faster than a "mathematical equation" alternative, perhaps because it uses a (real or implied) GOTO , which after all is what the PIC machine code actually executes. ;)

Generally you can make a reasonable estimate of the fastest construct from the number of bytes which the PE creates (or adds to the program). However, the tokens for + - * / etc. are probably all the same size (but * and / take longer to execute) and variable = 1 + variable is significantly slower than variable = variable + 1 (which is identical to inc variable). Also, ON .. GOTO can be much faster than any of the other constructs, perhaps by a factor as high as 5.

Cheers, Alan.
 
Top