From f40b722f94ed64579203b6f2958e8059af19d5fb Mon Sep 17 00:00:00 2001 From: Teascade Date: Sun, 27 Aug 2017 20:41:54 +0000 Subject: [PATCH] Add special cases and return, and fix around --- README.md | 82 +++++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 65 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 38fa63b..d253a9f 100644 --- a/README.md +++ b/README.md @@ -33,6 +33,7 @@ Table of contents for the Omega spec - [Scopes](#scopes) - [Parenthesis](#parenthesis) - [Values](#values) +- [Special cases](#special-cases) - [Keywords](#keywords) ## Examples @@ -80,32 +81,32 @@ Unary operators have such examples as: - `-` minus operator, negates the next value `-5` etc. 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. ### Logical operators 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 - `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 || 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 ^ false` returns true - `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 - `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 - `3 == 3` returns false - `!` Not unary operator. Negates the value associated with it. - `!true` returns false - `!(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 - `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. ``` - ## Scopes 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 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 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. - [`else`](#else) enters the scope if the if before failed. - [`def`](#def) defines a new function. +- [`return`](#return) - [`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`. - [`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: ``` let uninitialized: string; // Initializes this variable as string, but does not give it a value. -let five = 5; // Sets five to 5 -let var = "text"; // Sets var to "text" -let five = 6; // Causes an exception, cannot re-define five -five = 3; // (without let-keyword) Re-sets five to 3 +let five = 5; // Sets five to 5 +let var = "text"; // Sets var to "text" +let five = 6; // Causes a compile-time error, cannot re-define five +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`. - 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. - 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 `;`. +- 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` 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) { // 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`. - 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 `)`. - 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). +- 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` 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). #### `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`;`. ``` 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 second part (`i < 10` in this example) is the condition defining weather the loop-scope will be accessed or not. +- 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 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. - 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) @@ -346,7 +392,7 @@ while (true) { ``` - 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 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`;`. -- 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 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. +- If the rightside of the operator is not a type, a parse§ time error occurs. +.