BJEX Documentation
Complete reference for BJEX — syntax, built-ins, examples, and internals.
Complete reference for BJEX — syntax, built-ins, examples, and internals.
BJEX is a modern, beginner-oriented programming language and interpreter developed entirely from scratch in pure Java with zero external dependencies. It was created with one clear educational vision: to make programming easy to learn without sacrificing the fundamental concepts every programmer must understand.
Unlike traditional languages that require learners to study complex syntax before solving real problems, BJEX emphasizes clarity, simplicity, and practical learning. It allows new programmers to focus on computational thinking, algorithms, and problem-solving — not on confusing rules.
BJEX combines the readability of Python, the flexibility of JavaScript, and the robust architecture of a Java-based interpreter to provide a smooth, frustration-free learning experience.
.bjex file extension for all source files.
Example: hello.bjex, calculator.bjex.
"Programming should be easy to learn, enjoyable to practice, and powerful enough to build real solutions."
BJEX was designed to bridge the gap between learning programming and understanding how programming languages actually work internally.
BJEX is specifically designed for:
The language minimizes unnecessary syntax while preserving the core concepts found in all modern programming languages — so that everything learned in BJEX directly transfers to languages like Java, Python, and JavaScript.
BJEX is implemented using a complete, classical interpreter architecture. Every stage is hand-written in pure Java — no parser generators, no lexer frameworks.
| Component | Responsibility |
|---|---|
| Lexer | Converts raw source text into a stream of classified tokens. Handles all 4 comment styles, string literals, numbers, and operators. |
| Parser | Consumes the token stream and builds an Abstract Syntax Tree using recursive descent parsing. |
| AST | Tree of Node objects representing the program's structure — statements, expressions, literals, function calls. |
| Interpreter | Walks the AST and executes each node — evaluates expressions, calls functions, handles control flow. |
| Environment | Manages variable scoping — global scope, local function scopes, and closure chains. |
| Std Library | Built-in functions: print, input, len, upper, lower, substr, split, join, contains, typeof, range, now, readfile, writefile, matrix, array, dict. |
| Module System | Loads and executes external .bjex files as importable modules with namespace isolation. |
| Error Handler | Structured exception framework — throws typed errors (ValueError, NameError, etc.), caught by try/exception blocks. |
Get BJEX running in three steps.
Create a file called hello.bjex and paste this inside:
// My first BJEX program
name = input("Enter your name: ");
print("Hello,", name);
print("Welcome to BJEX Programming Language!");
Use BjexIde to Open your file or write code, and then click Run button.
java -version
BJEX uses dynamic typing — you never declare a type. Just assign a value and BJEX figures out the type automatically.
x = 42; // Integer
y = 3.14; // Float
name = "Hello BJEX"; // String
flag = true; // Boolean
empty = null; // Null
| Type | Example | Description |
|---|---|---|
| Integer | 42, -10, 0 | Whole numbers, positive or negative |
| Float | 3.14, -0.5 | Decimal numbers (double precision) |
| String | "Hello", "BJEX" | Text values enclosed in double quotes |
| Boolean | true, false | Logical true/false values |
| Array | array(1,2,3) | Ordered, dynamic collection of values |
| Dictionary | dict("k","v") | Key-value pairs, like a HashMap |
| Matrix | matrix([[1,2],[3,4]]) | 2D numeric matrix with math operations |
| Symbol | :ready, :done | Unique immutable identifier values |
| Time | now() | Current timestamp from runtime |
| Null | null | Represents no value / empty state |
a = 10 + 3; // Addition → 13
b = 10 - 3; // Subtraction → 7
c = 10 * 3; // Multiplication → 30
d = 10 / 3; // Division → 3.333...
e = 10 % 3; // Modulus → 1
f = 2 ^ 8; // Exponentiation → 256
x = 10;
print(x == 10); // Equal → true
print(x != 5); // Not equal → true
print(x > 5); // Greater than → true
print(x < 5); // Less than → false
print(x >= 10); // Greater/equal → true
print(x <= 9); // Less/equal → false
a = true;
b = false;
print(a and b); // Logical AND → false
print(a or b); // Logical OR → true
print(not a); // Logical NOT → false
first = "Hello";
last = "BJEX";
full = first + " " + last;
print(full); // → Hello BJEX
print() accepts any number of arguments separated by commas.
All values are converted to strings and printed space-separated.
print("Hello World"); // → Hello World
print("Value:", 42); // → Value: 42
print("Sum:", 10 + 5); // → Sum: 15
print("X =", x, "Y =", y); // → X = 10 Y = 20
print("Pi is approximately", 3.14); // → Pi is approximately 3.14
input() prints a prompt, waits for the user to type, and returns the value as a string.
name = input("Enter your name: ");
age = input("Enter your age: ");
print("Hello,", name, "— you are", age, "years old.");
input() always returns a String. Use arithmetic operations
carefully — convert with context if needed.
BJEX uses standard if / else if / else blocks with curly braces.
score = 75;
if (score >= 90) {
print("Grade: A");
} else if (score >= 75) {
print("Grade: B");
} else if (score >= 60) {
print("Grade: C");
} else {
print("Grade: F — Better luck next time!");
}
x = 15;
if (x > 10) {
if (x > 20) {
print("x is greater than 20");
} else {
print("x is between 10 and 20");
}
} else {
print("x is 10 or less");
}
age = 20;
pass = true;
if (age >= 18 and pass == true) {
print("Eligible and passed");
} else {
print("Not eligible");
}
Three-part C-style for loop: initializer; condition; increment.
// Count from 1 to 5
for (i = 1; i <= 5; i = i + 1) {
print("i =", i);
}
// Count down
for (n = 10; n >= 1; n = n - 1) {
print(n);
}
print("Blast off!");
Repeats as long as the condition is true.
count = 0;
while (count < 5) {
print("Count:", count);
count = count + 1;
}
arr = array(10, 20, 30, 40, 50);
i = 0;
while (i < length(arr)) {
print("Element", i, "=", arr[i]);
i = i + 1;
}
// Multiplication table
for (i = 1; i <= 5; i = i + 1) {
for (j = 1; j <= 5; j = j + 1) {
print(i, "*", j, "=", i * j);
}
}
Functions in BJEX are defined with the func keyword. They support
parameters, return values, and full local scoping.
func greet(name) {
return "Hello, " + name + "!";
}
message = greet("Bhargav");
print(message); // → Hello, Bhargav!
func add(a, b) {
return a + b;
}
func multiply(a, b, c) {
return a * b * c;
}
print(add(10, 25)); // → 35
print(multiply(2, 3, 4)); // → 24
func printBanner(title) {
print("=========================");
print(" " + title);
print("=========================");
}
printBanner("BJEX Language v1.0");
func square(n) {
return n * n;
}
func sumOfSquares(a, b) {
return square(a) + square(b);
}
print(sumOfSquares(3, 4)); // → 9 + 16 = 25
BJEX fully supports recursive functions. The function can call itself with a different argument until a base case is reached.
func factorial(n) {
if (n <= 1) {
return 1;
}
return n * factorial(n - 1);
}
print("5! =", factorial(5)); // → 120
print("10! =", factorial(10)); // → 3628800
func fibonacci(n) {
if (n <= 0) { return 0; }
if (n == 1) { return 1; }
return fibonacci(n - 1) + fibonacci(n - 2);
}
for (i = 0; i <= 10; i = i + 1) {
print("fib(" + i + ") =", fibonacci(i));
}
func sumDigits(n) {
if (n < 10) {
return n;
}
return (n % 10) + sumDigits(n / 10);
}
print(sumDigits(12345)); // → 15
Arrays in BJEX are dynamic, ordered collections. They support index access, appending, and all built-in operations.
// Create with array() function
arr = array(10, 20, 30, 40, 50);
// Create with literal syntax
nums = [1, 2, 3, 4, 5];
print("Array:", arr);
print("Literal:", nums);
arr = array(10, 20, 30, 40, 50);
print(arr[0]); // → 10 (first element)
print(arr[2]); // → 30 (third element)
print(arr[4]); // → 50 (last element)
arr = array(1, 2, 3);
// Append element to end
append(arr, 4);
append(arr, 5);
print(arr); // → [1, 2, 3, 4, 5]
// Get length
print(length(arr)); // → 5
arr = array(5, 10, 15, 20);
i = 0;
while (i < length(arr)) {
print("arr[" + i + "] =", arr[i]);
i = i + 1;
}
func sumArray(arr) {
total = 0;
i = 0;
while (i < length(arr)) {
total = total + arr[i];
i = i + 1;
}
return total;
}
nums = array(10, 20, 30, 40, 50);
print("Sum:", sumArray(nums)); // → 150
Dictionaries store key-value pairs — similar to a HashMap in Java or a dict in Python. Keys are strings. Values can be any type.
person = dict(
"name", "Bhargav",
"age", 21,
"country", "India",
"language","BJEX"
);
print(person);
d = dict("fruit", "Mango", "color", "Yellow");
// Get all keys
print(keys(d)); // → [fruit, color]
// Get all values
print(values(d)); // → [Mango, Yellow]
config = dict(
"debug", true,
"version", 1,
"name", "BJEX App",
"port", 8080
);
print("Debug mode:", keys(config));
print("Values:", values(config));
BJEX has native matrix support — a unique feature rarely found in beginner languages. Matrices are 2D numeric arrays with built-in arithmetic operations.
m1 = matrix([[1, 2],
[3, 4]]);
m2 = matrix([[5, 6],
[7, 8]]);
print("Matrix 1:", m1);
print("Matrix 2:", m2);
// Addition — element-wise
print("M1 + M2:", m1 + m2);
// → [[6,8],[10,12]]
// Multiplication — matrix product
print("M1 * M2:", m1 * m2);
// → [[19,22],[43,50]]
BJEX includes a powerful set of built-in string functions, all available without importing anything.
| Function | Description | Example |
|---|---|---|
len(s) | Returns length of string | len("hello") → 5 |
upper(s) | Converts to uppercase | upper("bjex") → "BJEX" |
lower(s) | Converts to lowercase | lower("BJEX") → "bjex" |
substr(s,start,end) | Extracts a substring | substr("abcdef",1,4) → "bcd" |
split(s,delim) | Splits string into array | split("a,b,c",",") → ["a","b","c"] |
join(arr,glue) | Joins array into string | join(["1","2","3"],"-") → "1-2-3" |
contains(s,sub) | Checks if substring exists | contains("hello","ll") → true |
sentence = "bhargav java expression language";
print("Length:", len(sentence)); // → 33
print("Upper:", upper(sentence)); // → BHARGAV JAVA EXPRESSION LANGUAGE
print("Substr:", substr(sentence, 0, 7)); // → bhargav
words = split(sentence, " ");
print("Words:", words); // → [bhargav, java, expression, language]
rejoined = join(words, "-");
print("Rejoined:", rejoined); // → bhargav-java-expression-language
print("Has 'java':", contains(sentence, "java")); // → true
Use these built-in functions to inspect and validate types at runtime.
| Function | Returns | Description |
|---|---|---|
typeof(val) | String | Returns type name as string: "integer", "float", "string", "boolean", "array", "dictionary", "matrix" |
isnumber(val) | Boolean | Returns true if value is Integer or Float |
isbool(val) | Boolean | Returns true if value is Boolean |
islist(val) | Boolean | Returns true if value is an Array |
print(typeof(42)); // → integer
print(typeof(3.14)); // → float
print(typeof("hello")); // → string
print(typeof(true)); // → boolean
print(typeof([1,2,3])); // → array
print(isnumber(42)); // → true
print(isnumber("hello")); // → false
print(isbool(true)); // → true
print(islist([1,2,3])); // → true
Generates a numeric array from start to end with a given step size.
// Range from 1 to 10, step 1
r1 = range(1, 10, 1);
print(r1); // → [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
// Even numbers: 0 to 20, step 2
evens = range(0, 20, 2);
print(evens); // → [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
// Count down: 10 to 1, step -1
countdown = range(10, 1, -1);
print(countdown);
// Get current timestamp
t1 = now();
print("Program started at:", t1);
// Use for simple timing
start = now();
// ... some work ...
end = now();
print("Start:", start);
print("End: ", end);
Symbols are unique, immutable identifier values prefixed with a colon :.
Two symbols with the same name are always equal. They are ideal for representing states,
flags, and named constants.
// Declare symbols
status = :ready;
mode = :active;
state = :ready;
// Symbol comparison
print(status == state); // → true (same name = equal)
print(status == mode); // → false (different names)
// Use symbols for readable state management
connectionState = :disconnected;
if (connectionState == :disconnected) {
print("Not connected to server");
} else if (connectionState == :connected) {
print("Connection established");
} else if (connectionState == :error) {
print("Connection error occurred");
}
BJEX provides structured, typed exception handling with try,
exception, and finally blocks — identical in concept to
Java and Python.
try {
x = 10 / 0;
} exception(ValueError) {
print("Caught: Division by zero!");
} finally {
print("This always runs — cleanup here.");
}
try {
print(undefinedVariable);
} exception(NameError) {
print("Caught: Variable does not exist.");
} finally {
print("Cleanup complete.");
}
try {
result = 10 / 0;
print(unknownVar);
} exception(ValueError) {
print("Math error caught.");
} exception(NameError) {
print("Name error caught.");
} finally {
print("Block complete.");
}
func safeDivide(a, b) {
try {
return a / b;
} exception(ValueError) {
print("Cannot divide by zero!");
return 0;
}
}
print(safeDivide(10, 2)); // → 5
print(safeDivide(10, 0)); // → Cannot divide by zero! 0
| Exception Type | Triggered When |
|---|---|
| ValueError | Division by zero, invalid numeric operations |
| NameError | Accessing an undefined variable |
| TypeError | Operation on incompatible types |
| IndexError | Array index out of bounds |
| FileError | File not found or I/O failure |
BJEX supports reading and writing text files with simple, clean built-in functions.
// Write text to a file (creates it if it doesn't exist)
writefile("output.txt", "Hello from BJEX!");
print("File written successfully.");
// Read the full content of a file
content = readfile("output.txt");
print("File content:", content);
try {
data = readfile("data.txt");
print("Read successful:", data);
} exception(FileError) {
print("File not found. Creating a new one...");
writefile("data.txt", "Default content");
} finally {
print("File operation complete.");
}
name = input("Enter your name: ");
score = input("Enter your score: ");
entry = name + "," + score;
writefile("scores.txt", entry);
print("Saved:", readfile("scores.txt"));
BJEX supports modular programming through the import statement.
You can split your code across multiple .bjex files and import them.
Create a file called mathutils.bjex:
// mathutils.bjex — reusable math functions
func square(n) {
return n * n;
}
func cube(n) {
return n * n * n;
}
func isPrime(n) {
if (n < 2) { return false; }
i = 2;
while (i * i <= n) {
if (n % i == 0) { return false; }
i = i + 1;
}
return true;
}
import mathutils.bjex;
print(mathutils.square(5)); // → 25
print(mathutils.cube(3)); // → 27
print(mathutils.isPrime(17)); // → true
print(mathutils.isPrime(10)); // → false
// Import built-in std module
import std.bjex;
print(std.helloModule()); // → Standard library loaded!
moduleName.functionName() syntax.
Every built-in function available in BJEX, no imports required.
| Function | Parameters | Returns | Description |
|---|---|---|---|
print(...) | Any values | void | Prints space-separated values to output |
input(prompt) | String | String | Prints prompt and reads user input |
len(s) | String or Array | Integer | Returns length |
upper(s) | String | String | Uppercase conversion |
lower(s) | String | String | Lowercase conversion |
substr(s,i,j) | String, Int, Int | String | Substring from index i to j (exclusive) |
split(s,d) | String, String | Array | Splits string on delimiter |
join(arr,g) | Array, String | String | Joins array with glue string |
contains(s,t) | String, String | Boolean | True if s contains substring t |
typeof(v) | Any | String | Returns type name as string |
isnumber(v) | Any | Boolean | True if Integer or Float |
isbool(v) | Any | Boolean | True if Boolean |
islist(v) | Any | Boolean | True if Array |
array(...) | Any values | Array | Creates a new dynamic array |
append(arr,v) | Array, Any | void | Appends value to array end |
length(arr) | Array | Integer | Returns array element count |
dict(...) | key,val pairs | Dictionary | Creates key-value dictionary |
keys(d) | Dictionary | Array | Returns array of all keys |
values(d) | Dictionary | Array | Returns array of all values |
matrix(arr) | 2D Array | Matrix | Creates a 2D numeric matrix |
range(s,e,step) | Int,Int,Int | Array | Generates numeric sequence |
now() | none | Time | Returns current timestamp |
readfile(path) | String | String | Reads entire file content |
writefile(path,txt) | String,String | void | Writes text to file (overwrites) |
BJEX is actively evolving. Here's what's planned for upcoming versions:
| Feature | Version | Status |
|---|---|---|
| GraalVM Native Image builds (.exe / .dmg / .deb) | v1.1.0 | 🔄 In Progress |
| Object-Oriented Programming — Classes & Objects | v1.2.0 | 📋 Planned |
| Lambda Expressions / Anonymous Functions | v1.2.0 | 📋 Planned |
| Interactive REPL (Read-Eval-Print Loop) | v1.3.0 | 📋 Planned |
| Package Manager for BJEX modules | v1.3.0 | 📋 Planned |
| Web-based BJEX Playground (run in browser) | v1.4.0 | 💡 Concept |
| Bytecode Compilation for faster execution | v2.0.0 | 💡 Concept |
| Dedicated BJEX IDE with syntax highlighting | v2.0.0 | 💡 Concept |
Comments
BJEX supports four different comment styles — more than most languages.
Single Line — Style 1
Single Line — Style 2
Multi-line — Style 1
Multi-line — Style 2