{"id":15349957,"url":"https://github.com/thomasmueller/bau-lang","last_synced_at":"2025-04-15T02:37:08.212Z","repository":{"id":246883436,"uuid":"822576175","full_name":"thomasmueller/bau-lang","owner":"thomasmueller","description":"Bau is a simple, concise, safe, powerful and fast programming language.","archived":false,"fork":false,"pushed_at":"2025-03-25T17:23:20.000Z","size":5155,"stargazers_count":18,"open_issues_count":0,"forks_count":3,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-03-25T18:31:45.363Z","etag":null,"topics":["programming-language"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/thomasmueller.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-07-01T12:08:31.000Z","updated_at":"2025-03-25T17:23:23.000Z","dependencies_parsed_at":"2024-08-26T07:04:01.905Z","dependency_job_id":"fad6186c-d2f1-4ffa-a94c-c92c278cc016","html_url":"https://github.com/thomasmueller/bau-lang","commit_stats":{"total_commits":29,"total_committers":2,"mean_commits":14.5,"dds":0.03448275862068961,"last_synced_commit":"04d642e4162764549557d2ff3ba257b11767df04"},"previous_names":["thomasmueller/bau-lang"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasmueller%2Fbau-lang","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasmueller%2Fbau-lang/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasmueller%2Fbau-lang/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomasmueller%2Fbau-lang/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thomasmueller","download_url":"https://codeload.github.com/thomasmueller/bau-lang/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248995102,"owners_count":21195497,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["programming-language"],"created_at":"2024-10-01T11:56:33.731Z","updated_at":"2025-04-15T02:37:08.169Z","avatar_url":"https://github.com/thomasmueller.png","language":"Java","readme":"# Bau\n\nA programming language for everyone.\n\n\u003ca href=\"https://thomasmueller.github.io/bau-lang/\"\u003eTry it out in the browser.\u003c/a\u003e\n\n* Easy to learn with a concise syntax inspired by Python.\n* Memory-safe. Automatic memory management using reference counting by default.\n* As fast as Rust where needed, using single ownership and borrowing.\n* Low memory usage and without GC pauses.\n* Runs everwhere: transpiles to C.\n* Null safety: Null pointer errors are prevented at compile time.\n* Ability to avoid runtime array bound checks using static analysis.\n\n## Example\n\n    fun fact(x int) int\n        if x \u003c= 1\n            return 1\n        return x * fact(x - 1)\n\n    for i:= range(0, 20)\n        println(fact(i))\n\n## Keywords\n\nControl flow\n* `if` `elif` `else` `for` `while`\n* `break` `continue` `return`\n* `throw` `catch` `switch` `case`\n\nAssignment, comparison, operations\n* `:` constant, `:=`  variable\n* `=` `+=` `-=` `*=` `/=` etc. update\n* `=` `\u003c` `\u003e` `\u003c=` `\u003e=` `\u003c\u003e`\n* `and` `or` `not` `+` `-` `*` `/` `%`\n* `\u0026` `|` `^` `~` `\u003c\u003c` `\u003e\u003e` bitwise\n\nData types and miscellaneous\n* `int` `i32` `i16` `i8`, `float` `f32`\n* `#` comment, `##` block comment\n* `fun` `type` `enum` `const` `macro`\n* `import` `module` `null`\n* `()` `[]` `.` `..` `,` `'` `` ` `` `?`\n\n### Constants, Variables\n\nIdentifiers contain letters, digits, and `_`.\n`:` defines a constant.\n`:=` defines a variable. `=` `+=` `-=` `*=`\n`/=` `\u0026=` `|=` `^=` `\u003c\u003c=` `\u003e\u003e=` updates it:\n\n    PI : 3.14159\n    x := 10\n    x += 1    # shortcut for x = x + 1\n\nA variable without value requires a type:\n\n    x int\n\n### Built-In Types\n\nThe built-in types are `int` `i32` `i16` `i8` (signed integer),\nand `float` `f32` (floating point).\n`int` can be restricted to a range using `0..`.\nDefaults are `int` and `float`; both are 64 bit.\nConversion functions change the type, and may truncate.\n\n    c := i8(10)\n    \n### Conditions\n\n`if` starts a condition.\nSpaces group statements into blocks.\n`elif` (else if) and `else` are optional.\n\n    if a = 0\n        println('zero')\n    elif a = 1\n        println('one')\n    else\n        println('many')\n\n### Loops\n\nThere are `for` and `while` loops.\n`,` is optional if the arguments are simple:\n\n    # loop from 0 to 9\n    for i := range(0, 10)\n        println(i)\n\n`for` is internally converted to `while`:\n\n    i := 0\n    while i \u003c 10\n        println(i)\n        i += 1\n\n`break` exits a loop. It may have a condition:\n\n    # prints 1 to 4\n    for i := range(1, 10)\n        break i = 5\n        println(i)\n\n### Comments\n\n`#` starts a line comments; \ntwo or more start and end a block comment.\n\n    # Line comment\n    \n    ##\n    Block comment\n    ##\n\nComments before types and functions are\nconverted to documentation.\n\n### Literals\n\nNumbers start with a digit. `_` is ignored.\n`.` is floating point, `0x` hexadecimal. \n\nStrings starting with `'` \nmay contain `\\n` newline, `\\t` tab, `\\'` single quote, \n`\\\\` backslash, `\\x00` byte. UTF-8 is used.\n\nRaw strings don't have escapes \nand start and end with one or more `` ` ``.\nMulti-line ones begin on the next line \nand may be indented.\n\n    a : 1_000_000\n    b : 3.1415\n    c : 0xcafe\n    d : 'String literal'\n    e : `Raw string`\n    f : ``\n        Two-line\n        raw string with `\n        ``\n\n### Operators\n\n`=` `\u003c` `\u003e` `\u003c=` `\u003e=` `\u003c\u003e` compare two values and return `1` or `0`.\n`not` inverses a comparison. `and` `or` combines comparisons;\nthe right side is only evaluated when needed.\nInteger `+` `-` `*` wrap around on over- / underflow.\n`/` `%`: integer division by 0 returns max, min, or 0.\n`\u0026` `|` `^` `~` `\u003c\u003c` `\u003e\u003e` are bitwise and, or, xor, not, \nshift right, and logical shift right: the leftmost bits become `0`.\n\n### Functions\n\n`fun` starts a function. It may `return` a value.\n`..` means variable number of arguments.\nFunctions can share a name if the number of arguments is different.\nThey can be declared first and implemented later.\n`const` functions are executed at compile time\nif the arguments are constants.\n`macro` function calls are replaced at compile time\nwith the implementation.\nTypes can be passed as parameters or implicitly\n(internally, this functions are templates).\n\n    fun square(x int) int\n        return x * x\n\n    fun sum(x int..) const int\n        sum := 0\n        for i := until(x.len)\n            sum += x[i]\n        return sum\n\n    fun if(cond int, true T, false T) macro T\n        if cond\n            return true\n        else\n            return false\n    \n    println('sum: ' sum(1 2 3))\n    for i := until(5)\n        println(square(i))\n        println(if(i % 2, 'odd', 'even'))\n\n### Types\n\nTypes can have fields and functions:\n\n    type Square\n        length int\n    fun Square area() int\n        return length * length\n    s : new(Square)\n      \nIf a type has a `close` function, then it is called\nbefore the memory is freed.\n`int` and other lowercase types are copied when assigned;\nuppercase types are referenced.\nFunctions on built-in types are allowed:\n\n    fun int square() int\n        return this * this\n    println(12.square())\n\nTypes can have parameters:\n\n    type List(T)\n        array T[]\n        size int\n    fun newList(T type) List(T)\n        ...\n    list := newList(Circle)\n\n### Null\n\n`?` means it may be `null`. \nAn explicit check is required before using the value.\nThere are no null pointer errors at runtime.\n\n    fun get(key int) Circle?\n        # may return null\n\n    v : get(key) \n    if v\n        print(v.area())\n\nValue types (eg. `int`) can't be `null`.\n\n### Arrays Access\n\nTo create and access arrays, use:\n\n    data : new(i8[], 3)\n    data[0] = 10\n\nBounds are checked where needed.\nAccess without runtime checks require that the compiler verifies correctness.\nIndex variables with range restrictions allow this.\nFor performance-critical code, use `[` `]!` to ensure\nno runtime checks are done.\nThe conditional `break` guarantees that `i` is within the bounds.\n\n    if data.len\n        i := 0 .. data.len\n        while 1\n            data[i]! = i\n            next : i + 1\n            break next \u003e= data.len\n            i = next\n\n### Memory Management\n\nObjects are reference counted by default.\nTo avoid cycles, explicitly set fields to `null`.\n\n    type Tree\n        left Tree?\n        right Tree?\n\n    fun Tree+ nodeCount() int\n        result := 1\n        l : left\n        if l\n            result += l.nodeCount()\n        r : right\n        if r\n            result += r.nodeCount()\n        return result\n\nWhere speed is critical, use single ownership,\nby adding `+` to the type, and borrow with `\u0026`.\n\n    type Tree\n        left Tree+?\n        right Tree+?\n\n    fun Tree+ nodeCount() int\n        result := 1\n        l : \u0026left\n        if l\n            result += l.nodeCount()\n        r : \u0026right\n        if r\n            result += r.nodeCount()\n        return result\n\n### Exceptions\n\n`throw` throws an exception. `catch` is needed,\nor the method needs `throws`.\nCustom exception types are allowed.\n\n    import org.bau.Exception\n        exception\n\n    fun square(x int) int throws exception\n        if x \u003e 3_000_000_000\n            throw exception('Too big')\n        return x * x\n    \n    x := square(3_000_000_001)\n    println(x)\n    catch e\n        println(e.message)\n\n### Modules and Import\n\n`import` allows using types and functions from a module.\nThe last part of the module name is the identifier.\nThe module identifier can be omitted\nif the type, function, or constant is listed after `import`.\nThe full module name can be used as well.\n\n    import org.bau.Utils\n        random\n    import org.bau.Math\n    println(random())\n    println(Utils.getNanoTime())\n    println(Math.PI)\n    println(org.bau.Math.PI)\n\n`module` defines a module. \nThe name needs to match the file path, here `org/bau/Math.bau`:\n\n    module org.bau.Math\n    PI : 3.14159265358979323846\n\n### Custom Loops\n\nLibraries and users can define their own `for` loops using user-defined functions.\nSuch functions work like macros, as they are expanded at compile time.\nThe loop is replaced during compilation with the function body.\nThe variable `_` represents the current iteration value.\nThe `return _` statement is replaced during compilation with the loop body.\n\n    fun main()\n        for x := evenRange(0, 30)\n            println('even: ' x)\n\n    fun evenRange(from int, to int) int\n        _ := from\n        while _ \u003c to\n            return _\n            _ += 2\n\nis equivalent to:\n\n    fun main()\n        x := 0\n        while x \u003c 30\n            println('even: ' x)\n            x += 2\n        \n### Tour\n\n#### Hello World\n\n    println('Hello World')\n\n#### Assignment\n\n\n#### Import, Functions\n\n    import org.bau.Utils\n\n    fun printTime()\n        println(Utils.getNanoTime())\n  \n    printTime()\n\n#### Random\n\n    import org.bau.Utils\n\n    println(Utils.random())\n\n#### Math\n\n    import org.bau.Math\n\n    println('Pi: ' Math.PI)\n    println(Math.sqrt(2))\n\n##### Functions\n\n    fun add(x int, y int) int\n        return x + y\n\n    println(add(42 1))\n\n##### Data Types\n\n    a := 10_000_000\n    b := i8(110)\n    c := i16(65000)\n    d : 'text'\n    e := 3.1416\n    f := 0..10\n    println(a ' ' b)\n\n##### Type Conversion\n\n    a := 10_000_000\n    b := 3\n    println(a / b)\n    println(float(a) / b)\n    \n##### Constants\n\n    PI : 3.1415\n    println(PI)\n    \n##### For Loops\n\n    sum := 0\n    for i := range(0, 10)\n        sum += i\n    println(sum)\n\n##### While Loops\n\n    sum := 1\n    while sum \u003c 10_000\n        sum += sum\n    println(sum)\n    \n##### If\n\n    for i := range(1, 10)\n        if i \u003c 5\n            println(i)\n\n##### If Else\n\n    for i := range(1, 10)\n        if i \u003c 5\n            println(i)\n        else\n            println(-i)\n\n##### If Elif Else\n\n    for i := range(1, 10)\n        if i = 0\n            println('zero')\n        elif i = 1\n            println('one')\n        elif i = 2\n            println('two')\n        else\n            println('many')\n\n##### Switch\n\n    import org.bau.Utils\n\n    for i := range(1, 10)\n        switch Utils.random() \u0026 7\n        case 0\n            println('zero')\n        case 1\n            println('one')\n        case 2, 3\n            println('2 or 3')\n        else  \n            println('other') \n\n##### Types\n\n    type point\n        x int\n        y int\n    \n    p := new(point)\n    p.x = 10\n    p.y = 20\n    \n##### Arrays\n\n    array : new(i8[], 10)\n    for i := until(array.len)\n        array[i] = i\n\n##### List\n\n    import org.bau.List\n        List\n        newList\n    \n    list := newList(int)\n    list.add(100)\n    list.add(80)\n    println(list.size)\n    println(list.array[0])\n\n##### Enum\n\n    enum weekday\n        sunday\n        monday\n        tuesday\n        wednesday\n        thursday\n        friday\n        saturday\n\n    for a := until(weekday.saturday + 1)\n        switch a\n        case weekday.sunday\n            println('sunday')\n        case weekday.monday\n            println('monday')\n        else\n            println('some other day: #' a)\n\n##### Macros and Ternary Condition\n\n    fun if(cond int, a T, b T) macro T\n        if cond\n            return a\n        else\n            return b\n\n    for i := until(3)\n        println(i ':', if(i, '\u003e0', 'zero'))\n\n#### Custom For Loops\n\n    fun main()\n        for x := primesUntil(30)\n            println('prime: ' x)\n    \n    fun primesUntil(until int) int\n        _ := 2\n        while 1 = 1\n            _ += 1 + (_ \u0026 1)\n            break _ \u003e until\n            if not isPrime(_)\n                continue \n            return _\n    \n    fun isPrime(x int) int\n        if (x \u0026 1) = 0\n            return 0\n        i := 3\n        while i * i \u003c= x\n            if x % i = 0\n                return 0\n            i += 2\n        return 1\n\n### Comparison\n\n|Feature               |Bau    |Python |C      |C++    |Java   |C#     |Go     |Rust   |Swift  |\n|----------------------|-------|-------|-------|-------|-------|-------|-------|-------|-------|\n|Memory Safety         |\u0026check;|\u0026check;|       |       |\u0026check;|\u0026check;|\u0026check;|\u0026check;|\u0026check;|\n|Easy to Learn and Use |\u0026check;|\u0026check;|\u0026check;|       |\u0026check;|\u0026check;|\u0026check;|       |\u0026check;|\n|Concise Syntax        |\u0026check;|\u0026check;|       |       |       |       |\u0026check;|       |\u0026check;|\n|Vendor Independent    |\u0026check;|\u0026check;|\u0026check;|\u0026check;|       |       |       |\u0026check;|       |\n|Strongly Typed        |\u0026check;|       |\u0026check;|\u0026check;|\u0026check;|\u0026check;|\u0026check;|\u0026check;|\u0026check;|\n|Fast Execution        |\u0026check;|       |\u0026check;|\u0026check;|\u0026check;|\u0026check;|\u0026check;|\u0026check;|\u0026check;|\n|No GC Pauses          |\u0026check;|       |\u0026check;|\u0026check;|       |       |       |\u0026check;|\u0026check;|\n|Runs Everywhere       |\u0026check;|       |\u0026check;|       |       |       |       |       |       |\n|Generics / Templates  |\u0026check;|       |       |\u0026check;|\u0026check;|\u0026check;|\u0026check;|\u0026check;|\u0026check;|\n|Macros                |\u0026check;|       |\u0026check;|\u0026check;|       |       |       |\u0026check;|       |\n|Exception Handling    |\u0026check;|\u0026check;|       |\u0026check;|\u0026check;|\u0026check;|\u0026check;|\u0026check;|\u0026check;|\n|Null Safety           |\u0026check;|       |       |       |       |\u0026check;|       |\u0026check;|\u0026check;|\n|Array Bounds Checks   |\u0026check;|\u0026check;|       |       |\u0026check;|\u0026check;|\u0026check;|\u0026check;|\u0026check;|\n|Compile-Time Execution|\u0026check;|       |       |\u0026check;|       |       |       |\u0026check;|       |\n\n### Non-Features\n\n* Many concepts of object-oriented programming languages are not supported,\n  for example inheritance, method overloading, polymorphism,\n  and more complex encapsulation.\n* Many concepts of functional programming languages are not supported, \n  for example high-order functions, functional composition,\n  closures.\n* `map`, `filter`, etc are not supported. One problem here is exception handling.\n* Reflection is not supported.\n* Tail calls are only optimized by the C compiler.\n* Multi-threading support is limited to what C supports.\n* Coroutines are not supported; however,\n  custom `for` loops are supported that work like macros.\n* `goto` and labels are not supported.\n* String interpolation is not supported to simplify the language. \n  Instead, use an arrays of strings. As commas are optional, this is short.\n* Dynamic dispatch is not supported.\n\n### Syntax\n\n* Spaces (indentation) is used to group statements. This reduces the number of lines.\n  Tabs are not supported. The reason is that spaces are more common,\n  and tabs do not mix well with spaces. By disallowing tabs, problems are detected early.\n* Commas in parameter lists are optional, if parameters are simple values.\n  The same as in shell scripts or Lisp.\n  This also makes 'print' statements more readable (without string interpolation).\n* There is no `boolean` data type to simplify the syntax. \n  Instead, `true` is `1` and `false` is `0`.\n  The common pitfalls, e.g. comparing the result of a comparison,\n  requires parenthesis (eg. `a \u003e b \u003c c` is not allowed).\n* Constants and variables are defined in a different way (`:` vs `:=`)\n  so that it's easier to see for a reader if it may change later.\n  But there is no keyword like \"var\", \"val\", \"const\", or \"final\" to shorten the code.\n* Definition of a variables is distinct from updating it (`:=` vs `=`) to quickly\n  detect if a variable was already defined, and to detect typos.\n* `break` and `continue` can have a condition, to avoid a separate line with `if`.\n* Labels for `break` and `continue` are not supported to simplify the language.\n  If needed, the function can return from inside the loop, or throw an exception\n  (such exceptions are very fast).\n* Comments are only a single character (`#`) to save some typing.\n  Block comments (`##`) are useful if the editor doesn't support commenting a block.\n  To support eg. Markdown inside of block comments, the delimiters can be variable length.\n* Raw strings are useful, to avoid escaping problems: https://xkcd.com/1638/\n* Multi-line strings are always raw strings, \n  as escape sequences don't seem useful for this (tabs are supported here).\n* Dangling `,` are supported to e.g. simplify re-ordering entries.\n* Bit operations `|`, `\u0026`, `^`, `~` have a higher order of precedence than comparison.\n  This is different from other programming languages.\n  It seems the reason why it is different in other languages is historical reasons only.\n* Instead of `\u0026\u0026` `||` `!` we use the keywords `and`, `or` and `not`, \n  to make these common cases easier to understand for new developers,\n  and in case of `not` to make it easier to read.\n* There are no separate unsigned data types, to simplify the language.\n* Bitwise shift to the right (`\u003e\u003e`) is a logical shift, that means for negative values,\n  a number of zeros are added to the left. The arithmetic shift is not supported\n  by the language itself, but can be supported by a library function\n  (same as eg. rotation). The reason is that logical shifts are more common.\n\n### Safety \n* There is no way to write unsafe code, except by calling C methods.\n* Array bounds are check, except if array access is guaranteed to be \n  inside the bounds. This is implemented using dependent types.\n  \n### Memory Management\n* Reference counting is used for reference types.\n* Mark-and-sweep garbage collection is not used to avoid pauses.\n* Borrow checking is not used to simplify writing code.\n* The plan is to use reference counting only where cycles are not possible.\n* The plan is to support weak references.\n* The plan is to support unique pointers, and arrays of pre-allocated objects \n  accessed via handlers and a generation\n\n### Exceptions and Panic\n* Exceptions need to be handled using `catch`, or re-thrown.\n* There is no `try` keyword: `catch` will catch all exceptions in the same scope.\n  This is to simplify the code, and reduce the need of indentation.\n  Ruby supports a similar syntax: `begin` is not needed.\n* Custom exception types are allowed, with some restrictions:\n  Exception types need to have an integer field `exceptionType`\n  that may not have a negative value (because internally, this field\n  is used to to flag whether the method was successful or not,\n  and a negative value is used to indicate success).\n* Possible null references need to be handled. \n  There is no way that null references can throw an exception or panic.\n* Integer division (`/`) by zero, the same as floating point division by zero,\n  doesn't throw an exception. Instead, it returns the highest / lowest value\n  (if dividing positive or negative numbers), or zero (for zero by zero).\n  This is to be more consistent with the floating point division, and\n  to avoid panic for cases were it was used for \"unimportant\" operations\n  such as calculating the number of instructions per second, for zero seconds.\n  The same goes for modulo operations.\n* Where array bound checks are needed, and the index is out of bounds,\n  the program panics.\n* If a type has a  `close()` function, it is called when the memory\n  is freed. If this function re-adds a reference to the object,\n  then the program panics.\n","funding_links":[],"categories":["Uncategorized"],"sub_categories":["Uncategorized"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomasmueller%2Fbau-lang","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthomasmueller%2Fbau-lang","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomasmueller%2Fbau-lang/lists"}