Add special cases and return, and fix around

This commit is contained in:
Teascade 2017-08-27 20:41:54 +00:00
parent 17c9b4f2bc
commit f40b722f94

View File

@ -33,6 +33,7 @@ Table of contents for the Omega spec
- [Scopes](#scopes) - [Scopes](#scopes)
- [Parenthesis](#parenthesis) - [Parenthesis](#parenthesis)
- [Values](#values) - [Values](#values)
- [Special cases](#special-cases)
- [Keywords](#keywords) - [Keywords](#keywords)
## Examples ## Examples
@ -80,32 +81,32 @@ Unary operators have such examples as:
- `-` minus operator, negates the next value `-5` etc. - `-` minus operator, negates the next value `-5` etc.
Binary operators have such examples as: Binary operators have such examples as:
- `&&` AND operator, checks weather both sides of the operator are `true`. - `&&` AND operator, checks whether both sides of the operator are `true`.
- `+` plus-operator, adds both sides of the operator together. - `+` plus-operator, adds both sides of the operator together.
### Logical operators ### Logical operators
These are the operators ofthen called as "conditions" and most commonly used in if-statements and such. These are the operators ofthen called as "conditions" and most commonly used in if-statements and such.
- `&&` AND binary operator. Checks weather both sides of the operator are `true` - `&&` AND binary operator. Checks whether both sides of the operator are `true`
- `true && true` returns true - `true && true` returns true
- `false && true` return false - `false && true` return false
- `||` OR binary operator. Checks weather either side of the operator is `true` - `||` OR binary operator. Checks whether either side of the operator is `true`
- `true || true` returns true - `true || true` returns true
- `true || false` return true - `true || false` return true
- `^` XOR binary operator. Checks weather only one side of the operator is true. - `^` XOR binary operator. Checks whether only one side of the operator is true.
- `true ^ true` return false - `true ^ true` return false
- `true ^ false` returns true - `true ^ false` returns true
- `false ^ false` returns false - `false ^ false` returns false
- `==` Equals binary operator. Checks weather both sides of the operator are the same. - `==` Equals binary operator. Checks whether both sides of the operator are the same.
- `"not" == "test"` returns false - `"not" == "test"` returns false
- `3 == 3` returns true - `3 == 3` returns true
- `!=` Not equals binary operator. Checks weather both sides of the operator are **not** the same. - `!=` Not equals binary operator. Checks whether both sides of the operator are **not** the same.
- `"not" != "test"` returns true - `"not" != "test"` returns true
- `3 == 3` returns false - `3 == 3` returns false
- `!` Not unary operator. Negates the value associated with it. - `!` Not unary operator. Negates the value associated with it.
- `!true` returns false - `!true` returns false
- `!(true ^ true)` returns true - `!(true ^ true)` returns true
- `?` Optional-exists unary operator. Checks weather the operator-wrapped value before the operator is empty or not. - `?` Optional-exists unary operator. Checks whether the operator-wrapped value before the operator is empty or not.
- `empty?` returns false. See [`empty`](#empty)-keyword - `empty?` returns false. See [`empty`](#empty)-keyword
- `optional?` returns true, if optional contains a value. - `optional?` returns true, if optional contains a value.
@ -159,7 +160,6 @@ let first = i++; // first becomes 0, i increments to 1
let second = i--; // second becomes 1, i decrements back to 0. let second = i--; // second becomes 1, i decrements back to 0.
``` ```
## Scopes ## Scopes
Scopes are areas of code surrounded by brackets `{}`. E.g. Scopes are areas of code surrounded by brackets `{}`. E.g.
``` ```
@ -204,6 +204,18 @@ Values in Omega are strongly typed, meaning combining two different types cannot
### Conditions ### Conditions
For the sake of glossary, conditions can simply be `true` or `false`, but in all cases where "conditions" are said, [logical operators](#logical-operators) also apply. For the sake of glossary, conditions can simply be `true` or `false`, but in all cases where "conditions" are said, [logical operators](#logical-operators) also apply.
## Special cases
There are some special (mostly arithmetic) cases where different languages might act one way or another, so here are a list of those cases and how Omega handles them:
**Division by zero (`x / 0`)**
This causes a runtime exception.
**Modulo of zero (`x % 0`)**
This also causes a runtime exception, as can be deducted.
**Integer under-/overflow**
Trying to assign a number larger or smaller than the byte-limit of the type allows (ie. larger than `2147483647` for `i32` or smaller than `-2147483647`), will cause a runtime exception.
## Keywords ## Keywords
The following keywords are specified to execute an action. The following keywords are specified to execute an action.
@ -211,6 +223,7 @@ The following keywords are specified to execute an action.
- [`if`](#if) enters the scope once if the condition is met. - [`if`](#if) enters the scope once if the condition is met.
- [`else`](#else) enters the scope if the if before failed. - [`else`](#else) enters the scope if the if before failed.
- [`def`](#def) defines a new function. - [`def`](#def) defines a new function.
- [`return`](#return)
- [`while`](#while) functions like `if`, but enters the scope as long as the condition is met. - [`while`](#while) functions like `if`, but enters the scope as long as the condition is met.
- [`for`](#for) initializes a scope which will be ran a number of times specified after the `for`. - [`for`](#for) initializes a scope which will be ran a number of times specified after the `for`.
- [`break`](#break) breaks the loop prematurely. - [`break`](#break) breaks the loop prematurely.
@ -225,10 +238,11 @@ The following keywords are specified to execute an action.
Initializes a new variable, as such: Initializes a new variable, as such:
``` ```
let uninitialized: string; // Initializes this variable as string, but does not give it a value. let uninitialized: string; // Initializes this variable as string, but does not give it a value.
let five = 5; // Sets five to 5 let five = 5; // Sets five to 5
let var = "text"; // Sets var to "text" let var = "text"; // Sets var to "text"
let five = 6; // Causes an exception, cannot re-define five let five = 6; // Causes a compile-time error, cannot re-define five
five = 3; // (without let-keyword) Re-sets five to 3 five = 3; // (without let-keyword) Re-sets five to 3
let test_var = print("hi!"); // Causes a compile-time error; print has no return type definied.
``` ```
- Initialization of new variable **must** contain `let`, but re-definition of an existing variable, **cannot** start with `let`. - Initialization of new variable **must** contain `let`, but re-definition of an existing variable, **cannot** start with `let`.
- The name of the variable being defined must follow the `let` after whitespace. - The name of the variable being defined must follow the `let` after whitespace.
@ -237,6 +251,8 @@ five = 3; // (without let-keyword) Re-sets five to 3
- type-definition's form is as follows: `: T`, and it cannot be preceded by whitespace. between the colon and the `T` there may be whitespace. - type-definition's form is as follows: `: T`, and it cannot be preceded by whitespace. between the colon and the `T` there may be whitespace.
- After whitespace, there may be (or must be, if no type-definition is given), an equals`=`-sign, after which there must be more whitespace, after which the [value](#value) of the variable is given. This is simply an [assignment operator](#assignment-operators). - After whitespace, there may be (or must be, if no type-definition is given), an equals`=`-sign, after which there must be more whitespace, after which the [value](#value) of the variable is given. This is simply an [assignment operator](#assignment-operators).
- After the value of the variable, the `let`-expression **must** end in a semicolon `;`. - After the value of the variable, the `let`-expression **must** end in a semicolon `;`.
- If you try to set the value of a variable via a function that has no [return](#return) type defined, a compile-time error occurs.
- There is no "null- or void-type" in Omega.
#### `if` #### `if`
Defines an if-statement, which will, if the condition is met, enter the scope defined _after_ the if. Defines an if-statement, which will, if the condition is met, enter the scope defined _after_ the if.
@ -289,6 +305,17 @@ def second_function(param1: string) {
def third_function(param1: i32, param2: string) { def third_function(param1: i32, param2: string) {
// Code // Code
} }
def returning_function() -> i32 {
return 5; // Returns 5
}
def erronous_returning_function(param: boolean) -> i32 {
if (param) {
return 5;
}
// Causes a compile-time exception.
}
``` ```
- The signature of the function/method **must** begin with `def`. - The signature of the function/method **must** begin with `def`.
- After `def` there must be a number of whitespace, after which the name of the defined function must follow. - After `def` there must be a number of whitespace, after which the name of the defined function must follow.
@ -301,6 +328,26 @@ def third_function(param1: i32, param2: string) {
- After the list of parameters there **must** be a closing bracket `)`. - After the list of parameters there **must** be a closing bracket `)`.
- Between the parenthesis and the parameter-lists, there may be any number of whitespace. - Between the parenthesis and the parameter-lists, there may be any number of whitespace.
- After the parenthesis and any number of whitespace, there must be the [function body](#scopes). - After the parenthesis and any number of whitespace, there must be the [function body](#scopes).
- If the function [`return`](#return)s something, there must be a return-type definition (`-> T`) after the function signature (see 4th example).
- If return-type is definied, but some paths of the function will not [`return`](#return) anything, a compile-time error occurs (see 5th example).
#### `return`
Returns the value rightside to the keyword. Must be inside a function definition to use this.
```
def returns_i32() -> i32 {
return 5;
}
def returns_string() -> string {
return "Test!";
}
return 3; // Compile-time error; outside any function definition.
```
- Must be inside a function definition to use. If used outside any function definition, a compile-time exception occurs.
- There must be a space between `return` and the returned value.
- Must end in a semicolon`;`.
#### `while` #### `while`
Defines a loop which will be as long as the [condition](#conditions) defined after it is met. Defines a loop which will be as long as the [condition](#conditions) defined after it is met.
@ -323,7 +370,6 @@ while true == false {
- After the value there must be a [scope definition](#scopes). - After the value there must be a [scope definition](#scopes).
#### `for` #### `for`
**TODO: Decide weather to use C-style or Rust-style for-loops**
Defines a loop very similar to while, but which parameters inside the parenthesis consists of three parts separated by semicolons`;`. Defines a loop very similar to while, but which parameters inside the parenthesis consists of three parts separated by semicolons`;`.
``` ```
for (let i = 0; i < 10; i++) { for (let i = 0; i < 10; i++) {
@ -331,8 +377,8 @@ for (let i = 0; i < 10; i++) {
} }
``` ```
- The first part (`let i = 0` in this example) is the beginning-expression. It can be any expression, and it will be executed as the loop begins weather or not the scope inside the loop will be accessed. - The first part (`let i = 0` in this example) is the beginning-expression. It can be any expression, and it will be executed as the loop begins whether or not the scope inside the loop will be accessed.
- The second part (`i < 10` in this example) is the condition defining weather the loop-scope will be accessed or not. - The second part (`i < 10` in this example) is the condition defining whether the loop-scope will be accessed or not.
- The third part (`i++` in this example) is the step-expression, which will be executed after each execution of the loop-scope. - The third part (`i++` in this example) is the step-expression, which will be executed after each execution of the loop-scope.
- Another difference to while where parenthesis are **not** necessary, in `for`, te parenthesis around these three parts **are** necessary. - Another difference to while where parenthesis are **not** necessary, in `for`, te parenthesis around these three parts **are** necessary.
- Otherwise `for` is identical to [`while`](#while) - Otherwise `for` is identical to [`while`](#while)
@ -346,7 +392,7 @@ while (true) {
``` ```
- The break must end with a semicolon`;`. - The break must end with a semicolon`;`.
- If there is no loop and break is called, an exception occurs. - If there is no loop and break is called, a error occurs.
#### `continue` #### `continue`
Continue is a simple keyword to skip the rest of the loop's body. Continue is a simple keyword to skip the rest of the loop's body.
@ -358,7 +404,7 @@ while (true) {
``` ```
- The continue must end with a semicolon`;`. - The continue must end with a semicolon`;`.
- If there is no loop and continue is called, an exception occurs. - If there is no loop and continue is called, a compile-time error occurs.
#### `unwrap` #### `unwrap`
Unwrap is a keyword used to unwrap an optional variable. Unwrap is a keyword used to unwrap an optional variable.
@ -408,3 +454,5 @@ if (int_opt?) {
``` ```
- Before `as` there must be a variable, or a value, and after there must be the type which the value is attempted to be cast as. - Before `as` there must be a variable, or a value, and after there must be the type which the value is attempted to be cast as.
- If the rightside of the operator is not a type, a parse§ time error occurs.
.