Giter VIP home page Giter VIP logo

lljs's Introduction

LLJS

LLJS is a typed dialect of JavaScript that offers a C-like type system with manual memory management. It compiles to JavaScript and lets you write memory-efficient and GC pause-free code less painfully, in short, LLJS is the bastard child of JavaScript and C. LLJS is early research prototype work, so don't expect anything rock solid just yet. The research goal here is to explore low-level statically typed features in a high-level dynamically typed language. Think of it as inline assembly in C, or the unsafe keyword in C#. It's not pretty, but it gets the job done.

Usage

For users of node.js, bin/ljc is provided.

For users of SpiderMonkey js shell, the compiler can be invoked with:

$ js ljc.js

in the src/ directory.

Memcheck

If you would like to compile with support for memory checking (detects leaks, accesses of unallocated and undefined memory locations, and double frees) then compile with the -m flag:

$ bin/ljc -m -o myscript.js myscript.ljs

And add the following code to the end of your program run to report any memory errors:

let m = require('memory');
// for SpiderMonkey do
// let m = load('memory.js')
console.log(m.memcheck.report());

The memory checker uses Proxies so if you use node.js you need to enable it with:

$ node --harmony-proxies myscript.js

Testing

To run the tests install the Mocha module then run:

export NODE_PATH=src/
mocha --compilers ljs:ljc

from the root LLJS directory.

lljs's People

Contributors

disnet avatar jankeromnes avatar mbebenita avatar rinon avatar sophiebits avatar syg avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

lljs's Issues

casting requires extra set of parentheses

It's annoying to have to write:

(int)(num)
(int)(getNum())

etc, every time I want to cast something. I should be able to just do:

(int)num
(int)getNum()

but it seems to require the explicit parentheses.

Downcasting of Signed Types Not Working

If you try to downcast any integer to a lower byte signed integer the output is wrong.

trace("i16: " + (i16)(65535));

Leads to "Unknown expression type: undefined". It works as long the casted integer is in range of the int16.

A solution could be to write the unsigned version of the target integer into a ArrayBuffer using the according view, then read it again from the target type view.

var castBuffer = new ArrayBuffer(2);
var i16 = new Int16Array(castBuffer);
var u16 = new Uint16Array(castBuffer);
var i8 = new Int8Array(castBuffer);
var u8 = new Uint8Array(castBuffer);

exports.toInt16 = function (i) { u16[0] = i & 65535; return i16[0]; }
exports.toInt8 = function (i) { u8[0] = i & 255; return i8[0]; }

Downcasting float64 to float32 could be hard. I don't have a solution for this yet.

Compiling LLJS to C

Given that LLJS is nearly C, would be great to have C as a potential compile target (using stdlib & malloc instead of ArrayBuffer). Or even Objective C.

Having one language to target the web as well as native would just be plain awesome. Plus, adding language features such as Classes, forEach loops etc (ES6?) would be a lot easier with LLJS. There's no reason it needs to be as plain as C.

memory.js and memcheck.js

Can the generated memory.js and memcheck.js code be safely used in other js projects or is it tightly integrated with LLJS

Harmony support

Any chance of this project using the esprima parser version with javascript harmony support? Willing to make an attempt at this if it is not planned in the future.

suggestions for performance?

Hey guys,

I finished hacking a simple benchmark together. It's pretty ugly code, but I think it's good enough to work with.

It's a simple 2d graphics renderer that does a little collision detection. It basically loads some images, adds a bunch of entities to the scene, and starts a loop which continually checks for collisions, updates entities, and renders them.

For collision detection, it divides the screen into a grid and caches entities that overlap each grid cell. That way, it's fast to lookup which entities are near the one you're checking. So the collision detection loops through all objects, fetches the ones around each one, and does a 2d axis-aligned box collision check. If the "player" entity collides with any other entity, it removes the other entity from the scene.

I wrote the first version in LLJS, and then converted it into normal javascript. I bumped the number of entities in the scene to 3000 to stress test it. You can run each one here:

The LLJS version was compiled this way: ./LLJS/bin/ljc -o main.js main.ljs

The results:

  • With LLJS: ~320ms / frame
  • Normal JS: ~180ms / frame

So right now normal javascript is about 1.7x faster. Is that just a bad usage for lljs? If so, I'm surprised because I thought games were one of the selling points for this kind of thing. Can you guys check out my code and suggest changes that might make LLJS shine? Is there some other way I should he handling the data & collision detection to make it faster on LLJS?

Edit: I'm using Firefox 16.0.2 on OS X.

output to stdout

I don't see a strait forward way to output the result on the console instead of creating a new file.

With that I could straigt forward pipe the compiled javascript to uglify or whatnot.

ljc demo.lljs | uglifyjs > out.js 

lljs.org hijacked

It seems that the lljs.org domain has been hijacked, and is now a blog. Archive.org shows that it was still intact as of May 22nd of this year.

string types

It looks like a string type does not exist. Is it supposed to be byte*?

I'm trying to create a struct with a string type member:

struct Foo {
    byte* bar;
}

let Foo* f = new Foo();
f->bar = 'Hello';

I get "incompatible types, assigning dyn to u8*, which seems to me that string types are not supported and thus can't be used with structs. Is that true?

Support for ES6-style Classes

Would be nice to go beyond plain C idioms and add support for classes (ES6 style). These can be easily represented as structs under the hood.

A real class system with inheritance and mixins would go a long way to making this far better alternative to C + emscripten. I'd have no issue with writing large web apps in LLJS that way.

Setting array sizes from constants throws

Defining an array size from a constant or variable throws a messageFormat is undefined error:

const SIZE = 100;

let int arr[SIZE];
struct ArrayStruct {
  int arr[SIZE];
};

Both declarations throws the error.

Arrays allocated on the heap are not affected though.

React native casting error

I am getting an error after writing this code that the type cast expression is expected to be wrapped with parenthesis.
Here is my code:

onPressedButton = channelId =>
{

this.setState(this.state.channelId: channelId) // here i am getting the error

Implement bit fields

The next big thing that LLJS Structs currently lack compared to Cโˆ•C++ are bit fields. A syntax similar to this snippet would be great:

struct BitFieldStruct {
  int x: 1;
  int y: 1;
  int padding: 6;
};

The static analysis should make sure that the sum of all consecutive bitfields is a multiple of 8.
Then at runtime, set values would be clamped between 0 and Math.pow(2, size_of_bitfield).
The storage on the stack would be super efficient as retrieving a value is as easy as doing stack[index] >> bit_field_offset & size_of_bit_field.

I'm not sure though how to handle endianess.

Do you think that it is something that could be implemented?

passing custom structs around on the stack

I hope it's helpful that I'm filing these bugs; let me know if I should hold off for some reason.

There seems to be a few bugs with the stack. I created a struct called Vec2d and pass it around on the stack. Here's the program:

extern console;

struct Vec2d {
    int x, y;
}

function Vec2d add(Vec2d vec1, Vec2d vec2) {
    let Vec2d res;
    res.x = vec1.x + vec2.x;
    res.y = vec1.y + vec2.y;

    console.log(res.x, res.y);

    return res;
}

let Vec2d vec1;
vec1.x = 10;
vec1.y = 11;

let Vec2d vec2;
vec2.x = 20;
vec2.y = 21;

add(vec1, vec2);

Now that I think of it, none of the examples show passing structs around on the stack like that. Is that supported? The output is 30 0 when it should be 30 32.

Additionally, if I tried to assign the result of add, I get an error:

let Vec2d vec3 = add(vec1, vec2);

james:~/projects/game-off-2012(master)% make
./LLJS/bin/ljc -o main.js main2.ljs

/Users/james/projects/game-off-2012/LLJS/src/ljc.js:231
      throw e;
            ^
TypeError: Cannot read property 'ty' of undefined

Support for function types

The "Functions" example on lljs.org shows that function copying leaks into the dynamic type system:

let unsafeQuux = quux;

Just to see what happens, let i32 unsafeQuux = quux; results in the error:

incompatible types: assigning dyn(i32, dyn, i32) to i32

But dyn(i32, dyn, i32) is not (apparently) a valid type declaration. The point of this issue is to suggest that functional types declarations be implemented in that format.

I didn't find any discussion on this yet. Is it technically unfeasible with the type system implementation? Maybe just challenging? Has any thought been put to it already? And is anyone already working on it?

Support for memory allocator with GC

The LLJS memory allocator does not support automatic garbage collection currently. Would be nice to be able to switch GC on/off when compiling. If the GC is turned on, the memory allocator would fall back to not using an ArrayBuffer at all - thus running like regular js. Alternatively could even try adding a Boehm GC to LLJS :)

preprocessor

Is there any plan to support some kind of c-style include statement or preprocessors in general?

It would make this project very interesting for me.

default value of memory/pointers

Do I need to be careful to set pointers to null when I'm instancing custom struct types?

For example:

struct Foo {
  int *bar;
}

let *foo = new Foo();
console.log(foo->bar);

if(foo->bar) {
  // ...
}

Can I assume that bar is null, or could the value from memory be something random like C? I'm assuming it's the latter, but so far it's always been 0/null.

lljs.org is down

lljs.org is down as for Wed May 14 2014 08:50:07 GMT+0200, the website is down.

add support for node.js

It would be cool to be able to use this transpiler from commandline within nodejs (and why not.. spidermonkey? :)

Create arrays as structs members

I'd like to know if you plan on adding the possibility to create arrays as struct members.

AFAIK, it is not possible. Such code won't compile:

struct Point {
  int x, y;
};
struct Octogon {
  Point points[8];
};

Though I can define arrays like this:

let points = new Point[8];

It doesn't seem to be possible to do in structs.

Since there's no way to easily comment on this awesome project... The use of the "let" word seems redundant and a bit more like BASH than C.

Since there's no way to easily comment on this awesome project... The use of the "let" word seems redundant and a bit more like BASH than C. So in other words, if your parser could work without let, it'd probably be the perfect project that I've ever seen. My primary issue with js is that it's not C like enough for me,

So to summarise the "let" keyword sounds like an odd thing to use instead of just using the types themselves. Other than that, it seems to be shaping up extremely nicely. Once it's in a bit more stable state, I'll likely start writing all of my javascript with it rather than writing pure javascript.

bug in order of operations parsing C casts

I'm trying to port some C code to LLJS using a simple string replacement script. In the C code, I have some logic like:

u8 i = (u8) ~(u8) (1 << 3);

but when attempting to compile that with LLJS compiler, I get an error:

t.js:4:18: error: Unexpected token ~
    let u8 i = (u8) ~(u8) (1 << 3);
                    ^

Seems it doesn't like the ~ char.

importing types

If I have split my code up into a few files, and one of them contains struct definitions, how do I use them in a different file? I can't seem to get the compiler to import them at compile-time somehow.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.