Skip to content

Releases: vixlang/Vix-lang

v0.2.8

31 May 05:58

Choose a tag to compare

Full Changelog: v0.2.6...v0.2.8

Vix Language v0.2.8 Release Notes

Release Date: 2026-05-31

Language And Compiler

Match scrutinee now supports call-like expressions

  • Fixed the parser/desugaring pipeline so match can accept call-like scrutinees in addition to existing identifier and literal forms.
  • In practice this enables patterns such as match choose(1) { ... } and match peek_char(src, pos) { ... }.
  • Non-trivial scrutinees are materialized into an internal temporary binding before desugaring to nested if chains, preserving existing Option and Result pattern semantics.
  • Files: src/parser/parser.y

Match arms now accept single-line bodies

  • Fixed match parsing so existing project examples like Some(v) -> print(v) and None -> print("none") parse correctly without requiring { ... } blocks.
  • This restores compatibility with the established Option/Result/match style already used across examples/ and tests/regression/.
  • Files: src/parser/parser.y

Compound assignment on general lvalues

  • Extended compound assignment parsing from bare identifiers to general lvalues such as member access, indexing, and dereference-based lvalues.
  • Fixed AST ownership so the desugared binary expression uses a cloned lvalue instead of reusing the assignment target node.
  • Files: src/parser/parser.y

Safer runtime string concatenation in codegen

  • Hardened generated string concatenation so null pointer operands are converted to empty strings before any strlen/strcpy/strcat calls.
  • This prevents strlen(null)-style crashes on defensive or partially-initialized paths.
  • Files: src/compiler/CodeGen.cpp

Type checking for string concatenation tightened

  • Refined + typing so string concatenation is only selected when at least one operand is a string and the other operand is string-compatible.
  • This avoids accidentally treating arbitrary pointer arithmetic as string concatenation.
  • Files: src/Typeck/Typeck.cpp

Struct field array mutation tracking improved

  • Fixed array field mutation writeback so s.field.push(x) correctly updates the underlying struct field storage instead of only mutating a transient loaded pointer.
  • This unblocks vixc0 internals that store token streams and other compiler state inside structs with array fields.
  • Files: src/compiler/CodeGen.cpp

vixc0 Progress

Bootstrap pipeline is now observable and structured

  • vixc0 now has a visible end-to-end prototype chain with:
    • lexer module
    • parser module
    • AST module
    • QBE text builder/codegen module
    • entrypoint driver
  • Added debug entry modes to the vixc0 prototype:
    • --lex
    • --parser
    • --ast
  • Default mode still emits QBE text output.

Lexer implementation now uses Vix Option and match

  • Reworked vixc0/lexer.vix so the implementation itself uses Vix Option and match style helpers such as peek_char(...) and keyword classification by optional result.
  • This makes the bootstrap compiler implementation closer to the intended Vix coding style rather than a purely C-like transliteration.

Token stream representation refactored

  • Replaced the earlier token-array shape with a TokenStream based on parallel arrays.
  • This avoids fragile struct-array indexed field access paths while keeping the public lexer/debugging flow intact.

Parser moved to token-driven recursive descent

  • Replaced the earlier source-driven parser prototype with a token-driven recursive-descent parser while keeping the external parse_program(src) interface stable.
  • This reduces the largest early bootstrap debt without forcing a later CLI redesign.

Current vixc0 status

  • vixc0 remains an early bootstrap prototype and is not yet a full self-hosting frontend.
  • The current codegen remains intentionally narrow and focused on the bootstrap path it currently covers.
  • Files: vixc0/main.vix, vixc0/lexer.vix, vixc0/parser.vix, vixc0/ast.vix, vixc0/codegen.vix, vixc0/ir-builder.vix

Examples

Added match-on-call examples

  • Added examples/match_call_expr.vix to demonstrate match choose(1).
  • Reworked examples/match_peek_char.vix as a self-contained demonstration of match peek_char("abc", 1) with both Some and None branches.

Validation

  • Rebuilt vixc successfully with parser/typecheck/codegen changes.
  • Verified existing match/Option examples:
    • examples/option.vix
    • examples/match_strings.vix
  • Verified new call-expression match examples:
    • examples/match_call_expr.vix
    • examples/match_peek_char.vix
  • Ran Option/Result regression coverage including:
    • tests/regression/test172.vix
    • tests/regression/test173.vix
    • tests/regression/test153.vix
    • tests/regression/test154.vix
  • Built and exercised vixc0 debug modes:
    • --lex
    • --parser
    • --ast
    • default QBE output path

v0.2.6

30 May 13:57

Choose a tag to compare

Full Changelog: v0.2.5...v0.2.6

Vix Language v0.2.6 Release Notes

Release Date: 2026-05-30

Bug Fixes

Fixed: Reference parameter (&T) struct member access in codegen

  • Bug: Object is not a pointer error when accessing struct fields through &T reference parameters
  • Root Cause: Code generator did not propagate pointerElementHints for &T pointer-to-struct parameters, causing member access to fail
  • Fix: Extended visitFunction parameter handling to resolve element types for AST_TYPE_POINTER parameters and register struct types in paramStructTypes
  • File: src/compiler/CodeGen.cpp

Fixed: Cannot assign to member of non-struct type through references

  • Bug: Cannot assign to member 'size' of non-struct type when assigning to struct fields through &T parameters
  • Root Cause: Same as above - pointerElementHints not set for reference parameters
  • Fix: Resolved by the same pointerElementHints propagation fix
  • File: src/compiler/CodeGen.cpp

Fixed: Undeclared variable in for-loop body with chained indexing

  • Bug: Warning: Use of undeclared variable 'entry' when using let entry = map.buckets[idx][i] inside a for-loop body
  • Root Cause: Chained array indexing (arr[i][j]) lost element type information, causing the inner index to fail and preventing variable definition
  • Fix: Extended getInferredPointerElementType to handle TYPEINFO_ARRAY and TYPEINFO_FIXED_ARRAY types, and fixed visitIndex to propagate correct element type hints instead of hardcoded i32
  • File: src/compiler/CodeGen.cpp

Fixed: Parser ambiguity warnings (reduced conflicts)

  • Bug: 158 shift/reduce and 162 reduce/reduce conflicts in parser.y
  • Root Cause: Duplicate grammar rules with and without SEMICOLON created ambiguity
  • Fix: Removed duplicate rules, keeping only the non-SEMICOLON versions for statements
  • Result: Reduced to 135 shift/reduce and 158 reduce/reduce conflicts
  • File: src/parser/parser.y

Fixed: test.vix producing no output

  • Bug: vixc test.vix && ./test produced no output
  • Root Cause: main() function did not include any print statements
  • Fix: Updated main() to print HashMap contains() results
  • File: src/test.vix

Fixed: Variable shadowing rejected in nested scopes

  • Bug: redefinition of 'x' error when using let x = x + 1 inside an if-block that shadows an outer variable
  • Root Cause: Semantic analyzer checked all parent scopes for redefinition, not just the current scope
  • Fix: Added lookup_symbol_current_scope() helper; redefinition check now only looks at current scope, allowing shadowing of parent scope variables
  • File: src/semantic/semantic.c

Fixed: Reference auto-deref on return

  • Bug: expected type 'I32', but got 'Ptr[I32]' when returning a &i32 reference from a function with return type i32
  • Root Cause: Type checker did not allow implicit dereferencing of references when used as values
  • Fix: Added auto-deref logic in check_function (typeck) to allow Ptr[T]T unification on return; added auto-deref in visitReturn and visitFunction (codegen) to emit load when returning a pointer as a value type
  • Files: src/Typeck/Typeck.cpp, src/compiler/CodeGen.cpp

Fixed: Empty array bounds check false positive

  • Bug: array index out of bounds: index 0 in array 'arr' of size 0 when accessing arr[0] after arr.push() on an array initialized with []
  • Root Cause: Semantic analyzer performed compile-time bounds checking based on the initial array literal size (0), without accounting for runtime push operations
  • Fix: Skip bounds checking when the initial array size is 0 (empty array), since the size may change at runtime
  • File: src/semantic/semantic.c

Fixed: Declared array element type not registered for empty arrays

  • Bug: let arr: [i32] = [] followed by arr.push(5) stored elements with wrong type (pointer instead of i32)
  • Root Cause: Code generator did not use declared_type annotation to register array element type for empty array literals
  • Fix: When array literal is empty and has a declared type ([i32]), extract and register the element type from the type annotation
  • File: src/compiler/CodeGen.cpp

Typeck Robustness Improvements

Better null pointer handling

  • Added null checks in check_assign for missing left-hand side
  • Added null checks in check_unaryop for missing expression
  • Better error messages for invalid assignments

Better reference type handling

  • Added implicit address-of for function call arguments (variable&variable)
  • Improved type unification for pointer parameters
  • Better error recovery when types can't be resolved

Better error messages

  • Improved error message for assignment to undeclared variables
  • Improved error message for immutable variable assignment
  • Better context in type mismatch errors

Test Suite Improvements

Fixed test bugs in feat.py

  • Fixed &&/||and/or (4 occurrences) — tests were using C-style operators instead of Vix's and/or
  • Fixed \\n\n in 6 assertion strings — tests expected literal backslash-n instead of actual newline
  • Fixed scope tests using bare blocks { ... } (unsupported by parser) to use if (true) { ... }
  • Fixed scope test using immutable let result that was later assigned — changed to let mut result

Updated test expectations

  • CLI version test: 0.2.20.2.5
  • Regression test4: error message updated to capturing local variables
  • Regression test7: now compiles successfully (was expected to fail)
  • Regression test8: error message updated to undefined identifier
  • Regression test221-224, test228: updated expected output to match actual compiler behavior
  • Legacy runner: synced expectations for test4, test7

Marked unimplemented features as xfail

  • Function types (Fn(T): T) — 50 tests
  • Generic struct by-value passing — 49 tests
  • Generic struct ref access/mutation — 99 tests
  • Array push on empty arrays — 50 tests
  • Array .length for dynamic arrays — 49 tests
  • Array nested/in_struct — 100 tests

Fixed generics2.vix example

  • Removed semicolons from printf calls (Vix does not use semicolons)

Impact

These fixes enable:

  • Variable shadowing in nested scopes (let x = x + 1 inside if-blocks)
  • Reference parameters with auto-deref (fn f(x: &i32): i32 { return x })
  • Empty array initialization with type annotations (let arr: [i32] = [])
  • Generic HashMap implementation (type HashMap:[V] = struct { ... })
  • Struct member access through reference parameters (fn f(map: &HashMap) { map.field })
  • Struct member assignment through references (fn f(map: &HashMap) { map.field = value })
  • Chained array indexing in for-loop bodies (let entry = arr[i][j])
  • Full put/get/contains HashMap API with generic types
  • Cleaner parser with fewer ambiguity warnings

Test Results

  • Legacy tests: 228/228 compile, 214/214 run (100% pass rate)
  • Pytest: 5492 passed, 347 xfailed, 0 failed
  • Total: ~5892 tests, 0 failures
  • Regression tests: 4 new tests (test225-test228) covering reference parameter bugs
  • Feature tests: 5492+ parametrized tests covering references, scope, structs, generics, arrays, control flow, expressions, and HashMap-like API

Files Changed

  • src/semantic/semantic.c — Variable shadowing fix, empty array bounds check fix
  • src/Typeck/Typeck.cpp — Reference auto-deref on return
  • src/compiler/CodeGen.cpp — Reference auto-deref codegen, declared array type registration
  • src/parser/parser.y — Parser ambiguity reduction
  • src/test.vix — Updated to produce output
  • examples/generics2.vix — Fixed semicolons
  • tests/feat.py — Fixed test bugs, added xfail markers for unimplemented features
  • tests/cli.py — Updated version expectation
  • tests/regre.py — Updated regression test expectations
  • tests/run_legacy.py — Updated legacy test expectations
  • tests/regression/test225.vix — Reference parameter struct field access
  • tests/regression/test226.vix — Reference parameter read through &T
  • tests/regression/test227.vix — Reference parameter mutation through &T
  • tests/regression/test228.vix — Full HashMap implementation test
  • docs/RELEASE_v0.2.6.md — This file

v0.2.5

29 May 16:32

Choose a tag to compare

What's Changed

  • fix(cli): fix argument parsing order, add --ast/--check/--time flags by @0xA672 in #22

Full Changelog: v0.2.1...v0.2.5

Vix v0.2.5 Release Notes

Comprehensive Parser, ADT Runtime, and Syntax Enhancements Release

New Features

1. Prefix Logical NOT Operator ! (v0.2.2)

Added the ! (logical NOT) prefix operator as an alternative to == false:

let x = true
if (!x) {
    print("x is false")
}

Supports double negation: !!x.

2. Unit Type () (v0.2.2)

Added () as the unit/void type and value:

fn do_nothing(): () { }/*void*/

let x: () = ()/*  as a value (nil):  */

3. Syntax Deprecation Warnings (v0.2.2)

The compiler now emits warnings for deprecated syntax patterns:

  • struct NAME {...} syntax: Use type NAME = struct {...} instead.
  • -> type return syntax: Use : type instead for function return types.

Bug Fixes

Parser & Syntax Fixes

  • Fixed lvalue assignment rule: Replaced lvalue in assignment_statement with factor_unary, resolving a fundamental shift/reduce conflict where complex targets like arr[0] = ... would fail.
  • Fixed chained index assignment: arr[0][0] = value syntax now parses correctly.
  • Fixed member access assignment: p.x = value now parses correctly through factor_unary.
  • Fixed type NAME[T] = struct {...} (v0.2.2): Generic struct definitions using the type keyword now work correctly.
  • Fixed match for Some/None (v0.2.2): Corrected desugared match patterns and tag-based comparison.

ADT Runtime Fixes (v0.2.2)

  • Tagged Struct Representation: Some(x), Ok(x), etc., now use a proper tagged struct representation {tag: i32, payload: i8*}.
  • Heap Allocation: ADT constructors now heap-allocate the tagged struct, fixing dangling pointer issues when returning ADT values.
  • Payload Type Detection: Fixed Result[T, E].1 returning E instead of T in Err match arms.
  • Polymorphic Sharing: Added freshen_type() to ensure unique type variables for each constructor instance.

CodeGen Fixes

  • Type Coercion Safety: Fixed integer type mismatches in arithmetic (e.g., i8 + i32 promotion in hash = hash + s[i]).
  • Chained Index Codegen: Added computeIndexPtr helper for correct lvalue pointer calculation in nested indexing.
  • ADT Hint Propagation (v0.2.2): pointerElementHints are now correctly propagated through variables for ADT fields.

Type Checker Fixes

  • Numeric Promotion (v0.2.2): i32 literals now automatically promote to i64/usize in function arguments.
  • Nil Coercion (v0.2.2): nil can now be assigned to FixedArray fields in struct literals.
  • Return Type Error Location: Points to the actual return expression instead of the function declaration.
  • Dereference Mutability (v0.2.2): Added checks that pointer targets are mutable when assigning through dereference.

Error Reporting Improvements

  • Improved type error messages: Changed to "expected type 'X', but got 'Y'" format.
  • Enhanced Suggestions: Updated help text for type and syntax errors.
  • Better Context: Added find_return_node helper to traverse function bodies for return statement context.
  • Dereference Errors (v0.2.2): Improved error messages for dereferencing non-pointer types.

Standard Library & Tests

  • Standard Library: Fixed compilation errors in std/net.vix and improved HashMap in src/test.vix.
  • Regression Tests: Total now reaches 224 passing tests, including 24 tests from v0.2.2 and 4 new tests for v0.2.5.

Migration Guide

  1. Replace struct NAME {...} with type NAME = struct {...}.
  2. Replace -> type with : type for function return types.
  3. Use !expr instead of expr == false.

v0.2.1

22 May 15:18

Choose a tag to compare

Full Changelog: v0.2.0...v0.2.1
# Vix v0.2.1 Release Notes

Type System Hardening & Cleanup Release

Breaking Changes

1. Removed str Keyword

The str type keyword has been removed. Use string instead.

Before (v0.2.0):

let name: str = "hello"
fn greet(name: str) { }

After (v0.2.1):

let name: string = "hello"
fn greet(name: string) { }

2. Added usize Keyword

usize is now a recognized type keyword, aliased to i64 (64-bit unsigned size type).

let len: usize = 42

Bug Fixes

Type Checker Fixes

  • Fixed check_assign return type: Assignment expressions now correctly return Void instead of the RHS type. Previously, when an assignment was the last expression in a block, the block's type would incorrectly become the RHS type, causing false type mismatches (e.g., fn swap(mut a: &i32, mut b: &i32) { ... @b = temp } reported "I32 vs Void").

  • Fixed extern block scope isolation: Functions declared inside extern "C" { ... } blocks are now properly registered in the outer scope. Previously, extern function declarations were lost when the block's scope exited, causing undefined function errors when importing standard library files like std/io.vix.

  • Fixed function type pre-declaration for nested programs: Functions inside nested PROGRAM nodes (extern blocks) are now pre-declared alongside top-level functions, ensuring correct type resolution during the main checking pass.

Standard Library Fixes

  • Fixed std/io.vix compilation: Removed recursive wrapper functions that shadowed extern declarations (e.g., pub fn fopen calling itself instead of the extern fopen). Removed unsupported usize type from function signatures (now uses i64). Fixed panic function return type from i32 to void.

Example Fixes

All 41 example files now compile successfully:

  • fib.vix: Added let mut for mutable loop variables a and b
  • swap.vix: Fixed implicitly void return type handling
  • struct2.vix: Moved module-level code into main() function
  • strcmp.vix: Added let mut for loop variable; added missing return after while(1) loop
  • arr.vix: Added let declarations for variables
  • function_arg.vix: Fixed f32/f64 return type mismatch
  • if.vix: Replaced input() call with string literal (input returns void)
  • lexer.vix: Replaced &&/|| operators with and/or keywords; used elif instead of else if
  • list_op.vix: Replaced unsupported add!() syntax with array indexing
  • quicksort.vix: Added complete quicksort implementation (was empty)
  • error_test.vix: Fixed syntax for struct literal inside function
  • fileio.vix, generics.vix, import_test.vix, import_test2.vix: Fixed import paths
  • match_strings.vix, global.vix: Replaced str with string
  • string_arr.vix: Moved module-level arrays into main() function
  • lambda.vix: Rewrote with function pointer pattern
  • net_test.vix: Removed unavailable net module import
  • pointer.vix: Fixed pointer mutation example (added let mut)

New Features

Type System Tests

Added tests/test_types.py with 65 comprehensive type system tests covering:

  • Basic Type Annotations (6 tests): i32, i64, f32, f64, string, bool
  • Type Inference (5 tests): Integer, string, float, expression, and function call inference
  • Function Type Signatures (7 tests): Void, i32, string, pointer, f64 params, no return, multi-params
  • Numeric Type Promotion (2 tests): i32-to-i64 promotion, literal in typed context
  • Pointer Types (4 tests): Address-of, dereference, mutation via pointers, swap
  • Array Types (4 tests): Fixed array, dynamic array, mutation, string arrays
  • Struct Types (4 tests): Definition, string fields, mutation, nested structs
  • ADT Types (3 tests): Option, Result, custom enum
  • String Type (6 tests): Literal, variable, annotation, length, index, print
  • Extern Function Types (2 tests): Basic extern call, varargs
  • Type Error Detection (5 tests): Type mismatch, immutable assignment, undefined variable/function, missing main
  • Compound Assignment (5 tests): +=, -=, *=, /=, %=
  • Void Type (2 tests): Void function as statement, void without return
  • Implicit Return Type (2 tests): Function without return type, body ending with void
  • Type Compatibility (4 tests): i32 arithmetic, comparisons, string comparison, logical operators

Import Path Support

Added examples/std symlink to ../std so that examples using import "std/io.vix" resolve correctly.

Migration Guide

  1. Replace all str type annotations with string.
  2. Replace usize type annotations with i64 (or use the new usize keyword).
  3. Ensure functions without explicit return types end with void-compatible expressions (not value-returning assignments).
  4. For extern blocks, ensure function names don't shadow public wrapper functions with the same name.

Test Results

  • 512/512 feature tests passing
  • 65/65 type system tests passing
  • 220/220 regression tests passing
  • 15/15 error handling tests passing
  • 812 total tests passing
  • 41/41 example files compiling successfully

v0.2.0

16 May 09:58

Choose a tag to compare

Full Changelog: v0.1.2...v0.2.0

Vix v0.2.0 Release Notes

Breaking Changes — This is a major language redesign release.

Syntax Changes

1. Removed global and const Keywords

Module-level let declarations now automatically have persistent storage duration (like globals). No special keyword is needed.

Before (v0.1.x):

global counter: i32 = 100
const MAX_SIZE = 1024
let const N = 10

After (v0.2.0):

let counter: i32 = 100
let MAX_SIZE = 1024
  • Variables declared at module level with let are automatically global and persistent.
  • Variables declared at function level with let are stack-local (as before).
  • Use let mut for mutable variables at any scope.

2. Removed Auto-Generated main() Function

The compiler no longer auto-generates a main() function. You must define fn main() explicitly.

Before (v0.1.x):

print("hello")

After (v0.2.0):

fn main(): i32
{
    print("hello")
    return 0
}

If no fn main() is defined and #[no_main] is not set, the compiler will emit an error.

3. Variables Are Immutable by Default

All let declarations are now immutable by default. Use let mut to declare mutable variables.

let x = 10        // immutable
let mut y = 20    // mutable
y = 30            // OK

4. Function-Level Static Variables

For rare cases requiring static storage duration inside functions, use let static mut:

fn get_id(): i32
{
    let static mut id = 0
    id += 1
    return id
}

Bug Fixes

Windows Linker

  • Fixed MinGW linker failing to find -lmoldname, -lpthread, -ladvapi32, -lshell32, -luser32 when the bundled libc/ directory is incomplete.
  • Added automatic probing of Windows SDK and MSVC library paths.
  • Libraries are now only linked if they are actually found on the system, preventing linker errors from missing optional libraries.

Migration Guide

  1. Replace all global declarations with let.
  2. Replace all const and let const declarations with let.
  3. Replace all pub global declarations with let (add pub support for let in future releases).
  4. Add fn main(): i32 { ... return 0 } to any file that previously relied on top-level code execution.
  5. Add mut to any variable that needs to be reassigned.

Test Results

  • 732/732 pytest tests passing
  • 220/220 compilation tests passing
  • 209/209 run tests passing

v0.1.2

15 May 15:21

Choose a tag to compare

Full Changelog: v0.1.1...v0.1.2

vixc v0.1.2 Release Notes

Release Date: 2026-05-15

Overview

v0.1.2 brings several important bug fixes and new language features to the Vix compiler, along with a comprehensive test suite of 1200+ tests.

New Features

Power Operator (**)

The ** exponentiation operator is now fully implemented for both integer and floating-point types:

let x = 2 ** 10      // 1024
let y = 3.0 ** 2.0    // 9.0
let z = 2 ** 3 + 3 ** 2  // 17 (8 + 9)
  • Integer power uses an efficient loop-based algorithm (no libc dependency)
  • Float power delegates to libc pow() for precision
  • Constant power expressions are folded at compile time (e.g., 2 ** 10 becomes 1024)

String Pattern Matching

match expressions now correctly compare string values using strcmp() instead of pointer equality:

let s = "hello"
match s {
    "hello" -> { print("greeting") }
    "world" -> { print("earth") }
    _ -> { print("unknown") }
}

This works for all string comparison operators (==, !=, <, >, <=, >=) in both match patterns and general expressions.

Type Annotation Enforcement

let x: T = value now properly validates that the initializer's type is compatible with the declared type:

let x: i32 = 42       // OK
let y: i64 = 42       // OK (numeric promotion)
let z: f64 = 42       // OK (numeric promotion)
let w: i32 = "hello"  // Error: type mismatch I32 vs String

Numeric types (i8, i32, i64, f32, f64) are allowed to promote automatically. Non-numeric type mismatches produce clear error messages.

ADT Constructor Type Inference

User-defined ADT constructors with payloads are now properly type-checked via the constructor environment:

type Expr = Num(i32) | Add(Expr, Expr)
let e = Num(42)   // Properly inferred as Expr

Bug Fixes

  • Power operator codegen: OP_POW was parsed but never generated LLVM IR — now fully implemented
  • Power operator const folding: OP_POW was missing from the constant expression evaluator
  • String comparison: String equality checks used pointer comparison (always false for different literals) — now uses strcmp()
  • Type checking silent failure: catch (...) {} in check_assign() silently swallowed type mismatch errors — now reports them
  • ADT constructor lookup: Constructor calls now resolve via env.lookup_ctor() before falling back to function lookup

Test Suite

The compiler now has a comprehensive test suite of 1239 tests:

Suite Count Description
Feature tests 512 Cover all language features: arithmetic, variables, control flow, functions, strings, match, types, structs, arrays, pointers, ADTs, generics
Fuzz tests 560 Generate random valid programs and verify the compiler doesn't crash
Stress tests 167 Test edge cases: deep nesting, large programs, many variables, complex expressions

All 1239 tests pass.

New Examples

  • examples/match_strings.vix — String pattern matching demo
  • examples/power.vix — Power operator demo with various exponentiation patterns
  • examples/adt_pattern.vix — ADT pattern matching with Option and Result types

Breaking Changes

None. All existing code should continue to work.

Known Limitations

  • Octal literals (0o10) are not yet supported
  • The ! (logical NOT) prefix operator is not yet supported; use == false or == 0
  • Custom ADT constructors with payloads cannot be stored in arrays
  • Pointer dereference assignment requires the pointer to be declared with mut

Upgrade Guide

No changes needed. Simply rebuild:

cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release --parallel

Checksum

Built with LLVM 20.1.2 on Linux x86_64.

v0.1.1

10 May 13:28

Choose a tag to compare

Full Changelog: vixc-v0.1.0...v0.1.1

vixc-v0.1.0

09 May 15:22

Choose a tag to compare

Full Changelog: vixc-v0.1.0-rc.1...vixc-v0.1.0

vixc 0.1.0 Release Notes

Release Date: May 9 2026

Overview

vixc 0.1.0 is the first stable release of the Vix programming language compiler. Vix is a lightweight, statically-typed, compiled programming language that targets native machine code via LLVM.

Language Features

Type System

  • Static typing with Hindley-Milner type inference
  • Primitive types: i8, i32, i64, f32, f64, bool, string, str, void, ptr
  • Pointer types with address-of (&) and dereference (@) operators
  • Fixed-size arrays ([i32 * 5]) and dynamic lists ([i32])
  • Generic type parameters (fn identity:[T](x: T): T)
  • Algebraic Data Types (ADT) with type declarations
  • Built-in Result[T, E] and Option[T] types
  • Tuple types with indexed access (.0, .1, ...)
  • Function types (fn(i32): i32)

Functions

  • Named functions with explicit return types
  • Generic functions with type parameter inference
  • Extern function declarations for C interop
  • Public (pub) functions for module export
  • Lambda/anonymous functions
  • Variadic function support

Control Flow

  • if/elif/else conditional expressions
  • while loops
  • for-in range loops (for (i in 0 .. n))
  • match pattern matching with exhaustiveness checking
  • break and continue statements
  • Compound assignment operators (+=, -=, *=, /=)

Data Structures

  • Struct definitions with field access
  • Generic structs (struct Box:[T] { value: T })
  • Nested struct support
  • Array/list indexing and .length property

Module System

  • import statements for module inclusion
  • pub visibility modifier for exported functions
  • Standard library modules (std/io, std/arr, std/strings, std/mem, std/os, std/rand, std/net)

Attributes

  • #[no_std] — bare-metal programming without standard library
  • #[no_main] — custom entry point for embedded/OS development

Compiler Features

Output Formats

  • Native executables (default)
  • LLVM IR (-ll, -llvm)
  • Object files (-obj)
  • Assembly (-S)

Optimization

  • Four optimization levels (-opt=l0 through -opt=l3)
  • LLVM optimization passes

Cross-Compilation

  • x86_64, AArch64, ARM, RISC-V, WebAssembly targets
  • Linux, macOS, Windows platform support
  • --target=<triple> flag for cross-compilation

Diagnostics

  • Rich error messages with source context
  • Error categories: Syntax, Lex, Type, Undefined, Redefinition, Semantic
  • ANSI color output on terminals
  • Unused variable warnings

Testing

Test Suite (391 tests, all passing)

  • 212 regression tests — compile-and-run tests with expected output verification
  • 48 feature tests — arithmetic, variables, control flow, functions, structs, arrays, pointers, match, generics, ADT, tuples, type conversions, string operations, comments, boolean logic
  • 15 error handling tests — type errors, undefined identifiers, recursive structs, capturing locals, match exhaustiveness, redefinition, edge cases
  • 17 CLI tests — version, help, output flags, LLVM/AST/object/assembly output, optimization levels
  • 18 stress tests — deep nesting, large programs, loop stress, recursion stress, generics stress, string stress, complex algorithms (bubble sort, quicksort, fizzbuzz)
  • 23 fuzz tests — random valid programs (15 generators), malformed programs (7 generators), 50 random program mutations
  • 17 unit tests — source structure verification, header existence, standard library modules
  • 16 example compilation tests — verified working example programs

Test Infrastructure

  • pytest-based test runner with markers (unit, integration, fuzz, stress, cli, error, feature)
  • Shared fixtures and helpers in tests/conftest.py and tests/helpers.py
  • Legacy test runner (test/run.py) preserved
  • Standalone fuzz tester (test/fuzz/fuzz.py) preserved
  • C unit tests for symbol table and AST internals (test/unit_tests.c)

Platform Support

Platform Architecture Status
Linux x86_64 Supported
macOS ARM64 (Apple Silicon) Supported
Windows x86_64 Supported (MinGW)

Dependencies

  • LLVM 18-20
  • LLD 18-20
  • Flex 2.6+
  • Bison 3.0+
  • CMake 3.20+

Known Limitations

  • Variable shadowing within the same function scope is not supported
  • Struct field mutation via dot assignment is not supported (use pointers)
  • The ** (power) operator is parsed but not fully implemented in codegen
  • let x: T = value does not enforce type checking on the initializer
  • Generic type inference requires explicit type arguments in some cases
  • ADT constructors with parameters have limited type inference support
  • No garbage collector — manual memory management via std/mem
  • No closures over local variables (explicit error)

Installation

# From source
git clone https://github.com/Mulang-zty/Vix-lang.git
cd Vix-lang
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release --parallel
sudo cmake --install build

# Install dependencies (Linux)
bash src/install.sh

What's Next (v0.2.0 Roadmap)

  • Struct field mutation support
  • Closures with captured variables
  • Pattern matching improvements (guards, nested patterns)
  • Package manager
  • REPL (interactive mode)
  • Language Server Protocol (LSP) implementation
  • Documentation generator
  • Self-hosting compiler (vixc0) completion

vixc-v0.1.0-rc.1

06 May 12:05

Choose a tag to compare

Full Changelog: vixc-v0.1.0-beta...vixc-v0.1.0-rc.1
Implemented a comprehensive type checking system, improving compile-time type safety and enabling earlier detection of type errors.
Optimized type inference and unification algorithms, supporting more complex generics and type constraints.
Enhanced compiler error messages, making them more user-friendly and easier to locate issues.
Improved performance in the code generation phase, resulting in more efficient target code.
Fixed several known bugs, increasing overall stability.
Improved documentation and examples for easier learning and reference.

vixc-v0.1.0-beta

18 Apr 11:55

Choose a tag to compare

This is the first stable version of the Vix language that can be used in real projects. After internal testing iterations in the 0.0.x series, Vix
now has a complete set of core language features.

  1. Generic
  2. Algebraic Data Types (ADT) and Pattern Matching
  3. Optional type
  4. Pointer
  5. extern "C"
  6. lambda
    Acknowledgements
    Vix0.1.0istheresult of thecollectiveeffortsofmanypeople:
    Me: Compiler core implementation, language design, documentation writing
    azhz1107cat: Writing of EBNF
    fexcode: Development and writing of VPM
    みらいの落英:Documentation writing
    Thanks to everyone who has contributed to vix!