diff --git a/docs/grammar.md b/docs/grammar.md new file mode 100644 index 0000000..919afff --- /dev/null +++ b/docs/grammar.md @@ -0,0 +1,174 @@ +# Grammar for Radish + +> Extremely experimental and subject to completely change + +## Hello World + +```rd +// import io +const io = #import("io"); + +// print hello world +pub fn main() -> { + io.println(stdout, "hello, world!"); +} +``` + +## Variables + +```rd +pub fn main() -> { + // default immutable + let x = 3; + // mut keyword gains mutability + let mut y = 4; + + y += x; + + // non-null by default + let z? = nil; + + // type can be explicitly denoted with `let <name>: <type>` + let score: i32 = 10; + + // strings are by default 0 terminated u8 array + let str = "hello world"; + + // explicit 0 terminated + let greet: u8[:0] = "hello world"; + + // explicit 2 terminated + let greet2: u8[:2] == "hello again"; +} +``` + +## some maths + +```rd +fn x3summation(n: i32) i32 -> { + return n * (n + 1) * (2 * n - 1) / 3; +} +``` + +```rd +// can use single statement instead of block +fn abs_deg(deg: f64) f64 -> deg % 360; +``` + +## if statements + +```rd +fn greet(is_human: bool) -> { + if is_human { + io.println(stdout, "Hello, human!"); + } else { + io.println(stdout, "Hello, robot!"); + } +} +``` + +``` +fn greet_more(is_human: bool) -> { + // if statements can return values + let target = if is_human "human" else "robot"; + io.println(stdout, "Hello, {s}!", target); +} +``` + +## Loops + +``` +fn game_loop() -> { + loop { + game_logic(); + + if need_exit() { + break; + } + } +} +``` + +``` +fn number_print() -> { + for i in 0..=10 { + if i == 3 { + continue; + } + + // prints 0 to 10 inclusive + io.println(stdout, "{}", i); + } +} +``` + +## Union return + +``` +fn read_input() u8[:0] | IOErr -> { + // takes input from stdin until newline or eof, no newline included + return io.scan_line(stdin, 0); +} +``` + +## Switch case + +``` +fn number(n :i32) u8[:0] -> { + return match n { + 0 -> "zero"; + 1 -> "one"; + 2..=9 -> "single digits"; + n >= 10 -> "big numbers"; + _ -> "negative numbers"; + } +} +``` + +## Pattern matching + +```rd +struct User { + name: u8[:0] +} + +fn username() User | CreationFailed -> { + // pattern match to return username or failed + return match io.scan_line(stdin, 0) { + u8[] line -> User{name: line}; + IOErr -> CreationFailed{err.st()}; + } +} +``` + +## Type Alias + +```rd +type Success = i32; +type Failure = IOErr | ParseErr | UserNotFoundErr; +type Signal = Success | Failure; + +fn get_a_signal() Signal -> { + // do a lot of stuff + // open files + if cannot_open return IOErr{err.st()}; + + // parse data + if failed_parsing return ParseErr{err.st()}; + + // get user + if cannot_find_user return UserNotFoundErr{err.st()}; + + // integer data found + return data; +} + +fn signal_handler(signal: Signal) -> { + match signal { + Success data -> io.println(stdout, "{}", data); + UserNotFoundErr -> io.println(stdout, "user not found"); + _ -> io.println(stdout, "internal error"); + } +} +``` +