Skip to content

Commit

Permalink
- Added the following methods inside ClassInit: method and invoke
Browse files Browse the repository at this point in the history
- Fixed a minor parsing error for consecutive calls.

Example:
	obj.method(arg)(arg);	# now it's parsed correcty as: obj.method(arg).call(arg);

new file:   scripts/Rosettacode/Ethiopian_multiplication.sf
new file:   scripts/call_an_object_method.sf
  • Loading branch information
trizen committed Sep 15, 2015
1 parent 214f064 commit 7fd6816
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 0 deletions.
2 changes: 2 additions & 0 deletions MANIFEST
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ scripts/built_in_classes.sf
scripts/c_plus_plus_input_output.sf
scripts/caesar_cipher.sf
scripts/calendar.sf
scripts/call_an_object_method.sf
scripts/catalan_numbers.sf
scripts/catalan_numbers_recursive.sf
scripts/chinese_remainder_theorem.sf
Expand Down Expand Up @@ -501,6 +502,7 @@ scripts/Rosettacode/Enumerations.sf
scripts/Rosettacode/Enumerations_1.sf
scripts/Rosettacode/Environment_variables.sf
scripts/Rosettacode/Equilibrium_index.sf
scripts/Rosettacode/Ethiopian_multiplication.sf
scripts/Rosettacode/Evaluate_binomial_coefficients.sf
scripts/Rosettacode/Evaluate_binomial_coefficients_1.sf
scripts/Rosettacode/Even_or_odd.sf
Expand Down
12 changes: 12 additions & 0 deletions lib/Sidef/Parser.pm
Original file line number Diff line number Diff line change
Expand Up @@ -2126,6 +2126,18 @@ package Sidef::Parser {
push @{$struct{$self->{class}}[-1]{call}}, @{$methods};
}

if (/\G(?=\()/) {
my $arg = $self->parse_arguments(code => $opt{code});

push @{$struct{$self->{class}}[-1]{call}},
{
method => 'call',
(%{$arg} ? (arg => [$arg]) : ())
};

redo;
}

if (/\G(?=\[)/) {
$struct{$self->{class}}[-1]{self} = {
$self->{class} => [
Expand Down
12 changes: 12 additions & 0 deletions lib/Sidef/Variable/ClassInit.pm
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,18 @@ package Sidef::Variable::ClassInit {
Sidef::Types::String::String->new($self->{name});
}

sub invoke {
my ($self, $name, @args) = @_;
$self->{__METHODS__}{$name}->call(@args);
}

sub method {
my ($self, $name) = @_;
exists($self->{__METHODS__}{$name})
? Sidef::Variable::LazyMethod->new(obj => $self, method => $self->{__METHODS__}{$name})
: ();
}

sub init {
my ($self, @args) = @_;

Expand Down
20 changes: 20 additions & 0 deletions scripts/Rosettacode/Ethiopian_multiplication.sf
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#!/usr/bin/ruby

#
## http://rosettacode.org/wiki/Ethiopian_multiplication
#

func double (n) { n * 2 };
func halve (n) { int(n / 2) };

func ethiopic_mult(a, b) {
var r = 0;
while (a > 0) {
a.is_even || (r += b);
a = halve(a);
b = double(b);
};
return r;
}

say ethiopic_mult(17, 34);
31 changes: 31 additions & 0 deletions scripts/call_an_object_method.sf
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#!/usr/bin/ruby

#
## http://rosettacode.org/wiki/Call_an_object_method
#

class MyClass {
method foo(arg) { arg }
}

var arg = 42;

# Class method
assert_eq(MyClass.method(:foo)(arg), arg);

# Alternatively, by specifying the self-object
assert_eq(MyClass.invoke(:foo, MyClass, arg), arg);

# Create an instance
var instance = MyClass();

# Instance method
assert_eq(instance.foo(arg), arg);

# Alternatively, by using an expression as a method
assert_eq(instance.(:foo)(arg), arg);

# Alternatively, by asking for a method
assert_eq(instance.method(:foo)(arg), arg);

say "** Test passed!";

0 comments on commit 7fd6816

Please sign in to comment.