Assignment operators #869

Closed
davidhesselbom opened this Issue Mar 12, 2015 · 3 comments

Projects

None yet

3 participants

@davidhesselbom
Contributor

Overriding some of the assignment operators doesn't work. It works for += -= *= **= /=, but for |= ^= &=, rock picks the wrong operator (the preceding one in the list of operators in BinaryOp), %= doesn't work at all and >>= <<= seem to be mistaken for > <. The code below demonstrates the problem. Comments show the output for each line, and expected output where applicable.

The source of one of these problems seems to be the % operator in BinaryOp, which offsets the rest of the operators in the list - this is why the operators above % in the list work as expected, but the rest don't. If the % operator were to be moved down the list to very end of it, or if a %= operator was made possible, that would probably solve the problem for |= ^= &=. >>= <<= is, perhaps, a different problem.

Foo: class {
    value: Int
    init: func(=value)
}
operator + (left, right: Foo) -> Foo {
    "+" println()
    Foo new(left value + right value)
}
operator - (left, right: Foo) -> Foo {
    "-" println()
    Foo new(left value + right value)
}
operator * (left, right: Foo) -> Foo {
    "*" println()
    Foo new(left value + right value)
}
operator ** (left, right: Foo) -> Foo {
    "**" println()
    Foo new(left value + right value)
}
operator / (left, right: Foo) -> Foo {
    "/" println()
    Foo new(left value + right value)
}
operator % (left, right: Foo) -> Foo {
    "%" println()
    Foo new(left value + right value)
}
operator >> (left, right: Foo) -> Foo {
    ">>" println()
    Foo new(left value + right value)
}
operator << (left, right: Foo) -> Foo {
    "<<" println()
    Foo new(left value + right value)
}
operator | (left, right: Foo) -> Foo {
    "|" println()
    Foo new(left value + right value)
}
operator ^ (left, right: Foo) -> Foo {
    "^" println()
    Foo new(left value + right value)
}
operator & (left, right: Foo) -> Foo {
    "&" println()
    Foo new(left value + right value)
}

foo := Foo new(1)

foo = foo + Foo new(2) // +
foo += Foo new(3) // +

foo = foo - Foo new(2) // -
foo -= Foo new(3) // -

foo = foo * Foo new(2) // *
foo *= Foo new(3) // *

foo = foo ** Foo new(2) // **
foo **= Foo new(3) // **

foo = foo / Foo new(2) // /
foo /= Foo new(3) // /

foo = foo % Foo new(2) // %
//foo %= Foo new(3)
// error Expected include, import, statement or declaration

foo = foo >> Foo new(2) // >>
//foo >>= Foo new(3)
// error Missing right operand for '>' operator!

foo = foo << Foo new(2) // <<
//foo <<= Foo new(3) 
// error Missing right operand for '<' operator!

foo = foo | Foo new(2) // |
foo |= Foo new(3) // <<, but expected |. If << is not implemented,
// error Invalid use of operator << between operands of type Foo and Foo

foo = foo ^ Foo new(2) // ^
foo ^= Foo new(3) // |, but expected ^. If | is not implemented,
// error Invalid use of operator | between operands of type Foo and Foo

foo = foo & Foo new(2) // & 
foo &= Foo new(3) // ^, but expected &. If ^ is not implemented,
// error Invalid use of operator ^ between operands of type Foo and Foo
@zhaihj
Contributor
zhaihj commented Mar 12, 2015

It seems that %= is not supported in current parser.

        - < ( "=>" | "<=>"| ">>="| "<<="| ">>" | "<<"
            | ">=" | "<=" | "!=" | "==" | ">" | "<" | "!" | "??"
            | "+=" | "-=" | "*=" | "**="| "/=" | "+" | "-" | "**" | "/" | "*" | "="
            | "[]="| "[]" | "&&" | "||" | "%" | "as" | "implicit as"
            | "&=" | "|=" | "^=" | "&"  | "|" | "^" | "~"
            ) >

>>= and <<= issue is caused by the following line in parser:

LESSTHAN     = '<'  !'=' -
MORETHAN     = '>'  !'=' -

If parser fails to match ">>" then it will try ">", here MORETHAN matches. We should change these lines to:

LESSTHAN     = '<'  !('=' | '<') -
MORETHAN     = '>'  !('=' | '>') -
@zhaihj zhaihj added a commit to zhaihj/rock that referenced this issue Mar 12, 2015
@zhaihj zhaihj fix ooc-lang#869 ddd1a30
@zhaihj
Contributor
zhaihj commented Mar 12, 2015

Incorrect function call is caused by % operator.
We are mapping opass to op by

type - Optype addASS - OpType add

but we have an extra % operator in the ones without assignment.

@zhaihj zhaihj added a commit to zhaihj/rock that referenced this issue Mar 12, 2015
@zhaihj zhaihj add test
comes from ooc-lang#869
1088d2c
@davidhesselbom
Contributor

I just noticed now that if both unary and binary - operators are implemented, I get
error Argl, you need 2 arguments to override the '-=' operator, not 1
when trying to use the -= operator.

Also, the error message reports the line above the one where the operator is implemented, so

Point2D: class {
    x, y: Float
    init: func(=x, =y)
    operator - -> This { This new(-this x, -this y) }
    operator - (other: This) -> This { This new(this x - other x, this y - other y) }
}

p := Point2D new(1.0f, 1.0f)
p2 := Point2D new(2.0f, 2.0f)
p -= p2

gives me

error Argl, you need 2 arguments to override the '-=' operator, not 1

    init: func(=x, =y)

but

Point2D: class {
    x, y: Float
    init: func(=x, =y)
    operator - (other: This) -> This { This new(this x - other x, this y - other y) }
    operator - -> This { This new(-this x, -this y) }
}

p := Point2D new(1.0f, 1.0f)
p2 := Point2D new(2.0f, 2.0f)
p -= p2

(all I did was swap lines 4 and 5) gives me

error Argl, you need 2 arguments to override the '-=' operator, not 1

    operator - (other: This) -> This { This new(this x - other x, this y - other y) }

In either case,

p := Point2D new(1.0f, 1.0f)
p2 := Point2D new(2.0f, 2.0f)
p = p - p2

works just fine.

@zhaihj zhaihj added a commit to zhaihj/rock that referenced this issue Mar 17, 2015
@zhaihj zhaihj Fix incorrect overload check 227529e
@fasterthanlime fasterthanlime added a commit that referenced this issue Jul 8, 2015
@fasterthanlime fasterthanlime #869 fix part 2 36ae73b
@fasterthanlime fasterthanlime modified the milestone: 0.9.10 Jul 10, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment