D to Javascript converter (a hacked up dmd)

Adam D. Ruppe destructionator at gmail.com
Sun Feb 26 19:51:21 PST 2012


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.



More information about the Digitalmars-d-announce mailing list