adamsol / Pyxell

Multi-paradigm programming language compiled to C++, written in Python.
MIT License
54 stars 6 forks source link

strange cpp generation #15

Closed bardo84 closed 1 year ago

bardo84 commented 1 year ago

Hi,

I tried the closure example: // closure.px func f() def x = 0

func g() def
    x += 1
    print x

g()
print x

f()

func f() def x = 0

func g() def
    x += 1
    print x

g()
print x

python pyxell.py closure.px then gives non-expected cpp file contents below (with exe result correct!) What goes wrong?

Exe compile works on company laptop after Python install via Windows app. Not working at home with pre-existing Python if that can make a difference. Error message is dll entry point for xxx_throw_bad_array_new_lengthv not found in dll xxx\closure.exe

File sizes: closure.px 109 closure.cpp: 588 closure.exe: 549864

`/ Generated by Pyxell 0.14.0. https://github.com/adamsol/Pyxell /

Float v1; Float v2; const String v3 = make_string("inf"s); Float v5; const String v9 = make_string("\n"s); Void f6();

Void f6() { Int v10; v10 = 0LL; std::function<Void()> f11 = [=, &f11]() mutable -> Void { v10 = (v10 + 1LL); write(toString(v10)); write(v9); }; f11(); write(toString(v10)); write(v9); }

int main() { v1 = 3.141592653589793; v2 = 2.718281828459045; Float v4 = [&](auto&& ...args) { return toFloat(v3, args...); }(); v5 = v4; f6(); return 0; }`

adamsol commented 1 year ago

Pyxell compiles the C++ code with an additional header: -include lib/base.hpp. That file is where most of the magic comes from. If you want to obtain a raw .cpp with all the includes resolved, use the -s flag (it's described in the readme).

P.S. Please use tripple backticks (```) to format the code snippets next time.

bardo84 commented 1 year ago

Getting weirder: After having changed the function names to be better searchable to outer / closure, I ran again. With -s flag, the output shows the full header, but NOT the expected code, without the flag the cpp contains the translation of an unknown source.

The same behavior I observed with the company laptop.

/*
Generated by Pyxell 0.14.0.
https://github.com/adamsol/Pyxell
*/

Float v1;
Float v2;
const String v3 = make_string("inf"s);
Float v5;
const String v9 = make_string("\n"s);
Void f6();

Void f6() {
    Int v10;
    v10 = 0LL;
    std::function<Void()> f11 = [=, &f11]() mutable -> Void {
        v10 = (v10 + 1LL);
        write(toString(v10));
        write(v9);
    };
    f11();
    write(toString(v10));
    write(v9);
}

int main() {
    v1 = 3.141592653589793;
    v2 = 2.718281828459045;
    Float v4 = [&](auto&& ...args) {
        return toFloat(v3, args...);
    }();
    v5 = v4;
    f6();
    return 0;
}
adamsol commented 1 year ago

I'm not sure what your expectations are, but the intermediate C++ code will not have your function or variable names. New names are generated automatically in the transpilation process. Everything is working correctly so far.

bardo84 commented 1 year ago

Sorry, I do not want to appear as a troll. I started with the closure example in my first post. It demos a nested function adding 1 to a variable initally 0.

Neither of the obtained cpp codes does contain that functionality. Either the long header file or the code defining the mathematical constants pi and euler.

I do not think that is any expected.

adamsol commented 1 year ago

This is the original function in Pyxell:

func f() def
    x = 0

    func g() def
        x += 1
        print x

    g()
    print x

This is the corresponding fragment in the generated C++:

Void f6() {
    Int v10;
    v10 = 0LL;
    std::function<Void()> f11 = [=, &f11]() mutable -> Void {
        v10 = (v10 + 1LL);
        write(toString(v10));
        write(v9);
    };
    f11();
    write(toString(v10));
    write(v9);
}

Function f is now f6. Variable x is v10. Function g is f11, written as lambda. Inside you can see the addition.

bardo84 commented 1 year ago

Sigh, ok. Where does the spurious code (pi, ..) come from?

Thx

adamsol commented 1 year ago

It's coming from lib/math.px. Surely this fragment could be not transpiled if the constants are not used, just like unused functions are not transpiled, but it's so short that I never felt the need to refactor this.