Page 1 of 1

Macro parameter: determine empty value

Posted: Wed Feb 22, 2017 11:10 am
by PeterJ
I try to find a reliable way, if a Macro parameter is set, or empty or contains the default value. Reason I want to treat the coding to be produced depending on it. I tried several proposals, but couldn't find a solution, which suits all variations. Maybe I overlooked something and someone has a good idea. I know of course, that a possible way is to move the parameter value in a temporary variable followed by a if statement, but I'd prefer a precompile solution.

Code: Select all

Macro Dquote()
  "
EndMacro
;
Macro MyMacro(parm1=)
  CompilerIf Dquote()parm1#Dquote()=""
    Debug "Parm1 not set"
  CompilerElse
    Debug "Parm1 is set: "+parm1
  CompilerEndIf 
EndMacro
;
; Macro calls
;
var$="Alice" 
MyMacro()            ; case 1 : parameter is not set
Mymacro(var$)     ; case 2 : parameter represents a variable
MyMacro("Alice")   ; case 3 : parameter is a string 
Case 1 and 2 work fine, case 3 produces a compiler error, because of the double double quotes, which is of course correct.

Maybe someone has a bright idea!

Peter

Re: Macro parameter: determine empty value

Posted: Wed Feb 22, 2017 2:31 pm
by HanPBF
I don't know a way to distinct a literal from a variable as after compiling they are both given values.

So the following code distincts only between given and not given using a default argument.

Code: Select all

enableExplicit

Macro DQ()
  "
EndMacro

#EMPTYSTRING="~"

Macro MyMacro(p=#EMPTYSTRING)
	if p=#EMPTYSTRING
		debug "no value given"
		
	else
		debug "value given"
	endif
EndMacro

define V.s="Alice"
MyMacro()            	; case 1 : parameter is not set
Mymacro(V)     				; case 2 : parameter represents a variable
MyMacro("Alice")			; case 3 : parameter is a string 
Or you can define another value type.

Code: Select all


enableExplicit


#Null = 0
#NullString = ""


structure StringValue
	Value				.s
	IsNull			.b
	IsUndefined .b
endStructure


declare		addStringValues		(*V1.StringValue, *V2.StringValue)
declare		debugStringValue	(*V.StringValue)
declare.s getValue					(*V.StringValue)
declare		isValueNull				(*V.StringValue)
declare		isValueUndefined	(*V.StringValue)
declare		isValueEmpty			(*V.StringValue)
declare		newStringValue		(Value.s="", IsUndefinedIfEmpty.b=#True)
declare 	setValue					(*V.StringValue, Value.s)



define *V1.StringValue	= newStringValue("")
define *V2.StringValue = newStringValue("")

define *V3.StringValue = addStringValues(*V1, *V2)

debugStringValue(*V3)


procedure addStringValues(*V1.StringValue, *V2.StringValue)
	protected *R.StringValue
	
	*R = newStringValue("")
	
	if *V1\IsUndefined
		if *V2\IsUndefined
			*R\IsUndefined = #True ; kept undefined
			
		else
			*R\Value 				= *V2\Value
			*R\IsUndefined	= #False
		endif
		
	else
		if *V2\IsUndefined
			*R\Value 				= *V1\Value
			*R\IsUndefined	= #False
			
		else
			*R\Value				= *V1\Value + *V2\Value
			*R\IsUndefined	= #False
		endif	
	endif
	
	procedureReturn *R
endProcedure

procedure debugStringValue(*V.StringValue)
	if *V\IsUndefined
		debug "#UNDEFINED"
		
	elseif *V\IsNull
		debug "#NULL"
		
	else
		debug *V\Value
	endif
endProcedure 

procedure setValue(*V.StringValue, Value.s)
	*V\Value = Value

	*V\IsNull = #False
EndProcedure

procedure.s getValue(*V.StringValue)
	if *V\IsNull
		ProcedureReturn #NullString
	else
		ProcedureReturn *V\Value
	endif
endProcedure

procedure isValueNull(*V.StringValue)
	ProcedureReturn *V\IsNull
EndProcedure

procedure isValueUndefined(*V.StringValue)
	ProcedureReturn *V\IsUndefined
EndProcedure

procedure isValueEmpty(*V.StringValue)
	ProcedureReturn bool(*V\Value="")
EndProcedure

procedure newStringValue(Value.s="", IsUndefinedIfEmpty.b=#True)
	protected *R.StringValue
	
	*R = AllocateStructure(StringValue)
	
	*R\Value = Value
	
	if Value="" and IsUndefinedIfEmpty
		*R\IsUndefined = #True
	endif
	
	procedureReturn *R
EndProcedure
Putting code into the compiling process is not the intention of PureBasic.
It's not a dynamic language; it's a fast executables generating fast compiler.

Re: Macro parameter: determine empty value

Posted: Wed Feb 22, 2017 3:17 pm
by PeterJ
HanPBF wrote:I don't know a way to distinct a literal from a variable as after compiling they are both given values.
So the following code distincts only between given and not given using a default argument.

Code: Select all

enableExplicit
Macro DQ()
  "
EndMacro
#EMPTYSTRING="~"
Macro MyMacro(p=#EMPTYSTRING)
	if p=#EMPTYSTRING
		debug "no value given"	
	else
		debug "value given"
	endif
EndMacro
I know this solution, but that's not what I intended. My goal was to create the necessary code at compile time. This seems not possible (right now). Anyway, not really a big deal, there are ways to circumvent it .
HanPBF wrote:I don't know a way to distinct a literal from a variable as after compiling they are both given values.
Putting code into the compiling process is not the intention of PureBasic.
It's not a dynamic language; it's a fast executables generating fast compiler.
I wouldn't agree to that. PB contains a typical one pass compiler with a pre-compiler included as many compilers do. Some haven't even precompile/macro facilities. Granted the PB macro language is basic, and sometimes I'd wish it contained a bit more functionality, which I think is not a contradiction to the one-pass compile.

Anyway thanks for reply!

Peter

Re: Macro parameter: determine empty value

Posted: Wed Feb 22, 2017 5:15 pm
by c4s
See this topic for a very related feature request: Improve Macro Handling with MacroIf and MacroParam()