254 lines
5.4 KiB
Markdown
254 lines
5.4 KiB
Markdown
|
|
# One
|
|
|
|
One is a statically typed language inspired by C, V, and go.
|
|
The compiler is still in development, and may present issues when compiling One code.
|
|
Note that you need to have eitehr gcc or clang installed to compile One code, as the compiler
|
|
produces C code that later gets compiled to an executable.
|
|
|
|
---
|
|
|
|
## Syntax
|
|
|
|
One's syntax rules are meant to be easily understandable and, more importantly, never ambiguous.
|
|
|
|
---
|
|
|
|
### Variables
|
|
|
|
In One, variables are declared with the `let` keyword.
|
|
The syntax will look something like this
|
|
|
|
```
|
|
let x int = 6;
|
|
```
|
|
|
|
You can also declare a constant using the `const` keyword instead.
|
|
|
|
```
|
|
const x int = 9;
|
|
```
|
|
---
|
|
|
|
### Comments
|
|
|
|
Comments in One start with a # and end with another # or a newline
|
|
|
|
```
|
|
#this is a comment
|
|
let a #this is also a comment# int = 9;
|
|
```
|
|
|
|
---
|
|
|
|
### Scopes
|
|
|
|
Like in most languages, variables in One are only limited to their scope.
|
|
You can access a variable from a deeper nested scope, but not the opposite:
|
|
|
|
```
|
|
let x int = 5;
|
|
if 5 > 0 {
|
|
x = 2;
|
|
}
|
|
```
|
|
|
|
is valid code, while
|
|
|
|
```
|
|
if 3 < 10 {
|
|
let y int = 288;
|
|
}
|
|
y = 10;
|
|
```
|
|
|
|
isn't valid, as the variable `y` cannot be access outside its scope.
|
|
|
|
You can also create scopes by wrapping statements in braces. This lets you declare
|
|
variables with the same name in different scopes, for example:
|
|
|
|
```
|
|
let x int = 3
|
|
{
|
|
let y real = 5.5;
|
|
print(y);
|
|
}
|
|
#y is now undefined again here
|
|
{
|
|
let y real = 0.2;
|
|
print(y);
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Primitive Types
|
|
|
|
As of now, One has a total of 4 primitive types: `void`. `int`, `real`, `bool` and `string`.
|
|
There are no methods for types, but you can cast a variable to one of them with this syntax
|
|
|
|
```
|
|
let myreal real = 1.5;
|
|
let myint int = int(myreal);
|
|
```
|
|
|
|
Right now, strings are implemented as direct counterparts to `char*` in C, which is what they
|
|
get translated to during compilation. Comparisons and operations on strings are still work in progress
|
|
and quite buggy, but you are free to use string literals for prints or simple variable declarations with no issues.
|
|
Variables cannot be declared with type `void`.
|
|
|
|
The `string` type actually behaves similarly to how a class would. While using the variable directly
|
|
gives you access to the actual string (which in C corresponds to the `char*`), you can use `.len` to
|
|
get the length of the string. Note that `len` is an immutable member, so you cannot maually set it.
|
|
|
|
```
|
|
let mystring string = "this is my string";
|
|
print(mystring, mystring.len)
|
|
```
|
|
|
|
produces this output:
|
|
|
|
```
|
|
this is my string 17
|
|
```
|
|
|
|
---
|
|
|
|
### Functions
|
|
|
|
Functions in One are very similar to what you see in languages such as go.
|
|
You declare a function called `foo` which takes an `int` and returns a `bool` with the following syntax:
|
|
|
|
```
|
|
fn foo(myarg int) bool {
|
|
return myarg < 10;
|
|
}
|
|
```
|
|
|
|
If a function is not expected to return anything, the return type must be `void`.
|
|
|
|
Calling a function looks like this:
|
|
|
|
```
|
|
let b bool = foo(9);
|
|
```
|
|
|
|
---
|
|
|
|
### Classes
|
|
|
|
Right now, Classes in One are very similar to C structs. They are declared using the `class` keyword
|
|
followed by the class name and a block with a list of class members.
|
|
Defining a class User might look something like this:
|
|
|
|
```
|
|
class User {
|
|
age int
|
|
name string
|
|
mail_verified bool
|
|
}
|
|
```
|
|
|
|
Creating an instance of a class is very simple, just write the name of the class
|
|
followed by braces and a list of initial values for the class members.
|
|
|
|
```
|
|
let myuser User = User{17, "uan", false}
|
|
```
|
|
|
|
Class types can be used anywhere primitive types can, such as function arguments
|
|
or other classes' members.
|
|
|
|
Class members can be defined as immutable with the `immutable` keyword before the member name.
|
|
This is checked at compile time and prevents that member's value to be changed after instantiation.
|
|
For example, this code would trigger a parse error, `as u.id = 0` attempts to change an immutable
|
|
member's value.
|
|
|
|
```
|
|
class User {
|
|
age int
|
|
name string
|
|
mail_verified bool
|
|
immutable id int
|
|
}
|
|
|
|
fn change_values(u User) {
|
|
u.age = 10;
|
|
u.name = "new name";
|
|
u.id = 0;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Print
|
|
|
|
Printing is still a work in progress feature, but right now you can print any primitive and non-primitive type.
|
|
The 'print' built-in function accepts a variable number of arguments, and will print allf
|
|
of them separated by a space.
|
|
|
|
```
|
|
let x int = 144;
|
|
print(x, 240);
|
|
```
|
|
|
|
produces this output:
|
|
|
|
```
|
|
144 240
|
|
```
|
|
|
|
class-type variables will be printed with special formatting which, if we takes
|
|
the User class and variable we defined earlier, will look like this.
|
|
|
|
```
|
|
User {
|
|
age: 17
|
|
name: uan
|
|
mail_verified: false
|
|
}
|
|
```
|
|
|
|
### Control Flow
|
|
|
|
Control flow in One isn't fully implemented yet, but it is already functional.
|
|
`if`, `else` and `elif` statements are fully implemented and are written like this:
|
|
|
|
```
|
|
let x int = 17;
|
|
|
|
if x >= 100 {
|
|
print(x, "is greater than 100");
|
|
} elif x >= 10 {
|
|
print(x, "is greater than 10"):
|
|
} else {
|
|
print(x, "is less than 10");
|
|
}
|
|
```
|
|
|
|
`while` loops are very similar, and can be written like this:
|
|
|
|
```
|
|
let i int = 0;
|
|
while i < 10 {
|
|
print(i);
|
|
i++;
|
|
}
|
|
```
|
|
|
|
### The main function
|
|
|
|
It is important that every One program has an entry point called `main`.
|
|
The 'main' function must always return `int` and does not accept any arguments.
|
|
|
|
```
|
|
fn main() int {
|
|
#my code here
|
|
}
|
|
```
|
|
|
|
It isn't necessary to explicitly insert a `return` statement in the main function.
|
|
Returning from the main function will exit the program with an exit code equal
|
|
to the returned integer.
|
|
|