Transpile these ES6 arrow functions! The ECMAScript 6 standard added many new features to the JavaScript language, including a new arrow function notation.

Your task is to write a basic ES6-to-ES5 transpiler. Given only an ES6 arrow function as input, output its ES5-compatible counterpart.

It's code-golf! May the shortest program in bytes win!



The Basics

An arrow function looks like this:

(a, b, c) =&gt; { return a + b - c }


And its equivalent ES5 function expression looks like this:

function(a, b, c) { return a + b - c }


In general, you can copy the body of the function (everything between the curly braces) verbatim.



Implicit Return Statement

Instead of a body with curly braces, a single expression can be used; the result of this expression is then returned.

(a, b, c) =&gt; a + b - c

function(a, b, c) { return a + b - c }


Another example:

(a, b, c) =&gt; (a + 1, b - 2 * c / 3)

function(a, b, c) { return (a + 1, b - 2 * c / 3) }


Again, you may simply copy the expression verbatim - BUT take care that you do not output a line break between it and the return keyword to avoid automatic semicolon insertion!



One Argument

Parentheses are optional if one argument is provided.

foo =&gt; { return foo + 'bar' }

function(foo) { return foo + 'bar' }




Whitespace

Finally, you must be able to account for any number of whitespace characters (space, tab, newline) before or after parentheses, variables, commas, curly braces, and the arrow*.

 ( o   ,  O
     , _    )=&gt;{

    return                                     "Please don't write code like this."
}


Whether or not you choose to preserve whitespace in the output is up to you. Keep 'em, remove 'em, or add your own - just make sure it's valid code!

*It's technically illegal for an arrow to come immediately after a line break, but I doubt this fact would help you. :)



A quick way to validate your output:

Enter var foo = &lt;your output&gt;; foo() into your browser console. If it doesn't complain, you're probably on the right track.



More rules for the wizards:


Input is a syntactically valid ES6 arrow function.
Assume the body of the function is ES5-compatible (and doesn't reference this, super, arguments, etc). This also means that the function will never contain another arrow function (but you may not assume that "=>" will never occur within the body).
Variable names will only consist of basic Latin letters, $ and _.
You need not transpile ES6 features that aren't listed above (default parameters, rest operator, destructuring, etc).
The space after a return statement is optional if followed by (, [, or {.
It isn't strictly necessary to match my test cases exactly - you can modify the code as much as you need if it'll help lower your byte count. Really, as long as you produce a syntactically valid, functionally equivalent ES5 function expression, you're golden!
JavaScript (ES6), 123 110 100 97 bytes

Saved 3 bytes thanks to @Neil

s=&gt;s.replace(/\(?(.*?)\)?\s*=&gt;\s*([^]*)/,(_,a,b)=&gt;`function(${a})${b[0]=='{'?b:`{return ${b}}`}`)


Assumes the input is a syntactically valid arrow function and nothing else. Correctly handles the case a =&gt;\na, though not handling is not any shorter as far as I can tell.

Output when the code is run through itself:

function(s){return s.replace(/\(?(.*?)\)?\s*=&gt;\s*([^]*)/,(_,a,b)=&gt;`function(${a})${b[0]=='{'?b:`{return ${b}}`}`)}




I can save 9 bytes with a possibly invalid format:

s=&gt;s.replace(/\(?(.*?)\)?\s*=&gt;\s*({?)([^]*?)}?$/,(_,a,z,b)=&gt;Function(a,z?b:'return '+b))


Output for itself:

function anonymous(s) {
return s.replace(/\(?([^=)]*)\)?\s*=&gt;\s*({?)([^]*?)}?$/,(_,a,z,b)=&gt;Function(a,z?b:'return '+b))
}


(Specifically, the function anonymous is what I'm worried about.)