Skip to content

Multi-statement expressions #654

@ark120202

Description

@ark120202

The missing ability to transform an expression to multiple statements is a blocker for many features:

roblox-ts implementation could be useful as a reference.

Some ideas:

Each transformStatement (and some other functions) should push a new context. A new method would push statements there. All extra statements would be prepended to result when transformStatement finishes. So:

foo(x ? x() : y());

->

local ____0
if x then
    ____0 = x()
else
    ____0 = y()
end
foo(____0)

where related part of transformConditionalExpression would look like:

const temporaryIdentifier = tstl.createIdentifier("____0");
this.pushStatements(/* create preceding statements with temporaryIdentifier */);
return temporaryIdentifier;

The more complex part begins when we have expressions that may have side effects, for example:

foo()(x ? x() : y());

the expected result for that would be:

local ____0 = foo()
local ____1
if x then
    ____1 = x()
else
    ____1 = y()
end
____0(____1)

I have few ideas about possible implementations:

  1. When transformStatement finishes, and it's context has any preceding statements, traverse result, find all side-effect expressions and extract it to variables.

    I'm not really sure that it's possible to implement, the traversing function should be quite complex to be able to extract it without breaking expected flow.

  2. Before pushing new context, traverse TS AST, and, if there is some expression that requires multi-statement transform, set a flag in the context. If that flag is set, any side-effect expression would be extracted to a variable.

    This one should be simpler, but it doesn't sound as a good design, since we'll have to implement logic for deciding it twice (during initial traverse and actual transform).

  3. Transform expression as usual, and, if we have any preceding statements, set some flag and transform it again.

    So, it's like the second option, but doesn't require additional logic for traversing. However that means that we should be sure that our transform functions don't have any side effects, because original result would be left unused.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions