diff --git a/README.md b/README.md index ce16128..81b9758 100644 --- a/README.md +++ b/README.md @@ -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++; diff --git a/lexer.v b/lexer.v index f6d45c1..b945ea6 100644 --- a/lexer.v +++ b/lexer.v @@ -177,6 +177,7 @@ fn lex(input string) ?[]Token { right++ if ['#', '\n'].contains(input[right].ascii_str()) { is_inside_comment = false + right++ } left = right } diff --git a/parser.v b/parser.v index f594678..4755a4b 100644 --- a/parser.v +++ b/parser.v @@ -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}