diff --git a/MANIFEST b/MANIFEST index 1d384944f..002a04d87 100644 --- a/MANIFEST +++ b/MANIFEST @@ -848,6 +848,7 @@ scripts/Tests/objects_init.sf scripts/Tests/one-dimensional_cellular_automata.sf scripts/Tests/one-dimensional_cellular_automata_2.sf scripts/Tests/open.sf +scripts/Tests/pair_namedparam_force_ops.sf scripts/Tests/pairs_test.sf scripts/Tests/palindrome_recursive.sf scripts/Tests/pascal_matrix_generation.sf diff --git a/lib/Sidef/Object/Object.pm b/lib/Sidef/Object/Object.pm index 2b3ba431d..22008859a 100644 --- a/lib/Sidef/Object/Object.pm +++ b/lib/Sidef/Object/Object.pm @@ -367,11 +367,16 @@ package Sidef::Object::Object { $func->call($arg, @args); }; - # Pair operator - *{__PACKAGE__ . '::' . ':'} = sub { + # Pair method: Fullwidth Colon; U+FF1A + *{__PACKAGE__ . '::' . ':'} = sub { Sidef::Types::Array::Pair->new($_[0], $_[1]); }; + # NamedParam method: Triple Colon Operator; U+2AF6 + *{__PACKAGE__ . '::' . '⫶'} = sub { + Sidef::Variable::NamedParam->new($_[0], $_[1]); + }; + # Logical AND *{__PACKAGE__ . '::' . '&&'} = sub { $_[0] ? $_[1] : $_[0]; diff --git a/lib/Sidef/Parser.pm b/lib/Sidef/Parser.pm index 7f423ddd9..dcc5bafba 100644 --- a/lib/Sidef/Parser.pm +++ b/lib/Sidef/Parser.pm @@ -324,7 +324,7 @@ package Sidef::Parser { ... != .. \\\\= \\\\ - !! ! : « » ~ + !! ! : : ⫶ « » ~ ); qr{ @@ -1149,6 +1149,8 @@ package Sidef::Parser { return Sidef::Types::String::String->new($1); } + # Bareword followed by a colon becomes a NamedParam with the bareword + # on the LHS if (/\G([^\W\d]\w*+):(?![=:])/gc) { my $name = $1; my $obj = $self->parse_obj(code => $opt{code}); diff --git a/scripts/Tests/hash_concat.sf b/scripts/Tests/hash_concat.sf index abe55d4c3..6b1b30129 100644 --- a/scripts/Tests/hash_concat.sf +++ b/scripts/Tests/hash_concat.sf @@ -14,7 +14,7 @@ assert_eq(hash{:a}, :b) hash += %w(c d) # 2-item array assert_eq(hash{:c}, :d) -hash += "2":3 # an actual Pair +hash += "2":3 # an actual Pair assert_eq(hash{"2"}, 3) say "** Test passed!" diff --git a/scripts/Tests/pair_namedparam_force_ops.sf b/scripts/Tests/pair_namedparam_force_ops.sf new file mode 100644 index 000000000..59bb7aaf1 --- /dev/null +++ b/scripts/Tests/pair_namedparam_force_ops.sf @@ -0,0 +1,17 @@ +#! /usr/bin/ruby + +var f = :name +assert_eq(f⫶ 1 -> dump, name: 1 -> dump) +assert_eq(f⫶ 1 -> dump, (f)⫶ 1 -> dump) +assert_eq((f)⫶ 1 -> dump, name: 1 -> dump) +assert_eq(:a⫶ 1 -> dump, a:1 -> dump) + +var n = 1 + +assert_ne(n: 2 -> dump, (n): 2 -> dump) +assert_eq((n): 2 -> dump, 1: 2 -> dump) +assert_eq(n:2, Pair(1, 2)) +assert_eq(1:2, 1+2i) +assert_eq(1:2, Pair(1, 2)) + +say "** Test passed!" diff --git a/scripts/Tests/pairs_test.sf b/scripts/Tests/pairs_test.sf index cee19b73d..40f29350c 100644 --- a/scripts/Tests/pairs_test.sf +++ b/scripts/Tests/pairs_test.sf @@ -4,7 +4,7 @@ ## This script is used for testing only # -var tree = 'root':'child':'grandchild':'end'; +var tree = 'root':'child':'grandchild':'end'; while (true) { say tree.first; diff --git a/scripts/Tests/roman_numerals_decoding.sf b/scripts/Tests/roman_numerals_decoding.sf index 365a2b214..94cbf863e 100644 --- a/scripts/Tests/roman_numerals_decoding.sf +++ b/scripts/Tests/roman_numerals_decoding.sf @@ -29,7 +29,7 @@ func roman2arabic (roman) { ## MAIN # -['MCMXC':1990, 'MMVIII':2008, 'MDCLXVI':1666].each { |pair| +[:MCMXC:1990, :MMVIII:2008, :MDCLXVI:1666].each { |pair| var arabic = roman2arabic(pair.first) == pair.second || die "Error occurred on #{pair.first}\n"; diff --git a/scripts/Tests/roman_numerals_decoding_3.sf b/scripts/Tests/roman_numerals_decoding_3.sf index 667449e14..dd6082bb5 100644 --- a/scripts/Tests/roman_numerals_decoding_3.sf +++ b/scripts/Tests/roman_numerals_decoding_3.sf @@ -2,19 +2,19 @@ func roman2arabic(digit) { digit.uc.trans([ - 'M': '1000+', - 'CM': '900+', - 'D': '500+', - 'CD': '400+', - 'C': '100+', - 'XC': '90+', - 'L': '50+', - 'XL': '40+', - 'X': '10+', - 'IX': '9+', - 'V': '5+', - 'IV': '4+', - 'I': '1+', + 'M': '1000+', + 'CM': '900+', + 'D': '500+', + 'CD': '400+', + 'C': '100+', + 'XC': '90+', + 'L': '50+', + 'XL': '40+', + 'X': '10+', + 'IX': '9+', + 'V': '5+', + 'IV': '4+', + 'I': '1+', ]).split('+').map{.to_i}.sum; } diff --git a/scripts/Tests/roman_numerals_encoding.sf b/scripts/Tests/roman_numerals_encoding.sf index 125c752a5..fcc0d2a8e 100644 --- a/scripts/Tests/roman_numerals_encoding.sf +++ b/scripts/Tests/roman_numerals_encoding.sf @@ -36,7 +36,7 @@ func arabic2roman (num) { ## MAIN # -[[1990,'MCMXC'], [2008,'MMVIII'], [1666,'MDCLXVI']].each { |pair| +[1990::MCMXC, 2008::MMVIII, 1666::MDCLXVI].each { |pair| var roman = arabic2roman(pair[0]); roman == pair[1] || "Error occurred on number: #{pair[0]}\n".die; "%s in roman is %s".printlnf(pair[0], roman); diff --git a/scripts/Tests/roman_numerals_encoding_2.sf b/scripts/Tests/roman_numerals_encoding_2.sf index ed1ec33e0..b348eae48 100644 --- a/scripts/Tests/roman_numerals_encoding_2.sf +++ b/scripts/Tests/roman_numerals_encoding_2.sf @@ -5,10 +5,10 @@ func arabic2roman(num, roman='') { static lookup = [ - :M:1000, :CM:900, :D:500, - :CD:400, :C:100, :XC:90, - :L:50, :XL:40, :X:10, - :IX:9, :V:5, :IV:4, :I:1 + :M:1000, :CM:900, :D:500, + :CD:400, :C:100, :XC:90, + :L:50, :XL:40, :X:10, + :IX:9, :V:5, :IV:4, :I:1 ]; lookup.each { |pair|