Page 1 of 1

Nested Macros

Posted: Tue Jan 29, 2013 4:29 am
by NicTheQuick
Nested Makros does not work as expected.

Code: Select all

Procedure.s sowhat_(a, b)
	ProcedureReturn "sowhat: " + Str(a - b)
EndProcedure

Macro Dq
	"
EndMacro

Macro Concat(prefix, suffix, a, b, moin=ro)
	Mac#moin prefix#suffix(para1, para2)
		Debug "Test: " + Dq#prefix#suffix#Dq + prefix#suffix#_(para1, para2)
	;EndMac#moin		;This line doesn't work
EndMacro

Concat(so, what, 1, 2)
EndMacro	;Instead I need it here

sowhat(1, 2)

Re: [PB 5.10b5] Nested Makros

Posted: Tue Jan 29, 2013 11:38 am
by Fred
It's not supported.

Re: [PB 5.10b5] Nested Makros

Posted: Tue Jan 29, 2013 11:53 am
by NicTheQuick
Is it already requested as a feature?
Practically it's working well except for this "EndMacro at an other position" thing.

Re: [PB 5.10b5] Nested Makros

Posted: Tue Jan 29, 2013 11:55 am
by Fred
I don't think it is, so I moved the topic.

Re: Nested Macros

Posted: Tue Jan 29, 2013 12:22 pm
by NicTheQuick
With nested macros you are able to do overloading of procedures.

The following code works and overloads four Procedures to multiply, add, subtract and divide 3D-vectors with 3D-vectors, 3D-vectors with skalars or skalars with 3D-vectors.

Code: Select all

EnableExplicit

Structure Vector
	x.f
	y.f
	z.f
EndStructure

Macro MacroRo
	ro
EndMacro

Macro VectorOp(op, opName)
	Procedure Vector#opName#Vector(*a.Vector, *b.Vector)
		*a\x op *b\x
		*a\y op *b\y
		*a\z op *b\z
	EndProcedure
	
	Procedure Vector#opName#Skalar(*a.Vector, b.f)
		*a\x op b
		*a\y op b
		*a\z op b
	EndProcedure
	Mac#MacroRo Vector#opName(a, b)
		CompilerIf Defined(a, #PB_Variable)	;a is a variable?
			CompilerIf Defined(b, #PB_Variable) ;b is a variable?
				CompilerIf TypeOf(b) = #PB_Structure ;b has a structure (unfortunality we can not check if the structure is really Vector)
					CompilerIf TypeOf(a) = #PB_Structure ;a has a structure
						Vector#opName#Vector(a, b)	;a and b have a structur
					CompilerElse
						Vector#opName#Skalar(b, a)	;b has a structure and a is a normal variable, maybe float or integer
					CompilerEndIf
				CompilerElse
					CompilerIf TypeOf(a) = #PB_Structure
						Vector#opName#Skalar(a, b)	;a has a structure and b is a normal variable, maybe float or integer
					CompilerElse
						CompilerError "VectorMul(Float, Float): At least on parameter has to be of type Vector."
					CompilerEndIf
				CompilerEndIf
			CompilerElse
				CompilerIf TypeOf(a) = #PB_Structure
					Vector#opName#Skalar(a, b)	;a has a structure und b is a constant value (until now only integers are possible)
				CompilerElse
					CompilerError "VectorMul(Float, Constant): At least on parameter has to be of type Vector."
				CompilerEndIf
			CompilerEndIf
		CompilerElse
			CompilerIf Defined(b, #PB_Variable)
				CompilerIf TypeOf(b) = #PB_Structure
					Vector#opName#Skalar(b, a)		;b has a structure und a is a constant value
				CompilerElse
					CompilerError "VectorMul(Constant, Float): At least on parameter has to be of type Vector."
				CompilerEndIf
			CompilerElse ;a und b sind keine Variablen -> Fehler
				CompilerError "VectorMul(Constant, Constant): At least on parameter has to be of type Vector."
			CompilerEndIf
		CompilerEndIf
;	EndMac#MacroRo
EndMacro

;For some reason I had to put the EndMacro after VectorOp instead of uncomment it three lines above
VectorOp(*, Mul)
EndMacro
VectorOp(+, Add)
EndMacro
VectorOp(/, Div)
EndMacro
VectorOp(-, Sub)
EndMacro

; After these macro executions the following procedures exist
; - VectorMulVector(*a.Vector, *b.Vector)
; - VectorMulSkalar(*a.Vector, b.f)
; - VectorAddVector(*a.Vector, *b.Vector)
; - VectorAddSkalar(*a.Vector, b.f)
; - VectorDivVector(*a.Vector, *b.Vector)
; - VectorDivSkalar(*a.Vector, b.f)
; - VectorSubVector(*a.Vector, *b.Vector)
; - VectorSubSkalar(*a.Vector, b.f)
;
; The following four macros help you ignoring the type and order of the parameters (overloading)
; - VectorMul(a, b)
; - VectorAdd(a, b)
; - VectorDiv(a, b)
; - VectorSub(a, b)

Define a.Vector, b.Vector, c.f
a\x = 1 : a\y = 2 : a\z = 3
b\x = 1 : b\y = 2 : b\z = 3
c = 4

Debug "a = (" + a\x + ", " + a\y + ", " + a\z + ")"
Debug "b = (" + b\x + ", " + b\y + ", " + b\z + ")"
Debug "c = " + c

VectorAdd(a, b)	;Vector + Vector
Debug "a + b"
Debug "a = (" + a\x + ", " + a\y + ", " + a\z + ")"

VectorMul(c, a) ;Skalar * Vector
Debug "c * a"
Debug "a = (" + a\x + ", " + a\y + ", " + a\z + ")"

VectorDiv(a, c) ;Vector / Skalar
Debug "a / c"
Debug "a = (" + a\x + ", " + a\y + ", " + a\z + ")"

VectorSub(a, b) ;Vector - Vector
Debug "a - b"
Debug "a = (" + a\x + ", " + a\y + ", " + a\z + ")"

VectorMul(a, 4) ;Vector * 4    ;Until now, it is not possible to using floating point numbers, but integers work as expected
Debug "a * 4"
Debug "a = (" + a\x + ", " + a\y + ", " + a\z + ")"

;To test the error checking uncomment one or more of these lines
;VectorAdd(3, 4)
;VectorAdd(c, c)
;VectorAdd(c, 2)
With native support for nested macros and a better TypeOf() command which also can distinguish between different structures, "constant strings" and constant floating point numbers (123.456), this example could be only the beginning of more advanced macroing.

Re: Nested Macros

Posted: Tue Jan 29, 2013 4:31 pm
by SFSxOI
I agree with Nic, native nested macro support would be a very nice addition