go-mix

module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 12, 2026 License: MIT

README ΒΆ

πŸš€ Go-Mix Programming Language

Go-Mix Logo

Go Version Build Status

Go-Mix is a high-performance, interpreted programming language implemented in Go. It combines dynamic typing with static safety features, lexical closures, and a comprehensive standard libraryβ€”perfect for prototyping, education, and embedding as a scripting layer in Go applications.


Table of Contents


πŸš€ Quick Start

Installation

Prerequisites: Go 1.18 or higher

git clone https://github.com/akashmaji946/go-mix.git
cd go-mix
sudo ./install.sh

This builds and installs go-mix to /usr/local/bin, making it accessible from anywhere on your system. See INSTALL.md for detailed instructions.

This generates the go-mix executable in the current directory (local use only).

Usage

Display Version:

go-mix --version    # or go-mix -v
Go-Mix version v1.0.0
License: MIT
Author: akashmaji(@iisc.ac.in)

Display Help:

go-mix --help       # or go-mix -h

Interactive REPL (Read-Eval-Print Loop):

go-mix

This launches an interactive session where you can type Go-Mix code line-by-line:

Go-Mix >>> var x = 42
Go-Mix >>> println(x)
42
Go-Mix >>> /help
/exit    - Exit the REPL
/scope   - Show current scope and variables
Go-Mix >>> 

Run a Program File:

go-mix samples/algo/05_factorial.gm
go-mix path/to/your/script.gm
Option 2: Manual Build
git clone https://github.com/akashmaji946/go-mix.git
cd go-mix
./build.sh

Run Tests:

go test ./...           # All tests
go test ./lexer -v      # Verbose
go test -coverage       # With coverage report
Option 3: Docker installation

Manual Installation: Refer DOCKER.MD for detailed instructions.

DockerHub Installation

docker pull akashmaji946/go-mix:latest

πŸ“š Core Architecture

1. Pratt Parser (Top-Down Operator Precedence)

Go-Mix uses a sophisticated Pratt Parser for expression parsing. Rather than relying on traditional recursive descent, the algorithm associates parsing logic directly with tokens and their precedence levels. This approach enables elegant handling of:

  • Complex operator hierarchies β€” bitwise vs. arithmetic operators
  • Member access β€” nested object property access (obj.field.nested)
  • Function calls β€” argument parsing with proper precedence
  • Extensibility β€” new operators can be added with minimal code changes
2. Hybrid Type System

Go-Mix implements three distinct variable kinds, each with different semantics:

var x = 42;          // Dynamic: type can change at runtime
let y = 3.14;        // Static: type-locked after first assignment
const PI = 3.14159;  // Immutable: cannot be reassigned

Dynamic Variables (var):

  • Type can change during execution
  • Ideal for rapid prototyping and flexible code
  • Behavior similar to Python or JavaScript

Static Variables (let):

  • Type is locked on first assignment
  • Provides safety without explicit type annotations
  • Prevents accidental type changes

Immutable Constants (const):

  • Cannot be reassigned after initial binding
  • Useful for configuration values and constants
  • Provides compile-time and runtime safety
3. Lexical Scoping & Closures

Functions are first-class citizens with full support for lexical closures:

fn makeCounter(start) {
    var count = start;
    fn increment() { 
        count = count + 1; 
        return count; 
    }
    return increment;
}

var counter = makeCounter(0);
println(counter()); // 1
println(counter()); // 2
println(counter()); // 3

// Each counter maintains its own 'count' variable
var counter2 = makeCounter(100);
println(counter2()); // 101

Variables are captured by reference in closures, allowing stateful function objects.


🎯 Language Features

Data Types

Go-Mix supports six primitive types plus nil:

Type Example Size Notes
int 42, 0xFF, 0o77 64-bit Signed integers; hex (0x) and octal (0o) support
float 3.14, 1.2e3, 1e-5 64-bit IEEE-754 double precision
bool true, false 1-bit Boolean logic values
string "Hello", "Line1\nLine2" Variable UTF-8 strings with escape sequences
char 'A', '\n', '\t' 32-bit Single Unicode character
nil nil Pointer-size Represents absence of value

Type Conversion Examples:

var s = "42";
var n = tostring(123);      // "123"
var i = 42;
var f = 42.0;               // Auto-conversion in numeric context

// Type checking
typeof(42);                 // "int"
typeof(3.14);              // "float"
typeof("text");            // "string"
typeof(true);              // "bool"
typeof(nil);               // "nil"
Variables & Scoping
Declaration & Assignment
// Variable declaration
var x = 10;
var y = "hello";
var z;                     // Uninitialized (nil)

// Static variables (type-locked)
let count = 0;
count = count + 1;         // OK
count = "text";            // ERROR: type mismatch

// Constant values
const MAX_SIZE = 100;
const PI = 3.14159;
MAX_SIZE = 200;            // ERROR: constants are immutable

// Multiple declaration (comma-separated)
var a = 1, b = 2, c = 3;
Scoping Rules

Go-Mix implements lexical (static) scoping with proper block-level scope:

var x = "global";

fn testScope() {
    var x = "function";     // Shadows outer x
    println(x);             // "function"
    
    if (true) {
        var x = "block";    // Shadows function-level x
        println(x);         // "block"
    }
    
    println(x);             // "function" (block x is gone)
}

println(x);                 // "global"

Control Flow & Iteration

Conditionals
If-Else Statements
if (age >= 18) {
    println("Adult");
} else if (age >= 13) {
    println("Teenager");
} else {
    println("Child");
}

// Ternary operator (via if-else)
var status = if (x > 0) { "positive"; } else { "non-positive"; };
Boolean Logic (Short-Circuit Evaluation)
var x = 5;

// AND operator (&&) - short circuits if first operand is false
if (x > 0 && x < 10) {
    println("Between 0 and 10");
}

// OR operator (||) - short circuits if first operand is true
if (x < 0 || x > 100) {
    println("Outside range");
}

// NOT operator (!)
if (!isError) {
    println("Success");
}

// Compound conditions
if ((x > 0 && x < 10) || (x > 100 && x < 110)) {
    println("Valid");
}
Loops
C-Style For Loop
// Standard for loop
for (var i = 0; i < 5; i = i + 1) {
    println(i);  // 0, 1, 2, 3, 4
}

// With break and continue
for (var i = 0; i < 10; i = i + 1) {
    if (i == 3) { continue; }    // Skip iteration
    if (i == 7) { break; }       // Exit loop
    println(i);
}

// Nested loops
for (var i = 0; i < 3; i = i + 1) {
    for (var j = 0; j < 3; j = j + 1) {
        println(i, j);
    }
}
While Loop
var count = 0;
while (count < 5) {
    println(count);
    count = count + 1;
}

// Multiple conditions
var x = 10, y = 0;
while (x > 0, y < 10) {
    x = x - 1;
    y = y + 1;
}

// Infinite loop with break
var i = 0;
while (true) {
    if (i >= 100) { break; }
    i = i + 1;
}
Range Iteration (Foreach)
// Range iteration (inclusive)
foreach i in 1...5 {      // 1, 2, 3, 4, 5
    println(i);
}

// Reverse range
foreach i in 5...1 {      // 5, 4, 3, 2, 1
    println(i);
}

// Array iteration with value
var arr = [10, 20, 30];
foreach val in arr {
    println(val);
}

// Array iteration with index and value
foreach idx, val in arr {
    println(idx, val);    // 0, 10; 1, 20; 2, 30
}

Collections & Data Structures

Arrays (Mutable Sequences)
// Array literals
var empty = [];
var numbers = [1, 2, 3, 4, 5];
var mixed = [1, "hello", true, 3.14];
var nested = [[1, 2], [3, 4], [5, 6]];

// Array indexing (0-based)
var arr = [10, 20, 30, 40, 50];
println(arr[0]);           // 10 (first element)
println(arr[2]);           // 30 (third element)

// Negative indexing (Python-style)
println(arr[-1]);          // 50 (last element)
println(arr[-2]);          // 40 (second-to-last)

// Index assignment
arr[1] = 25;               // [10, 25, 30, 40, 50]
arr[-1] = 55;              // [10, 25, 30, 40, 55]

// Array length
println(length(arr));      // 5
println(size(arr));        // 5 (alias)

// Array methods
push(arr, 60);             // Add to end: [10, 25, 30, 40, 55, 60]
pop(arr);                  // Remove from end: [10, 25, 30, 40, 55]
unshift(arr, 5);           // Add to start: [5, 10, 25, 30, 40, 55]
shift(arr);                // Remove from start: [10, 25, 30, 40, 55]
Maps (Dictionaries)
// Map literals (string keys only)
var user = map{
    "name": "Alice",
    "age": 30,
    "city": "New York"
};

// Key access
println(user["name"]);     // "Alice"
println(user["age"]);      // 30

// Adding/updating keys
user["email"] = "alice@example.com";
user["age"] = 31;

// Checking keys (error if missing)
// Note: accessing non-existent key returns nil or error

// Map methods
println(length(user));     // Number of key-value pairs
Lists (Heterogeneous)
// Lists are explicitly mutable sequences
var list = list(1, "two", 3.0, true, nil);

// Access like arrays
println(list[0]);          // 1
println(list[1]);          // "two"

// Different from arrays in type flexibility
var mixed_array = [1, 2, 3];  // Homogeneous
var mixed_list = list(1, "2", 3.0);  // Heterogeneous
Tuples (Immutable Sequences)
// Tuples are fixed-size, immutable
var coords = tuple(10, 20);
var rgb = tuple(255, 128, 64);
var data = tuple("John", 25, true);

// Access like arrays
println(coords[0]);        // 10
println(coords[1]);        // 20

// Immutable - cannot be modified
coords[0] = 15;            // ERROR
Sets (Unique Values)
// Sets contain unique values
var primes = set{2, 3, 5, 7, 11};
var colors = set{"red", "green", "blue"};
var numbers = set{1, 2, 2, 3, 3, 3};  // Results in {1, 2, 3}

// Checking membership
// Note: Set operations depend on implementation

println(length(primes));   // 5

Functions & Higher-Order Programming

Function Definitions
// Basic function
fn greet(name) {
    return "Hello, " + name;
}

println(greet("Alice"));   // "Hello, Alice"

// Function with multiple parameters
fn add(a, b) {
    return a + b;
}

println(add(3, 5));        // 8

// Function with no return (returns nil)
fn printInfo(x) {
    println("Value: " + x);
}

// Recursive function
fn factorial(n) {
    if (n <= 1) { return 1; }
    return n * factorial(n - 1);
}

println(factorial(5));     // 120
Function Expressions (Lambda)
// Anonymous functions assigned to variables
var double = fn(x) { return x * 2; };
println(double(5));        // 10

var add = fn(a, b) { return a + b; };
println(add(3, 4));        // 7

// Nested function definitions
var makeMultiplier = fn(factor) {
    return fn(x) { return x * factor; };
};

var times5 = makeMultiplier(5);
println(times5(3));        // 15
println(times5(7));        // 35
Higher-Order Functions (Functional Programming)
Map
// Apply function to each element
var nums = [1, 2, 3, 4, 5];
var doubled = map(nums, fn(x) { return x * 2; });
println(doubled);          // [2, 4, 6, 8, 10]

var squared = map(nums, fn(x) { return x * x; });
println(squared);          // [1, 4, 9, 16, 25]
Filter
// Keep elements that satisfy predicate
var numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var evens = filter(numbers, fn(x) { return x % 2 == 0; });
println(evens);            // [2, 4, 6, 8, 10]

var bigNums = filter(numbers, fn(x) { return x > 5; });
println(bigNums);          // [6, 7, 8, 9, 10]
Reduce
// Accumulate value across array
var nums = [1, 2, 3, 4, 5];

// Sum
var sum = reduce(nums, fn(acc, x) { return acc + x; }, 0);
println(sum);              // 15

// Product
var product = reduce(nums, fn(acc, x) { return acc * x; }, 1);
println(product);          // 120

// Building a string
var str = reduce(nums, fn(acc, x) { return acc + x; }, "");
println(str);              // "12345"
Find, Some, Every
var nums = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

// Find first matching element
var first_even = find(nums, fn(x) { return x % 2 == 0; });
println(first_even);       // 2

// Check if at least one element matches
var has_negative = some(nums, fn(x) { return x < 0; });
println(has_negative);     // false

var has_five = some(nums, fn(x) { return x == 5; });
println(has_five);         // true

// Check if all elements match
var all_positive = every(nums, fn(x) { return x > 0; });
println(all_positive);     // true

var all_even = every(nums, fn(x) { return x % 2 == 0; });
println(all_even);         // false
Sorting with Custom Comparators
var nums = [3, 1, 4, 1, 5, 9, 2, 6];

// In-place sort with default ordering
sort(nums);                // [1, 1, 2, 3, 4, 5, 6, 9]

// New sorted array (non-mutating)
var sorted = sorted(nums);

// Custom sort (descending)
csort(nums, fn(a, b) { 
    if (a > b) { return -1; }
    if (a < b) { return 1; }
    return 0;
});

// Sort strings by length
var words = ["apple", "pi", "banana", "cat"];
csort(words, fn(a, b) {
    var len_a = length(a);
    var len_b = length(b);
    if (len_a < len_b) { return -1; }
    if (len_a > len_b) { return 1; }
    return 0;
});

Object-Oriented Programming

Struct Definition & Methods
struct Circle {
    var radius = 0;

    // Constructor
    fn init(r) {
        this.radius = r;
    }

    // Instance methods
    fn area() {
        return 3.14159 * this.radius * this.radius;
    }

    fn circumference() {
        return 2 * 3.14159 * this.radius;
    }

    fn scale(factor) {
        this.radius = this.radius * factor;
        return this;  // Method chaining
    }

    fn toString() {
        return "Circle(radius=" + this.radius + ")";
    }
}

// Creating instances
var c = new Circle(5);
println(c.area());         // 78.53975
println(c.circumference()); // 31.4159

// Method chaining
c.scale(2).scale(2);       // radius becomes 20
Complex OOP Example
struct BankAccount {
    var balance = 0;
    var owner = "Unknown";

    fn init(owner, initial) {
        this.owner = owner;
        this.balance = initial;
    }

    fn deposit(amount) {
        if (amount <= 0) {
            panic("Deposit amount must be positive");
        }
        this.balance = this.balance + amount;
        return this.balance;
    }

    fn withdraw(amount) {
        if (amount > this.balance) {
            panic("Insufficient funds");
        }
        this.balance = this.balance - amount;
        return this.balance;
    }

    fn getBalance() {
        return this.balance;
    }

    fn getInfo() {
        return this.owner + " has $" + this.balance;
    }
}

var account = new BankAccount("Alice", 1000);
account.deposit(500);      // 1500
account.withdraw(200);     // 1300
println(account.getInfo()); // Alice has $1300

πŸ“– Standard Library & Builtins

Common Functions
Function Parameters Returns Description
print(...) Variable nil Output without newline
println(...) Variable nil Output with newline
printf(fmt, ...) String + args nil Formatted output (%d, %s, %f, %x)
length(obj) Array/String/Map int Length of collection
size(obj) Array/String/Map int Alias for length
typeof(obj) Any string Type name
tostring(obj) Any string String conversion
panic(msg) String error Raise runtime error
assert(cond, msg) Bool, String nil Assert condition
String Methods
Function Parameters Returns Example
upper(str) string string upper("hello") β†’ "HELLO"
lower(str) string string lower("HELLO") β†’ "hello"
trim(str) string string trim(" text ") β†’ "text"
ltrim(str) string string ltrim(" text") β†’ "text"
rtrim(str) string string rtrim("text ") β†’ "text"
split(str, sep) string, string array split("a,b,c", ",") β†’ ["a","b","c"]
join(arr, sep) array, string string join(["a","b","c"], ",") β†’ "a,b,c"
contains(str, sub) string, string bool contains("hello", "ell") β†’ true
starts_with(str, prefix) string, string bool starts_with("hello", "he") β†’ true
ends_with(str, suffix) string, string bool ends_with("hello", "lo") β†’ true
index(str, sub) string, string int index("hello", "ll") β†’ 2
substring(str, start, end) string, int, int string substring("hello", 1, 4) β†’ "ell"
replace(str, old, new) string, string, string string replace("hello", "l", "L") β†’ "heLLo"
reverse(str) string string reverse("hello") β†’ "olleh"
capitalize(str) string string capitalize("hello") β†’ "Hello"
ord(char) char int ord('A') β†’ 65
chr(code) int char chr(65) β†’ 'A'
count(str, sub) string, string int count("hello", "l") β†’ 2
is_digit(str) string bool is_digit("123") β†’ true
is_alpha(str) string bool is_alpha("abc") β†’ true

String Examples:

var text = "  Hello, World!  ";
println(upper(text));           // "  HELLO, WORLD!  "
println(trim(text));            // "Hello, World!"
println(split(text, ","));      // ["  Hello", " World!  "]
println(contains(text, "World")); // true
println(substring(text, 2, 7)); // "Hello"
Array Methods
Function Parameters Returns Description
push(arr, elem) array, any array Add to end
pop(arr) array any Remove & return last
shift(arr) array any Remove & return first
unshift(arr, elem) array, any array Add to beginning
sort(arr) array array In-place sort
sorted(arr) array array New sorted array
reverse(arr) array array Reverse array
clone_array(arr) array array Shallow copy
array(iterable) any array Convert to array

Array Examples:

var arr = [3, 1, 4, 1, 5, 9];

push(arr, 2);               // [3, 1, 4, 1, 5, 9, 2]
pop(arr);                   // [3, 1, 4, 1, 5, 9]
unshift(arr, 0);            // [0, 3, 1, 4, 1, 5, 9]
shift(arr);                 // [3, 1, 4, 1, 5, 9]

sorted(arr);                // [1, 1, 3, 4, 5, 9]
reverse([1, 2, 3]);         // [3, 2, 1]
clone_array(arr);           // Copy of arr
Math Functions
Function Parameters Returns Example
abs(n) number number abs(-42) β†’ 42
min(...args) numbers number min(3, 1, 4) β†’ 1
max(...args) numbers number max(3, 1, 4) β†’ 4
floor(n) float int floor(3.7) β†’ 3
ceil(n) float int ceil(3.2) β†’ 4
round(n) float int round(3.5) β†’ 4
sqrt(n) number float sqrt(16) β†’ 4.0
pow(base, exp) number, number number pow(2, 8) β†’ 256
sin(rad) float float Sine function
cos(rad) float float Cosine function
tan(rad) float float Tangent function
log(n) number float Natural logarithm
log10(n) number float Base-10 logarithm
exp(n) number float e^n
rand() none float Random [0.0, 1.0)
rand_int(min, max) int, int int Random in range

Math Examples:

println(abs(-42));          // 42
println(min(5, 3, 9, 1));   // 1
println(max(5, 3, 9, 1));   // 9
println(floor(3.9));        // 3
println(ceil(3.1));         // 4
println(sqrt(16));          // 4.0
println(pow(2, 10));        // 1024

var random = rand();        // 0.0 to 1.0
var dice = rand_int(1, 6);  // 1 to 6
File I/O
// Writing to file
var file = fopen("output.txt", "w");  // Write mode
fwrite(file, "Hello, ");
fwrite(file, "World!\n");
fclose(file);

// Reading from file
var file = fopen("output.txt", "r");  // Read mode
var content = fread(file, 1024);      // Read up to 1024 bytes
fclose(file);
println(content);           // "Hello, World!"

// Appending to file
var file = fopen("log.txt", "a");     // Append mode
fwrite(file, "Log entry\n");
fclose(file);

// File operations
var exists = file_exists("data.txt");
var deleted = file_delete("temp.txt");
var renamed = file_rename("old.txt", "new.txt");

// Get file size
var size = file_size("data.txt");
System & Environment
// Environment variables
var home = getenv("HOME");
var path = getenv("PATH");
setenv("DEBUG", "true");
setenv("LOG_LEVEL", "info");

// Process information
var pid = getpid();         // Process ID
var user = user();          // Current user
println("PID: " + pid);
println("User: " + user);

// Shell commands (execute external programs)
var output = exec("echo", "Hello from shell");
var result = exec("ls", "-la");

// Time functions
var now_sec = now();        // Unix timestamp (seconds)
var now_ms = now_ms();      // Unix timestamp (milliseconds)
sleep(1000);                // Sleep for 1000 milliseconds

// Time formatting
var timestamp = now();
var formatted = format_time(timestamp, "2006-01-02 15:04:05");
println(formatted);         // "2024-02-11 10:30:45"
JSON Handling
// Create data structure
var user = map{
    "id": 123,
    "name": "Alice",
    "email": "alice@example.com",
    "tags": ["admin", "developer"],
    "active": true
};

// Encode to JSON
var json_string = json_encode(user);
println(json_string);
// {"id":123,"name":"Alice","email":"alice@example.com","tags":["admin","developer"],"active":true}

// Decode from JSON
var decoded = json_string_decode_map(json_string);
println(decoded["name"]);   // "Alice"
println(decoded["tags"][0]); // "admin"

// Nested structures
var data = map{
    "users": [
        map{"name": "Alice", "age": 30},
        map{"name": "Bob", "age": 25}
    ],
    "total": 2
};

var json = json_encode(data);
var parsed = json_string_decode_map(json);
Type & Debugging Functions
var x = 42;
var arr = [1, 2, 3];
var user = map{"name": "Alice"};

// Type information
typeof(x);                  // "int"
typeof(arr);                // "array"
typeof(user);               // "map"
typeof(fn(){ });            // "func"
typeof(nil);                // "nil"

// Memory inspection
var addr_x = addr(x);       // Memory address as integer
var addr_arr = addr(arr);

// Reference checking (useful for shallow/deep copy distinction)
var y = arr;                // Shallow copy (same reference)
var z = clone_array(arr);   // Deep copy (different reference)

is_same_ref(arr, y);        // true (same reference)
is_same_ref(arr, z);        // false (different reference)

Error Handling

Panic & Recovery
// Panic terminates execution with error message
fn divide(a, b) {
    if (b == 0) {
        panic("Division by zero!");
    }
    return a / b;
}

// In normal execution:
println(divide(10, 2));     // 5
println(divide(10, 0));     // Panics with error
Type Safety
// Static variables prevent type errors
let count = 0;
count = count + 1;          // OK
count = "text";             // ERROR at runtime

// Dynamic variables allow flexibility
var data = 42;
data = "text";              // OK - type changed
data = [1, 2, 3];          // OK - type changed again
Error Objects
// Some functions return error objects
var result = someOperation();
if (result.GetType() == "error") {
    println("Error: " + result.ToString());
}

πŸŽ“ Sample Programs

The samples/ directory contains 200+ example programs organized by topic:

Algorithms (samples/algo/)
  • 01_linear_search.gm β€” Sequential search in array
  • 02_binary_search.gm β€” Logarithmic search in sorted array
  • 03_insertion_sort.gm β€” Insertion sort algorithm
  • 04_selection_sort.gm β€” Selection sort algorithm
  • 05_factorial.gm β€” Factorial (recursive and iterative)
  • 06_fibonacci.gm β€” Fibonacci sequence (multiple approaches)
  • 07_gcd.gm β€” Greatest common divisor
  • 08_prime_check.gm β€” Prime number checking
  • 09_bubble_sort.gm β€” Bubble sort implementation
  • 10_heap_sort.gm β€” Heap sort algorithm

Run any sample:

./go-mix samples/algo/05_factorial.gm
Arrays & Collections (samples/arrays/, samples/maps/, samples/lists/)
  • arrays/01_test_array_features.gm β€” Array operations and methods
  • maps/01_test_map_operations.gm β€” Dictionary/map examples
  • lists/01_test_list_features.gm β€” List manipulation
Strings & Formatting (samples/strings/, samples/format/)
  • strings/01_test_string_operations.gm β€” String manipulation examples
  • format/01_sprintf_demo.gm β€” String formatting with printf
File I/O & System (samples/files/, samples/os/)
  • files/04_file_basics.gm β€” File reading and writing
  • os/01_environment_demo.gm β€” Environment variables and process info
Objects & Structs (samples/structs/)

Examples demonstrating object-oriented programming with structs and methods.


Development & Contributing

Building from Source

Manual Build:

cd /path/to/go-mix
go build -o go-mix ./main

With Script:

./build.sh
Running Tests
# All tests
go test ./...

# Specific package
go test ./lexer
go test ./parser
go test ./eval

# Verbose output
go test -v ./...

# Coverage report
go test -coverage ./...

# Run with filtering
go test -run TestName ./package
Project Directory Structure
go-mix/
β”œβ”€β”€ main/                  # REPL & File Execution Entry Point
β”‚   β”œβ”€β”€ main.go           # Main interpreter logic (REPL & file execution modes)
β”‚   β”œβ”€β”€ print_visitor.go  # AST printing utilities for debugging
β”‚   └── main_test.go      # Main function tests
β”‚
β”œβ”€β”€ lexer/                 # Lexical Analysis (Source β†’ Tokens)
β”‚   β”œβ”€β”€ lexer.go          # Core lexer implementation, tokenization logic
β”‚   β”œβ”€β”€ token.go          # Token type definitions and constants
β”‚   β”œβ”€β”€ lexer_utils.go    # Helper functions for lexing
β”‚   └── lexer_test.go     # Lexer unit tests
β”‚
β”œβ”€β”€ parser/                # Parsing & AST (Tokens β†’ Abstract Syntax Tree)
β”‚   β”œβ”€β”€ parser.go         # Pratt parser main implementation
β”‚   β”œβ”€β”€ parser_expressions.go   # Expression parsing logic
β”‚   β”œβ”€β”€ parser_precedence.go    # Operator precedence definitions
β”‚   β”œβ”€β”€ node.go           # AST node structures (all node types)
β”‚   β”œβ”€β”€ test_visitor.go   # AST visitor for testing
β”‚   └── parser_test.go    # Parser unit tests
β”‚
β”œβ”€β”€ eval/                  # Evaluation Engine (AST β†’ Execution)
β”‚   β”œβ”€β”€ evaluator.go      # Core evaluator & runtime state management
β”‚   β”œβ”€β”€ evaluator_expressions.go  # Expression evaluation logic
β”‚   β”œβ”€β”€ evaluator_helpers.go      # Helper utilities for evaluation
β”‚   └── evaluator_test.go # Evaluator unit tests
β”‚
β”œβ”€β”€ repl/                  # Interactive REPL Loop
β”‚   └── repl.go           # Read-Eval-Print-Loop implementation
β”‚
β”œβ”€β”€ std/                   # Standard Library & Builtins
β”‚   β”œβ”€β”€ builtins.go       # Builtin function registry and interface
β”‚   β”œβ”€β”€ common.go         # Common utilities (print, println, length, typeof, etc.)
β”‚   β”œβ”€β”€ arrays.go         # Array manipulation (push, pop, slice, map, filter, reduce, sort, etc.)
β”‚   β”œβ”€β”€ list.go           # List operations (heterogeneous mutable sequences)
β”‚   β”œβ”€β”€ tuple.go          # Tuple operations (fixed immutable sequences)
β”‚   β”œβ”€β”€ map.go            # Map/Dictionary operations (key-value pairs)
β”‚   β”œβ”€β”€ set.go            # Set operations (unique value collections)
β”‚   β”œβ”€β”€ strings.go        # String utilities (upper, lower, split, join, substring, etc.)
β”‚   β”œβ”€β”€ math.go           # Mathematical functions (abs, sqrt, pow, floor, ceil, min, max, etc.)
β”‚   β”œβ”€β”€ file_io.go        # File operations (fopen, fwrite, fread, fclose, file_exists, etc.)
β”‚   β”œβ”€β”€ io.go             # Input/output utilities (scanf, input from stdin)
β”‚   β”œβ”€β”€ os.go             # OS interactions (getenv, setenv, exec, getpid, sleep, user, etc.)
β”‚   β”œβ”€β”€ time.go           # Time handling (now, now_ms, format_time, sleep, etc.)
β”‚   β”œβ”€β”€ format.go         # Type conversion & formatting (sprintf, json_encode, etc.)
β”‚   β”œβ”€β”€ struct.go         # Struct/object utilities
β”‚   └── types.go          # Type system utilities
β”‚
β”œβ”€β”€ file/                  # Stateful File I/O Handles
β”‚   └── file.go           # File object implementation (file handles for advanced I/O)
β”‚
β”œβ”€β”€ scope/                 # Lexical Scoping & Variable Management
β”‚   └── scope.go          # Scope management, variable binding, environment handling
β”‚
β”œβ”€β”€ function/              # Function Objects & Closures
β”‚   └── function.go       # Function representation, closure implementation
β”‚
β”œβ”€β”€ samples/               # Example Programs (50+ .gm files)
β”‚   β”œβ”€β”€ algo/             # Algorithms & Data Structures (50 examples)
β”‚   β”‚
β”‚   β”œβ”€β”€ arrays/           # Array Operations & Features (11 examples)
β”‚   β”‚
β”‚   β”œβ”€β”€ functions/        # Function Examples (14 examples)
β”‚   β”‚
β”‚   β”œβ”€β”€ loops/            # Loop Constructs (20 examples)
β”‚   β”‚
β”‚   β”œβ”€β”€ maps/             # Map/Dictionary Operations (8 examples)
β”‚   β”‚
β”‚   β”œβ”€β”€ lists/            # List Operations (7 examples)
β”‚   β”‚
β”‚   β”œβ”€β”€ sets/             # Set Operations (4 examples)
β”‚   β”‚
β”‚   β”œβ”€β”€ tuples/           # Tuple Operations (6 examples)
β”‚   β”‚
β”‚   β”œβ”€β”€ strings/          # String Manipulation (5 examples)
β”‚   β”‚
β”‚   β”œβ”€β”€ format/           # Formatting Examples (5 examples)
β”‚   β”‚
β”‚   β”œβ”€β”€ files/            # File I/O Examples (10 examples + test files)
β”‚   β”‚
β”‚   β”œβ”€β”€ structs/          # Object-Oriented Examples (40 examples)
β”‚   β”‚
β”‚   β”œβ”€β”€ os/               # OS & Environment Examples (5 examples)
β”‚   β”‚
β”‚   β”œβ”€β”€ time/             # Time Handling Examples (5 examples)
β”‚   β”‚
β”‚   β”œβ”€β”€ range/            # Range Iteration Examples (7 examples)
β”‚   β”‚
β”‚   └── typeof/           # Type Checking Examples (3 examples)
β”‚
β”œβ”€β”€ go.mod                 # Go module definition (github.com/akashmaji946/go-mix)
β”œβ”€β”€ go.sum                 # Go dependencies lock file
β”œβ”€β”€ build.sh              # Build script (runs tests + compiles binary)
β”œβ”€β”€ run.sh                # Test + Executable runner script
β”œβ”€β”€ LICENSE               # MIT License
β”œβ”€β”€ logo.PNG              # Project logo
β”œβ”€β”€ README.md             # This comprehensive documentation
└── PROJECT_STRUCTURE.md  # Detailed project structure documentation
Key Module Responsibilities

Lexer Package (lexer/)

  • Converts source code characters into tokens
  • Handles keywords, operators, identifiers, literals
  • Supports comments (single-line // and multi-line /* */)
  • Token types: Keywords, identifiers, numbers, strings, operators, delimiters

Parser Package (parser/)

  • Implements Pratt Parser (Top-Down Operator Precedence)
  • Creates Abstract Syntax Tree (AST) from tokens
  • Handles operator precedence and associativity
  • Supports all language constructs: declarations, expressions, statements, functions, structs
  • Error collection and reporting

Evaluator Package (eval/)

  • Walks the AST and executes code
  • Manages runtime state and environments
  • Handles variable scoping and closures
  • Implements all language semantics
  • Error handling and panic recovery

Standard Library Package (std/)

  • Provides 100+ builtin functions
  • Organized by type: arrays, strings, math, file I/O, OS, time, etc.
  • Each file focuses on one collection type or functional area
  • All builtins registered in builtins.go
Adding New Features
  1. Add lexer support (if new syntax needed)

    • Update lexer/token.go with new token type
    • Modify lexer/lexer.go tokenization logic
  2. Extend parser (if new AST nodes needed)

    • Add node struct to parser/node.go
    • Implement parsing logic in parser/parser*.go
  3. Implement in evaluator

    • Add evaluation logic to eval/evaluator*.go
    • Handle new node type in evaluation switch
  4. Add builtin functions (easiest approach)

    • Implement function in appropriate std/*.go file
    • Register in builtins slice in init()

�️ Installation & Tools

System-Wide Installation

To install Go-Mix globally on your system:

sudo ./install.sh

This script:

  • βœ… Verifies Go is installed (v1.18+)
  • βœ… Builds the executable from source
  • βœ… Installs to /usr/local/bin
  • βœ… Makes go-mix accessible from anywhere

For detailed installation instructions, see INSTALL.md.

Install Commands
sudo ./install.sh         # Install system-wide (recommended)
./install.sh rebuild      # Just build, don't install
sudo ./install.sh uninstall  # Remove installation
./install.sh clean        # Remove build artifacts
VS Code Extension

A professional VS Code extension is available for Go-Mix development:

Features:

  • 🎨 Syntax highlighting for .gm files
  • ⚑ Run code with Ctrl+Shift+G
  • πŸ“ 15+ code snippets
  • πŸ”Œ REPL integration
  • πŸ’‘ Keyword hover information
  • πŸ”„ Smart indentation & formatting

Installation:

  1. Open VS Code
  2. Go to Extensions (Ctrl+Shift+X)
  3. Search for "GoMix"
  4. Click Install

Or install from the VS Code Marketplace

For extension development, see vscode-ext/README.md


οΏ½πŸ“ License & Attribution

License: MIT

Author: Akash Maji
Contact: akashmaji@iisc.ac.in
Repository: github.com/akashmaji946/go-mix

Go-Mix is designed for:

  • Education β€” Learning language design and interpreter implementation
  • Prototyping β€” Rapid algorithm and idea development
  • Embedding β€” Adding scripting capabilities to JS like applications
  • Experimentation β€” Testing language features and design patterns

Contributions, issues, and feedback are welcome!


Quick Reference Card

// Variables
var x = 10;      let y = 3.14;    const Z = 42;

// Arrays & Collections
var arr = [1,2,3];              var map = map{"key": "value"};
arr[0];          arr[-1];        map["key"];

// Functions
fn add(a,b) { return a + b; }   var f = fn(x){ return x*2; };

// Control Flow
if (cond) { } else if { } else { }
for (var i=0; i<n; i=i+1) { }   while (cond) { }
foreach x in arr { }            foreach i, v in arr { }

// Functional
map(arr, fn(x){ return x*2; });
filter(arr, fn(x){ return x>5; });
reduce(arr, fn(a,x){ return a+x; }, 0);

// Classes & Objects
struct Name { var x; fn method() { } }
var obj = new Name();

// Common Functions
print(), println(), printf(), length(), typeof(), tostring()

// String Methods
upper(), lower(), split(), join(), contains(), substring()

// Math Functions
abs(), min(), max(), floor(), ceil(), sqrt(), pow()

// File I/O
fopen(), fwrite(), fread(), fclose()

// System
getenv(), setenv(), exec(), getpid(), sleep(), now()

Happy Coding with Go-Mix! πŸš€

Directories ΒΆ

Path Synopsis
File : go-mix/eval/evaluator.go Author : Akash Maji Contact : akashmaji(@iisc.ac.in)
File : go-mix/eval/evaluator.go Author : Akash Maji Contact : akashmaji(@iisc.ac.in)
Package file implements stateful file I/O for the Go-Mix language.
Package file implements stateful file I/O for the Go-Mix language.
File : go-mix/function/function.go Author : Akash Maji Contact : akashmaji(@iisc.ac.in)
File : go-mix/function/function.go Author : Akash Maji Contact : akashmaji(@iisc.ac.in)
File : go-mix/lexer/lexer.go Author : Akash Maji Contact : akashmaji(@iisc.ac.in)
File : go-mix/lexer/lexer.go Author : Akash Maji Contact : akashmaji(@iisc.ac.in)
File : go-mix/main/main.go Author : Akash Maji Contact : akashmaji(@iisc.ac.in)
File : go-mix/main/main.go Author : Akash Maji Contact : akashmaji(@iisc.ac.in)
File : go-mix/parser/node.go Author : Akash Maji Contact : akashmaji(@iisc.ac.in)
File : go-mix/parser/node.go Author : Akash Maji Contact : akashmaji(@iisc.ac.in)
Package repl implements the Read-Eval-Print Loop (REPL) for the Go-Mix interpreter.
Package repl implements the Read-Eval-Print Loop (REPL) for the Go-Mix interpreter.
File : go-mix/scope/scope.go Author : Akash Maji Contact : akashmaji(@iisc.ac.in)
File : go-mix/scope/scope.go Author : Akash Maji Contact : akashmaji(@iisc.ac.in)
This file implements built-in array manipulation methods for the Go-Mix language.
This file implements built-in array manipulation methods for the Go-Mix language.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL