Skip to content
Cubed edited this page Mar 2, 2024 · 3 revisions

Welcome to the Orange wiki!

Orange is a statically typed compiled language built to be simple but still have enough features to be usable.

The Basics

Just like most languages, Orange starts off execution at the main function.

fn main
    println("Hello, World!")
end

Function headers start with the fn keyword and the body ends with the end keyword.

You'll notice that we don't have parentheses in the function header. Orange doesn't use parentheses in the syntax of function definitions.

Variables are declared using the let keyword. We can perform basic arithmetic and assign values with familiar expression syntax from other languages.

fn main
    let x int
    let y int

    y = 4
    x = y * 2

    print("The values of x and y are: ")
    print(x)  // 8
    print(" and ")
    println(y)  // 4
end

You would also notice that the print and println functions can take integers or strings as their arguments. This is called polymorphism, a concept we will see more of in the language later on. The compiler internally creates a new instance of the function for each type of argument passed to it.

Here is the list of all the basic types that come with the language (as of Feb 2024):

  • int - A signed integer. Always takes up 4 bytes.
  • char - A simple character. One byte.
  • str - An alias for a pointer to characters.
  • void - A zero-sized type.
  • u64 - Takes up 8 bytes. Useful for hash algorithms or bit-optimised code
  • any - Represents any type. Can only be used as a pointer - &any

We can create pointers by prepending a type with &. eg:

  • &int points to an integer
  • &char points to a character. Similar to str, but the compiler will complain when assigning between the two types.
  • &any represents a generic pointer. any types are not allowed to exist independently, therefore variables of this type cannot be dereferenced.
  • And similarly for any other type...

An important point to note is that Orange is strongly typed. This means that a variable of one type cannot be assigned to a variable of any other type. Thus, the following is not allowed:

let x char
let y &int

y = &x  // ERROR

Functions

Every good programming language needs to have functions so that us mere mortals can write maintainable code.

fn double_it: int x -> int
    return x * 2
end

Here, we have defined a simple function double_it that takes an integer and returns an integer with the doubled value.

The syntax of the function header does not use parentheses. We have a colon : instead. The argument has a type and the name after the type - int x.

The return type in the signature is indicated by ->. It is optional as we saw in fn main, where the omission of the return type implies a return type of void.

We can call the function normally in our main function like so:

fn double_it: int x -> int
    return x * 2
end

fn main
    let y int
    let x int

    y = 4
    x = double_it(y)

    print("The values of x and y are: ")
    print(x)  // 8
    print(" and ")
    println(y)  // 4
end

Types

Apart from the builtin types, Orange lets us make our own types using the type keyword.

type ComplexInt
    let real int
    let imag int
end

fn main
    let c ComplexInt
    c.real = 5
    c.imag = 7

    println(c.real)  // 5
    println(c.imag)  // 7
end

Here, we have created a ComplexInt type with two fields - real and imag. Fields are accessible using the dot . operator. Types defined in Orange can have fields that use any type. Even the type itself.

type IntNode
    let data int
    let next &IntNode
end

As a bonus, the dot . operator can also be used on a pointer to a type as well.

type IntNode
    let data int
    let next &IntNode
end

fn main
    let node IntNode
    let node_ref &IntNode

    node_ref = &node
    node_ref.data = 15

    println(node.data)  // 15
end

Here, we have created two variables node and node_ref of types IntNode and &IntNode respectively. Then, because we set node_ref to point to node, we can modify the contents of node through node_ref. We can see that accessing the data field of node_ref requires the same dot operator - node_ref.data.

The alloc function

If you have dealt with linked lists in a low-level language like C before, you will know that they are useful only when coupled with the use of dynamic memory allocation.

Dynamic memory allocation is a way to hold onto some memory for an arbitrary amount of time. This is unlike regular variables in a function which go away after the return statement.

In Orange, dynamic memory allocation is done using the alloc and free functions.

Clone this wiki locally