Changelog
All notable changes to VDX, by version.
v0.1.4
2026-07-02- —Optimized
math.min()andmath.max()to single-pass (track min/max and float flag in one loop instead of two) - —math module expanded with 14 new functions:
isPrime,primes,primeCount,sort,sortDesc,count,lcm,sum,mean,comb,hypot,lerp,e,tau - —
math.primes(n)uses Sieve of Eratosthenes for fast prime generation - —
math.isPrime(n)uses 6k±1 trial division — O(√n) - —graph module expanded with 4 new functions:
area,grid,color,legend - —
graph.area(xs, ys)— area chart with filled region below the line - —
graph.grid(bool)— toggle dashed grid lines on/off - —
graph.color(name)— set plot color (named colors or hex strings) - —
graph.legend(labels)— add a legend box with color swatches - —All chart types (
scatter,line,bar,hist) now respectgraph.color()instead of hardcoded steelblue
v0.1.3
2026-06-30- —Fixed
for-inloops lacking loop safety protection — iterations are now timed and blocked if they exceed 2000ms, matching while and C-style for loop behavior - —@unsafe annotation now correctly applies to
for-inloops to bypass loop safety protection - —math module expanded with 16 new functions:
log,log2,log10,exp,cbrt,asin,acos,atan,atan2,degrees,radians,gcd,sign,clamp,factorial,fibonacci - —
math.fibonacci(n)uses fast doubling algorithm — O(log n) instead of O(n)
v0.1.2
2026-06-30- —Fixed bare method calls losing object field mutations when break or continue is thrown inside a method
- —Fixed
graph.bar()drawing bars fromvMininstead of the zero line for mixed positive/negative values - —Fixed
Value::toStringnot escaping inner quotes in strings inside arrays and dicts - —Fixed graph module
escXmlnot escaping control characters — now escapes all control chars as numeric XML entities - —Fixed graph module
PlotStatebeing shared across threads — changed tothread_local - —Fixed lexer not handling
\rand\0escape sequences in string literals - —Fixed
math.floor(),math.ceil(),math.round()causing undefined behavior on very large float values — now checks bounds - —Fixed
graph.show()usingtmpnam_swith a TOCTOU race condition — now usesstd::filesystem::temp_directory_path()with random filename
v0.1.1
2026-06-30- —Fixed
for-initerating over a copy of the array instead of the live array — modifications during iteration are now reflected - —Fixed
DotCallExprmethod calls losing object field mutations when break or continue is thrown inside a method - —Fixed
graph.bar()rendering incorrectly with all-negative values — now computes proper axis range from data - —Fixed integer overflow in ++/-- operators not being detected — now throws runtime error matching
+/-/*checks - —Fixed empty dict literal
{}causing a parse error — now correctly produces an empty dictionary
v0.1.0
2026-06-29- —this system overhaul — this now returns the actual object instead of doing scope lookup, fixing param/field shadowing bugs
- —Fixed
this.field = valueparse error — this field assignment now works inside methods - —Fixed
this.method()parse error — this method calls now work inside methods - —Fixed method-to-method calls losing object context — calling a bare method name from within another method now properly pushes object fields as scope
- —Fixed new re-executing side-effect statements (e.g. print) on every instantiation — only let field initializers are executed now
- —Fixed
classexecuting non-function statements at declaration time — now only registers methods - —Fixed nested imports not being processed — imported files' own
importstatements are now resolved recursively - —Fixed
math.random(min, max)rejectingmin == max— now returnsmininstead of erroring - —C++ quality:
noexcepton simple getters, const correctness onisVarConstandisTruthy - —graph module — new plotting and data visualization module (SVG vector graphics output):
graph.scatter(),graph.line(),graph.bar(),graph.hist(),graph.title(),graph.xlabel(),graph.ylabel(),graph.save(path),graph.show()
v0.0.15
2026-06-28- —
class{}wrapper is no longer mandatory — top-level statements (print, let, fn, if, while, for, etc.) can now be written directly without a class wrapper - —Top-level function declarations are now supported:
fn add(a, b) { ... }at file scope - —Top-level functions are importable: imported files can export plain functions (not just class methods)
- —Added recommendation warning: when a VDX file has no
classdeclaration, a tip is printed to stderr suggestingclass{}for better organization - —
class{}is now recommended but optional — existing code with classes continues to work unchanged - —Fixed
math.round()returning FLOAT instead of INT for float inputs — now returns INT likemath.floor()andmath.ceil() - —Fixed
math.random(max)being exclusive (0 to max-1) — now inclusive (0 to max) for consistency withmath.random(min, max) - —Fixed return/break/continue at top level (outside function/loop) causing crash — now handled gracefully
- —Fixed return/break/continue in class body (outside functions) causing crash — now handled gracefully
- —Fixed return/break/continue during object construction (new) causing crash — now handled gracefully
- —Fixed scope leak in
execClasson exception — scope is now properly popped on all exit paths - —Fixed scope leak in
execNewon exception — scope is now properly popped on all exit paths
v0.0.14
2026-06-28- —Fixed scope leak on return inside if blocks, while, for, and
for-inloops - —Fixed math module never being registered at startup
- —Fixed module function dispatch for
math.sqrt()etc. — now checksmoduleFunctionsbefore object lookup - —Module constants like
math.pinow work viaDotExprwith 0 args - —Fixed
std::stoi/std::stodthrowing uncaughtstd::out_of_rangeon out-of-range literals - —Fixed undefined behavior:
isdigit/isalpha/isalnumin lexer now receiveunsigned charcast - —Fixed const variables modifiable via
push(),pop(),arr[i]=,obj.f=, and ++/-- - —Fixed break/continue escaping method call boundaries via
DotCallExpr - —Fixed duplicate function names across classes — methods now namespaced as
ClassName::funcName - —Fixed
math.floor()andmath.ceil()returning FLOAT instead of INT - —Fixed duplicate class names silently overwriting each other — now throws error
- —Added unary minus/plus operator support:
let x = -5;,5 - -3now parse correctly - —Fixed
staticmodule registration flag breaking multiple Interpreter instances - —Fixed math functions silently accepting non-numeric arguments — now throws type error
v0.0.13
2026-06-27- —Fixed continue in while and for loops corrupting the scope stack (double popScope)
- —Fixed loop safety check logic: now correctly flags iterations taking >2s instead of <2s
- —Fixed break/continue escaping function call boundaries into outer loops
- —Fixed
importcrashing with unhandled exception when file doesn't exist (now gives clean error) - —Fixed signed integer overflow causing undefined behavior in
+,-,*— now throws runtime error - —Fixed duplicate function names across classes silently overwriting each other — now throws error
- —Fixed new capturing temporary variables (e.g. loop counters) as object fields — only captures let declarations
- —Added func as alias for fn keyword:
func add(a, b) { ... } - —Added ++/-- syntax in for-loop update:
for (let i = 0; i < 10; i++) { ... } - —Added math module to CMake build (was missing — dead code)
- —Fixed math module function signatures to match interpreter's
ModuleFunctype - —Added
#includefor portableisdigit/isalphausage in lexer and main - —Added compiler warnings (
/W4on MSVC,-Wall -Wextra -Wpedanticon GCC/Clang) - —Replaced
std::rand()withstd::mt19937for better random number quality - —Replaced hardcoded PI with
M_PIfrom - —Replaced
std::endlwith\nin print to avoid unnecessary flush - —Refactored repetitive try/catch in if/elif/else into
execBlockhelper - —Improved
extractLinerobustness: searches for "at line " instead of just "line " - —Removed pointless
pushScope/popScopeinexecImport
v0.0.12
2026-06-15- —Added dictionary/map type:
let user = {"name": "Alice", "age": 30}; - —Dictionary access:
user["name"]returns the value for a key - —Dictionary assignment:
user["city"] = "Paris";adds or updates keys - —Dictionary length:
len(user)returns number of key-value pairs - —Added
fsmodule with file I/O:fs.readFile(path)andfs.writeFile(path, content) - —Added array type annotations:
let nums: int[] = [1, 2, 3]; - —Added
dicttype annotation:let user: dict = {"name": "Bob"};
v0.0.11
2026-06-15- —Added
importstatement: import other VDX files withimport "filename.vdx"; - —Imported files provide access to their classes and functions
- —Circular import protection prevents infinite loops
- —Added
type(value)built-in: returns type name as string ("int", "float", "string", "bool", "array", "object", "void") - —Added
input()built-in: read user input from stdin - —Added
input(prompt)variant: print prompt then read input - —Added
pop(arr)built-in: remove and return last element from array - —Extended
len(obj): now works with objects, returning number of fields - —
len()now supports arrays, strings, and objects
v0.0.10
2026-06-08v0.0.9
2026-06-08- —Added break statement for exiting loops early
- —Added continue statement for skipping to next loop iteration
- —Added const keyword for declaring immutable constants
- —Constants support type annotations:
const PI: float = 3.14; - —Added math module with 12+ functions:
sqrt,pow,abs,sin,cos,tan,floor,ceil,round,min,max,random,pi - —Interpreter tracks const variables to prevent reassignment
- —Loop control statements work with while, for, and
for-inloops - —Break/continue exceptions properly propagate through function calls
v0.0.8
2026-03-23- —Added float type: float literals with decimal point (e.g.,
3.14,5.0) - —Added true / false boolean literals
- —Added optional type annotations on let:
let x: int = 5;,let pi: float = 3.14; - —Runtime type checking: annotated variables are validated at assignment
- —Mixed int/float arithmetic: operations auto-promote to float when either operand is float
- —Added new keyword for object instantiation:
let obj = new ClassName(); - —Dot field access:
obj.fieldreads a field from an object - —Dot field assignment:
obj.field = value;sets a field on an object - —Dot method calls:
obj.method(args)calls a method with access to object fields - —Objects print as
- —Added C-style for loop:
for (let i = 0; i < n; i = i + 1) { ... } - —Added
for-inloop over arrays:for (item in arr) { ... } - —@unsafe now also works with for loops
- —Float truthiness:
0.0is falsy, non-zero is truthy - —Object truthiness: objects are truthy
v0.0.7
2026-03-22- —Added arrays / lists:
let arr = [1, 2, 3]; - —Array index access:
arr[0] - —Array index assignment:
arr[0] = 5; - —String index access:
str[0]returns single character - —Built-in
len(): returns length of arrays and strings - —Built-in
push(arr, value): appends a value to an array - —Array printing:
print(arr)outputs[1, 2, 3] - —Array truthiness: non-empty arrays are truthy, empty arrays are falsy
- —Improved error reporting: errors now display file name, line number, and surrounding source lines
v0.0.6
2026-03-22- —Added loop safety protection: while loops that iterate faster than 2 seconds are blocked
- —Added @unsafe annotation: place before while to bypass loop speed protection
- —Added SVG icon (
assets/icon.svg) - —Added Windows MSI installer support via CMake CPack + WiX
- —Installer adds
vdxto system PATH - —Added
.vdxfile association in installer - —Added LICENSE.txt (MIT)
- —Website v0.1.0: main page, download page, documentation pages
v0.0.5
2026-03-22- —Added while loop:
while (condition) { body } - —Added block scoping: variables declared inside
{ }blocks are local - —Added
wait(ms)statement to pause execution - —Added variable reassignment:
name = expr;
v0.0.4
2026-03-22v0.0.3
2026-03-22- —Added fn keyword for function declarations with parameters
- —Added return statement for function return values
- —Function calls as expressions
- —Operators:
+,-,*,/,==,!=,<,>,<=,>= - —String concatenation with
+ - —Operator precedence and parenthesized expressions
- —Division by zero runtime error
- —Two-pass class execution (register functions first, then run statements)
v0.0.2
2026-03-22- —Added let keyword for variable declarations
- —Variables support string and integer values
- —Variables can be used in
print()arguments - —Added expression system (string literals, integer literals, identifiers)
v0.0.1
2026-03-22- —Initial release
- —Lexer with support for strings, integers, identifiers, keywords, symbols
- —Parser for
classdeclarations andprint()statements - —Tree-walking interpreter
- —
classkeyword: declare named classes with a body - —
print(): output string literals to stdout - —Line comments (
//)