Skip to content
A compiled implementation of Javascript, targetting C
Branch: master
Clone or download
Latest commit 55e7fe5 Apr 19, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
.github explode all the things Feb 18, 2019
actions/ci
c-notes
notes finishing implementation of dynamic runtime Feb 18, 2019
out
public npmi Apr 19, 2019
runtime cleanup warnings Apr 19, 2019
scripts rename Apr 19, 2019
sketches
specs Add specs - offline goodness Mar 2, 2019
src update expressions Apr 19, 2019
test update expressions Apr 19, 2019
.dockerignore explode all the things Feb 18, 2019
.editorconfig switch to editorconfig Jul 28, 2018
.gitignore build arte Mar 16, 2019
Makefile default target Apr 19, 2019
NOTES.md
README.md Use vendored libuv Mar 10, 2019
TODO.md
compile-and-run Fix up compiler tests Feb 18, 2019
compile-js make runtime a dynamic library - speed up compile times Feb 18, 2019
compile-js-lib finishing implementation of dynamic runtime Feb 18, 2019
compile-js-to-c More useful Feb 18, 2019
compile-run-c
exploding-deref.bc lots of interesting things - my gc-sketch is failing cos I realised I… Jul 25, 2018
index.html fw Apr 19, 2019
lib.sh Use vendored libuv Mar 10, 2019
link-c
package-lock.json deps up Feb 18, 2019
package.json fix function record GC Feb 18, 2019
server.Dockerfile work on demo site Mar 11, 2019
tsconfig.json Working on environment representation Jul 11, 2018

README.md

JS to C

A compiled implementation of ES5, targetting C.

Read my notes for a rough dev notes, or read more polished write ups on my blog.

Next thing to do - see TODO.md.

Example

The following JS

function fact(n) {
    return n < 3 ? n : n * fact(n - 1);
}
console.log(fact(5));

outputs as a C program. For instance the compiled fact function looks like:

// ...
JsValue *fact_1(Env *env) {
  JsValue *return_2;
  JsValue *left_5 = (envGet(env, interned_7) /* n */);
  JsValue *right_6 = (jsValueCreateNumber(3));
  JsValue *conditionalPredicate_4 = (LTOperator(left_5, right_6));
  JsValue *conditionalValue_3;
  if (isTruthy(conditionalPredicate_4)) {
    return_2 = (envGet(env, interned_7) /* n */);
  } else {
    JsValue *left_8 = (envGet(env, interned_7) /* n */);
    JsValue *callee_10 = (envGet(env, interned_11) /* fact */);
    JsValue *left_12 = (envGet(env, interned_7) /* n */);
    JsValue *right_13 = (jsValueCreateNumber(1));
    JsValue *call10Arg_0 = (subtractOperator(left_12, right_13));
    JsValue *args_10[] = {call10Arg_0};
    JsValue *right_9 = (functionRunWithArguments(callee_10, env, args_10, 1));
    return_2 = (multiplyOperator(left_8, right_9));
  }
  return return_2;
}
// ...

Guide

./runtime
    the C implementation of the language runtime
./src
    the TypeScript compiler

Testing

Functional

Run npm test to run/update tests. ./scripts/test-by-name $name to run a single test.

Failed tests provide a command to compile and run the C program with the debugger.

Unit

The runtime has unit tests - use the make test in ./runtime to run them, and ./runtime/scripts/compile-test-loop test-file-basename.

Runtime

Runtime C libraries for js-to-c.

Installing

Dependencies:

  • clang
  • Make
  • CMake (for libuv)

I'm trying to limit my focus to learning about compilation, so I've made no attempt to make this cross platform. It shouldn't be too tricky, libuv is the big dependency and it's cross platform.

make install

Developing

Builds and runs all tests:

make test

Libraries

See lib - currently just

  • debug.h
    • debug macros

Dynamic libraries

The runtime is built into a dynamic library to avoid recompiling. There's also a prelude, which allows langauge features to be implemented in JS that's pre-compiled to C.

Runtime

Files prefixed _ are private to the runtime and should not be relied on.

## Potential issues

grep for HMM to see potential problems I'm leaving alone for now as they seem tricky to solve properly/I'm unsure they'll be a problem in practice. Good place to look if weird bugs occur.

You can’t perform that action at this time.