D to Javascript converter (a hacked up dmd)

Adam D. Ruppe destructionator at gmail.com
Fri Mar 2 06:57:52 PST 2012


On Friday, 2 March 2012 at 09:33:44 UTC, Alix Pexton wrote:
> Have you considered faking scopes in JS using anonymous 
> functions?

Yeah, though right now I'm trusting the D compiler to
keep it straight, and it is doing a pretty good job
while being really simple to code.

What happens is all the local variables are mangled
with respect to their full scope too (which leads to
ridiculously long, but unique names).

The D scope simply outputs its own code:

D:
  { // create a scope
     int a = 10;
  }
   int a = 20; // the old a is out of scope, so we can do this

Javascript:
     var _D_inner_a = 10; // not a real var name, just demo
     var _D_outer_a = 20; // new var


The inner variable is still in scope, so I doubt Javascript
garbage collects it, but thanks to the rules of D, it is
never used again.

But, if you use a struct with a destructor (or scope(exit)),
it generates this:

D:
   {
     MyStruct a;
   }
    MyStruct a;

Javascript:

    try {
      var _D_inner_A = new MyStruct();
    }
    finally {
         MyStruct_destructor(_D_inner_A);
    }
    try {
       var _D_outer_A = new MyStruct();
    }
    finally {
        MyStruct_destructor(_D_outer_A);
    }



And, in this case, Javascript's bizarre scoping
actually simplifies things.


In Javascript, when you write "var x = y;" in the
middle of a function, the way it really works is
it adds a "var x;" to the top of the function,
and leaves "x = y;" in hte middle.


You write:
function test() {
     if(something_here()) {
        var a = 10;
     }
     a++;
}

Javascript acts as if you wrote:

function test() {
    var a;
    if(something_here()) {
          a = 10;
    }
    a++;
}


With our try/finally (that dmd generates, mostly; I didn't
have to do much to make this work), the var declartion
in the try being hoisted up top means we can be sure it
works correctly in the finally, too.




But, with regard to the D scoping, dmd mangles the names
to make sure you don't reference anything that's out of
scope accidentally by giving them unique names.




This hoisting behavior is the proper solution to the
CommaExp declarations mentioned previously, where
dmd likes to write: foo( (var a = 10, a) ) and the
sort.


Currently, I put the var a; in global scope, leaving
just (a=10,a) in the expression. This is legal Javascript,
and should be ok due to unique names, but it pollutes the globals.


If I add a way to instead put those var declarations in
function scope, it is cleaner - no globals - and the same
thing Javascript itself would do anyway!


I'll have to redo the string buffering to make that though,
so it will take some code to do it. Dumping it in the global
was simple to implement with what was already there.

> I don't think they are very pretty, but it is sometimes a 
> useful technique.

heh, same with mangled names :)


More information about the Digitalmars-d-announce mailing list