Releases: vixlang/Vix-lang
v0.2.8
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
matchcan accept call-like scrutinees in addition to existing identifier and literal forms. - In practice this enables patterns such as
match choose(1) { ... }andmatch peek_char(src, pos) { ... }. - Non-trivial scrutinees are materialized into an internal temporary binding before desugaring to nested
ifchains, preserving existingOptionandResultpattern semantics. - Files:
src/parser/parser.y
Match arms now accept single-line bodies
- Fixed
matchparsing so existing project examples likeSome(v) -> print(v)andNone -> print("none")parse correctly without requiring{ ... }blocks. - This restores compatibility with the established Option/Result/match style already used across
examples/andtests/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/strcatcalls. - 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
vixc0internals 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
vixc0now 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
vixc0prototype:--lex--parser--ast
- Default mode still emits QBE text output.
Lexer implementation now uses Vix Option and match
- Reworked
vixc0/lexer.vixso the implementation itself uses VixOptionandmatchstyle helpers such aspeek_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
TokenStreambased 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
vixc0remains 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.vixto demonstratematch choose(1). - Reworked
examples/match_peek_char.vixas a self-contained demonstration ofmatch peek_char("abc", 1)with bothSomeandNonebranches.
Validation
- Rebuilt
vixcsuccessfully with parser/typecheck/codegen changes. - Verified existing match/Option examples:
examples/option.vixexamples/match_strings.vix
- Verified new call-expression match examples:
examples/match_call_expr.vixexamples/match_peek_char.vix
- Ran Option/Result regression coverage including:
tests/regression/test172.vixtests/regression/test173.vixtests/regression/test153.vixtests/regression/test154.vix
- Built and exercised
vixc0debug modes:--lex--parser--ast- default QBE output path
v0.2.6
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 pointererror when accessing struct fields through&Treference parameters - Root Cause: Code generator did not propagate
pointerElementHintsfor&Tpointer-to-struct parameters, causing member access to fail - Fix: Extended
visitFunctionparameter handling to resolve element types forAST_TYPE_POINTERparameters and register struct types inparamStructTypes - 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 typewhen assigning to struct fields through&Tparameters - Root Cause: Same as above -
pointerElementHintsnot set for reference parameters - Fix: Resolved by the same
pointerElementHintspropagation fix - File:
src/compiler/CodeGen.cpp
Fixed: Undeclared variable in for-loop body with chained indexing
- Bug:
Warning: Use of undeclared variable 'entry'when usinglet 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
getInferredPointerElementTypeto handleTYPEINFO_ARRAYandTYPEINFO_FIXED_ARRAYtypes, and fixedvisitIndexto propagate correct element type hints instead of hardcodedi32 - 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 && ./testproduced 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 usinglet x = x + 1inside 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&i32reference from a function with return typei32 - 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 allowPtr[T]→Tunification on return; added auto-deref invisitReturnandvisitFunction(codegen) to emitloadwhen 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 0when accessingarr[0]afterarr.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
pushoperations - 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 byarr.push(5)stored elements with wrong type (pointer instead of i32) - Root Cause: Code generator did not use
declared_typeannotation 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_assignfor missing left-hand side - Added null checks in
check_unaryopfor 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'sand/or - Fixed
\\n→\nin 6 assertion strings — tests expected literal backslash-n instead of actual newline - Fixed scope tests using bare blocks
{ ... }(unsupported by parser) to useif (true) { ... } - Fixed scope test using immutable
let resultthat was later assigned — changed tolet mut result
Updated test expectations
- CLI version test:
0.2.2→0.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 + 1inside 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/containsHashMap 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 fixsrc/Typeck/Typeck.cpp— Reference auto-deref on returnsrc/compiler/CodeGen.cpp— Reference auto-deref codegen, declared array type registrationsrc/parser/parser.y— Parser ambiguity reductionsrc/test.vix— Updated to produce outputexamples/generics2.vix— Fixed semicolonstests/feat.py— Fixed test bugs, added xfail markers for unimplemented featurestests/cli.py— Updated version expectationtests/regre.py— Updated regression test expectationstests/run_legacy.py— Updated legacy test expectationstests/regression/test225.vix— Reference parameter struct field accesstests/regression/test226.vix— Reference parameter read through&Ttests/regression/test227.vix— Reference parameter mutation through&Ttests/regression/test228.vix— Full HashMap implementation testdocs/RELEASE_v0.2.6.md— This file
v0.2.5
What's Changed
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: Usetype NAME = struct {...}instead.-> typereturn syntax: Use: typeinstead for function return types.
Bug Fixes
Parser & Syntax Fixes
- Fixed
lvalueassignment rule: Replacedlvalueinassignment_statementwithfactor_unary, resolving a fundamental shift/reduce conflict where complex targets likearr[0] = ...would fail. - Fixed chained index assignment:
arr[0][0] = valuesyntax now parses correctly. - Fixed member access assignment:
p.x = valuenow parses correctly throughfactor_unary. - Fixed
type NAME[T] = struct {...}(v0.2.2): Generic struct definitions using thetypekeyword now work correctly. - Fixed
matchforSome/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].1returningEinstead ofTinErrmatch 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 + i32promotion inhash = hash + s[i]). - Chained Index Codegen: Added
computeIndexPtrhelper for correct lvalue pointer calculation in nested indexing. - ADT Hint Propagation (v0.2.2):
pointerElementHintsare now correctly propagated through variables for ADT fields.
Type Checker Fixes
- Numeric Promotion (v0.2.2):
i32literals now automatically promote toi64/usizein function arguments. - Nil Coercion (v0.2.2):
nilcan now be assigned toFixedArrayfields in struct literals. - Return Type Error Location: Points to the actual
returnexpression 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_nodehelper 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.vixand improvedHashMapinsrc/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
- Replace
struct NAME {...}withtype NAME = struct {...}. - Replace
-> typewith: typefor function return types. - Use
!exprinstead ofexpr == false.
v0.2.1
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_assignreturn type: Assignment expressions now correctly returnVoidinstead 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 likestd/io.vix. -
Fixed function type pre-declaration for nested programs: Functions inside nested
PROGRAMnodes (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.vixcompilation: Removed recursive wrapper functions that shadowed extern declarations (e.g.,pub fn fopencalling itself instead of the externfopen). Removed unsupportedusizetype from function signatures (now usesi64). Fixedpanicfunction return type fromi32tovoid.
Example Fixes
All 41 example files now compile successfully:
fib.vix: Addedlet mutfor mutable loop variablesaandbswap.vix: Fixed implicitly void return type handlingstruct2.vix: Moved module-level code intomain()functionstrcmp.vix: Addedlet mutfor loop variable; added missing return afterwhile(1)looparr.vix: Addedletdeclarations for variablesfunction_arg.vix: Fixedf32/f64return type mismatchif.vix: Replacedinput()call with string literal (input returns void)lexer.vix: Replaced&&/||operators withand/orkeywords; usedelifinstead ofelse iflist_op.vix: Replaced unsupportedadd!()syntax with array indexingquicksort.vix: Added complete quicksort implementation (was empty)error_test.vix: Fixed syntax for struct literal inside functionfileio.vix,generics.vix,import_test.vix,import_test2.vix: Fixed import pathsmatch_strings.vix,global.vix: Replacedstrwithstringstring_arr.vix: Moved module-level arrays intomain()functionlambda.vix: Rewrote with function pointer patternnet_test.vix: Removed unavailable net module importpointer.vix: Fixed pointer mutation example (addedlet 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
- Replace all
strtype annotations withstring. - Replace
usizetype annotations withi64(or use the newusizekeyword). - Ensure functions without explicit return types end with void-compatible expressions (not value-returning assignments).
- 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
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
letare automatically global and persistent. - Variables declared at function level with
letare stack-local (as before). - Use
let mutfor 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,-luser32when the bundledlibc/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
- Replace all
globaldeclarations withlet. - Replace all
constandlet constdeclarations withlet. - Replace all
pub globaldeclarations withlet(addpubsupport forletin future releases). - Add
fn main(): i32 { ... return 0 }to any file that previously relied on top-level code execution. - Add
mutto 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
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 ** 10becomes1024)
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_POWwas parsed but never generated LLVM IR — now fully implemented - Power operator const folding:
OP_POWwas 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 (...) {}incheck_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 demoexamples/power.vix— Power operator demo with various exponentiation patternsexamples/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== falseor== 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 --parallelChecksum
Built with LLVM 20.1.2 on Linux x86_64.
v0.1.1
Full Changelog: vixc-v0.1.0...v0.1.1
vixc-v0.1.0
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
typedeclarations - Built-in
Result[T, E]andOption[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/elseconditional expressionswhileloopsfor-inrange loops (for (i in 0 .. n))matchpattern matching with exhaustiveness checkingbreakandcontinuestatements- Compound assignment operators (
+=,-=,*=,/=)
Data Structures
- Struct definitions with field access
- Generic structs (
struct Box:[T] { value: T }) - Nested struct support
- Array/list indexing and
.lengthproperty
Module System
importstatements for module inclusionpubvisibility 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=l0through-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.pyandtests/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 = valuedoes 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.shWhat'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
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
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.
- Generic
- Algebraic Data Types (ADT) and Pattern Matching
- Optional type
- Pointer
- extern "C"
- 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!