How can I return a value using a MACRO?

General FreeBASIC programming questions.
Post Reply
adele
Posts: 47
Joined: Jun 13, 2015 19:33

How can I return a value using a MACRO?

Post by adele »

Hi,

I didn´t find a way to make a MACRO call to look/work like a function.
The idea is from the CHM reference for va_arg:
***
variable =va_arg ( argument_list, datatype )
Description
The va_arg MACRO allows the use of a variable number of arguments within a function. va_arg returns the current argument in the list, argument_list, with an expected data type of datatype. Before va_arg can be used, it must be Initialized with the command va_first. Unlike the C macro with the same name, va_arg does not automatically increment argument_list to the next argument within the list. Instead va_next must be used to find the next argument.
***

So tried to create a similar behaviour:

Code: Select all

Y=xform(x)
And xform is a MACRO, maybe:

Code: Select all

#Macro xform(_parameter_)
 ‘Do something with_parameter_, ex:
 Scope
    Dim myInt as integer=_parameter_
    myInt = ((myInt * 3) shl 2) + 99 ‘ nonsense, I know…
 ‘ And this won´t work:
 Return myInt ‘ *** this is the critical point ***
End Scope
#endmacro
Q: How can I return a value using a MACRO?

Thank you in advance!
Adi
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: How can I return a value using a MACRO?

Post by dodicat »

You can use a simple #define for your xform

The chm example using va_arg and va_first gets an average of some doubles.

With a bit of fiddeling a macro can produce an average of numbers.
Here is one method

Code: Select all

 

#define  xform(_parameter_)  ((_parameter_ * 3) shl 2) + 99


#macro GetAverage(d,start...)
scope
dim as long counter
dim as string s=#start
   do
       counter+=1
       var r=val(s)
       d+=r
       s=ltrim(s,str(r))
       s=ltrim(s,",")
       loop until s=""
     d= d/counter
    end scope
#endmacro


dim as double y=xform(2)
print y
print

dim as double average
GetAverage(average,1,2,3,4,5,-6.97,7,8,9,10,11,12,13,1234.008)
print average
print "check average"
print (1+2+3+4+5-6.97+7+8+9+10+11+12+13+1234.008)/14
sleep



  
sancho3
Posts: 358
Joined: Sep 30, 2017 3:22

Re: How can I return a value using a MACRO?

Post by sancho3 »

Macros simply do a replacement of text wherever the macro is called. So technically macros don't return values.
When working with them you can use the FBC command line parameter -pp.
It will create a .bas file called your_file_name.pp.bas. This file will be source code with the macros expanded in place.
This file is created even if there are errors and the source doesn't compile.
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: How can I return a value using a MACRO?

Post by dodicat »

Hi Sancho3
if you compile my code with -pp, line 13 looks strange, although it still runs OK in fb 1.5.
I wonder about fb 1.6 though.
sancho3
Posts: 358
Joined: Sep 30, 2017 3:22

Re: How can I return a value using a MACRO?

Post by sancho3 »

This line:

Code: Select all

dim as string s=$"1,2,3,4,5,-6.97,7,8,9,10,11,12,13,1234.008"
The $ is just ensuring that escape codes are ignored.
adele
Posts: 47
Joined: Jun 13, 2015 19:33

Re: How can I return a value using a MACRO?

Post by adele »

Hi,
Thank you all for the answers.
But I think my question was too less precise. My "function-macro" (let us call it
"change_it()" would consist of a couple of lines, with IFs and ELSEs (NOT #if !)
and a call to a real function, so that one-liners won´t work.
The result can not be calculated without using scoped VARs and temporary
result#1/result#2. I solved the "inner problem", but I´d like to use a more
comfortable, more readable syntax than:

Change_it(@resultVar) ' this works fine.

OK, again my question but more precisely:

var x=999
#macro change_it(_p_)
' do ANY code with or w/o (_p_) ,' assuming type is known
' resultVar ( lhs, here: x ) is NOT known by this macro
' let us assume result is the number 123
#end macro

"change_it" should be called with a left-sided resultVar:

x=change_it(Y) .OR., preferably:
x=change_it()

or, my last hope:

set x=change_it() ' "set" is NOT a reserved word, can the
' the name of a macro that calls change_it

After one of these macro calls, x should be 123

It is a pure syntax issue, not a problem of the code inside the macro.
I guess there is no way...
Oh, I forgot: all code must be local, neither shared nor global VARs can
be used.
THX

Adi
fxm
Moderator
Posts: 12107
Joined: Apr 22, 2009 12:46
Location: Paris suburbs, FRANCE

Re: How can I return a value using a MACRO?

Post by fxm »

The syntax of a macro is not comparable to that of a function (with return value) but rather to that of a subroutine.
So the desired return value must be retrieved via an additional parameter assigned in the body of the macro.

Code: Select all

#macro identify ([parameters], result)
   body
   result = ...
#endmacro
Obvious example (can be resolved using #define):

Code: Select all

#define greater1(x, y) Iif(x > y, x, y)

Print greater1(8, 5)
Print greater1(5, 8)
Print


#macro greater2(x, y, r)
  If x > y Then
    r = x
  Else
    r = y
  End If
#endmacro

Dim As Integer r
greater2(8, 5, r)
Print r
greater2(5, 8, r)
Print r

Sleep
Post Reply