Karina is a statically typed, general-purpose high-level programming language emphasizing simplicity, interoperability, and concise notation. Karina is fully compatible with Java, allowing you to use existing libraries and frameworks seamlessly while providing a modern programming experience.
📢 Heads up! If you run into any issues, bugs, unexpected behavior, or have any questions while using this project, you’re encouraged to open an issue.
Your feedback and inquiries are greatly appreciated!
You need Java 21 or higher. You can use SDKMAN! to manage your Java versions.
To install the Karina compiler, download and run the installer. After the installation, you can run the compiler from the command line:
karina -v
Karina: v0.5
Java: OpenJDK 64-Bit Server VM 23.0.2
karina new hello-world
cd hello-world
karina run
Hello, World!
The official documentation is available at karina-lang.org.
You need Java 21 or higher. You can use SDKMAN! to manage your Java versions.
git clone https://github.com/Plixo2/KarinaC.git
cd KarinaC
IDE setup
The Compiler is a standard Gradle project, so you can use it with any IDE that supports Gradle.
You can run the compiler via the Gradle task run
or run the Main Class directly.
The --run
command line argument can be used to run the program after compilation.
Manual setup
Make sure your JAVA_HOME
is set to the correct version.
gradlew run
The project is configured to build the demo project in resources/src/
by default.
Custom Environment
You can set System environment flags via build.gradle or the vm arguments in your IDE.
application {
// ...
applicationDefaultJvmArgs = ['-Dkarina.source="resources/local/"'] // set the source folder to your local dev folder
}
karina.source="<src folder>"
Points to your local development folder. Defaults to resources/src/
karina.out="<build file>"
Specifies the output jar file. Defaults to resources/out/build.jar
karina.classes="<true/false>"
Enables/Disables the generation of .class files. Defaults to true
karina.flight="<debug file>"
Specifies the debug flight recorder file path. Defaults to resources/flight.txt
karina.console="<true/false>"
Enables/Disables the flight recorder output to the console. Defaults to true
karina.binary="<true/false>"
Enables/Disables the usage of a binary format for faster reading of precompiled classes.
Can improve the startup performance over 20 times, but untested and may cause issues.
Defaults to false
karina.logging="<none/basic/verbose/verbose_jvm>"
Enables/Disables the flight recorder output to the console. Defaults to none
.
Useful for debugging the compiler.
You can set custom log types in here.
Adding log types will enable logging for specific parts of the compiler. You can get a detailed view of the inner workings of the compiler by setting the correct logging types.
E.g. LogTypes.CHECK_TYPE
will get you a very detailed view of the type checking process.
Note
This is the primary way to debug the compiler. Be aware that this will generate a lot of output, when to many log types are enabled.
Another helpful tool is javap
. Use it to inspect the generated bytecode in detail.
javap -c -v -p main.class > main.txt
This will write the bytecode of the main.class
file to main.txt
, where it can be inspected.
You can rebuild the standard library with the
Gradle task KARINA-BASE
.
This will create a new karina_base.jar
file, located in src/main/resources
Delete the base.bin.gz file in the resources
folder to force the compiler to rebuild the binary format, when in use.
Internals
- Read the source code into memory
- Load the precompiled jar files (java.core and the karina.base) into a ClassModel
- Parser Stage
- Parse the loaded files into tokens, then into an AST via Antlr
- Convert the Antlr AST into a ClassModel and IR
- Import Stage
- Resolve all types via imports
- Attribution Stage
- Expression validation and type inference
- Lower Stage
- Construct new classes, bridge methods, rewrite loops, etc
- Generate Stage
- Generate bytecode
- And then finally write the bytecode to disk
Other important classes:
... and packages:
- jvm_loading
- Responsible for loading precompiled classes
- model_api
- The API for the ClassModel. Represents all loaded classes and their fields, methods, etc
- stages
- All stages of the compiler.