JE
view release on metacpan or search on metacpan
lib/JE/Code.pm view on Meta::CPAN
sub _create_vars { # Process var and function declarations
my $vars = $code->{vars};
for(@$vars) {
if(ref) { # function
# format: [[...], function=> 'name',
# [ (params) ], $statements_obj, \@vars ]
# With optimisation on, the $statements_obj will
# actually be a code object.
$scope->[-1]->delete($$_[2], 1);
my $new_code_obj;
if(ref $$_[4] eq 'JE::Code') {
$new_code_obj = $$_[4]
}
else {
($new_code_obj = bless {
map+($_=>$code->{$_}),
qw/global source file line/
}, 'JE::Code')
->{tree} = $$_[4];
$new_code_obj->{vars} = $$_[5];
}
$scope->new_var($$_[2], new JE::Object::Function {
scope => $scope,
name => $$_[2],
argnames => $$_[3],
function => $new_code_obj
});
}
else {
$scope->new_var($_);
}
}
}
package JE::Code::Expression;
our $VERSION = '0.066';
# B::Deparse showed me how to get these values.
use constant nan => sin 9**9**9;
use constant inf => 9**9**9;
use subs qw'_eval_term';
use POSIX 'fmod';
use Scalar::Util 'tainted';
import JE::Code 'add_line_number';
sub add_line_number;
BEGIN{*T = *JE::Code::T;}
#----------for reference------------#
#sub _to_int {
# call to_number first
# then...
# NaN becomes 0
# 0 and Infinity remain as they are
# other nums are rounded towards zero ($_ <=> 0) * floor(abs)
#}
# Note that abs in ECMA-262
#sub _to_uint32 {
# call to_number, then ...
# return 0 for Nan, -?inf and 0
# (round toward zero) % 2 ** 32
#}
#sub _to_int32 {
# calculate _to_uint32 but subtract 2**32 if the result >= 2**31
#}
#sub _to_uint16 {
# just like _to_uint32, except that 2**16 is used instead.
#}
#---------------------------------#
{ # JavaScript operators
# Note: some operators are not dealt with here, but inside
# sub eval.
no strict 'refs';
*{'predelete'} = sub {
ref(my $term = shift) eq 'JE::LValue' or return
new JE::Boolean $global, 1;
my $base = $term->base;
new JE::Boolean $global,
defined $base ? $base->delete($term->property) : 1;
};
*{'prevoid'} = sub {
my $term = shift;
$term = get $term while ref $term eq 'JE::LValue';
return $global->undefined;
};
*{'pretypeof'} = sub {
my $term = shift;
ref $term eq 'JE::LValue' and
ref base $term eq '' and
return _new JE::String $global, 'undefined';
_new JE::String $global, typeof $term;
};
*{'pre++'} = sub {
# ~~~ These is supposed to use the same rules
# as the + infix op for the actual
# addition part. Verify that it does this.
my $term = shift;
$term->set(new JE::Number $global,
get $term->to_number + 1);
};
*{'pre--'} = sub {
# ~~~ These is supposed to use the same rules
# as the - infix op for the actual
# subtraction part. Verify that it does this.
my $term = shift;
$term->set(new JE::Number $global,
( run in 1.321 second using v1.01-cache-2.11-cpan-39bf76dae61 )