Skip to content

Commit

Permalink
- Improved the parsing of classes.
Browse files Browse the repository at this point in the history
- Improved the parsing of return type from functions.
- Added the `FileHandle` and `DirHandle` types.
- Merged `PipeHandle` into `FileHandle`. (removed `PipeHandle`)
- Added more tests.
  • Loading branch information
trizen committed Jul 5, 2015
1 parent 53a1520 commit 5c80e36
Show file tree
Hide file tree
Showing 18 changed files with 202 additions and 153 deletions.
3 changes: 1 addition & 2 deletions MANIFEST
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,6 @@ lib/Sidef/Types/Glob/FileHandle.pm
lib/Sidef/Types/Glob/FileHandle.pod
lib/Sidef/Types/Glob/Pipe.pm
lib/Sidef/Types/Glob/Pipe.pod
lib/Sidef/Types/Glob/PipeHandle.pm
lib/Sidef/Types/Glob/PipeHandle.pod
lib/Sidef/Types/Glob/Socket.pm
lib/Sidef/Types/Glob/Socket.pod
lib/Sidef/Types/Glob/SocketHandle.pm
Expand Down Expand Up @@ -370,6 +368,7 @@ scripts/recursion.sf
scripts/regex.sf
scripts/regex_bool.sf
scripts/return.sf
scripts/return_types.sf
scripts/reverse_recursive_general_solution.sf
scripts/reverse_words_in_a_string.sf
scripts/roman_numerals_decoding.sf
Expand Down
3 changes: 0 additions & 3 deletions META.json
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,6 @@
"Sidef::Types::Glob::Pipe" : {
"file" : "lib/Sidef/Types/Glob/Pipe.pm"
},
"Sidef::Types::Glob::PipeHandle" : {
"file" : "lib/Sidef/Types/Glob/PipeHandle.pm"
},
"Sidef::Types::Glob::Socket" : {
"file" : "lib/Sidef/Types/Glob/Socket.pm"
},
Expand Down
2 changes: 0 additions & 2 deletions META.yml
Original file line number Diff line number Diff line change
Expand Up @@ -124,8 +124,6 @@ provides:
file: lib/Sidef/Types/Glob/FileHandle.pm
Sidef::Types::Glob::Pipe:
file: lib/Sidef/Types/Glob/Pipe.pm
Sidef::Types::Glob::PipeHandle:
file: lib/Sidef/Types/Glob/PipeHandle.pm
Sidef::Types::Glob::Socket:
file: lib/Sidef/Types/Glob/Socket.pm
Sidef::Types::Glob::SocketHandle:
Expand Down
3 changes: 3 additions & 0 deletions lib/Sidef/Deparse/Sidef.pm
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,9 @@ package Sidef::Deparse::Sidef {
elsif ($ref eq 'Sidef::Math::Math') {
$code = 'Math';
}
elsif ($ref eq 'Sidef::Types::Glob::DirHandle') {
$code = 'DirHandle';
}
elsif ($ref eq 'Sidef::Types::Glob::FileHandle') {
if ($obj->{fh} eq \*STDIN) {
$code = 'STDIN';
Expand Down
131 changes: 82 additions & 49 deletions lib/Sidef/Parser.pm
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,10 @@ package Sidef::Parser {
| Block\b (?{ state $x = Sidef::Types::Block::Code->new })
| Backtick\b (?{ state $x = Sidef::Types::Glob::Backtick->new })
| ARGF\b (?{ state $x = Sidef::Types::Glob::FileHandle->new(fh => \*ARGV) })
| STDIN\b (?{ state $x = Sidef::Types::Glob::FileHandle->stdin })
| (?:STDIN|FileHandle)\b (?{ state $x = Sidef::Types::Glob::FileHandle->stdin })
| STDOUT\b (?{ state $x = Sidef::Types::Glob::FileHandle->stdout })
| STDERR\b (?{ state $x = Sidef::Types::Glob::FileHandle->stderr })
| DirHandle\b (?{ state $x = Sidef::Types::Glob::Dir->cwd->open })
| Dir\b (?{ state $x = Sidef::Types::Glob::Dir->new })
| File\b (?{ state $x = Sidef::Types::Glob::File->new })
| Fcntl\b (?{ state $x = Sidef::Types::Glob::Fcntl->new })
Expand Down Expand Up @@ -141,31 +142,12 @@ package Sidef::Parser {
| %C\b. (?{ [qw(1 to_chars Sidef::Types::Char::Chars)] })
)
}xs,
keywords => {
built_in_classes => {
map { $_ => 1 }
qw(
next
break
return
for foreach
if while
try loop
given switch
continue
require frequire
true false
nil
import
include
print println say
eval
read
die
warn
File
File FileHandle
Fcntl
Dir
Dir DirHandle
Arr Array Pair
MultiArray MultiArr
Hash
Expand All @@ -191,6 +173,30 @@ package Sidef::Parser {
Backtick
LazyMethod
true false
nil
)
},
keywords => {
map { $_ => 1 }
qw(
next
break
return
for foreach
if while
try loop
given switch
continue
require frequire
import
include
print println say
eval
read
die
warn
my
var
const
Expand Down Expand Up @@ -583,7 +589,7 @@ package Sidef::Parser {
my $class_name;
($name, $class_name) = $self->get_name_and_class($name);

if (exists $self->{keywords}{$name}) {
if (exists($self->{keywords}{$name}) or exists($self->{built_in_classes}{$name})) {
$self->fatal_error(
code => $_,
pos => $-[2],
Expand Down Expand Up @@ -867,7 +873,7 @@ package Sidef::Parser {
if (/\Gdefine\h+($self->{var_name_re})\h*/goc) {
my $name = $1;

if (exists $self->{keywords}{$name}) {
if (exists($self->{keywords}{$name}) or exists($self->{built_in_classes}{$name})) {
$self->fatal_error(
code => $_,
pos => (pos($_) - length($name)),
Expand Down Expand Up @@ -909,7 +915,7 @@ package Sidef::Parser {
$name = $1;
}

if (defined $name and exists $self->{keywords}{$name}) {
if (defined($name) and (exists($self->{keywords}{$name}) or exists($self->{built_in_classes}{$name}))) {
$self->fatal_error(
code => $_,
pos => (pos($_) - length($name)),
Expand Down Expand Up @@ -968,7 +974,7 @@ package Sidef::Parser {
? $var->{value}
: $value->inc;

if (exists $self->{keywords}{$name}) {
if (exists($self->{keywords}{$name}) or exists($self->{built_in_classes}{$name})) {
$self->fatal_error(
code => $_,
pos => (pos($_) - length($name)),
Expand Down Expand Up @@ -1003,26 +1009,40 @@ package Sidef::Parser {
: 'func'
: $1;

my $name = '';
my $class_name = $self->{class};
my $built_in_obj;
if ($type eq 'class' and /\G(?!\{)/) {
my $obj = eval {
if ($type eq 'class' and /\G(?![{(])/) {

my $try_expr;
if (/\G($self->{var_name_re})\h*/gco) {
($name, $class_name) = $self->get_name_and_class($1);
}
else {
$try_expr = 1;
}

if (
$try_expr or exists($self->{built_in_classes}{$name}) or do {
my ($obj) = $self->find_var($name, $class_name);
defined($obj) and $obj->{type} eq 'class';
}
) {
local $self->{_want_name} = 1;
my $code = substr($_, pos);
my ($obj) = $self->parse_expr(code => \$code);
pos($_) += pos($code);
$obj;
};
if (not $@ and defined $obj) {
my ($obj) = $self->parse_expr(code => $try_expr ? $opt{code} : \$name);

$built_in_obj =
ref($obj) eq 'HASH'
? Sidef::Types::Block::Code->new($obj)->run
: Sidef::Types::Block::Code->new({self => $obj})->_execute_expr;

if (defined $built_in_obj) {
$name = '';
}
}
}

my $name = '';
my $class_name = $self->{class};
if (not defined $built_in_obj) {
if ($type ne 'class') {
$name =
/\G($self->{var_name_re})\h*/goc ? $1
: $type eq 'method' && /\G($self->{operators_re})\h*/goc ? $+
Expand All @@ -1038,8 +1058,9 @@ package Sidef::Parser {

local $self->{class} = $class_name;

if ($type ne 'method'
&& exists($self->{keywords}{$name})) {
if ( $type ne 'method'
and $type ne 'class'
and (exists($self->{keywords}{$name}) or exists($self->{built_in_classes}{$name}))) {
$self->fatal_error(
code => $_,
pos => $-[0],
Expand Down Expand Up @@ -1105,7 +1126,7 @@ package Sidef::Parser {
if (/\G\h*<<?\h*/gc) {
while (/\G($self->{var_name_re})\h*/gco) {
my ($name) = $1;
my ($class, $code) = $self->find_var($name, $class_name);
my ($class) = $self->find_var($name, $class_name);
if (ref $class) {
if ($class->{type} eq 'class') {
push @{$obj->{inherit}}, $name;
Expand Down Expand Up @@ -1165,14 +1186,25 @@ package Sidef::Parser {
# Function return type (func name(...) -> Type {...})
# XXX: [KNOWN BUG] It doesn't check the returned type from method calls
if (/\G\h*(?:->|returns\b)\h*/gc) {
my $return_obj = eval {

my $name = '';
my $try_expr;
if (/\G($self->{var_name_re})\h*/gco) {
$name = $1;
}
else {
$try_expr = 1;
}

if (
$try_expr or exists($self->{built_in_classes}{$name}) or do {
my ($obj) = $self->find_var($name, $class_name);
defined($obj) and $obj->{type} eq 'class';
}
) {
local $self->{_want_name} = 1;
my $code = substr($_, pos);
my ($obj) = $self->parse_expr(code => \$code);
pos($_) += pos($code);
$obj;
};
if (not $@ and defined $return_obj) {
my ($return_obj) = $self->parse_expr(code => $try_expr ? $opt{code} : \$name);

$obj->{returns} =
ref($return_obj) eq 'HASH'
? Sidef::Types::Block::Code->new($return_obj)->run
Expand All @@ -1186,6 +1218,7 @@ package Sidef::Parser {
pos => pos($_)
);
}

}

/\G\h*\{\h*/gc
Expand Down Expand Up @@ -1437,7 +1470,7 @@ package Sidef::Parser {
$self->{static_objects}{'__DATA__'} //= do {
open my $str_fh, '<:utf8', \$self->{'__DATA__'};
Sidef::Types::Glob::FileHandle->new(fh => $str_fh,
file => Sidef::Types::Nil::Nil->new);
self => Sidef::Types::Glob::File->new($self->{file_name}));
}
);
}
Expand Down
6 changes: 5 additions & 1 deletion lib/Sidef/Types/Glob/Dir.pm
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package Sidef::Types::Glob::Dir {

use parent qw(
Sidef::Types::Glob::File
Sidef::Types::String::String
);

sub new {
Expand Down Expand Up @@ -162,6 +161,11 @@ package Sidef::Types::Glob::Dir {
$success ? $dir_obj : ();
}

*open_r = \&open;

sub open_w { ... }
sub open_rw { ... }

sub chdir {
my ($self) = @_;
@_ == 2 && ($self = $_[1]);
Expand Down
4 changes: 2 additions & 2 deletions lib/Sidef/Types/Glob/File.pm
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ package Sidef::Types::Glob::File {

my $success = CORE::open(my $fh, $mode, $self->get_value);
my $error = $!;
my $fh_obj = Sidef::Types::Glob::FileHandle->new(fh => $fh, file => $self);
my $fh_obj = Sidef::Types::Glob::FileHandle->new(fh => $fh, self => $self);

if (defined $fh_ref) {
$fh_ref->get_var->set_value($fh_obj);
Expand Down Expand Up @@ -462,7 +462,7 @@ package Sidef::Types::Glob::File {
my $success = sysopen(my $fh, $self->get_value, $mode->get_value, defined($perm) ? $perm->get_value : 0666);

if ($success) {
$var_ref->get_var->set_value(Sidef::Types::Glob::FileHandle->new(fh => $fh, file => $self));
$var_ref->get_var->set_value(Sidef::Types::Glob::FileHandle->new(fh => $fh, self => $self));
}

Sidef::Types::Bool::Bool->new($success);
Expand Down
8 changes: 4 additions & 4 deletions lib/Sidef/Types/Glob/FileHandle.pm
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ package Sidef::Types::Glob::FileHandle {

bless {
fh => $opt{fh},
file => $opt{file},
self => $opt{self},
},
__PACKAGE__;
}
Expand All @@ -19,11 +19,11 @@ package Sidef::Types::Glob::FileHandle {
$_[0]->{fh};
}

sub file {
$_[0]{file};
sub parent {
$_[0]{self};
}

*parent = \&file;
*self = \&parent;

sub is_on_tty {
Sidef::Types::Bool::Bool->new(-t $_[0]{fh});
Expand Down
2 changes: 1 addition & 1 deletion lib/Sidef/Types/Glob/Pipe.pm
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ package Sidef::Types::Glob::Pipe {
}

my $pid = open(my $pipe_h, $mode, @{$self});
my $pipe_obj = Sidef::Types::Glob::PipeHandle->new(pipe_h => $pipe_h, pipe => $self);
my $pipe_obj = Sidef::Types::Glob::FileHandle->new(fh => $pipe_h, self => $self);

if (defined($var_ref)) {
$var_ref->get_var->set_value($pipe_obj);
Expand Down
30 changes: 0 additions & 30 deletions lib/Sidef/Types/Glob/PipeHandle.pm

This file was deleted.

Loading

0 comments on commit 5c80e36

Please sign in to comment.