At some point, your code is going to grow in size. It's not a good idea to write all of it inside a single file. The Kal Preprocessor allows you to write your code in multiple files and then stitch them together into a single unit during execution.
You can write modular code that can be imported into multiple files or even multiple projects!
Use the
@
preprocessor directive to include an existing Kal file into your current file.
@
directive accepts both relative and absolute path to a file.
Let's look into an example for clarification
fn greet -> name {
stdout "Hello " name "!\n".
} greet.kal
This file can be included and used from another Kal file.
@greet.kal
:greet "World".
main.kal
The
.kal
extension can be omitted while including a file. Try using
@greet
instead of
@greet.kal
.
If a file is included multiple times, Kal will preprocess the first inclusion only. The subsequent inclusions will be ignored. The Kal interpreter does it to avoid re-declaration errors which commonly occur with multiple inclusions across multiple files.
@lib
@lib
stdout "Kal\n".
main.kal
The proprocessor directive does not end with a
.
Alternatively, you can include one or multiple files just before execution using the
-d
flag.
fn greet -> name {
stdout "Hello " name "\n".
} lib.kal
;; no file included
:greet "Earth".
main.kal
$ kal -d lib.kal main.kal
Multiple files can be provided by separating their paths with commas.
$ kal -d lib.kal,pkg.kal main.kal
The argument of
-d
flag must not contain spaces around the commas.
You can observe the output of the preprocessor using the
-p
flag.
The output can be saved to a file using the
-o
flag.
$ kal -p main.kal -o processedMain.kal
The best use of the preprocessor outside the internal scope of your project, is including existing projects into your own. The Kal Preprocessor allows you to build reusable packages and use them across multiple projects.
The preprocessor takes care of path resolution so that you don't have to spend time hard coding the correct relative or absolute path to the library.
But where do these packages live?
You are required to set a path to the directory where all the reusable packages live. During execution, Kal will use this path to find these packages.
The path, called the Kal Package Path, can be set using an environment variable
KAL_PKG
. This path can point to any valid directory. For convenience, let's create a directory called
pkg
in your home directory.
Now set
KAL_PKG
to point to this directory.
$ export KAL_PKG="$HOME/pkg"
You can add this line in your
.bashrc
file to skip setting
KAL_PKG
for every terminal session.
$ echo 'export KAL_PKG="$HOME/pkg"' >> ~/.bashrc
Follow an equivalent step for your shell if you are not using the Bash Shell.
Once done, verify by printing the
KAL_PKG
environment variable.
Let's start by creating a demo package called
greet
inside the directory that's set to
KAL_PKG
.
$ mkdir $KAL_PKG/greet
$ cd $KAL_PKG/greet
The entry point for every package is the
main.kal
file. The resolved package path points to this file.
Let's add our greet function inside this
main.kal
file.
fn greet -> name {
stdout "Hello " name "!\n".
} main.kal
This simple package is ready to be used. You can import this package inside any Kal project on your system using the
@pkg:
directive.
Create a Kal file somewhere else to test.
A Kal Package itself can constitute multiple files included using the
@
directive and other packages included using the
@pkg:
directive.
You can have directories inside Kal packages and each directory acting as a sub-package with its own
main.kal
.
Let's create a sub-package
greet/another
inside the
greet
package.
$ mkdir $KAL_PKG/greet/another
And add this code to another sub-package's
main.kal
.
fn sayHi -> name {
stdout "Hi " name "!\n".
} $KAL_PKG/greet/another/main.kal
Include the
another
sub-package and use
sayHi
.
@pkg:greet/another
:sayHi "Kal".
test.kal
Generally, you would want to use packages developed by other people.
KAL_PKG
is where you should put them to be globally accessible by any Kal program.
It's evident now how easy it is to set up a Kal package.
But that's not all! You can also set up CLI scripts that can be easily used anywhere.
CLI packages work in the same way except they use cli.kal as their entry point.
Let's enhance the greet package with a CLI script.
Create a new file:
$KAL_PKG/greet/cli.kal
.
This CLI script makes use of the existing greet function to demonstrate its functionality.
It can be invoked externally using the Kal interpreter.
Here:
-x
flag denotes script invocation. greet
is the CLI Package name. Friend
is a command-line argument.
A CLI Package can accept multiple command-line arguments.
Like Kal Packages, a CLI Package can also have CLI sub-packages.
A Kal Package can also be a CLI package and vice-versa.