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
Closed

Assignment operators #869

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

Comments

@davidhesselbom
Copy link
Contributor

@davidhesselbom davidhesselbom 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
@horasal
Copy link
Contributor

@horasal horasal 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     = '>'  !('=' | '>') -

Loading

horasal added a commit to horasal/rock that referenced this issue Mar 12, 2015
@horasal
Copy link
Contributor

@horasal horasal 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.

Loading

horasal added a commit to horasal/rock that referenced this issue Mar 12, 2015
@davidhesselbom
Copy link
Contributor Author

@davidhesselbom davidhesselbom 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.

Loading

horasal added a commit to horasal/rock that referenced this issue Mar 17, 2015
fasterthanlime added a commit that referenced this issue Jul 8, 2015
@fasterthanlime fasterthanlime added this to the 0.9.10 milestone Jul 10, 2015
@fasterthanlime fasterthanlime added this to the 0.9.10 milestone Jul 10, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants