From 99235da725b345c3c3ecc53a33e487436df3dcee Mon Sep 17 00:00:00 2001 From: anders_k Date: Sun, 8 Oct 2017 15:26:54 +0000 Subject: [PATCH] Added IntOp and System::Int64Op >>> SHR operator git-svn-id: https://svn.code.sf.net/p/nsis/code/NSIS/trunk@6926 212acab6-be3b-0410-9dea-997c60f758d6 --- Contrib/System/Source/System.c | 2 +- Contrib/System/System.html | 11 ++++++++++- Docs/src/history.but | 2 ++ Docs/src/int.but | 6 ++++-- Include/Win/WinDef.nsh | 3 +-- Source/exehead/exec.c | 1 + Source/exehead/fileform.h | 2 +- Source/script.cpp | 11 ++++------- Source/tokens.cpp | 2 +- 9 files changed, 25 insertions(+), 15 deletions(-) diff --git a/Contrib/System/Source/System.c b/Contrib/System/Source/System.c index 6d612255..b62e2ee2 100644 --- a/Contrib/System/Source/System.c +++ b/Contrib/System/Source/System.c @@ -402,7 +402,7 @@ PLUGINFUNCTIONSHORT(Int64Op) case _T('~'): i1 = ~i1; break; case _T('!'): i1 = !i1; break; case _T('<'): if (op[1] == _T('<')) i1 = i1 << i2; else i1 = i1 < i2; break; - case _T('>'): if (op[1] == _T('>')) i1 = i1 >> i2; else i1 = i1 > i2; break; + case _T('>'): if (op[1] == _T('>')) i1 = op[2] == _T('>') ? (UINT64)i1 >> (UINT64)i2 : i1 >> i2; else i1 = i1 > i2; break; case _T('='): i1 = (i1 == i2); break; } diff --git a/Contrib/System/System.html b/Contrib/System/System.html index 19bb8d48..78380992 100644 --- a/Contrib/System/System.html +++ b/Contrib/System/System.html @@ -595,8 +595,9 @@ good:
  • Multiplication -- *
  • Division -- /
  • Modulo -- %
  • -
  • Shift right -- >>
  • Shift left -- <<
  • +
  • Arithmetic shift right -- >>
  • +
  • Logical shift right -- >>>
  • Bitwise or -- |
  • Bitwise and -- &
  • Bitwise xor -- ^
  • @@ -645,6 +646,14 @@ DetailPrint "1 << 62 = $0" # 4611686018427387904 System::Int64Op 0x4000000000000000 >> 62 Pop $0 DetailPrint "0x4000000000000000 >> 62 = $0" # 1 + +System::Int64Op 0x8000000000000000 >> 1 +Pop $0 +DetailPrint "0x8000000000000000 >> 1 = $0" # -4611686018427387904 (0xC000000000000000) + +System::Int64Op 0x8000000000000000 >>> 1 +Pop $0 +DetailPrint "0x8000000000000000 >>> 1 = $0" # 4611686018427387904 (0x4000000000000000)
     System::Int64Op 0xF0F0F0F | 0xF0F0FFF
    diff --git a/Docs/src/history.but b/Docs/src/history.but
    index eed433b2..33528ebf 100644
    --- a/Docs/src/history.but
    +++ b/Docs/src/history.but
    @@ -20,6 +20,8 @@ Released on ??? ??rd, 20??
     
     \S2{} Minor Changes
     
    +\b Added IntOp and System::Int64Op >>> operator
    +
     \b Removed unused NSD_LB_Clear macro parameter
     
     \S2{} Build System
    diff --git a/Docs/src/int.but b/Docs/src/int.but
    index 4e70dedc..19a2d3b5 100644
    --- a/Docs/src/int.but
    +++ b/Docs/src/int.but
    @@ -31,10 +31,12 @@ Combines value1 and (depending on OP) value2 into the specified user variable (\
     
     \b \e{^} BINARY XORs value1 and value2
     
    -\b \e{>>} RIGHT SHIFTs value1 by value2
    -
     \b \e{<<} LEFT SHIFTs value1 by value2
     
    +\b \e{>>} ARITHMETIC RIGHT SHIFTs value1 by value2
    +
    +\b \e{>>>} LOGICALLY RIGHT SHIFTs value1 by value2
    +
     \b \e{~} BITWISE NEGATEs value1 (i.e. 7 becomes 4294967288)
     
     \b \e{!} LOGICALLY NEGATEs value1 (i.e. 7 becomes 0)
    diff --git a/Include/Win/WinDef.nsh b/Include/Win/WinDef.nsh
    index cf84ee4f..a91d6856 100644
    --- a/Include/Win/WinDef.nsh
    +++ b/Include/Win/WinDef.nsh
    @@ -39,8 +39,7 @@ IntOp ${_outvar} "${_in}" & 0xFFFF
     !define LOWORD "!insertmacro _Win_LOWORD "
     
     !macro _Win_HIWORD _outvar _in
    -IntOp ${_outvar} "${_in}" >> 16 ;sign extended :(
    -${LOWORD} ${_outvar} ${_outvar} ;make sure we strip off the upper word
    +IntOp ${_outvar} "${_in}" >>> 16
     !macroend
     !define HIWORD "!insertmacro _Win_HIWORD "
     
    diff --git a/Source/exehead/exec.c b/Source/exehead/exec.c
    index 86fed6f7..53b1a199 100644
    --- a/Source/exehead/exec.c
    +++ b/Source/exehead/exec.c
    @@ -719,6 +719,7 @@ static int NSISCALL ExecuteEntry(entry *entry_)
               case 10: if (v2) v%=v2; else { v=0; exec_error++; } break;
               case 11: v=v<>v2; break;
    +          case 13: v=(unsigned int)v>>(unsigned int)v2; break;
             }
             myitoa(p,v);
           }
    diff --git a/Source/exehead/fileform.h b/Source/exehead/fileform.h
    index 87105a3c..7e748845 100644
    --- a/Source/exehead/fileform.h
    +++ b/Source/exehead/fileform.h
    @@ -97,7 +97,7 @@ enum
     #endif
     #ifdef NSIS_SUPPORT_INTOPTS
       EW_INTCMP,            // IntCmp: 6 [val1, val2, equal, val1val2, unsigned?]
    -  EW_INTOP,             // IntOp: 4 [output, input1, input2, op] where op: 0=add, 1=sub, 2=mul, 3=div, 4=bor, 5=band, 6=bxor, 7=bnot input1, 8=lnot input1, 9=lor, 10=land], 11=1%2
    +  EW_INTOP,             // IntOp: 4 [output, input1, input2, op] where op: 0=add, 1=sub, 2=mul, 3=div, 4=bor, 5=band, 6=bxor, 7=bnot input1, 8=lor, 9=land 10=mod, 11=shl, 12=sar, 13=shr (bneg is implemented with bxor in compiler)
       EW_INTFMT,            // IntFmt: [output, format, input]
     #endif
     #ifdef NSIS_SUPPORT_STACK
    diff --git a/Source/script.cpp b/Source/script.cpp
    index 5a9ee0a4..6a6c3e94 100644
    --- a/Source/script.cpp
    +++ b/Source/script.cpp
    @@ -4125,16 +4125,13 @@ int CEXEBuild::doCommand(int which_token, LineParser &line)
         case TOK_INTOP:
           ent.which=EW_INTOP;
           ent.offsets[0]=GetUserVarIndex(line, 1);
    -      ent.offsets[3]=line.gettoken_enum(3,_T("+\0-\0*\0/\0|\0&\0^\0!\0||\0&&\0%\0<<\0>>\0~\0"));
    +      ent.offsets[3]=line.gettoken_enum(3,_T("+\0-\0*\0/\0|\0&\0^\0!\0||\0&&\0%\0<<\0>>\0>>>\0~\0"));
           if (ent.offsets[0] < 0 || ent.offsets[3] < 0 ||
    -        ((ent.offsets[3] == 7 || ent.offsets[3] == 13) && line.getnumtokens() > 4))
    +        ((ent.offsets[3] == 7 || ent.offsets[3] == 14) && line.getnumtokens() > 4))
             PRINTHELP()
           ent.offsets[1]=add_string(line.gettoken_str(2));
    -      if (ent.offsets[3] != 7 && ent.offsets[3] != 13) ent.offsets[2]=add_string(line.gettoken_str(4));
    -      if (ent.offsets[3] == 13) {
    -        ent.offsets[3]=6;
    -        ent.offsets[2]=add_asciistring(_T("0xFFFFFFFF"));
    -      }
    +      if (ent.offsets[3] != 7 && ent.offsets[3] != 14) ent.offsets[2]=add_string(line.gettoken_str(4));
    +      if (ent.offsets[3] == 14) ent.offsets[2]=add_asciistring(_T("0xFFFFFFFF")), ent.offsets[3]=6; // ~ using ^
           SCRIPT_MSG(_T("IntOp: %") NPRIs _T("=%") NPRIs _T("%") NPRIs _T("%") NPRIs _T("\n"),line.gettoken_str(1),line.gettoken_str(2),line.gettoken_str(3),line.gettoken_str(4));
         return add_entry(&ent);
         case TOK_INTFMT:
    diff --git a/Source/tokens.cpp b/Source/tokens.cpp
    index 6df45be4..ae3c27c4 100644
    --- a/Source/tokens.cpp
    +++ b/Source/tokens.cpp
    @@ -122,7 +122,7 @@ static tokenType tokenlist[TOK__LAST] =
     {TOK_INSTDIR,_T("InstallDir"),1,0,_T("default_install_directory"),TP_GLOBAL},
     {TOK_INSTPROGRESSFLAGS,_T("InstProgressFlags"),0,-1,_T("[flag [...]]\n    flag={smooth|colored}"),TP_GLOBAL},
     {TOK_INSTTYPE,_T("InstType"),1,0,_T("[un.]install_type_name | /NOCUSTOM | /CUSTOMSTRING=str | /COMPONENTSONLYONCUSTOM"),TP_GLOBAL},
    -{TOK_INTOP,_T("IntOp"),3,1,_T("$(user_var: result) val1 OP [val2]\n    OP=(+ - * / % | & ^ ~ ! || && << >>)"),TP_CODE},
    +{TOK_INTOP,_T("IntOp"),3,1,_T("$(user_var: result) val1 OP [val2]\n    OP=(+ - * / % | & ^ ~ ! || && << >> >>>)"),TP_CODE},
     {TOK_INTCMP,_T("IntCmp"),3,2,_T("val1 val2 jump_if_equal [jump_if_val1_less] [jump_if_val1_more]"),TP_CODE},
     {TOK_INTCMPU,_T("IntCmpU"),3,2,_T("val1 val2 jump_if_equal [jump_if_val1_less] [jump_if_val1_more]"),TP_CODE},
     {TOK_INTFMT,_T("IntFmt"),3,0,_T("$(user_var: output) format_string input"),TP_CODE},