DanielXMoore / Civet

A TypeScript superset that favors more types and less typing

Home Page:https://civet.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Trailing pipe or property access should expressionize statement

edemaine opened this issue · comments

Consider:

switch @value
  Value.Ace then 'A'
  Value.Jack then 'J'
  Value.Queen then 'Q'
  Value.King then 'K'
  else @value
.toString()

Currently this compiles to:

let m;if(m = this.value,m === Value.Ace) { 'A'}
else if(m === Value.Jack) { 'J'}
else if(m === Value.Queen) { 'Q'}
else if(m === Value.King) { 'K'}
else  { this.value };
$ => $.toString()

It behaves the same within an arrow function too; the $ => $.toString() gets implicitly returned but the switch value gets dropped. The issue is that the switch is a valid Statement and that takes priority over expressions.

I'd propose instead that it compiles to:

(()=>{let m;if(m = this.value,m === Value.Ace) { return 'A'}
else if(m === Value.Jack) { return 'J'}
else if(m === Value.Queen) { return 'Q'}
else if(m === Value.King) { return 'K'}
else  { return this.value }})()
.toString()

This is what we get with an explicit return added, I believe via ExpressionizedStatementWithTrailingCallExpressions. Maybe we just need to check for this before regular Statements, but when there's a positive number of trailing expressions?

Similar to postfix .foo, it'd be nice to have postfix pipelines. Original motivating example from Discord:

switch @value
  Value.Ace then 'A'
  Value.Jack then 'J'
  Value.Queen then 'Q'
  Value.King then 'K'
  else String @value
|> (+ @suit)

Currently this is a parse error, again because the switch parses as a Statement and that doesn't have postfixes available. But this one doesn't work with an explicit return either. Probably we need to add pipelines to ExpressionizedStatementWithTrailingCallExpressions (perhaps with a different name).

Another example I ran into today that doesn't work:

async do
  await foo()
  await bar()
.then =>
  baz()

(trying to make the outer function not async, but instead return a Promise)