Skip to content

Commit

Permalink
- Added support for structures.
Browse files Browse the repository at this point in the history
Example:
	struct Person {
	   String name,
	   Number age,
	};
	var p1 = Person(name: "Brad Pitt", age: 42);
	var p2 = Person("Angelina Jolie", 35);

	say p1.name;	# prints: "Brad Pitt"
	say p2.name;	# prints: "Angelina Jolie"
  • Loading branch information
trizen committed Oct 30, 2015
1 parent 83d3450 commit a353469
Show file tree
Hide file tree
Showing 13 changed files with 214 additions and 81 deletions.
3 changes: 3 additions & 0 deletions MANIFEST
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,7 @@ lib/Sidef/Types/Regex/Regex.pod
lib/Sidef/Types/String/String.pm
lib/Sidef/Types/String/String.pod
lib/Sidef/Variable/ClassInit.pm
lib/Sidef/Variable/ClassInit.pod
lib/Sidef/Variable/Const.pm
lib/Sidef/Variable/Const.pod
lib/Sidef/Variable/ConstInit.pm
Expand All @@ -149,6 +150,7 @@ lib/Sidef/Variable/Ref.pm
lib/Sidef/Variable/Static.pm
lib/Sidef/Variable/Static.pod
lib/Sidef/Variable/Struct.pm
lib/Sidef/Variable/Struct.pod
lib/Sidef/Variable/Variable.pm
LICENSE
Makefile.PL
Expand Down Expand Up @@ -731,6 +733,7 @@ scripts/Tests/string_escapes.sf
scripts/Tests/string_to_number.sf
scripts/Tests/strip_chars_from_str.sf
scripts/Tests/strip_non_ascii_chars.sf
scripts/Tests/structures.sf
scripts/Tests/subtractive_generator.sf
scripts/Tests/swap.sf
scripts/Tests/sylvesters_sequence.sf
Expand Down
42 changes: 34 additions & 8 deletions lib/Sidef/Deparse/Perl.pm
Original file line number Diff line number Diff line change
Expand Up @@ -567,16 +567,42 @@ HEADER
}
}
elsif ($ref eq 'Sidef::Variable::Struct') {
my $name = $self->_dump_class_name($obj);
if ($addr{$refaddr}++) {
$code = $obj->{__NAME__};
$code = $name;
}
else {
my @vars;
foreach my $key (sort keys %{$obj}) {
next if $key eq '__NAME__';
push @vars, $obj->{$key};
local $self->{parent_name} = ['struct initialization', $obj->{name}];

# Mark the variables all in use
foreach my $var (@{$obj->{vars}}) {
$var->{in_use} = 1;
}
$code = "struct $obj->{__NAME__} {" . $self->_dump_vars(@vars) . '}';

$Sidef::SPACES += $Sidef::SPACES_INCR;
$code =
"package $name {\n"
. (' ' x $Sidef::SPACES)
. "sub new {\n"
. (' ' x $Sidef::SPACES)
. $self->_dump_sub_init_vars('undef', @{$obj->{vars}})

. (' ' x ($Sidef::SPACES * 2))
. "bless {"
. join(", ", map { $self->_dump_string($_->{name}) . " => " . $self->_dump_var($_) } @{$obj->{vars}})
. "}, __PACKAGE__" . "\n"
. (' ' x $Sidef::SPACES) . "}\n"
.

(' ' x $Sidef::SPACES) . "*call = \\&new;\n" .

(' ' x $Sidef::SPACES)
. join("\n" . (' ' x $Sidef::SPACES),
map { "sub $_->{name} : lvalue { \$_[0]->{$_->{name}} }" } @{$obj->{vars}})

. "\n" . (' ' x ($Sidef::SPACES - $Sidef::SPACES_INCR)) . "}";

$Sidef::SPACES -= $Sidef::SPACES_INCR;
}
}
elsif ($ref eq 'Sidef::Variable::LocalInit') {
Expand Down Expand Up @@ -649,7 +675,7 @@ HEADER
$code = q{'} . $self->_dump_class_name($obj) . q{'};
}
else {
my $block = $obj->{__BLOCK__};
my $block = $obj->{block};

$code = "do {package ";

Expand All @@ -671,7 +697,7 @@ HEADER
$code .= ($package_name = $self->_dump_class_name($obj));
}

my $vars = $obj->{__VARS__};
my $vars = $obj->{vars};
local $self->{class} = refaddr($block);
local $self->{class_name} = $obj->{name};
local $self->{parent_name} = ['class initialization', $obj->{name}];
Expand Down
13 changes: 4 additions & 9 deletions lib/Sidef/Deparse/Sidef.pm
Original file line number Diff line number Diff line change
Expand Up @@ -200,15 +200,10 @@ package Sidef::Deparse::Sidef {
}
elsif ($ref eq 'Sidef::Variable::Struct') {
if ($addr{refaddr($obj)}++) {
$code = $obj->{__NAME__};
$code = $obj->{name};
}
else {
my @vars;
foreach my $key (sort keys %{$obj}) {
next if $key eq '__NAME__';
push @vars, $obj->{$key};
}
$code = "struct $obj->{__NAME__} {" . $self->_dump_vars(@vars) . '}';
$code = "struct $obj->{name} {" . $self->_dump_vars(@{$obj->{vars}}) . '}';
}
}
elsif ($ref eq 'Sidef::Variable::LocalInit') {
Expand Down Expand Up @@ -275,7 +270,7 @@ package Sidef::Deparse::Sidef {
);
}
else {
my $block = $obj->{__BLOCK__};
my $block = $obj->{block};
my $in_module = $obj->{class} ne $self->{class};

if ($in_module) {
Expand All @@ -286,7 +281,7 @@ package Sidef::Deparse::Sidef {

local $self->{class} = $obj->{class};
$code .= "class " . $self->_dump_class_name($obj->{name});
my $vars = $obj->{__VARS__};
my $vars = $obj->{vars};
$code .= '(' . $self->_dump_vars(@{$vars}) . ')';
if (exists $obj->{inherit}) {
$code .= ' << ' . join(', ', map { $_->{name} } @{$obj->{inherit}}) . ' ';
Expand Down
2 changes: 1 addition & 1 deletion lib/Sidef/Optimizer.pm
Original file line number Diff line number Diff line change
Expand Up @@ -505,7 +505,7 @@ package Sidef::Optimizer {
## ok
}
else {
$obj->{__BLOCK__} = $self->optimize_expr({self => $obj->{__BLOCK__}});
$obj->{block} = $self->optimize_expr({self => $obj->{block}});
}
}
elsif ($ref eq 'Sidef::Variable::Init') {
Expand Down
29 changes: 14 additions & 15 deletions lib/Sidef/Parser.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1084,9 +1084,9 @@ package Sidef::Parser {
# Struct declaration
if (/\Gstruct\b\h*/gc) {

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

if (defined($name) and (exists($self->{keywords}{$name}) or exists($self->{built_in_classes}{$name}))) {
Expand All @@ -1105,10 +1105,14 @@ package Sidef::Parser {
type => 'var',
);

my $struct = Sidef::Variable::Struct->__new__($name, $vars);
my $struct = Sidef::Variable::Struct->new(
name => $name,
class => $class_name,
vars => $vars,
);

if (defined $name) {
unshift @{$self->{vars}{$self->{class}}},
unshift @{$self->{vars}{$class_name}},
{
obj => $struct,
name => $name,
Expand Down Expand Up @@ -1283,8 +1287,7 @@ package Sidef::Parser {
: $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 '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 'class' ? Sidef::Variable::ClassInit->new(name => ($built_in_obj // $name), class => $class_name)
: $self->fatal_error(
error => "invalid type",
expected => "expected a magic thing to happen",
Expand Down Expand Up @@ -1345,19 +1348,15 @@ package Sidef::Parser {
},
);

$obj->__set_params__($var_names);
$obj->set_params($var_names);

# Class inheritance (class Name(...) << Name1, Name2)
if (/\G\h*<<?\h*/gc) {
while (/\G($self->{var_name_re})\h*/gco) {
my ($name) = $1;
if (defined(my $class = $self->find_var($name, $class_name))) {
if ($class->{type} eq 'class') {
push @{$obj->{inherit}}, $class->{obj}; #$class_name . '::' . $name;

#while (my ($name, $method) = each %{$class->{obj}{__METHODS__}}) {
# ($built_in_obj // $obj)->__add_method__($name, $method);
#}
push @{$obj->{inherit}}, $class->{obj};
}
else {
$self->fatal_error(
Expand Down Expand Up @@ -1403,7 +1402,7 @@ package Sidef::Parser {
local $self->{current_class} = $built_in_obj // $obj;
my $block = $self->parse_block(code => $opt{code});

$obj->__set_block__($block);
$obj->set_block($block);
}

if ($type eq 'func' or $type eq 'method') {
Expand Down Expand Up @@ -1506,7 +1505,7 @@ package Sidef::Parser {
$obj->{value} = $block;

#if (not $private) {
# $self->{current_class}->__add_method__($name, $block) if $type eq 'method';
# $self->{current_class}->add_method($name, $block) if $type eq 'method';
#}
}

Expand Down Expand Up @@ -1781,7 +1780,7 @@ package Sidef::Parser {
and defined(
my $var = List::Util::first(
sub { $_->{name} eq $name },
@{$self->{current_class}{__VARS__}},
@{$self->{current_class}{vars}},

#@{$self->{current_class}{__DEF_VARS__}}
)
Expand Down
8 changes: 8 additions & 0 deletions lib/Sidef/Types/Glob/Backtick.pod
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,14 @@ Aliases: I<run>, I<exec>, I<execute>

=cut

=head2 call

Backtick.call() -> I<Obj>

Return the

=cut

=head2 dump

Backtick.dump() -> I<Obj>
Expand Down
8 changes: 0 additions & 8 deletions lib/Sidef/Types/Hash/Hash.pm
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,6 @@ package Sidef::Types::Hash::Hash {
\%hash;
}

sub default {
my ($self, $value) = @_;
if (@_ > 1) {
$self->{__DEFAULT_VALUE__} = $value;
}
$self->{__DEFAULT_VALUE__};
}

sub items {
my ($self, @keys) = @_;
Sidef::Types::Array::Array->new(map { exists($self->{$_}) ? $self->{$_} : undef } @keys);
Expand Down
8 changes: 0 additions & 8 deletions lib/Sidef/Types/Hash/Hash.pod
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,6 @@ Return the

=cut

=head2 default

Hash.default() -> I<Obj>

Return the

=cut

=head2 delete

Hash.delete() -> I<Obj>
Expand Down
18 changes: 9 additions & 9 deletions lib/Sidef/Variable/ClassInit.pm
Original file line number Diff line number Diff line change
Expand Up @@ -6,31 +6,31 @@ package Sidef::Variable::ClassInit {
Sidef::Object::Object
);

sub __new__ {
sub new {
my (undef, %opt) = @_;
bless \%opt, __PACKAGE__;
}

sub __set_params__ {
sub set_params {
my ($self, $names) = @_;
$self->{__VARS__} = $names;
$self->{vars} = $names;
}

sub __set_block__ {
sub set_block {
my ($self, $block) = @_;
$self->{__BLOCK__} = $block;
$self->{block} = $block;
$self;
}

sub __add_method__ {
sub add_method {
my ($self, $name, $method) = @_;
$self->{__METHODS__}{$name} = $method;
$self->{methods}{$name} = $method;
$self;
}

sub __add_vars__ {
sub add_vars {
my ($self, $vars) = @_;
push @{$self->{__DEF_VARS__}}, @{$vars};
push @{$self->{def_vars}}, @{$vars};
$self;
}
};
Expand Down
64 changes: 64 additions & 0 deletions lib/Sidef/Variable/ClassInit.pod
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@

=encoding utf8

=head1 NAME

Sidef::Variable::ClassInit

=head1 DESCRIPTION

This object is ...

=head1 SYNOPSIS

var obj = ClassInit.new(...);


=head1 INHERITS

Inherits methods from:

* Sidef::Object::Object

=head1 METHODS


=head2 add_method

ClassInit.add_method() -> I<Obj>

Return the

=cut

=head2 add_vars

ClassInit.add_vars() -> I<Obj>

Return the

=cut

=head2 new

ClassInit.new() -> I<Obj>

Return the

=cut

=head2 set_block

ClassInit.set_block() -> I<Obj>

Return the

=cut

=head2 set_params

ClassInit.set_params() -> I<Obj>

Return the

=cut
Loading

0 comments on commit a353469

Please sign in to comment.