Page 1 of 1

Macro is not executed line by line.

Posted: Fri Feb 28, 2020 9:44 pm
by Naheulf
To act as normal code, macro content should be replaced and executed line by line.

This code show how macro works :

Code: Select all

Macro CEI
	CompilerElseIf #True
EndMacro

Macro TestCompilerElseIf
	CompilerIf #False
		; Nothing
	CEI ; In macro CEI is replaced before "execute" CompilerIf. So firsh #FOO is choosed
		#FOO = "FOO defined in macro"
	CompilerElse
		#FOO = "FOO defined in normal code"
	CompilerEndIf
EndMacro

; The same bloc of code as the one inside macro "TestCompilerElseIf"
CompilerIf #False
	; Nothing
CEI ; Outside macro CompilerIf is executed Before (because it's on another line). So the macro is never replaced.
	#FOO = "FOO defined in macro"
CompilerElse
	#FOO = "FOO defined in normal code"
CompilerEndIf

TestCompilerElseIf ; Constant already declared with a different value: #FOO
If macro is executed line per line non-infinite recursive macro can be used

Code: Select all

Macro DQ
	"
EndMacro

Macro Recursive(DEEP)
	CompilerWarning DQ#DEEP passes restantes"
	CompilerSelect DEEP
		CompilerCase 1
			CompilerWarning "Dernière passe"
		CompilerCase 2
			Recursive(1)
	CompilerEndSelect
EndMacro

Recursive(2)
With some tricks to use nested macro, line per line executions also allow to edit macro content form another macro. For example to create compiler variables. If I remove all tricks and workaround to be more human understandable is can looks like this :

Code: Select all

EnableExplicit ; This is concept code. It does NOT works without lot patchs and some preprocessor changes.

Macro SetMacroVar(MacroVar, Value)
	UndefineMacro MacroVar
	Macro MacroVar
		Value
	EndMacro
EndMacro

Macro AddMacroVar(MacroVar, Value)
	SetMacro(MacroVar, (MacroVar) + (Value))
EndMacro

Macro Normalize(MacroVar, Value)
	CompilerSelect Value
		CompilerCase 0
			SetMacroVar(MacroVar, 0)
		CompilerCase 1
			SetMacroVar(MacroVar, 1)
		CompilerCase 2
			SetMacroVar(MacroVar, 2)
		CompilerCase 3
			SetMacroVar(MacroVar, 3)
			; And so on
	CompilerEndSelect
EndMacro

SetMacroVar(FOO, 1)
AddMacroVar(FOO, 2)

CompilerWarning "FOO" ; Display "3"
If that kind of code work i believe PureBasic preprocessor can be Turing complete.

Re: Macro is not executed line by line.

Posted: Fri Feb 28, 2020 10:01 pm
by freak
Just because you don't like how it works does not make it a bug. That is called a feature request ;)

Moved.

Re: Macro is not executed line by line.

Posted: Fri Feb 28, 2020 10:02 pm
by Naheulf
If you change it, it would be nice if we can also write something like this :

Code: Select all

Macro PatchSection
	CompilerIf UsePatch
EndMacro

Macro EndPatchSection
	CompilerEndIf
EndMacro

Macro UsePatch
	#True ; Or #False
EndMacro


; Some normal code
PatchSection
	; Some patch code
EndPatchSection
; Some normal code again
Preprocessor should keep CompilerIf macro deepness to find CompilerEndIf. Because CompilerIf is in one macro level. Compiler should search matching CompilerEndIf one macro level too.

Re: Macro is not executed line by line.

Posted: Sat Feb 29, 2020 9:00 am
by Naheulf
OK I found a workaround to have code executed line by line in full line macro. (When macro call is the only stuff on the line)

1 - I use some tricks to use nested macro and "save" macro params in predefined macro / macrovar (i use "macrovar" to designate macro used as variable for preprocessor)

2 - Put real macro content in dedicated file

3 - Include this file in the macro.

Re: Macro is not executed line by line.

Posted: Sat Feb 29, 2020 3:01 pm
by kenmo
If you change it, it would be nice if we can also write something like this :
But why write it like that?? You can already achieve it so easily:

Code: Select all

#UsePatch = #True ; Or #False

; Some normal code
CompilerIf #UsePatch
   ; Some patch code
CompilerEndIf
; Some normal code again

Re: Macro is not executed line by line.

Posted: Sun Mar 01, 2020 12:37 pm
by Naheulf
kenmo wrote:
If you change it, it would be nice if we can also write something like this :
But why write it like that?? You can already achieve it so easily:

Code: Select all

#UsePatch = #True ; Or #False

; Some normal code
CompilerIf #UsePatch
   ; Some patch code
CompilerEndIf
; Some normal code again
I used "patch" to have simple example. It's intended to allow loop macros creation like "CompilerWhile(condition)" and "CompilerWend".