Nougat Documentation
IV - Programming
4.1 Expressions
In programming, expressions are piece/unit of code that resolves and evaluates into a value. However, in Nougat, there are many expression types which are discussed below, this includes the literals, operations, arrays, maps, and lambdas.
4.1.1 Literals
Literals are expressions of constant value representation which are executed during the source code's runtime. These are interpreted are runtime so that the data can be and will be stored.
4.1.1.1 Numbers
Every constant numbers are treated as 8 bytes double precision floating-point real numbers which has 11-bit exponential length and 52-bits mantissa length. Additionally, there are four format of numbers that can be used in Nougat; hexadecimal, octadecimal, binary, and default decimal format.
Moreover, the maximum value of a number that can be defined in Nougat is 1.7976931348623158 E+308 and the minimum is 2.2250738585072014 E-308.
Base | Example |
Decimal | 88 |
Binary | 0b1011000 |
Octadecimal | 0c130 |
Hexadecimal | 0x58 |
As shown in the example above, 88 in the default decimal format in binary format starts with prefix 0b, octadecimal with 0c, and hexadecimal with 0x.
4.1.1.2 Bools
Booleans in computing and programming is a value than can be either "true" or "false" which is used in representation of truth value in logic and Boolean Algebra.
4.1.1.3 Nil
A value but empty in Nougat is called, "nil", however, zero and nil are different. The difference is that zero is identified as number, meanwhile nil is nothing or void.
4.1.1.4 Strings
Strings is a data that represents and contains texts, it can be either a constant or from a variable. In Nougat, string is considered a data type, thus can be treated as array (will be discussed in next subsections). Here is an example string in Nougat: "Hello world!"
As shown in the example, strings should be inside double quotations (but single quotations would also do). Additionally, strings can also contain escape sequence. These escape sequence are commands along with the string which in runtime will be replaced with its corresponding value. Below is the table thats shows the escape sequence commands in Nougat.
Escape Sequence | Value |
\a | Alert |
\bn...n | Binary value. The n's after the \b should be replaced with an actual binary number. |
\f | Formfeed/Page break |
\n | New line |
\on...n | Octal value. The n's after the \o should be replaced with an actual octal number. |
\r | Carriage return |
\s | Backspace |
\t | Horizontal tab |
\uxxxx | Hexadecimal value. The four x after the \u should be replaced with a hexadecimal value. |
\v | Vertical tab |
\xhh | Hexadecimal value. The two h after the \x should be replaced with a hexadecimal value. |
\" | Double quotation mark to avoid terminating the string expression. |
\' | Single quotation mark to avoid terminating the string expression. |
Here's an example usage of escape sequence, whereas it containts the string "Hello, world!" and ends with a new line and a carriage return: "Hello, world!\r\n"
4.1.2 Operators
According to Wikipedia, operators might differ either syntatically or semantically and these are constructs defined in a programming language that commonly behaves like functions. Operators in Nougat, additionally, uses punctuations, for example plus "+", minus "-", comma ",", less than "<" and greater than ">" sign.
4.1.2.1 Pre-expressional Operators
Pre-expressional operators in Nougat, like in any other traditional imperative programming languages, are operators placed before the expression. For instance, in a mathematical expression, the - sign is placed before a number to denote a negation.
Operator | Description |
+ | Converts a negative number into a positive number. Note that this is operator doesn't make any effect on non-negative numbers. |
- | Negates any number. |
~ | Bitwise complement operator reverses each bit in a number. A very easy to understand explanation is for example, "~0xffff0000" is equivalent to "0x0000ffff". |
! | Logical negation operator. This produces a true value if its operand has a false value and vice-versa. Example, !false is equal to true. |
These pre-expressional operators are also widely known as "Unary Prefix" or "Unary Operators".
4.1.2.2 Binary Operators
Binary operations in programming are expressions whereas a left and right expression is being evaluated through a certain operation.
Operator | Description | Example |
+ | Additive operator. Adds a two expression; the expressions can be integer, string, boolean, etc. | 4 + 4 = 8 |
- | Subtraction operator. Subtracts two expressions. This can also be used in strings to remove a particular substring. | 12 - 4 = 8 "Hello, world!" - "Hello, " = "world!" |
/ | Division operator. Divides numbers (e.g., integers, decimals, etc). | 24 / 3 = 8 |
* | Multiplication operator. Multiplies a number, however additionally, this reconcaternates a string if the left-hand expression is a string and the right-hand expression is a number. | 4 * 2 = 8 "-" * 8 = "--------" |
% | Remainder operator. Returns the remainder of a division operation. | 8 % 3 = 2 |
^ | Bitwise OR operator. | 11 ^ 3 = 8 |
& | Bitwise AND operator. | 8 & 3 = 0 |
| | Bitwise OR operator. | 8 | 3 = 11 |
<< | Left-shift bitwise operator. Shifts the individual bits of the first operand to the left. | 4 << 1 = 8 |
>> | Right-shift bitwise operator. Shift the operand's bits to the right. | 16 >> 1 8 |
? | Nil-coalescing operator. This returns the value of right expression if left is nil, otherwise returns the left value. | nil ? "Hello!" = "Hello!" 10 ? nil = 10 |
== | Equal-to operator. Evaluates to true if both expressions has an equal value. | "Hi!" == "Hello!" = false 1 == 1 = true |
!= | Not-equal-to operator. Evaluates to false if both expressions has an equal value. | "Hi!" != "Hello!" = true 1 != 1 = false |
&& | Logical AND operator. Evaluates to true if both expressions are true. | true && true = true false && (1 == 1) false |
|| | Logical OR operator. Evaluates to true if one of the expression is true, if both are false then false. | false || true = true (1 == 2) || (2 == 3) = false |
< | Less than operator. Returns true if the left expression has a number value which is less than the right expression number value. | 8 < 4 = false 4 < 8 = true |
> | Greater than operator. Returns true if the left expression has a number value which is greater than the right expression number value. | 8 > 4 = true 4 > 8 = false |
<= | Less-than-or-equal operator. Returns true if the left expression has a number value which is less than or equal the right expression number value. | 8 <= 4 = false 8 <= 8 = true |
>= | Greater-than-or-equal operator. Returns true if the left expression has a number value which is greater than or equal the right expression number value. | 8 >= 4 = true 8 >= 8 = true |
4.1.3 Arrays & Maps
Arrays and maps in Nougat can store multiple values which can be then later on access by either index (if array) or key (if map).
4.1.3.1 Arrays
Arrays are object/variables that can store multiple values and later be accessed with the use of an index. Items of an array should be inside brackets ([ and ]) that follows an ampersand (&), while items are enumerated by commas. Arrays, since Nougat is a dynamically typed programming language, can store any data with any type (e.g., number, string, etc.) Below is an example of array store in variable named "greetings". (The variable declarations will be discussed on next sections.)
var greetings = &["Hello, world!", "你好世界!", "مرحبا بالعالم!"];
Hence, the variable greetings was declared and contains an array with three string literals as values. These values can be later on replaced and accessed, but can't be removed or deleted.
In order to access an object/value inside an array, index number should be used between brackets after the variable name. For instance, greetings[0], which would return the value "Hello, world!" Array's index always starts with 0, for some reason, which means that the first element of the array has an index of 0, while the second element is at index 1, and so on.
4.1.3.2 Maps
Maps are objects like arrays that can store multiple values, however, unlike arrays, values from a map in Nougat can be access through either by using a key or by selecting a child identifier. Any object types in a map can be a key; a string, number, symbol, or even a function name. In order to initialize a map, keys and values (separated by a colon) must be placed inside curly braces ({ and }) that follows an ampersand (&). For example:
var greetings = &{
"English": "Hello, world!",
"Chinese": "你好世界!",
"Arabic": "مرحبا بالعالم!"
};
As shown above, strings are being used as a key of string values which are stored in the variable greetings. These values can be later accessed the same way array values are accessed, however, the index are the keys in this case of maps. For instance, greetings["Chinese"] which will return the string value "你好世界!"
4.1.4 Lambdas
Lambdas in Nougat are anonymous function expressions (functions will be discussed on the next subsection). These anonymous functions can be used as bridge, for instance, lambdas can be used as an argument for making a feedback event from a listener. Here's an example of a lambda being declared to a variable named lambdaExample:
var lambdaExample = fun() {
render "Hello, world!";
};
As lambdaExample contains a lambda, it can now be later called as function. For example, lambdaExample(). Another difference between a lambda and a function is that, lambdas cannot have names and are treated as expressions.
4.2 Comments
Like in any other programming languages, Nougat, also allows programmers to insert comments. Comments are programmer-readable annotations and/or explanations that adds readability to the code which makes it easier to read for humans. However, these in-line texts doesn't affect the code on execution and is being ignored by the interpreter.
# This is a comment.
var example; # Comments starts here.
In Nougat, comments can be placed in any line. Comments should start with # sign, and ends with the next line. The code above is an example placement of comments in Nougat.
4.3 Variables & Functions
4.3.1 Variables
Variables in programming is a data storage associated with a symbol or name (often called identifier). These variables can store values and later can be replaced with another value or access its value. However, variables in Nougat, unlike in other programming language, cannot be constant and doesn't have a data type. Thus, any variable in Nougat can be an integer, string, etc. Variables in Nougat can be declared with the use of syntaces below.
var <name>;
var <name> = <value>;
var <name>, <name>, etc...;
var <name> = <value<, <name> = <value<, etc...;
And so on...
Here is an example of variable declaration and usage.
var greetings = "Hello, world!";
render greetings;
The render statement will be later discussed on the next subsections. Variables' value can be then replaced by simply using the = operator.
var greetings = "Hello, world!";
render greetings;
greetings = "Value's now changed!"
render greetings;
Furthermore, variable names can only be used once and are case-sensitive, thus, hello is a different name from Hello. Numbers can also be placed after letters as variable names.
4.3.2 Functions
Functions are reusable and organized blocks of codes to perform a specific task. Functions can take an input(s) called parameters, and can possibly produce and return an output. Below is the syntax for declaring functions in Nougat.
fun <name>(<param name> = <value>, ...) <statement>
It is very important to note that parameter names and its default values are optional. And also that parameter name should be different from other parameter names if parameters are more than one. Here are examples of function declarations.
fun sayHello() {
render "Hello!\n";
}
fun greet(greeting) {
render greeting + "!\n";
}
fun printGreeting(greeting = "Hello, from printGreeting()!") {
render greeting + "\n";
}
These functions can later be called with the use of their names followed by parenthesis, and expressional arguments if it requires parameters. It is also important to note that if a function parameter is declared with a default value, following parameters must also have default values too. Additionally, a function must be called and have arguments with the same number of parameters with the declaration. However, parameters with default value are optional. Thus, the above function examples can be called as shown below.
fun main() {
sayHello();
greet("Hola");
printGreeting();
printGreeting("こんにちは!");
}
The definition and usage of the main() function will be tackled later on the next subsection. The code above is expected to give the result:
Hello!
Hola!
Hello, from printGreeting()!
こんにちは!
4.3.2.1 The main() Function
Like most programming languages, the main function is an entry point whereas it is a point in a program where the execution begins. Here is an example of a Hello World program in Nougat.
fun main() {
render "Hello, world!";
}
The Nougat interpreter looks for the main() function of the loaded script and executes if it has no pre-compilation errors (e.g. syntax errors).
4.4 Statements
In accordance to Wikipedia's definition, a statement is an imperative programming language's syntatic unit and is the smallest standalone element that expresses an action to be carried out.
Moreover, statements can have internal components such as expression as keywords to define an statement. Every statement in Nougat should end with a semicolon (;).
4.4.1 Render
The render statement is an statement used to render the text representation of a specified object to the standard output stream.
Render Statement Syntax:
render <expression>;
Examples of render statement usage had already been shown from previous subsections, however, here's another example:
fun main() {
render "Hello, world!";
}
4.4.2 If, Else If, and Else
If, else-if, and else statements are also called conditional programming. Decision making in Nougat, like in any other programming languages, can be used to test and evaluate an expression then executes a certain statement or block if the condition was met.
if statements primarily checks a condition and skips if the condition was not met, while else if statements follows an if statement and executes a statement/block if the previous if or else if statement was skipped. Lastly, the else statement, whereas it executes a certain statement/block if previous if or else if statements' conditions were not met.
fun main() {
var hello = "Hello!";
if(hello == "Hi!") {
render "hello is \"Hi!\"";
}
else if(hello == "Hola!") {
render "hello is \"Hola!\"";
}
else render "hello is \"" + hello + "\"";
}
Hence, the code above will output hello is "Hello!", since the variable hello contains string "Hello!" the conditions in if and else if statement will not be met.
It is also important that else if and else statements are optional, if an if statement's condition was not met then it'll be skipped.
4.4.3 Switch, Case, and Default
The switch statement in Nougat can be used in performing task that has different options for different task. It is also equitable for shorter if-else statements, while the cases are ifs and the default statement is the else statement.
switch(<value>) {
case <value>:
<statement>
...
default:
<statement>
}
A case statement can have another case statement below itself but not a default statement. And unlike other programming languages, Nougat doesn't require a break statement after a case and default statement. Below is an example of a Nougat program that show an example use of switch statement.
fun main() {
var value = 3;
switch(value) {
case 1:
case 2:
render "The value is either 1 or 2.";
case 3:
render "The value is 3.";
default:
render "The value is neither 1, 2, nor 3.";
}
}
4.4.4 Looping
Looping in programming is process of doing a task repeatedly while condition is being met under a circumstance. On the other hand, looping is a process in programming that does a certain instruction until a condition is met.
In Nougat, there are several statements for doing loops discussed below; while, do while, for, and iter.
4.4.4.1 While Loop
A while loop in Nougat programming language like in most programming languages, is a control flow statement for creating a loop that executes a certain block or statement until the given condition is met.
while(<expression>)
<statement>
The example usage of while below creates a loop that repeats while the variable i has an integer value of less than 10.
fun main() {
var i = 0;
while(i < 10) {
render "The value is " + i + ".\n";
i = i + 1;
}
}
4.4.4.2 Do-While Loop
The do while loop is almost similar to a while loop, however, the only difference between the two is that, in do while the condition is checked after the block or statement, thus, guarantees block/statement's execution at least once.
do <statement>
while(<expression>);
An example of do while statement usage is shown below. (Derived from 4.4.4.1 While Loop's example.)
fun main() {
var i = 0;
do {
render "The value is " + i + ".\n";
i = i + 1;
} while(i < 10);
}
4.4.4.3 Iteration
The iter loop in Nougat is a loop control flow which has an identifier (as shown in the syntax below) that acts as placeholder of a value from the expression (that should be containing array) on every loop's execution.
iter(<identifier> of <expression>)
<statement>
Each value of array in the expression is automatically set as per execution of the statement, the value is then stored to the identifier that acts as the placeholder. The identifier's name cannot be used inside the statement of the iter itself as variable or lambda's name.
fun main() {
var array = &[ "Hello!", "Hi!", "Hola!" ];
iter(value of array)
render value + "\n";
}
4.4.4.4 Break and Continue
The break and continue are both always used inside a loop's block. break's main function is to stop a loop while the continue is used to continue the execution.
fun main() {
var i = 0;
while(true) {
if(i < 10) {
if(i % 2 == 0)
render "The even number is " + i + ".\n";
i = i + 1;
}
else if(i >= 10) break;
else continue;
}
}
Unlike other statements or conflow flows, these two doesn't require anything but a semicolon at the end. It is important to note that a continue statement will proceed for another execution of the loop and will not execute the following statement even though it belongs to the same block, additionally, the deferrals (which will be discussed on the next sub-section) will be skipped.
4.4.5 Error Handling
Error handling in Nougat is simple and easy to understand. Imagine throwing an error and attempt/try to catch if something was thrown, then finally do something after catching it. That's it! That's how error handling is done in Nougat.
4.4.5.1 Throwing Object
Any expression or value can be thrown in Nougat, this thrown object can be later on caught using a catch statement.
throw <expression>;
If a thrown object is not caught, then the execution will halt and an uncaught error message will be shown that contains the thrown object.
fun main() {
throw "This is just a throw example!";
}
4.4.5.2 Try, Catch, Finally
In Nougat error handling, like almost any other programming languages, it uses a try statement for the main execution block that tries to catch if any error will occur, then if an error was thrown, then the execution from the try statement will be aborted an will jump to the catch statement. In a catch statement, a symbol can be declared - this symbol will be used as placeholder of the thrown object. Lastly, a finally statement that follows a catch statement is used to finalize things up or to do some clean ups in the execution.
try <statement>
catch(<identifier>) <statement>
finally <statement>
Moreover, it is optional to declare. If no symbol declared to be used as placeholder, then the parenthesis must be omitted. Additionally, a finally statement is also optional, and can be added only if needed.
fun main() {
try {
throw "This is just a throw example!";
}
catch(errorMessage) {
render "The error caught was:\n\t" + errorMessage;
}
}
4.4.6 Go-thread Concurrency
The go threads in Nougat is a concept inspired from Go programming language. Intended for shorthand statement for creating concurrent executions via multi-threading.
go <statement>
In Golang, goroutines try to reduce the time and memory cost, however, in Nougat, go are OS threads.
fun main() {
go render "Hello\n";
go render "Hola\n";
}
4.4.7 Return Values
A return statement stops the execution of a function of where it is located, then returns the value of the object as value of the function after being called in a stack.
return <expression>;
If a return statement has no expression defined, it stops the function's execution and then automatically returns a nil value.
fun add(x, y) {
return x + y;
}
fun main() {
render "1 + 1 = " + add(1, 1);
}
4.4.8 Deferrals
The defer statements is commonly used for ensuring that a function has performed a clean-up. The defer statement are always executed after a statement block's execution with the queue sequence of FILO (first-in, last-out).
defer <statement>
However, it is also important to note that defer statements will be executed even before a return, break, continue, and throw statement will be executed.
fun main() {
defer render "World!";
defer render "Hello, ";
}
4.5 File Inclusion
In programming, file inclusion is a concept to organize functions and other definitions by separating it to different files and folders. In Nougat, file inclusions can be done by declaring it from the header of the file with the syntax below:
include "<file_path>";
include "<file_path>", "<file_path>", ...;
Including a multiple files is allowed as shown in the syntax below. However, it is also important to ensure the correct placement of files and folder to avoid future errors. Furthermore, all files the are included must end with the file extension ".nou".
hello.nou
fun hello() {
render "Hello from hello.nou file!";
}
main.nou
include "hello.nou"
fun main() {
hello();
}