Skip to content

Commit

Permalink
Replace Object.: with :(U+FF1A) and ⫶ (U+2AF6)
Browse files Browse the repository at this point in the history
Breaking change, to remove the `:` (colon)
    operator from Object.

Its use has been bisected into the :
    (fat/fullwidth colon) and ⫶ (triple colon).

Previously the appearance of a `:` in the syntax
    was ambiguous, so it has been disambiguated
    to mean only NamedParam (when the LHS is a
    bareword) or Complex (when the LHS is a
    real number).

There is no direct overlap between these two
    syntaxes, but it's now possible to create
    a NamedParam with a real number as its name.

: remains as a first-class operator to create
    NamedParams using barewords, and to construct
    Complex literals.
- :, the fullwidth colon U+FF1A: force creation
    of a Pair from self and the first argument.

- ⫶, the triple-colon operator U+2AF6: force
    creation of a NamedParam with the object
    on its LHS as the name.

    In other words, whereas the normal NamedParam
    colon operator expects a bareword on its LHS,
    the triple-colon evaluates its left hand side
    and therefore allows runtime-computed objects
    as the names in NamedParams, rather than
    forcing only barewords.

    Previously it was not possible to iterate an
    array of strings and generate NamedParams
    from them, because the : (colon) NamedParam
    operator (understandably) doesn't even accept
    a parenthesised expression on its LHS.

    Making NamedParam a directly invokable class
    would also be useful, but a shorthand is nice
    for this.
  • Loading branch information
catb0t committed Mar 11, 2019
1 parent 2947293 commit 4454206
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 24 deletions.
1 change: 1 addition & 0 deletions MANIFEST
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
9 changes: 7 additions & 2 deletions lib/Sidef/Object/Object.pm
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down
4 changes: 3 additions & 1 deletion lib/Sidef/Parser.pm
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ package Sidef::Parser {
...
!= ..
\\\\= \\\\
!! ! : « » ~
!! ! : : ⫶ « » ~
);

qr{
Expand Down Expand Up @@ -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});
Expand Down
2 changes: 1 addition & 1 deletion scripts/Tests/hash_concat.sf
Original file line number Diff line number Diff line change
Expand Up @@ -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!"
17 changes: 17 additions & 0 deletions scripts/Tests/pair_namedparam_force_ops.sf
Original file line number Diff line number Diff line change
@@ -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!"
2 changes: 1 addition & 1 deletion scripts/Tests/pairs_test.sf
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion scripts/Tests/roman_numerals_decoding.sf
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
26 changes: 13 additions & 13 deletions scripts/Tests/roman_numerals_decoding_3.sf
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion scripts/Tests/roman_numerals_encoding.sf
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
8 changes: 4 additions & 4 deletions scripts/Tests/roman_numerals_encoding_2.sf
Original file line number Diff line number Diff line change
Expand Up @@ -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
:M1000, :CM900, :D500,
:CD400, :C100, :XC90,
:L50, :XL40, :X10,
:IX9, :V5, :IV4, :I1
];

lookup.each { |pair|
Expand Down

0 comments on commit 4454206

Please sign in to comment.