Skip to content

Latest commit

 

History

History
384 lines (324 loc) · 6.72 KB

README.md

File metadata and controls

384 lines (324 loc) · 6.72 KB

ToffeeScript

ToffeeScript is a CoffeeScript dialect with Asynchronous Grammar

Features

  1. Asynchronous everywhere
    • Condition: If, Switch
    • Loop: For In, For Of, While with guard when
    • Mathematics
    • Logical Operation
  2. Auto Callback
  3. Regexp Operator =~ and matches \~, \&, \0~\9
  4. High efficent code generated.
  5. Sourcemap Supported.
    • Follow up to CoffeeScript 1.6.2 so far
  6. Safety named-function supported.
    • Added in ToffeeScript 1.6.2-3

Installation

npm install toffee-script

Named Function

ToffeeScript support named function which is different from CoffeeScript. if the function defined in the first level of code block and the function name haven't been used, then compile it as named function. see Code Examples section It won't have compatible issue with CoffeeScript except one case

# m never declared above, m must be local variable and assign to undefined
m()
m = ->
m

in CoffeeScript will throw exception undefined is not function. Use m as constant undefined variable is rare case.

in ToffeeScript function m is hoisted, and will run function m() as Javascript does.

Code Examples

Left: ToffeeScript

Right: Generated JavaScript

Basic

x, y = a! b
console.log x, y
var x, y,
  _this = this;

a(b, function() { x = arguments[0], y = arguments[1]; return console.log(x, y); });

with powerful CoffeeScript assignment [...]

[@x, y...] = a! b
console.log @x, y
var y,
  _this = this,
  __slice = [].slice;

a(b, function() { _this.x = arguments[0], y = 2 <= arguments.length ? __slice.call(arguments, 1) : []; return console.log(_this.x, y); });

Condition

if i
  x = a!
else
  y = b!
console.log x, y
var x, y,
  _this = this;

if (i) { a(function() { x = arguments[0]; _$$_0(); }); } else { b(function() { y = arguments[0]; _$$_0(); }); }

function _$$_0() { return console.log(x, y); };

Async in condition

if e = a!
  return cb(e)
foo()
var e,
  _this = this;

a(function() { _$cb$_2(e = arguments[0]); }); function _$cb$2($$0) { if ($$_0) { return cb(e); } else { _$$_1(); } function _$$_1() { return foo(); }; };

Async in condition with multi return

Async call always return first argument

if e, data = fs.readFile! 'foo'
  return cb(e)
console.log data
var data, e,
  _this = this;

fs.readFile('foo', function() { _$cb$_2((e = arguments[0], data = arguments[1], e)); }); function _$cb$2($$0) { if ($$_0) { return cb(e); } else { _$$_1(); } function _$$_1() { return console.log(data); }; };

Loop

Support For In, For Of, While with guard when

xs = for i in [1..3] when i > 2
  a!
  # return arguments[0] in default
var i, xs, _$res$_1, _i,
  _this = this;

_$res$_1 = []; i = _i = 1; function _step() { i = ++_i; _body(); }; function _body() { if (i <= 3) { if (i > 2) { a(function($$_2) { step($res$1.push($$_2)); }); } else { _step(); } } else { _done(); } }; function _done() { _$cb$0($res$_1); }; _body(); function _$cb$_0() { return xs = arguments[0]; };

Mathematics

x = a! + b! * c!
var x,
  _this = this;

a(function(_$$1) { b(function($$3) { c(function($$_4) { _$cb$2($$_3 * _$$_4); }); }); function _$cb$2($$_5) { _$cb$0($$_1 + _$$_5); }; }); function _$cb$_0() { return x = arguments[0]; };

Object

A =
  a: a
  b: b!
  c: c
var A, _$$_1,
  _this = this;

_$$1 = a; b(function($$_2) { _$cb$_0({ a: _$$_1, b: _$$_2, c: c }); }); function _$cb$_0() { return A = arguments[0]; };

Logical

Support ||, &&, ?, &&=, ||=, ?=

x = a! || b!
console.log x
var x,
  _this = this;

a(function(_$$1) { if ($$_1) { _$cb$3($$1); } else { b(function($$_2) { _$cb$3($$_2); }); } }); function _$cb$3($$_4) { _$cb$0($$_4); }; function _$cb$_0() { x = arguments[0]; return console.log(x); };

Auto Callback

a = (autocb) -> return 3
function a(autocb) {
  return autocb(3);
};

Return Multiple Values

a = (autocb) -> return null, 3
function a(autocb) {
  return autocb(null, 3);
};

Autocb with default args

a = (paramA, autocb(e, data)) ->
  e = foo!
  if something
    data = 1
  else
    data = 2
function a(paramA, autocb) {
  var data, e,
    _this = this;
  foo(function() {
    e = arguments[0];
    if (something) {
      data = 1;
      autocb(e, data);
    } else {
      data = 2;
      autocb(e, data);
    }
  });
};

Regexp

if a =~ b || b =~ c
  \~
  \&
  \0
  \9
var __matches;

if ((__matches = a.match(b)) || (__matches = b.match(c))) { __matches; __matches[0]; __matches[0]; __matches[9]; }

Named Function Supported

a = ->
b = ->
null
function a() {};

function b() {};

null;

Those cases will be kept in non-named function

f = null
if a
  b = c ->
d e = ->
f = ->
null
var b, e, f;

f = null;

if (a) { b = c(function() {}); }

d(e = function() {});

f = function() {};

null;