<commit_before># $Id$

=head1 NAME

src/grammar/expr/operators.pir - [expr] operator definitions.

=head2 Prefix Operators

=cut

.HLL 'Tcl', ''
.namespace

# XXX No strings.
.sub 'prefix:+' # unary plus
    .param pmc a
    $N0 = a
    .return ($N0)
.end

# XXX No strings.
.sub 'prefix:-'     # unary minus
    .param pmc a
    $N0 = a
    $N0 = neg $N0
    .return ($N0)
.end

# XXX Integer Only
.sub 'prefix:~'     # bit-wise NOT
    .param int a
    $I0 = bnot a
    .return ($I0)
.end

# XXX No strings.
.sub 'prefix:!'     # logical NOT
    .param int a
    $I0 = not a
    .return ($I0)
.end

=head2 Infix Operators

&&, || (and ?:) are handled during the PGE transformation stage.

=cut

# this is used to make double-quoted strings work
# (they're a series of captures that need to be concatenated)
.sub 'infix:concat'
    .param pmc a
    .param pmc b

    $S0 = a
    $S1 = b
    $S0 = $S0 . $S1

    $P0 = new 'TclString'
    $P0 = $S0
    .return($P0)
.end

.sub 'infix:*'  
    .param pmc a
    .param pmc b
<commit_msg>[tcl]: Make [expr] unary ops work/fail correctly with strings<commit_after># $Id$

=head1 NAME

src/grammar/expr/operators.pir - [expr] operator definitions.

=head2 Prefix Operators

=cut

.HLL 'Tcl', ''
.namespace

# unary plus
.sub 'prefix:+' :multi(String)
    .param pmc a

    .local pmc __number
    __number = get_root_global ['_tcl'], '__number'

    push_eh is_string
      a = __number(a)
    clear_eh

    .return(a)

is_string:
    .throw("can't use non-numeric string as operand of \"+\"")
.end

.sub 'prefix:+' :multi(pmc)
    .param pmc a
    $N0 = a
    .return ($N0)
.end

# unary minus
.sub 'prefix:-' :multi(String)
    .param pmc a

    .local pmc __number
    __number = get_root_global ['_tcl'], '__number'

    push_eh is_string
      a = __number(a)
    clear_eh

    $N0 = a
    $N0 = neg $N0
    .return($N0)

is_string:
    .throw("can't use non-numeric string as operand of \"-\"")
.end

.sub 'prefix:-' :multi(pmc)
    .param pmc a
    $N0 = a
    $N0 = neg $N0
    .return ($N0)
.end

# bit-wise NOT
.sub 'prefix:~' :multi(String)
    .param pmc a

    .local pmc __number
    __number = get_root_global ['_tcl'], '__number'

    push_eh is_string
      a = __number(a)
    clear_eh

    $I0 = a
    $I0 = bnot $I0
    .return($I0)

is_string:
    .throw("can't use non-numeric string as operand of \"~\"")
.end

.sub 'prefix:~' :multi(pmc)
    .param int a
    $I0 = bnot a
    .return ($I0)
.end

# logical NOT
.sub 'prefix:!' :multi(String)
    .param pmc a

    .local pmc __number
    __number = get_root_global ['_tcl'], '__number'

    push_eh is_string
      a = __number(a)
    clear_eh

    $I0 = a
    $I0 = not $I0
    .return($I0)

is_string:
    .throw("can't use non-numeric string as operand of \"!\"")
.end

.sub 'prefix:!' :multi(pmc)
    .param int a
    $I0 = not a
    .return ($I0)
.end

=head2 Infix Operators

&&, || (and ?:) are handled during the PGE transformation stage.

=cut

# this is used to make double-quoted strings work
# (they're a series of captures that need to be concatenated)
.sub 'infix:concat'
    .param pmc a
    .param pmc b

    $S0 = a
    $S1 = b
    $S0 = $S0 . $S1

    $P0 = new 'TclString'
    $P0 = $S0
    .return($P0)
.end

.sub 'infix:*'  
    .param pmc a
    .param pmc b

{'fraction_non_alphanumeric': 0.14160097028502122, 'fraction_numerical': 0.016979987871437233, 'mean_word_length': 2.2924151696606785, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7649721', 'n_tokens_mistral': 1361, 'n_tokens_neox': 1330, 'n_words': 407}