changeset 3214:cd145cc2f2c9 v7.3.377

updated for version 7.3.377 Problem: No support for bitwise AND, OR, XOR and invert. Solution: Add add(), or(), invert() and xor() functions.
author Bram Moolenaar <bram@vim.org>
date Wed, 14 Dec 2011 15:32:50 +0100
parents b7b6c1ed9336
children c5e3e1e6e7b2
files runtime/doc/eval.txt src/eval.c src/testdir/test65.in src/testdir/test65.ok src/version.c
diffstat 5 files changed, 129 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- 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:
--- 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.
  */
--- 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
 
--- 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
--- 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,