sweet.js
Sweeten your JavaScript.
sweet.js
How can I transform the following snippet:
let myVar: string = 'test';
To following output:
// type {string}
var myVar = 'test';
using sweetjs?
UPDATE
I'm looking for a way to transform the exact first code snippet to the second one. Including the // type {string}
comment.
I Want to use it to create a simple DSL to generate a code to be checked with google closure compiler.
Source: (StackOverflow)
I want to use parenthesis in macros body to group expressions. For example:
macro m {
rule { ($x, $y) } => {
$x >>> ($y * 5)
}
}
Sweet.js remove all parenthesis:
m(6, 7) => 6 >>> 7 * 5
I expect next output:
m(6, 7) => 6 >>> (7 * 5)
How can I escape parenthesis inside macros body?
Source: (StackOverflow)
I'm trying to write a case macro in sweet.js but I don't know how to match the end of a block.
In particular I would like to match the code between the macro call and the end of the block that contains it.
For example if my macro is myMacro
, and the code is as follows
var foo = function() {
console.log('log1');
myMacro(someArg);
console.log('log2');
console.log('log3');
}
I would like to be able to match the lines with 'log2' and 'log3'.
My guess is that I can't but I can't find a clear definition how matching works in the documentation (pointers would be appreciated).
Is it possible ?
Source: (StackOverflow)
How would you create a string from an argument to a sweet.js macro? For example:
let foo = macro {
rule {
$name
} => {
console.log('$name', $name);
}
}
var x = 42;
foo x
Will output:
console.log(x, x);
When I'd prefer it to output:
console.log('x', x);
So the first argument has quotes around it.
Source: (StackOverflow)
I want to expand a token to a string. For example, I have this macro:
macro String {
rule {
$x
} => {
"$x"
}
}
I would expect String 1
to expand to "1"
, however it expands to just 1;
How can I accomplish this?
EDIT: This seems imposible to do with a declarative approach, but should be possible with an imperative approach (see this comment):
macro String {
case {_ $x } => {
return #{"$x"}
}
}
But that still expands with quotes.
Source: (StackOverflow)
I want to implement a higher order function (hof
) that essentially works like F# style forward-pipe operator (passes a value as the first argument to another function, myFunc
). The only way I can think of is this:
function hof(val, myFunc, args_array) {...}
where args_array
is the array of arguments for the call to myFunc
(excluding the first argument, since that's going to be val
)
But this doesn't look very elegant to me. Is there a better way to do this?
Edit: I found this on github https://gist.github.com/aaronpowell/d5ffaf78666f2b8fb033. But I don't really understand what the sweet.js
code is doing. It'd be very helpful if you could annotate the code, specifically:
case infix { $val | _ $fn($args (,) ...) } => {
return #{
($fn.length <= [$args (,) ...].length + 1 ? $fn($args (,) ..., $val) : $fn.bind(null, $args (,) ..., $val))
}
}
case infix { $val | _ $fn } => {
return #{
($fn.length <= 1 ? $fn($val) : $fn.bind(null, $val))
}
}
Source: (StackOverflow)
I just got in JavaScript and noticed that lazy evaluation is not directly supported in this language. Natively the code turns into the hell of boiler plate like this:
function lazy(f) {
var v = undefined;
return function() {
if (v == undefined)
v = f();
return v;
}
}
// 10 times larger than actual operation
var foo = lazy(function() {
return 3 + 3;
});
But I found Sweet.js and believe that it can make the code simple like this:
var foo = lazy (3 + 3);
var goo = lazy {
var a = 3 + 3;
return a;
};
So I tested out Edit Sweet.js:
function lazy_f(f) {
var v = undefined;
return function() {
if (v == undefined)
v = f();
return v;
}
}
macro lazy {
rules { $expr } => {
lazy_f(function() { return $expr; })
}
}
var foo = lazy (3 + 3);
It worked with a single expr. But there are cases that lazy
takes in a block of expr like this:
var goo = lazy {
var a = 3 + 3;
return a;
};
So I arranged the above code like this:
function lazy_f(f) {
var v = undefined;
return function() {
if (v == undefined)
v = f();
return v;
}
}
macro lazy {
rule { $($expr) (;) ... } => { //
lazy_f(function() $expr ...); //
} //
rules { $expr } => {
lazy_f(function() { return $expr; })
}
}
var foo = lazy (3 + 3);
var goo = lazy {
var a = 3 + 3;
return a;
};
And it doesn't work for some reason. I believe the first pattern $($expr) (;) ...
shouldn't match with (3 + 3)
, but apparently it's doing.
I worked on this for an hour and finally gave up. How do you make the two patterns working at the same time?
If it's not possible to do so, I would like to take another way for a single expr:
lar foo = 3 + 3;
var foo_content = foo();
And I don't know how to do this as well.
Source: (StackOverflow)
I am really new to sweet.js.
I would love to have multiline strings in javascript just like in EcmaScript 6:
var htmlString = `Say hello to
multi-line
strings!`;
Is it possible to formulate a sweetjs macro handling that (and how ??) ?
Furthermore, would it be possible to do String Interpolation/Templating using that macro just like ES6 does ?
Source: (StackOverflow)
I'm brand new to Sweet.js. My first simple macro is the following
macro test {
rule {
$className($entityName)
} => {
function test$className()
{
console.print("$className");
console.print("$entityName");
}
}
}
test me(More)
which produces
function test$className() {
console.print(me);
console.print(More);
}
but I'd like it to produce this:
function testMe() {
console.print("me");
console.print("More");
}
but any variants I've tried for it haven't worked. Any suggestions?
Source: (StackOverflow)
I am attempting to use SweetJS in my project. In order to better understand and learn SweetJS I thought I would start with a simple "class" macro (I know a few exist, just playing around here...). I can NOT seem to get SweetJS to stop messing with my local variables "self" and "superCall" however. Any ideas what I am doing wrong? I would like var self=this
to remain var self=this
instead of being mangled.
macro class {
case { _ $name extends $parent {
constructor $cargs { $cbody ... }
$($mname $margs { $mbody ... } ) ...
} } => {
return #{
function $name $cargs { var self=this,superCall=$parent.prototype; $cbody ... }
$name.prototype = Object.create($parent.prototype);
($name.prototype.$mname = function $margs {var self=this,superCall=$parent.prototype; $mbody ... } ) ...;
}
}
case { _ $name { $body ...} } => {
return #{ class $name extends test2 { $body ... } };
}
}
macro super {
case { $macroName.$name( $($args (,) ...) ) } => {
letstx $s = [makeIdent("self", #{ $macroName })];
letstx $sC = [makeIdent("superCall", #{ $macroName })];
return #{
$sC.$name.call($s)
};
}
case { $macroName( $args ... ) } => {
letstx $s = [makeIdent("self", #{ $macroName })];
letstx $sC = [makeIdent("superCall", #{ $macroName })];
return #{
superCall.constructor.call($s);
};
}
}
class test extends cow {
constructor(arg1, arg2) {
console.log('Hello world!');
}
method1(arg1, arg2) {
super.method1();
}
}
This expands to:
function test(arg1, arg2) {
var self$2 = this, superCall$2 = cow.prototype;
console.log('Hello world!');
}
test.prototype = Object.create(cow.prototype);
test.prototype.method1 = function (arg1, arg2) {
var self$2 = this, superCall$2 = cow.prototype;
superCall.method1.call(self);
};
As you can see, var self=this
has been turned into var self$2 = this
. How can I prevent this? I have attempted to use makeIdent
, but I think I am doing something wrong. Any ideas? Thanks!
Source: (StackOverflow)
I'm trying to write a sweet.js
macro which needs to generate method call syntax, obj.method()
, but the method
is passed in to the macro as a literal expression. For example:
mcall(obj, toString().length);
// becomes
obj.toString().length;
I've got something that's close:
macro mcall {
rule { ($o, $m:expr) } => { $o.$m }
}
mcall(obj, toString().length);
However, this apparently expands to this:
obj . ( toString ( ) . length );
Where are these extra parentheses coming from, and how do I get rid of them? Should I be using case rules and #{}
? I tried permutations of that but still couldn't succeed at generating a method call without extra parentheses.
Source: (StackOverflow)
I'm playing around with sweetjs and for the life of me can't figure out why this rule for parameterless multiline skinny arrow syntax isn't matched
Code:
macro -> {
rule infix { () | { $body ... $last:expr } } => {
function( ) {
$body ...;
return $last
}
}
}
var fn = () -> {
var a = 1;
a + 2;
};
expect(fn()).to.equal(3);
results in
SyntaxError: [macro] Macro `-` could not be matched with `> {} ; expect ()...`
10: var fn = () -> {
^
Source: (StackOverflow)
One of the items on my TODO list is creating a fun coding language that 'compiles' to JavaScript. I would like to try out Sweet.js for this, but I'm wondering if it is possible to write a rule that targets keywords that are before the rule?
As an example, let's say you'd want to create a Yoda-styled JavaScript. A source line could look like this:
six var is;
Would be mapped to
var six;
Is this possible using Sweet.js?
Source: (StackOverflow)
From the shell, I can call the Sweet.js compiler.
sjs -m macro-providing-module -o output-directory/file.js input-directory/file.sjs
How can I do the same from inside a Node.js module such that instead of outputting to a specified file, I get the compiled output as a string?
var sweetjs = require('sweet.js');
var input = require('fs').readSync('input-directory/file.sjs');
var module = 'macro-providing-module';
var output = sweetjs(/* ??? */);
Source: (StackOverflow)
In the bluebird wiki article about JavaScript optimization killers, the author mentions that passing the arguments
keyword to any function (except apply
) will cause the parent function to not be optimizable. I would like to create a sweet.js macro that allows me to write standard idiomatic JavaScript but will take care of the optimization killer.
Ideally, I would like a macro that would take the following function:
function foo() {
var args = [].slice.call(arguments);
return args;
}
And output something like this:
function foo() {
var args = [];
for(var i, len = arguments.length; i < len; i++) {
args.push(arguments[i]);
}
return args;
}
I am having trouble with getting the sweet.js macro syntax correct, however. This is what I have so far:
example.sjs
let arguments = macro {
rule infix {
[].slice.call |
} => {
[];
for(var i = 0, len = arguments.length; i < len; i++) {
args.push(arguments[i])
}
}
}
function toArray() {
var args = [].slice.call arguments
return args;
}
Which outputs the following:
function toArray() {
var args$2 = [];
for (var i = 0, len = arguments.length; i < len; i++) {
args.push(arguments[i]);
}
return args$2;
}
I tried making my macro have parenthesis around the arguments
keyword and also include the var
declaration, but without any success. I tried something like this:
invalid macro
let arguments = macro {
rule infix {
var $var = [].slice.call ( | )
} => {
var $var = [];
for(var i = 0, len = arguments.length; i < len; i++) {
args.push(arguments[i])
}
}
}
This produces the following error:
SyntaxError: [syntaxCase] Infix macros require a `|` separator
414:
^
Source: (StackOverflow)