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 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. 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 #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: 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 { if 5 > 0 {
x = 2; x = 2;
} }
@@ -57,7 +57,7 @@ is valid code, while
``` ```
if 3 < 10 { if 3 < 10 {
let y int = 288; let y: int = 288;
} }
y = 10; 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: 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); print(y);
} }
#y is now undefined again here #y is now undefined again here
{ {
let y real = 0.2; let y: real = 0.2;
print(y); 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 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 myreal: real = 1.5;
let myint int = int(myreal); let myint: int = int(myreal);
``` ```
Right now, strings are implemented as direct counterparts to `char*` in C, which is what they 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. 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) 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: functions. Here's an example:
``` ```
let x int = 6; let x: int = 6;
let ref_to_x ref(int) = ref(x); let ref_to_x: ref(int) = ref(x);
let y int = deref(ref_to_x) # same as y = 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 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: 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 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 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 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: 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; 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: 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 { class User {
age int age: int
name string name: string
mail_verified bool 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. 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 Class types can be used anywhere primitive types can, such as function arguments
@@ -200,13 +200,13 @@ member's value.
``` ```
class User { class User {
age int age: int
name string name: string
mail_verified bool mail_verified: bool
immutable id int immutable id: int
} }
fn change_values(u User) { fn change_values(u: User) {
u.age = 10; u.age = 10;
u.name = "new name"; u.name = "new name";
u.id = 0; 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. of them separated by a space.
``` ```
let x int = 144; let x: int = 144;
print(x, 240); 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: `if`, `else` and `elif` statements are fully implemented and are written like this:
``` ```
let x int = 17; let x: int = 17;
if x >= 100 { if x >= 100 {
print(x, "is greater than 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: `while` loops are very similar, and can be written like this:
``` ```
let i int = 0; let i: int = 0;
while i < 10 { while i < 10 {
print(i); print(i);
i++; i++;

View File

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

View File

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