DISCLAIMER: This repository is currently under active maintenance. This README serves as a live technical manifest and personal scratchpad for engine development.
Vyne is currently in its early stages but already supports a robust set of core programming constructs, specialized for terminal-based logic and ASCII manipulation.
Vyne features a powerful C-Transpiler that bridges the gap between high-level expressive syntax and low-level machine performance. Instead of compiling to a heavy bytecode or relying solely on an interpreter, Vyne generates human-readable, optimized C99 code.
The transformation process follows a strict pipeline to ensure that the semantic meaning of Vyne logic is preserved while maximizing execution speed:
- AST Flattening: Complex, nested expressions are decomposed into a linear sequence of C statements. This prevents stack-depth issues and allows the C compiler to better optimize register usage.
- Mangled Namespacing: To support Vyne's
groupandinterfacestructures in a flat C namespace, the engine uses a deterministic mangling scheme (e.g.,Master.Element.getName()becomesfn_Master_Element_getName). - Implicit Header Injection: The transpiler automatically links the source with
vyne_runtime.h, a lightweight header providing the coreValuesystem, Arena memory management, and built-in math/graphics operations.
- Zero Overhead Portability: Any system with a C compiler (GCC, Clang, MSVC) can run Vyne code.
- Aggressive Optimization: By transpiling to C, Vyne inherits decades of optimization research embedded in modern C compilers (like loop unrolling and vectorization).
- Embedded Friendly: The resulting binaries are extremely small (starting at 50 KB), making Vyne suitable for resource-constrained environments or as an embedded logic engine for larger C++ projects.
To generate and compile the C source in one command:
# This generates script.vy.c and compiles it to script.exe
vynec --compile ./tests/logic_test.vyRecursive functions are a stress test for any language's call stack and value system. Vyneβs transpiler consistently outperforms its interpreter by nearly 3x in recursion-heavy tasks.
| Execution Mode | Time (ms) | Speed Gain |
|---|---|---|
| AST Interpreter | 54.52 ms | 1.0x (Base) |
| Compiled (GCC -O3) | 20.78 ms | ~2.6x Faster |
To prevent Stack Overflow during deep recursion (like Fibonacci 30+), Vyne's transpiler employs a specialized memory strategy:
- Heap-Based Call Frames: Unlike standard C which uses the limited system stack for function arguments, Vyne's transpiler allocates argument arrays inside the Vyne Arena.
- Flattened Expression Trees: Nested function calls (e.g.,
f(g(x))) are automatically flattened into temporary variables during code generation. This ensures that the C stack only handles function return addresses, while all heavy data resides in the heap. - Arena Block Allocation: Memory is managed in high-speed 8MB blocks, where allocation is a simple pointer increment, ensuring zero overhead during recursive calls.
| Feature | Syntax Example | Description |
|---|---|---|
| Arithmetic | (+, -, *, /, <, >, ==) |
Standard mathematical and comparison operators. |
| Bitwise | (&&, ||) |
Low-level bit manipulation for flags and binary data. |
| Functions | fn calculate(x) { ... } |
Defined using the fn keyword with scoped arguments. |
| Logic Flow | if cond { ... } |
Standard conditional branching. |
| Loops | while cond { ... } |
Standard iteration for repeated execution logic. |
| Scoping | group Graphics { ... } |
Encapsulate logic and variables into named namespaces. |
| Modules | module vcore |
Interfaces with native C++ libraries and system resources. |
Vyne employs a hybrid type system that supports both Explicit Declaration and Inferred Typing. This allows for flexible scripting while maintaining the safety required for complex logic.
| Mode | Syntax Example | Description |
|---|---|---|
| Inferred | score = 95 |
Type is determined at runtime based on the assigned value. |
| Explicit | age :: Int64 = 30 |
The variable is "locked" to a specific type; future assignments must match. |
| Constant | const PI :: Float64 = 3.14 |
Immutable binding. Reassignment attempts will trigger a Runtime Error. |
Vyne recognizes the following core types during explicit declaration:
Int64: Signed 64-bit integer. Used for indexing, pointers, and discrete counts.Float64: 64-bit double-precision floating point. Used for ML, DSP, and physics.String: UTF-8 encoded character sequences.Boolean: Logicaltrueorfalse.Array: Dynamic list ofValueobjects.
To ensure engine stability, the following rules are enforced:
[ Note: Type Mismatch ] If a variable is declared as
val :: Int64, assigning aStringto it later will result in aType Error.
[ Note: Constant Protection ] Constants must be initialized at the moment of declaration. Once set, they are read-only for the duration of the program execution.
Vyne leverages native C++ modules to handle high-performance tasks that the interpreter shouldn't do alone.
- π‘ vcore System-level utilities, sleep timers, and process management.
- π¨ vglib Vyneβs high-performance Graphics & Audio Engine. Features hardware-accelerated 3D rendering (Z-buffer), spatial audio pipelines, and native hardware input mapping.
- π§ vmem Memory management and introspection β track heap usage, inspect raw memory addresses, and monitor variable footprints.
- π§ͺ vmath A comprehensive wrapper for the C++ standard math library, featuring trigonometric functions, hyperbolic operations, and mathematical constants like
$\pi$ and$\phi$ .
Vyne uses interface definitions to create structured data types. Unlike traditional interfaces, Vyne interfaces act as Constructors and can contain Methods with access to the instance via the self keyword.
| Component | Syntax Example | Description |
|---|---|---|
| Fields | row :: Int64 |
Explicitly typed data members. |
| Methods | magnitude() { ... } |
Functions defined inside the interface scope. |
| Self-Ref | self.x |
Accesses the current instance's fields or other methods. |
| Namespacing | group Types :: mod { ... } |
Interfaces can be nested inside groups for strict organizational hierarchy. |
Interfaces are instantiated using the type name as a constructor. Methods are invoked using dot notation.
use extern "vlinalg.vy";
Parameters are mapped positionally to the interface fields
pos :: vlinalg.Types.Vector = vlinalg.Types.Vector(10, 20);
Methods have internal access to fields via 'self'
m = pos.magnitude();
Methods can accept other instances as typed parameters
other_pos = vlinalg.Types.Vector(5, 5);
cp = pos.cross_product(other_pos);
Every struct instance in Vyne supports built-in reflection to assist with debugging and dynamic logic:
obj.fields(): Returns anArrayof strings containing all defined field names.out(obj): Native string representation showing the internal state:Vector { x: 10, y: 20 }.- Member Assignment: Supports direct updates to fields, e.g.,
pos.x = 50.
- Constructor Hook: When the
FunctionCallNodeidentifies a target name residing in theInterfaceTablerather than theFunctionTable, it triggers an automatic allocation of aVyneInstance. - Symbol Mapping: Arguments passed to the constructor are mapped positionally to the fields defined in the
InterfaceNode. selfBinding: During a method call, the interpreter injects aselfsymbol into the localSymbolContainerscope, pointing back to the caller's memory address.- Recursive Resolution: The parser and interpreter support deep pathing for types (e.g.,
Module.Group.Interface) to ensure clear encapsulation.
out(x) # Print to terminal
type(x) # Returns "Float64", "String", "Array", or "Function"
sizeof(x) # Get length of strings or count of array elements
string(x) # Convert any data type to string
int64(x) # Convert any data type to Int64
float64(x) # Convert any data type to Float64
sequence(x, y) # Generates a sequence ( array ) in given range of numbersArrays in Vyne are dynamic and come with built-in methods for data manipulation:
arr.push(val)/arr.pop()β Stack operations.arr.delete(val)β Remove specific elements.arr.sort()β In-place numeric sorting.arr.reverse()β Flip array order.arr.place_all(val, count)β Bulk initialize an array.arr.clear()β Wipe all data from the instance.
To build the interpreter from source, clone the repository and compile using your preferred C++ compiler:
git clone https://github.com/tuncaygafarli/vyne.git
cd vyne
makeVyne's engine architecture is fully documented using Doxygen. This allows you to explore the interpreter's internals through a searchable web interface, complete with class diagrams and function call graphs.
To build the documentation locally, ensure you have Doxygen and Graphviz installed, then run:
doxygen DoxyfileOnce the process finishes, open the following file in your browser:
vyne-docs/html/index.html
The documentation provides several powerful ways to understand how Vyne works:
-
Abstract Syntax Tree (AST) Hierarchy: Navigate to
Classes -> Class Hierarchy. This visualizes how every language feature (likeWhileNode,BinOpNode, orFunctionNode) inherits from the baseASTNode. -
Collaboration Diagrams: Each class page features a diagram showing which other objects it depends on. For example, you can see how an
AssignmentNodeinteracts with theSymbolContainer. -
Function Call Graphs: Every
evaluate()method includes a flowchart showing which sub-functions are called during execution. This is extremely helpful for tracing how the interpreter processes complex Vyne scripts. -
Native Module Bindings: Explore the
modulesnamespace to see the C++ implementation ofvglib(the donut renderer) andvcore. You can view the raw C++ math directly alongside the documentation.
vyne/compiler: The Lexer and Parser that turn source code into an AST.vyne/core: The main execution engine and theValuesystem.vyne/modules: Native C++ extensions that provide high-performance features to the language.