View mode: basic / threaded / horizontal-split · Log in · Help
February 27, 2012
D to Javascript converter (a hacked up dmd)
https://github.com/downloads/adamdruppe/dtojs/dtojs.zip

Daniel Murphy's microd fork of dmd, meant to output C,
made me realize it'd be fairly easy to use that same method
for other languages too.

So, I spent some time these last two weekends making it work
to put out Javascript.


See below for a copy/paste of the readme on how to get started.

A live demo:
http://arsdnet.net/dtojs/test.html

D source code:
http://arsdnet.net/dtojs/microd.d



As you can see, a lot of things work: functions, main,
most the operators, loops, if, basic data types,
even structs, classes (including inheritance), and exceptions.


Take a look at the generated javascript
http://arsdnet.net/dtojs/microd.js

It looks messy, since it uses mangled names almost everywhere.
(if you replace the mangled names with shorter things, it cuts
the size down by like 60%. Or, you can gzip it for a 10x 
reduction.
 See tools/mangledown.d in the zip, but this is raw so you can see
what it makes.)



For classes, it creates a vtable and some run time type 
information
on the Javascript object. This allows dynamic casts and virtual
functions to work like you expect in D.

You can see _Dmain in the middle of the file, and at the bottom,
you can see it is called if present, so you can have one or not 
have
one at your preference.

As you scroll down, you'll see the methods. Since I forked a C
generator, they are made and usually called as free functions,
but extern(js) (see below) are made as object properties.


Not so obvious is the runtime that's mixed in there.

Here's the D source code:
http://arsdnet.net/dtojs/object.d


It's pretty simple code. extern(js) works to let you - and other
JS things - easily interact with the outside world, since it
turns off mangling while letting you define things like loose
variadics.

There is no handwritten Javascript except for the if(_Dmain) at
the end. The rest of the runtime and library is written in D.



Speaking of library, I started something there too.

http://arsdnet.net/dtojs/browser/

the browser package generates no Javascript code. It simply
binds to existing functionality so D can use it in a more
structured manner. (object.d generates ~14kb of code when
raw. If you run mangledown on it, it goes down to about 6.)

browser.document provides some access to the browser DOM.

http://arsdnet.net/dtojs/std/

The std package is a kind of Phobos library, meant to make
source-compatible code with regular D stuff. It generates some
javascript.


I don't want to use the real Phobos though because it is fairly
large, and won't take advantage of the browser's existing library
functions. It *might* work in here though; I haven't tried.



The browser package makes no attempt at cross browser 
compatibility,
but you can test for functions like you would in real JS:

if(&document.querySelector) { we have it }



If I start to use this thing seriously, I might provide a library
wrapper that does this kind of thing.






Anyway, it works pretty well in the trivial tests I've done
so far, but I haven't used it for anything more serious.



Kinda cool though, and hasn't been that hard. The dmd compiler
isn't so bad to hack up once you get to know it.

Combined with the stuff others and I have already done for
D on the server, we might just be coming up on web apps that
use the same D everywhere!

========
Here's how to use it:

First, copy in the backend folder from the dmd.zip you
get from Digital Mars.

(You need it to compile, but I don't have a license to
distribute it myself.)


Then, run make to build the hacked dmd.



When its done, change into the "test" directory and
start to play. The makefile there shows how to build
some javascript.

../dmd -md yourfile.d

and optionally you can use my library in there from
test/browser and test/std.(add std/*.d to the dmd
command line to make sure its code is generated in.)

You can ignore most the messages it spams out; it
will do its best to generate the file anyway.

test/browser is the kind of core runtime to this,
in addition to object.d.

object.d - the stuff D expects and the basic JS language
constructs

browser/*.d - bindings to objects and functions the browser 
provides
such as the DOM.

Most global functions in the browser are found in 
browser/window.d.


std/*.d - just super minimal wrappers to browser functions laid 
out
more like Phobos.
February 27, 2012
Re: D to Javascript converter (a hacked up dmd)
On 2012-02-27 04:51, Adam D. Ruppe wrote:
> https://github.com/downloads/adamdruppe/dtojs/dtojs.zip
>
> Daniel Murphy's microd fork of dmd, meant to output C,
> made me realize it'd be fairly easy to use that same method
> for other languages too.
>
> So, I spent some time these last two weekends making it work
> to put out Javascript.
>

Interesting, and cool.

-- 
/Jacob Carlborg
February 27, 2012
Re: D to Javascript converter (a hacked up dmd)
Cool!

Can you call custom (external, from 3rd party libs) JS functions from
there?
You should port jquery syntax sugar :)


Il giorno lun, 27/02/2012 alle 09.48 +0100, Jacob Carlborg ha scritto:

> On 2012-02-27 04:51, Adam D. Ruppe wrote:
> > https://github.com/downloads/adamdruppe/dtojs/dtojs.zip
> >
> > Daniel Murphy's microd fork of dmd, meant to output C,
> > made me realize it'd be fairly easy to use that same method
> > for other languages too.
> >
> > So, I spent some time these last two weekends making it work
> > to put out Javascript.
> >
> 
> Interesting, and cool.
>
February 27, 2012
Re: D to Javascript converter (a hacked up dmd)
"Adam D. Ruppe" <destructionator@gmail.com> wrote in message 
news:yfmgvgprfpiquakiyjlk@forum.dlang.org...
> https://github.com/downloads/adamdruppe/dtojs/dtojs.zip
>
> Daniel Murphy's microd fork of dmd, meant to output C,
> made me realize it'd be fairly easy to use that same method
> for other languages too.
>
> So, I spent some time these last two weekends making it work
> to put out Javascript.
>

This is great - it might make javascript actually usable as a platform. =D

How come you didn't do this as a proper fork/branch of dmd?  It seems like 
doing it this way would make it harder to maintain, and it certainly makes 
it harder to see what's been changed.

It's also not too hard to strip out the backend if you want to redistribute 
the binary.  (stub out e2ir,s2ir,glue,toobj,iasm and remove the backend 
specific stuff from main)
February 27, 2012
Re: D to Javascript converter (a hacked up dmd)
Does this mean I can do node.js in D? :)

On Monday, 27 February 2012 at 03:51:22 UTC, Adam D. Ruppe wrote:
> https://github.com/downloads/adamdruppe/dtojs/dtojs.zip
>
> Daniel Murphy's microd fork of dmd, meant to output C,
> made me realize it'd be fairly easy to use that same method
> for other languages too.
>
> So, I spent some time these last two weekends making it work
> to put out Javascript.
>
>
> See below for a copy/paste of the readme on how to get started.
>
> A live demo:
> http://arsdnet.net/dtojs/test.html
>
> D source code:
> http://arsdnet.net/dtojs/microd.d
>
>
>
> As you can see, a lot of things work: functions, main,
> most the operators, loops, if, basic data types,
> even structs, classes (including inheritance), and exceptions.
>
>
> Take a look at the generated javascript
> http://arsdnet.net/dtojs/microd.js
>
> It looks messy, since it uses mangled names almost everywhere.
> (if you replace the mangled names with shorter things, it cuts
> the size down by like 60%. Or, you can gzip it for a 10x 
> reduction.
>  See tools/mangledown.d in the zip, but this is raw so you can 
> see
> what it makes.)
>
>
>
> For classes, it creates a vtable and some run time type 
> information
> on the Javascript object. This allows dynamic casts and virtual
> functions to work like you expect in D.
>
> You can see _Dmain in the middle of the file, and at the bottom,
> you can see it is called if present, so you can have one or not 
> have
> one at your preference.
>
> As you scroll down, you'll see the methods. Since I forked a C
> generator, they are made and usually called as free functions,
> but extern(js) (see below) are made as object properties.
>
>
> Not so obvious is the runtime that's mixed in there.
>
> Here's the D source code:
> http://arsdnet.net/dtojs/object.d
>
>
> It's pretty simple code. extern(js) works to let you - and other
> JS things - easily interact with the outside world, since it
> turns off mangling while letting you define things like loose
> variadics.
>
> There is no handwritten Javascript except for the if(_Dmain) at
> the end. The rest of the runtime and library is written in D.
>
>
>
> Speaking of library, I started something there too.
>
> http://arsdnet.net/dtojs/browser/
>
> the browser package generates no Javascript code. It simply
> binds to existing functionality so D can use it in a more
> structured manner. (object.d generates ~14kb of code when
> raw. If you run mangledown on it, it goes down to about 6.)
>
> browser.document provides some access to the browser DOM.
>
> http://arsdnet.net/dtojs/std/
>
> The std package is a kind of Phobos library, meant to make
> source-compatible code with regular D stuff. It generates some
> javascript.
>
>
> I don't want to use the real Phobos though because it is fairly
> large, and won't take advantage of the browser's existing 
> library
> functions. It *might* work in here though; I haven't tried.
>
>
>
> The browser package makes no attempt at cross browser 
> compatibility,
> but you can test for functions like you would in real JS:
>
> if(&document.querySelector) { we have it }
>
>
>
> If I start to use this thing seriously, I might provide a 
> library
> wrapper that does this kind of thing.
>
>
>
>
>
>
> Anyway, it works pretty well in the trivial tests I've done
> so far, but I haven't used it for anything more serious.
>
>
>
> Kinda cool though, and hasn't been that hard. The dmd compiler
> isn't so bad to hack up once you get to know it.
>
> Combined with the stuff others and I have already done for
> D on the server, we might just be coming up on web apps that
> use the same D everywhere!
>
> ========
> Here's how to use it:
>
> First, copy in the backend folder from the dmd.zip you
> get from Digital Mars.
>
> (You need it to compile, but I don't have a license to
> distribute it myself.)
>
>
> Then, run make to build the hacked dmd.
>
>
>
> When its done, change into the "test" directory and
> start to play. The makefile there shows how to build
> some javascript.
>
> ../dmd -md yourfile.d
>
> and optionally you can use my library in there from
> test/browser and test/std.(add std/*.d to the dmd
> command line to make sure its code is generated in.)
>
> You can ignore most the messages it spams out; it
> will do its best to generate the file anyway.
>
> test/browser is the kind of core runtime to this,
> in addition to object.d.
>
> object.d - the stuff D expects and the basic JS language
> constructs
>
> browser/*.d - bindings to objects and functions the browser 
> provides
> such as the DOM.
>
> Most global functions in the browser are found in 
> browser/window.d.
>
>
> std/*.d - just super minimal wrappers to browser functions laid 
> out
> more like Phobos.
February 27, 2012
Re: D to Javascript converter (a hacked up dmd)
On Monday, 27 February 2012 at 09:46:51 UTC, Andrea Fontana wrote:
> Can you call custom (external, from 3rd party libs)
> JS functions from there?

Yes, just make:

extern(js) void function_name_here(...);

and you can call it. For jQuery, you'd probably want
to define an extern(js) class JQuery {} with all its method
names. Since so many of them take strings, I think this would
actually be somewhat easy.
February 27, 2012
Re: D to Javascript converter (a hacked up dmd)
On Monday, 27 February 2012 at 11:32:52 UTC, Daniel Murphy wrote:
> How come you didn't do this as a proper fork/branch of dmd?

At first, I downloaded a zip of your fork just to take a
look at it - I had no intention of actually modifying it.

But, then I started to play around and never cleaned
stuff up.

/home/me/d/toys/yebblies-dmd-7723455/src

That's the name of the directory where it lives on
my computer :)


I pushed it up to github last night right before
making the ng post as a last-minute decision, figuring
github would make it easier for people to look at.


Redoing it as a proper fork won't be that hard; most the
changes are in the one microd.c file anyway. Maybe I
will next weekend.

> It's also not too hard to strip out the backend if you want to 
> redistribute
> the binary.  (stub out e2ir,s2ir,glue,toobj,iasm and remove the 
> backend specific stuff from main)

Cool. I took a quick look at doing that but just horribly
broke my build.

Isn't parts of ctfe implemented in glue.c though? I don't
see it obviously in there, but I thought I saw something
about that once.
February 27, 2012
Re: D to Javascript converter (a hacked up dmd)
On Monday, 27 February 2012 at 12:10:17 UTC, node wrote:
> Does this mean I can do node.js in D? :)

Probably. When I did my testing, I ran the code in
dmdscript and later, firefox. The javascript it outputs
is pretty basic so I imagine it will work in any
engine.

To access the library, you can define them as
extern(js) functions or classes, and then some
global objects. In my code, check out src/test/browser
for examples - that package is just bindings to the
browser's functions.

Those are translated to javascript almost exactly
as you write it in D, giving access to the outside
world pretty naturally.



Remember though two important facts:

1) there's no optimization here. The D compiler just
spits out the code tree in the new language. So, don't
expect speed bonuses.

2) Not all of D works. But, a decent chunk of it does
and I think it's ready for some serious playing already.
February 27, 2012
Re: D to Javascript converter (a hacked up dmd)
Il giorno lun, 27/02/2012 alle 16.09 +0100, Adam D. Ruppe ha scritto:

> On Monday, 27 February 2012 at 09:46:51 UTC, Andrea Fontana wrote:
> > Can you call custom (external, from 3rd party libs)
> > JS functions from there?
> 
> Yes, just make:
> 
> extern(js) void function_name_here(...);


Good!


> 
> and you can call it. For jQuery, you'd probably want
> to define an extern(js) class JQuery {} with all its method
> names. Since so many of them take strings, I think this would
> actually be somewhat easy.



About jquery: i mean what about a d function similar to  $() jquery
function for better elements handling (instead of getElementById() )
February 27, 2012
Re: D to Javascript converter (a hacked up dmd)
On Monday, 27 February 2012 at 15:39:50 UTC, Andrea Fontana wrote:
> About jquery: i mean what about a d function similar to  $() 
> jquery
> function for better elements handling (instead of 
> getElementById() )

Have you seen my dom library? :P

It's all server side but it is just awesome. Lots of
convenience functions, getting elements is easy, and
operating on them as a group is too, either through
a wrapper struct or just using foreach yourself.

I definitely want to port some of it to the javascript
output.

https://github.com/adamdruppe/misc-stuff-including-D-programming-language-web-stuff
the file is dom.d. It also depends on characterencodings.d.

The most jquery-like interface is Document's opIndex:

document[`#something .my-thing > p`].addClass("matched")
  .appendText("matched me!");


Though, I really think that querySelectorAll + foreach
wipes out jquery's element selection advantage.

querySelectorAll is in all browsers IE8 and up. Adding
foreach to javascript can be done with text macro
(see html.d in my github) or D->JS of course has foreach
too!


The zip of d->js actually breaks on foreach here, but
it was an easy fix. I'll push up the changes this next
weekend.


Anyway, here's how it looks:

foreach(element; document.querySelectorAll("#blah > p"))
    // do something to element
« First   ‹ Prev
1 2 3 4 5
Top | Discussion index | About this forum | D home