New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement compiled mode for Perlang #406
Comments
It does, since Clang is natively a cross-compiler. But that unfortunately doesn't magically solve all related problems:
|
An interesting approach to this is the way Golang is handling this. A single CI job can generate artifacts for a number of platforms and architectures, with very little extra work for the project itself. I saw this myself in action recently: https://gitlab.com/fleeting-plugin-hetzner/fleeting-plugin-hetzner/-/blob/main/.gitlab/ci/build.gitlab-ci.yml?ref_type=heads. The end result can be seen in this pipeline: https://gitlab.com/fleeting-plugin-hetzner/fleeting-plugin-hetzner/-/pipelines/1188295744 Now, this doesn't help us immediately since we don't intend to use Go for this. 😂 But it's still interesting to see, and we should aim for something similar in Perlang: cross compilation should be easy. It's fine if it requires an automatic in-the-background network download of standard libraries though; I presume (without having looked at the details) that this is how the Go toolchain does it. |
This provides some of the groundwork for this, mentioned in #406: > Distribute the (compiled) stdlib along with snapshot builds The changes to the `Makefile` means that running `make install` will now install the `stdlib` into the expected location. The next step is to get the `stdlib` bundled with releases and release snapshots as well.
This provides some of the groundwork for this, mentioned in #406: > Distribute the (compiled) stdlib along with snapshot builds The changes to the `Makefile` means that running `make install` will now install the `stdlib` into the expected location. The next step is to get the `stdlib` bundled with releases and release snapshots as well.
This provides some of the groundwork for this, mentioned in #406: > Distribute the (compiled) stdlib along with snapshot builds The changes to the `Makefile` means that running `make install` will now install the `stdlib` into the expected location. The next step is to get the `stdlib` bundled with releases and release snapshots as well.
This provides some of the groundwork for this, mentioned in #406: > Distribute the (compiled) stdlib along with snapshot builds The changes to the `Makefile` means that running `make install` will now install the `stdlib` into the expected location. The next step is to get the `stdlib` bundled with releases and release snapshots as well.
The required groundwork for including experimental compilation in release/snapshot binaries has now been done. 🎉 Moving this to the 0.5.0 milestone now, and intending to publish a 0.4.0 release very soon. |
As discussed in #406, the REPL will go away for some time, until we can (at some point) reimplement it on top of LLVM. At that point, the REPL will be _dynamically emitting native code_, i.e. still not require a JIT interpreter of any form. Based on some experiments I've done with LLVM, this should be doable. The `-e "<code-to-be-executed>"` will also be removed for now, but will take that as a separate commit.
As discussed in #406, the REPL will go away for some time, until we can (at some point) reimplement it on top of LLVM. At that point, the REPL will be _dynamically emitting native code_, i.e. still not require a JIT interpreter of any form. Based on some experiments I've done with LLVM, this should be doable. The `-e "<code-to-be-executed>"` will also be removed for now, but will take that as a separate commit.
This has been an oversight while working on the experimental Perlang compiler (#406). The bug was discovered when implementing the changes in #463; when we started running one of those tests, no error was emitted even though the code was redefining a top-level function. It turned out that the compiler would silently overwrite a function if you defined it twice.
This has been an oversight while working on the experimental Perlang compiler (#406). The bug was discovered when implementing the changes in #463; when we started running one of those tests, no error was emitted even though the code was redefining a top-level function. It turned out that the compiler would silently overwrite a function if you defined it twice.
This has been an oversight while working on the experimental Perlang compiler (#406). The bug was discovered when implementing the changes in #463; when we started running one of those tests, no error was emitted even though the code was redefining a top-level function. It turned out that the compiler would silently overwrite a function if you defined it twice.
This is the biggest change for a while. Because #406 is moving along nicely, we are now ready to: * Flip the switch, i.e. _make compiled mode the default_ for Perlang. * Remove the PerlangInterpreter class in its entirety. This may be reimplemented in one form or another, once we have the LLVM-emitting backend in place, but not as a tree-walking interpreter. This probably means we'll drop Windows (and perhaps macOS) support for a while. Please don't despair; this is not intended to be permanent. While we depend on a specific Clang version for compiling Perlang code, it simply gets easier to not have to support too many platforms. Once we have started emitting C++ code from Perlang, in an idempotent way (being able to disable all timestamping etc in the file header), we could see how hard it would be to get this Perlang-to-C++-transpiled code compiling on macOS and Windows too.
This is the biggest change for a while. Because #406 is moving along nicely, we are now ready to: * Flip the switch, i.e. _make compiled mode the default_ for Perlang. * Remove the PerlangInterpreter class in its entirety. This may be reimplemented in one form or another, once we have the LLVM-emitting backend in place, but not as a tree-walking interpreter. This probably means we'll drop Windows (and perhaps macOS) support for a while. Please don't despair; this is not intended to be permanent. While we depend on a specific Clang version for compiling Perlang code, it simply gets easier to not have to support too many platforms. Once we have started emitting C++ code from Perlang, in an idempotent way (being able to disable all timestamping etc in the file header), we could see how hard it would be to get this Perlang-to-C++-transpiled code compiling on macOS and Windows too.
This is the biggest change for a while. Because #406 is moving along nicely, we are now ready to: * Flip the switch, i.e. _make compiled mode the default_ for Perlang. * Remove the PerlangInterpreter class in its entirety. This may be reimplemented in one form or another, once we have the LLVM-emitting backend in place, but not as a tree-walking interpreter. This probably means we'll drop Windows (and perhaps macOS) support for a while. Please don't despair; this is not intended to be permanent. While we depend on a specific Clang version for compiling Perlang code, it simply gets easier to not have to support too many platforms. Once we have started emitting C++ code from Perlang, in an idempotent way (being able to disable all timestamping etc in the file header), we could see how hard it would be to get this Perlang-to-C++-transpiled code compiling on macOS and Windows too.
This is the biggest change for a while. Because #406 is moving along nicely, we are now ready to: * Flip the switch, i.e. _make compiled mode the default_ for Perlang. * Remove the PerlangInterpreter class in its entirety. This may be reimplemented in one form or another, once we have the LLVM-emitting backend in place, but not as a tree-walking interpreter. This probably means we'll drop Windows (and perhaps macOS) support for a while. Please don't despair; this is not intended to be permanent. While we depend on a specific Clang version for compiling Perlang code, it simply gets easier to not have to support too many platforms. Once we have started emitting C++ code from Perlang, in an idempotent way (being able to disable all timestamping etc in the file header), we could see how hard it would be to get this Perlang-to-C++-transpiled code compiling on macOS and Windows too.
This is the biggest change for a while. Because #406 is moving along nicely, we are now ready to: * Flip the switch, i.e. _make compiled mode the default_ for Perlang. * Remove the PerlangInterpreter class in its entirety. This may be reimplemented in one form or another, once we have the LLVM-emitting backend in place, but not as a tree-walking interpreter. This probably means we'll drop Windows (and perhaps macOS) support for a while. Please don't despair; this is not intended to be permanent. While we depend on a specific Clang version for compiling Perlang code, it simply gets easier to not have to support too many platforms. Once we have started emitting C++ code from Perlang, in an idempotent way (being able to disable all timestamping etc in the file header), we could see how hard it would be to get this Perlang-to-C++-transpiled code compiling on macOS and Windows too.
#465) This is the biggest change for a while. Because #406 is moving along nicely, we are now ready to: * Flip the switch, i.e. _make compiled mode the default_ for Perlang. * Remove the PerlangInterpreter class in its entirety. This may be reimplemented in one form or another, once we have the LLVM-emitting backend in place, but not as a tree-walking interpreter. This probably means we'll drop Windows (and perhaps macOS) support for a while. Please don't despair; this is not intended to be permanent. While we depend on a specific Clang version for compiling Perlang code, it simply gets easier to not have to support too many platforms. Once we have started emitting C++ code from Perlang, in an idempotent way (being able to disable all timestamping etc in the file header), we could see how hard it would be to get this Perlang-to-C++-transpiled code compiling on macOS and Windows too.
This is the main feature being worked on in the current 0.5.0 milestone, but it won't be finished when we carve out the 0.5.0 release. Moving to 0.6.0. |
In #396, I described the recent events leading up to me trying out what LLVM can do for us, in terms of making it possible to run Perlang programs completely independent of the .NET platform.
After that comment was written, and some discussions I had with an old friend of mine (@diwic - thanks a lot to you! 🙏), I started hacking on this and doing a little experiment: How hard would it be to write a compiler for Perlang, which emits C++ code, compiles this code, and then runs the end result? This is obviously not the "final solution" in any way and it is admittedly a bit clumsy. Still, if it was good enough for Bjarne Strousrup, it ought to be good enough for me as well. (Naturally, Strousrup's preprocessor and later Cfront compiler didn't emit C++, but you get the picture.)
I'm setting the milestone for this to 0.4.0, but naturally, given the sheer size of this task, the compiler will in no way be complete in 0.4.0. But it'll probably work to the point where I feel comfortable about pushing it out to the public.
Rough steps
BigInt
: Add support for BigInt in compiled mode #415stdlib
along with snapshot builds. This involves a bit of complexity, since native C++ code has historically only been able to compile on the same platform as the CI job is running on. We'll need to investigate ifclang
makes this easier for us.amd64
-only at this point (in compiled mode). In other words, we'll provide a Linuxamd64
binary of thestdlib
for now and emit an error message on other platforms stating that experimental compilation is not yet supported.stdlib
in Linux-based.tar.gz
snapshots #445, with the above limitation (Linux-only).PerlangCompiler
uses thestdlib
artifacts (.so
/.a
files and.h
/.hpp
header files), when being executed from a snapshot build.$PERLANG_ROOT
is set.$PERLANG_ROOT
is still used when running Perlang from source, so let's leave this as-is for now.I am currently (2023-11-03) leaning towards dropping (parts of) the REPL soon, perhaps in the 0.5.0 or 0.6.0 release. This will make things simpler and free us from having to keeping it working all the time, since it won't be working in compiled anyway (for quite a long time, realistically speaking). Once the Perlang compiler is mature enough to be able to interface with LLVM to generate machine code for an arbitrary Perlang expression tree, we can reimplement the REPL on top of this.
Suggested approach: make some "glue tooling" for interfacing between Perlang and C++ (and perhaps between Perlang and C# in the intermediate stage), so that we can expose the Perlang AST types to a little C++ helper library. The helper library will then consume the LLVM headers and emit machine code for the Perlang AST.
-e
option dropped in (consoleapp) Remove REPL code #446 and (consoleapp) Remove-e <script>
option #447.ASCIIString
toString
(https://github.com/perlang-org/perlang/pull/451/files#r1548516040)ASCIIString
instd::shared_ptr<T>
#453, which should be "good enough" for now. As the compiler matures (and we can eventually move away from relying too much on C++), we can rework this to use more stack-basedASCIIString
instances where possible, to reduce the number of heap allocations.AsciiString
andint
: (many) Support string+integer concatenation in compiled mode #472, (many) Support more types in string+int and int+string concatenation #473AsciiString
andAsciiString
: (many) Support string concatenation in compiled mode #470cargo
)perlang .
orperlang <some-directory>
approach, i.e. compile all files in a given directory; this seems to be similar to how https://vlang.io/ does it. The easy way here would be to just emit a single C++ file; if we do it like this, I think we can postpone the "build system" question for (perhaps much) later..so
(subsequently.dll
on Windows) files.The text was updated successfully, but these errors were encountered: