pike.git
/
src
/
operators.c
version
»
Context lines:
10
20
40
80
file
none
3
pike.git/src/operators.c:1:
/* || This file is part of Pike. For copyright information see COPYRIGHT. || Pike is distributed under GPL, LGPL and MPL. See the file COPYING || for more information.
-
|| $Id: operators.c,v 1.
180
2003/11/10 01:
19
:
51
mast Exp $
+
|| $Id: operators.c,v 1.
181
2003/11/10 01:
42
:
32
mast Exp $
*/ #include "global.h" #include <math.h>
-
RCSID("$Id: operators.c,v 1.
180
2003/11/10 01:
19
:
51
mast Exp $");
+
RCSID("$Id: operators.c,v 1.
181
2003/11/10 01:
42
:
32
mast Exp $");
#include "interpret.h" #include "svalue.h" #include "multiset.h" #include "mapping.h" #include "array.h" #include "stralloc.h" #include "opcodes.h" #include "operators.h" #include "language.h" #include "pike_memory.h"
pike.git/src/operators.c:55:
for(i=1;i<args;i++) \ if(! ( FUN (sp-args+i-1, sp-args+i))) \ break; \ pop_n_elems(args); \ push_int(i==args); \ } \ } /*! @decl int(0..1) `!=(mixed arg1, mixed arg2, mixed ... extras) *!
-
*! Inequality
operator
.
+
*! Inequality
test
.
*!
-
*!
@returns
-
*!
Returns
@expr{0@}
(zero)
if
all
the
arguments
are equal, and
-
*!
@expr{1@} otherwise
.
+
*!
Every expression with the @expr{!=@} operator becomes a call to
+
*!
this
function,
i.e.
@expr{a!=b@}
is
the
same
as
+
*!
@expr{predef::`!=(a,b)@}
.
*!
-
*! This is the inverse of @[`==()].
+
*! This is the inverse of @[`==()]
; see that function for further
+
*! details
.
*!
-
+
*! @returns
+
*! Returns @expr{1@} if the test is successful, @expr{0@}
+
*! otherwise.
+
*!
*! @seealso *! @[`==()] */ PMOD_EXPORT void f_ne(INT32 args) { f_eq(args); o_not(); } /*! @decl int(0..1) `==(mixed arg1, mixed arg2, mixed ... extras) *!
-
*! Equality
operator
.
+
*! Equality
test
.
*!
-
+
*! Every expression with the @expr{==@} operator becomes a call to
+
*! this function, i.e. @expr{a==b@} is the same as
+
*! @expr{predef::`==(a,b)@}.
+
*!
+
*! If more than two arguments are given, each argument is compared
+
*! with the following one as described below, and the test is
+
*! successful iff all comparisons are successful.
+
*!
+
*! If the first argument is an object with an @[lfun::`==()], that
+
*! function is called with the second as argument, and the test is
+
*! successful iff its result is nonzero (according to @[`!]).
+
*!
+
*! Otherwise, if the second argument is an object with an
+
*! @[lfun::`==()], that function is called with the first as
+
*! argument, and the test is successful iff its result is nonzero
+
*! (according to @[`!]).
+
*!
+
*! Otherwise, if the arguments are of different types, the test is
+
*! unsuccessful. Function pointers to programs are automatically
+
*! converted to program pointers if necessary, though.
+
*!
+
*! Otherwise the test depends on the type of the arguments:
+
*! @mixed
+
*! @type int
+
*! Successful iff the two integers are numerically equal.
+
*! @type float
+
*! Successful iff the two floats are numerically equal or if
+
*! both are NaN.
+
*! @type string
+
*! Successful iff the two strings are identical, character for
+
*! character. (Since all strings are kept unique, this is
+
*! actually a test whether the arguments point to the same
+
*! string, and it therefore run in constant time.)
+
*! @type array|mapping|multiset|object|function|program|type
+
*! Successful iff the two arguments point to the same instance.
+
*! @endmixed
+
*!
*! @returns
-
*! Returns @expr{1@} if
all
the
arguments
are
equal
,
and
-
*!
@expr{0@} (zero)
otherwise.
+
*! Returns @expr{1@} if the
test
is
successful
,
@expr{0@}
+
*! otherwise.
*!
-
+
*! @note
+
*! Floats and integers are not automatically converted to test
+
*! against each other, so e.g. @expr{0==0.0@} is false.
+
*!
+
*! @note
+
*! Programs are not automatically converted to types to be compared
+
*! type-wise.
+
*!
*! @seealso
-
*! @[`!=()]
+
*! @[`!
()], @[`!
=()]
*/ COMPARISON(f_eq,"`==", is_eq) /*! @decl int(0..1) `<(mixed arg1, mixed arg2, mixed ... extras) *!
-
*! Less than
operator
.
+
*! Less than
test
.
*!
-
+
*! Every expression with the @expr{<@} operator becomes a call to
+
*! this function, i.e. @expr{a<b@} is the same as
+
*! @expr{predef::`<(a,b)@}.
+
*!
*! @returns
-
*! Returns @expr{1@} if the
arguments
are
strictly increasing
,
and
-
*!
@expr{0@} (zero)
otherwise.
+
*! Returns @expr{1@} if the
test
is
successful
,
@expr{0@}
+
*! otherwise.
*! *! @seealso *! @[`<=()], @[`>()], @[`>=()] */ COMPARISON(f_lt,"`<" , is_lt) /*! @decl int(0..1) `<=(mixed arg1, mixed arg2, mixed ... extras) *!
-
*! Less or equal
operator
.
+
*! Less
than
or equal
test
.
*!
-
+
*! Every expression with the @expr{<=@} operator becomes a call to
+
*! this function, i.e. @expr{a<=b@} is the same as
+
*! @expr{predef::`<=(a,b)@}.
+
*!
*! @returns *! Returns @expr{1@} if the arguments are not strictly decreasing, and *! @expr{0@} (zero) otherwise. *! *! This is the inverse of @[`>()]. *! *! @seealso *! @[`<()], @[`>()], @[`>=()] */ COMPARISON(f_le,"`<=",!is_gt) /*! @decl int(0..1) `>(mixed arg1, mixed arg2, mixed ... extras) *!
-
*! Greater than
operator
.
+
*! Greater than
test
.
*!
-
+
*! Every expression with the @expr{>@} operator becomes a call to
+
*! this function, i.e. @expr{a>b@} is the same as
+
*! @expr{predef::`>(a,b)@}.
+
*!
*! @returns *! Returns @expr{1@} if the arguments are strictly decreasing, and *! @expr{0@} (zero) otherwise. *! *! @seealso *! @[`<()], @[`<=()], @[`>=()] */ COMPARISON(f_gt,"`>" , is_gt) /*! @decl int(0..1) `>=(mixed arg1, mixed arg2, mixed ... extras) *!
-
*! Greater or equal
operator
.
+
*!
Greater
than
or equal
test
.
*!
-
+
*! Every expression with the @expr{>=@} operator becomes a call to
+
*! this function, i.e. @expr{a>=b@} is the same as
+
*! @expr{predef::`>=(a,b)@}.
+
*!
*! @returns *! Returns @expr{1@} if the arguments are not strictly increasing, and *! @expr{0@} (zero) otherwise. *! *! This is the inverse of @[`<()]. *! *! @seealso *! @[`<=()], @[`>()], @[`<()] */ COMPARISON(f_ge,"`>=",!is_lt)
pike.git/src/operators.c:160:
"Operator not in object.\n"); \ apply_low(sp[-args].u.object, i, args-1); \ free_svalue(sp-2); \ sp[-2]=sp[-1]; \ sp--; \ dmalloc_touch_svalue(sp); \ } while (0) /*! @decl mixed `+(mixed arg1) *! @decl mixed `+(object arg1, mixed ... extras)
-
*! @decl
string
`+(
string
arg1,
string|int|float
arg2
)
-
*! @decl string `+(int|float arg1
,
string
arg2
)
+
*! @decl
mixed
`+(
mixed
arg1,
mixed
arg2
,
mixed
...
extras
)
*! @decl int `+(int arg1, int arg2) *! @decl float `+(float arg1, int|float arg2) *! @decl float `+(int|float arg1, float arg2)
-
+
*! @decl string `+(int|float arg1, string arg2)
+
*! @decl string `+(string arg1, string|int|float arg2)
*! @decl array `+(array arg1, array arg2) *! @decl mapping `+(mapping arg1, mapping arg2) *! @decl multiset `+(multiset arg1, multiset arg2)
-
*! @decl mixed `+(mixed arg1, mixed arg2, mixed ... extras)
+
*!
-
*! Addition
operator
.
+
*! Addition
/concatenation
.
*!
-
+
*! Every expression with the @expr{+@} operator becomes a call to
+
*! this function, i.e. @expr{a+b@} is the same as
+
*! @expr{predef::`+(a,b)@}. Longer @expr{+@} expressions are
+
*! normally optimized to one call, so e.g. @expr{a+b+c@} becomes
+
*! @expr{predef::`+(a,b,c)@}.
+
*!
*! @returns
-
*! If there's
only
a single argument, that argument
will
be
returned.
+
*! If there's a single argument, that argument
is
returned.
*! *! If @[arg1] is an object with only one reference and an
-
*! @[lfun::`+=()], that function
will
be
called with the rest of
-
*!
the
arguments, and its result is returned.
+
*! @[lfun::`+=()], that function
is
called with the rest of
the
+
*! arguments, and its result is returned.
*! *! Otherwise, if @[arg1] is an object with an @[lfun::`+()], that
-
*! function
will
be
called with the rest of the arguments, and its
+
*! function
is
called with the rest of the arguments, and its
*! result is returned. *!
-
*! Otherwise if any of the other arguments is an object that has
-
*! an @[lfun::``+()] the first such function
will
be
called
-
*!
with the
arguments leading up to it, and @[`+()] is then called
+
*! Otherwise
,
if any of the other arguments is an object that has
+
*! an @[lfun::``+()]
,
the first such function
is
called
with the
+
*! arguments leading up to it, and @[`+()] is then called
*! recursively with the result and the rest of the arguments. *!
-
*!
If
there are two arguments the result
will
be
:
+
*!
Otherwise,
if
there are
more than
two arguments the result
is:
+
*! @expr{`+(`+(@[arg1], @[arg2]), @@@[extras])@}
+
*!
+
*! Otherwise the result depends on the argument types
:
*! @mixed arg1
-
*! @type
string
-
*!
@[
arg2
]
will
be
converted
to
a
string,
and
the
result
the
-
*!
strings
concatenated.
-
*!
@type
int|
float
-
*!
@mixed
arg2
-
*! @type string
-
*! @[arg1]
will
be
converted to string
,
and
the
result the
-
*!
strings
concatenated
.
-
*! @type
int|float
-
*!
The
result
will
be
@expr{@
[arg1]
+
@[arg2]
@},
and
will
-
*!
be
a
float
if
either
@[arg1]
or
@[arg2]
is
a
float.
-
*!
@endmixed
-
*! @type
array
-
*! The
arrays
will
be
concatenated.
-
*!
@type
mapping
-
*!
The
mappings
will
be
joined.
-
*!
@type
multiset
-
*!
The
multisets
will
be
added
.
+
*! @type
int|float
+
*!
@mixed
arg2
+
*!
@type int|float
+
*!
The
result
is
@expr{@[arg1]
+ @[arg2]@}, and is a
float
+
*!
if either @[arg1] or @[
arg2
] is a float.
+
*! @type string
+
*! @[arg1]
is
converted to string
which
is
concatenated
+
*!
with
@[arg2]
.
+
*!
@endmixed
+
*!
@type
string
+
*!
@[arg2]
is
converted
to
a
string, and the
result
is
+
*!
concatenated to the end of @
[arg1]
.
+
*!
@type array
+
*! The result is
@[arg2]
concatenated
to the end of @[arg1].
+
*!
@type
mapping
+
*!
The
result
is like
@[arg1]
but
extended with the entries
+
*! from
@[arg2]
.
If
the
same index (according to @[hash_value]
+
*!
and @[`==]) occur in both, the value from @[arg2] is used.
+
*! @type
multiset
+
*! The
result
is
like
@[arg1] but extended with the entries
+
*!
from @[arg2]. Subsequences with orderwise equal indices
+
*!
(i.e.
where
@[`<]
returns
false) are concatenated into the
+
*!
result
with
the
subsequence
from
@[arg1]
before
the
one
from
+
*!
@[arg2]
.
*! @endmixed
-
+
*! The function is not destructive on the arguments - the result is
+
*! always a new instance.
*!
-
*! Otherwise if there are more than 2 arguments the result will be:
-
*! @expr{`+(`+(@[arg1], @[arg2]), @@@[extras])@}
-
*!
+
*! @note *! In Pike 7.0 and earlier the addition order was unspecified. *! *! If @[arg1] is @expr{UNDEFINED@} it will behave as the empty *! array/mapping/multiset if needed. This behaviour was new *! in Pike 7.0. *! *! @seealso *! @[`-()], @[lfun::`+()], @[lfun::``+()] */
pike.git/src/operators.c:1064:
default: { int args = 2; SIMPLE_BAD_ARG_ERROR("`-", 1, "int|float|string|mapping|multiset|array|object"); } } } /*! @decl mixed `-(mixed arg1)
+
*! @decl mixed `-(mixed arg1, mixed arg2, mixed ... extras)
*! @decl mixed `-(object arg1, mixed arg2)
-
*! @decl mixed `-(mixed arg1,
mixed
arg2)
+
*! @decl mixed `-(mixed arg1,
object
arg2)
+
*! @decl int `-(int arg1, int arg2)
+
*! @decl float `-(float arg1, int|float arg2)
+
*! @decl float `-(int|float arg1, float arg2)
+
*! @decl string `-(string arg1, string arg2)
+
*! @decl array `-(array arg1, array arg2)
*! @decl mapping `-(mapping arg1, array arg2)
-
*! @decl mapping `-(mapping arg1, multiset arg2)
+
*! @decl mapping `-(mapping arg1, mapping arg2)
-
*! @decl
array
`-(
array
arg1,
array
arg2)
+
*! @decl
mapping
`-(
mapping
arg1,
multiset
arg2)
*! @decl multiset `-(multiset arg1, multiset arg2)
-
*! @decl float `-(float arg1, int|float arg2)
-
*! @decl float `-(int arg1, float arg2)
-
*! @decl int `-(int arg1, int arg2)
-
*! @decl string `-(string arg1, string arg2)
-
*! @decl mixed `-(mixed arg1, mixed arg2, mixed ... extras)
+
*!
-
*! Negation/subtraction
operator
.
+
*! Negation/subtraction
/set
difference
.
*!
-
+
*! Every expression with the @expr{-@} operator becomes a call to
+
*! this function, i.e. @expr{-a@} is the same as
+
*! @expr{predef::`-(a)@} and @expr{a-b@} is the same as
+
*! @expr{predef::`-(a,b)@}. Longer @expr{-@} expressions are
+
*! normally optimized to one call, so e.g. @expr{a-b-c@} becomes
+
*! @expr{predef::`-(a,b,c)@}.
+
*!
*! @returns
-
*! If there's
only
a single argument, that argument
will
be
returned
-
*!
negated.
If @[arg1]
was
an object
,
@expr{@
[
arg1]
::`-()
@}
will
be
called
-
*! without arguments.
+
*! If there's a single argument, that argument
is
returned
negated.
+
*! If @[arg1]
is
an object
with an @
[
lfun
::`-()
],
that
function
is
+
*!
called
without arguments
, and its result is returned
.
*!
-
*! If there are more than two arguments the result
will be
:
+
*! If there are more than two arguments the result
is
:
*! @expr{`-(`-(@[arg1], @[arg2]), @@@[extras])@}. *!
-
*!
If
@[arg1] is an object
that
overloads
@expr{`
-()
@}
, that
function will
-
*!
be
called with @[arg2] as
the
single
argument
.
+
*!
Otherwise,
if
@[arg1] is an object
with
an
@[lfun::`
-()
]
, that
+
*!
function
is
called with @[arg2] as
argument,
and
its result is
+
*! returned
.
*!
-
*!
If
@[arg2] is an object
that
overloads
@expr{``
-()
@}
, that
function will
-
*!
be
called with @[arg1] as
the
single
argument
.
+
*!
Otherwise,
if
@[arg2] is an object
with
an
@[lfun::``
-()
]
, that
+
*!
function
is
called with @[arg1] as
argument,
and
its result is
+
*! returned
.
*!
-
*! Otherwise the result
will
be
as
follows
:
+
*! Otherwise the result
depends
on
the
argument types
:
*! @mixed arg1
-
*! @type
mapping
-
*! @mixed arg2
-
*! @type array
-
*! The result will be @[arg1] with all occurrances of
-
*! @[arg2] removed.
-
*! @type multiset
|
mapping
-
*! The result will be @[arg1] with all occurrences of
-
*! @expr{@[indices](@[arg2])@} removed.
-
*! @endmixed
-
*! @type array|multiset
-
*! The result will be the elements of @[arg1] that are not in @[arg2].
-
*! @type
float
|int
-
*! The result
will
be
@expr{@[arg1] - @[arg2]@}, and
will
be
a float
-
*!
if
either @[arg1] or @[arg2] is a float.
+
*! @type
int
|float
+
*! The result
is
@expr{@[arg1] - @[arg2]@}, and
is
a float
if
+
*! either @[arg1] or @[arg2] is a float.
*! @type string
-
*!
Result
will
be
the string
@[arg1] with all
occurrances
of
the
-
*! substring @[arg2] removed.
+
*!
The
result
is
@[arg1] with all
nonoverlapping
occurrences
of
+
*!
the
substring @[arg2] removed.
In cases with two overlapping
+
*! occurrences, the leftmost is removed.
+
*! @type array|mapping|multiset
+
*! The result is like @[arg1] but without the elements/indices
+
*! that match any in @[arg2] (according to @[`==] and, in the
+
*! case of mappings, @[hash_value]).
*! @endmixed
-
+
*! The function is not destructive on the arguments - the result is
+
*! always a new instance.
*! *! @note *! In Pike 7.0 and earlier the subtraction order was unspecified. *! *! @seealso *! @[`+()] */ PMOD_EXPORT void f_minus(INT32 args) { switch(args)
pike.git/src/operators.c:1440:
case T_MAPPING: r_speedup(args,func); return; default: while(--args > 0) func(); } } /*! @decl mixed `&(mixed arg1)
+
*! @decl mixed `&(mixed arg1, mixed arg2, mixed ... extras)
*! @decl mixed `&(object arg1, mixed arg2) *! @decl mixed `&(mixed arg1, object arg2) *! @decl int `&(int arg1, int arg2)
-
+
*! @decl string `&(string arg1, string arg2)
*! @decl array `&(array arg1, array arg2)
-
*! @decl multiset `&(multiset arg1, multiset arg2)
+
*! @decl mapping `&(mapping arg1, mapping arg2)
-
*! @decl string `&(string arg1, string arg2)
-
*! @decl type `&(type|program arg1, type|program arg2)
+
*! @decl mapping `&(mapping arg1, array arg2)
-
*! @decl mapping `&(array arg1, mapping arg2)
+
*! @decl mapping `&(mapping arg1, multiset arg2)
-
*! @decl
mapping
`&(multiset arg1,
mapping
arg2)
-
*! @decl
mixed
`&(
mixed
arg1,
mixed
arg2
, mixed ... extras
)
+
*! @decl
multiset
`&(multiset arg1,
multiset
arg2)
+
*! @decl
type
`&(
type|program
arg1,
type|program
arg2)
*!
-
*! Bitwise and/intersection
operator
.
+
*! Bitwise and/intersection.
*!
-
+
*! Every expression with the @expr{&@} operator becomes a call to
+
*! this function, i.e. @expr{a&b@} is the same as
+
*! @expr{predef::`&(a,b)@}.
+
*!
*! @returns
-
*! If there's a single argument, that argument
will
be
returned.
+
*! If there's a single argument, that argument
is
returned.
*!
-
*! If there are more than two arguments
,
the result
will be
:
+
*! If there are more than two arguments the result
is
:
*! @expr{`&(`&(@[arg1], @[arg2]), @@@[extras])@}. *!
-
*!
If
@[arg1] is an object
that
has
an @[lfun::`&()], that
function
-
*!
will
be
called with @[arg2] as
the
single
argument
.
+
*!
Otherwise,
if
@[arg1] is an object
with
an @[lfun::`&()], that
+
*!
function
is
called with @[arg2] as
argument,
and
its result is
+
*! returned
.
*!
-
*!
If
@[arg2] is an object
that
has
an @[lfun::``&()], that
function
-
*!
will
be
called with @[arg1] as
the
single
argument
.
+
*!
Otherwise,
if
@[arg2] is an object
with
an @[lfun::``&()], that
+
*!
function
is
called with @[arg1] as
argument,
and
its result is
+
*! returned
.
*!
-
*! Otherwise the result
will
be
as
follows
:
+
*! Otherwise the result
depends
on
the
argument types
:
*! @mixed arg1 *! @type int
-
*!
The
result will be the bitwise
and of @[arg1] and @[arg2].
-
*! @type array|multiset|mapping
-
*! The result will be the elements of @[arg1] and @[arg2] that
-
*! occurr in both.
-
*! @type type|program
-
*! The result will be the type intersection of @[arg1] and @[arg2].
+
*!
Bitwise
and of @[arg1] and @[arg2].
*! @type string
-
*! The result
will
be
the
string where the
elements
of @[arg1]
-
*!
and
@[arg2]
have
been
pairwise
bitwise
anded
.
+
*! The result
is
a
string where
each character is
the
bitwise
+
*! and
of
the characters in the same position in
@[arg1]
and
+
*!
@[arg2].
The arguments must be strings of the same length.
+
*! @type array|mapping|multiset
+
*! The result is like
@[
arg1] but only with the
+
*! elements/indices that match any in @[
arg2]
(according
to
+
*!
@[`==] and, in the case of mappings, @[hash_value])
.
+
*! @type type|program
+
*! Type intersection of @[arg1] and @[arg2].
*! @endmixed
-
+
*! The function is not destructive on the arguments - the result is
+
*! always a new instance.
*! *! @seealso *! @[`|()], @[lfun::`&()], @[lfun::``&()] */ PMOD_EXPORT void f_and(INT32 args) { switch(args) { case 0: SIMPLE_TOO_FEW_ARGS_ERROR("`&", 1); case 1: return;
pike.git/src/operators.c:1650:
} STRING_BITOP(|,"OR") default: PIKE_ERROR("`|", "Bitwise OR on illegal type.\n", sp, 2); } } /*! @decl mixed `|(mixed arg1)
+
*! @decl mixed `|(mixed arg1, mixed arg2, mixed ... extras)
*! @decl mixed `|(object arg1, mixed arg2) *! @decl mixed `|(mixed arg1, object arg2) *! @decl int `|(int arg1, int arg2)
-
+
*! @decl string `|(string arg1, string arg2)
+
*! @decl array `|(array arg1, array arg2)
*! @decl mapping `|(mapping arg1, mapping arg2) *! @decl multiset `|(multiset arg1, multiset arg2)
-
*! @decl array `|(array arg1, array arg2)
-
*! @decl string `|(string arg1, string arg2)
+
*! @decl type `|(program|type arg1, program|type arg2)
-
*! @decl mixed `|(mixed arg1, mixed arg2, mixed ... extras)
+
*!
-
*! Bitwise or/
join operator
.
+
*! Bitwise or/
union
.
*!
-
+
*! Every expression with the @expr{|@} operator becomes a call to
+
*! this function, i.e. @expr{a|b@} is the same as
+
*! @expr{predef::`|(a,b)@}.
+
*!
*! @returns
-
*! If there's a single argument, that argument
will
be
returned.
+
*! If there's a single argument, that argument
is
returned.
*!
-
*! If there are more than two arguments, the result
will be
:
+
*! If there are more than two arguments, the result
is
:
*! @expr{`|(`|(@[arg1], @[arg2]), @@@[extras])@}. *!
-
*!
If
@[arg1] is an object
that
has
an @[lfun::`|()], that
function
-
*!
will
be
called with @[arg2] as
the
single
argument
.
+
*!
Otherwise,
if
@[arg1] is an object
with
an @[lfun::`|()], that
+
*!
function
is
called with @[arg2] as
argument,
and
its result is
+
*! returned
.
*!
-
*!
If
@[arg2] is an object
that
has
an @[lfun::``|()], that
function
-
*!
will
be
called with @[arg1] as
the
single
argument
.
+
*!
Otherwise,
if
@[arg2] is an object
with
an @[lfun::``|()], that
+
*!
function
is
called with @[arg1] as
argument,
and
its result is
+
*! returned
.
*!
-
*! Otherwise the result
will
be
as
follows
:
+
*! Otherwise the result
depends
on
the
argument types
:
*! @mixed arg1
-
*! @type int
-
*! The result
will
be
the
binary
or of @[arg1] and @[arg2].
-
*! @type
mapping|multiset
-
*! The result
will
be
the
join
of
@[arg1]
and
@[arg2]
.
-
*!
@type
array
-
*!
The
result
will
be
the
concatenation
of
@[arg1] and @[arg2].
-
*! @type
string
-
*! The result
will
be
the
pairwise
bitwose
or
of
@[
arg1
] and @[arg2].
-
*! @type
type|program
-
*! The result
will
be
the type
join
of @[arg1] and @[arg2].
+
*! @type int
+
*!
Bitwise or of @[arg1] and @[arg2].
+
*! @type string
+
*!
The result
is
a
string where each character is
the
bitwise
+
*!
or of
the characters in the same position in
@[arg1] and
+
*!
@[arg2].
The arguments must be strings of the same length.
+
*! @type
array
+
*! The result
is
an
array with
the
elements
in
@[arg1]
+
*!
concatenated with those in
@[arg2]
that doesn't occur in
+
*!
@[arg1] (according to @[`==]). The order between the
+
*!
elements
that
come
from
the
same
argument
is kept.
+
*!
+
*! Every element in
@[arg1]
is only matched once against an
+
*! element in @[arg2], so if @[arg2] contains several elements
+
*! that are equal to each other
and
are more than their
+
*! counterparts in
@[
arg1], the rightmost remaining elements in
+
*! @[
arg2]
are kept
.
+
*! @type
mapping
+
*! The result
is
like
@[arg1] but extended with
the
entries
+
*!
from
@[
arg2
]
.
If the same index (according to @[hash_value]
+
*!
and @[
`==]) occur in both, the value from @[
arg2]
is used
.
+
*! @type
multiset
+
*! The result
is
like
@[arg1] but extended with
the
entries in
+
*! @[arg2] that doesn't already occur in @[arg1] (according to
+
*! @[`==]). Subsequences with orderwise equal entries (i.e.
+
*! where @[`<] returns false) are handled just like the array
+
*! case above.
+
*! @type
type
|program
+
*!
Type union
of @[arg1] and @[arg2].
*! @endmixed
-
+
*! The function is not destructive on the arguments - the result is
+
*! always a new instance.
*! *! @seealso *! @[`&()], @[lfun::`|()], @[lfun::``|()] */ PMOD_EXPORT void f_or(INT32 args) { switch(args) { case 0: SIMPLE_TOO_FEW_ARGS_ERROR("`|", 1); case 1: return;
pike.git/src/operators.c:1859:
} STRING_BITOP(^,"XOR") default: PIKE_ERROR("`^", "Bitwise XOR on illegal type.\n", sp, 2); } } /*! @decl mixed `^(mixed arg1)
+
*! @decl mixed `^(mixed arg1, mixed arg2, mixed ... extras)
*! @decl mixed `^(object arg1, mixed arg2) *! @decl mixed `^(mixed arg1, object arg2) *! @decl int `^(int arg1, int arg2)
-
+
*! @decl string `^(string arg1, string arg2)
+
*! @decl array `^(array arg1, array arg2)
*! @decl mapping `^(mapping arg1, mapping arg2) *! @decl multiset `^(multiset arg1, multiset arg2)
-
*! @decl array `^(array arg1, array arg2)
-
*! @decl string `^(string arg1, string arg2)
+
*! @decl type `^(program|type arg1, program|type arg2)
-
*! @decl mixed `^(mixed arg1, mixed arg2, mixed ... extras)
+
*!
-
*! Exclusive or
operator
.
+
*! Exclusive or.
*!
-
+
*! Every expression with the @expr{^@} operator becomes a call to
+
*! this function, i.e. @expr{a^b@} is the same as
+
*! @expr{predef::`^(a,b)@}.
+
*!
*! @returns
-
*! If there's a single argument, that argument
will
be
returned.
+
*! If there's a single argument, that argument
is
returned.
*!
-
*! If there are more than two arguments, the result
will be
:
+
*! If there are more than two arguments, the result
is
:
*! @expr{`^(`^(@[arg1], @[arg2]), @@@[extras])@}. *!
-
*!
If
@[arg1] is an object
that
has
an @[lfun::`^()], that
function
-
*!
will
be
called with @[arg2] as
the
single
argument
.
+
*!
Otherwise,
if
@[arg1] is an object
with
an @[lfun::`^()], that
+
*!
function
is
called with @[arg2] as
argument,
and
its result is
+
*! returned
.
*!
-
*!
If
@[arg2] is an object
that
has
an @[lfun::``^()], that
function
-
*!
will
be
called with @[arg1] as
the
single
argument
.
+
*!
Otherwise,
if
@[arg2] is an object
with
an @[lfun::``^()], that
+
*!
function
is
called with @[arg1] as
argument,
and
its result is
+
*! returned
.
*!
-
*! Otherwise the result
will
be
as
follows
:
+
*! Otherwise the result
depends
on
the
argument types
:
*! @mixed arg1
-
*! @type int
-
*! The result
will
be
the bitwise
xor
of @[arg1] and @[arg2].
-
*! @type
mapping|multiset|
array
-
*! The result
will
be
the elements
of
@[arg1]
and
@[arg2] that
-
*! only
occurr
in one
of
them
.
-
*! @type
string
-
*! The result
will
be
the
pairwise
bitwise
xor
of
@[arg1] and @[arg2].
-
*! @type type|program
-
*! The result
will
be
the
result
of
+
*! @type int
+
*!
Bitwise exclusive or of @[arg1] and @[arg2].
+
*! @type string
+
*!
The result
is
a
string where each character is
the bitwise
+
*!
exclusive or
of
the characters in the same position in
+
*!
@[arg1] and @[arg2].
The arguments must be strings of the
+
*!
same length.
+
*!
@type array
+
*! The result
is
an
array with
the elements
in
@[arg1]
that
+
*! doesn't occur in
@[arg2]
concatenated with those in @[arg2]
+
*!
that
doesn't occur in @[arg1] (according to @[`==]). The
+
*!
order between the elements that come from the same argument
+
*! is kept.
+
*!
+
*! Every element is
only
matched
once against an element
in
the
+
*! other array, so if
one
contains
several elements that are
+
*! equal to each other and are more than their counterparts in
+
*! the other array, the rightmost remaining elements are kept
.
+
*! @type
mapping
+
*! The result
is
like
@[arg1] but with
the
entries
from
@[arg1]
+
*!
and
@[
arg2] whose indices are different between them
+
*! (according to @[hash_value] and @[`==]).
+
*! @type multiset
+
*! The result is like @[
arg1]
but with the entries from @[arg1]
+
*!
and @[arg2]
that are different between them (according to
+
*! @[hash_value] and @[`==])
.
Subsequences with orderwise equal
+
*!
entries (i.e. where @[`<] returns false) are handled just
+
*! like the array case above.
+
*!
@type type|program
+
*! The result
is
a
type
computed
like this:
*! @expr{(@[arg1]&~@[arg2])|(~@[arg1]&@[arg2])@}. *! @endmixed
-
+
*! The function is not destructive on the arguments - the result is
+
*! always a new instance.
*! *! @seealso *! @[`&()], @[`|()], @[lfun::`^()], @[lfun::``^()] */ PMOD_EXPORT void f_xor(INT32 args) { switch(args) { case 0: SIMPLE_TOO_FEW_ARGS_ERROR("`^", 1); case 1: return;
pike.git/src/operators.c:1972:
SIMPLE_BAD_ARG_ERROR("`<<", 2, "int(0..)|object"); } sp--; sp[-1].u.integer = sp[-1].u.integer << sp->u.integer; } /*! @decl int `<<(int arg1, int arg2) *! @decl mixed `<<(object arg1, int|object arg2) *! @decl mixed `<<(int arg1, object arg2) *!
-
*! Left shift
operator
.
+
*! Left shift.
*!
-
+
*! Every expression with the @expr{<<@} operator becomes a call to
+
*! this function, i.e. @expr{a<<b@} is the same as
+
*! @expr{predef::`<<(a,b)@}.
+
*!
*! If @[arg1] is an object that implements @[lfun::`<<()], that *! function will be called with @[arg2] as the single argument. *! *! If @[arg2] is an object that implements @[lfun::``<<()], that *! function will be called with @[arg1] as the single argument. *! *! Otherwise @[arg1] will be shifted @[arg2] bits left. *! *! @seealso *! @[`>>()]
pike.git/src/operators.c:2047:
} sp--; sp[-1].u.integer = sp[-1].u.integer >> sp->u.integer; } /*! @decl int `>>(int arg1, int arg2) *! @decl mixed `>>(object arg1, int|object arg2) *! @decl mixed `>>(int arg1, object arg2) *!
-
*! Right shift
operator
.
+
*! Right shift.
*!
-
+
*! Every expression with the @expr{>>@} operator becomes a call to
+
*! this function, i.e. @expr{a>>b@} is the same as
+
*! @expr{predef::`>>(a,b)@}.
+
*!
*! If @[arg1] is an object that implements @[lfun::`>>()], that *! function will be called with @[arg2] as the single argument. *! *! If @[arg2] is an object that implements @[lfun::``>>()], that *! function will be called with @[arg1] as the single argument. *! *! Otherwise @[arg1] will be shifted @[arg2] bits right. *! *! @seealso *! @[`<<()]
pike.git/src/operators.c:2280:
*! @decl array `*(array arg1, float arg2) *! @decl string `*(string arg1, int arg2) *! @decl string `*(string arg1, float arg2) *! @decl string `*(array(string) arg1, string arg2) *! @decl array `*(array(array) arg1, array arg2) *! @decl float `*(float arg1, int|float arg2) *! @decl float `*(int arg1, float arg2) *! @decl int `*(int arg1, int arg2) *! @decl mixed `*(mixed arg1, mixed arg2, mixed ... extras) *!
-
*! Multiplication
operator
.
+
*! Multiplication
/repetition/implosion
.
*!
-
+
*! Every expression with the @expr{*@} operator becomes a call to
+
*! this function, i.e. @expr{a*b@} is the same as
+
*! @expr{predef::`*(a,b)@}. Longer @expr{*@} expressions are
+
*! normally optimized to one call, so e.g. @expr{a*b*c@} becomes
+
*! @expr{predef::`*(a,b,c)@}.
+
*!
*! @returns
-
*! If there's
only
a single argument, that argument will be returned.
+
*! If there's a single argument, that argument will be returned.
*! *! If the first argument is an object that implements @[lfun::`*()], *! that function will be called with the rest of the arguments. *! *! If there are more than two arguments, the result will be *! @expr{`*(`*(@[arg1], @[arg2]), @@@[extras])@}. *! *! If @[arg2] is an object that implements @[lfun::``*()], that *! function will be called with @[arg1] as the single argument. *!
pike.git/src/operators.c:2633:
*! @decl array(string) `/(string arg1, float arg2) *! @decl array(array) `/(array arg1, int arg2) *! @decl array(array) `/(array arg1, float arg2) *! @decl array(string) `/(string arg1, string arg2) *! @decl array(array) `/(array arg1, array arg2) *! @decl float `/(float arg1, int|float arg2) *! @decl float `/(int arg1, float arg2) *! @decl int `/(int arg1, int arg2) *! @decl mixed `/(mixed arg1, mixed arg2, mixed ... extras) *!
-
*! Division
operator
.
+
*! Division
/split
.
*!
-
+
*! Every expression with the @expr{/@} operator becomes a call to
+
*! this function, i.e. @expr{a/b@} is the same as
+
*! @expr{predef::`/(a,b)@}.
+
*!
*! @returns *! If there are more than two arguments, the result will be *! @expr{`/(`/(@[arg1], @[arg2]), @@@[extras])@}. *! *! If @[arg1] is an object that implements @[lfun::`/()], that *! function will be called with @[arg2] as the single argument. *! *! If @[arg2] is an object that implements @[lfun::``/()], that *! function will be called with @[arg1] as the single argument. *!
pike.git/src/operators.c:2832:
} /*! @decl mixed `%(object arg1, mixed arg2) *! @decl mixed `%(mixed arg1, object arg2) *! @decl string `%(string arg1, int arg2) *! @decl array `%(array arg1, int arg2) *! @decl float `%(float arg1, float|int arg2) *! @decl float `%(int arg1, float arg2) *! @decl int `%(int arg1, int arg2) *!
-
*! Modulo
operator
.
+
*! Modulo.
*!
-
+
*! Every expression with the @expr{%@} operator becomes a call to
+
*! this function, i.e. @expr{a%b@} is the same as
+
*! @expr{predef::`%(a,b)@}.
+
*!
*! @returns *! If @[arg1] is an object that implements @[lfun::`%()] then *! that function will be called with @[arg2] as the single argument. *! *! If @[arg2] is an object that implements @[lfun::``%()] then *! that function will be called with @[arg2] as the single argument. *! *! Otherwise the result will be as follows: *! @mixed arg1 *! @type string|array
pike.git/src/operators.c:2926:
free_svalue(sp-1); sp[-1].type=T_INT; sp[-1].u.integer=0; } } /*! @decl int(0..1) `!(object|function arg) *! @decl int(1..1) `!(int(0..0) arg) *! @decl int(0..0) `!(mixed arg) *!
-
*!
Negation
operator
.
+
*!
Logical
not
.
*!
-
+
*! Every expression with the @expr{!@} operator becomes a call to
+
*! this function, i.e. @expr{!a@} is the same as
+
*! @expr{predef::`!(a)@}.
+
*!
+
*! It's also used when necessary to test truth on objects, i.e. in
+
*! a statement @expr{if (o) ...@} where @expr{o@} is an object, the
+
*! test becomes the equivalent of @expr{!!o@} so that any
+
*! @[lfun::`!()] the object might have gets called.
+
*!
*! @returns *! If @[arg] is an object that implements @[lfun::`!()], that function *! will be called. *! *! If @[arg] is @expr{0@} (zero), a destructed object, or a function in a *! destructed object, @expr{1@} will be returned. *! *! Otherwise @expr{0@} (zero) will be returned. *!
-
+
*! @note
+
*! No float is considered false, not even @expr{0.0@}.
+
*!
*! @seealso *! @[`==()], @[`!=()], @[lfun::`!()] */ PMOD_EXPORT void f_not(INT32 args) { if(args != 1) { /* FIXME: Not appropriate with too many args. */ SIMPLE_TOO_FEW_ARGS_ERROR("`!", 1); } o_not();
pike.git/src/operators.c:3034:
PIKE_ERROR("`~", "Bad argument.\n", sp, 1); } } /*! @decl mixed `~(object arg) *! @decl int `~(int arg) *! @decl float `~(float arg) *! @decl type `~(type|program arg) *! @decl string `~(string arg) *!
-
*! Complement
operator
.
+
*! Complement
/inversion
.
*!
-
+
*! Every expression with the @expr{~@} operator becomes a call to
+
*! this function, i.e. @expr{~a@} is the same as
+
*! @expr{predef::`~(a)@}.
+
*!
*! @returns *! The result will be as follows: *! @mixed arg *! @type object *! If @[arg] implements @[lfun::`~()], that function will be called. *! @type int *! The bitwise inverse of @[arg] will be returned. *! @type float *! The result will be @expr{-1.0 - @[arg]@}. *! @type type|program
pike.git/src/operators.c:3186:
*! @decl mixed `[](array arg, int index) *! @decl mixed `[](array arg, mixed index) *! @decl mixed `[](mapping arg, mixed index) *! @decl int(0..1) `[](multiset arg, mixed index) *! @decl int `[](string arg, int index) *! @decl mixed `[](program arg, string index) *! @decl mixed `[](object arg, mixed start, mixed end) *! @decl string `[](string arg, int start, int end) *! @decl array `[](array arg, int start, int end) *!
-
*! Index
and range operator
.
+
*! Index
/subrange
.
*!
-
+
*! Every non-lvalue expression with the @expr{[]@} operator becomes
+
*! a call to this function, i.e. @expr{a[i]@} is the same as
+
*! @expr{predef::`[](a,i)@} and @expr{a[i..j]@} is the same as
+
*! @expr{predef::`[](a,i,j)@}. If the lower limit @expr{i@} is left
+
*! out, @expr{0@} is passed to the function. If the upper limit
+
*! @expr{j@} is left out, @[Int.NATIVE_MAX] is passed to the
+
*! function, but that might be changed to an even larger number in
+
*! the future.
+
*!
*! @returns *! If @[arg] is an object that implements @[lfun::`[]()], that function *! will be called with the rest of the arguments. *! *! If there are 2 arguments the result will be as follows: *! @mixed arg *! @type object *! The non-static (ie public) symbol named @[index] will be looked up *! in @[arg]. *! @type int
pike.git/src/operators.c:3226:
*! Otherwise if there are 3 arguments the result will be as follows: *! @mixed arg *! @type string *! A string with the characters between @[start] and @[end] (inclusive) *! in @[arg] will be returned. *! @type array *! An array with the elements between @[start] and @[end] (inclusive) *! in @[arg] will be returned. *! @endmixed *!
+
*! @note
+
*! An indexing expression in an lvalue context, i.e. where the
+
*! index is being assigned a new value, uses @[`[]=] instead of
+
*! this function.
+
*!
*! @seealso
-
*! @[`->()], @[lfun::`[]()]
+
*! @[`->()], @[lfun::`[]()]
, @[`[]=]
*/ PMOD_EXPORT void f_index(INT32 args) { switch(args) { case 0: case 1: PIKE_ERROR("`[]", "Too few arguments.\n", sp, args); break; case 2:
pike.git/src/operators.c:3256:
} } /*! @decl mixed `->(object arg, string index) *! @decl mixed `->(int arg, string index) *! @decl mixed `->(array arg, string index) *! @decl mixed `->(mapping arg, string index) *! @decl int(0..1) `->(multiset arg, string index) *! @decl mixed `->(program arg, string index) *!
-
*! Arrow index
operator
.
+
*! Arrow index.
*!
-
*!
This
function
behaves
much
like
@[
`
[]
(
)]
,
just
that
the index
is
always
-
*!
a
string.
+
*!
Every
non-lvalue expression with the @expr{->@} operator becomes
+
*! a call to this
function
.
@expr{a->b@}
is
the
same as
+
*! @expr{predef::
`
^
(
a,"b"
)
@}
where
@expr{"b"@}
is
the
symbol
+
*!
@expr{b@}
in
string
form
.
*!
-
+
*! This function behaves like @[`[]], except that the index is
+
*! passed literally as a string instead of being evaluated.
+
*!
*! @returns *! If @[arg] is an object that implements @[lfun::`->()], that function *! will be called with @[index] as the single argument. *! *! Otherwise the result will be as follows: *! @mixed arg *! @type object *! The non-static (ie public) symbol named @[index] will be looked up *! in @[arg]. *! @type int
pike.git/src/operators.c:3286:
*! If @[index] exists in @[arg] the corresponding value will be *! returned. Otherwise @expr{UNDEFINED@} will be returned. *! @type multiset *! If @[index] exists in @[arg], @expr{1@} will be returned. *! Otherwise @expr{UNDEFINED@} will be returned. *! @type program *! The non-static (ie public) constant symbol @[index] will be *! looked up in @[arg]. *! @endmixed *!
+
*! @note
+
*! In an expression @expr{a->b@}, the symbol @expr{b@} can be any
+
*! token that matches the identifier syntax - keywords are
+
*! disregarded in that context.
+
*!
+
*! @note
+
*! An arrow indexing expression in an lvalue context, i.e. where
+
*! the index is being assigned a new value, uses @[`->=] instead of
+
*! this function.
+
*!
*! @seealso
-
*! @[`[]()], @[lfun::`->()], @[::`->()]
+
*! @[`[]()], @[lfun::`->()], @[::`->()]
, @[`->=]
*/ PMOD_EXPORT void f_arrow(INT32 args) { switch(args) { case 0: case 1: PIKE_ERROR("`->", "Too few arguments.\n", sp, args); break; case 2:
pike.git/src/operators.c:3313:
PIKE_ERROR("`->", "Too many arguments.\n", sp, args); } } /*! @decl mixed `[]=(object arg, mixed index, mixed val) *! @decl mixed `[]=(object arg, string index, mixed val) *! @decl mixed `[]=(array arg, int index, mixed val) *! @decl mixed `[]=(mapping arg, mixed index, mixed val) *! @decl int(0..1) `[]=(multiset arg, mixed index, int(0..1) val) *!
-
*! Index
assign operator
.
+
*! Index
assignment
.
*!
-
+
*! Every lvalue expression with the @expr{[]@} operator becomes a
+
*! call to this function, i.e. @expr{a[b]=c@} is the same as
+
*! @expr{predef::`[]=(a,b,c)@}.
+
*!
*! If @[arg] is an object that implements @[lfun::`[]=()], that function *! will be called with @[index] and @[val] as the arguments. *! *! @mixed arg *! @type object *! The non-static (ie public) variable named @[index] will be looked up *! in @[arg], and assigned @[val]. *! @type array|mapping *! Index @[index] in @[arg] will be assigned @[val]. *! @type multiset *! If @[val] is @expr{0@} (zero), one occurrance of @[index] in *! @[arg] will be removed. Otherwise @[index] will be added *! to @[arg] if it is not already there. *! @endmixed *! *! @returns *! @[val] will be returned. *!
-
+
*! @note
+
*! An indexing expression in a non-lvalue context, i.e. where the
+
*! index is being queried instead of assigned, uses @[`[]] instead
+
*! of this function.
+
*!
*! @seealso
-
*! @[`->=()], @[lfun::`[]=()]
+
*! @[`->=()], @[lfun::`[]=()]
, @[`[]]
*/ PMOD_EXPORT void f_index_assign(INT32 args) { switch (args) { case 0: case 1: case 2: PIKE_ERROR("`[]=", "Too few arguments.\n", sp, args); break; case 3:
pike.git/src/operators.c:3359:
break; default: PIKE_ERROR("`[]=", "Too many arguments.\n", sp, args); } } /*! @decl mixed `->=(object arg, string index, mixed val) *! @decl mixed `->=(mapping arg, string index, mixed val) *! @decl int(0..1) `->=(multiset arg, string index, int(0..1) val) *!
-
*! Arrow
assign
operator
.
+
*! Arrow
index
assignment
.
*!
-
*!
This
function
behaves
much
like
@[
`
[]
=(
)]
,
just
that
the index
is
always
-
*!
a
string.
+
*!
Every
lvalue expression with the @expr{->@} operator becomes a
+
*! call to this
function
,
i.e.
@expr{a->b=c@}
is
the same as
+
*! @expr{predef::
`
->
=(
a,"b",c
)
@}
where
@expr{"b"@}
is
the
symbol
+
*!
@expr{b@}
in
string
form
.
*!
-
+
*! This function behaves like @[`[]=], except that the index is
+
*! passed literally as a string instead of being evaluated.
+
*!
*! If @[arg] is an object that implements @[lfun::`->=()], that function *! will be called with @[index] and @[val] as the arguments. *! *! @mixed arg *! @type object *! The non-static (ie public) variable named @[index] will be looked up *! in @[arg], and assigned @[val]. *! @type array|mapping *! Index @[index] in @[arg] will be assigned @[val]. *! @type multiset *! If @[val] is @expr{0@} (zero), one occurrance of @[index] in *! @[arg] will be removed. Otherwise @[index] will be added *! to @[arg] if it is not already there. *! @endmixed *! *! @returns *! @[val] will be returned. *!
-
+
*! @note
+
*! In an expression @expr{a->b=c@}, the symbol @expr{b@} can be any
+
*! token that matches the identifier syntax - keywords are
+
*! disregarded in that context.
+
*!
+
*! @note
+
*! An arrow indexing expression in a non-lvalue context, i.e. where
+
*! the index is being queried instead of assigned, uses @[`->]
+
*! instead of this function.
+
*!
*! @seealso
-
*! @[`[]=()], @[lfun::`->=()]
+
*! @[`[]=()], @[lfun::`->=()]
, @[`->]
*/ PMOD_EXPORT void f_arrow_assign(INT32 args) { switch (args) { case 0: case 1: case 2: PIKE_ERROR("`->=", "Too few arguments.\n", sp, args); break; case 3:
pike.git/src/operators.c:3410:
PIKE_ERROR("`->=", "Too many arguments.\n", sp, args); } } /*! @decl int sizeof(string arg) *! @decl int sizeof(array arg) *! @decl int sizeof(mapping arg) *! @decl int sizeof(multiset arg) *! @decl int sizeof(object arg) *!
-
*!
Sizeof
operator
.
+
*!
Size
query
.
*! *! @returns *! The result will be as follows: *! @mixed arg *! @type string *! The number of characters in @[arg] will be returned. *! @type array|multiset *! The number of elements in @[arg] will be returned. *! @type mapping *! The number of key-value pairs in @[arg] will be returned.