sweet-js / sweet-core

Sweeten your JavaScript.
https://www.sweetjs.org
BSD 2-Clause "Simplified" License
4.58k stars 208 forks source link

Basic examples not working #750

Open danielo515 opened 6 years ago

danielo515 commented 6 years ago

Hello,

Taking several of the basic examples and trying to run them on the online editor produces errors. For example:

syntax let = function (ctx) {
  let ident = ctx.next().value;
  ctx.next(); // eat `=`
  let init = ctx.expand('expr').value;
  return #`
    (function (${ident}) {
      ${ctx} // <2>
    }(${init}))
  `
};

let bb8 = new Droid('BB-8', 'orange');
console.log(bb8.beep());

yields the following error:

Goto  Error: Unknown object: {"value":{"token":{"type":{"klass":{"name":"String"},"name":""},"typeCode":4,"str":"BB-8","octal":null,"slice":{"text":"'BB-8'","start":229,"startLocation":{"line":12,"column":21,"filename":"","position":229},"end":235}},"bindings":{"_map":{}},"scopesets":{"all":[{"name":"outsideEdge_35"}],"phase":{"0":[{"name":"insideEdge0_36"}]}}},"type":"RawSyntax","loc":null} 

Same thing happens if I install sweet from npm and try to compile it. I also tried to build a basic macro, but I'm only getting errors related to unknow objects to JSON.parse and that stuff.

The project seems to be a great potential, but I think it does not play well with the latest JS features like spread operator and template literals.

Regards

gabejohnson commented 6 years ago

It looks like the arguments to Droid aren't being enforested. It will work if you wrap the constructor call in parens:

let bb8 = (new Droid('BB-8', 'orange'));
console.log(bb8.beep());
danielo515 commented 6 years ago

Hello @gabejohnson Thanks for your answer.

Seems that you know how to workaround the possible problems that could emerge. Could you please help me building a very simple macro ? I just want to simulate the apply operator from haskell. So:

add $ 1 2
// becomes
add (1) (2)

I made several attempts, but none of them succeed compiling. Regards

gabejohnson commented 6 years ago

@danielo515 You're going to need to use the operator keyword as outlined https://www.sweetjs.org/doc/tutorial#sweet-operators

This is what I came up with

operator $ right 0 = (left, right) =>
  #`
    ${left}(${right})
  `;

log $ 1; // log(1);

You're not going to be able to support something like log $ 1 2 though as the second argument to $ is an already fully expanded expression. log $ 1 $ 2 should work though.

vendethiel commented 6 years ago

@gabejohnson "space" does not play in precedence resolution, right?

gabejohnson commented 6 years ago

@vendethiel not certain what you mean, but the space b/w 1 2 should just result in a syntax error. But sweet resolves it by putting 2 in a separate statement.

danielo515 commented 6 years ago

Hello @gabejohnson , That's something I tried already. Since writing one dollar sing instead of two parents is less typing, the final result will be equally ugly. This seems to be a great challenge for everything I tried so far: babel-macros, livescript, babel plugins, sweet....