Skip to content

Commit

Permalink
- Simplified and generalized the support for local variables.
Browse files Browse the repository at this point in the history
They can now localize entire expressions, instead of only strict variable names.

Example:
	local hash{:key} = 42;		# localize an element inside an hash

However, for the sake of simplicity, local variable no longer can declare new variables.

Example:
	local new_var = "foo";		# "new_var" is declared as a global variable (with a warning)
  • Loading branch information
trizen committed Nov 1, 2015
1 parent 11e952b commit 4409629
Show file tree
Hide file tree
Showing 11 changed files with 59 additions and 122 deletions.
5 changes: 1 addition & 4 deletions MANIFEST
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,6 @@ lib/Sidef/Variable/Label.pm
lib/Sidef/Variable/Label.pod
lib/Sidef/Variable/LazyMethod.pm
lib/Sidef/Variable/Local.pm
lib/Sidef/Variable/LocalInit.pm
lib/Sidef/Variable/LocalInit.pod
lib/Sidef/Variable/LocalMagic.pm
lib/Sidef/Variable/LocalMagic.pod
lib/Sidef/Variable/Magic.pm
lib/Sidef/Variable/Magic.pod
lib/Sidef/Variable/NamedParam.pm
Expand Down Expand Up @@ -629,6 +625,7 @@ scripts/Tests/levenshtein_distance_cached.sf
scripts/Tests/Lingua/RO/Numbers.sm
scripts/Tests/lingua_ro.sf
scripts/Tests/lingua_ro_numbers.sf
scripts/Tests/local_vars.sf
scripts/Tests/logic.sf
scripts/Tests/long_division.sf
scripts/Tests/longest_common_prefix.sf
Expand Down
6 changes: 0 additions & 6 deletions META.json
Original file line number Diff line number Diff line change
Expand Up @@ -290,12 +290,6 @@
"Sidef::Variable::Local" : {
"file" : "lib/Sidef/Variable/Local.pm"
},
"Sidef::Variable::LocalInit" : {
"file" : "lib/Sidef/Variable/LocalInit.pm"
},
"Sidef::Variable::LocalMagic" : {
"file" : "lib/Sidef/Variable/LocalMagic.pm"
},
"Sidef::Variable::Magic" : {
"file" : "lib/Sidef/Variable/Magic.pm"
},
Expand Down
4 changes: 0 additions & 4 deletions META.yml
Original file line number Diff line number Diff line change
Expand Up @@ -172,10 +172,6 @@ provides:
file: lib/Sidef/Variable/LazyMethod.pm
Sidef::Variable::Local:
file: lib/Sidef/Variable/Local.pm
Sidef::Variable::LocalInit:
file: lib/Sidef/Variable/LocalInit.pm
Sidef::Variable::LocalMagic:
file: lib/Sidef/Variable/LocalMagic.pm
Sidef::Variable::Magic:
file: lib/Sidef/Variable/Magic.pm
Sidef::Variable::NamedParam:
Expand Down
8 changes: 1 addition & 7 deletions lib/Sidef/Deparse/Perl.pm
Original file line number Diff line number Diff line change
Expand Up @@ -605,14 +605,8 @@ HEADER
$Sidef::SPACES -= $Sidef::SPACES_INCR;
}
}
elsif ($ref eq 'Sidef::Variable::LocalInit') {
$code = 'local $' . $obj->{class} . '::' . $obj->{name};
}
elsif ($ref eq 'Sidef::Variable::LocalMagic') {
$code = 'local ' . $obj->{name};
}
elsif ($ref eq 'Sidef::Variable::Local') {
$code = '$' . $obj->{class} . '::' . $obj->{name};
$code = 'local ' . $self->deparse_script($obj->{expr});
}
elsif ($ref eq 'Sidef::Variable::Global') {
$code = '$' . $obj->{class} . '::' . $obj->{name},;
Expand Down
11 changes: 1 addition & 10 deletions lib/Sidef/Deparse/Sidef.pm
Original file line number Diff line number Diff line change
Expand Up @@ -201,11 +201,8 @@ package Sidef::Deparse::Sidef {
$code = "struct $obj->{name} {" . $self->_dump_vars(@{$obj->{vars}}) . '}';
}
}
elsif ($ref eq 'Sidef::Variable::LocalInit') {
$code = "local $obj->{name}";
}
elsif ($ref eq 'Sidef::Variable::Local') {
$code = "$obj->{name}";
$code = 'local ' . '(' . $self->deparse_script($obj->{expr}) . ')';
}
elsif ($ref eq 'Sidef::Variable::Global') {
$code = 'global ' . $obj->{class} . '::' . $obj->{name},;
Expand All @@ -216,12 +213,6 @@ package Sidef::Deparse::Sidef {
elsif ($ref eq 'Sidef::Variable::ConstInit') {
$code = join(";\n" . (" " x $Sidef::SPACES), map { $self->deparse_expr({self => $_}) } @{$obj->{vars}});
}
elsif ($ref eq 'Sidef::Variable::LocalInit') {
$code = 'local ' . $obj->{class} . '::' . $obj->{name};
}
elsif ($ref eq 'Sidef::Variable::LocalMagic') {
$code = 'local ' . $obj->{name};
}
elsif ($ref eq 'Sidef::Types::Range::RangeNumber' or $ref eq 'Sidef::Types::Range::RangeString') {
$code = $self->_dump_reftype($obj);
}
Expand Down
34 changes: 13 additions & 21 deletions lib/Sidef/Parser.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1196,14 +1196,15 @@ package Sidef::Parser {
return {$self->{class} => [{self => $obj, call => [{method => '@*'}]}]};
}

# Localization of magic variables
if (/\Glocal\h*(\$[.,\/\@\\+\-:;"'`><?~!\$%&|()\[\]])/gc) {
return Sidef::Variable::LocalMagic->new(name => $1);
# Local variables
if (/\Glocal\b\h*/gc) {
my $expr = $self->parse_obj(code => $opt{code});
return Sidef::Variable::Local->new(expr => $expr);
}

# Declaration of local variables, classes, methods and functions
if (
/\G(local|global|func|class)\b\h*/gc
/\G(func|class|global)\b\h*/gc
|| /\G(->)\h*/gc
|| (exists($self->{current_class})
&& /\G(method)\b\h*/gc)
Expand Down Expand Up @@ -1257,16 +1258,11 @@ package Sidef::Parser {
}

if ($type ne 'class') {
$name =
/\G($self->{var_name_re})\h*/goc ? $1
: $type eq 'method' && /\G($self->{operators_re})\h*/goc ? $+
: $type ne 'local' ? ''
: $self->fatal_error(
error => "invalid '$type' declaration",
expected => "expected a name",
code => $_,
pos => pos($_)
);
$name = (
/\G($self->{var_name_re})\h*/goc ? $1
: $type eq 'method' && /\G($self->{operators_re})\h*/goc ? $+
: ''
);
($name, $class_name) = $self->get_name_and_class($name);
}

Expand All @@ -1283,11 +1279,10 @@ package Sidef::Parser {
}

my $obj =
$type eq 'local' ? Sidef::Variable::Local->new(name => $name, class => $class_name)
: $type eq 'global' ? Sidef::Variable::Global->new(name => $name, class => $class_name)
: $type eq 'func' ? Sidef::Variable::Variable->new(name => $name, type => $type, class => $class_name)
$type eq 'func' ? Sidef::Variable::Variable->new(name => $name, type => $type, class => $class_name)
: $type eq 'method' ? Sidef::Variable::Variable->new(name => $name, type => $type, class => $class_name)
: $type eq 'class' ? Sidef::Variable::ClassInit->new(name => ($built_in_obj // $name), class => $class_name)
: $type eq 'global' ? Sidef::Variable::Global->new(name => $name, class => $class_name)
: $self->fatal_error(
error => "invalid type",
expected => "expected a magic thing to happen",
Expand Down Expand Up @@ -1327,10 +1322,7 @@ package Sidef::Parser {
};
}

if ($type eq 'local') {
return Sidef::Variable::LocalInit->new(name => $name, class => $class_name);
}
elsif ($type eq 'global') {
if ($type eq 'global') {
return $obj;
}

Expand Down
10 changes: 0 additions & 10 deletions lib/Sidef/Variable/LocalInit.pm

This file was deleted.

25 changes: 0 additions & 25 deletions lib/Sidef/Variable/LocalInit.pod

This file was deleted.

10 changes: 0 additions & 10 deletions lib/Sidef/Variable/LocalMagic.pm

This file was deleted.

25 changes: 0 additions & 25 deletions lib/Sidef/Variable/LocalMagic.pod

This file was deleted.

43 changes: 43 additions & 0 deletions scripts/Tests/local_vars.sf
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/ruby

#
## Test 1
#

class Example {
method foo(arg) {
assert_eq(self{:bar}, arg);
}
}

var obj = Example();

obj{:bar} = 21; # add some value inside the object
obj.foo(21); # call the method foo

do {
local obj{:bar} = 42; # localize the value of 'bar' to 42
obj.foo(42); # call the method foo
assert_eq(obj{:bar}, 42);
}

obj.foo(21); # the value of bar is unlocalized here
assert_eq(obj{:bar}, 21); # test again to be sure


#
## Test 2
#

global x = 42;

do {
assert_eq(x, 42);
local x = 100;
assert_eq(x, 100);
}

assert_eq(x, 42);


say "** Test passed!";

0 comments on commit 4409629

Please sign in to comment.