Code Monkey home page Code Monkey logo

Comments (10)

CrazyPython avatar CrazyPython commented on August 22, 2024

It would be even better with C++14: it has closures that can automatically capture by reference and automatically type themselves

from ts2c.

CrazyPython avatar CrazyPython commented on August 22, 2024

If I wanted to implement closures via outputting a superset of C, which files of this project would I need to change?

from ts2c.

andrei-markeev avatar andrei-markeev commented on August 22, 2024

@CrazyPython there's an extended readme under "src" folder that describes file purposes and approaches used in implementation: https://github.com/andrei-markeev/ts2c/tree/master/src

@brunobasto started implementing anonymous functions, see his commit e22121b, it might help you to get some understanding of the scope.

Closures can be easily expressed with nested functions in C. Nesting functions isn't a part of standard, but it is supported by gcc so it might be a viable approach for basic implementation.

So for example you have this code:

var sum = 0;
var k = 2;
var add = function(n) { sum += n * k; }
add(30);
console.log(sum);

then the corresponding C code could look something like this:

int16_t sum, k;
int main() {
    int16_t add(int16_t n) {
        sum += n * k;
    }
    sum = 0;
    k = 2;
    add(30);
    printf("%d\n", sum);
}

But if we want to keep to the standard only (which I believe is important, because I believe there could be some toolchain implementations that don't support nested functions), then the easiest way would probably be to try to lift the variables into global scope, changing their name so that it doesn't conflict with any existing variables. This is not efficient memory-wise though, and memory consumption is quite important on embedded devices.

So most likely the best way to do it is to

  1. Detect which variables from current scope are used inside function expression
  2. Add those variables as parameters to the function (and if they're changed inside this function, then they should be passed by reference)

So the example above will probably compile to something like this:

int16_t add(int16_t n, int16_t* sum, int16_t k) {
    *sum += n * k;
}
int16_t sum, k;
int main() {
    sum = 0;
    k = 2;
    add(30, &sum, k);
    printf("%d\n", sum);
}

Obviously this approach is quite hard to implement and requires changes in types detection and memory management.

from ts2c.

zaoqi avatar zaoqi commented on August 22, 2024

@andrei-markeev

int16_t sum, k;
int main() {
    int16_t add(int16_t n) {
        sum += n * k;
    }
    add(30);
    printf("%d\n", sum);
}

It won't return a function correctly.

from ts2c.

andrei-markeev avatar andrei-markeev commented on August 22, 2024

well passing pointers to the function is a whole different story... but in fact I think it will work fine with nested functions, for example this code works fine:

int16_t sum, k;

void *test1() {
    int16_t add(int16_t n) {
        sum += n * k;
    }
    sum = 0;
    k = 2;
    add(30);
    printf("1. %d\n", sum);
    return &add;
}

int main() {
    int16_t (*add_func)(int) = test1();
    (*add_func)(5);
    printf("2. %d\n", sum);
}

corresponds to the following TS code:

var sum = 0;
var k = 2;
function test() {
    var add = function(n) { sum += n * k; }
    add(30);
    console.log("1.",sum);
    return add;
}
var add_func = test();
add_func(5);
console.log("2.",sum);

If we don't use nested functions however, then your idea with struct that contains function pointer and closure parameters becomes the valid one. So ultimately this is what we would have to do, yes.

from ts2c.

CrazyPython avatar CrazyPython commented on August 22, 2024

somewhat unrelated question: does ts2c support function pointers? (I have an existing application where a closure is created inside a class, and it assigns that closure inside the constructor.)

from ts2c.

andrei-markeev avatar andrei-markeev commented on August 22, 2024

not currently

in COVERAGE.md, this whole feature - closures + function pointers, is referred to as "function inside expressions"

from ts2c.

zaoqi avatar zaoqi commented on August 22, 2024

https://github.com/fabiosantoscode/js2cpp
https://github.com/fabiosantoscode/dumbjs

It turns

function foo(x) {
    x++
    return function () { return x }
}
console.log(foo(0)())

Into

var _flatten_0 = function (_closure) {
    return _closure.x
}
var foo = function (x) {
    var _closure_0 = {}
    _closure_0.x = x
    _closure_0.x++
    return BIND(_flatten_0, _closure_0)
}
var main = function () {
    console.log(foo(0)())
}

@andrei-markeev This may be more effective

from ts2c.

andrei-markeev avatar andrei-markeev commented on August 22, 2024

This is certainly an option, however, additional transpilation step will make output code less readable, and also increase overall transpilation time. So I would rather avoid it.

from ts2c.

andrei-markeev avatar andrei-markeev commented on August 22, 2024

Closures are now implemented, even though I expect that there might still be some edge cases where it does not work. Please let me know if you notice those!

from ts2c.

Related Issues (20)

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.