livescript / discuss

A place to discuss the future of LiveScript
5 stars 0 forks source link

Convert AST #3

Open dk00 opened 7 years ago

dk00 commented 7 years ago

I'm working on a tool that converts LiveScript AST to ES AST, current version supports output of babel AST. You can try it here.

With this, LiveScript can be compiled to any version of ES (that babel supports).

Why?

See gkz/LiveScript#821.

We have good tools can generate ES code from a tree, if we use them wisely, it would be an easy way to keep up with latest ES features.

Status

LiveScript features other than for, while, yield, function*, class are implemented or partially implemented, all of that required to host itself are done, and the first version is published to npm.

It can be used with babel as a custom parser, and when using in this way, first class code coverage support is enabled. The coverage tool can instrument directly with original source locations, instead of translate compiled locations back with source maps (see also: coverage report of itself).

import can be used like require! at top scope, and export is converted to ES equivalent instead.

import
  redux: {create-store}
  react
  \react-dom : *: $

export
  default: my-app, alias: another
  {my-fn}
  external: {external-fn, renamed: external-name}
import { createStore } from "redux";
import react from "react";
import * as $ from "react-dom";
export { myApp as default, another as alias };
export { myFn };
export { externalFn, externalName as renamed } from "external";

Destructuring is also converted to its ES equivalent, this also enables splats in object:

{name, age, ...rest} = weight: 110 name: \emma age: 20
let name, age, rest;
({
  name='no name',
  age,
  ...rest
} = {
  weight: 110,
  name: "emma",
  age: 20
});

Existence operators are compiled with ES destructuring, to avoid using multiple temporary variables.

t = get-obj!?[prop-key 0]? arg .[prop-key 1]? arg
let t, that, key$, ref$;
t = (that = getObj()) != null ?
  typeof that[key$ = propKey(0)] == "function" ?
  typeof (
    [ref$, key$] =
    [that[key$](arg), propKey(1)], ref$[key$]
  ) == "function" ?
  ref$[key$](arg)
  : void 8 : void 8 : void 8;

do expressions(just advanced to stage 1!) are used to turn everything into expressions.

result = if 2 / 2 is 0
  'something'
else
  'something else'
let result;
result = do {
  if (2 / 2 === 0) {
    "something";
  } else {
    "something else";
  }
};

async/await expressions are also possible to add with this, and will be included in next release.

vendethiel commented 7 years ago

Being able to remove makeReturn and makeComprehension surely look like an interesting solution.