[PB 5.10b5] CompilerIf TypeOf("asdf") = #PB_String and more

Got an idea for enhancing PureBasic? New command(s) you'd like to see?
User avatar
NicTheQuick
Addict
Addict
Posts: 1504
Joined: Sun Jun 22, 2003 7:43 pm
Location: Germany, Saarbrücken
Contact:

[PB 5.10b5] CompilerIf TypeOf("asdf") = #PB_String and more

Post by NicTheQuick »

Hi,

I want to check if a given parameter of a Macro is a constant string or a float (double).

Code: Select all

EnableExplicit

Procedure TypEgal_Long(a.l)
	Debug "Long: " + a
EndProcedure

Procedure TypEgal_Integer(a.l)
	Debug "Integer: " + a
EndProcedure

Procedure TypEgal_Float(a.f)
	Debug "Float: " + a
EndProcedure

Procedure TypEgal_Quad(a.q)
	Debug "Quad: " + a
EndProcedure

Procedure TypEgal_String(a.s)
	Debug "String: " + a
EndProcedure

Procedure TypEgal_Simple(a.i)
	Debug "Constant value: " + a
EndProcedure

Macro TypEgal(a)
	CompilerIf Defined(a, #PB_Variable)
		CompilerSelect TypeOf(a)
			CompilerCase #PB_Long
				TypEgal_Long(a)
			CompilerCase #PB_Integer
				TypEgal_Integer(a)
			CompilerCase #PB_Float
				TypEgal_Float(a)
			CompilerCase #PB_Quad
				TypEgal_Quad(a)
			CompilerCase #PB_String
				TypEgal_String(a)
		CompilerEndSelect
	CompilerElse
		;Is it a string or a float?
		TypEgal_Simple(a)
	CompilerEndIf
EndMacro

Define l.l, i.i, f.f, q.q, s.s
l = 1234
i = 5678
f = 0.1234
q = 12345678901234
s = "Test"

TypEgal(l)
TypEgal(i)
TypEgal(f)
TypEgal(q)
TypEgal(s)
TypEgal(123)
;TypEgal("asdf")	;doesn't work
;TypEgal(123.456)	;doesn't work
And is it possible to check if a given variable has a certain structure? So you can write Procedures with overloading like this.

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)	;Ist a eine Variable?
			CompilerIf Defined(b, #PB_Variable) ;Ist b eine Variable?
				CompilerIf TypeOf(b) = #PB_Structure
					CompilerIf TypeOf(a) = #PB_Structure
						Vector#opName#Vector(a, b)	;a und b sind vom Typ Vector
					CompilerElse
						Vector#opName#Skalar(b, a)	;b ist vom Typ Vector und a eine normale Variable
					CompilerEndIf
				CompilerElse
					CompilerIf TypeOf(a) = #PB_Structure
						Vector#opName#Skalar(a, b)	;a ist vom Typ Vector und b eine normale Variable
					CompilerElse
						CompilerError "VectorMul(Float, Float): Mindestens ein Parameter von VectorMul() muss ein Vector sein."
					CompilerEndIf
				CompilerEndIf
			CompilerElse
				CompilerIf TypeOf(a) = #PB_Structure
					Vector#opName#Skalar(a, b)	;a ist vom Typ Vector und b ein fester Wert
				CompilerElse
					CompilerError "VectorMul(Float, Constant): Mindestens ein Parameter von VectorMul() muss ein Vector sein."
				CompilerEndIf
			CompilerEndIf
		CompilerElse
			CompilerIf Defined(b, #PB_Variable) ;Ist b eine Variable?
				CompilerIf TypeOf(b) = #PB_Structure
					Vector#opName#Skalar(b, a)		;b ist vom Tyo Vector und a ein fester Wert
				CompilerElse
					CompilerError "VectorMul(Constant, Float): Mindestens ein Parameter von VectorMul() muss ein Vector sein."
				CompilerEndIf
			CompilerElse ;a und b sind keine Variablen -> Fehler
				CompilerError "VectorMul(Constant, Constant): Mindestens ein Parameter von VectorMul() muss ein Vector sein."
			CompilerEndIf
		CompilerEndIf
;	EndMac#MacroRo
EndMacro

VectorOp(*, Mul)
EndMacro
VectorOp(+, Add)
EndMacro
VectorOp(/, Div)
EndMacro
VectorOp(-, Sub)
EndMacro

; Ab hier gibt es jetzt folgende Procedures:
; - 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)
;
; Dank den folgenden vier weiteren Makros, braucht man sich um diese Procedures aber nicht zu kümmern:
; - 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    ;Leider gehen hier wieder keine Fließkommazahlen, sehr wohl aber Ganzzahlen
Debug "a * 4"
Debug "a = (" + a\x + ", " + a\y + ", " + a\z + ")"

;Hier noch ein paar Fehlermeldungen, auskommentieren zum Testen
;VectorAdd(3, 4)
;VectorAdd(c, c)
;VectorAdd(c, 2)
But instead of checking if the given variable has simply a structure, it were more useful to check if the type is really a 'Vector'.
Sorry for the german comments.
The english grammar is freeware, you can use it freely - But it's not Open Source, i.e. you can not change it or publish it in altered way.