Welcome to Vipr! Vipr is a statically typed, ahead-of-time compiled programming language designed for simplicity, readability, and learning. Drawing inspiration from Python and Rust, Vipr v0.3.0 features a clean indentation-based syntax, mandatory type annotations, and strict block scoping.
-
Repository for online playground: vipr-web
Every executable Vipr program must define a main function. This is the entry point where execution begins.
def main() -> void:
print("Hello, Vipr!")
Vipr features mandatory type declarations and provides the following built-in primitives:
| Type | Description | Size |
|---|---|---|
bool |
Boolean value (true or false) |
1 byte |
int |
Signed integer | 32-bit |
float |
Floating-point number | 32-bit IEEE-754 |
char |
Single character | 8-bit |
string |
Text string (maps natively to std::string and supports + concatenation) |
Implementation-defined |
void |
Used exclusively for functions that return no value | N/A |
Variables must be declared with their type using the let keyword. Constants are declared using const. Vipr does not support type inference, but it does support multiple assignments on a single line!
Statements are terminated by newlines; there are no semicolons.
Variables:
// Declaration without initialization (gets default value)
let age: int
// Declaration with initialization
let name: string = "Alice"
// Reassignment
age = 25
// Multiple declaration and assignment
let x, y: float = 1.5, 2.0
x, y = y, x
Constants:
Use the const keyword to declare immutable values. Constants must be initialized immediately and cannot be reassigned later.
const PI: float = 3.14159
Arrays:
Vipr supports fixed-size and dynamic arrays that map to std::vector<T>.
// Array literals and explicit types
let numbers: int[] = [1, 2, 3, 4, 5]
// Empty dynamic array
let dynamic_floats: float[]
append(dynamic_floats, 3.14)
// Index access and modification
numbers[0] = 10
let first: int = numbers[0]
Built-in Functions for Data Structures:
len(arr): Returns the integer size of astringorarray.append(arr, item): Appends an element dynamically to the end of anarray.
Vipr keeps console interaction incredibly simple with two built-in statements:
input(variable1, variable2): Reads user input directly into existing variables.print(expr1, expr2): Outputs strings, variables, or the results of expressions sequentially to the console, followed by a newline.
def main() -> void:
let user_age: int
print("Enter your age:")
input(user_age)
print("In 5 years, you will be:", user_age + 5)
Vipr supports standard operators with traditional precedence rules:
- Arithmetic:
+,-,*,/,% - Comparison:
==,!=,<,>,<=,>= - Logical:
and,or,not - Assignment:
=,+=,-=,*=,/=
Conditional logic uses standard if, elif, and else blocks. Parentheses are NOT required around the condition. Code blocks are defined by a colon : and Python-style indentation.
let score: int = 85
if score >= 90:
print("A")
elif score >= 80:
print("B")
else:
print("C")
Vipr supports two types of loops: while loops and range-based for loops.
While Loop:
let count: int = 0
while count < 5:
print(count)
count = count + 1
For Loop:
Vipr uses a range(start, end, step) construct for strictly typed integer iteration.
for i: int in range(0, 10, 1):
print(i)
Functions are declared using the def keyword, followed by the parameters, an arrow ->, the return type, and a colon :.
Functions returning a value:
def multiply(a: int, b: int) -> int:
return a * b
Functions returning nothing:
Functions that do not return data must explicitly declare a void return type. The return statement can be omitted or used without an expression.
def greet(user: string) -> void:
print("Welcome, ", user)
Scope:
Vipr uses strict block scoping. Variables declared inside an indented block (like inside an if statement or a loop) are completely invisible outside of that block.
Comments:
// This is a single-line comment
/*
This is a
multi-line comment
*/
Here is a full Vipr program putting it all together:
const MAX_LIMIT: int = 100
def add(a: int, b: int) -> int:
return a + b
def main() -> void:
let x, y: int
print("Enter first number:")
input(x)
print("Enter second number:")
input(y)
let result: int = add(x, y)
print("Result:", result)
if result > MAX_LIMIT:
print("Large number")
else:
print("Small number")
Since the Vipr compiler generates C++ code and compiles it natively, you must have g++ (with support for C++11) installed on your system and available in your PATH.
Linux (Debian/Ubuntu):
Use apt to install the build essentials which includes g++:
sudo apt update
sudo apt install g++Linux (Fedora/RHEL):
Use dnf to install GCC:
sudo dnf install gcc-c++Windows: Vipr relies on GCC, so we recommend installing TDM-GCC.
- Download the TDM-GCC installer for your system.
- Follow the setup instructions (making sure to leave the option to "Add to PATH" checked).
- Open a new terminal and verify the installation with
g++ --version.
The Vipr compiler supports the following command-line flags:
-o <name>: Specify the output binary name.--emit-cpp: Save the generated C++ code instead of deleting it (useful for inspection).--dump-ast: Print the Abstract Syntax Tree to the console for debugging.
If you have the compiled compiler binary (e.g., vipr or vipr.exe):
./vipr <file.vipr> -o custom_bin --dump-ast --emit-cppThis generates a native executable named after your source file (e.g., compiling hello.vipr outputs hello in the same directory). You can then run your compiled program:
./helloIf you have Rust and Cargo installed, you can compile and run directly from the repository source:
cargo run -- <file.vipr>