How to use Uni ? (beta version)

This is the documentation of Uni-py beta. If you want to know about the overall concept of Union, check this article.

Disclaimer: If you ever struggle with a functionnality you don’t see here, chances are it’s doable with c++ imports or the std library

Types:

Typelist:

  • int

  • float

  • double

  • string

  • any

  • …and whatever is considered a type in c++

Type operations:

Coming soon…

Type casts:

var: type

static_cast<type>(value)

1
2
3
4
x: int = 8
y: float = 14
z: float = x: float / y
w: float = static_cast<float>(x) / y

std::to_string(value)

1
message: string = std::to_string(3) + " + " + std::to_string(18.54526526)

std::stoi(value)

1
number: int = std::stoi(input())

Arrays

name: type[] = {values}

name: type[]

1
2
3
xs: int[] = { 0, 1, 2 }
xs.push_back(3)
print(x[3]) // 3

Operators

  • +: sums two numbers, or concatenates two strings

  • -: subtracts two numbers

  • *: multiplies two numbers

  • /: divides two numbers

  • +=: like +, but assigns the value on the left to the result

  • -=: like -, but assigns the value on the left to the result

  • *=: like *, but assigns the value on the left to the result

  • /=: like /, but assigns the value on the left to the result

  • <-: concetenates a value to a variable

  • ->: same but backwards (this symbol has uses later on)

    1
    2
    3
    4
    5
    6
    a: int (8)
    x: string = "Hello"
    print(x <- ", World") // Hello, World
    print("The fox says " -> x) // The fox says Hello, World
    print(x + 6 -> a) 14
    print(a) // 14

Variables

Declaration

name: type

name: type = value

name: type (arguments for type constructor)

1
2
3
4
5
6
7
x : int = 8
y : float = 12.0
j : any = "Hello World"
v : MyClass (12, 14)
k : string = "Hi"
a : int (3)
b : float;

Assignment

name = value

1
2
3
x = 12
y = 8.0
j = "wow"

Pointers

Point to something:

Pointers can only point to a variable, not any value

ptr<type>(variable)

1
2
x: int (8)
x_reference: ptr<int>(x)

Get value of pointer:

ptr_variable::value

1
x == x_reference::value //true

Store heavy values

1
2
my_enemies: ptr<Heavy_Class>[]
my_enemies.push_back(new Heavy_Class(400, 200, 10, 30))

‘’New’’ Syntax

name: ptr<type> = new arguments

1
my_vector_pointer: ptr<vector2d> = new 0, 0

Functions

Declaration

func: type name:

func: type name (params if at least one):

func<Generics>: type name:

1
2
3
4
5
6
func: int main:
return 0
func: string double_string(s: string):
return s + s
func<T, A>: T add_two_class_members(t: T, a: A):
return t + a

Calls

name(args)

name<Genrics>(args)

1
2
3
main()
double_string("Hello")
add_two_class_members<Type1, Type2>(member1, member2)

Threads

Threads are a sort of function, that is called on another thread, and runs parallelly.

Declaration

thread: type name:

thread: type name (params if at least one):

thread<Generics>: type name:

1
2
thread: int comain:
return

All threads are void type by return, type indicates info on the ‘’state value’’

‘’State Value’’

All threads have a ‘’state value’’ that can be watched by other threads. More on that later.
You can change this value only in the thread with -> value. It is read-only in other threads and shouldn’t be altered or pointed to.

1
2
3
4
5
thread: int comain:
-> -1 //not finished
...
-> 1 //done
return

Thread Safety

lock: Will block all other identical threads when they reach this statement until unlocked

unlock: Unlocks other identical threads

Calls

Threads can be called with:

name: type = watch thread_name(arguments)

Here, name holds the ‘’state value’’ of the thread being run.

Then, in the same scope, you either need to waitfor the thread to complete, or detach it.

detach name: still runs the thread, but won’t ever wait for it to finish

waitfor name: blocks the code from running until the thread is done

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
thread: int lengthy_process:
-> -1
...
lock
modify something
unlock
...
-> 1
return

func: int main:
a: int = watch lengthy_process()
b: int = watch lengthy_process()

detach b

...do things...

print("dunno about a")
waitfor a
print("a is done")

At the end of this program, a is finished for sure, but we don’t know at all about b. We could check its state though.

Logic

if statement:

else

1
2
3
4
if x > 4:
print("x is big")
else:
print("x is small")

Loops

While loops

while expression:

1
2
while true:
print("infinite loop")

For loops

for name in iterable:

name assumes all the values in the iterable one by one.

for name to max:

name assumes all the values from 0 to max (excluded)

for name of iterable:

name assumes all the values from 0 to the length of the iterable

1
2
3
4
5
6
7
x: int[] = { 4, 5, 6 }
for i in x:
print(i) // 4 5 6
for i to 7:
print(i) // 0 1 2 3 4 5 6
for i of x:
print(i) // 0 1 2

Break statement

break

Classes

class name:

class<generics> name:

1
2
3
class MyClass:
func: int one:
return 1

Namespaces

namespace::value

1
std::cin()

Structure

Any program must have a main function, of which the return value is the exit code.

1
2
func: int main:
return 0 // Everything went fine

Olc Pixel Game Engine Integration

using olcPixelGameEngine will create all the boilerplate for you.

All you now have to define is:

1
2
3
4
5
6
7
func: bool App::OnUserCreate:
//this gets exectuted as the window starts
return true //false if something went wrong

func: bool App::OnUserUpdate(fElapsedTime: float):
//this gets called as often as possible
return true //false to close the app

And initialize the app in main:

1
2
3
4
5
6
7
func: int main:

appName: App("Name")
if demo.Construct(width, height, pixelWidth, pixelHeight): // for example 640, 360, 1, 1
demo.Start()

return 0