<commit_before>package P6C::IMCC::Binop;
use strict;
use SelfLoader;
use Data::Dumper;
use Carp 'confess';
use P6C::IMCC ':all';
use P6C::Util ':all';
use P6C::Context;
require P6C::IMCC::ExtRegex;
require Exporter;
use vars qw(@ISA %EXPORT_TAGS @EXPORT_OK);
@ISA = qw(Exporter);
@EXPORT_OK = qw(do_pow do_logand do_logor do_defined do_concat do_repeat
		do_range do_smartmatch imcc_op simple_binary simple_binary_pasm);
%EXPORT_TAGS = (all => [@EXPORT_OK]);

sub do_pow ;
sub do_logand ;
sub do_logor ;
sub do_defined ;
sub do_concat ;
sub do_repeat ;
sub do_range ;

sub do_smartmatch ;
sub smartmatch_type ;
sub sm_array_num ;
sub sm_hash_scalar ;
sub sm_expr_num ;
sub sm_expr_str ;

# Remap operator symbols from P6 to IMCC.
sub imcc_op {
	my $op = shift;
	return "~~" if ($op eq '^^');
	return "."  if ($op eq '~');
	return "|"  if ($op eq '+|');
	return "&"  if ($op eq '+&');
	return "~"  if ($op eq '+^');
	return $op;
}

# Remap operator symbols from P6 to PASM opcodes
sub pasm_op {
	my $op = shift;
	return "bands" if ($op eq '~&');
	return "bors"  if ($op eq '~|');
	return "bxors" if ($op eq '~^');
	return $op;
}

#
# Create generic code for $a op $b.
sub simple_binary {
    my $x = shift;
    my $ltmp = $x->l->val;
    my $rtmp = $x->r->val;
    my $dest = newtmp 'PerlUndef';
    my $op = imcc_op($x->op);
    code("\t$dest = $ltmp $op $rtmp\n");
    return $dest;
}

#
# Some p6 operators correspond to a single PASM opcode but don't
# have PIR syntax.
sub simple_binary_pasm {
    my $x = shift;
    my $dest = newtmp 'PerlUndef';
    my $ltmp = $x->l->val;
    my $rtmp = $x->r->val;
    my $opcode = pasm_op($x->op);
    code("\t$opcode $dest, $ltmp, $rtmp\n");
    return $dest;
}

1;

__DATA__

package P6C::IMCC::Binop;

# XXX: exponentiation in a loop.  Will be replaced once IMCC allows more ops.
sub do_pow {
    my $x = shift;
    my $lv = $x->l->val;
    my $rv = $x->r->val;
    my $cnt = gentmp 'int';
    my $ln = newtmp 'num';
    my $rn = newtmp 'num';
    my $dn = newtmp 'num';
    code(<<END);
       $ln = $lv
       $rn = $rv
       $dn = $ln ** $rn
END
    return primitive_in_context($dn, 'num', $x->{ctx});
}

# short-circuit logical '&&' operator
# XXX: returns scalar undef when false in array context.  Bad.
sub do_logand {
    my $x = shift;
    my $dest = newtmp 'PerlUndef';
    my $thenlab = genlabel 'logical_and';
    my $endlab = genlabel 'logical_and';
    my $res = $x->l->val;
    code(<<END);
	if $res goto $thenlab
	goto $endlab<commit_msg>Right now, I think we should be nicest to whoever's debugging, rather than worrying about the load time. Maybe once we get away from the mind-numbingly slow parser...<commit_after>package P6C::IMCC::Binop;
use strict;
#use SelfLoader;
use Data::Dumper;
use Carp 'confess';
use P6C::IMCC ':all';
use P6C::Util ':all';
use P6C::Context;
require P6C::IMCC::ExtRegex;
require Exporter;
use vars qw(@ISA %EXPORT_TAGS @EXPORT_OK);
@ISA = qw(Exporter);
@EXPORT_OK = qw(do_pow do_logand do_logor do_defined do_concat do_repeat
		do_range do_smartmatch imcc_op simple_binary simple_binary_pasm);
%EXPORT_TAGS = (all => [@EXPORT_OK]);

sub do_pow ;
sub do_logand ;
sub do_logor ;
sub do_defined ;
sub do_concat ;
sub do_repeat ;
sub do_range ;

sub do_smartmatch ;
sub smartmatch_type ;
sub sm_array_num ;
sub sm_hash_scalar ;
sub sm_expr_num ;
sub sm_expr_str ;

# Remap operator symbols from P6 to IMCC.
sub imcc_op {
	my $op = shift;
	return "~~" if ($op eq '^^');
	return "."  if ($op eq '~');
	return "|"  if ($op eq '+|');
	return "&"  if ($op eq '+&');
	return "~"  if ($op eq '+^');
	return $op;
}

# Remap operator symbols from P6 to PASM opcodes
sub pasm_op {
	my $op = shift;
	return "bands" if ($op eq '~&');
	return "bors"  if ($op eq '~|');
	return "bxors" if ($op eq '~^');
	return $op;
}

#
# Create generic code for $a op $b.
sub simple_binary {
    my $x = shift;
    my $ltmp = $x->l->val;
    my $rtmp = $x->r->val;
    my $dest = newtmp 'PerlUndef';
    my $op = imcc_op($x->op);
    code("\t$dest = $ltmp $op $rtmp\n");
    return $dest;
}

#
# Some p6 operators correspond to a single PASM opcode but don't
# have PIR syntax.
sub simple_binary_pasm {
    my $x = shift;
    my $dest = newtmp 'PerlUndef';
    my $ltmp = $x->l->val;
    my $rtmp = $x->r->val;
    my $opcode = pasm_op($x->op);
    code("\t$opcode $dest, $ltmp, $rtmp\n");
    return $dest;
}

1;

# __DATA__

package P6C::IMCC::Binop;

# XXX: exponentiation in a loop.  Will be replaced once IMCC allows more ops.
sub do_pow {
    my $x = shift;
    my $lv = $x->l->val;
    my $rv = $x->r->val;
    my $cnt = gentmp 'int';
    my $ln = newtmp 'num';
    my $rn = newtmp 'num';
    my $dn = newtmp 'num';
    code(<<END);
       $ln = $lv
       $rn = $rv
       $dn = $ln ** $rn
END
    return primitive_in_context($dn, 'num', $x->{ctx});
}

# short-circuit logical '&&' operator
# XXX: returns scalar undef when false in array context.  Bad.
sub do_logand {
    my $x = shift;
    my $dest = newtmp 'PerlUndef';
    my $thenlab = genlabel 'logical_and';
    my $endlab = genlabel 'logical_and';
    my $res = $x->l->val;
    code(<<END);
	if $res goto $thenlab
	goto $endlab
{'fraction_non_alphanumeric': 0.1614280170741172, 'fraction_numerical': 0.0038804811796662787, 'mean_word_length': 3.3030050083472453, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 39, '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': '3608104', 'n_tokens_mistral': 2100, 'n_tokens_neox': 2053, 'n_words': 628}