# HG changeset patch # User Bram Moolenaar # Date 1323873170 -3600 # Node ID cd145cc2f2c918b9fd77dc177f69805c77e31e41 # Parent b7b6c1ed933651e3f63e785c4f8fe13d01cea9da updated for version 7.3.377 Problem: No support for bitwise AND, OR, XOR and invert. Solution: Add add(), or(), invert() and xor() functions. diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -801,11 +801,12 @@ expr6 . expr6 .. String concatenation For |Lists| only "+" is possible and then both expr6 must be a list. The result is a new list with the two lists Concatenated. -expr7 * expr7 .. number multiplication *expr-star* -expr7 / expr7 .. number division *expr-/* -expr7 % expr7 .. number modulo *expr-%* +expr7 * expr7 .. Number multiplication *expr-star* +expr7 / expr7 .. Number division *expr-/* +expr7 % expr7 .. Number modulo *expr-%* For all, except ".", Strings are converted to Numbers. +For bitwise operators see |and()|, |or()| and |xor()|. Note the difference between "+" and ".": "123" + "456" = 579 @@ -1687,6 +1688,7 @@ USAGE RESULT DESCRIPTION ~ abs( {expr}) Float or Number absolute value of {expr} acos( {expr}) Float arc cosine of {expr} add( {list}, {item}) List append {item} to |List| {list} +and( {expr}, {expr}) Number bitwise AND append( {lnum}, {string}) Number append {string} below line {lnum} append( {lnum}, {list}) Number append lines {list} below line {lnum} argc() Number number of files in the argument list @@ -1825,6 +1827,7 @@ inputrestore() Number restore typeahea inputsave() Number save and clear typeahead inputsecret( {prompt} [, {text}]) String like input() but hiding the text insert( {list}, {item} [, {idx}]) List insert {item} in {list} [before {idx}] +invert( {expr}) Number bitwise invert isdirectory( {directory}) Number TRUE if {directory} is a directory islocked( {expr}) Number TRUE if {expr} is locked items( {dict}) List key-value pairs in {dict} @@ -1864,6 +1867,7 @@ mode( [expr]) String current editing m mzeval( {expr}) any evaluate |MzScheme| expression nextnonblank( {lnum}) Number line nr of non-blank line >= {lnum} nr2char( {expr}) String single char with ASCII value {expr} +or( {expr}, {expr}) Number bitwise OR pathshorten( {expr}) String shorten directory names in a path pow( {x}, {y}) Float {x} to the power of {y} prevnonblank( {lnum}) Number line nr of non-blank line <= {lnum} @@ -1987,6 +1991,7 @@ winsaveview() Dict save view of curren winwidth( {nr}) Number width of window {nr} writefile( {list}, {fname} [, {binary}]) Number write list of lines to file {fname} +xor( {expr}, {expr}) Number bitwise XOR abs({expr}) *abs()* Return the absolute value of {expr}. When {expr} evaluates to @@ -2026,6 +2031,13 @@ add({list}, {expr}) *add()* Use |insert()| to add an item at another position. +and({expr}, {expr}) *and()* + Bitwise AND on the two arguments. The arguments are converted + to a number. A List, Dict or Float argument causes an error. + Example: > + :let flag = and(bits, 0x80) + + append({lnum}, {expr}) *append()* When {expr} is a |List|: Append each item of the |List| as a text line below line {lnum} in the current buffer. @@ -3782,6 +3794,11 @@ insert({list}, {item} [, {idx}]) *inse Note that when {item} is a |List| it is inserted as a single item. Use |extend()| to concatenate |Lists|. +invert({expr}) *invert()* + Bitwise invert. The argument is converted to a number. A + List, Dict or Float argument causes an error. Example: > + :let bits = invert(bits) + isdirectory({directory}) *isdirectory()* The result is a Number, which is non-zero when a directory with the name {directory} exists. If {directory} doesn't @@ -4347,6 +4364,13 @@ getpos({expr}) Get the position for {exp call setpos('.', save_cursor) < Also see |setpos()|. +or({expr}, {expr}) *or()* + Bitwise OR on the two arguments. The arguments are converted + to a number. A List, Dict or Float argument causes an error. + Example: > + :let bits = or(bits, 0x80) + + pathshorten({expr}) *pathshorten()* Shorten directory names in the path {expr} and return the result. The tail, the file name, is kept as-is. The other @@ -6121,7 +6145,15 @@ writefile({list}, {fname} [, {binary}]) To copy a file byte for byte: > :let fl = readfile("foo", "b") :call writefile(fl, "foocopy", "b") -< + + +xor({expr}, {expr}) *xor()* + Bitwise XOR on the two arguments. The arguments are converted + to a number. A List, Dict or Float argument causes an error. + Example: > + :let bits = xor(bits, 0x80) + + *feature-list* There are three types of features: diff --git a/src/eval.c b/src/eval.c --- a/src/eval.c +++ b/src/eval.c @@ -474,6 +474,7 @@ static void f_abs __ARGS((typval_T *argv static void f_acos __ARGS((typval_T *argvars, typval_T *rettv)); #endif static void f_add __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_and __ARGS((typval_T *argvars, typval_T *rettv)); static void f_append __ARGS((typval_T *argvars, typval_T *rettv)); static void f_argc __ARGS((typval_T *argvars, typval_T *rettv)); static void f_argidx __ARGS((typval_T *argvars, typval_T *rettv)); @@ -602,6 +603,7 @@ static void f_inputrestore __ARGS((typva static void f_inputsave __ARGS((typval_T *argvars, typval_T *rettv)); static void f_inputsecret __ARGS((typval_T *argvars, typval_T *rettv)); static void f_insert __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_invert __ARGS((typval_T *argvars, typval_T *rettv)); static void f_isdirectory __ARGS((typval_T *argvars, typval_T *rettv)); static void f_islocked __ARGS((typval_T *argvars, typval_T *rettv)); static void f_items __ARGS((typval_T *argvars, typval_T *rettv)); @@ -640,6 +642,7 @@ static void f_mzeval __ARGS((typval_T *a #endif static void f_nextnonblank __ARGS((typval_T *argvars, typval_T *rettv)); static void f_nr2char __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_or __ARGS((typval_T *argvars, typval_T *rettv)); static void f_pathshorten __ARGS((typval_T *argvars, typval_T *rettv)); #ifdef FEAT_FLOAT static void f_pow __ARGS((typval_T *argvars, typval_T *rettv)); @@ -751,6 +754,7 @@ static void f_winrestview __ARGS((typval static void f_winsaveview __ARGS((typval_T *argvars, typval_T *rettv)); static void f_winwidth __ARGS((typval_T *argvars, typval_T *rettv)); static void f_writefile __ARGS((typval_T *argvars, typval_T *rettv)); +static void f_xor __ARGS((typval_T *argvars, typval_T *rettv)); static int list2fpos __ARGS((typval_T *arg, pos_T *posp, int *fnump)); static pos_T *var2fpos __ARGS((typval_T *varp, int dollar_lnum, int *fnum)); @@ -7715,6 +7719,7 @@ static struct fst {"acos", 1, 1, f_acos}, /* WJMc */ #endif {"add", 2, 2, f_add}, + {"and", 2, 2, f_and}, {"append", 2, 2, f_append}, {"argc", 0, 0, f_argc}, {"argidx", 0, 0, f_argidx}, @@ -7850,6 +7855,7 @@ static struct fst {"inputsave", 0, 0, f_inputsave}, {"inputsecret", 1, 2, f_inputsecret}, {"insert", 2, 3, f_insert}, + {"invert", 1, 1, f_invert}, {"isdirectory", 1, 1, f_isdirectory}, {"islocked", 1, 1, f_islocked}, {"items", 1, 1, f_items}, @@ -7888,6 +7894,7 @@ static struct fst #endif {"nextnonblank", 1, 1, f_nextnonblank}, {"nr2char", 1, 1, f_nr2char}, + {"or", 2, 2, f_or}, {"pathshorten", 1, 1, f_pathshorten}, #ifdef FEAT_FLOAT {"pow", 2, 2, f_pow}, @@ -7999,6 +8006,7 @@ static struct fst {"winsaveview", 0, 0, f_winsaveview}, {"winwidth", 1, 1, f_winwidth}, {"writefile", 2, 3, f_writefile}, + {"xor", 2, 2, f_xor}, }; #if defined(FEAT_CMDL_COMPL) || defined(PROTO) @@ -8572,6 +8580,18 @@ f_add(argvars, rettv) } /* + * "and(expr, expr)" function + */ + static void +f_and(argvars, rettv) + typval_T *argvars; + typval_T *rettv; +{ + rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL) + & get_tv_number_chk(&argvars[1], NULL); +} + +/* * "append(lnum, string/list)" function */ static void @@ -12958,6 +12978,17 @@ f_insert(argvars, rettv) } /* + * "invert(expr)" function + */ + static void +f_invert(argvars, rettv) + typval_T *argvars; + typval_T *rettv; +{ + rettv->vval.v_number = ~get_tv_number_chk(&argvars[0], NULL); +} + +/* * "isdirectory()" function */ static void @@ -14108,6 +14139,18 @@ f_nr2char(argvars, rettv) } /* + * "or(expr, expr)" function + */ + static void +f_or(argvars, rettv) + typval_T *argvars; + typval_T *rettv; +{ + rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL) + | get_tv_number_chk(&argvars[1], NULL); +} + +/* * "pathshorten()" function */ static void @@ -18394,6 +18437,19 @@ f_writefile(argvars, rettv) } /* + * "xor(expr, expr)" function + */ + static void +f_xor(argvars, rettv) + typval_T *argvars; + typval_T *rettv; +{ + rettv->vval.v_number = get_tv_number_chk(&argvars[0], NULL) + ^ get_tv_number_chk(&argvars[1], NULL); +} + + +/* * Translate a String variable into a position. * Returns NULL when there is an error. */ diff --git a/src/testdir/test65.in b/src/testdir/test65.in --- a/src/testdir/test65.in +++ b/src/testdir/test65.in @@ -1,4 +1,4 @@ -Test for floating point. +Test for floating point and logical operators. STARTTEST :so small.vim @@ -72,6 +72,23 @@ STARTTEST :$put ='float2nr' :$put =float2nr(123.456) :$put =float2nr(-123.456) +:$put ='AND' +:$put =and(127, 127) +:$put =and(127, 16) +:$put =and(127, 128) +:$put ='OR' +:$put =or(16, 7) +:$put =or(8, 7) +:$put =or(0, 123) +:$put ='XOR' +:$put =xor(127, 127) +:$put =xor(127, 16) +:$put =xor(127, 128) +:$put ='invert' +:$put =and(invert(127), 65535) +:$put =and(invert(16), 65535) +:$put =and(invert(128), 65535) +:$put =invert(1.0) :/^Results/,$wq! test.out ENDTEST diff --git a/src/testdir/test65.ok b/src/testdir/test65.ok --- a/src/testdir/test65.ok +++ b/src/testdir/test65.ok @@ -54,3 +54,20 @@ 4.0 float2nr 123 -123 +AND +127 +16 +0 +OR +23 +15 +123 +XOR +0 +111 +255 +invert +65408 +65519 +65407 +0 diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -715,6 +715,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 377, +/**/ 376, /**/ 375,