Skip to content

The Basics

Ryna is an imperative, strongly-typed programming language with many common features. Here We will explain the main ones. All these should be enough to get you started writing basic code, but more complex features will be analyzed later in their own respective sections.

Literals

One of the main ways you can create values is by writing down explicit constants that the compiler will understand as basic types. These are called literals and are a very important concept in many languages, but more so in Ryna. Here are all the literals that tthe language supports.

Integers

Integers can be inputted in Ryna in a similar way as other languages:

881452      // Basic integer (no size limit)
-32         // Negative integers are also literals
0b1000110   // Binary integers (70 in this case)
0xFF1A      // Hexadecimal integers (65306 in this case)

All these values are compiled to Int values.

Floating Point numbers

Floating point numbers are more or less the same as in other languages:

1.56        // Basic float
-67.2       // Negative floats are also literals
1e10        // Scientific notation is allowed
2E-5
1.5e2
-2.2E-8

All these values are compiled to Float values.

Logical values

The only logical literals Ryna supports are true and false. They are compiled to Bool values.

Strings

Strings in Ryna are UTF-8 encoded and are inputted by using double quotes with the possibility of escape sequences. These would be some examples:

"This is an example"

"This is an example with \t tabs and line \n jumps"

"Also, you 
can have
multiline 
strings"

All these values are compiled to String values.

Characters

Characters do not exist in Ryna as a class, but they can be used as Int code points:

'w' // This is equal to 119

This can be used when iterating over code points.

Variables

In contrast to functional languages, Ryna does have support for variables and they are used as much as in any other imperative language. Constants are not implemented for now, but they might be introduced in a future release.

Definition

The syntax for variable definitions is as follows:

let name: Type = expression;

In let statements, name can be any alphanumeric identifier that does not begin with a number ("_" is also allowed), Type can be any valid type of the ones seen in the Type System section and expression can be anything that is not a statement. These would be some valid examples:

let example_1: Int = 3 + 6;     // Simple definition
let example_2 = 3 + 6;          // Here the Int type is inferred
let example_3 = "Test";         // A String type is inferred

Assignment

When you have already defined a variable, you can replace its value by using the = operator:

let example: Int = 3 + 6;

example = 5;      // Replace the value by 5
example = true;   // ERROR: Bool is not bindable to Int

Getting values

To get the value of a variable, just use its name in the code. Note that you will get a Reference to the value instead of the value to prevent the user from making unnecessary copies:

let big = "Imagine this is a very big string ...";

let big_2: String = big;            // ERROR: @String is not bindable to String
let big_3: @String = big;           // Keeps a reference
let big_4: String = big.deref();    // Copies the original data
let big_5: &String = big.demut();   // Keeps a constant reference

Reference assignment

Sometimes you might need to change the underlying values of a mutable reference. An example of this would be trying to change an element inside an array or mutating a class instance. For these cases you can use the := operator:

/*
    Imagine a class Example that has an Int 
    attribute called attribute_1
*/

let example: Example = some_class_instance;

example.attribute_1() := 5;     // This is only allowed using this operator
example.attribute_1() := "Test" // ERROR: String is not bindable to Int

Functions

You can also use functions in Ryna, as you might expect. Functions are called using the parentheses syntax used in most imperative languages, including angle brackets in the case of generics.

Operations

Just as most programming languages, Ryna has operators and operations. These encode operations with one, two o even more expressions called operands. Ryna supports four kind of operators:

  1. Prefix operators: the operator comes before a single expression (example: -5).
  2. Postfix operators: the operator comes after a single expression (example: 5!).
  3. Binary (infix) operators: the operator comes betwwen two expressions (example: 1 + 2).
  4. N-ary operators: the operator has an opening and a closing delimiter. Operands are before and inside the delimiters (example: mat[4, 5]).

All these operators and operations can be defined in a similar way as functions. The syntax for generics varies depending on the type of operator and will be explained in their corresponding section.

Flow control

These are the flow-control operations that are allowed in Ryna.

If-else

The language supports if-else control flow with the following syntax:

// Else ifs and elses are optional
if condition {
    [...]
} else if condition {
    [...]
} else {
    [...]
}

conditions must evaluate to Bool.

While

While loops have the following syntax:

while condition {
    [...]
}

conditions must also evaluate to Bool. You can break and continue in while loops.

For

For loops are the most complicated of the three. To begin with, you need an Iterable object, which is defined as one that implements the Iterable interface (more information about interfaces in their section). After this, you can write the following:

// container must implement Iterable
for i in container {
    [...]
}

if you want to make a custom class iterable you have to implement that Interface manually. You can break and continue in for loops.