This document provides comprehensive documentation for the Pava language. Pava is a dynamically typed, interpreted language with a syntax inspired by modern scripting languages. It supports variables, user-defined functions (with and without default arguments), control flow statements, arrays (lists), modules, built-in (native) functions, and more. This documentation covers syntax tutorials, built-in functions with examples, array operations, module usage, and complete code examples.
maven and jdk17-openjdk (Install from your package manager)
⚒️ Build package with maven:
git clone https://github.com/raz0229/pavalang.git
cd pavalang
chmod +x ./build.sh
sudo ./build.sh
💫 Run and Test pava from working directory:
./pava source.pava
From PKGBUILD on Arch Linux in working directory:
makepkg -si
or simply, install from AUR using your favorite AUR helper:
yaourt -S pavalang
Other distros:
sudo snap install pavalang --beta
- 📖 Introduction
- 🔤 Lexical Structure
- 📝 Syntax Overview
- 📦 Variables
- 🔧 Functions
- 👤 User-Defined Functions
- ⚙️ Default Function Arguments
- 🔙 Return Statements
- 🎛️ Control Flow
- 🔍 If Statements
- 🔄 While Statements
- 🔁 For Statements
- 🔗 Logical Operators
- 🧱 Blocks and Scoping
- 📊 Arrays (Lists)
- 📄 Array Literals
- 🔢 Index Access and Assignment
- 📏 Fixed-Size Array Declarations
- 📂 Modules
- 🛠️ Built-In Functions
- 📜 Code Examples
⚠️ Error Handling- 🎉 Conclusion
Pavalang is a lightweight tree-walking interpreter designed to teach language implementation techniques. It supports dynamic typing, first-class functions, closures, and a set of built-in functionalities that allow you to build applications quickly. Pava is written entirely in Java and is syntatically similar to Python hence, Pava. This documentation covers the complete syntax and built-in functionalities of Pava.
Use // for single-line comments.
Pava tokens include:
-
Parentheses
(,) -
Braces
{,} -
Brackets
[,] -
Commas and semicolons
-
Operators (
+,-,*,/, etc.) -
Identifiers
-
Strings (enclosed in double quotes)
-
Numbers
-
Keywords (
let,fun,if,while,for,return,pao,kaddo, etc.)
A file starting with #! (e.g., #!/bin/pava) is ignored by the lexer.
Variables are declared using the let keyword.
Example:
let a = 10;
let name = "Alice";
let flag = true;
Variables can be reassigned using the = operator.
Example:
a = 20;
print "a\nb\tc \\n";
Outputs:
a
b c \n
Syntax:
Functions are declared with the fun keyword, followed by the function name, a parameter list in parentheses, and a block for the body.
Example without Arguments:
fun greet() {
print "Hello!";
}
greet();
Example with Arguments:
fun add(x, y) {
return x + y;
}
print add(3, 5); // Output: 8
Syntax:
Parameters can have default values. Default parameters must be the rightmost parameters.
Valid Example:
fun foo(x, y = 20) {
print x + y;
}
foo(5); // Uses default: Output: 25
foo(5, 30); // Output: 35
Invalid Example:
fun bar(x = 10, y) {} // Error: Parameters with default values must be trailing.
Syntax:
Use the return keyword to return a value from a function.
Examples:
fun foo() { return 10; }
print foo(); // Output: 10
fun f() {
if (false) return "no"; else return "ok";
}
print f(); // Output: ok
fun f() {
return;
print "bad"; // Unreachable code.
}
print f(); // Output: nil
The if statement tests a condition, executing the "then" branch if true; an optional else branch is available.
Example:
if (true) print "good";
if (true) {
print "block body";
}
The while statement repeatedly executes its body while the condition remains truth ( No, Pava doesn't support ++).
Example:
let i = 0;
while (i < 3) {
print i;
i = i + 1;
}
// Output: 0, 1, 2 (each on a new line)
For statements are desugared into a block that includes an initializer, condition, and increment clause. For is just syntatic sugar with underlying while loop.
Examples:
// For with missing increment:
for (let baz = 0; baz < 3;) print baz = baz + 1;
// Output: 1, 2, 3
// Full for statement:
for (let world = 0; world < 3; world = world + 1) {
print world;
}
// Output: 0, 1, 2
Operators:
-
Logical AND (
and) returns the first falsy value (or the last value if all are truthy). -
Logical OR (
or) returns the first truthy value.
Examples:
print false and "ok"; // Output: false
if ((true and "hello")) print "hello"; // Output: hello
if ((97 and "baz")) print "baz"; // Output: baz
if ((false or "baz")) print "baz"; // Output: baz
if ((true or "world")) print "world"; // Output: true (short-circuits)
Blocks are enclosed in { } and group statements. They also create a new local scope.
Examples:
{
let foo = "before";
print foo;
}
{
let foo = "after";
print foo;
}
// Output: before, then after
{
let hello = 88;
{
let foo = 88;
print foo;
}
print hello;
}
// Output: 88, then 88
An array is a comma-separated list of values enclosed in square brackets.
Examples:
let arr = [1,2,3,4,5];
print arr[0]; // Output: 1
print arr[3]; // Output: 4
print length(arr); // Output: 5
let li = ["abc", 123.23, true];
print li[0]; // Output: abc
print li[1]; // Output: 123.23
print li[2]; // Output: true
Use square brackets to access and assign to array elements.
Examples:
let li = [1,2,3,4,5];
print li[0]; // Output: 1
li[0] = 69;
print li[0]; // Output: 69
let str = "ABCDEF";
print str; // Output: ABCDEF
str[0] = "Z";
str[1] = "Y";
print str; // Output: ZYCDEF
Declaring a variable with square brackets after its name creates an array of fixed size with all elements initialized to nil.
Example:
let arr[3];
arr[0] = 71;
arr[1] = 29;
arr[2] = 12;
print arr[0]; // Output: 71
print arr[1]; // Output: 29
print arr[2]; // Output: 12
Accessing an index out of range results in a runtime error.
Modules are separate Pava files that can contain function definitions and variables. A module file ends with an export statement, and modules are imported using the pao keyword (Pun intended).
Module File Example (math.Pava):
fun addTwo(x, y) {
return x + y;
}
fun multiplyTwo(x, y) {
return x * y;
}
kaddo Math;
Importing a Module (main.Pava):
pao "math"; // Extension (.pava) is optional; system will search /usr/share/pava first.
print Math.addTwo(3,5); // Output: 8
print Math.multiplyTwo(2,7); // Output: 14
Module Import Behavior:
-
The interpreter first searches for the module in
/usr/share/pava -
If not found, it searches in the working directory
-
The
paostatement ignores the extension if not provided -
The module file must end with a
kaddostatement -
When imported, the module's exported namespace is accessible via dot notation
Pava provides a set of built-in (native) functions that are bound in the global environment and can be called like any other function.
Description: Returns the current time in milliseconds since midnight January 1, 1970 UTC (UNIX Timestamp).
Usage:
print clock();
print clock() + 75;
Example Output:
1731411035
1731411110
Description: Returns the string "Akhtar Lava" :)
Usage:
print pava();
Example Output:
Akhtar Lava
Description: Returns a string representing the type of its argument. Possible types include: NUMBER, STRING, BOOLEAN, FUNCTION, NIL, OBJECT.
Usage:
print typeof(123); // Output: NUMBER
let x = "Hello, World!";
print typeof(x); // Output: STRING
Description: Prompts the user for input. If a prompt string is provided, it is displayed; otherwise, no prompt is shown. Returns the input as a string.
Usage:
let x = input("Enter a number: ");
print "The number is: " + x;
let age = input();
print "Your age is: " + age;
Example Output:
Enter a number: 98.43
The number is: 98.43
18
Your age is: 18
Description: Prints the provided message to the standard error stream.
Usage:
err("Fatal error!");
Example Output (stderr):
Fatal error!
Description: Converts a number to its string representation.
Usage:
print string(123);
Example Output:
123
Description: Converts a string to a number.
Usage:
print number("123");
Example Output:
123
Description: Executes the provided shell command and returns its output as a string.
Usage:
print shell("echo hello");
Example Output:
hello
Description: Returns the length of a string or array.
Usage:
print length("abc"); // Output: 3
let arr = [1,2,3,4,5];
print length(arr); // Output: 5
Description: Exits the program with the given exit code (Exit Code must be positive) .
Usage:
exit(0);
Effect: Terminates the interpreter with the provided exit code.
Description: Returns the ASCII code of a single-character string (No, Pava doesn't support single quotes for characters).
Usage:
print getAsciiCode("A"); // Output: 65
Description: Converts a number (ASCII code) to its corresponding character as a string.
Usage:
print fromAsciiCode(65); // Output: A
Pava provides runtime and syntax error messages with line numbers.
When a syntax error is encountered, a message is displayed in the format:
[line X] Syntax Error: <message>
For example, trying to access an out-of-range index or using an invalid operand will print:
[line X] Runtime Error: <message>
If a function returns a value using return, it will properly exit the function body.
Files starting with #! are automatically skipped by the lexer.
Pava is a full-featured scripting language designed for learning language implementation techniques. This documentation has covered:
-
Lexical and Syntactic Structure: Variables, functions (with and without default arguments), control flow (if, while, for), logical operators, blocks, arrays/lists, modules, and more.
-
Built-In Functions: A wide array of native functions for time, string/number conversion, shell commands, error printing, and ASCII manipulation.
-
Modules: How to import/export modules and access module members.
-
Arrays/Lists: Array literals, indexing, bounds checking, index assignment, and fixed-size array declarations.
-
Error Handling: Both syntax and runtime errors are reported with line numbers.
-
Examples: Comprehensive code examples demonstrate each language feature.
This documentation serves as a complete reference for developers using Pava. As Pava evolves, additional features (such as classes, more built-in functions, and improved module systems) could be added. For now, you have a robust language implementation that supports a rich set of features ideal for learning and rapid prototyping.
Happy coding in Pava! 🎉
