=encoding utf8
=head1 NAME
std/path/zz/operators - Operator definitions for ZZPath expressions.
=head1 IMPLEMENTATION SUPPORT
This module is supported by all implementations of ZuzuScript.
=head1 DESCRIPTION
This module extends the base ZPath operator model with
ZuzuScript-flavoured expression operators.
=head1 EXPORTS
=head2 Classes
=over
=item C<Operator>
ZZPath operator class extending C<std/path/z/operators> C<Operator>.
=back
=head2 Functions
=over
=item C<< string_operand(ev, ctx, expr) >>, C<< string_operands(ev, ctx, left, right) >>
Parameters: evaluator, context, and expression AST nodes. Returns:
C<String> or C<Array>. Evaluates one or two operands as strings.
=item C<< first_eval_value(values) >>, C<< primitive_eval_value(values) >>
Parameters: C<values> is an evaluated node array. Returns: value.
Extracts the first or primitive value used by ZZPath operators.
=item C<< collection_operand(ev, ctx, expr) >>
Parameters: evaluator, context, and expression AST node. Returns:
collection value. Evaluates an operand for collection operators.
=item C<< builtin_can(value, method_name) >>
Parameters: C<value> is any value and C<method_name> is a method name.
Returns: C<Boolean>. Tests whether built-in values support a method.
=back
=head2 Constants
=over
=item C<STANDARD_OPERATORS>
Type: C<Array>. Complete ZZPath operator definition table.
=item C<logical_negation>, C<logical_and>, C<logical_nand>, C<logical_xor>, C<logical_or>
Type: C<Function>. Logical operator implementations.
=item C<numeric_power>, C<numeric_multiplication>, C<numeric_division>, C<numeric_modulus>, C<numeric_addition>, C<numeric_subtraction>, C<numeric_equality>, C<numeric_inequality>, C<numeric_less_than>, C<numeric_greater_than>, C<numeric_less_than_or_equal>, C<numeric_greater_than_or_equal>, C<numeric_compare>
Type: C<Function>. Numeric operator implementations.
=item C<string_concatenation>, C<string_equality>, C<string_inequality>, C<string_greater_than>, C<string_greater_than_or_equal>, C<string_less_than>, C<string_less_than_or_equal>, C<string_compare>, C<string_equality_insensitive>, C<string_inequality_insensitive>, C<string_greater_than_insensitive>, C<string_greater_than_or_equal_insensitive>, C<string_less_than_insensitive>, C<string_less_than_or_equal_insensitive>, C<string_compare_insensitive>
Type: C<Function>. String operator implementations.
=item C<regexp_match>, C<bitwise_and>, C<bitwise_xor>, C<bitwise_or>, C<set_union>, C<set_intersection>, C<set_difference>, C<collection_membership>, C<collection_non_membership>, C<set_subsetof>, C<set_supersetof>, C<set_equivalentof>, C<type_aware_equality>, C<type_aware_inequality>, C<object_can>
Type: C<Function>. Regular expression, bitwise, collection, type-aware,
and object capability operator implementations.
=back
=head1 COPYRIGHT AND LICENCE
B<< std/path/zz/operators >> is copyright Toby Inkster.
It is free software; you may redistribute it and/or modify it under
the terms of either the Artistic License 1.0 or the GNU General Public
License version 2.
=cut
from std/path/z/operators import Operator as ZOperator;
class Operator extends ZOperator;
const logical_negation := function ( op, ev, ast, ctx, expr ) {
const got := ev.eval_expr( expr, ev.nested_ctx( ctx ) );
const value := got.length() > 0 ? got[0] : null;
return op.wrap( not ev.truthy(value) );
};
const numeric_power := function ( op, ev, ast, ctx, left, right ) {
const left_val := op._handle_numeric_operand( ev, ctx, left );
const right_val := op._handle_numeric_operand( ev, ctx, right );
return op.wrap( left_val ** right_val );
};
const numeric_multiplication := function ( op, ev, ast, ctx, left, right ) {
const left_val := op._handle_numeric_operand( ev, ctx, left );
const right_val := op._handle_numeric_operand( ev, ctx, right );
return op.wrap( left_val × right_val );
};
const numeric_division := function ( op, ev, ast, ctx, left, right ) {
const left_val := op._handle_numeric_operand( ev, ctx, left );
const right_val := op._handle_numeric_operand( ev, ctx, right );
return op.wrap( left_val ÷ right_val );
};
const numeric_modulus := function ( op, ev, ast, ctx, left, right ) {
const left_val := op._handle_numeric_operand( ev, ctx, left );
const right_val := op._handle_numeric_operand( ev, ctx, right );
return op.wrap( left_val mod right_val );
};
const numeric_addition := function ( op, ev, ast, ctx, left, right ) {
const left_val := op._handle_numeric_operand( ev, ctx, left );
const right_val := op._handle_numeric_operand( ev, ctx, right );
return op.wrap( left_val + right_val );
};
const numeric_subtraction := function ( op, ev, ast, ctx, left, right ) {
const left_val := op._handle_numeric_operand( ev, ctx, left );
const right_val := op._handle_numeric_operand( ev, ctx, right );
return op.wrap( left_val - right_val );
};
const numeric_equality := function ( op, ev, ast, ctx, left, right ) {
const left_val := op._handle_numeric_operand( ev, ctx, left );
const right_val := op._handle_numeric_operand( ev, ctx, right );
return op.wrap( left_val = right_val );
};
const numeric_inequality := function ( op, ev, ast, ctx, left, right ) {
const left_val := op._handle_numeric_operand( ev, ctx, left );
const right_val := op._handle_numeric_operand( ev, ctx, right );
return op.wrap( left_val ≠ right_val );
};
const numeric_less_than := function ( op, ev, ast, ctx, left, right ) {
const left_val := op._handle_numeric_operand( ev, ctx, left );
const right_val := op._handle_numeric_operand( ev, ctx, right );
return op.wrap( left_val < right_val );
};
const numeric_greater_than := function ( op, ev, ast, ctx, left, right ) {
const left_val := op._handle_numeric_operand( ev, ctx, left );
const right_val := op._handle_numeric_operand( ev, ctx, right );
return op.wrap( left_val > right_val );
};
const numeric_less_than_or_equal := function (
op,
ev,
ast,
ctx,
left,
right,
) {
const left_val := op._handle_numeric_operand( ev, ctx, left );
const right_val := op._handle_numeric_operand( ev, ctx, right );
return op.wrap( left_val ≤ right_val );
};
const numeric_greater_than_or_equal := function (
op,
ev,
ast,
ctx,
left,
right,
) {
const left_val := op._handle_numeric_operand( ev, ctx, left );
const right_val := op._handle_numeric_operand( ev, ctx, right );
return op.wrap( left_val ≥ right_val );
};
const numeric_compare := function ( op, ev, ast, ctx, left, right ) {
const left_val := op._handle_numeric_operand( ev, ctx, left );
const right_val := op._handle_numeric_operand( ev, ctx, right );
return op.wrap( left_val <=> right_val );
};
function string_operand ( ev, ctx, expr ) {
const result := ev.eval_expr( expr, ev.nested_ctx( ctx ) );
return "" unless result.length;
const value := ev.to_string( result[0] );
return value ≡ null ? "" : "" _ value;
}
function string_operands ( ev, ctx, left, right ) {
return [
string_operand( ev, ctx, left ),
string_operand( ev, ctx, right ),
];
}
const string_concatenation := function ( op, ev, ast, ctx, left, right ) {
const values := string_operands( ev, ctx, left, right );
return op.wrap( values[0] _ values[1] );
};
const string_equality := function ( op, ev, ast, ctx, left, right ) {
const values := string_operands( ev, ctx, left, right );
return op.wrap( values[0] eq values[1] );
};
const string_inequality := function ( op, ev, ast, ctx, left, right ) {
const values := string_operands( ev, ctx, left, right );
return op.wrap( values[0] ne values[1] );
};
const string_greater_than := function ( op, ev, ast, ctx, left, right ) {
const values := string_operands( ev, ctx, left, right );
return op.wrap( values[0] gt values[1] );
};
const string_greater_than_or_equal := function ( op, ev, ast, ctx, left, right ) {
const values := string_operands( ev, ctx, left, right );
return op.wrap( values[0] ge values[1] );
};
const string_less_than := function ( op, ev, ast, ctx, left, right ) {
const values := string_operands( ev, ctx, left, right );
return op.wrap( values[0] lt values[1] );
};
const string_less_than_or_equal := function ( op, ev, ast, ctx, left, right ) {
const values := string_operands( ev, ctx, left, right );
return op.wrap( values[0] le values[1] );
};
const string_compare := function ( op, ev, ast, ctx, left, right ) {
const values := string_operands( ev, ctx, left, right );
return op.wrap( values[0] cmp values[1] );
};
const string_equality_insensitive := function ( op, ev, ast, ctx, left, right ) {
const values := string_operands( ev, ctx, left, right );
const left_val := lc values[0];
const right_val := lc values[1];
return op.wrap( left_val eq right_val );
};
const string_inequality_insensitive := function ( op, ev, ast, ctx, left, right ) {
const values := string_operands( ev, ctx, left, right );
const left_val := lc values[0];
const right_val := lc values[1];
return op.wrap( left_val ne right_val );
};
const string_greater_than_insensitive := function ( op, ev, ast, ctx, left, right ) {
const values := string_operands( ev, ctx, left, right );
const left_val := lc values[0];
const right_val := lc values[1];
return op.wrap( left_val gt right_val );
};
const string_greater_than_or_equal_insensitive := function (
op,
ev,
ast,
ctx,
left,
right,
) {
const values := string_operands( ev, ctx, left, right );
const left_val := lc values[0];
const right_val := lc values[1];
return op.wrap( left_val ge right_val );
};
const string_less_than_insensitive := function ( op, ev, ast, ctx, left, right ) {
const values := string_operands( ev, ctx, left, right );
const left_val := lc values[0];
const right_val := lc values[1];
return op.wrap( left_val lt right_val );
};
const string_less_than_or_equal_insensitive := function (
op,
ev,
ast,
ctx,
left,
right,
) {
const values := string_operands( ev, ctx, left, right );
const left_val := lc values[0];
const right_val := lc values[1];
return op.wrap( left_val le right_val );
};
const string_compare_insensitive := function ( op, ev, ast, ctx, left, right ) {
const values := string_operands( ev, ctx, left, right );
const left_val := lc values[0];
const right_val := lc values[1];
return op.wrap( left_val cmp right_val );
};
const regexp_match := function ( op, ev, ast, ctx, left, right ) {
const values := string_operands( ev, ctx, left, right );
return op.wrap( values[0] ~ values[1] );
};
const bitwise_and := function ( op, ev, ast, ctx, left, right ) {
const left_val := op._handle_numeric_operand( ev, ctx, left );
const right_val := op._handle_numeric_operand( ev, ctx, right );
return op.wrap( left_val & right_val );
};
const bitwise_xor := function ( op, ev, ast, ctx, left, right ) {
const left_val := op._handle_numeric_operand( ev, ctx, left );
const right_val := op._handle_numeric_operand( ev, ctx, right );
return op.wrap( left_val ^ right_val );
};
const bitwise_or := function ( op, ev, ast, ctx, left, right ) {
const left_val := op._handle_numeric_operand( ev, ctx, left );
const right_val := op._handle_numeric_operand( ev, ctx, right );
return op.wrap( left_val | right_val );
};
function first_eval_value ( values ) {
return values.length() > 0 ? values[0] : null;
}
function primitive_eval_value ( values ) {
const first := first_eval_value(values);
return first ≡ null ? null : first.primitive_value();
}
function collection_operand ( ev, ctx, expr ) {
const values := ev.eval_expr( expr, ev.nested_ctx( ctx ) );
if ( values.length() = 1 ) {
return values[0].primitive_value();
}
return values.map( fn value → value.primitive_value() );
}
const logical_and := function ( op, ev, ast, ctx, left, right ) {
const left_vals := ev.eval_expr( left, ev.nested_ctx( ctx ) );
if ( ev.truthy( first_eval_value(left_vals) ) ) {
return ev.eval_expr( right, ev.nested_ctx( ctx ) );
}
return op.wrap(false);
};
const logical_nand := function ( op, ev, ast, ctx, left, right ) {
const left_vals := ev.eval_expr( left, ev.nested_ctx( ctx ) );
if ( not ev.truthy( first_eval_value(left_vals) ) ) {
return op.wrap(true);
}
const right_vals := ev.eval_expr( right, ev.nested_ctx( ctx ) );
return op.wrap( ev.truthy( first_eval_value(right_vals) ) ? false : true );
};
const logical_xor := function ( op, ev, ast, ctx, left, right ) {
const left_vals := ev.eval_expr( left, ev.nested_ctx( ctx ) );
const right_vals := ev.eval_expr( right, ev.nested_ctx( ctx ) );
const left_truth := ev.truthy( first_eval_value(left_vals) );
const right_truth := ev.truthy( first_eval_value(right_vals) );
return op.wrap( ( left_truth xor right_truth ) ? true : false );
};
const logical_or := function ( op, ev, ast, ctx, left, right ) {
const left_vals := ev.eval_expr( left, ev.nested_ctx( ctx ) );
if ( ev.truthy( first_eval_value(left_vals) ) ) {
return op.wrap(true);
}
const right_vals := ev.eval_expr( right, ev.nested_ctx( ctx ) );
return op.wrap( ev.truthy( first_eval_value(right_vals) ) ? true : false );
};
const set_union := function ( op, ev, ast, ctx, left, right ) {
const left_val := collection_operand( ev, ctx, left );
const right_val := collection_operand( ev, ctx, right );
return op.wrap( left_val union right_val );
};
const set_intersection := function ( op, ev, ast, ctx, left, right ) {
const left_val := collection_operand( ev, ctx, left );
const right_val := collection_operand( ev, ctx, right );
return op.wrap( left_val intersection right_val );
};
const set_difference := function ( op, ev, ast, ctx, left, right ) {
const left_val := collection_operand( ev, ctx, left );
const right_val := collection_operand( ev, ctx, right );
return op.wrap( left_val ∖ right_val );
};
const collection_membership := function ( op, ev, ast, ctx, left, right ) {
const left_vals := ev.eval_expr( left, ev.nested_ctx( ctx ) );
const left_val := primitive_eval_value(left_vals);
const right_val := collection_operand( ev, ctx, right );
return op.wrap( left_val in right_val );
};
const collection_non_membership := function ( op, ev, ast, ctx, left, right ) {
const left_vals := ev.eval_expr( left, ev.nested_ctx( ctx ) );
const left_val := primitive_eval_value(left_vals);
const right_val := collection_operand( ev, ctx, right );
return op.wrap( left_val ∉ right_val );
};
const set_subsetof := function ( op, ev, ast, ctx, left, right ) {
const left_val := collection_operand( ev, ctx, left );
const right_val := collection_operand( ev, ctx, right );
return op.wrap( left_val subsetof right_val );
};
const set_supersetof := function ( op, ev, ast, ctx, left, right ) {
const left_val := collection_operand( ev, ctx, left );
const right_val := collection_operand( ev, ctx, right );
return op.wrap( left_val supersetof right_val );
};
const set_equivalentof := function ( op, ev, ast, ctx, left, right ) {
const left_val := collection_operand( ev, ctx, left );
const right_val := collection_operand( ev, ctx, right );
return op.wrap( left_val equivalentof right_val );
};
const type_aware_equality := function ( op, ev, ast, ctx, left, right ) {
const left_vals := ev.eval_expr( left, ev.nested_ctx( ctx ) );
const right_vals := ev.eval_expr( right, ev.nested_ctx( ctx ) );
return op.wrap( ev.equals(
first_eval_value(left_vals),
first_eval_value(right_vals),
) );
};
const type_aware_inequality := function ( op, ev, ast, ctx, left, right ) {
const left_vals := ev.eval_expr( left, ev.nested_ctx( ctx ) );
const right_vals := ev.eval_expr( right, ev.nested_ctx( ctx ) );
return op.wrap( not ev.equals(
first_eval_value(left_vals),
first_eval_value(right_vals),
) );
};
function builtin_can ( value, method_name ) {
return false if value ≡ null
or method_name ≡ null
or method_name eq "";
if ( value instanceof Array or value instanceof Bag or value instanceof Set ) {
return method_name in [
"length",
"empty",
"contains",
"push",
"to_Array",
"to_Bag",
"to_Set",
];
}
if ( value instanceof Dict or value instanceof PairList ) {
return method_name in [
"length",
"empty",
"exists",
"keys",
"values",
"to_Array",
];
}
if ( value instanceof String or value instanceof BinaryString ) {
return method_name in [ "length" ];
}
return false;
}
const object_can := function ( op, ev, ast, ctx, left, right ) {
const left_vals := ev.eval_expr( left, ev.nested_ctx( ctx ) );
const right_vals := ev.eval_expr( right, ev.nested_ctx( ctx ) );
const left_val := primitive_eval_value(left_vals);
const right_val := primitive_eval_value(right_vals);
return op.wrap(
( left_val can (right_val) ) or builtin_can( left_val, right_val )
);
};
const STANDARD_OPERATORS := [
new Operator(
spelling: "?:",
kind: "ELVIS",
precedence: 1,
lex_ignore: true,
),
new Operator(
spelling: "+",
kind: "UPLUS",
unary: true,
precedence: 20,
f: function ( op, ev, ast, ctx, expr ) {
const value := op._handle_numeric_operand( ev, ctx, expr );
return op.wrap( +value );
},
),
new Operator(
spelling: "-",
kind: "UMINUS",
unary: true,
precedence: 20,
f: function ( op, ev, ast, ctx, expr ) {
const value := op._handle_numeric_operand( ev, ctx, expr );
return op.wrap( -value );
},
),
new Operator(
spelling: "√",
kind: "SQRT",
unary: true,
precedence: 20,
f: function ( op, ev, ast, ctx, expr ) {
const value := op._handle_numeric_operand( ev, ctx, expr );
return op.wrap( sqrt value );
},
),
new Operator(
spelling: "!",
kind: "NOT",
unary: true,
precedence: 20,
f: logical_negation,
),
new Operator(
spelling: "¬",
kind: "NOTSYM",
unary: true,
precedence: 20,
f: logical_negation,
),
new Operator(
spelling: "**",
kind: "POW",
require_ws: true,
right_assoc: true,
precedence: 13,
f: numeric_power,
),
new Operator(
spelling: "×",
kind: "TIMES_SIGN",
precedence: 12,
f: numeric_multiplication,
),
new Operator(
spelling: "*",
kind: "TIMES",
require_ws: true,
precedence: 12,
lex_ignore: true,
alias: "STAR",
f: numeric_multiplication,
),
new Operator(
spelling: "÷",
kind: "DIVIDE_SIGN",
precedence: 12,
f: numeric_division,
),
new Operator(
spelling: "/",
kind: "DIVIDE",
require_ws: true,
precedence: 12,
lex_ignore: true,
alias: "SLASH",
f: numeric_division,
),
new Operator(
spelling: "mod",
kind: "MOD",
precedence: 12,
f: numeric_modulus,
),
new Operator(
spelling: "+",
kind: "PLUS",
require_ws: true,
precedence: 11,
f: numeric_addition,
),
new Operator(
spelling: "-",
kind: "MINUS",
require_ws: true,
precedence: 11,
f: numeric_subtraction,
),
new Operator(
spelling: "=",
kind: "EQ",
precedence: 5,
f: numeric_equality,
),
new Operator(
spelling: "≠",
kind: "NE",
precedence: 5,
f: numeric_inequality,
),
new Operator(
spelling: "<",
kind: "LT",
precedence: 5,
f: numeric_less_than,
),
new Operator(
spelling: ">",
kind: "GT",
precedence: 5,
f: numeric_greater_than,
),
new Operator(
spelling: "≤",
kind: "LE_SIGN",
precedence: 5,
f: numeric_less_than_or_equal,
),
new Operator(
spelling: "<=",
kind: "LE",
precedence: 5,
f: numeric_less_than_or_equal,
),
new Operator(
spelling: "≥",
kind: "GE_SIGN",
precedence: 5,
f: numeric_greater_than_or_equal,
),
new Operator(
spelling: ">=",
kind: "GE",
precedence: 5,
f: numeric_greater_than_or_equal,
),
new Operator(
spelling: "≶",
kind: "CMP_SIGN",
precedence: 5,
f: numeric_compare,
),
new Operator(
spelling: "<=>",
kind: "CMP",
precedence: 5,
f: numeric_compare,
),
new Operator(
spelling: "≷",
kind: "CMP_REV_SIGN",
precedence: 5,
f: numeric_compare,
),
new Operator(
spelling: "_",
kind: "CONCAT",
require_ws: true,
precedence: 10,
f: string_concatenation,
),
new Operator(
spelling: "eq",
kind: "STR_EQ",
precedence: 5,
f: string_equality,
),
new Operator(
spelling: "ne",
kind: "STR_NE",
precedence: 5,
f: string_inequality,
),
new Operator(
spelling: "gt",
kind: "STR_GT",
precedence: 5,
f: string_greater_than,
),
new Operator(
spelling: "ge",
kind: "STR_GE",
precedence: 5,
f: string_greater_than_or_equal,
),
new Operator(
spelling: "lt",
kind: "STR_LT",
precedence: 5,
f: string_less_than,
),
new Operator(
spelling: "le",
kind: "STR_LE",
precedence: 5,
f: string_less_than_or_equal,
),
new Operator(
spelling: "cmp",
kind: "STR_CMP",
precedence: 5,
f: string_compare,
),
new Operator(
spelling: "eqi",
kind: "STR_EQI",
precedence: 5,
f: string_equality_insensitive,
),
new Operator(
spelling: "nei",
kind: "STR_NEI",
precedence: 5,
f: string_inequality_insensitive,
),
new Operator(
spelling: "gti",
kind: "STR_GTI",
precedence: 5,
f: string_greater_than_insensitive,
),
new Operator(
spelling: "gei",
kind: "STR_GEI",
precedence: 5,
f: string_greater_than_or_equal_insensitive,
),
new Operator(
spelling: "lti",
kind: "STR_LTI",
precedence: 5,
f: string_less_than_insensitive,
),
new Operator(
spelling: "lei",
kind: "STR_LEI",
precedence: 5,
f: string_less_than_or_equal_insensitive,
),
new Operator(
spelling: "cmpi",
kind: "STR_CMPI",
precedence: 5,
f: string_compare_insensitive,
),
new Operator(
spelling: "~",
kind: "REGEXP_MATCH",
precedence: 5,
f: regexp_match,
),
new Operator(
spelling: "&",
kind: "BAND",
precedence: 8,
f: bitwise_and,
),
new Operator(
spelling: "^",
kind: "BXOR",
precedence: 7,
f: bitwise_xor,
),
new Operator(
spelling: "|",
kind: "BOR",
precedence: 6,
f: bitwise_or,
),
new Operator(
spelling: "⋀",
kind: "LAND_SIGN",
precedence: 3,
f: logical_and,
),
new Operator(
spelling: "and",
kind: "LAND",
precedence: 3,
f: logical_and,
),
new Operator(
spelling: "⊼",
kind: "LNAND_SIGN",
precedence: 3,
f: logical_nand,
),
new Operator(
spelling: "nand",
kind: "LNAND",
precedence: 3,
f: logical_nand,
),
new Operator(
spelling: "⊻",
kind: "LXOR_SIGN",
precedence: 2,
f: logical_xor,
),
new Operator(
spelling: "xor",
kind: "LXOR",
precedence: 2,
f: logical_xor,
),
new Operator(
spelling: "⋁",
kind: "LOR_SIGN",
precedence: 1,
f: logical_or,
),
new Operator(
spelling: "or",
kind: "LOR",
precedence: 1,
f: logical_or,
),
new Operator(
spelling: "⋃",
kind: "SET_UNION_SIGN",
precedence: 9,
f: set_union,
),
new Operator(
spelling: "union",
kind: "SET_UNION",
precedence: 9,
f: set_union,
),
new Operator(
spelling: "⋂",
kind: "SET_INTERSECTION_SIGN",
precedence: 9,
f: set_intersection,
),
new Operator(
spelling: "intersection",
kind: "SET_INTERSECTION",
precedence: 9,
f: set_intersection,
),
new Operator(
spelling: "∖",
kind: "SET_DIFFERENCE_SIGN",
precedence: 9,
f: set_difference,
),
new Operator(
spelling: "\\",
kind: "SET_DIFFERENCE",
precedence: 9,
require_ws: true,
f: set_difference,
),
new Operator(
spelling: "∈",
kind: "MEMBER_SIGN",
precedence: 5,
f: collection_membership,
),
new Operator(
spelling: "in",
kind: "MEMBER",
precedence: 5,
f: collection_membership,
),
new Operator(
spelling: "∉",
kind: "NOT_MEMBER_SIGN",
precedence: 5,
f: collection_non_membership,
),
new Operator(
spelling: "⊂",
kind: "SUBSETOF_SIGN",
precedence: 5,
f: set_subsetof,
),
new Operator(
spelling: "subsetof",
kind: "SUBSETOF",
precedence: 5,
f: set_subsetof,
),
new Operator(
spelling: "⊃",
kind: "SUPERSETOF_SIGN",
precedence: 5,
f: set_supersetof,
),
new Operator(
spelling: "supersetof",
kind: "SUPERSETOF",
precedence: 5,
f: set_supersetof,
),
new Operator(
spelling: "⊂⊃",
kind: "EQUIVALENTOF_SIGN",
precedence: 5,
f: set_equivalentof,
),
new Operator(
spelling: "equivalentof",
kind: "EQUIVALENTOF",
precedence: 5,
f: set_equivalentof,
),
new Operator(
spelling: "≡",
kind: "TYPE_EQ_SIGN",
precedence: 4,
f: type_aware_equality,
),
new Operator(
spelling: "==",
kind: "TYPE_EQ",
precedence: 4,
f: type_aware_equality,
),
new Operator(
spelling: "≢",
kind: "TYPE_NE_SIGN",
precedence: 4,
f: type_aware_inequality,
),
new Operator(
spelling: "!=",
kind: "TYPE_NE",
precedence: 4,
f: type_aware_inequality,
),
new Operator(
spelling: "can",
kind: "CAN",
precedence: 5,
f: object_can,
),
new Operator(
spelling: "~",
kind: "BNOT",
unary: true,
precedence: 20,
f: function ( op, ev, ast, ctx, expr ) {
const value := op._handle_numeric_operand( ev, ctx, expr );
return op.wrap( ~value );
},
),
];
std/path/zz/operators
Standard Library source code
Operator definitions for ZZPath expressions.
Module
- Name
std/path/zz/operators- Area
- Standard Library
- Source
modules/std/path/zz/operators.zzm