Most imperative languages have assignment operators as right-associative operators.

This allows the language to interpret the following command:

a = b = 4*3


In DM, assignment operators are non-associative. This means that in order to perform this operation you must:

b = 4*3
a = b


This would break no existing code because non-associative assignment operators by definition is a non-behavior.
In response to Ter13
I would love this (and I'd also like, by extension, for it to handle stuff like a = b += c as well). I'm not quite sure how I'd go about it at the compiler level.

IF the nodes are already being handled right-to-left (I'm not so sure about that), and if the expression a = b = c can be parsed into nodes properly, then in theory it's simply a matter of altering the way the assignment operators are compiled into code.

[edit]
It appears that wherever the current behavior is happening, it may be at a fairly early level like the parser. I'll have to see if it's doing right-to-left properly. At a cursory glance, ParseExpr2i() is handling these cases and it's handing off the rhs to ParseExpr2h(), suggesting that the only reason chaining currently isn't supported might simply be a design decision.
In response to Ter13
ParseExpr2i
ParseExpr2h

Jesus.
In response to Ter13
I've been looking into this, and it appears there are two places to change.

One is in the parsing routine, as I suspected. When I make that change, the node structures are built correctly.

The other place I need to change is in the conversion to bytecode. Interestingly, it looks like at one point this concept might have been planned for the = operator, as there's logic to support a node with more than 2 children. However that's not really the logic I'm concerned with. The structure of nodes I'm looking at goes something like this:

    =
  /   \
a       =
       / \
      b   c

Apparently when it goes to convert the b=c part to bytecode, it's tripping up some code that's expecting an expression to have been pushed to the stack. So I have to change some of the peek/pop behavior around to get this to work.

This is getting into compiler-guts parts that I've never touched, so there's a lot of iffiness in my mind as to whether this can work.
In response to Ter13
Read: When Lummox digs into compiler-guts he comes out tripping.
In response to Ter13
dupe/same idea? ID:1225436 (boy, I was stupid 2 years ago)
I was able to puzzle this out. Because I think it would be a bad idea to change the compiler behavior for this mid-beta, I'll introduce this feature in 511.
Lummox JR changed status to 'Open'
In response to Super Saiyan X
Super Saiyan X wrote:
Any usage outside of conditional statements seems pointless. Not only does it look weird, but it lessens readability.
I'm thinking that if this were added, it'd only be for conditionals or in certain locations, just because there's no real functional gain anywhere else.

Super Saiyan X wrote:
boy, I was stupid 2 years ago

Nadrew wrote:
Nadrew resolved issue (Not Feasible)

Changing this aspect of the compiler is incredibly non-trivial and definitely not worth the time and effort required to do it.

LummoxJr wrote:
I was able to puzzle this out.

Lummox based AF. When I threw my hat in this fight, I didn't honestly think it'd happen.

I will never underestimate your godliness again, herr Lummox.
To explain how this setup will work:

- When the = operator is chained to another assignment operator, it will be implemented as a PEEK instead of a POP. That is, whatever value is on the stack will stay on the stack but will be stored in a var, instead of being taken off the stack and stored in a var. In abstract terms, the value of a=b as an expression is b, not a.

- When a different assignment operator is chained, it will work as normal and then a PUSH instruction will be added to read from the var that stored the result. Therefore, a = b += c is identical to b += c followed by a = b. The value of a+=b as an expression is a, post-modification.

This means that when chaining assign-and-operate operators like +=, you'll get best performance if the middle var is a proc var, argument, or global. Otherwise, it will go through a datum var write followed by a datum var read, which is less efficient. In other words, pixel_x = pixel_y += n is probably not a good way to go because pixel_y has to be written and then read, but pixel_x = pixel_y = 0 should be fine.

I could, with more effort, add versions of those operations that simply push v1 to the stack after they assign it to a var--or maybe, add an instruction that just takes v1 and pushes it. (This is assuming they all use v1, which I'm pretty sure is the case.) However, in complex cases like matrix and icon operations, I don't know if that necessarily would be the best way to go. It's probably better to take the hit in the var assignment cases, for the sake of expediency. a = b += c is not a common pattern, IMO, outside of loop counters and the like.
praise lummox
Yes! :D
Will this also enable us to do this?
if(var nullable = FindThing())
nullable.etc // nullable exists

nullable.etc // compiler error: nullable not defined here
In response to Kaiochao
I don't see why not.
it might be too late, but one suggestion would be to make it generate a warning unless its part of a subexpression. (in control statements that is)

This means if you do if (blah = 1) it gives a warning, but you can do if ((blah = 1)) to suppress the warning and say you meant to do that.

Would prevent accidentally replacing == with =
Lummox JR resolved issue with message:
Assignment operators can be chained, and have proper right-to-left evaluation order. This means a statement like a = b = 2 is now valid.
In response to Lummox JR
Lummox JR wrote:
I don't see why not.

It doesn't, but I don't really mind.
In response to Kaiochao
Ah, it might be that if() won't really allow a var definition in its condition. I think for() and catch() might be the only places that's allowed.
This does not work at all. You get a compiler error such as this: code\core\mob\character\character_actions.dm:4:error: 1: invalid expression (737)

Would be cool if if() could do this as well.
In response to FKI
FKI wrote:
This does not work at all. You get a compiler error such as this: code\core\mob\character\character_actions.dm:4:error: 1: invalid expression (737)

Would be cool if if() could do this as well.

The var thing doesn't work, or the chained assignments? What's the actual code you're referring to? The var thing was already tested by Kaiochao.
Page: 1 2 3