Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assignment operators #869

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

Comments

@davidhesselbom
Copy link
Contributor

commented Mar 12, 2015

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

This comment has been minimized.

Copy link
Contributor

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 added a commit to zhaihj/rock that referenced this issue Mar 12, 2015
@zhaihj

This comment has been minimized.

Copy link
Contributor

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 added a commit to zhaihj/rock that referenced this issue Mar 12, 2015
add test
comes from ooc-lang#869
@davidhesselbom

This comment has been minimized.

Copy link
Contributor Author

commented Mar 16, 2015

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 added a commit to zhaihj/rock that referenced this issue Mar 17, 2015
fasterthanlime added a commit that referenced this issue Jul 8, 2015

@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
Projects
None yet
3 participants
You can’t perform that action at this time.