diff --git a/README.md b/README.md index 66324e6..2ba9cbc 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,12 @@ Welcome to Bits Runner Builder! - [Detailed Syntax](Syntax.md) ## Overview -Bits Runner Builder (brb) is a compiler for Bits Runner Code (brc) language, which has been designed for the Bits Runner Builder operating system. It aims to be an opinionated, low-level language, a sort of improved C while providing a revised syntax and a couple of quality of life improvement. It's a simple system programming language, so no class hierarchies, templates, or other unnecessary fluff. +Bits Runner Builder (brb) is a compiler for Bits Runner Code (brc) language, which has been designed for the Bits Runner operating system. It aims to be an opinionated, low-level language, a sort of improved C while providing a revised syntax and a couple of quality of life improvement. It's a simple system programming language, so no class hierarchies, templates, or other unnecessary fluff. It has been been built with LLVM so it should be fairly performant. ## Main features -It should allow for low-level system programming, so one of the main features is a seamless support for embeded assembly, pointers mainipulation and explicit data handling. For this reason data types have explicit byte-sizes, there is no runtime and the memory is manually managed. +BRC allows for low-level system programming, so one of the main features is a seamless support for embeded assembly, pointers mainipulation and explicit data handling. For this reason data types have explicit byte-sizes, there is no runtime and the memory is manually managed. The language aims to be simple, easy to reason about and predictable. For this reason there a class-like features, but no inheritance. Composition is much better anyway and doesn't lead to incomprehensible codebases (did I mention that it's opinionated?). diff --git a/Reference.md b/Reference.md index 837aec1..c57cd0b 100644 --- a/Reference.md +++ b/Reference.md @@ -1,21 +1,41 @@ -# Fatures Description +# BRC Language Reference -## List language elements -- Literals -- Variables - - Integers (signed & unsigned) - - Floating points - - Data (array type) - - Type (structure type) - - Pointers -- Functions -- Conditions -- Repeat (loop) -- Modules -- Comments +## Overview +Bits Runner Code (BRC) borrows a lot of concepts and syntax from C, but in a slightly modified way. The idea is to use familiar concept in a simplified way, avoiding usage of unnecessary fluff and just to make the code simpler and shorter, while avoiding any unambigouity. + +Semicolons are not placed at the end of statements, but instead they delimit blocks, such as body of a function or a loop. There are no curly brackets. They are not necessary if you, for example, declare an external method or have an `if` expression in a single line. Round brackets `()` are also not ncessary in most of the cases, for example when defining a function or evaluating a condition, but are required for function calls. New lines also play important role and may be required or invalid, depending on the context. + +Single equal sign `=` denotes comparion and instead left arrow `<-` is used as an assign symbol. + +Source code is grouped into named modules, each module can be compromised of number of files. There is no separate header file, instead prefix `@pub` if attached to externally visible symbols. + +## Language Elements +- Comments (`//`, `/* */`) +- Literals (`123`, `0xa2`, `0b0101`, `3.14`, `"Hello"`, `'!'`, `true`, `false`) +- Operators (`+`, `-`, `*`, `/`, `%`, `<-`, `<`, `<=`, `>`, `>=`, `=`, `!=`) +- Variables (`u8`, `u32`, `s8`, `s32`, `r32`, `data`, `blob`) +- Functions (`fun`) +- Raw Functions (`raw`) +- Conditional Expressions (`if`, `else`) +- Loops (`rep`) + +## Comments +Like in C, comments can specified using either `\\` which will run until the end of the line or through `/* */` block. However, unlike C, the `/* bla bla /* bla */ */` comments can be also embeded inside each other. +``` +// this is a main function +main fun -> u32 + /* + num1 <- 2 + 5 + /* num1 <- 4 * num1 */ + // num1 <- 5 * num1 + */ + ret 0 +; + +``` ## Literals -**Number literals** can be specified as decimal, hexadecimal, and binary numbers. Digits can be separated by an '_' but it cannot be the first or the last character (otherwise it will get interpreted as and identifier). +**Number literals** can be specified as decimal, hexadecimal, and binary numbers. Digits can be separated by an '_' but it cannot be the first or the last character (otherwise it will get interpreted as an identifier). ``` // Valid examples: @@ -41,31 +61,180 @@ _100 _0b1101 ``` -## Functions +**Text literals** can be specified either as an implicitly zero terminated string, or as a single character. Strings are converted into arrays. Characters can be also backslash '\' escaped, just like in C. +``` +// Examples +"Hello world" +"Hello world\0" // in this case, the final zero is not appended +'H' +'!' +'\n' -## Conditions -If-Else statements can be written on a single or multiple lines and are an expression, which allows for something like this: +// Escape sequences +'\b' // backspace +'\n' // new line +'\t' // tab +'\\' // backslash +'\'' // single quotation mark +'\"' // double quotiation mark +'\0' // 0 (as in integer 0) +``` + +**Boolean literals** can also be specified using `true` or `false` keywords. There is no implicit conversion from integer to boolean and vice-versa. + +## Operators +All the standard operators, such as `+`, `-`, `*`, `/`, `%` are available. The biggest difference is that the assignment uses the left arrow `<-` and thus a comparison can be done through a single equal sign `=`. +``` ++ // addition +- // subtraction +* // multiplication +/ // division +% // division reminder += // is equal +!= // is not equal +< // is less than +<= // is less or equal +=> // is greater than +> // is gearter or equal +<- // assignment +( ) // precdence +``` + +## Variables +Variables are specified by first providing the name and then the type. There is also an optional initializer. +``` +bytesInKilobyte u32 <- 1_024 +text data <- "Hello world!" +pi r32 <- 3.14 +``` + +**Simple variables** +There are standard float and integer types available, but unlike in C, you have to be explicit about their size and signiness. You can only perform `=` and `!=` operations on booleans. There is no `void` type or an equivalent. +``` +u8 // unsigned integer, 8 bits +u32 // unsigned integer, 32 bits +s8 // signed integer, 8 bits +s32 // signed integer, 32 bits +r32 // floating point (real), 32 bits +bool // true or false +``` + +**Data variables** or arrays, as known in C. They are a sequence of static length or elements of the same type. Length has to be specified either explicitly or through and initializer. +``` +text data <- "Hello world!" +fibonaciNumbers <- [1, 1, 2, 3, 5, 8] // Anything past the first 4 numbers will be ignored +``` + +**Blob variables**, otherwise known as structures. Composite types which we can specify by ourselves. The usage is fairly smillar as in C. Semicolon and new line are required in the definition. +``` +user blob + age u32 + name data + isActive bool +; + +bob user +bob.age <- 18 +bob.name <- "Bob" +bob.isActive <- true +``` + +## Functions +Functions in BRC work just like in C. You can specify an optional list of arguments and a return type. Calls require usage of round brackets. Colon should be omitted if there are no arguments. Arrow has to be on the same line as the return type. +``` +// Valid examples +main fun -> u32 + ret 0 +; + +addNums fun: num1 s32, s32 -> s32 + ret num1 + num2 +; + +addNums fun: + num1 s32, + num2 s32 + -> s32 + + ret num1 + num2 +; + +addNums(5, 4) + +logInUser fun: user User + // do some internet stuff 📡 +; + +logInUser(bob) + +explodeEverything fun + // Do a boom! 💥 +; + +explodeEverything() + +// Invalid examples +addNums num1 s32, num2 s32 -> s32 +[..] + +addNums: num1 s32 + ,num2 s32 -> s32 +[..] + +addNums: num1 s32, num2 s32 -> + s32 +[..] +``` + +## Raw Functions +A unique feature of BRC is a seamless use of inline assembly. Raw functions can be used just like normal functions, altoght there is a couple of limitations and they require so called constraints to be specified. It's the same as in gcc or clang, but they are specified as a single string instead of splitting them into input, output, and clobbers. Some more information can be found here [A Practical Guide to GCC Inline Assembly](https://blog.alex.balgavy.eu/a-practical-guide-to-gcc-inline-assembly/). Intel syntax is used for the assembly. +``` +rawAdd raw<"=r,r,r">: num1 u32, num2 u32 -> u32 + add $1, $2 + mov $0, $1 +; + +// later on +result u32 <- rawAdd(5, 4) +``` + +## Conditional Expressions +If-Else statements can be written on a single or multiple lines and are an expression, which allows them to return values. ``` isValid bool <- if count = 0: doForEmpty() else doForCount(count) + +if numer > 0: + doStuff(number) +else + fatalError() +; + +if featureFlag: + // Special case ⚰️ +; + +if hasCompleted: exit() + +if processedElementsCount < 10: print("Success) else + print("Failure") + processFailure(processedElementsCount) +; ``` -## Repeats -C-style for, while, and do-while are all combined into a single `rep` loop. The format is `rep init, pre-condition, post-condition`. `init` allows to setup a counter, pre-condition is evaluated before and post after each loop. Each part is optional, but if you include post-condition, pre-condition must also be include. Some examples: +## Loops +C-style for, while, and do-while are all combined into a single `rep` loop. The format is `rep init, pre-condition, post-condition`. `init` allows to setup a counter, pre-condition is evaluated before and post after each loop. Each part is optional, but if you include post-condition, pre-condition must also be include. Body can be specified on the same line as the loop, in which case the final semicolon should not be included. ``` // infinite loop rep: doStuff() // do things ten times -rep i s32 <- 0, i < 10: +rep i u32 <- 0, i < 10: doStuff(i) i <- i + 1 ; // do things at least once -rep i s32 <- 0, true, i < someValue: +rep i u32 <- 0, true, i < someValue: doStuff(i) ; ``` - -## Comments -Like in C, comments can specified using either `\\` which will run until the end of the line or through `/* */` block. However, unlike C, the `/* bla bla /* bla */ */` comments can be also embeded inside each other. diff --git a/src/Parser/Parser.cpp b/src/Parser/Parser.cpp index 2720985..bd27bed 100644 --- a/src/Parser/Parser.cpp +++ b/src/Parser/Parser.cpp @@ -253,8 +253,8 @@ shared_ptr Parser::matchStatementFunction() { Parsee::groupParsee( ParseeGroup( { - Parsee::tokenParsee(TokenKind::RIGHT_ARROW, true, false, false), Parsee::tokenParsee(TokenKind::NEW_LINE, false, false, false), + Parsee::tokenParsee(TokenKind::RIGHT_ARROW, true, false, false), Parsee::valueTypeParsee(true, true, true) } ), false, true, false