andrei-markeev / ts2c

Convert Javascript/TypeScript to C
ISC License
1.26k stars 95 forks source link

Nice project #1

Closed darrylryan closed 8 years ago

darrylryan commented 8 years ago

This is a cool idea... I'd love to see a fully working ts2c compiler.

Have you had a look at Haxe at all? The Haxe compiler can compile Haxe code to pretty stable C code and works well. The syntax for Haxe is somewhat similar to TypeScript too as they are both descended from Javascript.and use similar types and type annotations. I imagine it could be modified to work with Typescript a lot more easily than starting from scratch.

darrylryan commented 8 years ago

Actually there is already a project that transpiles TS to Haxe and then you can compile it to C... it sort of works but it needs some updating: jeremyfa/node-ts2hx

andrei-markeev commented 8 years ago

Hi,

Thanks for your feedback! Yes I tried Haxe but there are some problems with it (see section "Ts2hx and Haxe" below). Many people ask questions along same lines, so let's convert this answer into a little "wiki" if you don't mind - maybe I'll incorporate this into the main README.md later.

IoT and wearables: challenges and constraints

One of the main goals of this project is JavaScript/TypeScript on IoT devices and wearables.

I have in mind first of all ESP8266, Pebble watch, MSP430 family and Atmel AVR family (used in Arduino boards), which means microcontrollers and very small amounts of memory available.

So, RAM ranges literally from 512 bytes to 120KB, and ROM/Flash from 1KB to 4MB.

Why not some more powerful devices? The thing is, if you want to create a sustainable IoT device that works couple of years from battery, you have to use low-power microcontrollers and forget about things like Raspberry Pi.

But in this case, usually the only option available is to use C, which is very low-level, and many people don't know C (but everyone knows JavaScript!).

Let's take a simple example: consider I want to build a device that fetches some data from a sensor and periodically send it over WiFi to the cloud. It is probably a 2-hour deal in JavaScript, including tests, but it might easily be 2 days in C even for a person who knows C well.

I personally faced this problem when developing applications for Pebble watch. It's either Pebble.js which runs on phone and sends all the UI updates via Bluetooth, consuming battery like crazy, or you have C API and 24 KB maximum binary size. They're now spending huge amount of efforts trying to bring JavaScript interpreter on board, but it likely will be supported only on newer watches that have more memory and better CPU.

JavaScript on microcontrollers: current state

Many people understand that we need to bring JS to microcontrollers, and nowadays even big companies like Samsung create JavaScript interpreters tailored specifically for microcontrollers and IoT. However these projects even in best case have relatively big overhead.

For example:

Ts2hx and Haxe

I tried this combination a while ago. These are the problems I spotted:

  1. Haxe compiles to C++, not to C
  2. It has relatively huge runtime "shipped" with the application
  3. "Hello world" example produces 900KB executable
  4. Haxe more like compiles, not transpiles - so mostly unreadable output, e.g. this is what a simple method call looks like:
HX_STACK_LINE(18)
::String tmp1 = f->myMethod(HX_HCSTRING("test","\x52","\xc8","\xf9","\x4c"));
HX_STACK_VAR(tmp1,"tmp1");

TS2C project

Below are some stand-out features of TS2C:

  1. I'm adding only the stuff that developer actually uses in his code. No dead code is ever added during transpilation.
  2. I'm using only C89 features sticking to ANSI/ISO 9899-1990 International Standard as some microcontrollers don't support anything newer.
  3. I'm putting significant efforts into ensuring that output is as readable as possible and maps well to the original source.

I realize that some JavaScript language features are have to be left out, first of all certainly eval, but current impression is that it is possible to transpile most of the language.

Let's see :)

endel commented 7 years ago

Nice initiative. 👍

The idea is kinda crazy, but I'm really looking forward to seeing what can be achieved out of this. I often find myself thinking that it would be INSANE to be able to create a game using WebGL/TypeScript and "magically" transpile it down to C. Just hit the watch button. ;)

Cheers!

andrei-markeev commented 7 years ago

Thanks for the feedback @endel!

At this point the idea is to support only JS language core and built-in objects, and then if you need e.g. OpenGL, you can do something like import {glColor, ...} from 'GL/gl.h'; and call those functions you imported, and TS2C just generates #include <GL/gl.h> and transpiles the function calls.

So the code is not really intended to be fully universal, maybe only parts of it, like pure functions, etc.

This is in part because of idea to program microcontrollers - they all have very different APIs and often don't even fully support standard library as in C89 spec, so it's quite unrealistic to create any common interface for them.

Of course it should be possible to make some wrappers so that WebGL API transpiles to corresponding OpenGL API, but that would be a separate project :wink:

Anyway, even at this point it feels like :sparkles: magic :sparkles: - you create quite high-level JS code and boom - it transpiles into C-code and you start looking into it and you understand that you would not write much better yourself :stuck_out_tongue_winking_eye: