A system to amalgamate features from other languages into any code base you work on, and you can keep interacting with upstream in the original language.
For example, we could write a fizzbuzz.cpp like this:
int main()
for i<10
if i%3==0&&i%5==0
console.log("FizzBuzz");
else if i%3==0
console.log("Fizz");
else if i%5==0
console.log("Buzz");
else
console.log(i);
return 0And run:
ama -f cpp/cpp_indent -f auto_paren \
-f cpp/sane_for -f cpp/jsism.EnableConsole \
fizzbuzz.cppTo get:
#include <iostream>
int main() {
for (auto i = 0; i < 10; i++) {
if (i % 3 == 0 && i % 5 == 0) {
std::cout << ("FizzBuzz") << std::endl;
} else if (i % 3 == 0) {
std::cout << ("Fizz") << std::endl;
} else if (i % 5 == 0) {
std::cout << ("Buzz") << std::endl;
} else {
std::cout << (i) << std::endl;
}
}
return 0
}The project itself is a bigger example. You can build this repository with plain C++11, but it's actually developed in a different dialect. Try building it and run script/sync.js, then check the generated *.ama.cpp.
Key features:
- Works on anything The system can process any code as is. It will parse whatever it understands and let unrecognized syntax pass through unchanged.
- Bidirectional Many filters have an inverse version so you can translate upstream to your favorite dialect, develop there, then translate them back before committing.
- Low effort The core of Amalang is a very simple Javascript API. One can hook up a tiny DSL in hours then ditch it when there is no longer a need to keep up.
Works best on languages with a reasonable resemblance to C. That includes Python. See example/ to see more of Amalang in action.
mkdir -p build
cd build
cmake ..
make
cd ..
build/ama script/sync.jsmd build
cd build
cmake ..
cmake --build .
cd ..
build\ama script\sync.jsTo quickly try out the features, run ama --help to see a list of filters and use ama -f <filter> <file> to try one.
For bigger tasks, add some Javascript to your code under an @ama tag. See example/hello_world.cpp for a simple tutorial. See example/cmake for an automatic C++ build / run setup.
On an existing project, the recommended way is to set up a bidirectional synchronization script like script/sync.js. The script should update in-repository source files when you change the custom-dialect files, and synchronize back any pulled upstream change.
This process can be automated by the ama --init command. The command automatically creates script/sync.js with a complete list of customization features, which can be enabled by uncommenting. You can then ama --build to build the project with cmake, or add ama script/sync.js as a pre-build command to your build system.
Currently the auto-created sync.js only customizes C++ development.
Performance critical applications could use the internal C++ API directly and forgo the Javascript interpreter. For that purpose, you can link with libamal.so (amal.dll on Windows) and #include "<Amalang project directory>/src/script/jsapi.hpp" in your C++ project.
Alternatively, you can create a native module and call that from Javascript. Seeexample/native_module for an example. The native module still needs to link libamal.so and include jsapi.hpp.
We welcome pull requests. We need your help to build up an ecosystem.
See the document for contributors.
Amalang is powered by QuickJS.