syntax now requires : before type in declarations

This commit is contained in:
uan
2026-02-08 08:40:49 +01:00
parent 7b5eef3bcb
commit 294fbbd69c
3 changed files with 37 additions and 31 deletions

View File

@@ -20,13 +20,13 @@ In One, variables are declared with the `let` keyword.
The syntax will look something like this
```
let x int = 6;
let x: int = 6;
```
You can also declare a constant using the `const` keyword instead.
```
const x int = 9;
const x: int = 9;
```
---
@@ -36,7 +36,7 @@ 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;
let #also a comment# a: int = 9;
```
---
@@ -47,7 +47,7 @@ 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;
let x: int = 5;
if 5 > 0 {
x = 2;
}
@@ -57,7 +57,7 @@ is valid code, while
```
if 3 < 10 {
let y int = 288;
let y: int = 288;
}
y = 10;
```
@@ -68,14 +68,14 @@ You can also create scopes by wrapping statements in braces. This lets you decla
variables with the same name in different scopes, for example:
```
let x int = 3
let x: int = 3
{
let y real = 5.5;
let y: real = 5.5;
print(y);
}
#y is now undefined again here
{
let y real = 0.2;
let y: real = 0.2;
print(y);
}
```
@@ -88,8 +88,8 @@ As of now, One has a total of 4 primitive types: `void`. `int`, `real`, `bool` a
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);
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
@@ -102,7 +102,7 @@ gives you access to the actual string (which in C corresponds to the `char*`), y
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";
let mystring: string = "this is my string";
print(mystring, mystring.len)
```
@@ -123,9 +123,9 @@ and to prevent this, One has designated `ref` and `deref` keywords that are mean
functions. Here's an example:
```
let x int = 6;
let ref_to_x ref(int) = ref(x);
let y int = deref(ref_to_x) # same as y = x
let x: int = 6;
let ref_to_x: ref(int) = ref(x);
let y: int = deref(ref_to_x) # same as y = x
```
References to objects are again quite similar to C, with the only real difference being
@@ -134,13 +134,13 @@ reference to an object with the `.` notation. But you cannot access the members
reference nesting goes further. For example:
```
let u User = User{17} #user has age 17
let u: User = User{17} #user has age 17
print(u.age) # outputs 17
let ref_to_u ref(User) = ref(u)
let ref_to_u: ref(User) = ref(u)
print(ref_to_u.age) # outputs 17
let nested_ref ref(ref(User)) = ref(ref_to_u)
let nested_ref: ref(ref(User)) = ref(ref_to_u)
print(nested_ref.age) # not valid
```
@@ -154,7 +154,7 @@ 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 {
fn foo(myarg: int) bool {
return myarg < 10;
}
```
@@ -164,7 +164,7 @@ 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);
let b: bool = foo(9);
```
---
@@ -177,9 +177,9 @@ Defining a class User might look something like this:
```
class User {
age int
name string
mail_verified bool
age: int
name: string
mail_verified: bool
}
```
@@ -187,7 +187,7 @@ 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}
let myuser: User = User{17, "uan", false}
```
Class types can be used anywhere primitive types can, such as function arguments
@@ -200,13 +200,13 @@ member's value.
```
class User {
age int
name string
mail_verified bool
immutable id int
age: int
name: string
mail_verified: bool
immutable id: int
}
fn change_values(u User) {
fn change_values(u: User) {
u.age = 10;
u.name = "new name";
u.id = 0;
@@ -238,7 +238,7 @@ The 'print' built-in function accepts a variable number of arguments, and will p
of them separated by a space.
```
let x int = 144;
let x: int = 144;
print(x, 240);
```
@@ -265,7 +265,7 @@ 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;
let x: int = 17;
if x >= 100 {
print(x, "is greater than 100");
@@ -279,7 +279,7 @@ if x >= 100 {
`while` loops are very similar, and can be written like this:
```
let i int = 0;
let i: int = 0;
while i < 10 {
print(i);
i++;

View File

@@ -177,6 +177,7 @@ fn lex(input string) ?[]Token {
right++
if ['#', '\n'].contains(input[right].ascii_str()) {
is_inside_comment = false
right++
}
left = right
}

View File

@@ -474,6 +474,8 @@ fn (mut p Parser) parse_class_member() ClassMember {
member_name := p.peek().text
p.expect(.identifier)
p.expect(.colon)
type_tok := p.next()
type_name := match type_tok.type {
.type {type_tok.text}
@@ -741,6 +743,7 @@ fn (mut p Parser) parse_var_decl(is_const bool) VarDecl {
if name_tok.type != .identifier {
parse_error("Expected variable name after let")
}
p.expect(.colon)
type_tok := p.next()
type_name := match type_tok.type {
@@ -816,6 +819,8 @@ fn (mut p Parser) parse_func_decl() FuncDecl {
}
p_name := p.next().text
p.expect(.colon)
type_tok := p.next()
p_type := match type_tok.type {
.type {type_tok.text}