Author Topic: Ternary operator considered harmful?  (Read 755 times)

jj2007

  • Member
  • *****
  • Posts: 7558
  • Assembler is fun ;-)
    • MasmBasic
Ternary operator considered harmful?
« on: May 27, 2015, 09:02:05 AM »
Ternary operator considered harmful?

Maybe. But it can also save quite some bytes, if the affected argument happens to be inside a complex function:

.if FileSave$("Plain Masm32=*.asm|MasmBasic=*.asc|All files=*.*")
     FileWrite FileSave$(), stream:hMyEdit, If?(InstrOr(FileSave$(), ".rtf" or ".asc", 1), SF_RTF, SF_TEXT)
.endif


Some tests - let me know if something is missing or wrong:
Code: [Select]
include \masm32\MasmBasic\MasmBasic.inc
  SetGlobals x100=100
  Init
  PrintLine "Testing the ternary operator function If?(cmpargs, result_true, result_false):"
  PrintLine "(111=True, 222=False)"
  mov ecx, 123
  mov edi, ecx ; OK
  Print Str$("\necx=%i:\n", ecx)
  Print Str$("ecx eq 123: %i\n", If?(ecx eq edi, 111, 222))
  Print Str$("ecx eq 100: %i\n", If?(ecx eq x100, 111, 222))
  Print Str$("ecx ne 123: %i\n", If?(ecx ne edi, 111, 222))
  Print Str$("ecx ne 100: %i\n", If?(ecx ne x100, 111, 222))
  Print Str$("ecx ge 123: %i\n", If?(ecx ge edi, 111, 222))
  Print Str$("ecx gt 123: %i\n", If?(ecx gt edi, 111, 222))
  Print Str$("ecx above 123: %i\n", If?(ecx ab edi, 111, 222))
  Print Str$("ecx below 124: %i\n", If?(ecx bl 124, 111, 222))
  PrintLine "ecx above 123: ", If?(ecx ab 123, "above", "not above") ; string output
  PrintLine "ecx below 123: ", If?(ecx bl 123, "below", "not below")
  PrintLine "ecx ge 123: ", If?(ecx ge 123, "greater or equal", "not greater or equal") ; string output
  PrintLine "ecx gt 123: ", If?(ecx gt 123, "greater", "not greater")

  mov ecx, -123
  Print Str$("\necx=%i:\n", ecx)
  Print Str$("ecx eq 123: %i\n", If?(ecx eq edi, 111, 222))
  Print Str$("ecx eq 100: %i\n", If?(ecx eq x100, 111, 222))
  Print Str$("ecx ne 123: %i\n", If?(ecx ne edi, 111, 222))
  Print Str$("ecx ne 100: %i\n", If?(ecx ne x100, 111, 222))
  Print Str$("ecx ge 123: %i\n", If?(ecx ge edi, 111, 222))
  Print Str$("ecx gt 123: %i\n", If?(ecx gt edi, 111, 222))
  Print Str$("ecx above 123: %i\n", If?(ecx ab edi, 111, 222))
  Print Str$("ecx below 124: %i\n", If?(ecx bl 124, 111, 222))
  PrintLine "ecx above 123: ", If?(ecx ab 123, "above", "not above") ; string output
  PrintLine "ecx below 123: ", If?(ecx bl 123, "below", "not below")
  PrintLine "ecx ge 123: ", If?(ecx ge 123, "greater or equal", "not greater or equal") ; string output
  PrintLine "ecx gt 123: ", If?(ecx gt 123, "greater", "not greater")

  Exit
end start

Output:
Code: [Select]
Testing the ternary operator function If?(cmpargs, result_true, result_false):
(111=True, 222=False)

ecx=123:
ecx eq 123: 111
ecx eq 100: 222
ecx ne 123: 222
ecx ne 100: 111
ecx ge 123: 111
ecx gt 123: 222
ecx above 123: 222
ecx below 124: 111
ecx above 123: not above
ecx below 123: not below
ecx ge 123: greater or equal
ecx gt 123: not greater

ecx=-123:
ecx eq 123: 222
ecx eq 100: 222
ecx ne 123: 111
ecx ne 100: 111
ecx ge 123: 222
ecx gt 123: 222
ecx above 123: 111
ecx below 124: 222
ecx above 123: above
ecx below 123: not below
ecx ge 123: not greater or equal
ecx gt 123: not greater

Requires MasmBasic of 27 May 2015. From the help file (\Masm32\MasmBasic\MbGuide.rtf):
If?      ; ternary operator
      Syntax: mov eax, If?(comparison, result_true, result_false)
      mov ecx, 123
      mov edi, ecx
      Print Str$("ecx eq 123: %i\n", If?(ecx eq edi, 111, 222))                              ; if ecx equals edi, take 111, otherwise 222
      Print Str$("ecx ne 123: %i\n", If?(ecx ne 123, 111, 222))
      PrintLine "ecx above 123: ", If?(ecx ab 123, "above", "not above")                  ; unsigned comparison, string output
      PrintLine "ecx below 123: ", If?(ecx bl 123, "below", "not below")
      PrintLine "ecx ge 123: ", If?(ecx ge 123, "greater or equal", "not greater or equal")      ; signed comparison, string output
      PrintLine "ecx gt 123: ", If?(ecx gt 123, "greater", "not greater")
      .if FileSave$("Plain Asm=*.asm|MasmBasic=*.asc||Rich text=*.rtf|All files=*.*")            ; saves quite some bytes with complex functions
            FileWrite FileSave$(), stream:hMyEdit, If?(InstrOr(FileSave$(), ".rtf" or ".asc", 1), SF_RTF, SF_TEXT)      ; choose the right format
      .endif
Rem      - the comparison follows the macro syntax, with some deviations (in red) for technical reasons:
        - eq=equal, ne=not equal
        - ab=above, ae=above or equal      (unsigned)
        - bl=below, be=below or equal
        - gt=greater, ge=greater or equal      (signed)
        - lt=less than, le=less or equal
      - if one of the options is "quoted text", strings will be returned, otherwise integer