ceylon / ceylon.ast

Apache License 2.0
18 stars 3 forks source link

Expression statements #54

Closed lucaswerkmeister closed 10 years ago

lucaswerkmeister commented 10 years ago

Only certain expressions are valid statements:

  • assignment,
  • prefix or postfix increment or decrement,
  • invocation of a method,
  • instantiation of a class.
ExpressionStatement: ( Assignment | IncrementOrDecrement | Invocation ) ";"

[…] A specification statement may specify or initialize the persistent value of a forward-declared reference, or specify the implementation of a forward-declared getter or function.

Specification: ValueSpecification | LazySpecification

[…]

ValueSpecification: MemberName Specifier ";"

Note: there is an apparent ambiguity here. Is the statement x=1; a value specification statement, or an assignment expression statement? The language resolves this ambiguity by favoring the interpretation as a specification statement whenever that interpretation is viable. This is a transparent solution, since it accepts strictly more code than the alternative interpretation, and for ambiguous cases the actual semantics are identical between the two interpretations.

Since the ceylon.ast AST should be unambigous, I’d make ExpressionStatement’s Expression have the type ArithmeticAssignmentOperation | SetAssignmentOperation | LogicalAssignmentOperation | PrefixOperation | PostfixOperation | Invocation; that is, instead of AssignmentOperation, have “AssignmentOperation ∖ AssignOperation” (that’s a set minus), which (as Ceylon doesn’t have complement types) we denote by listing the case types of AssignmentOperation without AssignOperation.

(Perhaps it should be split into AssignmentStatement, PrefixPostfixStatement, InvocationStatement? Otherwise the type becomes so long…)

Any opposed?

lucaswerkmeister commented 10 years ago

On second thought, it should definitely be split like that.

lucaswerkmeister commented 10 years ago

Ah damn, no, I got that completely wrong. In general, you have to allow an expression statement with a plain assignment expression, in order to support this:

things.first.content = thing;
(currentElement else defaultElement).attribute = val;

These aren’t covered by Specification because for a specification, the LHS is just a member name.

So I’ll just have to assert (at runtime :( ) that the LHS of the assignment isn’t a simple base expression.

Should I do that? Or perhaps that should be allowed?

(Well, at least the types in ExpressionStatement and AssignmentStatement are a lot simpler now… so that’s nice. It’s probably still worth it to have separate classes for them, though.)