Noxy
Statically Typed Programming Language

A powerful statically typed language with a high-performance stack-based Virtual Machine written in Go, created by Estêvão Fonseca. Supports primitives, structs, dynamic arrays, maps, and much more.

🦉 Mascot: Our purple owl symbolizes wisdom and elegance in software development.

Web Interpreter GitHub View Examples
hello.nx
print("Hello from Noxy!")

// Basic operations
let x: int = 10
let y: int = 20
print("Sum: " + to_str(x + y))

// Struct example
struct Product
    id: int,
    name: string,
    price: float
end

let product: Product = Product(1, "Laptop", 2500.50)
print("Product: " + product.name)

Language Features

Static Type System

Full support for int, float, string, bool, and array types with compile-time type checking.

Stack-Based VM

Stack-based Virtual Machine written in Go for high performance and portability.

Data Structures

Native support for structs, arrays, self-referencing, and complex data structures.

Advanced Algorithms

Implementation of binary search, linked lists, binary trees, and sorting algorithms.

Self-Referencing

Self-referencing structs using the ref operator to create recursive data structures.

Type Conversions

Universal to_str function and numeric conversions for flexible data manipulation.

Concurrency

Go-style concurrency with spawn and channels for parallel execution on multiple cores.

First-Class Functions

Support for anonymous functions, closures with captured variables, and passing functions as arguments.

Language Syntax

Variable Declaration

let x: int = 42
let y: float = 3.14
let text: string = "Hello, World!"
let active: bool = true

Arrays

let numbers: int[5] = [1, 2, 3, 4, 5]
let matrix: float[3] = [1.1, 2.2, 3.3]
let size: int = length(numbers)

Structs

struct Person
    name: string,
    age: int,
    active: bool
end

let person: Person = Person("John", 25, true)
person.age = 26

Functions

func add(a: int, b: int) -> int
    return a + b
end

func greet(name: string)
    print("Hello, " + name + "!")
end

// Closure
let multiplier: int = 2
let double: func = func(x: int) -> int
    return x * multiplier
end

Dynamic Arrays & Maps

// Dynamic Array
let list: int[] = []
append(list, 42)
let val: int = pop(list)

// Map
let scores: map[string, int] = {"Alice": 100}
scores["Bob"] = 95
print(scores["Alice"])

Control Structures

if x > 10 then
    print("x is greater than 10")
elif x == 10 then
    print("x is exactly 10")
else
    print("x is less than 10")
end

while i < 10 do
    print(i)
    i = i + 1
end

// For Loop
for item in list do
    print(item)
end

Self-Referencing

struct TreeNode
    value: int,
    left: ref TreeNode,
    right: ref TreeNode
end

let root: TreeNode = TreeNode(50, null, null)
root.left = ref TreeNode(25, null, null)

Imports & Modules

// Import standard library
use strings
use io

// Use imported functions
print(strings.to_upper("hello"))

Standard Library

// Available modules:
// io, time, sys, net, http, json, crypto

use time
print(time.now())

use sys
print(sys.argv()[0])

Concurrency

let c: chan int = make_chan(0)
spawn(worker, c)
let msg: int = chan_recv(c)

Practical Examples

Concurrency (Producer-Consumer)

Using channels to communicate between concurrent routines.

use time

func worker(id: int, c: chan string)
    time.sleep(100)
    chan_send(c, "Message from " + to_str(id))
end

func main()
    let c: chan string = make_chan(0)
    spawn(worker, 1, c)
    spawn(worker, 2, c)
    
    // Receive 2 messages
    print(chan_recv(c))
    print(chan_recv(c))
end

Hello World

A basic example showing the fundamental syntax of the Noxy language.

print("Hello from Noxy!")

// Basic operations
let x: int = 10
let y: int = 30
print("Sum: ")
print(x + y)

// Struct example
struct Product
    id: int,
    name: string,
    price: float
end

let product: Product = Product(1, "Laptop", 2500.50)
print("Product: ")
print(product.name)

Binary Tree

Implementation of a binary tree with pre-order traversal.

struct Node
  data: int,
  left: ref Node,
  right: ref Node
end

// Create binary tree
let root: Node = Node(1, null, null)
root.left = Node(2, null, null)
root.right = Node(3, null, null)
root.left.left = Node(4, null, null)
root.left.right = Node(5, null, null)

func pre_order(node: ref Node)
  if node != null then
    print(to_str(node.data))
    pre_order(node.left)
    pre_order(node.right)
  end
end

pre_order(root)

Linked List

Implementation of a linked list with insertion and printing operations.

struct Node
    value: int,
    next: ref Node
end

func append(node: ref Node, value: int)
    if node.next == null then
        node.next = ref Node(value, null)
    else
        append(node.next, value)
    end
end

func print_list(node: ref Node)
    while node != null do
        print(to_str(node.value))
        node = node.next
    end
end

let list: Node = Node(10, null)
append(list, 20)
append(list, 30)
print_list(list)

HashMap

Implementation of a hashmap with string keys using a polynomial hash function.

struct Node
    key: string,
    value: string,
    next: ref Node
end

let buckets: Node[16] = [null, null, null, null, ...]

func hash(key: string, size: int) -> int
    let hash_value: int = 0
    let i: int = 0
    while i < strlen(key) do
        hash_value = (hash_value * 31 + ord(key[i])) % size
        i = i + 1
    end
    return hash_value
end

func push(key: string, value: string)
    let index: int = hash(key, 16)
    if buckets[index] == null then
        buckets[index] = Node(key, value, null)
    else
        // Add to linked list
        let node: Node = buckets[index]
        while node.next != null do
            node = node.next
        end
        node.next = ref Node(key, value, null)
    end
end

Safe Division

Result pattern for safe error handling in operations that may fail.

struct Result
    is_ok: bool,
    value: int,
    error: string
end

func Ok(value: int) -> Result
    return Result(true, value, "")
end

func Err(error_name: string) -> Result
    return Result(false, 0, error_name)
end

func safe_divide(a: int, b: int) -> Result
    if b == 0 then
        return Err("DIVISION_BY_ZERO")
    end
    return Ok(a / b)
end

let result: Result = safe_divide(10, 0)
if result.is_ok then
    print("Result: " + to_str(result.value))
else
    print("Error: " + result.error)
end

Closures

Functions can capture variables from their outer scope, allowing for state encapsulation.

func makeAccount(initialBalance: int) -> func
    let balance: int = initialBalance
    
    // Return a function that captures 'balance'
    return func(amount: int) -> int
        balance = balance + amount
        return balance
    end
end

let account: func = makeAccount(100)
print("Initial: 100")
print("Deposit 50: " + to_str(account(50)))   // 150
print("Withdraw 30: " + to_str(account(-30))) // 120

HTTP Server

Built-in support for creating concurrent HTTP servers.

use http_server

func handler(req: HttpRequest) -> HttpResponse
    if req.path == "/" then
        return http_server.response_text("Hello from Noxy!")
    elif req.path == "/json" then
        return http_server.response_json("{\"status\": \"ok\"}")
    end
    return http_server.response_404()
end

// Create and start server
let server: HttpServer = http_server.new_server("127.0.0.1", 8080)
print("Server running on http://127.0.0.1:8080")
http_server.serve(server, handler)

Installation and Usage

Prerequisites

  • Go 1.21 or higher
  • Git

Installation

# Clone the repository
git clone https://github.com/estevaofon/noxy.git
cd noxy

# Build the project
go build -o noxy ./cmd/noxy

Compiling Programs

# Run the program
./noxy program.nx

# Or via Go run
go run ./cmd/noxy/main.go program.nx