Skip to content

Commit

Permalink
Add information about declarations and semicolon as end
Browse files Browse the repository at this point in the history
  • Loading branch information
H1ghBre4k3r committed Feb 23, 2023
1 parent 9f418c2 commit cc31d08
Showing 1 changed file with 60 additions and 5 deletions.
65 changes: 60 additions & 5 deletions README.md
Expand Up @@ -27,6 +27,18 @@ if 3 < 5 {
}
```

You can optionally explicitly end an expression with a semicolon:

```why
if 3 < 5 {
"foo"
} else {
"bar"
};
```

In some situations this is required, since Y would interpret the provided expressions in a different way. See section about functions.

### Variables

To store the values of expressions, you are able to declare variables:
Expand Down Expand Up @@ -89,11 +101,11 @@ let bar := if a > b {

Y supports a couple of primitive types which are build directly into the lanuage:

- `int` for numbers (current 32 bit)
- `str` for string **constants**
- `bool` for boolean values
- `void` for "empty" values
- functions (see later for information on how to declare a function type)
- `int` for numbers (current 32 bit)
- `str` for string **constants**
- `bool` for boolean values
- `void` for "empty" values
- functions (see later for information on how to declare a function type)

More complex types are subject for futures features.

Expand Down Expand Up @@ -124,6 +136,32 @@ let add := (x : int, y : int) : int => {

Function definitions work in a similar way like regular variable definitions, since functions are treated as first-class citizens in Y.

#### Call-Postfix

To call a function, you can postfix any expression which evaluates to a function (currently only identifiers) with `([param, [param, ...]])` to call it the given arguments.

This may lead to certain pitfalls, since Y is _not_ whitespace-sensitive! For example, the following will lead to a type error:

```why
let foo := (some_condition: bool) : int => {
if some_condition {
print("Condition is true!")
}
(3 + 4)
}
```

Here, `(3 + 4)` (although it is intended as the return expression of the function) is interpreted as a call to the result of the if expression. To prevent this, you have to explicitly terminate the if expression with a semicolon:

```why
let foo := (some_condition: bool) : int => {
if some_condition {
print("Condition is true!")
}; // <- semicolon to terminate expression
(3 + 4)
}
```

#### Function Type

If you want to declare a parameter of your function to be a function itself, you can do it like this:
Expand Down Expand Up @@ -166,6 +204,23 @@ Please note that all non-function-members of a module (i.e., all other variables

In the future, we plan to add support for exporting constants, but until then be aware of this limitation.

### Declarations

If you want to declare a function (or a variable) which is already pre-defined (or comes from another source), you can do so via the `declare` keyword. A declaration consists of the name of the variable to declare and a corresponding type annotation. E.g.:

```why
declare print : (str) -> void
```

### Builtins

Currently, Y provides two pre-defined functions: `print` (for printing strings) and `printi` (for printing numbers). To use them, you have to declare them somewhere in your program:

```
declare print : (str) -> void
declare printi : (int) -> void
```

## Pipeline

To turn a Y program into an executable (or interpret it), the compiler takes several steps.
Expand Down

0 comments on commit cc31d08

Please sign in to comment.