Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Introduction

Xen is a loosely-typed, imperative scripting language written in C. Its syntax closely resembles C-like languages and the interpreter itself is a mere 120 Kb in size. Its primary purpose is to serve as a learning project for myself and a fun side project to work on in my free time. It is not designed with the intent of being a serious, production-ready language.

With that being said, this guide serves as a hopefully-useful overview of Xen and its current offerings.

Installation

Xen ships precompiled binaries for Linux, Windows, and macOS. See your platform below for install instructions.

Linux

The easiest way to install Xen on Linux is to run the following command in your terminal:

curl -f https://raw.githubusercontent.com/jakerieger/Xen/refs/heads/gh-pages/install.sh | sh

You can also download packages for Ubuntu/Debian and Fedora, or just install manually from a tarball.

Download Xen for Linux

Windows

You can install Xen on Windows via the installer package (.exe) or manually from a zip archive.

Download Xen for Windows

macOS

Xen has releases for both x64 and ARM64 macOS platforms. To install, download the appropriate tarball for your CPU architecture. Extract it and put the xen executable somewhere in your PATH environment variable.

Download Xen for macOS

Building from Source

If you prefer to install Xen by building from source, you’ll need a system that support makefiles and GCC (or Clang).

Cross-Compiling

Xen uses cross-compilation toolchains for Linux like MinGW and osxcross to provide builds for platforms other than Linux. In order to build all platforms without modification to the makefiles requires having these toolchains installed and in your PATH.

If you have all the required toolchains installed, you can run the following command to build targets for all platforms:

$ make all-platforms

Compiler Support

By default, Xen uses GCC to build on Linux, MinGW for Windows, and Clang for macOS. MSVC has not been tested in any capacity.

Building Xen

1. Get the source

Cloning from GitHub:

GitHub will have the latest changes but typically contains breaking changes. Checkout a tagged release if stability is what you want.

$ git clone https://github.com/XenLanguage/Xen

Download source tarball from releases:

This contains source code from stable releases.

$ wget https://github.com/jakerieger/Xen/archive/refs/tags/v0.5.4.tar.gz

2. Run make

$ cd Xen
$ make all

That’s pretty much it. Builds will be located in build/<platform>-<target>.

Developer Tools

At the moment, Xen doesn’t have an available language server. It does provide two editor extensions that provide basic syntax highlighting for VS Code and Neovim.

Hello, Xen!

Let’s kick things off with the canonical “Hello World” example in Xen. Open a new file and add the following to it:

include io;

io.println("Hello, Xen!");

Save it as hello_xen.xen and close it.

Now open a terminal and enter the following:

$ xen hello_xen.xen

You should see “Hello, Xen!” printed to your console. That’s it!

The Basics

Operators

Strings

Collections

Arrays

Dictionaries

Control Flow

Functions

Lambdas

Classes

Properties

Methods

Other Types

xen::io

Provides utilities for input and output.

include io;

Public Functions

print

print (value: any, ...) -> null

Prints text to the console.

println

println (value: any, ...) -> null

Prints text to the console, adding a newline at the end.

input

input (prefix: string) -> string | null

Receives input from the console, submitted when the enter key is pressed.

clear

clear () -> null

Clears the console screen.

pause

pause () -> null

Waits for the user the press the enter key.

xen::os

Provides utilities for interacting with the operating system.

include os;

Public Functions

readtxt

readtxt (filename: string) -> string | null

Reads a file to a string.

readlines

readlines (filename: string) -> [string] | null

Read a file’s lines into an array.

readbytes

readbytes (filename: string) -> UInt8Array | null

Read a file into a byte array.

exit

exit (exit_code?: number) -> null

Exit the current process.

exec

exec (cmd: string, args?: [string]) -> null

Execute the specified command.

mkdir

mkdir (dir: string, overwrite?: bool) -> bool

Create a new directory. If overwrite is true and the directory already exists, it will be overwritten with the new, empty directory.

rmdir

rmdir (dir: string) -> bool

Deletes the specified directory. For files, use rm.

rm

rm (file: string) -> bool

Deletes the specified file. For directories, use rmdir.

exists

exists (path: string) -> bool

Returns whether the given directory or file exists.

sleep

sleep (duration: number) -> number

Sleeps the current process for duration seconds.

xen::string

Provides utilities for working with strings. All of the available functions in this namespace are also available as member functions to string objects.

include string;

Public Functions

len

len (str: string) -> number

Returns the number of characters in the string.

upper

upper (str: string) -> string | null

Converts the given string to UPPERCASE.

lower

lower (str: string) -> string | null

Converts the given string to lowercase.

substr

substr (str: string, start: number, end: number) -> string | null

Returns a substring taken from the source string at [ str[start], str[end] ].

find

find (str: string, needle: string) -> number | null

Find the given substring (needle) in the source string. Returns the index of the last matched character.

trim

trim (str: string) -> string | null

Removes whitespace from the given string.

contains

contains (str: string, needle: string) -> bool | null

Returns whether the given substring (needle) exists within the source string.

starts_with

starts_with (str: string, prefix: string) -> bool | null

Returns whether the given source string starts with the given prefix.

ends_with

ends_with (str: string, suffix: string) -> bool | null

Returns whether the given source string ends with the given suffix.

split

split (str: string, split_on: string) -> [string] | null

Splits the source string at the given split token and returns an array of strings.

replace

replace (str: string, old_str: string, new_str: string) -> [string] | null

Replaces old_str in src with new_str.

xen::array

Provides utilities for working with arrays. All of the available functions in this namespace are also available as member functions to array objects.

include array;

Public Functions

len

len (arr: array) -> number

Returns the number of values in the array.

push

push (arr: array, value: any) -> number | null

Pushes a new value to the array. Returns the new number elements or null if failed.

pop

pop (arr: array) -> any

Pops the most recent value from the array and returns it. This removes the value from the array.

first

first (arr: array) -> any

Returns the first element in the array.

last

last (arr: array) -> any

Returns the last element in the array.

clear

clear (arr: array) -> null

Empties the given array, removing all previous values.

contains

contains (arr: array, value: any) -> bool | null

Returns whether the given value exists in the array.

index_of

index_of (arr: array, value: any) -> number | null

Gets the index of the given value in the array.

reverse

reverse (arr: array) -> array | null

Reverse the insertion order of the elements in the array.

join

join (arr: array, delim: string) -> string | null

Joins each element in the array with the given delimeter and returns a string.

xen::datetime

Provides utilities for date and time.

include datetime;

Public Functions

now

now () -> number

Return the current milliseconds elapsed since the UNIX epoch.

clock

clock () -> number

Return the current CPU clock time.

xen::dictionary

Provides utilities for working with dictionaries. All of the available functions in this namespace are also available as member functions to dictionary objects.

include dictionary;

Public Functions

len

len (dict: dictionary) -> number

Returns the number of entries in the dictionary.

keys

keys (dict: dictionary) -> [string]

Returns all keys as a list.

values

values (dict: dictionary) -> [any]

Returns all values as a list.

has

has (dict: dictionary, value: any) -> bool

Returns whether the given dictionary contains an entry with the given value.

remove

remove (dict: dictionary, value: any) -> bool

Remove entry with given value from dictionary.

clear

clear (dict: dictionary) -> null

Empties the given dictionary, removing all items.

xen::net

Provides utitlies for networking and web services.

include net;

Public Classes

TcpStream

Provides facilities for communicating with a TcpListener session. Typically created and returned by accepted TCP connections via TcpListener.

var conn = new net.TcpStream(remote_addr, remote_port);

Public Properties

  • remote_addr: number - The remote IPv4 address of the remote host the stream is currently connected to
  • remote_port: number - The port of the remote host the stream is currently connected through

Private Properties

  • _fd: number - Socket file descriptor for current connection

Public Methods

read

read (max_bytes = 4096) -> string | null

Read up to max_bytes from stream.

write

write (data) -> number

Write data to stream.

send

send (data) -> number

Alias for write.

recv

recv (max_bytes = 4096) -> string | null

Alias for read.

close

close () -> null

Close the connection.

shutdown

shutdown (method: number) -> null

Shutdown the connection. The method can be one of three values:

  • 0: read
  • 1: write
  • 2: both

TcpListener

Binds a specified port and listens to incoming TCP connections on that port. Can receive a TcpStream instance from connections, allowing the ability to read and write data between the host (TcpListener) and client (TcpStream).

var listener = new net.TcpListener(port);

Public Properties

  • port: number - The port to bind to

Private Properties

  • _socket: number - The bound socket file descriptor

Public Methods

bind

bind () -> bool

Bind the socket to the instance port.

listen

listen () -> bool

Begin listening to incoming traffic.

bind_and_listen

bind_and_listen () -> bool

Combines the previous two methods into one.

accept

accept () -> TcpStream | null

Waits on incoming connections and accepts the first one, returning a TcpStream instance.

close

close () -> null

Closes the connection, terminating any active connections with clients.