Seite 2 von 2

Re: Enumeration mit 2er-Potenzen

Verfasst: 30.07.2013 16:23
von RSBasic
@c4s
Du brauchst z.B. PB 5.20, damit es funktioniert.

Re: Enumeration mit 2er-Potenzen

Verfasst: 30.07.2013 16:26
von c4s
@RSBasic
Ja, habe ich auch gerade festgestellt (siehe Edit). Bei Demivec stand aber "für 5.11"... ;)

Re: Enumeration mit 2er-Potenzen

Verfasst: 30.07.2013 16:40
von CSHW89
Ja 5.11 war leider genau die Version, in der beides nicht funktioniert hatte. Die erste nicht, weil Vergleiche nur noch mit Bool funktionierten, und die zweite nicht, weil Bool(const = const) nicht zur Compilezeit berechnet wurde, sondern erst zur Laufzeit. Somit war Bool(const = const) für den Compiler keine Konstante, und konnte deshalb auch nicht einer Konstanten zugewiesen werden.

Aber Fred hat zum Glück mein Wunsch zur 5.20 umgesetzt :D

lg Kevin

Re: Enumeration mit 2er-Potenzen

Verfasst: 18.08.2013 16:59
von Regenduft
Schöne Lösung! Ich hatte das nur mit CompilerIf hinbekommen, was allerdings den Vorteil hat, dass man sich die 1 beim Enumeration sparen kann (bzw. muss).

Code: Alles auswählen

Macro EnumFlag(Konstante)
  CompilerIf #PB_Compiler_EnumerationValue > 0 : Konstante = (#PB_Compiler_EnumerationValue-1)<<1 : CompilerElse : Konstante = 1 : CompilerEndIf
EndMacro

Enumeration
  EnumFlag(#a)
  EnumFlag(#b)
  EnumFlag(#c)
  EnumFlag(#d)
EndEnumeration

Debug #a
Debug #b
Debug #c
Debug #d
CSHW89 hat geschrieben:Aber Fred hat zum Glück mein Wunsch zur 5.20 umgesetzt :D
Was? Gibt's das jetzt nativ? Wo? Wie? Ich finde nichts... Bin ich wieder zu blind oder zu blöd zum Suchen (oder beides)? :?

Re: Enumeration mit 2er-Potenzen

Verfasst: 18.08.2013 18:13
von CSHW89
Regenduft hat geschrieben:CSHW89 hat geschrieben:
Aber Fred hat zum Glück mein Wunsch zur 5.20 umgesetzt :D
Was? Gibt's das jetzt nativ? Wo? Wie? Ich finde nichts... Bin ich wieder zu blind oder zu blöd zum Suchen (oder beides)? :?
Es ging um das Auswerten von Bool() zur Compilezeit. Soetwas hatte vor 5.20 nicht funktioniert:

Code: Alles auswählen

#const = Bool(#c1 = #c2)
Ich benutze halt diese Variante, die in der Zeit zwischen PB 5.10 und PB 5.20 nicht funktionierte:

Code: Alles auswählen

Macro enum2pow(_const_)
  _const_ = (Bool(#PB_Compiler_EnumerationValue=1) + Bool(#PB_Compiler_EnumerationValue>1) * ((#PB_Compiler_EnumerationValue-1)<<1))
EndMacro
Mir war vor allem wichtig, dass die Zeilen zwischen Enumerate/EndEnumerate gleich aussehen. Das man also für die erste Konstante keine andere Form wählen muss.

Aber das mit dem CompileIf ist natürlich auch ne gute Idee. Hätte ich mal vorher drauf kommen sollen :D

lg Kevin

Re: Enumeration mit 2er-Potenzen

Verfasst: 18.08.2013 18:43
von Regenduft
Achso, dann hatte ich das falsch verstanden.

Bei meiner ersten Lösung hatte ich mir auch total das Hirn zermartert! Am Ende, als ich die einfachere Lösung fand, sah das so einfach aus, dass ich mich gar nicht getraut hatte es zu posten.

Es folgt mein erster Versuch... total umständlich... aber es funktioniert... halbwegs... :lol:
Zwischen "DoFlagging" dürfen keine Leerzeilen stehen. Ist ein gutes Beispiel, dass man nicht krampfhaft an einem Lösungsansatz festhalten sollte! Ich hatte da vermutlich mehr Zeit hinein gesteckt wie in alle manuellen "Flaggereien" zusammen. Ist wirklich ziemlich alt... Es darf gelacht werden!

Code: Alles auswählen

;{ Flagging-Makros
  Macro FlaggingQuote
    "
  EndMacro
  Macro StartFlagging(EnumerationName, Bytes = 0)
    CompilerIf Defined(StartFlagging_#EnumerationName, #PB_Constant)
      CompilerError "Flagging-Name bereits vergeben: "+FlaggingQuote#EnumerationName#FlaggingQuote
    CompilerEndIf
    CompilerIf Bytes > 0
      #FlagBytes_#EnumerationName = Bytes
      #FlagBytes_#EnumerationName$ = FlaggingQuote#Bytes#FlaggingQuote
    CompilerEndIf
    #StartFlagging_#EnumerationName = #PB_Compiler_Line + 1
  EndMacro
  Macro DoFlagging(EnumerationName, FlagName)
    CompilerIf Defined(StartFlagging_#EnumerationName, #PB_Constant) = 0
      CompilerError "StartFlagging fehlt: "+FlaggingQuote#EnumerationName#FlaggingQuote
    CompilerEndIf
    CompilerIf Defined(StopFlagging_#EnumerationName, #PB_Constant)
      CompilerError "Flagging bereits gestoppt: "+FlaggingQuote#EnumerationName#FlaggingQuote
    CompilerEndIf
    CompilerIf Defined(Flag_#EnumerationName#_#FlagName, #PB_Constant)
      CompilerError "Flag existiert bereits: "+FlaggingQuote#EnumerationName#FlaggingQuote
    CompilerEndIf
    ;===============================================================================================
    #Flag_#EnumerationName#_#FlagName = 1 << ( #PB_Compiler_Line - #StartFlagging_#EnumerationName )
    ;===============================================================================================
    CompilerIf Defined(FlagBytes_#EnumerationName, #PB_Constant)
      CompilerIf #Flag_#EnumerationName#_#FlagName > 1 << ( #FlagBytes_#EnumerationName << 3 - 1)
        CompilerError "Flagging auf "+#FlagBytes_#EnumerationName$+" Byte begrenzt"
      CompilerEndIf
    CompilerEndIf
  EndMacro
  Macro StopFlagging(EnumerationName)
    CompilerIf Defined(StartFlagging_#EnumerationName, #PB_Constant) = 0
      CompilerError "StartFlagging fehlt: "+FlaggingQuote#EnumerationName#FlaggingQuote
    CompilerEndIf
    CompilerIf #StartFlagging_#EnumerationName = #PB_Compiler_Line
      CompilerError "leerer Flagging-Block: "+FlaggingQuote#EnumerationName#FlaggingQuote
    CompilerEndIf
    CompilerIf Defined(StopFlagging_#EnumerationName, #PB_Constant)
      CompilerError "Flagging bereits gestoppt: "+FlaggingQuote#EnumerationName#FlaggingQuote
    CompilerEndIf
    #StopFlagging_#EnumerationName = #PB_Compiler_Line - #StartFlagging_#EnumerationName
  EndMacro
;} Ende Flagging-Makros

StartFlagging(Foo)
  DoFlagging(Foo, a)
  DoFlagging(Foo, b)
  DoFlagging(Foo, c)
  DoFlagging(Foo, d)
StopFlagging(Foo)

Debug #Flag_Foo_a
Debug #Flag_Foo_b
Debug #Flag_Foo_c
Debug #Flag_Foo_d