diff --git a/README.md b/README.md index 73f5e30..d9d0f6b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Rain programming language -![](icons/Rain-Logo.png) +![](icons/Rain-File-Icon.png) ## Why did i want to create "Rain"? @@ -9,4 +9,4 @@ My goal is to create a fast and better language for building games and apps in g **Files in [`src/`](src/) folder are not intended to be used for now**, it was used before for testing lexing of the language. -Here is the syntax I'm thinking to implement, of course that would happen far in the future: [language_syntax.rain file](language_syntax.rain). +Here is the syntax I'm thinking to implement, of course that would happen far in the future: [language_syntax file](language_syntax.md). diff --git a/language_syntax.md b/language_syntax.md new file mode 100644 index 0000000..8beee44 --- /dev/null +++ b/language_syntax.md @@ -0,0 +1,254 @@ +# Language Syntax of Rain Language + +This is file for showcasing the syntax of my programming language aka. Rain. Syntax is inspired from many languages, heavily Jai, Javascript, C++, and Wren. + +Enjoy! + +## Main function, everything starts from here: + +```rain +main :: () { + println("Hello world!"); +} +``` + +## Comments: + +In rain we accept only line comments: `// comment` + +## Variables: + +### Mutable variable + +```rain +x := 5; +``` + +### Constant + +```rain +y :: 6; +``` + +Specify variable like this: + +```rain +foo: int = 65; +bar := float(3); // will be turned into 3.0 +``` + +You can initialize multiple variables in the same line: + +```rain +x := 5, y := 5; +``` + +## Data Types: + +In Rain we have most of the known data types, known in diffrent languages. + +Integers: +| Signed | Unsigned | +| - | - | +| `i8` | `u8` | +| `i16` | `u16` | +| `int` | `u32` | +| `i64` | `u64` | + +Float: +- `f32` +- `f64` + +Text: +- `char` +- `string` + +## Functions: + +```rain +hello :: (name) { + println("Hello ${name}!"); +} + +hello("Sky"); // > "Hello Sky!" + +squared :: (x) { + x ** 2 +} + +println("The squared of 5 is: ${squared(5)}") // > "The squared of 5 is: 25" + +squared_by :: (x, y = 2) int { + return x ** y; +} +``` + +## Arrays: + +```rain +numbers := [0, 1, 2, 3, 4]; + +names : string[5] = []; + +names[0] = "Evry"; +names[1] = "Daniel"; +names[2] = "Chandler"; +``` + +## Objects: + +```rain +z :: object { + "foo": 1, + "bar": x, + "baz": 2 +} +``` + +## Structs: + +```rain +Vector2 :: struct { + x: int, + y: int, +} + +a := Vector2 { 6, 5 }; + +println(a.x); // > 6 + +println(a); // > Vector2 { x: 6, y: 5 } + +Vector2 : magnitude : () { + return int(sqrt(this.x * this.x + this.y * this.y)); +} + +println(a.magnitude()); // > 7.8 +``` + +## Fibers: + +Create a fiber like this: + +```rain +foo :: fiber { + println("Fiber called"); +} + +foo.call(); // > "Fiber called!" +``` + +Yielding: + +```rain +bar :: fiber { + println("passed to yield: {foo.call()}"); +} + +foo.yield("hello, world!"); // > "passed to yield: hello, world!" +``` + +## Operators: + +### `::` + +Initializator or `::` can be used to create a function, a struct or a constant that, like a struct and function, can't be modified after creation. + +```rain +x: int : 5 + +StructName : FuncName : () { + // do something... +} +``` + +### `:=` + +The second initializator (`:=`), also known as the walrus operator, creates a modifiable variable: + +```rain +x := 5; + +x: int = 5; + +x: int[] = []; +``` + +## Import and Modules + +in file.rain: + +```rain +pub foo :: () { + println("foo"); +} +``` + +in main.rain file: + +```rain +#import "file.rain" + +main :: () { + foo(); +} +``` + +## Conditional statements + +If statement: + +```rain +x := 5; +y := 3; + +if (x == y + 2) { + println("This is true!"); +} else { + println("This is false"); +} +``` + +For statement: + +For can be used to loop through arrays: + +```rain +number := [0, 1, 2, 3, 4, 5]; + +for num in numbers { + println(num); +} + +names := ["Sam", "Peter"] + +for i, name in names { + println("{i}) {name}"); + // > 0) Sam + // 1) Peter +} + +// range numbers +for i in 0 .. 5 { + print(i); +} +// > 01234 + +// or conditional looping, also known as `while` loop in other languages +sum := 0 +i := 0 + +for i <= 100 { + sum += i; + i++; +} +println(sum); // > 5050 +``` + +## References and heap + +```rain +x := 6; +``` + +I've formatted the provided text using the Markdown rules you've explained. Let me know if you need any further adjustments or assistance! diff --git a/language_syntax.rain b/language_syntax.rain index d9cf2c8..ecf6be0 100644 --- a/language_syntax.rain +++ b/language_syntax.rain @@ -1,5 +1,4 @@ -// main.rain file -// +//// Language Syntax // This is file for showcasing the syntax of my programming language aka. Rain. // Syntax is inspired from many languages, heavily Jai, Javascript, C++, and Wren. // @@ -8,9 +7,7 @@ /// Main function, everything starts from here: main :: () { - println("Hello world!") - - return 0 + println("Hello world!"); } /// Comments: @@ -20,32 +17,32 @@ main :: () { /// Variables: // Mutuable variable -x := 5 +x := 5; // Constant -y :: 6 +y :: 6; // Specify variable like this: -foo: int = 65 -bar := float(3) // will be turned into 3.0 +foo: int = 65; +bar := float(3); // will be turned into 3.0 // You can initliaze more variables in same line: -x := 5, y := 5 +x := 5, y := 5; /// Functions: hello :: (name) { - println("Hello ${name}!") + println("Hello ${name}!"); } -hello("Sky") // > "Hello Sky!" +hello("Sky"); // > "Hello Sky!" // squared2 :: (x) { -// return x ** 2 +// return x ** 2; // } -// In Rain if you want to just straight up return the value (with calculations or not), just write it, and forget the return keyword: +// In Rain, same as in Rust, if you want to just straight up return the value (with calculations or not), just write it, and forget the return keyword: squared :: (x) { x ** 2 } @@ -56,19 +53,19 @@ println("The squared of 5 is: ${squared(5)}") // > "The squared of 5 is: 25" // Optional arguments need a default value (like you can see on y argument), and if you want you want specify what return value will be, just add the variable type after parantheses: squared_by :: (x, y = 2) int { - return x ** y + return x ** y; } /// Arrays: -numbers := [0, 1, 2, 3, 4] +numbers := [0, 1, 2, 3, 4]; -names : string[5] = [] +names : string[5] = []; -names[0] = "Evry" -names[1] = "Daniel" -names[2] = "Chandler" +names[0] = "Evry"; +names[1] = "Daniel"; +names[2] = "Chandler"; /// Objects: @@ -82,15 +79,15 @@ z :: object { Vector2 :: struct { - x: int; - y: int; + x: int, + y: int, } -a := Vector2 { 6, 5 } +a := Vector2 { 6, 5 }; -println(a.x) // > 6 +println(a.x); // > 6 -println(a) // > Vector2 { x: 6, y: 5 } +println(a); // > Vector2 { x: 6, y: 5 } // Functions for structs: @@ -98,25 +95,25 @@ Vector2 : magnitude : () { return int(sqrt(this.x * this.x + this.y * this.y)); } -println(a.magnitude()) // > 7.8 +println(a.magnitude()); // > 7.8 /// Fibers: // Create a fiber like this: foo :: fiber { - println("Fiber called") + println("Fiber called"); } // And call it: -foo.call() // > "Fiber called!" +foo.call(); // > "Fiber called!" // Yielding: bar :: fiber { - println("passed to yield: {foo.call()}") + println("passed to yield: {foo.call()}"); } -foo.yield("hello, world!") // > "passed to yield: hello, world!" +foo.yield("hello, world!"); // > "passed to yield: hello, world!" /// Operators: @@ -138,12 +135,12 @@ StructName : FuncName : () { // `:=`: // The second initializator (`:=`) also known as walrus operator, creates a modifiable variable: -x := 5 +x := 5; // You can specify the variable type before the `=` operator: -x: int = 5 +x: int = 5; -x: int[] = [] +x: int[] = []; /// Import and Modules @@ -157,19 +154,19 @@ pub foo :: () { #import "file.rain" main :: () { - foo() + foo(); } /// Condtional statements // If statmenet -x := 5 -y := 3 +x := 5; +y := 3; if (x == y + 2) { - // true + println("This is true!"); } else { - // false + println("This is false"); } @@ -177,23 +174,23 @@ if (x == y + 2) { // for can be used to loop trought arrays: -number := [0, 1, 2, 3, 4, 5] +number := [0, 1, 2, 3, 4, 5]; for num in numbers { - println(num) + println(num); } names := ["Sam", "Peter"] for i, name in names { - println("{i}) {name}") + println("{i}) {name}"); // > 0) Sam // 1) Peter } // range numbers for i in 0 .. 5 { - print(i) + print(i); } // > 01234 @@ -202,14 +199,14 @@ sum := 0 i := 0 for i <= 100 { - sum += i - i++ + sum += i; + i++; } -println(sum) // > 5050 +println(sum); // > 5050 /// References and heap -x := 6 +x := 6; diff --git a/src/rain/mod.rs b/src/rain/mod.rs index f85de51..f5e3169 100644 --- a/src/rain/mod.rs +++ b/src/rain/mod.rs @@ -57,6 +57,9 @@ pub enum TokenType { Public, // pub Enum, // enum + Return, // return keyword + Null, // null = the nothing keyword + Unknown, } @@ -268,6 +271,8 @@ impl<'a> Lexer<'a> { } match ident.as_str() { + "return" => TokenType::Return, + "null" => TokenType::Null, "if" => TokenType::If, "else" => TokenType::Else, "for" => TokenType::For, diff --git a/test/test.rain b/test/test.rain index e46aecd..4b00427 100644 --- a/test/test.rain +++ b/test/test.rain @@ -2,8 +2,8 @@ Vector2 :: struct { - x: int; - y: int; + x: int, + y: int, } main :: () {