├── demo.bau ├── config ├── dictionary.txt └── bau │ ├── package.json │ └── language-configuration.json ├── src ├── test │ ├── resources │ │ └── org │ │ │ └── bau │ │ │ ├── demo.bau │ │ │ ├── converter │ │ │ ├── helloWorld.bau │ │ │ ├── traitsModule.bau │ │ │ ├── comment.md │ │ │ ├── lz4.bau │ │ │ ├── literals.bau │ │ │ ├── modulesExample2.bau │ │ │ ├── operators.bau │ │ │ ├── arrayLen.bau │ │ │ ├── fileRead.bau │ │ │ ├── modulesList.bau │ │ │ ├── traits.bau │ │ │ ├── constFunction.bau │ │ │ ├── forLoopBreakContinue.bau │ │ │ ├── functionPointer.bau │ │ │ ├── modulesExample.bau │ │ │ ├── arrayBounds.bau │ │ │ ├── string.bau │ │ │ ├── throwCatchDemo.bau │ │ │ ├── byteArray.bau │ │ │ ├── arrayReadInt.bau │ │ │ ├── arrayShortFunction.bau │ │ │ ├── nullMap.bau │ │ │ ├── functionDeclareAndImplementLater.bau │ │ │ ├── owned.bau │ │ │ ├── typeWithParameter.bau │ │ │ ├── arrayRange.bau │ │ │ ├── factorial.bau │ │ │ ├── throwCatchVoidFunction.bau │ │ │ ├── functionsBubbleSort.bau │ │ │ ├── utils.bau │ │ │ ├── hexOrd.bau │ │ │ ├── ternaryCondition.bau │ │ │ ├── comment.bau │ │ │ ├── string2.bau │ │ │ ├── typeOpenClose.bau │ │ │ ├── munchausen.bau │ │ │ ├── functions.bau │ │ │ ├── enum.bau │ │ │ ├── macro.bau │ │ │ ├── traitsSimple.bau │ │ │ ├── fibonacci.bau │ │ │ ├── pi.bau │ │ │ ├── nullPreventNullAccess.bau │ │ │ ├── sort.bau │ │ │ ├── arrayFunction.bau │ │ │ ├── binaryTreeRefCount.bau │ │ │ ├── throwCatch.bau │ │ │ ├── binaryTreeOwned.bau │ │ │ └── binaryTree.bau │ │ │ ├── benchmarks │ │ │ ├── rust │ │ │ │ ├── Cargo.toml │ │ │ │ ├── pi_digits │ │ │ │ │ └── Cargo.toml │ │ │ │ └── munchausen.rs │ │ │ ├── ena │ │ │ │ ├── fibonacci.ena │ │ │ │ ├── binaryTrees.ena │ │ │ │ └── fannkuch.ena │ │ │ ├── lua │ │ │ │ └── fibonacci.lua │ │ │ ├── swift │ │ │ │ ├── piDigits │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── Package.swift │ │ │ │ │ └── Sources │ │ │ │ │ │ └── main.swift │ │ │ │ ├── munchausen.swift │ │ │ │ └── mandelbrot.swift │ │ │ ├── munchausen.py │ │ │ ├── python │ │ │ │ ├── munchausen.py │ │ │ │ ├── piDigits.py │ │ │ │ ├── mandelbrotComplex.py │ │ │ │ ├── mandelbrot.py │ │ │ │ ├── binaryTrees.py │ │ │ │ └── fannkuch.py │ │ │ ├── munchausen.bau │ │ │ ├── bau │ │ │ │ ├── munchausen.bau │ │ │ │ ├── piDigits.bau │ │ │ │ ├── mandelbrot.bau │ │ │ │ ├── binaryTreesRefCount.bau │ │ │ │ └── binaryTrees.bau │ │ │ ├── munchausen.nim │ │ │ ├── nim │ │ │ │ ├── munchausen.nim │ │ │ │ ├── piDigits.nim │ │ │ │ ├── binaryTrees.nim │ │ │ │ └── mandelbrot.nim │ │ │ ├── munchausen.swift │ │ │ ├── munchausen.v │ │ │ ├── v │ │ │ │ ├── munchausen.v │ │ │ │ ├── mandelbrot.v │ │ │ │ └── binaryTrees.v │ │ │ ├── munchausen.rs │ │ │ ├── c │ │ │ │ ├── munchausen.c │ │ │ │ ├── spectralNorm.c │ │ │ │ └── mandelbrot.c │ │ │ ├── munchausen.c │ │ │ ├── munchausen.go │ │ │ ├── go │ │ │ │ ├── munchausen.go │ │ │ │ ├── spectralNorm.go │ │ │ │ └── mandelbrot.go │ │ │ ├── piDigits.py │ │ │ ├── mandelbrotComplex.py │ │ │ ├── piDigits.bau │ │ │ ├── zig │ │ │ │ └── munchausen.zig │ │ │ ├── munchausen.zig │ │ │ ├── mandelbrot.bau │ │ │ ├── mini │ │ │ │ ├── binaryTrees.mini │ │ │ │ └── fannkuch.mini │ │ │ ├── binaryTreesRefCount.bau │ │ │ ├── piDigits.nim │ │ │ ├── spectralNorm.c │ │ │ ├── mandelbrot.py │ │ │ ├── mandelbrot.c │ │ │ ├── spectralNorm.go │ │ │ ├── binaryTrees.bau │ │ │ ├── mandelbrot.v │ │ │ ├── binaryTrees.py │ │ │ ├── binaryTrees.nim │ │ │ ├── mandelbrot.nim │ │ │ ├── fannkuch.py │ │ │ ├── mandelbrot.swift │ │ │ ├── mandelbrot.go │ │ │ └── binaryTrees.v │ │ │ ├── factorial.bau │ │ │ ├── readI32Le.bau │ │ │ └── stringTest.bau │ └── java │ │ └── org │ │ └── bau │ │ ├── ena │ │ ├── ast │ │ │ ├── Node.java │ │ │ ├── Stmt.java │ │ │ └── Expr.java │ │ ├── Token.java │ │ ├── TokenType.java │ │ ├── RegCompileTool.java │ │ └── types │ │ │ └── Type.java │ │ ├── stdlib │ │ ├── cache │ │ │ ├── Cache.java │ │ │ └── HitRateCacheWrapper.java │ │ ├── tar │ │ │ └── TarTest.java │ │ ├── collections │ │ │ ├── SortedMap.java │ │ │ ├── BitField.java │ │ │ ├── Stack.java │ │ │ ├── StackTest.java │ │ │ └── PermutationsTest.java │ │ ├── sort │ │ │ ├── BinarySearch.java │ │ │ ├── number │ │ │ │ ├── NumberShellSort.java │ │ │ │ ├── NumberInsertionSort.java │ │ │ │ └── NumberIntroSort.java │ │ │ ├── ShellSort.java │ │ │ ├── BinarySearchTest.java │ │ │ └── HeapSort.java │ │ ├── security │ │ │ ├── SHA256Test.java │ │ │ ├── ARC4Test.java │ │ │ ├── ARC4.java │ │ │ ├── ChaCha12Test.java │ │ │ └── ChaCha20Test.java │ │ ├── locale │ │ │ ├── NumberFormatterTest.java │ │ │ └── NumberFormatter.java │ │ ├── stats │ │ │ └── QuantileSketchTest.java │ │ ├── math │ │ │ ├── FastDivide.java │ │ │ ├── PrimeSieveTest.java │ │ │ ├── PrimeSieve.java │ │ │ └── Factorial.java │ │ ├── util │ │ │ ├── HashTest.java │ │ │ ├── ReservoirSampling.java │ │ │ └── Hash.java │ │ ├── io │ │ │ └── ChecksumTest.java │ │ └── graphics │ │ │ └── TiffTest.java │ │ ├── LanguageLibraries.java │ │ ├── traits │ │ ├── TypeList.java │ │ ├── TraitFunction.java │ │ ├── Type.java │ │ └── Trait.java │ │ ├── LanguageDocker.java │ │ ├── perf │ │ └── TooSimple.java │ │ ├── utils │ │ └── TestParseHex.java │ │ ├── benchmarks │ │ ├── Loop.kt │ │ ├── Munchausen.kt │ │ ├── Loop.java │ │ ├── Munchausen.java │ │ └── PiDigits.kt │ │ ├── TestInterpret.java │ │ ├── LanguageFunctions.java │ │ ├── TestOperators.java │ │ ├── TestComment.java │ │ ├── TestFor.java │ │ ├── TestConverter.java │ │ ├── games │ │ └── Chess.java │ │ ├── languageServer │ │ └── Shutdown.java │ │ ├── TestNull.java │ │ └── LanguageModules.java └── main │ ├── resources │ └── org │ │ └── bau │ │ ├── Exception.bau │ │ ├── Std.bau │ │ ├── os │ │ ├── Sleep.bau │ │ └── Signal.bau │ │ ├── Convert.bau │ │ ├── Env.bau │ │ ├── List.bau │ │ └── Locale.bau │ └── java │ └── org │ └── bau │ └── parser │ ├── MemoryType.java │ ├── ProgramContext.java │ ├── Trait.java │ ├── LeftValue.java │ ├── FullName.java │ ├── Statement.java │ ├── SpecialOperation.java │ └── NativeCode.java ├── doc ├── performance.png ├── performance.xlsx ├── syntaxMetrics.png ├── ~$performance.xlsx ├── playground.md ├── playground-about.md ├── transpile.md └── conciseSyntax.md ├── docs ├── performance.png ├── syntaxMetrics.png ├── codemirror │ └── initCodeMirror.js └── styles.css ├── .gitignore ├── transpile.md ├── Makefile └── pom.xml /demo.bau: -------------------------------------------------------------------------------- 1 | println('hello') -------------------------------------------------------------------------------- /config/dictionary.txt: -------------------------------------------------------------------------------- 1 | println 2 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/demo.bau: -------------------------------------------------------------------------------- 1 | println('Hello ' 'World') 2 | -------------------------------------------------------------------------------- /doc/performance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasmueller/bau-lang/HEAD/doc/performance.png -------------------------------------------------------------------------------- /doc/performance.xlsx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasmueller/bau-lang/HEAD/doc/performance.xlsx -------------------------------------------------------------------------------- /docs/performance.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasmueller/bau-lang/HEAD/docs/performance.png -------------------------------------------------------------------------------- /doc/syntaxMetrics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasmueller/bau-lang/HEAD/doc/syntaxMetrics.png -------------------------------------------------------------------------------- /docs/syntaxMetrics.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomasmueller/bau-lang/HEAD/docs/syntaxMetrics.png -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/helloWorld.bau: -------------------------------------------------------------------------------- 1 | println('Hello World') 2 | 3 | ## Expected 4 | Hello World 5 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/traitsModule.bau: -------------------------------------------------------------------------------- 1 | module traitsModule 2 | 3 | fun testAbc() 4 | println('testAbc') 5 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/comment.md: -------------------------------------------------------------------------------- 1 | 2 | ### type List(T) 3 | A list of entries 4 | 5 | #### fun test() 6 | Test function 7 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/lz4.bau: -------------------------------------------------------------------------------- 1 | import org.bau.compress.Lz4Tool 2 | 3 | fun main() 4 | Lz4Tool.main() 5 | 6 | ## Expected 7 | -------------------------------------------------------------------------------- /src/test/java/org/bau/ena/ast/Node.java: -------------------------------------------------------------------------------- 1 | package org.bau.ena.ast; 2 | 3 | public interface Node { 4 | int line(); 5 | 6 | int column(); 7 | } 8 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .classpath 3 | .project 4 | .settings/ 5 | bin/ 6 | target/ 7 | got/ 8 | langServ.in.txt 9 | langServ.out.txt 10 | demo.c 11 | -------------------------------------------------------------------------------- /src/main/resources/org/bau/Exception.bau: -------------------------------------------------------------------------------- 1 | module org.bau.Exception 2 | 3 | # An exception 4 | type exception 5 | exceptionType int 6 | message i8[] 7 | 8 | -------------------------------------------------------------------------------- /src/main/java/org/bau/parser/MemoryType.java: -------------------------------------------------------------------------------- 1 | package org.bau.parser; 2 | 3 | public enum MemoryType { 4 | COPY, 5 | REF_COUNT, 6 | OWNER, 7 | BORROW 8 | } 9 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/cache/Cache.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.cache; 2 | 3 | public interface Cache { 4 | V get(K key); 5 | void put(K key, V value); 6 | } 7 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/rust/Cargo.toml: -------------------------------------------------------------------------------- 1 | workspace = { members = ["pi_digits"] } 2 | 3 | [profile.release] 4 | opt-level = 3 5 | strip = true 6 | panic = "abort" 7 | -------------------------------------------------------------------------------- /doc/~$performance.xlsx: -------------------------------------------------------------------------------- 1 | Microsoft Office User Microsoft Office User -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/ena/fibonacci.ena: -------------------------------------------------------------------------------- 1 | fun fibonacci(n int) int 2 | if n<3 3 | ret 1 4 | else 5 | ret fibonacci(n-1) + fibonacci(n-2) 6 | 7 | println(fibonacci(10)) 8 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/tar/TarTest.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.tar; 2 | 3 | import org.junit.Test; 4 | 5 | public class TarTest { 6 | 7 | @Test 8 | public void test() { 9 | 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/main/resources/org/bau/Std.bau: -------------------------------------------------------------------------------- 1 | module org.bau.Std 2 | 3 | # The value of the first byte in the string. 0 if the string is empty. 4 | fun ord(s i8[]) const int 5 | if s.len 6 | return s[0] 7 | return 0 8 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/rust/pi_digits/Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | edition = "2024" 3 | resolver = "3" 4 | name = "pi_digits" 5 | version = "1.0.0" 6 | 7 | [dependencies] 8 | num-bigint = "0.4" 9 | num-traits = "0.2" -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/literals.bau: -------------------------------------------------------------------------------- 1 | a : 1_000_000 2 | b : 3.1415 3 | c : 0xcafe 4 | d : 'String literal' 5 | e : `Raw string` 6 | f : `` 7 | Two-line 8 | raw string with ` 9 | `` 10 | g : -1.23e-45 11 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/modulesExample2.bau: -------------------------------------------------------------------------------- 1 | import org.bau.Utils 2 | random 3 | import org.bau.Math 4 | PI 5 | 6 | println(random()) 7 | println(PI) 8 | 9 | ## Expected 10 | -2152535657050944081 11 | 3.141592653589793 -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/operators.bau: -------------------------------------------------------------------------------- 1 | i64v := int(1) 2 | i32v := i32(1) 3 | i16v := i16(1) 4 | i8v := i8(1) 5 | f64v := float(1) 6 | f32v := f32(1) 7 | a := 12345 >> 1 8 | b := 12345 << 1 9 | c := a / b 10 | d := a % b 11 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/lua/fibonacci.lua: -------------------------------------------------------------------------------- 1 | local function fibonacci(n) 2 | if n<3 then 3 | return 1 4 | else 5 | return fibonacci(n-1) + fibonacci(n-2) 6 | end 7 | end 8 | 9 | print(fibonacci(44)) 10 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/arrayLen.bau: -------------------------------------------------------------------------------- 1 | fun printLen(data i8[]) 2 | println(data.len) 3 | 4 | fun test() 5 | data : i8[10] 6 | println(data.len) 7 | printLen(data) 8 | 9 | test() 10 | 11 | ## Expected 12 | 10 13 | 10 14 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/fileRead.bau: -------------------------------------------------------------------------------- 1 | import org.bau.File 2 | 3 | fun test() 4 | file := File.openFile('hello.txt', 'r') 5 | data : i8[16] 6 | file.read(data, 0, 15) 7 | data[5] = 0 8 | println(data) 9 | 10 | test() 11 | -------------------------------------------------------------------------------- /src/test/java/org/bau/LanguageLibraries.java: -------------------------------------------------------------------------------- 1 | package org.bau; 2 | 3 | /* 4 | 5 | emulate floating point in a library: https://github.com/clemensmanert/fas/blob/master/fas/float.hpp 6 | 7 | */ 8 | public class LanguageLibraries { 9 | 10 | } 11 | -------------------------------------------------------------------------------- /src/test/java/org/bau/traits/TypeList.java: -------------------------------------------------------------------------------- 1 | package org.bau.traits; 2 | 3 | import java.util.HashMap; 4 | 5 | public class TypeList { 6 | HashMap types = new HashMap<>(); 7 | HashMap traits = new HashMap<>(); 8 | } 9 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/swift/piDigits/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | xcuserdata/ 5 | DerivedData/ 6 | .swiftpm/configuration/registries.json 7 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 8 | .netrc 9 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/factorial.bau: -------------------------------------------------------------------------------- 1 | fun factorial(x i64) i64 2 | if x <= 1 3 | return 1 4 | return x * factorial(x - 1) 5 | 6 | i := 0 7 | while i <= 10 8 | print('Factorial of ', i, ' = ', factorial(i), '\n') 9 | i += 1 10 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/modulesList.bau: -------------------------------------------------------------------------------- 1 | import org.bau.List 2 | List 3 | newList 4 | 5 | list := newList(int) 6 | list.add(100) 7 | list.add(80) 8 | println(list.size) 9 | println(list.array[0]) 10 | 11 | ## Expected 12 | 2 13 | 100 14 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/traits.bau: -------------------------------------------------------------------------------- 1 | import traitsModule 2 | 3 | fun test() 4 | println('test') 5 | 6 | fun main() 7 | println('main') 8 | test() 9 | traitsModule.testAbc() 10 | 11 | ## Expected 12 | main 13 | test 14 | testAbc 15 | -------------------------------------------------------------------------------- /src/test/java/org/bau/LanguageDocker.java: -------------------------------------------------------------------------------- 1 | package org.bau; 2 | 3 | /* 4 | 5 | https://hub.docker.com/_/gcc 6 | 7 | docker run -it gcc:12.4.0-bookworm 8 | 9 | docker cp got/blockGame.c 076d62cd9ee1:/ 10 | 11 | */ 12 | public class LanguageDocker { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/readI32Le.bau: -------------------------------------------------------------------------------- 1 | fun readI32Le(d i8[], pos i32) i32 2 | return d[pos] | (d[pos + 1] << 8) | (d[pos + 2] << 16) | (d[pos + 3] << 24) 3 | 4 | x := new i8[4] 5 | x[0] = 0x12 6 | x[1] = 0x34 7 | x[2] = 0x56 8 | x[3] = 0x78 9 | print(readI32Le(x, 0)) 10 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/constFunction.bau: -------------------------------------------------------------------------------- 1 | fun sum(x T..) const T 2 | result := T(0) 3 | for i := until(x.len) 4 | result += x[i]! 5 | return result 6 | 7 | println(sum(1, 2, 3)) 8 | println(sum(1.1, 2.2, 3.3)) 9 | 10 | ## Expected 11 | 6 12 | 6.6 13 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/forLoopBreakContinue.bau: -------------------------------------------------------------------------------- 1 | fun range(from int, to int) int 2 | _ := from 3 | while _ < to 4 | return _ 5 | _ += 1 6 | 7 | for a := range(0, 10) 8 | break a = 5 9 | continue a = 2 10 | println(a) 11 | 12 | ## Expected 13 | 0 14 | 1 15 | 3 16 | 4 17 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/collections/SortedMap.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.collections; 2 | 3 | public interface SortedMap { 4 | 5 | int size(); 6 | 7 | void clear(); 8 | 9 | void put(K key, V value); 10 | 11 | V get(K key); 12 | 13 | void remove(K key); 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/functionPointer.bau: -------------------------------------------------------------------------------- 1 | fun abc(name i8[]) int 2 | println('hello ' name) 3 | return 1 4 | 5 | fun callMe(x fun(i8[]) int) 6 | a : x('you') 7 | println('returned ' a) 8 | 9 | fun main() 10 | callMe(abc) 11 | 12 | ## Expected 13 | hello you 14 | returned 1 15 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/modulesExample.bau: -------------------------------------------------------------------------------- 1 | import org.bau.Utils 2 | import org.bau.Math 3 | println(Utils.random()) 4 | println(Math.PI) 5 | println(org.bau.Utils.random()) 6 | println(org.bau.Math.PI) 7 | 8 | ## Expected 9 | -2152535657050944081 10 | 3.141592653589793 11 | 7960286522194355700 12 | 3.141592653589793 13 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/arrayBounds.bau: -------------------------------------------------------------------------------- 1 | fun test() 2 | data : i8[10] 3 | for i:= until(data.len) 4 | data[i]! = i 5 | sum := 0 6 | for i:= range(0 20) 7 | sum += data[i] 8 | println(sum) 9 | 10 | test() 11 | 12 | ## Expected 13 | Panic: Array index 10 is out of bounds for the array length 10 14 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/string.bau: -------------------------------------------------------------------------------- 1 | type string 2 | data i8[] 3 | 4 | fun str(s i8[]) string 5 | x := string(s) 6 | return x 7 | 8 | x : string[3] 9 | x[0] = str('hello') 10 | x[1] = str('world') 11 | x[2] = str('!') 12 | 13 | println(x[0].data ' ' x[1].data ' ' x[2].data) 14 | 15 | ## Expected 16 | hello world ! 17 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/throwCatchDemo.bau: -------------------------------------------------------------------------------- 1 | import org.bau.Exception 2 | exception 3 | 4 | fun square(x int) int throws exception 5 | if x > 3_000_000_000 6 | throw exception('Too large') 7 | return x * x 8 | 9 | x := square(3_000_000_001); 10 | println(x) 11 | catch e 12 | println(e.message) 13 | 14 | ## Expected 15 | Too large 16 | -------------------------------------------------------------------------------- /docs/codemirror/initCodeMirror.js: -------------------------------------------------------------------------------- 1 | var width = (window.innerWidth > 0) ? window.innerWidth : document.documentElement.clientWidth; 2 | if (width > 900) { 3 | this.inputEditor = CodeMirror.fromTextArea(document.getElementById("source"), { 4 | lineNumbers: false, mode: "text/bau" 5 | }); 6 | setInterval(function () { 7 | inputEditor.save(); 8 | }, 200) 9 | } -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/byteArray.bau: -------------------------------------------------------------------------------- 1 | fun readI32Le(d i8[], pos i32) i32 2 | return d[pos] | (d[pos + 1] << 8) | (d[pos + 2] << 16) | (d[pos + 3] << 24) 3 | 4 | fun test() 5 | x : i8[4] 6 | x[0]! = 0x12 7 | x[1]! = 0x34 8 | x[2]! = 0x56 9 | x[3]! = 0x78 10 | println(readI32Le(x, i32(0))) 11 | 12 | test() 13 | 14 | ## Expected 15 | 2018915346 16 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/arrayReadInt.bau: -------------------------------------------------------------------------------- 1 | fun readInt(d i8[], pos 0 .. d.len - 4) int 2 | return (d[pos]! & 0xff) | 3 | ((d[pos + 1]! & 0xff) << 8) | 4 | ((d[pos + 2]! & 0xff) << 16) | 5 | ((d[pos + 3]! & 0xff) << 24) 6 | 7 | fun test() 8 | data : i8[4] 9 | println(readInt(data, 0)) 10 | 11 | test() 12 | 13 | ## Expected 14 | 0 15 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/arrayShortFunction.bau: -------------------------------------------------------------------------------- 1 | fun fill(data int[]) 2 | if data.len <= 0 3 | return 4 | i := 0..data.len 5 | while 1 = 1 6 | data[i]! = i 7 | next : i + 1 8 | break next >= data.len 9 | i = next 10 | 11 | fun test() 12 | data : int[16] 13 | fill(data) 14 | println(data.len) 15 | 16 | test() 17 | 18 | ## Expected 19 | 16 20 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/nullMap.bau: -------------------------------------------------------------------------------- 1 | type Value 2 | data int 3 | 4 | fun get(key int) Value? 5 | if key <= 0 6 | return null 7 | result : Value() 8 | result.data = key * 10 9 | return result 10 | 11 | fun test() 12 | a : get(0) 13 | if a 14 | println(a.data) 15 | b : get(1) 16 | if b 17 | println(b.data) 18 | 19 | test() 20 | 21 | ## Expected 22 | 10 23 | -------------------------------------------------------------------------------- /docs/styles.css: -------------------------------------------------------------------------------- 1 | /* 2 | * { 3 | border: 1px solid black; 4 | } 5 | */ 6 | 7 | body { 8 | margin: 32px; 9 | } 10 | 11 | .top { 12 | width: 100%; 13 | font-family: 'Montserrat', sans-serif; 14 | font-size: 1em; 15 | } 16 | 17 | .top textarea { 18 | box-sizing: border-box; 19 | height: 50vh; 20 | resize: vertical; 21 | } 22 | 23 | .top button { 24 | top: 10px; 25 | left: 10px; 26 | padding: 5px; 27 | } 28 | -------------------------------------------------------------------------------- /src/main/resources/org/bau/os/Sleep.bau: -------------------------------------------------------------------------------- 1 | module org.bau.os.Sleep 2 | 3 | fun sleep(millis int) 4 | if millis < 0 5 | return 6 | native(`#include 7 | #include 8 | struct timespec ts; 9 | ts.tv_sec = millis / 1000; 10 | ts.tv_nsec = (millis % 1000) * 1000000; 11 | int res; 12 | do { 13 | res = nanosleep(&ts, &ts); 14 | } while (res && errno == EINTR); 15 | `) 16 | -------------------------------------------------------------------------------- /src/test/java/org/bau/traits/TraitFunction.java: -------------------------------------------------------------------------------- 1 | package org.bau.traits; 2 | 3 | class TraitFunction { 4 | final int id; 5 | Trait trait; 6 | final String name; 7 | 8 | TraitFunction(int id, String name, Trait trait) { 9 | this.id = id; 10 | this.name = name; 11 | this.trait = trait; 12 | } 13 | 14 | public String toString() { 15 | return name + ":" + trait.id + ":" + id; 16 | } 17 | 18 | } -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/functionDeclareAndImplementLater.bau: -------------------------------------------------------------------------------- 1 | fun odd(x int) int 2 | if x = 0 3 | return 0 4 | return even(x - 1) 5 | 6 | fun even(x int) int 7 | if x = 0 8 | return 1 9 | return odd(x - 1) 10 | 11 | println('odd(10)=' odd(10)) 12 | println('even(10)=' even(10)) 13 | println('odd(11)=' odd(11)) 14 | println('even(11)=' even(11)) 15 | 16 | ## Expected 17 | odd(10)=0 18 | even(10)=1 19 | odd(11)=1 20 | even(11)=0 21 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/owned.bau: -------------------------------------------------------------------------------- 1 | fun main() 2 | x : Entry+() 3 | x.key = 1 4 | x.value = 100 5 | x.print() 6 | y : x 7 | y.print() 8 | println('end') 9 | 10 | type Entry 11 | key int 12 | value int 13 | 14 | fun clear(n Entry+) 15 | println('clear ' n.key) 16 | 17 | fun Entry+ print() 18 | println('key: ' key ' value: ' value) 19 | 20 | ## Expected 21 | key: 1 value: 100 22 | key: 1 value: 100 23 | end 24 | -------------------------------------------------------------------------------- /transpile.md: -------------------------------------------------------------------------------- 1 | # Transpile 2 | 3 | Download and build the latest version: 4 | 5 | git clone git@github.com:thomasmueller/bau-lang.git 6 | cd bau-lang 7 | 8 | Using Maven: 9 | 10 | mvn -DskipTests clean install 11 | 12 | Using the Make: 13 | 14 | make jar 15 | 16 | Create a `demo.bau` file, transpile it, compile, and run: 17 | 18 | echo "println('Hello World')" > hello.bau 19 | java -jar target/*.jar hello.bau 20 | gcc -O3 hello.c -o hello 21 | ./hello 22 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/typeWithParameter.bau: -------------------------------------------------------------------------------- 1 | type List(T) 2 | array T[] 3 | size int 4 | 5 | fun List(T) add(x T) 6 | if size >= array.len 7 | n : T[array.len * 2] 8 | array = n 9 | array[size] = x 10 | size += 1 11 | 12 | fun test() 13 | intList := List(int)(int[4]) 14 | intList.add(10) 15 | intList.add(20) 16 | println(intList.array[0]) 17 | println(intList.array[1]) 18 | 19 | test() 20 | 21 | ## Expected 22 | 10 23 | 20 24 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/arrayRange.bau: -------------------------------------------------------------------------------- 1 | fun test() 2 | data : i8[10] 3 | if data.len <= 0 4 | return 5 | i := 0 .. data.len 6 | while 1 = 1 7 | data[i]! = i 8 | next : i + 1 9 | break next >= data.len 10 | i = next 11 | sum := 0 12 | i = 0 13 | while 1 = 1 14 | sum += data[i]! 15 | next : i + 1 16 | break next >= data.len 17 | i = next 18 | println(sum) 19 | 20 | test() 21 | 22 | ## Expected 23 | 45 24 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/swift/piDigits/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version: 6.0 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "piDigits", 7 | dependencies: [ 8 | .package(url: "https://github.com/attaswift/BigInt.git", from: "5.4.0") 9 | ], 10 | targets: [ 11 | .executableTarget( 12 | name: "piDigits", 13 | dependencies: [ 14 | .product(name: "BigInt", package: "BigInt") 15 | ] 16 | ) 17 | ] 18 | ) 19 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/factorial.bau: -------------------------------------------------------------------------------- 1 | fun factorial(x int) int 2 | if x <= 1 3 | return 1 4 | return x * factorial(x - 1) 5 | 6 | i := 0 7 | while i <= 10 8 | println('Factorial of ' i ' = ' factorial(i)) 9 | i += 1 10 | 11 | ## Expected 12 | Factorial of 0 = 1 13 | Factorial of 1 = 1 14 | Factorial of 2 = 2 15 | Factorial of 3 = 6 16 | Factorial of 4 = 24 17 | Factorial of 5 = 120 18 | Factorial of 6 = 720 19 | Factorial of 7 = 5040 20 | Factorial of 8 = 40320 21 | Factorial of 9 = 362880 22 | Factorial of 10 = 3628800 23 | -------------------------------------------------------------------------------- /src/main/resources/org/bau/Convert.bau: -------------------------------------------------------------------------------- 1 | module org.bau.Convert 2 | 3 | import org.bau.Exception 4 | exception 5 | 6 | # parse an integer 7 | # overflow is ignored 8 | # throws an exception if the string does not match [0-9]+ 9 | fun parsePositiveInt(s i8[]) int throws exception 10 | result := 0 11 | if s.len = 0 12 | throw exception(s) 13 | for i := until(s.len) 14 | c : s[i] 15 | if c <= ord('0') or c >= ord('9') 16 | throw exception(s) 17 | result = result * 10 + c - ord('0') 18 | return result -------------------------------------------------------------------------------- /src/test/java/org/bau/ena/Token.java: -------------------------------------------------------------------------------- 1 | package org.bau.ena; 2 | 3 | public final class Token { 4 | final TokenType type; 5 | final String lexeme; 6 | final int line; 7 | final int column; 8 | 9 | Token(TokenType type, String lexeme, int line, int column) { 10 | this.type = type; 11 | this.lexeme = lexeme; 12 | this.line = line; 13 | this.column = column; 14 | } 15 | 16 | @Override 17 | public String toString() { 18 | return type + "(" + lexeme + ")@" + line + ":" + column; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/throwCatchVoidFunction.bau: -------------------------------------------------------------------------------- 1 | import org.bau.Exception 2 | exception 3 | 4 | fun print(x int) throws exception 5 | if x > 5 6 | throw exception('Value too large') 7 | println('x = ' x); 8 | 9 | i := 0 10 | while i <= 10 11 | print(i) 12 | catch e 13 | println('Error: ' e.message) 14 | i += 1 15 | 16 | ## Expected 17 | x = 0 18 | x = 1 19 | x = 2 20 | x = 3 21 | x = 4 22 | x = 5 23 | Error: Value too large 24 | Error: Value too large 25 | Error: Value too large 26 | Error: Value too large 27 | Error: Value too large 28 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/functionsBubbleSort.bau: -------------------------------------------------------------------------------- 1 | fun bubbleSort(T type, array T..) 2 | n := array.len 3 | while 1 4 | swapped := 0 5 | for i := until(array.len - 1) 6 | if array[i] > array[i + 1] 7 | tmp := array[i] 8 | array[i] = array[i + 1] 9 | array[i + 1] = tmp 10 | swapped = 1 11 | n -= 1 12 | break swapped = 0 13 | for i:= until(array.len) 14 | println(array[i]) 15 | 16 | bubbleSort(int, 1, 3, 2) 17 | 18 | ## Expected 19 | 1 20 | 2 21 | 3 22 | -------------------------------------------------------------------------------- /src/test/java/org/bau/ena/TokenType.java: -------------------------------------------------------------------------------- 1 | package org.bau.ena; 2 | 3 | enum TokenType { 4 | // Special 5 | EOF, NEWLINE, INDENT, DEDENT, 6 | 7 | // Identifiers and literals 8 | IDENT, INT, REAL, TEXT, 9 | 10 | // Keywords 11 | IF, ELIF, ELSE, LOOP, EXIT, RET, FUN, TYPE, AND, OR, 12 | 13 | // Punctuation 14 | LPAREN, RPAREN, LBRACK, RBRACK, COMMA, DOT, 15 | 16 | // Operators 17 | ASSIGN, // : (assignment) 18 | EQ, // = (equality) 19 | PLUS, MINUS, STAR, SLASH, PERCENT, LT, GT, LE, GE, NE, // <> is NE 20 | SHL, SHR, AMP, BAR, CARET, 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/org/bau/perf/TooSimple.java: -------------------------------------------------------------------------------- 1 | package org.bau.perf; 2 | 3 | // https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 4 | 5 | // output: 3.141591654 6 | public class TooSimple { 7 | public static void main(String[] args) { 8 | // long n = Long.parseLong(args[0]); 9 | long n = 1_000_000; 10 | double sum = 0.0; 11 | double flip = -1.0; 12 | for (long i = 1; i <= n; i++) { 13 | flip *= -1.0; 14 | sum += flip / (2 * i - 1); 15 | } 16 | System.out.printf("%.9f\n", sum * 4.0); 17 | } 18 | 19 | } 20 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # This makefile allows to build and use the transpiler 2 | # without having to install Maven etc. 3 | 4 | jar: 5 | mkdir -p target/build 6 | javac -d target/build -sourcepath src/main/java src/main/java/org/bau/tools/Transpile.java 7 | cp -r src/main/resources/* target/build/ 8 | echo "Main-Class: org.bau.tools.Transpile" > target/manifest.txt 9 | jar cfm target/bau.jar target/manifest.txt -C target/build . 10 | 11 | transpile: 12 | java -jar target/bau.jar demo.bau 13 | 14 | compile: 15 | gcc -O3 demo.c -o demo 16 | 17 | run: 18 | ./demo 19 | 20 | clean: 21 | rm -rf target/build 22 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/utils.bau: -------------------------------------------------------------------------------- 1 | import org.bau.Utils 2 | import org.bau.Math 3 | 4 | a := Utils.getNanoTime() 5 | println(a) 6 | b := Utils.getNanoTime() 7 | println(a) 8 | c := Utils.getDateTime() 9 | println(c.year '-' c.month '-' c.day ' ' c.hour ':' c.minute ':' c.second '.' c.millis) 10 | Utils.setRandomSeed(Utils.getNanoTime()) 11 | println(Utils.random()) 12 | println(Math.PI) 13 | for i := range(2, 4) 14 | println(Math.sqrt(i)) 15 | 16 | ## Expected 17 | 0 18 | 0 19 | 2000-1-1 0:0:0.0 20 | -2152535657050944081 21 | 3.141592653589793 22 | 1.4142135623730954 23 | 1.7320508075688774 24 | -------------------------------------------------------------------------------- /src/main/java/org/bau/parser/ProgramContext.java: -------------------------------------------------------------------------------- 1 | package org.bau.parser; 2 | 3 | import java.util.LinkedHashSet; 4 | 5 | public class ProgramContext { 6 | FunctionDefinition function; 7 | int nextExceptionVariableId; 8 | int nextSkipLabel; 9 | int nextCatchLabel; 10 | DataType needToCatch; 11 | public LinkedHashSet delareList = new LinkedHashSet<>(); 12 | 13 | void nextFunction() { 14 | nextExceptionVariableId = 0; 15 | nextSkipLabel = 0; 16 | nextCatchLabel = 0; 17 | needToCatch = null; 18 | delareList.clear(); 19 | } 20 | 21 | } 22 | -------------------------------------------------------------------------------- /src/test/java/org/bau/utils/TestParseHex.java: -------------------------------------------------------------------------------- 1 | package org.bau.utils; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import java.util.Random; 6 | 7 | import org.bau.parser.NumberValue; 8 | import org.junit.Test; 9 | 10 | public class TestParseHex { 11 | @Test 12 | public void test() { 13 | Random r = new Random(1); 14 | for (int i = 0; i < 100; i++) { 15 | long x = r.nextLong(); 16 | String hex = Long.toHexString(x); 17 | long y = NumberValue.parseUnsignedHexLong(hex); 18 | assertEquals(x, y); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/hexOrd.bau: -------------------------------------------------------------------------------- 1 | ## 2 | fun ord(s i8[]) int 3 | if s.len <= 0 4 | return 0 5 | return s[0] 6 | ## 7 | 8 | fun hex(x int, len int) i8[] 9 | l := len 10 | if l < 0 11 | l = 0 12 | elif l > 8 13 | l = 8 14 | data : i8[l] 15 | y := x 16 | i := l - 1 17 | while i >= 0 18 | c := ord('0') + (y & 0xf) 19 | if (y & 0xf) > 9 20 | c = ord('a') + (y & 0xf) - 10 21 | data[i] = c 22 | y >>= 4 23 | i -= 1 24 | return data 25 | 26 | println(hex(0x12fea234, 8)) 27 | 28 | ## Expected 29 | 12fea234 30 | -------------------------------------------------------------------------------- /config/bau/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "bau", 3 | "version": "0.0.1", 4 | "engines": { 5 | "vscode": ">=1.0.0" 6 | }, 7 | "publisher": "me", 8 | "contributes": { 9 | "languages": [{ 10 | "id": "bau", 11 | "aliases": ["Bau", "bau"], 12 | "extensions": [".bau",".bau"], 13 | "configuration": "./language-configuration.json" 14 | }], 15 | "grammars": [{ 16 | "language": "bau", 17 | "scopeName": "source.bau", 18 | "path": "./syntaxes/bau.tmLanguage.json" 19 | }] 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/java/org/bau/parser/Trait.java: -------------------------------------------------------------------------------- 1 | package org.bau.parser; 2 | 3 | import java.util.ArrayList; 4 | 5 | public class Trait { 6 | private final FullName fullName; 7 | final ArrayList functions = new ArrayList<>(); 8 | public final ArrayList requiredTraitNames = new ArrayList<>(); 9 | private int slot; 10 | 11 | public Trait(FullName fullName) { 12 | this.fullName = fullName; 13 | } 14 | 15 | public String getName() { 16 | return fullName.name; 17 | } 18 | 19 | public String getModule() { 20 | return fullName.module; 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/ternaryCondition.bau: -------------------------------------------------------------------------------- 1 | fun if(condition int, a T, b T) T 2 | if condition 3 | return a 4 | return b 5 | 6 | fun int then(a T, b T) const T 7 | if this 8 | return a 9 | return b 10 | 11 | fun typeName(a T) i8[] 12 | return T.name 13 | 14 | for i := range(-1, 2) 15 | println('abs(' i ')= ' if(i < 0, -i, i)) 16 | println('abs(' i ')= ' (i < 0).then(-i, i)) 17 | println('typeName: ' typeName(1)) 18 | 19 | ## Expected 20 | abs(-1)= 1 21 | abs(-1)= 1 22 | typeName: int 23 | abs(0)= 0 24 | abs(0)= 0 25 | typeName: int 26 | abs(1)= 1 27 | abs(1)= 1 28 | typeName: int 29 | -------------------------------------------------------------------------------- /src/test/java/org/bau/benchmarks/Loop.kt: -------------------------------------------------------------------------------- 1 | package org.bau.benchmarks 2 | 3 | import java.util.* 4 | 5 | fun main(args: Array) { 6 | require(args.size >= 1) 7 | val main = Class.forName(args[0]).getMethod("main", Array::class.java) 8 | val a2 = Arrays.copyOfRange(args, 1, args.size) 9 | for (i in 0..2) { 10 | // Just an attempt to collect garbage 11 | System.gc() 12 | val start = System.currentTimeMillis() 13 | main.invoke(null, a2 as Any) 14 | val time = System.currentTimeMillis() - start 15 | System.out.printf("\nRun #%d: %3.3f s\n", i, time / 1000.0) 16 | System.gc() 17 | } 18 | } -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/munchausen.py: -------------------------------------------------------------------------------- 1 | # https://github.com/jabbalaci/SpeedTests 2 | 3 | LIMIT = 440_000_000 4 | 5 | def main(): 6 | cache: list[int] = get_cache() 7 | for n in range(0, LIMIT): 8 | if is_munchausen(n, cache): 9 | print(n) 10 | 11 | def is_munchausen(number: int, cache: list[int]) -> bool: 12 | n = number 13 | total = 0 14 | while n > 0: 15 | digit = n % 10 16 | total += cache[digit] 17 | if total > number: 18 | return False 19 | n = n // 10 20 | return total == number 21 | 22 | def get_cache() -> list[int]: 23 | return [0] + [i ** i for i in range(1, 10)] 24 | 25 | main() 26 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/python/munchausen.py: -------------------------------------------------------------------------------- 1 | # https://github.com/jabbalaci/SpeedTests 2 | 3 | LIMIT = 440_000_000 4 | 5 | def main(): 6 | cache: list[int] = get_cache() 7 | for n in range(0, LIMIT): 8 | if is_munchausen(n, cache): 9 | print(n) 10 | 11 | def is_munchausen(number: int, cache: list[int]) -> bool: 12 | n = number 13 | total = 0 14 | while n > 0: 15 | digit = n % 10 16 | total += cache[digit] 17 | if total > number: 18 | return False 19 | n = n // 10 20 | return total == number 21 | 22 | def get_cache() -> list[int]: 23 | return [0] + [i ** i for i in range(1, 10)] 24 | 25 | main() 26 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/munchausen.bau: -------------------------------------------------------------------------------- 1 | # https://github.com/jabbalaci/SpeedTests 2 | 3 | import org.bau.Math 4 | 5 | fun main() 6 | for i := until(LIMIT) 7 | if isMunchausen(i) 8 | println(i) 9 | 10 | fun isMunchausen(number int) int 11 | n := number 12 | total := 0 13 | while n > 0 14 | digit : n % 10 15 | total += cache[digit] 16 | if total > number 17 | return 0 18 | n /= 10 19 | return total = number 20 | 21 | fun getCache() const int[] 22 | result : int[10] 23 | for i := range(1, 10) 24 | result[i] = int(Math.pow(i, i)) 25 | return result 26 | 27 | LIMIT : 440_000_000 28 | cache : getCache() 29 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/bau/munchausen.bau: -------------------------------------------------------------------------------- 1 | # https://github.com/jabbalaci/SpeedTests 2 | 3 | import org.bau.Math 4 | 5 | fun main() 6 | for i := until(LIMIT) 7 | if isMunchausen(i) 8 | println(i) 9 | 10 | fun isMunchausen(number int) int 11 | n := number 12 | total := 0 13 | while n > 0 14 | digit : n % 10 15 | total += cache[digit] 16 | if total > number 17 | return 0 18 | n /= 10 19 | return total = number 20 | 21 | fun getCache() const int[] 22 | result : int[10] 23 | for i := range(1, 10) 24 | result[i] = int(Math.pow(i, i)) 25 | return result 26 | 27 | LIMIT : 440_000_000 28 | cache : getCache() 29 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/collections/BitField.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.collections; 2 | 3 | public class BitField { 4 | 5 | private final long[] data; 6 | 7 | public BitField(int len) { 8 | data = new long[(len + 63) / 64]; 9 | } 10 | 11 | public void set(int index) { 12 | data[index >>> 6] |= 1L << (index & 0x3f); 13 | } 14 | 15 | public void flip(int index) { 16 | data[index >>> 6] ^= 1L << (index & 0x3f); 17 | } 18 | 19 | public void clear(int index) { 20 | data[index >>> 6] &= ~(1L << (index & 0x3f)); 21 | } 22 | 23 | public boolean get(int index) { 24 | return (data[index >>> 6] >> (index & 0x3f) & 1) == 1; 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /src/main/resources/org/bau/os/Signal.bau: -------------------------------------------------------------------------------- 1 | module org.bau.os.Signal 2 | 3 | enum signalId 4 | SIGHUP: 1 5 | SIGINT 6 | SIGQUIT 7 | SIGILL 8 | SIGTRAP 9 | SIGABRT 10 | SIGEMT 11 | SIGFPE 12 | SIGKILL 13 | SIGBUS 14 | SIGSEGV 15 | SIGSYS 16 | SIGPIPE 17 | SIGALRM 18 | SIGTERM 19 | SIGURG 20 | SIGSTOP 21 | SIGTSTP 22 | SIGCONT 23 | SIGCHLD 24 | SIGTTIN 25 | SIGTTOU 26 | SIGIO 27 | SIGXCPU 28 | SIGXFSZ 29 | SIGVTALRM 30 | SIGPROF 31 | SIGWINCH 32 | SIGINFO 33 | SIGUSR1 34 | SIGUSR2 35 | 36 | fun signal(signalId int, callback fun(i32)) 37 | native(`#include 38 | signal(signalId, callback_1); 39 | `) 40 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/sort/BinarySearch.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.sort; 2 | 3 | public class BinarySearch { 4 | 5 | public static > int binarySearch(T[] d, T x) { 6 | return binarySearch(d, x, 0, d.length); 7 | } 8 | 9 | public static > int binarySearch(T[] d, T x, int from, int to) { 10 | while (from < to) { 11 | int m = (from + to) >>> 1; 12 | int cmp = x.compareTo(d[m]); 13 | if (cmp > 0) { 14 | from = m + 1; 15 | } else if (cmp < 0) { 16 | to = m; 17 | } else { 18 | return m; 19 | } 20 | } 21 | return -from - 1; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/security/SHA256Test.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.security; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import java.nio.charset.StandardCharsets; 6 | 7 | import org.bau.stdlib.string.HexEncode; 8 | import org.junit.Test; 9 | 10 | public class SHA256Test { 11 | 12 | @Test 13 | public void test() { 14 | assertEquals("ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad", 15 | HexEncode.convertBytesToHex(SHA256.getHash("abc".getBytes(StandardCharsets.UTF_8)))); 16 | assertEquals("cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0", 17 | HexEncode.convertBytesToHex(SHA256.getHash("a".repeat(1000000).getBytes(StandardCharsets.UTF_8)))); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/munchausen.nim: -------------------------------------------------------------------------------- 1 | # https://github.com/jabbalaci/SpeedTests 2 | 3 | import math 4 | 5 | func get_cache(): array[10, int] = 6 | result[0] = 0 7 | for i in 1 .. 9: 8 | result[i] = i ^ i 9 | 10 | const 11 | MAX = 440_000_000 12 | cache: array[10, int] = get_cache() 13 | 14 | func is_munchausen(number: int): bool = 15 | var 16 | n = number 17 | total = 0 18 | while n > 0: 19 | let digit = n mod 10 20 | total += cache[digit] 21 | if total > number: 22 | return false 23 | n = n div 10 24 | total == number 25 | 26 | proc main() = 27 | for i in 0 ..< MAX: 28 | if is_munchausen(i): 29 | echo i 30 | 31 | when isMainModule: 32 | main() -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/comment.bau: -------------------------------------------------------------------------------- 1 | # Line comment 2 | 3 | ## 4 | Block comment 5 | ## 6 | 7 | ## 8 | A list of entries 9 | ## 10 | type List(T) 11 | array T[] 12 | size int 13 | 14 | ## 15 | Add an entry to the list 16 | ## 17 | fun List(T) add(x T) 18 | if size >= array.len 19 | n : T[array.len * 2] 20 | for i := until(size) 21 | n[i] = array[i] 22 | array = n 23 | array[size] = x 24 | size += 1 25 | 26 | # Test function 27 | fun test() 28 | list := List(int)(int[1]) 29 | for i := range(0 10) 30 | list.add(i) 31 | for i := until(list.size) 32 | println(list.array[i]) 33 | 34 | test() 35 | 36 | ## Expected 37 | 0 38 | 1 39 | 2 40 | 3 41 | 4 42 | 5 43 | 6 44 | 7 45 | 8 46 | 9 47 | -------------------------------------------------------------------------------- /src/main/java/org/bau/parser/LeftValue.java: -------------------------------------------------------------------------------- 1 | package org.bau.parser; 2 | 3 | import org.bau.runtime.Memory; 4 | import org.bau.runtime.Value; 5 | 6 | /** 7 | * An assignment target 8 | */ 9 | public interface LeftValue extends Expression { 10 | 11 | String assignmentC(); 12 | 13 | Expression replace(Variable old, Expression with); 14 | 15 | void setBoundValue(Expression scope, String modify, Expression value); 16 | 17 | void addBoundCondition(Expression scope, String operation, Expression right); 18 | 19 | String decrementRefCountC(); 20 | String incrementRefCountC(); 21 | 22 | Value setValue(Memory memory, Value val, boolean incRefCount, boolean initial); 23 | 24 | boolean isContant(); 25 | 26 | void incrementReassignCount(); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/nim/munchausen.nim: -------------------------------------------------------------------------------- 1 | # https://github.com/jabbalaci/SpeedTests 2 | 3 | import math 4 | 5 | func get_cache(): array[10, int] = 6 | result[0] = 0 7 | for i in 1 .. 9: 8 | result[i] = i ^ i 9 | 10 | const 11 | MAX = 440_000_000 12 | cache: array[10, int] = get_cache() 13 | 14 | func is_munchausen(number: int): bool = 15 | var 16 | n = number 17 | total = 0 18 | while n > 0: 19 | let digit = n mod 10 20 | total += cache[digit] 21 | if total > number: 22 | return false 23 | n = n div 10 24 | total == number 25 | 26 | proc main() = 27 | for i in 0 ..< MAX: 28 | if is_munchausen(i): 29 | echo i 30 | 31 | when isMainModule: 32 | main() -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/string2.bau: -------------------------------------------------------------------------------- 1 | import org.bau.String 2 | indexOf 3 | replaceAll 4 | substring 5 | split 6 | 7 | import org.bau.List 8 | List 9 | 10 | fun test() 11 | x : 'hello world' 12 | println('indexOf ll: ' indexOf(x, 'll')) 13 | println('l ->L : ' replaceAll('hello world', 'l', 'L')) 14 | println('l ->LL: ' replaceAll('hello world', 'l', 'LL')) 15 | println('ll->L : ' replaceAll('hello world', 'll', 'L')) 16 | list : split('hello,world,!', ',') 17 | for i := until(list.size) 18 | s : list.get(i) 19 | println('#' i ': ' s.data) 20 | 21 | test() 22 | 23 | ## Expected 24 | indexOf ll: 2 25 | l ->L : heLLo worLd 26 | l ->LL: heLLLLo worLLd 27 | ll->L : heLo world 28 | #0: hello 29 | #1: world 30 | #2: ! 31 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/typeOpenClose.bau: -------------------------------------------------------------------------------- 1 | type File 2 | fp int 3 | 4 | fun openFile(fp int) File 5 | f : File() 6 | f.fp = fp 7 | println('opening ' f.fp) 8 | return f 9 | 10 | fun File close() 11 | println('closing ' fp) 12 | 13 | fun File use() 14 | println('use ' fp) 15 | 16 | i := 0 17 | while i < 10 18 | f : openFile(i) 19 | println('opened ' i) 20 | break i = 5 21 | f.use() 22 | i += 1 23 | 24 | ## Expected 25 | opening 0 26 | opened 0 27 | use 0 28 | closing 0 29 | opening 1 30 | opened 1 31 | use 1 32 | closing 1 33 | opening 2 34 | opened 2 35 | use 2 36 | closing 2 37 | opening 3 38 | opened 3 39 | use 3 40 | closing 3 41 | opening 4 42 | opened 4 43 | use 4 44 | closing 4 45 | opening 5 46 | opened 5 47 | closing 5 48 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/munchausen.bau: -------------------------------------------------------------------------------- 1 | fun main() 2 | for i := until(LIMIT) 3 | if isMunchausen(i) 4 | println(i) 5 | 6 | fun getCache() const int[] 7 | result : int[10] 8 | result[0] = 0 9 | for i := range(1, 10) 10 | result[i] = pow(i, i) 11 | return result 12 | 13 | fun pow(a int, b int) const int 14 | result := 1 15 | for i := until(b) 16 | result *= a 17 | return result 18 | 19 | fun isMunchausen(number int) int 20 | n := number 21 | total := 0 22 | while n > 0 23 | digit : n % 10 24 | total += cache[digit]! 25 | if total > number 26 | return 0 27 | n /= 10 28 | return total = number 29 | 30 | LIMIT : 4400 31 | cache : getCache() 32 | 33 | ## Expected 34 | 0 35 | 1 36 | 3435 37 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/munchausen.swift: -------------------------------------------------------------------------------- 1 | // https://github.com/jabbalaci/SpeedTests 2 | 3 | import Foundation 4 | 5 | let LIMIT = 440_000_000 6 | 7 | let cache: [Int] = { 8 | var result = [Int](repeating: 0, count: 10) 9 | for i in 1...9 { 10 | result[i] = Int(pow(Double(i), Double(i))) 11 | } 12 | return result 13 | }() 14 | 15 | func isMunchausen(_ number: Int) -> Bool { 16 | var n = number 17 | var total = 0 18 | while n > 0 { 19 | let digit = n % 10 20 | total += cache[digit] 21 | if total > number { 22 | return false 23 | } 24 | n /= 10 25 | } 26 | return total == number 27 | } 28 | 29 | func main() { 30 | for i in 0 ..< LIMIT { 31 | if isMunchausen(i) { 32 | print(i) 33 | } 34 | } 35 | } 36 | 37 | main() -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/munchausen.v: -------------------------------------------------------------------------------- 1 | // https://github.com/jabbalaci/SpeedTests 2 | 3 | import math 4 | 5 | const limit = 440_000_000 6 | 7 | fn main() { 8 | cache := get_cache() 9 | for i in 0 .. limit { 10 | if is_munchausen(i, cache) { 11 | println(i) 12 | } 13 | } 14 | } 15 | 16 | fn is_munchausen(number int, cache []int) bool { 17 | mut n := number 18 | mut total := 0 19 | for n > 0 { 20 | digit := n % 10 21 | total += cache[digit] 22 | if total > number { 23 | return false 24 | } 25 | n /= 10 26 | } 27 | return total == number 28 | } 29 | 30 | fn get_cache() []int { 31 | mut result := []int{len: 10} 32 | for i in 1 .. 10 { 33 | result[i] = int(math.pow(f64(i), f64(i))) 34 | } 35 | return result 36 | } 37 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/swift/munchausen.swift: -------------------------------------------------------------------------------- 1 | // https://github.com/jabbalaci/SpeedTests 2 | 3 | import Foundation 4 | 5 | let LIMIT = 440_000_000 6 | 7 | let cache: [Int] = { 8 | var result = [Int](repeating: 0, count: 10) 9 | for i in 1...9 { 10 | result[i] = Int(pow(Double(i), Double(i))) 11 | } 12 | return result 13 | }() 14 | 15 | func isMunchausen(_ number: Int) -> Bool { 16 | var n = number 17 | var total = 0 18 | while n > 0 { 19 | let digit = n % 10 20 | total += cache[digit] 21 | if total > number { 22 | return false 23 | } 24 | n /= 10 25 | } 26 | return total == number 27 | } 28 | 29 | func main() { 30 | for i in 0 ..< LIMIT { 31 | if isMunchausen(i) { 32 | print(i) 33 | } 34 | } 35 | } 36 | 37 | main() -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/v/munchausen.v: -------------------------------------------------------------------------------- 1 | // https://github.com/jabbalaci/SpeedTests 2 | 3 | import math 4 | 5 | const limit = 440_000_000 6 | 7 | fn main() { 8 | cache := get_cache() 9 | for i in 0 .. limit { 10 | if is_munchausen(i, cache) { 11 | println(i) 12 | } 13 | } 14 | } 15 | 16 | fn is_munchausen(number int, cache []int) bool { 17 | mut n := number 18 | mut total := 0 19 | for n > 0 { 20 | digit := n % 10 21 | total += cache[digit] 22 | if total > number { 23 | return false 24 | } 25 | n /= 10 26 | } 27 | return total == number 28 | } 29 | 30 | fn get_cache() []int { 31 | mut result := []int{len: 10} 32 | for i in 1 .. 10 { 33 | result[i] = int(math.pow(f64(i), f64(i))) 34 | } 35 | return result 36 | } 37 | -------------------------------------------------------------------------------- /src/main/resources/org/bau/Env.bau: -------------------------------------------------------------------------------- 1 | module org.bau.Env 2 | 3 | fun argCount() int 4 | native(``` 5 | return __argc; 6 | ```) 7 | return 0 8 | 9 | fun exit(code int) 10 | native(``` 11 | exit(code); 12 | ```) 13 | println('Exit code ' code '; will now throw an array out-of-bounds exception') 14 | x : int[0] 15 | x[0] = 1 16 | 17 | fun atExit(callback fun()) 18 | native(``` 19 | atexit(callback_0); 20 | ```) 21 | 22 | fun arg(index int) i8[] 23 | if index < 0 or index >= argCount() 24 | return i8[0] 25 | len := 0 26 | native(``` 27 | #include 28 | len = strlen(__argv[index]); 29 | ```) 30 | result : i8[len] 31 | native(``` 32 | strncpy((char*) result->data, __argv[index], len); 33 | ```) 34 | return result 35 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/functions.bau: -------------------------------------------------------------------------------- 1 | import org.bau.Utils 2 | 3 | fun square(x int) int 4 | return x * x 5 | 6 | fun square(a int, b int) int 7 | return a * a + b * b 8 | 9 | fun sum(a int, b int..) int 10 | sum := a 11 | for i := until(b.len) 12 | sum += b[i] 13 | return sum 14 | 15 | fun int rotateRight(n int) int 16 | return (this >> n) | (this << (64 - n)) 17 | 18 | fun float twice() float 19 | return this + this 20 | 21 | println(square(2) ' ' square(2 3)) 22 | println(sum(1 2)) 23 | println(sum(1 2 3)) 24 | println(sum(1 2 3 4)) 25 | println('ascii of "0" is ' ord('0')) 26 | println(1.rotateRight(1) ' = ' 0x1.rotateRight(1)) 27 | 28 | println(1.0.twice() ' = ' 1.0e0.twice()) 29 | 30 | ## Expected 31 | 4 13 32 | 3 33 | 6 34 | 10 35 | ascii of "0" is 48 36 | -9223372036854775808 = -9223372036854775808 37 | 2.0 = 2.0 38 | -------------------------------------------------------------------------------- /src/test/java/org/bau/benchmarks/Munchausen.kt: -------------------------------------------------------------------------------- 1 | // https://github.com/jabbalaci/SpeedTests 2 | 3 | package org.bau.benchmarks 4 | 5 | import kotlin.math.pow 6 | 7 | var LIMIT: Int = 440000000 8 | var cache: IntArray = getCache2() 9 | 10 | fun main(args: Array) { 11 | for (i in 0 until LIMIT) 12 | if (isMunchausen(i)) 13 | println(i) 14 | } 15 | 16 | fun isMunchausen(number: Int): Boolean { 17 | var n = number 18 | var total = 0 19 | while (n > 0) { 20 | val digit = n % 10 21 | total += cache[digit] 22 | if (total > number) 23 | return false 24 | n /= 10 25 | } 26 | return total == number 27 | } 28 | 29 | fun getCache2(): IntArray { 30 | val cache = IntArray(10) 31 | for (i in 1..9) 32 | cache[i] = i.toDouble().pow(i.toDouble()).toInt() 33 | return cache 34 | } -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/munchausen.rs: -------------------------------------------------------------------------------- 1 | // https://github.com/jabbalaci/SpeedTests 2 | 3 | const LIMIT: i32 = 440_000_000; 4 | 5 | fn main() { 6 | let cache = get_cache(); 7 | for n in 0 .. LIMIT { 8 | if is_munchausen(n, &cache) { 9 | println!("{}", n); 10 | } 11 | } 12 | } 13 | 14 | fn is_munchausen(number: i32, cache: &[i32; 10]) -> bool { 15 | let mut n = number; 16 | let mut total = 0; 17 | while n > 0 { 18 | let digit = n % 10; 19 | total += cache[digit as usize]; 20 | if total > number { 21 | return false; 22 | } 23 | n /= 10; 24 | } 25 | number == total 26 | } 27 | 28 | fn get_cache() -> [i32; 10] { 29 | let mut cache = [0; 10]; 30 | for n in 1..=9 { 31 | cache[n] = (n as i32).pow(n as u32); 32 | } 33 | cache 34 | } 35 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/rust/munchausen.rs: -------------------------------------------------------------------------------- 1 | // https://github.com/jabbalaci/SpeedTests 2 | 3 | const LIMIT: i32 = 440_000_000; 4 | 5 | fn main() { 6 | let cache = get_cache(); 7 | for n in 0 .. LIMIT { 8 | if is_munchausen(n, &cache) { 9 | println!("{}", n); 10 | } 11 | } 12 | } 13 | 14 | fn is_munchausen(number: i32, cache: &[i32; 10]) -> bool { 15 | let mut n = number; 16 | let mut total = 0; 17 | while n > 0 { 18 | let digit = n % 10; 19 | total += cache[digit as usize]; 20 | if total > number { 21 | return false; 22 | } 23 | n /= 10; 24 | } 25 | number == total 26 | } 27 | 28 | fn get_cache() -> [i32; 10] { 29 | let mut cache = [0; 10]; 30 | for n in 1..=9 { 31 | cache[n] = (n as i32).pow(n as u32); 32 | } 33 | cache 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/sort/number/NumberShellSort.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.sort.number; 2 | 3 | public class NumberShellSort { 4 | 5 | public static void sort(long[] a) { 6 | sort(a, 0, a.length); 7 | } 8 | 9 | public static void sort(long[] a, int from, int to) { 10 | int h = 16, gap = 1; 11 | while (to - from > h / 16) { 12 | h = h + h + h / 4 + 16; 13 | } 14 | do { 15 | h = (h - 16) * 4 / 9; 16 | gap = (int) ((h + 15) / 16); 17 | for (int i = gap + from; i < to; i++) { 18 | long t = a[i]; 19 | int j = i; 20 | for (; j >= gap + from && a[j - gap] > t; j -= gap) { 21 | a[j] = a[j - gap]; 22 | } 23 | a[j] = t; 24 | } 25 | } while (gap > 1); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/enum.bau: -------------------------------------------------------------------------------- 1 | enum weekday 2 | sunday: 0 3 | monday 4 | tuesday 5 | wednesday: 3 6 | thursday 7 | friday 8 | saturday 9 | 10 | fun get(a int) int 11 | println('day ' a) 12 | return a 13 | 14 | for a := until(weekday.saturday + 1) 15 | switch get(a) 16 | case weekday.sunday 17 | println('...is sunday') 18 | case weekday.monday 19 | println('...is monday') 20 | case weekday.tuesday, 21 | weekday.wednesday 22 | println('...is tuesday or wednesday') 23 | else 24 | println('...is some other day') 25 | 26 | ## Expected 27 | day 0 28 | ...is sunday 29 | day 1 30 | ...is monday 31 | day 2 32 | ...is tuesday or wednesday 33 | day 3 34 | ...is tuesday or wednesday 35 | day 4 36 | ...is some other day 37 | day 5 38 | ...is some other day 39 | day 6 40 | ...is some other day 41 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/c/munchausen.c: -------------------------------------------------------------------------------- 1 | // https://github.com/jabbalaci/SpeedTests/blob/master/c/main.c 2 | 3 | #include 4 | #include 5 | 6 | #define LIMIT 440000000 7 | 8 | int cache[10]; 9 | int is_munchausen(int number); 10 | void set_cache(); 11 | 12 | int main() { 13 | set_cache(); 14 | for (int i = 0; i < LIMIT; i++) 15 | if (is_munchausen(i)) 16 | printf("%d\n", i); 17 | return 0; 18 | } 19 | 20 | int is_munchausen(int number) { 21 | int n = number; 22 | int total = 0; 23 | while (n > 0) { 24 | int digit = n % 10; 25 | total += cache[digit]; 26 | if (total > number) 27 | return 0; 28 | n /= 10; 29 | } 30 | return total == number; 31 | } 32 | 33 | void set_cache() { 34 | cache[0] = 0; 35 | for (int i = 1; i <= 9; ++i) 36 | cache[i] = pow(i, i); 37 | } 38 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/munchausen.c: -------------------------------------------------------------------------------- 1 | // https://github.com/jabbalaci/SpeedTests/blob/master/c/main.c 2 | 3 | #include 4 | #include 5 | 6 | #define LIMIT 440000000 7 | 8 | int cache[10]; 9 | int is_munchausen(int number); 10 | void set_cache(); 11 | 12 | int main() { 13 | set_cache(); 14 | for (int i = 0; i < LIMIT; i++) 15 | if (is_munchausen(i)) 16 | printf("%d\n", i); 17 | return 0; 18 | } 19 | 20 | int is_munchausen(int number) { 21 | int n = number; 22 | int total = 0; 23 | while (n > 0) { 24 | int digit = n % 10; 25 | total += cache[digit]; 26 | if (total > number) 27 | return 0; 28 | n /= 10; 29 | } 30 | return total == number; 31 | } 32 | 33 | void set_cache() { 34 | cache[0] = 0; 35 | for (int i = 1; i <= 9; ++i) 36 | cache[i] = pow(i, i); 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/locale/NumberFormatterTest.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.locale; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Test; 6 | 7 | public class NumberFormatterTest { 8 | 9 | @Test 10 | public void format() { 11 | assertEquals("0", NumberFormatter.format(0, (byte) '_', 3, 3)); 12 | assertEquals("1_234", NumberFormatter.format(1234, (byte) '_', 3, 3)); 13 | assertEquals("1_234_567", NumberFormatter.format(1234567, (byte) '_', 3, 3)); 14 | assertEquals("1_234_567_890", NumberFormatter.format(1234567890, (byte) '_', 3, 3)); 15 | assertEquals("1_23_45_67_890", NumberFormatter.format(1234567890, (byte) '_', 3, 2)); 16 | assertEquals("12_3456_7890", NumberFormatter.format(1234567890, (byte) '_', 4, 4)); 17 | 18 | assertEquals("1 ' 234", NumberFormatter.format(1234, " ' ", 3, 3)); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/test/java/org/bau/ena/RegCompileTool.java: -------------------------------------------------------------------------------- 1 | package org.bau.ena; 2 | 3 | import org.bau.ena.ast.Stmt; 4 | import org.bau.ena.vm.reg.RegBytecode; 5 | import org.bau.ena.vm.reg.RegCompiler; 6 | 7 | import java.io.IOException; 8 | import java.nio.file.Files; 9 | import java.nio.file.Path; 10 | 11 | public final class RegCompileTool { 12 | public static void main(String[] args) throws IOException { 13 | if (args.length < 2) { 14 | System.err.println("Usage: RegCompileTool "); 15 | System.exit(1); 16 | } 17 | String src = Files.readString(Path.of(args[0])); 18 | Stmt.Program prog = Parser.parse(src); 19 | RegCompiler comp = new RegCompiler(); 20 | RegBytecode bc = comp.compile(prog); 21 | comp.writeToFile(bc, Path.of(args[1])); 22 | System.out.println("Wrote bytecode to " + args[1]); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/test/java/org/bau/TestInterpret.java: -------------------------------------------------------------------------------- 1 | package org.bau; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Test; 6 | 7 | import org.bau.parser.Parser; 8 | import org.bau.parser.Program; 9 | 10 | public class TestInterpret { 11 | 12 | @Test 13 | public void helloWorld() { 14 | Program p = new Parser("println('Hello World')").parse(); 15 | assertEquals("Hello World\n", p.run()); 16 | } 17 | 18 | @Test 19 | public void calc() { 20 | assertEquals("1 million + 1 = 1000001\n", new Parser( 21 | "println('1 million + 1 = ', 1_000_000 + 1)" 22 | ).parse().run()); 23 | } 24 | 25 | @Test 26 | public void calc2() { 27 | assertEquals("1 million + 1 = 1000001\n", new Parser( 28 | "println('1 million + 1 = ', 1_000_000 + 1,)" 29 | ).parse().run()); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/org/bau/benchmarks/Loop.java: -------------------------------------------------------------------------------- 1 | package org.bau.benchmarks; 2 | 3 | import java.lang.reflect.Method; 4 | import java.util.Arrays; 5 | 6 | public class Loop { 7 | 8 | public static void main(String... args) throws Exception { 9 | if (args.length < 1) { 10 | throw new IllegalArgumentException(); 11 | } 12 | Method main = Class.forName(args[0]).getMethod("main", String[].class); 13 | String[] a2 = Arrays.copyOfRange(args, 1, args.length); 14 | for (int i = 0; i < 3; i++) { 15 | // Just an attempt to collect garbage 16 | System.gc(); 17 | long start = System.currentTimeMillis(); 18 | main.invoke(null, (Object) a2); 19 | long time = System.currentTimeMillis() - start; 20 | System.out.printf("\nRun #%d: %3.3f s\n", i, time / 1000.0); 21 | System.gc(); 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /src/test/resources/org/bau/stringTest.bau: -------------------------------------------------------------------------------- 1 | type String 2 | data i8[] 3 | pos int 4 | 5 | fun newString() String 6 | s : String 7 | nd : i8[16] 8 | nd[0] = 65 9 | nd[1] = 0 10 | s.data = nd 11 | s.pos = 0 12 | return s 13 | 14 | fun String print() 15 | println(data) 16 | 17 | fun String resize() 18 | old : data 19 | nd : i8[old.len * 2] 20 | if (old.len > 0) and (nd.len > 0) 21 | i := 0..old.len 22 | j := 0..nd.len 23 | while 1 24 | nd[j] = old[i] 25 | break i + 1 > old.len 26 | break j + 1 > nd.len 27 | i += 1 28 | j += 1 29 | this.data = nd 30 | 31 | fun String append(x i8) 32 | if pos >= data.len - 1 33 | this.resize() 34 | d : this.data 35 | d[pos?] = x 36 | this.pos += 1 37 | 38 | s := newString() 39 | s.append(72) 40 | s.append(105) 41 | s.print() 42 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/munchausen.go: -------------------------------------------------------------------------------- 1 | // https://github.com/jabbalaci/SpeedTests 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "math" 8 | ) 9 | 10 | const LIMIT = 440_000_000 11 | 12 | func main() { 13 | cache := getCache() 14 | for i := 0; i < LIMIT; i++ { 15 | if isMunchausen(i, &cache) { 16 | fmt.Println(i) 17 | } 18 | } 19 | } 20 | 21 | func isMunchausen(number int, cache *[10]int) bool { 22 | n := number 23 | total := 0 24 | for n > 0 { 25 | digit := n % 10 26 | total += cache[digit] 27 | if total > number { 28 | return false 29 | } 30 | n /= 10 31 | } 32 | return total == number 33 | } 34 | 35 | func getCache() [10]int { 36 | var result [10]int 37 | for i := 1; i <= 9; i++ { 38 | result[i] = int(math.Pow(float64(i), float64(i))) 39 | } 40 | return result 41 | } 42 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/go/munchausen.go: -------------------------------------------------------------------------------- 1 | // https://github.com/jabbalaci/SpeedTests 2 | 3 | package main 4 | 5 | import ( 6 | "fmt" 7 | "math" 8 | ) 9 | 10 | const LIMIT = 440_000_000 11 | 12 | func main() { 13 | cache := getCache() 14 | for i := 0; i < LIMIT; i++ { 15 | if isMunchausen(i, &cache) { 16 | fmt.Println(i) 17 | } 18 | } 19 | } 20 | 21 | func isMunchausen(number int, cache *[10]int) bool { 22 | n := number 23 | total := 0 24 | for n > 0 { 25 | digit := n % 10 26 | total += cache[digit] 27 | if total > number { 28 | return false 29 | } 30 | n /= 10 31 | } 32 | return total == number 33 | } 34 | 35 | func getCache() [10]int { 36 | var result [10]int 37 | for i := 1; i <= 9; i++ { 38 | result[i] = int(math.Pow(float64(i), float64(i))) 39 | } 40 | return result 41 | } 42 | -------------------------------------------------------------------------------- /src/test/java/org/bau/LanguageFunctions.java: -------------------------------------------------------------------------------- 1 | package org.bau; 2 | 3 | /* 4 | 5 | Varargs 6 | Java void printNumbers(int... numbers) 7 | Python def manyArgs(*arg) 8 | Swift func sum1(_ numbers: Int...) 9 | init(format: String, any CVarArg...) 10 | Lua function fwrite (fmt, ...) unpack(arg) 11 | C++ void simple_printf(const char* fmt...) va_list args; va_start(args, fmt); 12 | C double average(int count, ...) va_start(ap, second); 13 | C# public void Foo(int x, params string[] values) 14 | Javascript func(...arr) 15 | Go func sum(nums ...int) 16 | Ruby def variable_args(arg1, *more) 17 | Rust macro; fn foo(args: &[&str]) foo(&["hello", "world", "I", "am", "arguments"]); 18 | Kotlin fun sum(vararg xs: Int) 19 | Scala def printAll(strings: String*): Unit 20 | 21 | 22 | fun println(arg str...) 23 | 24 | 25 | 26 | */ 27 | public class LanguageFunctions { 28 | 29 | } 30 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/stats/QuantileSketchTest.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.stats; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | 5 | import java.util.Arrays; 6 | import java.util.Random; 7 | 8 | import org.junit.Test; 9 | 10 | public class QuantileSketchTest { 11 | 12 | @Test 13 | public void test() { 14 | Random random = new Random(1); 15 | QuantileSketch sketch = new QuantileSketch(random, 1000); 16 | int count = 10_000; 17 | double[] list = new double[count]; 18 | for (int i = 0; i < count; i++) { 19 | double x = random.nextDouble(); 20 | sketch.add(x); 21 | list[i] = x; 22 | } 23 | Arrays.sort(list); 24 | double diff; 25 | for(double d = 0.01; d < 1.0; d += 0.1) { 26 | diff = Math.abs(sketch.quantile(d) - list[(int) (count * d)]); 27 | assertTrue(diff < 0.002); 28 | } 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/macro.bau: -------------------------------------------------------------------------------- 1 | fun exit(code int) 2 | native(``` 3 | #include 4 | exit(code); 5 | ```) 6 | # recursive call causes stack overflow 7 | exit(code) 8 | 9 | fun assert(condition int, message i8[]) macro 10 | if not condition 11 | println(message) 12 | exit(1) 13 | 14 | fun if(cond int, a T, b T) macro T 15 | if cond 16 | return a 17 | else 18 | return b 19 | 20 | fun expensiveCalc(a i8[]) i8[] 21 | println('expensive calculation with param: ' a) 22 | return a 23 | 24 | for i := until(2) 25 | x : if(i, expensiveCalc('not zero'), expensiveCalc('zero')) 26 | println(i ': ' x) 27 | assert(i < 1, 'assertion failed') 28 | println('next') 29 | println('end') 30 | 31 | ## Expected 32 | expensive calculation with param: zero 33 | 0: zero 34 | next 35 | expensive calculation with param: not zero 36 | 1: not zero 37 | assertion failed 38 | Panic: Stack overflow 39 | -------------------------------------------------------------------------------- /src/main/java/org/bau/parser/FullName.java: -------------------------------------------------------------------------------- 1 | package org.bau.parser; 2 | 3 | import java.util.Objects; 4 | 5 | public class FullName { 6 | public String module; 7 | public String name; 8 | public FullName(String module, String name) { 9 | this.module = module; 10 | this.name = name; 11 | } 12 | @Override 13 | public int hashCode() { 14 | return Objects.hash(module, name); 15 | } 16 | @Override 17 | public boolean equals(Object obj) { 18 | if (this == obj) 19 | return true; 20 | if (obj == null) 21 | return false; 22 | if (getClass() != obj.getClass()) 23 | return false; 24 | FullName other = (FullName) obj; 25 | return Objects.equals(module, other.module) && Objects.equals(name, other.name); 26 | } 27 | 28 | public String toString() { 29 | if (module == null) { 30 | return name; 31 | } 32 | return module + "." + name; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/java/org/bau/benchmarks/Munchausen.java: -------------------------------------------------------------------------------- 1 | // https://github.com/jabbalaci/SpeedTests 2 | 3 | package org.bau.benchmarks; 4 | 5 | public class Munchausen { 6 | static int LIMIT = 440_000_000; 7 | static int[] cache = getCache(); 8 | 9 | public static void main(String[] args) { 10 | for (int i = 0; i < LIMIT; ++i) 11 | if (isMunchausen(i)) 12 | System.out.println(i); 13 | } 14 | 15 | static boolean isMunchausen(int number) { 16 | int n = number; 17 | int total = 0; 18 | while (n > 0) { 19 | int digit = n % 10; 20 | total += cache[digit]; 21 | if (total > number) 22 | return false; 23 | n /= 10; 24 | } 25 | return total == number; 26 | } 27 | 28 | static int[] getCache() { 29 | int[] cache = new int[10]; 30 | for (int i = 1; i <= 9; ++i) 31 | cache[i] = (int) Math.pow(i, i); 32 | return cache; 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /src/test/java/org/bau/ena/types/Type.java: -------------------------------------------------------------------------------- 1 | package org.bau.ena.types; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | public sealed interface Type 7 | permits Type.Int, Type.Real, Type.Text, Type.Array, Type.Struct, Type.Fun, Type.Void, Type.Unknown { 8 | record Int() implements Type { 9 | } 10 | 11 | record Real() implements Type { 12 | } 13 | 14 | record Text() implements Type { 15 | } 16 | 17 | record Array(Type elem) implements Type { 18 | } 19 | 20 | record Struct(String name, Map fields) implements Type { 21 | } 22 | 23 | record Fun(List params, Type ret) implements Type { 24 | } 25 | 26 | record Void() implements Type { 27 | } 28 | 29 | record Unknown() implements Type { 30 | } 31 | 32 | static final Int INT = new Int(); 33 | static final Real REAL = new Real(); 34 | static final Text TEXT = new Text(); 35 | static final Void VOID = new Void(); 36 | static final Unknown UNKNOWN = new Unknown(); 37 | } 38 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/math/FastDivide.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.math; 2 | 3 | public class FastDivide { 4 | 5 | private final long multiply; 6 | private final int shift; 7 | 8 | private FastDivide(long multiply, int shift) { 9 | this.multiply = multiply; 10 | this.shift = shift; 11 | } 12 | 13 | public long divide(long x) { 14 | return (x * multiply) >>> shift; 15 | } 16 | 17 | public static FastDivide build(long divisor) { 18 | if (divisor < 0) { 19 | throw new IllegalArgumentException("negative divisor"); 20 | } else if (divisor >= Integer.MAX_VALUE / 2) { 21 | throw new IllegalArgumentException("divisor too large"); 22 | } 23 | int shift = 32 + (64 - Long.numberOfLeadingZeros(divisor - 1)); 24 | long multiply = (1L << shift) / divisor; 25 | 26 | if ((1L << 32) - multiply * divisor <= multiply - 1) { 27 | multiply++; 28 | } 29 | return new FastDivide(multiply, shift); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /doc/playground.md: -------------------------------------------------------------------------------- 1 | # Playground 2 | 3 | The Playground allows to transpile and run Bau programs in the browser. 4 | 5 | ## Run Locally 6 | 7 | To run the playground locally, clone the git repository, 8 | and then open docs/playground.html with a browser. 9 | The browser needs to support Javascript and WASM. 10 | There is no need to install any other software. 11 | 12 | ## Technical Implementation Details 13 | 14 | The playground is a static web app. 15 | All processing (transpilation, compilation, running the generated program) is done in the browser. 16 | The playground can be downloaded and used offline. It consists of: 17 | 18 | * Source code editor: CodeMirror, implemented in JavaScript. For mobile clients, a HTML "textarea" is used. 19 | * Transpiler: TeaVM, ahead-of-time compiler for Java bytecode. JavaScript is used. 20 | * C compiler and runtime: XCC, a very small C compiler. WASM is used here. 21 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/collections/Stack.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.collections; 2 | 3 | public class Stack { 4 | private T[] array; 5 | private int size; 6 | 7 | @SuppressWarnings("unchecked") 8 | public Stack(int capacity) { 9 | array = (T[]) new Object[capacity]; 10 | } 11 | 12 | public boolean isFull() { 13 | return size == array.length; 14 | } 15 | 16 | public boolean isEmpty() { 17 | return size == 0; 18 | } 19 | 20 | public boolean push(T value) { 21 | if (isFull()) { 22 | return false; 23 | } else { 24 | array[size++] = value; 25 | return true; 26 | } 27 | } 28 | 29 | public T pop() { 30 | if (isEmpty()) { 31 | return null; 32 | } else { 33 | return array[--size]; 34 | } 35 | } 36 | 37 | public T peek() { 38 | if (isEmpty()) { 39 | return null; 40 | } else { 41 | return array[size - 1]; 42 | } 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/sort/ShellSort.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.sort; 2 | 3 | import java.util.Comparator; 4 | 5 | /** 6 | * Shell sort. 7 | * 8 | * Not stable. 9 | * Worst case: O(n ^ ~1.34) 10 | * Memory: O(1) 11 | */ 12 | public class ShellSort { 13 | 14 | public static void sort(T[] a, Comparator c) { 15 | sort(a, c, 0, a.length); 16 | } 17 | 18 | public static void sort(T[] a, Comparator c, int from, int to) { 19 | int h = 16, gap = 1; 20 | while (to - from > h / 16) { 21 | h = h + h + h / 4 + 16; 22 | } 23 | do { 24 | h = (h - 16) * 4 / 9; 25 | gap = (int) ((h + 15) / 16); 26 | for (int i = gap + from; i < to; i++) { 27 | T t = a[i]; 28 | int j = i - gap; 29 | for (; j >= from && c.compare(a[j], t) > 0; j -= gap) { 30 | a[j + gap] = a[j]; 31 | } 32 | a[j + gap] = t; 33 | } 34 | } while (gap > 1); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /doc/playground-about.md: -------------------------------------------------------------------------------- 1 | # Playground 2 | 3 | The Playground allows to transpile and run Bau programs in the browser. 4 | 5 | ## Run Locally 6 | 7 | To run the playground locally, clone the git repository, 8 | and then open docs/playground.html with a browser. 9 | The browser needs to support Javascript and WASM. 10 | There is no need to install any other software. 11 | 12 | ## Technical Implementation Details 13 | 14 | The playground is a static web app. 15 | All processing (transpilation, compilation, running the generated program) is done in the browser. 16 | The playground can be downloaded and used offline. It consists of: 17 | 18 | * Source code editor: CodeMirror, implemented in JavaScript. For mobile clients, a HTML "textarea" is used. 19 | * Transpiler: TeaVM, ahead-of-time compiler for Java bytecode. JavaScript is used. 20 | * C compiler and runtime: XCC, a very small C compiler. WASM is used here. 21 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/collections/StackTest.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.collections; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertFalse; 5 | import static org.junit.Assert.assertTrue; 6 | 7 | import org.junit.Test; 8 | 9 | public class StackTest { 10 | 11 | @Test 12 | public void test() { 13 | Stack stack = new Stack<>(5); 14 | assertTrue(stack.push(10)); 15 | assertTrue(stack.push(20)); 16 | assertTrue(stack.push(30)); 17 | assertTrue(stack.push(40)); 18 | assertTrue(stack.push(50)); 19 | assertFalse(stack.push(60)); 20 | assertEquals(50, stack.peek().intValue()); 21 | assertEquals(50, stack.pop().intValue()); 22 | assertEquals(40, stack.pop().intValue()); 23 | assertEquals(30, stack.pop().intValue()); 24 | assertEquals(20, stack.pop().intValue()); 25 | assertEquals(10, stack.pop().intValue()); 26 | assertEquals(null, stack.pop()); 27 | assertEquals(null, stack.peek()); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/resources/org/bau/List.bau: -------------------------------------------------------------------------------- 1 | module org.bau.List 2 | 3 | # List 4 | type List(T) 5 | array T[] 6 | size int 7 | 8 | # Create a new list 9 | fun newList(T type) List(T) 10 | return List(T)(T[4]) 11 | 12 | # Append an entry to the list 13 | fun List(T) add(x T) 14 | if size >= array.len 15 | n : T[array.len * 2] 16 | for i := until(array.len) 17 | n[i] = array[i] 18 | array = n 19 | array[size] = x 20 | size += 1 21 | 22 | # Insert an entry to the list at the given index 23 | fun List(T) add(index int, x T) 24 | if size >= array.len 25 | n : T[array.len * 2] 26 | for i := until(array.len) 27 | n[i] = array[i] 28 | array = n 29 | p := size 30 | while p > index 31 | array[p] = array[p - 1] 32 | p -= 1 33 | array[index] = x 34 | size += 1 35 | 36 | fun List(T) remove(pos int) 37 | while pos < size - 1 38 | array[pos] = array[pos + 1] 39 | pos += 1 40 | array[pos] = null 41 | 42 | fun List(T) get(x int) T? 43 | return array[x] 44 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/math/PrimeSieveTest.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.math; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import java.math.BigInteger; 6 | 7 | import org.junit.Test; 8 | 9 | public class PrimeSieveTest { 10 | 11 | @Test 12 | public void test() { 13 | int largeN = 1_000; 14 | long sum = 0; 15 | PrimeSieve sieve = PrimeSieve.generate((int) Math.sqrt(largeN)); 16 | for (int i = 0; i < largeN; i++) { 17 | if (sieve.isPrime(i)) { 18 | sum += i; 19 | } 20 | } 21 | assertEquals(sumPrimesTo(largeN), sum); 22 | } 23 | 24 | private static long sumPrimesTo(int largeN) { 25 | long sum = 0; 26 | int count = 0; 27 | for (int i = 0; i < largeN; i++) { 28 | if (BigInteger.valueOf(i).isProbablePrime(15)) { 29 | sum += i; 30 | count++; 31 | } 32 | } 33 | System.out.println("count " + count + " sum " + sum + " to " + largeN); 34 | return sum; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/org/bau/parser/Statement.java: -------------------------------------------------------------------------------- 1 | package org.bau.parser; 2 | 3 | import java.util.HashSet; 4 | 5 | import org.bau.runtime.Memory; 6 | 7 | public interface Statement { 8 | 9 | enum StatementResult { 10 | OK, 11 | BREAK, 12 | RETURN, 13 | CONTINUE, 14 | THROW, 15 | PANIC, 16 | TIMEOUT 17 | } 18 | 19 | public static String indent(String s) { 20 | if (s.isEmpty()) { 21 | return s; 22 | } 23 | boolean nl = s.endsWith("\n"); 24 | s = s.trim().replaceAll("\n", "\n "); 25 | if (nl) { 26 | s += "\n"; 27 | } 28 | return " " + s; 29 | } 30 | 31 | Statement replace(Variable old, Expression with); 32 | 33 | StatementResult run(Memory m); 34 | 35 | void optimize(ProgramContext context); 36 | 37 | String toC(); 38 | 39 | default void setBounds(Expression scope) { 40 | 41 | } 42 | 43 | void collectTypes(HashSet set, MemoryType memoryType); 44 | 45 | void used(Program program); 46 | 47 | } 48 | -------------------------------------------------------------------------------- /doc/transpile.md: -------------------------------------------------------------------------------- 1 | # Transpile 2 | 3 | Download and build the latest version: 4 | 5 | git clone git@github.com:thomasmueller/bau-lang.git 6 | cd bau-lang 7 | 8 | Using Maven: 9 | 10 | mvn -DskipTests clean install 11 | 12 | Alternatively, using the Make: 13 | 14 | make jar 15 | 16 | Create a `demo.bau` file, transpile it, compile, and run: 17 | 18 | echo "println('Hello World')" > hello.bau 19 | java -jar target/*.jar hello.bau 20 | gcc -O3 hello.c -o hello 21 | ./hello 22 | 23 | ## C Compiler and Toolchain 24 | 25 | The generated source code is relatively simple and readable C code. 26 | The following features are needed: 27 | 28 | * `goto` is used for `continue` and exception handling 29 | * `varargs` are used for functions with a variable number of arguments. 30 | * Functions that may throw an exception return a struct. 31 | * The standard library is used by default. 32 | 33 | The regular C tools may be used. As an exception, to analyze performance 34 | on Mac OS, use the following command: 35 | 36 | xctrace record --template 'Time Profiler' --launch a.out 37 | -------------------------------------------------------------------------------- /src/test/java/org/bau/TestOperators.java: -------------------------------------------------------------------------------- 1 | package org.bau; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import java.util.Random; 6 | 7 | import org.junit.Test; 8 | 9 | public class TestOperators { 10 | 11 | @Test 12 | public void shiftRight() { 13 | Random r = new Random(1); 14 | for (int test = 0; test < 1000000; test++) { 15 | int i = r.nextInt(); 16 | for (int n = 0; n < 64; n++) { 17 | int c1 = i >> n; 18 | // this would be wrong: int c2 = i / (1 << n); 19 | // see also https://en.wikipedia.org/wiki/Arithmetic_shift 20 | // from https://stackoverflow.com/questions/31879878/how-can-i-perform-arithmetic-right-shift-in-c-in-a-portable-way 21 | int s = -(i >>> 31); 22 | int c2 = ((s ^ i) >> n) ^ s; 23 | assertEquals(c1, c2); 24 | } 25 | } 26 | } 27 | 28 | @Test 29 | public void shift() { 30 | assertEquals(49152, 3L << -50); 31 | assertEquals(0, 3L >>> -50); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/piDigits.py: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import sys 5 | 6 | def main(): 7 | global acc, den, num 8 | n = 10000 9 | if len(sys.argv) > 1: 10 | n = int(sys.argv[1]) 11 | acc, den, num = 0, 1, 1 12 | i, k = 0, 0 13 | while i < n: 14 | k += 1 15 | next_term(k) 16 | if num > acc: 17 | continue 18 | d = extract_digit(3) 19 | if d != extract_digit(4): 20 | continue 21 | eliminate_digit(d) 22 | print(chr(ord('0') + d), end = "") 23 | i += 1 24 | if i % 10 == 0: 25 | print("\t:%d" % i) 26 | 27 | def extract_digit(nth): 28 | return (num * nth + acc) // den 29 | 30 | def eliminate_digit(d): 31 | global acc, den, num 32 | acc -= den * d 33 | acc *= 10 34 | num *= 10 35 | 36 | def next_term(k): 37 | global acc, den, num 38 | k2 = k * 2 + 1 39 | acc += num * 2 40 | acc *= k2 41 | den *= k2 42 | num *= k 43 | 44 | main() 45 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/security/ARC4Test.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.security; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.bau.stdlib.string.HexEncode; 6 | import org.junit.Test; 7 | 8 | public class ARC4Test { 9 | @Test 10 | public void test() { 11 | ARC4 arc4 = new ARC4("Key".getBytes()); 12 | byte[] ciphertext = arc4.encrypt("Plaintext".getBytes()); 13 | assertEquals("bbf316e8d940af0ad3", HexEncode.convertBytesToHex(ciphertext)); 14 | 15 | arc4 = new ARC4("Wiki".getBytes()); 16 | ciphertext = arc4.encrypt("pedia".getBytes()); 17 | assertEquals("1021bf0420", HexEncode.convertBytesToHex(ciphertext)); 18 | 19 | arc4 = new ARC4("Secret".getBytes()); 20 | ciphertext = arc4.encrypt("Attack at dawn".getBytes()); 21 | assertEquals("45a01f645fc35b383552544b9bf5", HexEncode.convertBytesToHex(ciphertext)); 22 | 23 | arc4 = new ARC4("Secret".getBytes()); 24 | assertEquals("Attack at dawn", new String(arc4.encrypt(HexEncode.convertHexToBytes("45a01f645fc35b383552544b9bf5")))); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/python/piDigits.py: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import sys 5 | 6 | def main(): 7 | global acc, den, num 8 | n = 10000 9 | if len(sys.argv) > 1: 10 | n = int(sys.argv[1]) 11 | acc, den, num = 0, 1, 1 12 | i, k = 0, 0 13 | while i < n: 14 | k += 1 15 | next_term(k) 16 | if num > acc: 17 | continue 18 | d = extract_digit(3) 19 | if d != extract_digit(4): 20 | continue 21 | eliminate_digit(d) 22 | print(chr(ord('0') + d), end = "") 23 | i += 1 24 | if i % 10 == 0: 25 | print("\t:%d" % i) 26 | 27 | def extract_digit(nth): 28 | return (num * nth + acc) // den 29 | 30 | def eliminate_digit(d): 31 | global acc, den, num 32 | acc -= den * d 33 | acc *= 10 34 | num *= 10 35 | 36 | def next_term(k): 37 | global acc, den, num 38 | k2 = k * 2 + 1 39 | acc += num * 2 40 | acc *= k2 41 | den *= k2 42 | num *= k 43 | 44 | main() 45 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/traitsSimple.bau: -------------------------------------------------------------------------------- 1 | trait Reader 2 | read() int 3 | 4 | trait Writer : Reader 5 | write(x int) 6 | 7 | type Memory : Reader, Writer 8 | array int[] 9 | pos int 10 | 11 | fun Memory read() int 12 | p : pos 13 | if p < 0 or p >= array.len 14 | return -1 15 | pos += 1 16 | return array[p] 17 | 18 | fun Memory write(x int) 19 | p : pos 20 | if p < 0 or p >= array.len 21 | println('not writing to pos=' p) 22 | return 23 | pos += 1 24 | println('writing to pos=' p) 25 | array[p] = x 26 | 27 | fun get(r Reader) int 28 | println('reading') 29 | return r.read() 30 | 31 | fun put(w Writer, x int) 32 | println('writing') 33 | w.write(x) 34 | 35 | fun main() 36 | println('start') 37 | mem : Memory(int[10]) 38 | r Reader : mem 39 | # r.read() 40 | println('write 10'); 41 | w Writer : mem 42 | put(w, 10) 43 | mem.pos = 0 44 | x : get(mem) 45 | println('read ' x) 46 | 47 | ## Expected 48 | start 49 | write 10 50 | writing 51 | reading 52 | read {array=*2, pos=0} 53 | -------------------------------------------------------------------------------- /src/test/java/org/bau/TestComment.java: -------------------------------------------------------------------------------- 1 | package org.bau; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.bau.parser.Parser; 6 | import org.junit.Test; 7 | 8 | public class TestComment { 9 | 10 | @Test 11 | public void comments() { 12 | assertEquals("a := 1\n" 13 | + "a = 2\n" 14 | + "a = 3\n" 15 | + "a = 4\n" 16 | + "a = 5\n" 17 | + "", 18 | new Parser(""" 19 | a := 1 20 | # commented line 21 | a = 2 22 | ## block comment 1 23 | comment 24 | ## 25 | a = 3 26 | ### block comment 2 27 | ## more 28 | # more 29 | ## more 30 | ### 31 | a = 4 32 | ## short block comment ## a = 5 33 | """).parse().toString()); 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/fibonacci.bau: -------------------------------------------------------------------------------- 1 | ticks := 0 2 | 3 | fun fibonacciRecursive(n int) int 4 | ticks += 1 5 | if n < 2 6 | return n 7 | return fibonacciRecursive(n - 1) + fibonacciRecursive(n - 2) 8 | 9 | fun fibonacciIterative(n int) int 10 | r0 := 0 11 | r1 := 0 12 | r := 1 13 | for i := range(1, n) 14 | r1 = r0 15 | r0 = r 16 | r = r1 + r0 17 | ticks += 1 18 | return r 19 | 20 | fun fibonacciConst(n int) const int 21 | r0 := 0 22 | r1 := 0 23 | r := 1 24 | for i := range(1, n) 25 | r1 = r0 26 | r0 = r 27 | r = r1 + r0 28 | return r 29 | 30 | ticks = 0 31 | println('fibonacci(20) recursive: ' fibonacciRecursive(20) ', ticks: ' ticks) 32 | ticks = 0 33 | println('fibonacci(20) iterative: ' fibonacciIterative(20) ', ticks: ' ticks) 34 | ticks = 0 35 | println('fibonacci(20) const: ' fibonacciConst(20) ', ticks: ' ticks) 36 | 37 | 38 | ## Expected 39 | fibonacci(20) recursive: 6765, ticks: 21891 40 | fibonacci(20) iterative: 6765, ticks: 19 41 | fibonacci(20) const: 6765, ticks: 0 42 | -------------------------------------------------------------------------------- /src/test/java/org/bau/traits/Type.java: -------------------------------------------------------------------------------- 1 | package org.bau.traits; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashSet; 5 | 6 | class Type { 7 | 8 | // name of type 9 | String name; 10 | 11 | // the traits this type implements 12 | ArrayList traits = new ArrayList<>(); 13 | 14 | int totalTraitCount = 0; 15 | 16 | // functions (combinations of all functions of all traits) 17 | ArrayList traitFunctions = new ArrayList<>(); 18 | 19 | public void collectAllNonMarkerTraits(HashSet target) { 20 | for(Trait t : traits) { 21 | t.collectAllNonMarkerTraits(target); 22 | } 23 | } 24 | 25 | public String toString() { 26 | StringBuilder buff = new StringBuilder(); 27 | buff.append("type " + name + " : "); 28 | 29 | int i=0; 30 | for(Trait t : traits) { 31 | if (i++ > 0) { 32 | buff.append(", "); 33 | } 34 | buff.append(t.name + "/" + t.functionList.size()); 35 | } 36 | // buff.append(")"); 37 | return buff.toString(); 38 | } 39 | 40 | } -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/mandelbrotComplex.py: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import sys 5 | 6 | def main(): 7 | cout = sys.stdout.buffer.write 8 | n = int(sys.argv[1]) 9 | xr_size = range(n) 10 | xr_iter = range(50) 11 | bit = 128 12 | byte_acc = 0 13 | cout(("P4\n%d %d\n" % (size, size)).encode('ascii')) 14 | size = float(size) 15 | for y in xr_size: 16 | fy = 2j * y / size - 1j 17 | for x in xr_size: 18 | z = 0j 19 | c = 2. * x / size - 1.5 + fy 20 | for i in xr_iter: 21 | z = z * z + c 22 | if abs(z) >= 2.0: 23 | break 24 | else: 25 | byte_acc += bit 26 | if bit > 1: 27 | bit >>= 1 28 | else: 29 | cout(bytes([byte_acc])) 30 | bit = 128 31 | byte_acc = 0 32 | if bit != 128: 33 | cout(bytes([byte_acc])) 34 | bit = 128 35 | byte_acc = 0 36 | 37 | main() -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/python/mandelbrotComplex.py: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import sys 5 | 6 | def main(): 7 | cout = sys.stdout.buffer.write 8 | n = int(sys.argv[1]) 9 | xr_size = range(n) 10 | xr_iter = range(50) 11 | bit = 128 12 | byte_acc = 0 13 | cout(("P4\n%d %d\n" % (size, size)).encode('ascii')) 14 | size = float(size) 15 | for y in xr_size: 16 | fy = 2j * y / size - 1j 17 | for x in xr_size: 18 | z = 0j 19 | c = 2. * x / size - 1.5 + fy 20 | for i in xr_iter: 21 | z = z * z + c 22 | if abs(z) >= 2.0: 23 | break 24 | else: 25 | byte_acc += bit 26 | if bit > 1: 27 | bit >>= 1 28 | else: 29 | cout(bytes([byte_acc])) 30 | bit = 128 31 | byte_acc = 0 32 | if bit != 128: 33 | cout(bytes([byte_acc])) 34 | bit = 128 35 | byte_acc = 0 36 | 37 | main() -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/sort/BinarySearchTest.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.sort; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import java.util.Arrays; 6 | import java.util.Random; 7 | 8 | import org.junit.Test; 9 | 10 | public class BinarySearchTest { 11 | 12 | @Test 13 | public void random() { 14 | Random random = new Random(1); 15 | for (int i = 0; i < 1_000; i++) { 16 | int size = random.nextInt(50) + 1; 17 | Integer[] arr = new Integer[size]; 18 | arr[0] = random.nextInt(10); 19 | for (int j = 1; j < size; j++) { 20 | arr[j] = arr[j - 1] + random.nextInt(10) + 1; 21 | } 22 | int target; 23 | if (random.nextBoolean()) { 24 | target = arr[random.nextInt(size)]; 25 | } else { 26 | target = random.nextInt(arr[size - 1] + 20); 27 | } 28 | int got = BinarySearch.binarySearch(arr, target); 29 | int expected = Arrays.binarySearch(arr, target, Integer::compare); 30 | assertEquals(expected, got); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/security/ARC4.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.security; 2 | 3 | public class ARC4 { 4 | 5 | private byte[] state = new byte[256]; 6 | private int i = 0, j = 0; 7 | 8 | public ARC4(byte[] key) { 9 | for (int i = 0; i < 256; i++) { 10 | state[i] = (byte) i; 11 | } 12 | for (int i = 0, j = 0; i < 256; i++) { 13 | j = (j + state[i] + key[i % key.length]) & 0xff; 14 | swap(i, j); 15 | } 16 | } 17 | 18 | public byte[] encrypt(byte[] input) { 19 | byte[] output = new byte[input.length]; 20 | for (int k = 0; k < input.length; k++) { 21 | output[k] = (byte) (nextByte() ^ input[k]); 22 | } 23 | return output; 24 | } 25 | 26 | public byte nextByte() { 27 | i = (i + 1) & 0xff; 28 | j = (j + state[i]) & 0xff; 29 | swap(i, j); 30 | int t = (state[i] + state[j]) & 0xff; 31 | return state[t]; 32 | } 33 | 34 | private void swap(int i, int j) { 35 | byte temp = state[i]; 36 | state[i] = state[j]; 37 | state[j] = temp; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/collections/PermutationsTest.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.collections; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import org.junit.Test; 6 | 7 | public class PermutationsTest { 8 | 9 | @Test 10 | public void permutations() { 11 | int len = 3; 12 | Character[] input = new Character[len]; 13 | for(int i=0; i perm = new Permutations<>(input, output); 24 | StringBuffer buff = new StringBuffer(); 25 | while(perm.next()) { 26 | for(int i=0; i 1 9 | n = Math.parseInt(Env.arg(1)) 10 | k, i := 0 11 | buff : i8[10] 12 | while i < n 13 | k += 1 14 | nextTerm(k) 15 | continue num.compare(acc) > 0 16 | d : extractDigit(3) 17 | continue d <> extractDigit(4) 18 | eliminateDigit(d) 19 | buff[i % 10] = ord('0') + d 20 | i += 1 21 | if i % 10 = 0 22 | println(buff ' : ' i) 23 | 24 | acc bigInt := 0 25 | den, num bigInt := 1 26 | 27 | fun extractDigit(nth int) int 28 | return num.mul(nth).add(acc).div(den).toInt() 29 | 30 | fun eliminateDigit(d int) 31 | acc = acc.sub(den.mul(d)) 32 | acc = acc.mul(10) 33 | num = num.mul(10) 34 | 35 | fun nextTerm(k int) 36 | acc = acc.add(num.shiftLeft(1)) 37 | acc = acc.mul(k * 2 + 1) 38 | den = den.mul(k * 2 + 1) 39 | num = num.mul(k) 40 | 41 | ## Expected 42 | 3141592653 : 10 43 | 5897932384 : 20 44 | 6264338327 : 30 45 | 9502884197 : 40 46 | 1693993751 : 50 47 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/piDigits.bau: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import org.bau.BigInt 5 | bigInt 6 | import org.bau.Math 7 | import org.bau.Env 8 | 9 | fun main() 10 | n := 10_000 11 | if Env.argCount() > 1 12 | n = Math.parseInt(Env.arg(1)) 13 | k, i := 0 14 | buff : i8[10] 15 | while i < n 16 | k += 1 17 | nextTerm(k) 18 | continue num.compare(acc) > 0 19 | d : extractDigit(3) 20 | continue d <> extractDigit(4) 21 | eliminateDigit(d) 22 | buff[i % 10] = ord('0') + d 23 | i += 1 24 | if i % 10 = 0 25 | println(buff ' : ' i) 26 | 27 | acc bigInt := 0 28 | den, num bigInt := 1 29 | 30 | fun extractDigit(nth int) int 31 | return num.mul(nth).add(acc).div(den).toInt() 32 | 33 | fun eliminateDigit(d int) 34 | acc = acc.sub(den.mul(d)) 35 | acc = acc.mul(10) 36 | num = num.mul(10) 37 | 38 | fun nextTerm(k int) 39 | acc = acc.add(num.shiftLeft(1)) 40 | acc = acc.mul(k * 2 + 1) 41 | den = den.mul(k * 2 + 1) 42 | num = num.mul(k) 43 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/bau/piDigits.bau: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import org.bau.BigInt 5 | bigInt 6 | import org.bau.Math 7 | import org.bau.Env 8 | 9 | fun main() 10 | n := 10_000 11 | if Env.argCount() > 1 12 | n = Math.parseInt(Env.arg(1)) 13 | k, i := 0 14 | buff : i8[10] 15 | while i < n 16 | k += 1 17 | nextTerm(k) 18 | continue num.compare(acc) > 0 19 | d : extractDigit(3) 20 | continue d <> extractDigit(4) 21 | eliminateDigit(d) 22 | buff[i % 10] = ord('0') + d 23 | i += 1 24 | if i % 10 = 0 25 | println(buff ' : ' i) 26 | 27 | acc bigInt := 0 28 | den, num bigInt := 1 29 | 30 | fun extractDigit(nth int) int 31 | return num.mul(nth).add(acc).div(den).toInt() 32 | 33 | fun eliminateDigit(d int) 34 | acc = acc.sub(den.mul(d)) 35 | acc = acc.mul(10) 36 | num = num.mul(10) 37 | 38 | fun nextTerm(k int) 39 | acc = acc.add(num.shiftLeft(1)) 40 | acc = acc.mul(k * 2 + 1) 41 | den = den.mul(k * 2 + 1) 42 | num = num.mul(k) 43 | -------------------------------------------------------------------------------- /src/test/java/org/bau/TestFor.java: -------------------------------------------------------------------------------- 1 | package org.bau; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.fail; 5 | 6 | import org.bau.parser.Parser; 7 | import org.junit.Test; 8 | 9 | public class TestFor { 10 | 11 | @Test 12 | public void breakOutsideOfLoop() { 13 | try { 14 | new Parser(""" 15 | fun test() 16 | a := 1 17 | break 18 | test() 19 | """).parse(); 20 | fail(); 21 | } catch (IllegalStateException e) { 22 | assertEquals("'break' statement outside of a loop at line 3:\n" 23 | + " break\n" 24 | + " ^", e.getMessage()); 25 | } 26 | } 27 | 28 | @Test 29 | public void forLoop() { 30 | assertEquals(""" 31 | while 1 = 1 32 | a := 0 33 | while a < 10 34 | println(a) 35 | a += 1 36 | break 37 | """, 38 | new Parser(""" 39 | fun range(from int, to int) int 40 | _ := from 41 | while _ < to 42 | return _ 43 | _ += 1 44 | for a := range(0, 10) 45 | println(a) 46 | """).parse().toString()); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/org/bau/parser/SpecialOperation.java: -------------------------------------------------------------------------------- 1 | package org.bau.parser; 2 | 3 | import java.util.HashSet; 4 | 5 | import org.bau.runtime.Memory; 6 | 7 | public class SpecialOperation implements Statement { 8 | 9 | private final SpecialOperationType type; 10 | 11 | SpecialOperation(SpecialOperationType type) { 12 | this.type = type; 13 | } 14 | 15 | @Override 16 | public Statement replace(Variable old, Expression with) { 17 | return this; 18 | } 19 | 20 | @Override 21 | public StatementResult run(Memory m) { 22 | return StatementResult.OK; 23 | } 24 | 25 | @Override 26 | public void optimize(ProgramContext context) { 27 | } 28 | 29 | @Override 30 | public String toC() { 31 | if (type == SpecialOperationType.ZERO_COUNT_TABLE_GC) { 32 | return "_zeroCountTableGC();\n"; 33 | } 34 | throw new IllegalStateException(); 35 | } 36 | 37 | public enum SpecialOperationType { 38 | ZERO_COUNT_TABLE_GC 39 | } 40 | 41 | @Override 42 | public void collectTypes(HashSet set, MemoryType memoryType) { 43 | // nothing 44 | } 45 | 46 | @Override 47 | public void used(Program program) { 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/nullPreventNullAccess.bau: -------------------------------------------------------------------------------- 1 | type Value 2 | data int 3 | 4 | fun get(key int) Value? 5 | if key <= 0 6 | return null 7 | result : Value() 8 | result.data = key * 10 9 | return result 10 | 11 | fun testIf() 12 | println('testIf') 13 | for i := until(3) 14 | a : get(i) 15 | if a 16 | println(' get(' i ') = ' a.data) 17 | else 18 | println(' get(' i ') = null') 19 | 20 | fun testReturn() 21 | println('testReturn') 22 | for i := until(3) 23 | a : get(i) 24 | if not a 25 | return 26 | println(' get(' i ') = ' a.data) 27 | 28 | fun testContinue() 29 | println('testContinue') 30 | for i := until(3) 31 | a : get(i) 32 | continue not a 33 | println(' get(' i ') = ' a.data) 34 | 35 | fun testBreak() 36 | println('testBreak') 37 | for i := until(3) 38 | a : get(i) 39 | break not a 40 | println(' get(' i ') = ' a.data) 41 | 42 | testIf() 43 | testReturn() 44 | testContinue() 45 | testBreak() 46 | 47 | ## Expected 48 | testIf 49 | get(0) = null 50 | get(1) = 10 51 | get(2) = 20 52 | testReturn 53 | testContinue 54 | get(1) = 10 55 | get(2) = 20 56 | testBreak 57 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/zig/munchausen.zig: -------------------------------------------------------------------------------- 1 | // https://github.com/jabbalaci/SpeedTests 2 | 3 | const std = @import("std"); 4 | 5 | const LIMIT: u64 = 440_000_000; 6 | 7 | pub fn main() !void { 8 | var stdout = std.fs.File.stdout().writerStreaming(&.{}); 9 | const cache = getCache(); 10 | var i: u64 = 0; 11 | while (i < LIMIT) : (i += 1) { 12 | if (isMunchausen(i, &cache)) { 13 | try stdout.interface.print("{}\n", .{i}); 14 | } 15 | } 16 | } 17 | 18 | fn isMunchausen(number: u64, cache: *const [10]u64) bool { 19 | var n = number; 20 | var total: u64 = 0; 21 | while (n > 0) { 22 | const digit = n % 10; 23 | total += cache[digit]; 24 | if (total > number) { 25 | return false; 26 | } 27 | n /= 10; 28 | } 29 | return total == number; 30 | } 31 | 32 | fn getCache() [10]u64 { 33 | var result: [10]u64 = [_]u64{0} ** 10; 34 | var i: u64 = 1; 35 | while (i <= 9) : (i += 1) { 36 | result[i] = powInt(i, i); 37 | } 38 | 39 | return result; 40 | } 41 | 42 | fn powInt(base: u64, exp: u64) u64 { 43 | var result: u64 = 1; 44 | var e = exp; 45 | while (e > 0) : (e -= 1) { 46 | result *= base; 47 | } 48 | return result; 49 | } 50 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/util/HashTest.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.util; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | import static org.junit.Assert.assertTrue; 5 | 6 | import java.util.Random; 7 | 8 | import org.junit.Test; 9 | 10 | public class HashTest { 11 | 12 | @Test 13 | public void hash() { 14 | assertEquals(0, Hash.hash(0)); 15 | assertTrue(1 != Hash.hash(1)); 16 | } 17 | 18 | @Test 19 | public void hashBytes() { 20 | assertEquals(0, Hash.hashCode(new byte[0])); 21 | assertEquals(-5509026399873832431L, Hash.hashCode(new byte[100])); 22 | assertEquals(-4519909738722218942L, Hash.hashCode(new byte[200])); 23 | } 24 | 25 | @Test 26 | public void reduce() { 27 | Random r = new Random(0); 28 | for (int i = 0; i < 1_000_000; i++) { 29 | long x = r.nextLong(); 30 | int max = r.nextInt(10_000); 31 | int got = Hash.reduce(x, max); 32 | if (max == 0) { 33 | assertEquals(0, got); 34 | } else { 35 | assertTrue(got >= 0 && got < max); 36 | assertEquals(0, Hash.reduce(0, max)); 37 | assertEquals(max - 1, Hash.reduce(-1, max)); 38 | } 39 | } 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/munchausen.zig: -------------------------------------------------------------------------------- 1 | // https://github.com/jabbalaci/SpeedTests 2 | 3 | const std = @import("std"); 4 | 5 | const LIMIT: u64 = 440_000_000; 6 | 7 | pub fn main() !void { 8 | var stdout = std.fs.File.stdout().writerStreaming(&.{}); 9 | const cache = getCache(); 10 | var i: u64 = 0; 11 | while (i < LIMIT) : (i += 1) { 12 | if (isMunchausen(i, &cache)) { 13 | try stdout.interface.print("{}\n", .{i}); 14 | } 15 | } 16 | } 17 | 18 | fn isMunchausen(number: u64, cache: *const [10]u64) bool { 19 | var n = number; 20 | var total: u64 = 0; 21 | 22 | while (n > 0) { 23 | const digit = n % 10; 24 | total += cache[digit]; 25 | if (total > number) { 26 | return false; 27 | } 28 | n /= 10; 29 | } 30 | 31 | return total == number; 32 | } 33 | 34 | fn getCache() [10]u64 { 35 | var result: [10]u64 = [_]u64{0} ** 10; 36 | 37 | var i: u64 = 1; 38 | while (i <= 9) : (i += 1) { 39 | result[i] = powInt(i, i); 40 | } 41 | 42 | return result; 43 | } 44 | 45 | fn powInt(base: u64, exp: u64) u64 { 46 | var result: u64 = 1; 47 | var e = exp; 48 | while (e > 0) : (e -= 1) { 49 | result *= base; 50 | } 51 | return result; 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/org/bau/parser/NativeCode.java: -------------------------------------------------------------------------------- 1 | package org.bau.parser; 2 | 3 | import java.util.HashSet; 4 | 5 | import org.bau.runtime.Memory; 6 | 7 | public class NativeCode implements Statement { 8 | 9 | private final String nativeCode; 10 | 11 | NativeCode(String nativeCode) { 12 | this.nativeCode = nativeCode; 13 | } 14 | 15 | @Override 16 | public Statement replace(Variable old, Expression with) { 17 | return this; 18 | } 19 | 20 | @Override 21 | public StatementResult run(Memory m) { 22 | // m.print(new Value.ValueI8Array("native ".getBytes(StandardCharsets.UTF_8))); 23 | // m.print(new Value.ValueI8Array(nativeCode.getBytes(StandardCharsets.UTF_8))); 24 | // m.println(); 25 | return StatementResult.OK; 26 | } 27 | 28 | @Override 29 | public void collectTypes(HashSet set, MemoryType memoryType) { 30 | // nothing 31 | } 32 | 33 | public void optimize(ProgramContext context) { 34 | } 35 | 36 | @Override 37 | public String toC() { 38 | return nativeCode; 39 | } 40 | 41 | public String toString() { 42 | return "native(" + StringLiteral.escape(nativeCode) + ")"; 43 | } 44 | 45 | @Override 46 | public void used(Program program) { 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/sort.bau: -------------------------------------------------------------------------------- 1 | import org.bau.Utils 2 | 3 | fun shellSort(a T[]) 4 | h := 16 5 | while a.len > h / 16 6 | h = h + h + h / 4 + 16 7 | while h > 15 8 | h = (h - 16) / 9 * 4 9 | g : (h + 15) / 16 10 | for i := range(g, a.len) 11 | t : a[i] 12 | j := i - g 13 | while j >= 0 and a[j] > t 14 | a[j + g] = a[j] 15 | j -= g 16 | a[j + g] = t 17 | 18 | fun insertionSort(a T[]) 19 | for i := range(1, a.len) 20 | t := a[i] 21 | j := i - 1 22 | while j >= 0 and a[j] > t 23 | a[j + 1] = a[j] 24 | j -= 1 25 | a[j + 1] = t 26 | 27 | fun test() 28 | x : int[5] 29 | for i := until(x.len) 30 | x[i] = Utils.random() 31 | insertionSort(x) 32 | for i := until(x.len) 33 | println(x[i]) 34 | for i := until(x.len) 35 | x[i] = Utils.random() 36 | shellSort(x) 37 | for i := until(x.len) 38 | println(x[i]) 39 | 40 | test() 41 | 42 | ## Expected 43 | -2152535657050944081 44 | -537132696929009172 45 | 487617019471545679 46 | 1961750202426094747 47 | 7960286522194355700 48 | -4214222208109204676 49 | -884877559730491226 50 | 3207296026000306913 51 | 4532161160992623299 52 | 6038094601263162090 53 | -------------------------------------------------------------------------------- /config/bau/language-configuration.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": { 3 | "lineComment": "#", 4 | "blockComment": ["##\n", "##"] 5 | }, 6 | "brackets": [ 7 | ["[", "]"], 8 | ["(", ")"] 9 | ], 10 | "autoClosingPairs": [ 11 | { "open": "[", "close": "]" }, 12 | { "open": "(", "close": ")" }, 13 | { "open": "'", "close": "'", "notIn": ["string", "comment"] }, 14 | { "open": "`", "close": "`", "notIn": ["string", "comment"] } 15 | ], 16 | "autoCloseBefore": ".,<>!=]) \n", 17 | "surroundingPairs": [ 18 | ["[", "]"], 19 | ["(", ")"], 20 | ["'", "'"] 21 | ], 22 | "folding": { 23 | "markers": { 24 | "start": "^\\s*//\\s*#?region\\b", 25 | "end": "^\\s*//\\s*#?endregion\\b" 26 | } 27 | }, 28 | "wordPattern": "(-?\\d*\\.\\d\\w*)|([^\\`\\~\\!\\@\\#\\%\\^\\&\\*\\(\\)\\-\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\'\\\"\\,\\.\\<\\>\\/\\?\\s]+)", 29 | "onEnterRules": [ 30 | { 31 | "beforeText": "^\\s*(?:if|elif|else|for|while|case|catch|fun|type|enum|import|and|or|not|\\.|\\(|\\,).*?\\s*$", 32 | "action": { "indent": "indent" } 33 | }, 34 | { 35 | "beforeText": "^\\s*(?:return|throw).*?\\s*$", 36 | "action": { "indent": "outdent" } 37 | }, 38 | { 39 | "beforeText": "^\\s*(?:break|continue)\\s*$", 40 | "action": { "indent": "outdent" } 41 | } 42 | ] 43 | } 44 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/mandelbrot.bau: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import org.bau.Env 5 | import org.bau.File 6 | import org.bau.Math 7 | 8 | fun main() 9 | n := 200 10 | if Env.argCount() > 1 11 | n = Math.parseInt(Env.arg(1)) 12 | w, h := n 13 | iter: 50 14 | limit: 2.0 15 | bitNum := 0 16 | byteAcc := i8(0) 17 | println('P4\n' w ' ' h) 18 | for y := until(h) 19 | for x := until(w) 20 | Zr, Zi, Tr, Ti := 0.0 21 | Cr := 2.0 * x / w - 1.5 22 | Ci := 2.0 * y / h - 1.0 23 | for i := until(iter) 24 | break Tr + Ti > limit * limit 25 | Zi = 2.0 * Zr * Zi + Ci 26 | Zr = Tr - Ti + Cr 27 | Tr = Zr * Zr 28 | Ti = Zi * Zi 29 | byteAcc <<= 1 30 | if Tr + Ti <= limit * limit 31 | byteAcc |= 0x01 32 | bitNum += 1 33 | if bitNum = 8 34 | File.putchar(byteAcc) 35 | byteAcc = 0 36 | bitNum = 0 37 | elif x = w - 1 38 | byteAcc <<= 8 - (w % 8) 39 | File.putchar(byteAcc) 40 | byteAcc = 0 41 | bitNum = 0 42 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/bau/mandelbrot.bau: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import org.bau.Env 5 | import org.bau.File 6 | import org.bau.Math 7 | 8 | fun main() 9 | n := 200 10 | if Env.argCount() > 1 11 | n = Math.parseInt(Env.arg(1)) 12 | w, h := n 13 | iter: 50 14 | limit: 2.0 15 | bitNum := 0 16 | byteAcc := i8(0) 17 | println('P4\n' w ' ' h) 18 | for y := until(h) 19 | for x := until(w) 20 | Zr, Zi, Tr, Ti := 0.0 21 | Cr := 2.0 * x / w - 1.5 22 | Ci := 2.0 * y / h - 1.0 23 | for i := until(iter) 24 | break Tr + Ti > limit * limit 25 | Zi = 2.0 * Zr * Zi + Ci 26 | Zr = Tr - Ti + Cr 27 | Tr = Zr * Zr 28 | Ti = Zi * Zi 29 | byteAcc <<= 1 30 | if Tr + Ti <= limit * limit 31 | byteAcc |= 0x01 32 | bitNum += 1 33 | if bitNum = 8 34 | File.putchar(byteAcc) 35 | byteAcc = 0 36 | bitNum = 0 37 | elif x = w - 1 38 | byteAcc <<= 8 - (w % 8) 39 | File.putchar(byteAcc) 40 | byteAcc = 0 41 | bitNum = 0 42 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/math/PrimeSieve.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.math; 2 | 3 | import org.bau.stdlib.collections.BitField; 4 | 5 | public class PrimeSieve { 6 | 7 | private final int limit; 8 | private final BitField notPrime; 9 | 10 | private PrimeSieve(int limit, BitField notPrime) { 11 | this.limit = limit; 12 | this.notPrime = notPrime; 13 | } 14 | 15 | static PrimeSieve generate(int limit) { 16 | BitField notPrime = new BitField(limit >>> 1); 17 | for (int p = 3; p * p <= limit; p += 2) { 18 | if (!notPrime.get(p >>> 1)) { 19 | for (int i = p * p; i <= limit; i += p + p) { 20 | notPrime.set(i >>> 1); 21 | } 22 | } 23 | } 24 | return new PrimeSieve(limit, notPrime); 25 | } 26 | 27 | public boolean isPrime(long n) { 28 | if (n <= 3) { 29 | return n >= 2; 30 | } 31 | if (n % 2 == 0 || n % 3 == 0) { 32 | return false; 33 | } 34 | if (n < limit) { 35 | return !notPrime.get((int) (n >>> 1)); 36 | } 37 | for (long f = 5; f * f <= n; f += 6) { 38 | if ((n % f) == 0 || (n % (f + 2)) == 0) { 39 | return false; 40 | } 41 | } 42 | return true; 43 | } 44 | 45 | } -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/ena/binaryTrees.ena: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | type Node(left Node, right Node) 5 | 6 | fun nodeCount(n Node) int 7 | res: 1 8 | if n.left <> 0 9 | res +: nodeCount(n.left) 10 | if n.right <> 0 11 | res +: nodeCount(n.right) 12 | ret res 13 | 14 | fun buildTree(depth int) Node 15 | if depth = 0 16 | ret Node(0, 0) 17 | ret Node(buildTree(depth - 1), buildTree(depth - 1)) 18 | 19 | fun count(depth int) int 20 | ret nodeCount(buildTree(depth)) 21 | 22 | fun stretch(depth int) 23 | println('stretch tree of depth ', depth, ' check: ', count(depth)) 24 | 25 | fun main() 26 | n: 3 27 | minDepth: 4 28 | maxDepth: n 29 | if minDepth + 2 > n 30 | maxDepth: minDepth + 2 31 | stretchDepth: maxDepth + 1 32 | stretch(stretchDepth) 33 | longLived: buildTree(maxDepth) 34 | depth: minDepth 35 | loop depth <= maxDepth 36 | iterations: 1 << (maxDepth - depth + minDepth) 37 | sum: 0 38 | for i < iterations 39 | sum +: count(depth) 40 | println(iterations, ' trees of depth ', depth, ' check: ', sum) 41 | depth +: 2 42 | println('long lived tree of depth ', maxDepth, ' check: ', nodeCount(longLived)) 43 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/mini/binaryTrees.mini: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | type Node(left Node, right Node) 5 | 6 | fun nodeCount(n Node) int 7 | res: 1 8 | if n.left <> 0 9 | res +: nodeCount(n.left) 10 | if n.right <> 0 11 | res +: nodeCount(n.right) 12 | ret res 13 | 14 | fun buildTree(depth int) Node 15 | if depth = 0 16 | ret Node(0, 0) 17 | ret Node(buildTree(depth - 1), buildTree(depth - 1)) 18 | 19 | fun count(depth int) int 20 | ret nodeCount(buildTree(depth)) 21 | 22 | fun stretch(depth int) 23 | println('stretch tree of depth ', depth, ' check: ', count(depth)) 24 | 25 | fun main() 26 | n: 3 27 | minDepth: 4 28 | maxDepth: n 29 | if minDepth + 2 > n 30 | maxDepth: minDepth + 2 31 | stretchDepth: maxDepth + 1 32 | stretch(stretchDepth) 33 | longLived: buildTree(maxDepth) 34 | depth: minDepth 35 | loop depth <= maxDepth 36 | iterations: 1 << (maxDepth - depth + minDepth) 37 | sum: 0 38 | for i < iterations 39 | sum +: count(depth) 40 | println(iterations, ' trees of depth ', depth, ' check: ', sum) 41 | depth +: 2 42 | println('long lived tree of depth ', maxDepth, ' check: ', nodeCount(longLived)) 43 | -------------------------------------------------------------------------------- /src/test/java/org/bau/TestConverter.java: -------------------------------------------------------------------------------- 1 | package org.bau; 2 | 3 | import java.io.IOException; 4 | import java.io.InputStream; 5 | import java.io.InputStreamReader; 6 | import java.io.LineNumberReader; 7 | import java.io.RandomAccessFile; 8 | import java.nio.charset.StandardCharsets; 9 | 10 | import org.bau.parser.Parser; 11 | import org.bau.parser.Program; 12 | import org.junit.Test; 13 | 14 | public class TestConverter { 15 | 16 | @Test 17 | public void demo() throws IOException { 18 | InputStream in = getClass().getResourceAsStream("demo.bau"); 19 | LineNumberReader r = new LineNumberReader(new InputStreamReader(in, StandardCharsets.UTF_8)); 20 | StringBuilder buff = new StringBuilder(); 21 | while (true) { 22 | String line = r.readLine(); 23 | if (line == null) { 24 | break; 25 | } 26 | buff.append(line).append("\n"); 27 | } 28 | String source = buff.toString(); 29 | Program p = new Parser(source).parse(); 30 | RandomAccessFile f = new RandomAccessFile("demo.c", "rw"); 31 | String c = p.toC(); 32 | byte[] data = c.getBytes(StandardCharsets.UTF_8); 33 | f.write(data); 34 | f.setLength(data.length); 35 | f.close(); 36 | // gcc -O3 demo.c; ./a.out 37 | 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/binaryTreesRefCount.bau: -------------------------------------------------------------------------------- 1 | import org.bau.Math 2 | import org.bau.Env 3 | 4 | fun main() 5 | minDepth : 4 6 | maxDepth := 10 7 | if Env.argCount() > 1 8 | maxDepth = Math.parseInt(Env.arg(1)) 9 | stretchDepth : maxDepth + 1 10 | stretch(stretchDepth) 11 | longLived : buildTree(maxDepth) 12 | depth := minDepth 13 | while depth <= maxDepth 14 | iterations := 1 << (maxDepth - depth + minDepth) 15 | sum := 0; 16 | for i := until(iterations) 17 | sum += count(depth) 18 | println(iterations '\t trees of depth ' depth '\t check: ' sum) 19 | depth += 2 20 | println('long lived tree of depth ' maxDepth '\t check: ' longLived.nodeCount()) 21 | 22 | fun stretch(depth int) 23 | println('stretch tree of depth ' depth '\t check: ' count(depth)) 24 | 25 | fun count(depth int) int 26 | return buildTree(depth).nodeCount() 27 | 28 | type Tree 29 | left Tree? 30 | right Tree? 31 | 32 | fun buildTree(depth int) Tree 33 | if depth = 0 34 | return Tree(null, null) 35 | return Tree(buildTree(depth - 1), buildTree(depth - 1)) 36 | 37 | fun Tree nodeCount() int 38 | result := 1 39 | l : left 40 | if l 41 | result += l.nodeCount() 42 | r : right 43 | if r 44 | result += r.nodeCount() 45 | return result 46 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/bau/binaryTreesRefCount.bau: -------------------------------------------------------------------------------- 1 | import org.bau.Math 2 | import org.bau.Env 3 | 4 | fun main() 5 | minDepth : 4 6 | maxDepth := 10 7 | if Env.argCount() > 1 8 | maxDepth = Math.parseInt(Env.arg(1)) 9 | stretchDepth : maxDepth + 1 10 | stretch(stretchDepth) 11 | longLived : buildTree(maxDepth) 12 | depth := minDepth 13 | while depth <= maxDepth 14 | iterations := 1 << (maxDepth - depth + minDepth) 15 | sum := 0; 16 | for i := until(iterations) 17 | sum += count(depth) 18 | println(iterations '\t trees of depth ' depth '\t check: ' sum) 19 | depth += 2 20 | println('long lived tree of depth ' maxDepth '\t check: ' longLived.nodeCount()) 21 | 22 | fun stretch(depth int) 23 | println('stretch tree of depth ' depth '\t check: ' count(depth)) 24 | 25 | fun count(depth int) int 26 | return buildTree(depth).nodeCount() 27 | 28 | type Tree 29 | left Tree? 30 | right Tree? 31 | 32 | fun buildTree(depth int) Tree 33 | if depth = 0 34 | return Tree(null, null) 35 | return Tree(buildTree(depth - 1), buildTree(depth - 1)) 36 | 37 | fun Tree nodeCount() int 38 | result := 1 39 | l : left 40 | if l 41 | result += l.nodeCount() 42 | r : right 43 | if r 44 | result += r.nodeCount() 45 | return result 46 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/cache/HitRateCacheWrapper.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.cache; 2 | 3 | import java.util.concurrent.atomic.LongAdder; 4 | 5 | public class HitRateCacheWrapper { 6 | 7 | private final Cache base; 8 | private final LongAdder misses = new LongAdder(); 9 | private final LongAdder hits = new LongAdder(); 10 | private final LongAdder gets = new LongAdder(); 11 | 12 | HitRateCacheWrapper(Cache base) { 13 | this.base = base; 14 | } 15 | 16 | public Long get(Integer key) { 17 | gets.increment(); 18 | Long result; 19 | result = base.get(key); 20 | if (result == null) { 21 | result = key * 10L; 22 | base.put(key, result); 23 | misses.increment(); 24 | } else { 25 | hits.increment(); 26 | } 27 | return result; 28 | } 29 | 30 | public void put(Integer key, Long value) { 31 | base.put(key, value); 32 | } 33 | 34 | @Override 35 | public String toString() { 36 | String result = "hits: " + hits + " misses: " + misses + " gets: " + gets + " " + base.toString(); 37 | if (gets.longValue() == 0) { 38 | return "0% hit rate: " + result; 39 | } 40 | return (100 * hits.longValue() / gets.longValue()) + "% hit rate: " + result; 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/piDigits.nim: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import std/[os, strutils, options] 5 | import bigints 6 | 7 | var 8 | acc = 0.initBigInt 9 | den = 1.initBigInt 10 | num = 1.initBigInt 11 | ten = 10.initBigInt 12 | 13 | proc extractDigit(nth: int): int = 14 | let n = (num * nth.initBigInt + acc) div den 15 | result = toInt[int](n).get() 16 | 17 | proc eliminateDigit(d: int) = 18 | acc -= den * d.initBigInt 19 | acc *= ten 20 | num *= ten 21 | 22 | proc nextTerm(k: int) = 23 | let k2 = initBigInt(k * 2 + 1) 24 | acc += num.shl(1) 25 | acc *= k2 26 | den *= k2 27 | num *= k.initBigInt 28 | 29 | proc main() = 30 | var n = 10000 31 | let args = commandLineParams() 32 | if args.len > 0: 33 | n = parseInt(args[0]) 34 | var i = 0 35 | var k = 0 36 | while i < n: 37 | inc k 38 | nextTerm(k) 39 | if num > acc: 40 | continue 41 | let d = extractDigit(3) 42 | if d != extractDigit(4): 43 | continue 44 | eliminateDigit(d) 45 | stdout.write(chr(ord('0') + d)) 46 | inc i 47 | if i mod 10 == 0: 48 | stdout.write("\t:", $i, "\n") 49 | stdout.write("\n") 50 | 51 | when isMainModule: 52 | main() 53 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/security/ChaCha12Test.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.security; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | 5 | import java.util.Arrays; 6 | 7 | import org.bau.stdlib.string.HexEncode; 8 | import org.junit.Test; 9 | 10 | public class ChaCha12Test { 11 | 12 | @Test 13 | public void test() { 14 | byte[] key = HexEncode.convertHexToBytes("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); 15 | byte[] nonce = HexEncode.convertHexToBytes("000000000000004a00000000"); 16 | String plain = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it."; 17 | byte[] test = HexEncode.convertHexToBytes("8d47e256f00475f2661d4fbf7f2a1137" 18 | + "b63f066215d22dccbfc52e4fbe1701fc" 19 | + "f8885f7a1a39b63f797754d801111d3c" 20 | + "0d5f0c9012717425ddf867ef5f1ab14d" 21 | + "7f01852a87965ee3d8727d8c7f09d5bf" 22 | + "68a8fa8dc0cac74e88cf26b1729099d7" 23 | + "37b4ecabba683522483ff77e62b65e39" 24 | + "ca58"); 25 | ChaCha12 cha = new ChaCha12(key, nonce); 26 | byte[] result = cha.encrypt(plain.getBytes()); 27 | System.out.println(HexEncode.convertBytesToHex(result)); 28 | assertTrue(Arrays.equals(test, result)); 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/nim/piDigits.nim: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import std/[os, strutils, options] 5 | import bigints 6 | 7 | var 8 | acc = 0.initBigInt 9 | den = 1.initBigInt 10 | num = 1.initBigInt 11 | ten = 10.initBigInt 12 | 13 | proc extractDigit(nth: int): int = 14 | let n = (num * nth.initBigInt + acc) div den 15 | result = toInt[int](n).get() 16 | 17 | proc eliminateDigit(d: int) = 18 | acc -= den * d.initBigInt 19 | acc *= ten 20 | num *= ten 21 | 22 | proc nextTerm(k: int) = 23 | let k2 = initBigInt(k * 2 + 1) 24 | acc += num.shl(1) 25 | acc *= k2 26 | den *= k2 27 | num *= k.initBigInt 28 | 29 | proc main() = 30 | var n = 10000 31 | let args = commandLineParams() 32 | if args.len > 0: 33 | n = parseInt(args[0]) 34 | var i = 0 35 | var k = 0 36 | while i < n: 37 | inc k 38 | nextTerm(k) 39 | if num > acc: 40 | continue 41 | let d = extractDigit(3) 42 | if d != extractDigit(4): 43 | continue 44 | eliminateDigit(d) 45 | stdout.write(chr(ord('0') + d)) 46 | inc i 47 | if i mod 10 == 0: 48 | stdout.write("\t:", $i, "\n") 49 | stdout.write("\n") 50 | 51 | when isMainModule: 52 | main() 53 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/security/ChaCha20Test.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.security; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | 5 | import java.util.Arrays; 6 | 7 | import org.bau.stdlib.string.HexEncode; 8 | import org.junit.Test; 9 | 10 | public class ChaCha20Test { 11 | 12 | @Test 13 | public void test() { 14 | // https://datatracker.ietf.org/doc/html/rfc7539 15 | byte[] key = HexEncode.convertHexToBytes("000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"); 16 | byte[] nonce = HexEncode.convertHexToBytes("000000000000004a00000000"); 17 | String plain = "Ladies and Gentlemen of the class of '99: If I could offer you only one tip for the future, sunscreen would be it."; 18 | byte[] test = HexEncode.convertHexToBytes("6e2e359a2568f98041ba0728dd0d6981" 19 | + "e97e7aec1d4360c20a27afccfd9fae0b" 20 | + "f91b65c5524733ab8f593dabcd62b357" 21 | + "1639d624e65152ab8f530c359f0861d8" 22 | + "07ca0dbf500d6a6156a38e088a22b65e" 23 | + "52bc514d16ccf806818ce91ab7793736" 24 | + "5af90bbf74a35be6b40b8eedf2785e42" 25 | + "874d" 26 | ); 27 | ChaCha20 cha = new ChaCha20(key, nonce); 28 | byte[] result = cha.encrypt(plain.getBytes()); 29 | assertTrue(Arrays.equals(test, result)); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/util/ReservoirSampling.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.util; 2 | 3 | import java.util.Random; 4 | 5 | /** 6 | * Reservoir sampling. When adding more than 1 billion entries, new entries 7 | * replace existing entries slightly more often: with a fixed probability of 1:1 8 | * billion. 9 | * 10 | * @param the type 11 | */ 12 | public class ReservoirSampling { 13 | 14 | private final Random random; 15 | private final int resultSize; 16 | private T[] array; 17 | private int pos; 18 | private long count; 19 | 20 | @SuppressWarnings("unchecked") 21 | public ReservoirSampling(int count, Random random) { 22 | this.resultSize = count; 23 | this.array = (T[]) new Object[count]; 24 | this.random = random; 25 | } 26 | 27 | public void add(T obj) { 28 | if (pos < resultSize) { 29 | array[pos] = obj; 30 | pos++; 31 | return; 32 | } 33 | count++; 34 | long r = random.nextLong(); 35 | int reduce = (int) Math.min(count, 1_000_000_000); 36 | int index = Hash.reduce((int) r, reduce); 37 | if (index < resultSize) { 38 | array[index] = obj; 39 | } 40 | } 41 | 42 | public T[] getArray() { 43 | return array; 44 | } 45 | 46 | public long getCount() { 47 | return count; 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.bau 8 | bau 9 | 1.0-SNAPSHOT 10 | 11 | 12 | 18 13 | 18 14 | 15 | 16 | 17 | 18 | 19 | org.apache.maven.plugins 20 | maven-jar-plugin 21 | 22 | 23 | 24 | true 25 | org.bau.tools.Transpile 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | junit 36 | junit 37 | [4.13.1,) 38 | test 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /src/test/java/org/bau/games/Chess.java: -------------------------------------------------------------------------------- 1 | package org.bau.games; 2 | 3 | public class Chess { 4 | 5 | final static int KING = 1, QUEEN = 2, ROOK = 3, BISHOP = 4, KNIGHT = 5, PAWN = 6, BLACK = 7; 6 | 7 | // white chess king ♔ U+2654 ♔ ♔ 8 | // white chess queen ♕ U+2655 ♕ ♕ 9 | // white chess rook ♖ U+2656 ♖ ♖ 10 | // white chess bishop ♗ U+2657 ♗ ♗ 11 | // white chess knight ♘ U+2658 ♘ ♘ 12 | // white chess pawn ♙ U+2659 ♙ ♙ 13 | // black chess king ♚ U+265A ♚ ♚ 14 | // black chess queen ♛ U+265B ♛ ♛ 15 | // black chess rook ♜ U+265C ♜ ♜ 16 | // black chess bishop ♝ U+265D ♝ ♝ 17 | // black chess knight ♞ U+265E ♞ ♞ 18 | // black chess pawn ♟ U+265F ♟ ♟ 19 | 20 | 21 | int[] board = new int[64]; 22 | 23 | void init() { 24 | board = new int[64]; 25 | board[0] = board[7] = ROOK; 26 | board[1] = board[6] = KNIGHT; 27 | board[2] = board[5] = BISHOP; 28 | board[3] = QUEEN; 29 | board[4] = KING; 30 | for (int i = 0; i < 8; i++) { 31 | board[i + 56] = board[i]; 32 | board[i] += BLACK; 33 | board[i + 8] = PAWN + BLACK; 34 | board[i + 48] = PAWN; 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/spectralNorm.c: -------------------------------------------------------------------------------- 1 | /* The Computer Language Benchmarks Game 2 | * https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | * 4 | * Contributed by Sebastien Loisel 5 | */ 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | double eval_A(int i, int j) { 12 | return 1.0 / ((i + j) * (i + j + 1) / 2 + i + 1); 13 | } 14 | 15 | void eval_A_times_u(int N, const double u[], double Au[]) { 16 | int i, j; 17 | for(i = 0; i < N; i++) { 18 | Au[i] = 0; 19 | for (j = 0; j < N; j++) 20 | Au[i] += eval_A(i, j) * u[j]; 21 | } 22 | } 23 | 24 | void eval_At_times_u(int N, const double u[], double Au[]) { 25 | int i, j; 26 | for (i = 0; i < N; i++) { 27 | Au[i] = 0; 28 | for (j=0;j 8 | #include 9 | #include 10 | 11 | double eval_A(int i, int j) { 12 | return 1.0 / ((i + j) * (i + j + 1) / 2 + i + 1); 13 | } 14 | 15 | void eval_A_times_u(int N, const double u[], double Au[]) { 16 | int i, j; 17 | for(i = 0; i < N; i++) { 18 | Au[i] = 0; 19 | for (j = 0; j < N; j++) 20 | Au[i] += eval_A(i, j) * u[j]; 21 | } 22 | } 23 | 24 | void eval_At_times_u(int N, const double u[], double Au[]) { 25 | int i, j; 26 | for (i = 0; i < N; i++) { 27 | Au[i] = 0; 28 | for (j=0;j= data.len 31 | i = next 32 | 33 | fun arrayOf(T type, entries T..) T[] 34 | return entries 35 | 36 | fun i8[] len() int 37 | return this.len 38 | 39 | fun sum(a int, b int) int 40 | return a + b 41 | 42 | fun array(entries T..) T[] 43 | return entries 44 | 45 | 46 | ## Expected 47 | 0 48 | 1 49 | 2 50 | 3 51 | 4 52 | 5 53 | 6 54 | 7 55 | 8 56 | 9 57 | 10 58 | 11 59 | 12 60 | 13 61 | 14 62 | 15 63 | 0 64 | 1 65 | 2 66 | 3 67 | 44 68 | 0 69 | 1 70 | 2 71 | 3 72 | 1.0 73 | 2.0 74 | 3.0 75 | len 3 76 | 1 77 | 0 78 | 44 79 | len of hello is 5 80 | -------------------------------------------------------------------------------- /src/test/java/org/bau/TestNull.java: -------------------------------------------------------------------------------- 1 | package org.bau; 2 | 3 | import static org.junit.Assert.assertTrue; 4 | import static org.junit.Assert.fail; 5 | 6 | import org.bau.parser.Parser; 7 | import org.junit.Test; 8 | 9 | public class TestNull { 10 | 11 | @Test 12 | public void preventNullReturn() { 13 | try { 14 | new Parser(""" 15 | type Value 16 | data int 17 | 18 | fun get(key int) Value 19 | if key <= 0 20 | return null 21 | result : Value 22 | result.data = key * 10 23 | return result 24 | 25 | fun test() 26 | a : get(0) 27 | println(a.data) 28 | 29 | test() 30 | """).parse(); 31 | fail(); 32 | } catch (Exception e) { 33 | assertTrue(e.getMessage(), e.getMessage().indexOf("may not be 'null'") > 0); 34 | } 35 | } 36 | 37 | @Test 38 | public void preventNullAccess() { 39 | try { 40 | new Parser(""" 41 | type Value 42 | data int 43 | 44 | fun get(key int) Value? 45 | if key <= 0 46 | return null 47 | result : Value() 48 | result.data = key * 10 49 | return result 50 | 51 | fun test() 52 | a : get(0) 53 | println(a.data) 54 | 55 | test() 56 | """).parse(); 57 | fail(); 58 | } catch (Exception e) { 59 | assertTrue(e.getMessage().indexOf("'a' could be null here") > 0); 60 | } 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/mandelbrot.py: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import sys, struct 5 | 6 | def main(): 7 | cout = sys.stdout.buffer.write 8 | n = 200 9 | if len(sys.argv) > 1: 10 | n = int(sys.argv[1]) 11 | w = h = n 12 | Iter = 50 13 | Limit = 2.0 14 | sys.stdout.buffer.write(f'P4\n{w} {h}\n'.encode()) 15 | for y in range(h): 16 | bit_num, byte_acc = 0, 0 17 | for x in range(w): 18 | Zr = Zi = Tr = Ti = 0.0 19 | Cr = 2.0 * x / w - 1.5 20 | Ci = 2.0 * y / h - 1.0 21 | i = 0 22 | while i < Iter and Tr + Ti <= Limit * Limit: 23 | Zi = 2.0 * Zr * Zi + Ci 24 | Zr = Tr - Ti + Cr 25 | Tr = Zr * Zr 26 | Ti = Zi * Zi 27 | i += 1 28 | byte_acc <<= 1 29 | if Tr + Ti <= Limit * Limit: 30 | byte_acc |= 0x01 31 | bit_num += 1 32 | if bit_num == 8: 33 | sys.stdout.buffer.write(struct.pack('B', byte_acc)) 34 | bit_num = 0 35 | byte_acc = 0 36 | elif x == w - 1: 37 | byte_acc <<= 8 - (w % 8) 38 | sys.stdout.buffer.write(struct.pack('B', byte_acc)) 39 | bit_num = 0 40 | byte_acc = 0 41 | 42 | main() -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/python/mandelbrot.py: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import sys, struct 5 | 6 | def main(): 7 | cout = sys.stdout.buffer.write 8 | n = 200 9 | if len(sys.argv) > 1: 10 | n = int(sys.argv[1]) 11 | w = h = n 12 | Iter = 50 13 | Limit = 2.0 14 | sys.stdout.buffer.write(f'P4\n{w} {h}\n'.encode()) 15 | for y in range(h): 16 | bit_num, byte_acc = 0, 0 17 | for x in range(w): 18 | Zr = Zi = Tr = Ti = 0.0 19 | Cr = 2.0 * x / w - 1.5 20 | Ci = 2.0 * y / h - 1.0 21 | i = 0 22 | while i < Iter and Tr + Ti <= Limit * Limit: 23 | Zi = 2.0 * Zr * Zi + Ci 24 | Zr = Tr - Ti + Cr 25 | Tr = Zr * Zr 26 | Ti = Zi * Zi 27 | i += 1 28 | byte_acc <<= 1 29 | if Tr + Ti <= Limit * Limit: 30 | byte_acc |= 0x01 31 | bit_num += 1 32 | if bit_num == 8: 33 | sys.stdout.buffer.write(struct.pack('B', byte_acc)) 34 | bit_num = 0 35 | byte_acc = 0 36 | elif x == w - 1: 37 | byte_acc <<= 8 - (w % 8) 38 | sys.stdout.buffer.write(struct.pack('B', byte_acc)) 39 | bit_num = 0 40 | byte_acc = 0 41 | 42 | main() -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/swift/piDigits/Sources/main.swift: -------------------------------------------------------------------------------- 1 | // The Computer Language Benchmarks Game 2 | // https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import Foundation 5 | import BigInt 6 | 7 | var acc = BigInt(0) 8 | var den = BigInt(1) 9 | var num = BigInt(1) 10 | let ten = BigInt(10) 11 | 12 | @MainActor 13 | func extractDigit(_ nth: Int) -> Int { 14 | return Int(((num * BigInt(nth)) + acc) / den) 15 | } 16 | 17 | @MainActor 18 | func eliminateDigit(_ d: Int) { 19 | acc -= den * BigInt(d) 20 | acc *= ten 21 | num *= ten 22 | } 23 | 24 | @MainActor 25 | func nextTerm(_ k: Int) { 26 | acc += num << 1 27 | let k2p1 = BigInt(k * 2 + 1) 28 | acc *= k2p1 29 | den *= k2p1 30 | num *= BigInt(k) 31 | } 32 | 33 | @MainActor 34 | func main() { 35 | var n = 10_000 36 | if CommandLine.arguments.count > 1 { 37 | n = Int(CommandLine.arguments[1]) ?? 10_000 38 | } 39 | var i = 0 40 | var k = 0 41 | while i < n { 42 | k += 1 43 | nextTerm(k) 44 | if num > acc { 45 | continue 46 | } 47 | let d = extractDigit(3) 48 | if d != extractDigit(4) { 49 | continue 50 | } 51 | eliminateDigit(d) 52 | print(Character(UnicodeScalar(48 + d)!), terminator: "") 53 | i += 1 54 | if i % 10 == 0 { 55 | print(" : \(i)") 56 | } 57 | } 58 | } 59 | 60 | main() -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/c/mandelbrot.c: -------------------------------------------------------------------------------- 1 | // The Computer Language Benchmarks Game 2 | // https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | #include 5 | #include 6 | 7 | int main(int argc, char **argv) { 8 | int w, h, bit_num = 0; 9 | int i, iter = 50; 10 | char byte_acc = 0; 11 | double x, y, limit = 2.0; 12 | double Zr, Zi, Cr, Ci, Tr, Ti; 13 | int n = 200; 14 | if (argc > 1) 15 | n = atoi(argv[1]); 16 | w = h = n; 17 | printf("P4\n%d %d\n", w, h); 18 | for (y = 0; y < h; y++) { 19 | for (x = 0; x < w; x++) { 20 | Zr = Zi = Tr = Ti = 0; 21 | Cr = 2.0 * x / w - 1.5; 22 | Ci = 2.0 * y / h - 1.0; 23 | for (i = 0; i < iter && Tr + Ti <= limit * limit; i++) { 24 | Zi = 2.0 * Zr * Zi + Ci; 25 | Zr = Tr - Ti + Cr; 26 | Tr = Zr * Zr; 27 | Ti = Zi * Zi; 28 | } 29 | byte_acc <<= 1; 30 | if (Tr + Ti <= limit * limit) 31 | byte_acc |= 0x01; 32 | bit_num++; 33 | if (bit_num == 8) { 34 | putc(byte_acc, stdout); 35 | byte_acc = 0; 36 | bit_num = 0; 37 | } else if (x == w - 1) { 38 | byte_acc <<= 8 - w % 8; 39 | putc(byte_acc, stdout); 40 | byte_acc = 0; 41 | bit_num = 0; 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/mandelbrot.c: -------------------------------------------------------------------------------- 1 | // The Computer Language Benchmarks Game 2 | // https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | #include 5 | #include 6 | 7 | int main(int argc, char **argv) { 8 | int w, h, bit_num = 0; 9 | int i, iter = 50; 10 | char byte_acc = 0; 11 | double x, y, limit = 2.0; 12 | double Zr, Zi, Cr, Ci, Tr, Ti; 13 | int n = 200; 14 | if (argc > 1) 15 | n = atoi(argv[1]); 16 | w = h = n; 17 | printf("P4\n%d %d\n", w, h); 18 | for (y = 0; y < h; y++) { 19 | for (x = 0; x < w; x++) { 20 | Zr = Zi = Tr = Ti = 0; 21 | Cr = 2.0 * x / w - 1.5; 22 | Ci = 2.0 * y / h - 1.0; 23 | for (i = 0; i < iter && Tr + Ti <= limit * limit; i++) { 24 | Zi = 2.0 * Zr * Zi + Ci; 25 | Zr = Tr - Ti + Cr; 26 | Tr = Zr * Zr; 27 | Ti = Zi * Zi; 28 | } 29 | byte_acc <<= 1; 30 | if (Tr + Ti <= limit * limit) 31 | byte_acc |= 0x01; 32 | bit_num++; 33 | if (bit_num == 8) { 34 | putc(byte_acc, stdout); 35 | byte_acc = 0; 36 | bit_num = 0; 37 | } else if (x == w - 1) { 38 | byte_acc <<= 8 - w % 8; 39 | putc(byte_acc, stdout); 40 | byte_acc = 0; 41 | bit_num = 0; 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/sort/number/NumberInsertionSort.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.sort.number; 2 | 3 | public class NumberInsertionSort { 4 | 5 | public static boolean isSorted(long[] d, int left, int right) { 6 | for(int i = right - 1; i > left; i--) { 7 | if (d[i] > d[i + 1]) { 8 | return false; 9 | } 10 | } 11 | return true; 12 | } 13 | 14 | public static void insertionSort(long[] d, int left, int right) { 15 | for (int i = left + 1, j; i <= right; i++) { 16 | long t = d[i]; 17 | for (j = i - 1; j >= left && d[j] > t; j--) { 18 | d[j + 1] = d[j]; 19 | } 20 | d[j + 1] = t; 21 | } 22 | } 23 | 24 | public static void binaryInsertionSort(long[] d, int left, int right) { 25 | for (int i = left + 1; i <= right; i++) { 26 | long x = d[i]; 27 | int ins = binarySearch(d, x, left, i - 1); 28 | for (int j = i - 1; j >= ins; j--) { 29 | d[j + 1] = d[j]; 30 | } 31 | d[ins] = x; 32 | } 33 | } 34 | 35 | public static int binarySearch(long[] d, long x, int from, int to) { 36 | while (from <= to) { 37 | int m = (from + to) >>> 1; 38 | if (x >= d[m]) { 39 | from = m + 1; 40 | } else { 41 | to = m - 1; 42 | } 43 | } 44 | return from; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/go/spectralNorm.go: -------------------------------------------------------------------------------- 1 | // The Computer Language Benchmarks Game 2 | // https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | package main 5 | 6 | import ( 7 | "flag" 8 | "fmt" 9 | "math" 10 | "strconv" 11 | ) 12 | 13 | var n = 0 14 | 15 | func evalA(i, j int) int { return ((i+j)*(i+j+1)/2 + i + 1) } 16 | 17 | type Vec []float64 18 | 19 | func (v Vec) Times(u Vec) { 20 | for i := 0; i < len(v); i++ { 21 | v[i] = 0 22 | for j := 0; j < len(u); j++ { 23 | v[i] += u[j] / float64(evalA(i, j)) 24 | } 25 | } 26 | } 27 | 28 | func (v Vec) TimesTransp(u Vec) { 29 | for i := 0; i < len(v); i++ { 30 | v[i] = 0 31 | for j := 0; j < len(u); j++ { 32 | v[i] += u[j] / float64(evalA(j, i)) 33 | } 34 | } 35 | } 36 | 37 | func (v Vec) ATimesTransp(u Vec) { 38 | x := make(Vec, len(u)) 39 | x.Times(u) 40 | v.TimesTransp(x) 41 | } 42 | 43 | func main() { 44 | flag.Parse() 45 | if flag.NArg() > 0 { 46 | n, _ = strconv.Atoi(flag.Arg(0)) 47 | } 48 | N := n 49 | u := make(Vec, N) 50 | for i := 0; i < N; i++ { 51 | u[i] = 1 52 | } 53 | v := make(Vec, N) 54 | for i := 0; i < 10; i++ { 55 | v.ATimesTransp(u) 56 | u.ATimesTransp(v) 57 | } 58 | var vBv, vv float64 59 | for i := 0; i < N; i++ { 60 | vBv += u[i] * v[i] 61 | vv += v[i] * v[i] 62 | } 63 | fmt.Printf("%0.9f\n", math.Sqrt(vBv/vv)) 64 | } 65 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/spectralNorm.go: -------------------------------------------------------------------------------- 1 | // The Computer Language Benchmarks Game 2 | // https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | package main 5 | 6 | import ( 7 | "flag" 8 | "fmt" 9 | "math" 10 | "strconv" 11 | ) 12 | 13 | var n = 0 14 | 15 | func evalA(i, j int) int { return ((i+j)*(i+j+1)/2 + i + 1) } 16 | 17 | type Vec []float64 18 | 19 | func (v Vec) Times(u Vec) { 20 | for i := 0; i < len(v); i++ { 21 | v[i] = 0 22 | for j := 0; j < len(u); j++ { 23 | v[i] += u[j] / float64(evalA(i, j)) 24 | } 25 | } 26 | } 27 | 28 | func (v Vec) TimesTransp(u Vec) { 29 | for i := 0; i < len(v); i++ { 30 | v[i] = 0 31 | for j := 0; j < len(u); j++ { 32 | v[i] += u[j] / float64(evalA(j, i)) 33 | } 34 | } 35 | } 36 | 37 | func (v Vec) ATimesTransp(u Vec) { 38 | x := make(Vec, len(u)) 39 | x.Times(u) 40 | v.TimesTransp(x) 41 | } 42 | 43 | func main() { 44 | flag.Parse() 45 | if flag.NArg() > 0 { 46 | n, _ = strconv.Atoi(flag.Arg(0)) 47 | } 48 | N := n 49 | u := make(Vec, N) 50 | for i := 0; i < N; i++ { 51 | u[i] = 1 52 | } 53 | v := make(Vec, N) 54 | for i := 0; i < 10; i++ { 55 | v.ATimesTransp(u) 56 | u.ATimesTransp(v) 57 | } 58 | var vBv, vv float64 59 | for i := 0; i < N; i++ { 60 | vBv += u[i] * v[i] 61 | vv += v[i] * v[i] 62 | } 63 | fmt.Printf("%0.9f\n", math.Sqrt(vBv/vv)) 64 | } 65 | -------------------------------------------------------------------------------- /src/test/java/org/bau/benchmarks/PiDigits.kt: -------------------------------------------------------------------------------- 1 | // The Computer Language Benchmarks Game 2 | // https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | package org.bau.benchmarks 5 | 6 | import java.math.BigInteger 7 | 8 | fun main(args: Array) { 9 | var n = 10000 10 | if (args.isNotEmpty()) 11 | n = args[0].toInt() 12 | var k = 0 13 | var i = 0 14 | while (i < n) { 15 | k++ 16 | nextTerm(k) 17 | if (num > acc) 18 | continue 19 | val d = extractDigit(3) 20 | if (d != extractDigit(4)) 21 | continue 22 | eliminateDigit(d) 23 | print(('0'.code + d).toChar()) 24 | i++ 25 | if (i % 10 == 0) 26 | println(" : $i") 27 | } 28 | } 29 | 30 | var ten: BigInteger = BigInteger.TEN 31 | var acc: BigInteger = BigInteger.ZERO 32 | var den: BigInteger = BigInteger.ONE 33 | var num: BigInteger = BigInteger.ONE 34 | 35 | fun extractDigit(nth: Int): Int { 36 | return num.multiply(BigInteger.valueOf(nth.toLong())).add(acc).divide(den).toInt() 37 | } 38 | 39 | fun eliminateDigit(d: Int) { 40 | acc = acc.subtract(den.multiply(BigInteger.valueOf(d.toLong()))) 41 | acc = acc.multiply(ten) 42 | num = num.multiply(ten) 43 | } 44 | 45 | fun nextTerm(k: Int) { 46 | acc = acc.add(num.shiftLeft(1)) 47 | val k2p1 = BigInteger.valueOf((k * 2 + 1).toLong()) 48 | acc = acc.multiply(k2p1) 49 | den = den.multiply(k2p1) 50 | num = num.multiply(BigInteger.valueOf(k.toLong())) 51 | } 52 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/io/ChecksumTest.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.io; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import java.util.Arrays; 6 | import java.util.Random; 7 | import java.util.zip.Adler32; 8 | import java.util.zip.CRC32; 9 | 10 | import org.junit.Test; 11 | 12 | public class ChecksumTest { 13 | 14 | @Test 15 | public void random() { 16 | Random r = new Random(1); 17 | for (int i = 0; i < 10_000; i++) { 18 | byte[] data = new byte[r.nextInt(100)]; 19 | long got = Checksum.crc32(data); 20 | CRC32 crc = new CRC32(); 21 | crc.update(data); 22 | long value = crc.getValue(); 23 | assertEquals(value, got); 24 | 25 | Adler32 adler = new Adler32(); 26 | adler.update(data); 27 | value = adler.getValue(); 28 | got = Checksum.adler32(data); 29 | assertEquals(value, got); 30 | } 31 | } 32 | 33 | @Test 34 | public void test() { 35 | byte[] ones = new byte[1_000_000]; 36 | Arrays.fill(ones, (byte) 1); 37 | assertEquals(233063202, Checksum.adler32(ones)); 38 | assertEquals(1823800358, Checksum.crc32(ones)); 39 | assertEquals(-757937976, Checksum.fletcher32(ones)); 40 | byte[] zeros = new byte[1_000_000]; 41 | assertEquals(1126236161, Checksum.adler32(zeros)); 42 | assertEquals(309971870, Checksum.crc32(zeros)); 43 | assertEquals(-1, Checksum.fletcher32(zeros)); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/sort/number/NumberIntroSort.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.sort.number; 2 | 3 | public class NumberIntroSort { 4 | 5 | public static void sort(long[] a) { 6 | sort(a, 0, a.length); 7 | } 8 | 9 | public static void sort(long[] a, int from, int to) { 10 | quicksort(a, from, to - 1, 0); 11 | } 12 | 13 | private static void quicksort(long a[], int low, int high, int depth) { 14 | if (high - low < 30) { 15 | NumberInsertionSort.insertionSort(a, low, high); 16 | return; 17 | } 18 | if (depth > 100) { 19 | NumberShellSort.sort(a, low, high + 1); 20 | return; 21 | } 22 | int swapCount = 0; 23 | int pi = low + (high - low) / 2; 24 | long pivot = a[pi]; 25 | int l = low, h = high; 26 | while (true) { 27 | while (pivot > a[l]) { 28 | l++; 29 | } 30 | while (pivot < a[h]) { 31 | h--; 32 | } 33 | if (l >= h) { 34 | pi = h; 35 | break; 36 | } 37 | swapCount++; 38 | long temp = a[l]; 39 | a[l] = a[h]; 40 | a[h] = temp; 41 | l++; 42 | h--; 43 | } 44 | if (swapCount == 0 && NumberInsertionSort.isSorted(a, low, high)) { 45 | return; 46 | } 47 | quicksort(a, low, pi, depth + 1); 48 | quicksort(a, pi + 1, high, depth + 1); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /doc/conciseSyntax.md: -------------------------------------------------------------------------------- 1 | # Concise Syntax 2 | 3 | Bau attempts to be easy to learn, with clear, simple, and concise syntax. 4 | It is inspired by Python, a language widely regarded for its readability and simplicity. 5 | The following diagram compares the surface-level conciseness of the programming 6 | languages, using the source code of the benchmark implementations. 7 | 8 | 9 | 10 | (Comparison to Python; lower means more concise) 11 | 12 | We compare the number of lines, bytes, whitespace characters, 13 | alphanumeric characters, and special character against Python. 14 | Python is considered both concise and highly readable, 15 | and, arguably, this reputation is one of the reasons for its popularity. 16 | 17 | For all languages, the same algorithms, variable names, 18 | and indentation rules (4 space characters) are used. 19 | The `_` character (underscore / underline) is excluded 20 | from the comparison, because some languages use camelCase and some use snake_case, 21 | and also because some (but not all) languages support `_` 22 | to make large number more readable. 23 | There is no trailing whitespace in the examples, 24 | and the comments are exactly the same. 25 | The comparison is not perfect, but shows a clear trend: 26 | Bau is very similar to Python (and even more concise in some aspects), 27 | and the other languages are about 10% to 80% more verbose. 28 | 29 | Conciseness and simplicity are important for multiple reasons: 30 | when writing programs, but it is even more important when reading the source code. 31 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/binaryTrees.bau: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import org.bau.Math 5 | import org.bau.Env 6 | 7 | fun main() 8 | n := 10 9 | if Env.argCount() > 1 10 | n = Math.parseInt(Env.arg(1)) 11 | minDepth : 4 12 | maxDepth := n 13 | if minDepth + 2 > n 14 | maxDepth = minDepth + 2 15 | stretchDepth : maxDepth + 1 16 | stretch(stretchDepth) 17 | longLived : buildTree(maxDepth) 18 | depth := minDepth 19 | while depth <= maxDepth 20 | iterations := 1 << (maxDepth - depth + minDepth) 21 | sum := 0 22 | for i := until(iterations) 23 | sum += count(depth) 24 | println(iterations '\t trees of depth ' depth '\t check: ' sum) 25 | depth += 2 26 | println('long lived tree of depth ' maxDepth '\t check: ' longLived.nodeCount()) 27 | 28 | fun stretch(depth int) 29 | println('stretch tree of depth ' depth '\t check: ' count(depth)) 30 | 31 | fun count(depth int) int 32 | return buildTree(depth).nodeCount() 33 | 34 | type Tree 35 | left Tree+? 36 | right Tree+? 37 | 38 | fun buildTree(depth int) Tree+ 39 | if depth = 0 40 | return Tree+(null, null) 41 | return Tree+(buildTree(depth - 1), buildTree(depth - 1)) 42 | 43 | fun Tree+ nodeCount() int 44 | result := 1 45 | l : &left 46 | if l 47 | result += l.nodeCount() 48 | r : &right 49 | if r 50 | result += r.nodeCount() 51 | return result 52 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/bau/binaryTrees.bau: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import org.bau.Math 5 | import org.bau.Env 6 | 7 | fun main() 8 | n := 10 9 | if Env.argCount() > 1 10 | n = Math.parseInt(Env.arg(1)) 11 | minDepth : 4 12 | maxDepth := n 13 | if minDepth + 2 > n 14 | maxDepth = minDepth + 2 15 | stretchDepth : maxDepth + 1 16 | stretch(stretchDepth) 17 | longLived : buildTree(maxDepth) 18 | depth := minDepth 19 | while depth <= maxDepth 20 | iterations := 1 << (maxDepth - depth + minDepth) 21 | sum := 0 22 | for i := until(iterations) 23 | sum += count(depth) 24 | println(iterations '\t trees of depth ' depth '\t check: ' sum) 25 | depth += 2 26 | println('long lived tree of depth ' maxDepth '\t check: ' longLived.nodeCount()) 27 | 28 | fun stretch(depth int) 29 | println('stretch tree of depth ' depth '\t check: ' count(depth)) 30 | 31 | fun count(depth int) int 32 | return buildTree(depth).nodeCount() 33 | 34 | type Tree 35 | left Tree+? 36 | right Tree+? 37 | 38 | fun buildTree(depth int) Tree+ 39 | if depth = 0 40 | return Tree+(null, null) 41 | return Tree+(buildTree(depth - 1), buildTree(depth - 1)) 42 | 43 | fun Tree+ nodeCount() int 44 | result := 1 45 | l : &left 46 | if l 47 | result += l.nodeCount() 48 | r : &right 49 | if r 50 | result += r.nodeCount() 51 | return result 52 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/math/Factorial.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.math; 2 | 3 | import java.math.BigInteger; 4 | 5 | import org.junit.Test; 6 | 7 | public class Factorial { 8 | 9 | // TODO see https://github.com/thomasmueller/minperf/blob/master/src/test/java/org/minperf/Probability.java 10 | 11 | @Test 12 | public void test() { 13 | for (int i = 0; i < 500; i += 10) { 14 | long f1 = factorial(i); 15 | double f2 = factorial2(i); 16 | double f3 = factorial3(i); 17 | // System.out.println(i + " " + f1 + " " + f2 + " " + f3); 18 | 19 | // 52 8.065817517×10^67 20 | // 70 1.197857167×10^100 21 | // 100 9.332621544×10^157 22 | // 100 9223372036854775807 9.332621538103648E157 9.332621544394415E157 23 | } 24 | } 25 | 26 | long factorial(long n) { 27 | long result = 1; 28 | for (int i = 1; i <= n && result > 0; i++) { 29 | result *= i; 30 | } 31 | if (result < 0) { 32 | return Long.MAX_VALUE; 33 | } 34 | return result; 35 | } 36 | 37 | double factorial2(double n) { 38 | double z = n + 1; 39 | return Math.sqrt(2 * Math.PI / z) * Math.pow((z + 1 / (12 * z - (1 / 10 / z))) / Math.E, z); 40 | } 41 | 42 | double factorial3(long n) { 43 | BigInteger x = BigInteger.ONE; 44 | for (int i = 1; i <= n; i++) { 45 | x = x.multiply(BigInteger.valueOf(i)); 46 | } 47 | return x.doubleValue(); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/mandelbrot.v: -------------------------------------------------------------------------------- 1 | // The Computer Language Benchmarks Game 2 | // https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import os 5 | 6 | fn main() { 7 | mut n := 200 8 | if os.args.len > 1 { 9 | n = os.args[1].int() 10 | } 11 | w := n 12 | h := n 13 | mut bit_num := 0 14 | mut byte_acc := u8(0) 15 | iter := 50 16 | limit := 2.0 17 | print('P4\n${w} ${h}\n') 18 | for y in 0 .. h { 19 | for x in 0 .. w { 20 | mut zr, mut zi, mut tr, mut ti := 0.0, 0.0, 0.0, 0.0 21 | cr := 2.0 * f64(x) / f64(w) - 1.5 22 | ci := 2.0 * f64(y) / f64(h) - 1.0 23 | for _ in 0 .. iter { 24 | if tr + ti > limit * limit { 25 | break 26 | } 27 | zi = 2.0 * zr * zi + ci 28 | zr = tr - ti + cr 29 | tr = zr * zr 30 | ti = zi * zi 31 | } 32 | byte_acc <<= 1 33 | if tr + ti <= limit * limit { 34 | byte_acc |= u8(0x01) 35 | } 36 | bit_num++ 37 | if bit_num == 8 { 38 | print(byte_acc.ascii_str()) 39 | byte_acc = 0 40 | bit_num = 0 41 | } else if x == w - 1 { 42 | // pad remaining bits 43 | byte_acc <<= u8(8 - w % 8) 44 | print(byte_acc.ascii_str()) 45 | byte_acc = 0 46 | bit_num = 0 47 | } 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/v/mandelbrot.v: -------------------------------------------------------------------------------- 1 | // The Computer Language Benchmarks Game 2 | // https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import os 5 | 6 | fn main() { 7 | mut n := 200 8 | if os.args.len > 1 { 9 | n = os.args[1].int() 10 | } 11 | w := n 12 | h := n 13 | mut bit_num := 0 14 | mut byte_acc := u8(0) 15 | iter := 50 16 | limit := 2.0 17 | print('P4\n${w} ${h}\n') 18 | for y in 0 .. h { 19 | for x in 0 .. w { 20 | mut zr, mut zi, mut tr, mut ti := 0.0, 0.0, 0.0, 0.0 21 | cr := 2.0 * f64(x) / f64(w) - 1.5 22 | ci := 2.0 * f64(y) / f64(h) - 1.0 23 | for _ in 0 .. iter { 24 | if tr + ti > limit * limit { 25 | break 26 | } 27 | zi = 2.0 * zr * zi + ci 28 | zr = tr - ti + cr 29 | tr = zr * zr 30 | ti = zi * zi 31 | } 32 | byte_acc <<= 1 33 | if tr + ti <= limit * limit { 34 | byte_acc |= u8(0x01) 35 | } 36 | bit_num++ 37 | if bit_num == 8 { 38 | print(byte_acc.ascii_str()) 39 | byte_acc = 0 40 | bit_num = 0 41 | } else if x == w - 1 { 42 | // pad remaining bits 43 | byte_acc <<= u8(8 - w % 8) 44 | print(byte_acc.ascii_str()) 45 | byte_acc = 0 46 | bit_num = 0 47 | } 48 | } 49 | } 50 | } -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/sort/HeapSort.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.sort; 2 | 3 | import java.util.Comparator; 4 | 5 | /** 6 | * Non-recursive heap sort. 7 | * 8 | * Not stable. 9 | * Worst case: O(n * log(n)) 10 | * Memory: O(1) 11 | */ 12 | public class HeapSort { 13 | 14 | // https://en.oi-wiki.org/basic/heap-sort/ 15 | 16 | public static void sort(T[] a, Comparator c) { 17 | sort(a, c, 0, a.length); 18 | } 19 | 20 | public static void sort(T[] a, Comparator c, int from, int to) { 21 | int len = to - from; 22 | for (int k = 1; k >= 0; k--) { 23 | for (int i = len - 1; i >= 0; i--) { 24 | T tmp = a[from]; 25 | a[from] = a[from + i]; 26 | a[from + i] = tmp; 27 | int right = i + k * (len - i) - 1; 28 | int parent = i * k; 29 | int child = parent * 2 + 1; 30 | while (child <= right) { 31 | if (child + 1 <= right && c.compare(a[from + child], a[from + child + 1]) < 0) { 32 | child++; 33 | } 34 | if (c.compare(a[from + parent], a[from + child]) >= 0) { 35 | break; 36 | } 37 | tmp = a[from + parent]; 38 | a[from + parent] = a[from + child]; 39 | a[from + child] = tmp; 40 | parent = child; 41 | child = parent * 2 + 1; 42 | } 43 | } 44 | } 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /src/test/java/org/bau/LanguageModules.java: -------------------------------------------------------------------------------- 1 | package org.bau; 2 | 3 | /* 4 | 5 | "module" keyword 6 | - Rust: modules contain modules 7 | - Rust: extern crate foo as the_other_foo; 8 | - Rust: Only the public items of a module can be accessed from outside the module scope. 9 | - Rust: "use deeply::nested::function as other_function" 10 | - Rust: self::function() -- in the same module 11 | - Rust: self::cool::function() -- in different module inside this one 12 | - Rust: super::function() -- parent module 13 | - Rust: Cargo.toml [dependencies] macos-perf = "0.1.1" 14 | - Java: using absolute names 15 | - Java: static import (but this has problems) 16 | - Python: from fibo import fib, fib2; import fibo; from fibo import *; import fibo as fib; from fibo import fib as fibonacci 17 | - Python: dir() does not list the names of built-in functions and variables. 18 | - Python: from ..filters import equalizer 19 | - Javascript: import * as name from "module-name"; import { export1 } from "module-name"; import { export1 as alias1 } from "module-name"; 20 | - Javascript: import myDefault, { foo, bar } from "/modules/my-module.js"; 21 | - C: include 22 | - C++ include, namespace, use 23 | - C++ modules https://learn.microsoft.com/en-us/cpp/cpp/modules-cpp?view=msvc-170 24 | - C++ export module Example; import Example; import std.core; using namespace std; 25 | - C# "using System.Text;" 26 | - Go "package main" / "import ("fmt" "math/rand" ) "println(rand.Intn(10))" 27 | - Go "import "github.com/google/uuid"" 28 | - Go "import ("math/rand" crand "crypto/rand") 29 | 30 | */ 31 | public class LanguageModules { 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/test/java/org/bau/ena/ast/Stmt.java: -------------------------------------------------------------------------------- 1 | package org.bau.ena.ast; 2 | 3 | public sealed interface Stmt extends Node permits Stmt.Assign, Stmt.ExprStmt, Stmt.If, Stmt.Loop, 4 | Stmt.Exit, Stmt.Return, Stmt.Block, Stmt.Function, Stmt.TypeDef, Stmt.Program { 5 | public record Assign(Expr target, Expr value, int line, int column) implements Stmt { 6 | } 7 | 8 | public record ExprStmt(Expr expr, int line, int column) implements Stmt { 9 | } 10 | 11 | public record If(Expr[] conds, Block[] blocks, Block elseBlock, int line, int column) implements Stmt { 12 | } 13 | 14 | public record Loop(Expr cond, Block body, int line, int column) implements Stmt { 15 | } 16 | 17 | public record Exit(int line, int column) implements Stmt { 18 | } 19 | 20 | public record Return(Expr value, int line, int column) implements Stmt { 21 | } 22 | 23 | public record Block(Stmt[] statements, int line, int column) implements Stmt { 24 | } 25 | 26 | public record Function(String name, Param[] params, String returnType, Block body, int line, int column) 27 | implements Stmt { 28 | } 29 | 30 | public record Param(String name, String type) { 31 | } 32 | 33 | public record TypeDef(String name, Param[] fields, int line, int column) implements Stmt { 34 | } 35 | 36 | public record Program(Stmt[] items) implements Stmt { 37 | @Override 38 | public int line() { 39 | return 1; 40 | } 41 | 42 | @Override 43 | public int column() { 44 | return 1; 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/binaryTreeRefCount.bau: -------------------------------------------------------------------------------- 1 | import org.bau.Utils 2 | 3 | fun main() 4 | minDepth : 1 5 | maxDepth : 3 6 | stretchDepth : maxDepth + 1 7 | stretch Tree? := with(stretchDepth) 8 | println('ref count') 9 | if stretch 10 | println('stretch tree of depth ' stretchDepth ' check: ' stretch.nodeCount()) 11 | stretch = null 12 | longLived := with(maxDepth) 13 | depth := minDepth 14 | while depth <= maxDepth 15 | iterations := 1 << (maxDepth - depth + minDepth) 16 | check := 0; 17 | i := 1 18 | while i <= iterations 19 | t := with(depth) 20 | check += t.nodeCount() 21 | i += 1 22 | println(iterations ' trees of depth ' depth ' check: ' check) 23 | depth += 2 24 | println('long lived tree of depth ' maxDepth ' check: ' longLived.nodeCount()) 25 | 26 | type Tree 27 | left Tree? 28 | right Tree? 29 | 30 | fun Tree nodeCount() int 31 | result := 1 32 | l : left 33 | if l 34 | result += l.nodeCount() 35 | r : right 36 | if r 37 | result += r.nodeCount() 38 | return result 39 | 40 | fun count(depth int) int 41 | t := with(depth) 42 | c := t.nodeCount() 43 | return c 44 | 45 | fun with(depth int) Tree 46 | if depth = 0 47 | return Tree(null, null) 48 | return Tree(with(depth - 1), with(depth - 1)) 49 | 50 | ## Expected 51 | ref count 52 | stretch tree of depth 4 check: 31 53 | 8 trees of depth 1 check: 24 54 | 2 trees of depth 3 check: 30 55 | long lived tree of depth 3 check: 15 56 | -------------------------------------------------------------------------------- /src/test/java/org/bau/ena/ast/Expr.java: -------------------------------------------------------------------------------- 1 | package org.bau.ena.ast; 2 | 3 | import java.util.Collections; 4 | import java.util.Map; 5 | import java.util.WeakHashMap; 6 | 7 | import org.bau.ena.types.Type; 8 | 9 | public sealed interface Expr extends Node permits Expr.Literal, Expr.Variable, Expr.Binary, Expr.Unary, Expr.Call, 10 | Expr.Member, Expr.Index, Expr.NewArray, Expr.Paren { 11 | Map __TYPES = Collections.synchronizedMap(new WeakHashMap<>()); 12 | 13 | default Type type() { 14 | return __TYPES.get(this); 15 | } 16 | 17 | default void setType(Type t) { 18 | __TYPES.put(this, t); 19 | } 20 | 21 | public record Literal(Object value, int line, int column) implements Expr { 22 | } 23 | 24 | public record Variable(String name, int line, int column) implements Expr { 25 | } 26 | 27 | public record Binary(Expr left, String op, Expr right, int line, int column) implements Expr { 28 | } 29 | 30 | public record Unary(String op, Expr expr, int line, int column) implements Expr { 31 | } 32 | 33 | public record Call(Expr target, Expr[] args, int line, int column) implements Expr { 34 | } 35 | 36 | public record Member(Expr target, String name, int line, int column) implements Expr { 37 | } 38 | 39 | public record Index(Expr target, Expr index, int line, int column) implements Expr { 40 | } 41 | 42 | public record NewArray(String baseType, Expr length, int line, int column) implements Expr { 43 | } 44 | 45 | public record Paren(Expr inner, int line, int column) implements Expr { 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/binaryTrees.py: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import sys 5 | 6 | class Node: 7 | def __init__(self, left = None, right = None): 8 | self.left = left 9 | self.right = right 10 | 11 | def node_count(self): 12 | result = 1 13 | if self.left is not None: 14 | result += self.left.node_count() 15 | if self.right is not None: 16 | result += self.right.node_count() 17 | return result 18 | 19 | def build_tree(depth): 20 | if depth == 0: 21 | return Node() 22 | return Node(build_tree(depth - 1), build_tree(depth - 1)) 23 | 24 | def count(depth): 25 | return build_tree(depth).node_count() 26 | 27 | def stretch(depth): 28 | print(f"stretch tree of depth {depth}\t check: {count(depth)}") 29 | 30 | def main(): 31 | n = 10 32 | if len(sys.argv) > 1: 33 | n = int(sys.argv[1]) 34 | min_depth = 4 35 | max_depth = n 36 | if min_depth + 2 > n: 37 | max_depth = min_depth + 2 38 | stretch_depth = max_depth + 1 39 | stretch(stretch_depth) 40 | long_lived = build_tree(max_depth) 41 | for depth in range(min_depth, max_depth + 1, 2): 42 | iterations = 1 << (max_depth - depth + min_depth) 43 | sum = 0 44 | for _ in range(iterations): 45 | sum += count(depth) 46 | print(f"{iterations}\t trees of depth {depth}\t check: {sum}") 47 | print(f"long lived tree of depth {max_depth}\t check: {long_lived.node_count()}") 48 | 49 | main() -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/binaryTrees.nim: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import os, strutils, std/strformat 5 | 6 | type 7 | Node = ref object 8 | left, right: Node 9 | 10 | proc buildTree(depth: int): Node = 11 | if depth == 0: 12 | new result 13 | else: 14 | result = Node(left: buildTree(depth - 1), right: buildTree(depth - 1)) 15 | 16 | proc nodeCount(n: Node): int = 17 | if n == nil: 18 | return 0 19 | else: 20 | return 1 + nodeCount(n.left) + nodeCount(n.right) 21 | 22 | proc count(depth: int): int = 23 | result = nodeCount(buildTree(depth)) 24 | 25 | proc stretch(depth: int) = 26 | let c = count(depth) 27 | echo &"stretch tree of depth {depth}\t check: {c}" 28 | 29 | proc main() = 30 | let args = commandLineParams() 31 | var n = 10 32 | if args.len > 0: 33 | n = parseInt(args[0]) 34 | const minDepth = 4 35 | var maxDepth = n 36 | if minDepth + 2 > n: 37 | maxDepth = minDepth + 2 38 | let stretchDepth = maxDepth + 1 39 | stretch(stretchDepth) 40 | let longLived = buildTree(maxDepth) 41 | for depth in countup(minDepth, maxDepth, 2): 42 | let iterations = 1 shl (maxDepth - depth + minDepth) 43 | var sum = 0 44 | for i in 0 ..< iterations: 45 | sum += count(depth) 46 | echo &"{iterations}\t trees of depth {depth}\t check: {sum}" 47 | echo &"long lived tree of depth {maxDepth}\t check: {nodeCount(longLived)}" 48 | 49 | when isMainModule: 50 | main() 51 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/python/binaryTrees.py: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import sys 5 | 6 | class Node: 7 | def __init__(self, left = None, right = None): 8 | self.left = left 9 | self.right = right 10 | 11 | def node_count(self): 12 | result = 1 13 | if self.left is not None: 14 | result += self.left.node_count() 15 | if self.right is not None: 16 | result += self.right.node_count() 17 | return result 18 | 19 | def build_tree(depth): 20 | if depth == 0: 21 | return Node() 22 | return Node(build_tree(depth - 1), build_tree(depth - 1)) 23 | 24 | def count(depth): 25 | return build_tree(depth).node_count() 26 | 27 | def stretch(depth): 28 | print(f"stretch tree of depth {depth}\t check: {count(depth)}") 29 | 30 | def main(): 31 | n = 10 32 | if len(sys.argv) > 1: 33 | n = int(sys.argv[1]) 34 | min_depth = 4 35 | max_depth = n 36 | if min_depth + 2 > n: 37 | max_depth = min_depth + 2 38 | stretch_depth = max_depth + 1 39 | stretch(stretch_depth) 40 | long_lived = build_tree(max_depth) 41 | for depth in range(min_depth, max_depth + 1, 2): 42 | iterations = 1 << (max_depth - depth + min_depth) 43 | sum = 0 44 | for _ in range(iterations): 45 | sum += count(depth) 46 | print(f"{iterations}\t trees of depth {depth}\t check: {sum}") 47 | print(f"long lived tree of depth {max_depth}\t check: {long_lived.node_count()}") 48 | 49 | main() -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/nim/binaryTrees.nim: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import os, strutils, std/strformat 5 | 6 | type 7 | Node = ref object 8 | left, right: Node 9 | 10 | proc buildTree(depth: int): Node = 11 | if depth == 0: 12 | new result 13 | else: 14 | result = Node(left: buildTree(depth - 1), right: buildTree(depth - 1)) 15 | 16 | proc nodeCount(n: Node): int = 17 | if n == nil: 18 | return 0 19 | else: 20 | return 1 + nodeCount(n.left) + nodeCount(n.right) 21 | 22 | proc count(depth: int): int = 23 | result = nodeCount(buildTree(depth)) 24 | 25 | proc stretch(depth: int) = 26 | let c = count(depth) 27 | echo &"stretch tree of depth {depth}\t check: {c}" 28 | 29 | proc main() = 30 | let args = commandLineParams() 31 | var n = 10 32 | if args.len > 0: 33 | n = parseInt(args[0]) 34 | const minDepth = 4 35 | var maxDepth = n 36 | if minDepth + 2 > n: 37 | maxDepth = minDepth + 2 38 | let stretchDepth = maxDepth + 1 39 | stretch(stretchDepth) 40 | let longLived = buildTree(maxDepth) 41 | for depth in countup(minDepth, maxDepth, 2): 42 | let iterations = 1 shl (maxDepth - depth + minDepth) 43 | var sum = 0 44 | for i in 0 ..< iterations: 45 | sum += count(depth) 46 | echo &"{iterations}\t trees of depth {depth}\t check: {sum}" 47 | echo &"long lived tree of depth {maxDepth}\t check: {nodeCount(longLived)}" 48 | 49 | when isMainModule: 50 | main() 51 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/throwCatch.bau: -------------------------------------------------------------------------------- 1 | import org.bau.Exception 2 | exception 3 | 4 | fun factorial(x int) int throws exception 5 | if x > 20 6 | throw exception('Value too large') 7 | if x <= 1 8 | return 1 9 | f := factorial(x - 1) 10 | return x * f 11 | 12 | i := 0 13 | while i <= 30 14 | println('Factorial of ' i ' is ' factorial(i)) 15 | catch e 16 | println('Factorial of ' i ' resulted in ' e.message) 17 | i += 1 18 | 19 | ## Expected 20 | Factorial of 0 is 1 21 | Factorial of 1 is 1 22 | Factorial of 2 is 2 23 | Factorial of 3 is 6 24 | Factorial of 4 is 24 25 | Factorial of 5 is 120 26 | Factorial of 6 is 720 27 | Factorial of 7 is 5040 28 | Factorial of 8 is 40320 29 | Factorial of 9 is 362880 30 | Factorial of 10 is 3628800 31 | Factorial of 11 is 39916800 32 | Factorial of 12 is 479001600 33 | Factorial of 13 is 6227020800 34 | Factorial of 14 is 87178291200 35 | Factorial of 15 is 1307674368000 36 | Factorial of 16 is 20922789888000 37 | Factorial of 17 is 355687428096000 38 | Factorial of 18 is 6402373705728000 39 | Factorial of 19 is 121645100408832000 40 | Factorial of 20 is 2432902008176640000 41 | Factorial of 21 resulted in Value too large 42 | Factorial of 22 resulted in Value too large 43 | Factorial of 23 resulted in Value too large 44 | Factorial of 24 resulted in Value too large 45 | Factorial of 25 resulted in Value too large 46 | Factorial of 26 resulted in Value too large 47 | Factorial of 27 resulted in Value too large 48 | Factorial of 28 resulted in Value too large 49 | Factorial of 29 resulted in Value too large 50 | Factorial of 30 resulted in Value too large 51 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/binaryTreeOwned.bau: -------------------------------------------------------------------------------- 1 | import org.bau.Utils 2 | 3 | fun main() 4 | minDepth : 1 5 | maxDepth : 3 6 | stretchDepth : maxDepth + 1 7 | stretch Tree+? := with(stretchDepth) 8 | println('ownership / borrowing') 9 | if stretch 10 | println('stretch tree of depth ' stretchDepth ' check: ' stretch.nodeCount()) 11 | stretch = null 12 | longLived := with(maxDepth) 13 | depth := minDepth 14 | while depth <= maxDepth 15 | iterations := 1 << (maxDepth - depth + minDepth) 16 | check := 0; 17 | i := 1 18 | while i <= iterations 19 | t := with(depth) 20 | check += t.nodeCount() 21 | i += 1 22 | println(iterations ' trees of depth ' depth ' check: ' check) 23 | depth += 2 24 | println('long lived tree of depth ' maxDepth ' check: ' longLived.nodeCount()) 25 | 26 | type Tree 27 | left Tree+? 28 | right Tree+? 29 | 30 | fun Tree+ nodeCount() int 31 | result := 1 32 | l : &left 33 | if l 34 | result += l.nodeCount() 35 | r : &right 36 | if r 37 | result += r.nodeCount() 38 | return result 39 | 40 | fun count(depth int) int 41 | t := with(depth) 42 | c := t.nodeCount() 43 | return c 44 | 45 | fun with(depth int) Tree+ 46 | if depth = 0 47 | return Tree+(null, null) 48 | return Tree+(with(depth - 1), with(depth - 1)) 49 | 50 | ## Expected 51 | ownership / borrowing 52 | stretch tree of depth 4 check: 31 53 | 8 trees of depth 1 check: 24 54 | 2 trees of depth 3 check: 30 55 | long lived tree of depth 3 check: 15 56 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/mandelbrot.nim: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import strutils, os 5 | 6 | proc main() = 7 | var n = 200 8 | let args = commandLineParams() 9 | if args.len > 0: 10 | n = parseInt(args[0]) 11 | let w = n 12 | let h = n 13 | var bitNum = 0 14 | var byteAcc: uint8 = 0 15 | let iter = 50 16 | const z = 0.0 17 | const limit = 2.0 18 | stdout.write("P4\n", $w, " ", $h, "\n") 19 | for y in 0 ..< h: 20 | for x in 0 ..< w: 21 | var Zr = z 22 | var Zi = z 23 | var Tr = z 24 | var Ti = z 25 | let Cr = 2.0 * float64(x) / float64(w) - 1.5 26 | let Ci = 2.0 * float64(y) / float64(h) - 1.0 27 | var i = 0 28 | while i < iter and Tr + Ti <= limit * limit: 29 | Zi = 2.0 * Zr * Zi + Ci 30 | Zr = Tr - Ti + Cr 31 | Tr = Zr * Zr 32 | Ti = Zi * Zi 33 | inc i 34 | byteAcc = byteAcc shl 1 35 | if Tr + Ti <= limit * limit: 36 | byteAcc = byteAcc or 0x01'u8 37 | inc bitNum 38 | if bitNum == 8: 39 | stdout.write(char(byteAcc)) 40 | byteAcc = 0 41 | bitNum = 0 42 | elif x == w - 1: 43 | byteAcc = byteAcc shl (8 - w mod 8) 44 | stdout.write(char(byteAcc)) 45 | byteAcc = 0 46 | bitNum = 0 47 | 48 | when isMainModule: 49 | main() 50 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/nim/mandelbrot.nim: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import strutils, os 5 | 6 | proc main() = 7 | var n = 200 8 | let args = commandLineParams() 9 | if args.len > 0: 10 | n = parseInt(args[0]) 11 | let w = n 12 | let h = n 13 | var bitNum = 0 14 | var byteAcc: uint8 = 0 15 | let iter = 50 16 | const z = 0.0 17 | const limit = 2.0 18 | stdout.write("P4\n", $w, " ", $h, "\n") 19 | for y in 0 ..< h: 20 | for x in 0 ..< w: 21 | var Zr = z 22 | var Zi = z 23 | var Tr = z 24 | var Ti = z 25 | let Cr = 2.0 * float64(x) / float64(w) - 1.5 26 | let Ci = 2.0 * float64(y) / float64(h) - 1.0 27 | var i = 0 28 | while i < iter and Tr + Ti <= limit * limit: 29 | Zi = 2.0 * Zr * Zi + Ci 30 | Zr = Tr - Ti + Cr 31 | Tr = Zr * Zr 32 | Ti = Zi * Zi 33 | inc i 34 | byteAcc = byteAcc shl 1 35 | if Tr + Ti <= limit * limit: 36 | byteAcc = byteAcc or 0x01'u8 37 | inc bitNum 38 | if bitNum == 8: 39 | stdout.write(char(byteAcc)) 40 | byteAcc = 0 41 | bitNum = 0 42 | elif x == w - 1: 43 | byteAcc = byteAcc shl (8 - w mod 8) 44 | stdout.write(char(byteAcc)) 45 | byteAcc = 0 46 | bitNum = 0 47 | 48 | when isMainModule: 49 | main() 50 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/fannkuch.py: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import sys 5 | 6 | def main(): 7 | n = 4 8 | if len(sys.argv) > 1: 9 | n = int(sys.argv[1]) 10 | print(f"Pfannkuchen({n}) = {fannkuch(n)}") 11 | 12 | def fannkuch(n): 13 | perm1 = list(range(n)) 14 | count = [0] * n 15 | perm = [0] * n 16 | flips, checksum, nperm = 0, 0, 0 17 | r = n 18 | while r > 0: 19 | while r > 1: 20 | count[r - 1] = r 21 | r -= 1 22 | perm[:] = perm1[:] 23 | # Count flips and update max and checksum 24 | f = 0 25 | k = perm[0] 26 | while k != 0: 27 | for i in range(k // 2 + 1): 28 | perm[i], perm[k - i] = perm[k - i], perm[i] 29 | i += 1 30 | k = perm[0] 31 | f += 1 32 | if f > flips: 33 | flips = f 34 | if (nperm & 1) == 0: 35 | checksum += f 36 | else: 37 | checksum -= f 38 | # Use incremental change to generate another permutation 39 | while True: 40 | if r == n: 41 | print(checksum) 42 | return flips 43 | p0 = perm1[0] 44 | i = 0 45 | while i < r: 46 | j = i + 1 47 | perm1[i] = perm1[j] 48 | i = j 49 | perm1[r] = p0 50 | count[r] -= 1 51 | if count[r] > 0: 52 | break 53 | r += 1 54 | nperm += 1 55 | return flips 56 | 57 | main() 58 | -------------------------------------------------------------------------------- /src/main/resources/org/bau/Locale.bau: -------------------------------------------------------------------------------- 1 | module org.bau.Locale 2 | 3 | type locale 4 | decimalPointChar int 5 | groupSeparatorChar int 6 | groupSizeSmall int 7 | groupSizeLarge int 8 | 9 | # Get the current locale name. This is initially 'C' unless the locale is changed 10 | fun getLocaleName() i8[] 11 | result : i8[256] 12 | native(```#include 13 | char *s = setlocale(LC_ALL, 0); 14 | printf("Current locale: %s\n", s); 15 | int i = 0; 16 | for (; i < 255 && s[i]; i++) { // stop at 255 so you have room for terminator 17 | result->data[i] = (uint8_t)s[i]; 18 | } 19 | result->data[i] = 0; // NUL terminator 20 | ```) 21 | return result 22 | 23 | # Sets the locale of this process. When specifying '' (empty string), it uses the environment variables to select the locale. 24 | fun setLocale(name i8[]) 25 | native(```#include 26 | char s[256]; 27 | for (int i = 0; i < 256; i++) { 28 | s[i] = 0; 29 | if (i < name->len) { 30 | s[i] = name->data[i]; 31 | } 32 | } 33 | setlocale(LC_ALL, s); 34 | const char *loc = setlocale(LC_ALL, NULL); 35 | ```) 36 | 37 | # Get the current locale data. 38 | fun getLocale() locale 39 | result : locale() 40 | native(```#include 41 | setlocale(LC_ALL, ""); 42 | struct lconv *lc = localeconv(); 43 | result.decimalPointChar = lc->decimal_point[0]; 44 | result.groupSeparatorChar = lc->thousands_sep[0]; 45 | result.groupSizeSmall = lc->grouping[0]; 46 | ```) 47 | return result 48 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/python/fannkuch.py: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import sys 5 | 6 | def main(): 7 | n = 4 8 | if len(sys.argv) > 1: 9 | n = int(sys.argv[1]) 10 | print(f"Pfannkuchen({n}) = {fannkuch(n)}") 11 | 12 | def fannkuch(n): 13 | perm1 = list(range(n)) 14 | count = [0] * n 15 | perm = [0] * n 16 | flips, checksum, nperm = 0, 0, 0 17 | r = n 18 | while r > 0: 19 | while r > 1: 20 | count[r - 1] = r 21 | r -= 1 22 | perm[:] = perm1[:] 23 | # Count flips and update max and checksum 24 | f = 0 25 | k = perm[0] 26 | while k != 0: 27 | for i in range(k // 2 + 1): 28 | perm[i], perm[k - i] = perm[k - i], perm[i] 29 | i += 1 30 | k = perm[0] 31 | f += 1 32 | if f > flips: 33 | flips = f 34 | if (nperm & 1) == 0: 35 | checksum += f 36 | else: 37 | checksum -= f 38 | # Use incremental change to generate another permutation 39 | while True: 40 | if r == n: 41 | print(checksum) 42 | return flips 43 | p0 = perm1[0] 44 | i = 0 45 | while i < r: 46 | j = i + 1 47 | perm1[i] = perm1[j] 48 | i = j 49 | perm1[r] = p0 50 | count[r] -= 1 51 | if count[r] > 0: 52 | break 53 | r += 1 54 | nperm += 1 55 | return flips 56 | 57 | main() 58 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/mandelbrot.swift: -------------------------------------------------------------------------------- 1 | // The Computer Language Benchmarks Game 2 | // https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import Foundation 5 | 6 | func mandelbrot(n: Int) { 7 | let w = n 8 | let h = n 9 | let iter = 50 10 | let limit = 2.0 11 | var bitNum = 0 12 | var byteAcc: UInt8 = 0 13 | FileHandle.standardOutput.write("P4\n\(w) \(h)\n".data(using: .ascii)!) 14 | for y in 0.. 1 ? Int(CommandLine.arguments[1]) ?? 200 : 200 48 | mandelbrot(n: n) 49 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/mandelbrot.go: -------------------------------------------------------------------------------- 1 | // The Computer Language Benchmarks Game 2 | // https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | package main 5 | 6 | import ( 7 | "bufio" 8 | "flag" 9 | "fmt" 10 | "os" 11 | "strconv" 12 | ) 13 | 14 | func main() { 15 | flag.Parse() 16 | n := 200 17 | if flag.NArg() > 0 { 18 | n, _ = strconv.Atoi(flag.Arg(0)) 19 | } 20 | out := bufio.NewWriter(os.Stdout) 21 | defer out.Flush() 22 | w := n 23 | h := n 24 | bitNum := 0 25 | byteAcc := byte(0) 26 | iter := 50 27 | const z = 0.0 28 | const limit = 2.0 29 | fmt.Fprintf(out, "P4\n%d %d\n", w, h) 30 | for y := 0; y < h; y++ { 31 | for x := 0; x < w; x++ { 32 | Zr, Zi, Tr, Ti := z, z, z, z 33 | Cr := 2 * float64(x) / float64(w) - 1.5 34 | Ci := 2 * float64(y) / float64(h) - 1 35 | for i := 0; i < iter && Tr + Ti <= limit * limit; i++ { 36 | Zi = 2 * Zr * Zi + Ci 37 | Zr = Tr - Ti + Cr 38 | Tr = Zr * Zr 39 | Ti = Zi * Zi 40 | } 41 | byteAcc <<= 1 42 | if Tr + Ti <= limit * limit { 43 | byteAcc |= 0x01 44 | } 45 | bitNum++ 46 | if bitNum == 8 { 47 | out.WriteByte(byteAcc) 48 | byteAcc = 0 49 | bitNum = 0 50 | } else if x == w - 1 { 51 | byteAcc <<= 8 - w % 8 52 | out.WriteByte(byteAcc) 53 | byteAcc = 0 54 | bitNum = 0 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/swift/mandelbrot.swift: -------------------------------------------------------------------------------- 1 | // The Computer Language Benchmarks Game 2 | // https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import Foundation 5 | 6 | func mandelbrot(n: Int) { 7 | let w = n 8 | let h = n 9 | let iter = 50 10 | let limit = 2.0 11 | var bitNum = 0 12 | var byteAcc: UInt8 = 0 13 | FileHandle.standardOutput.write("P4\n\(w) \(h)\n".data(using: .ascii)!) 14 | for y in 0.. 1 ? Int(CommandLine.arguments[1]) ?? 200 : 200 48 | mandelbrot(n: n) 49 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/ena/fannkuch.ena: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | fun fannkuch(n int) int 5 | perm1: int[n] 6 | for i < n 7 | perm1[i]: i 8 | perm: int[n] 9 | count: int[n] 10 | flips: 0 11 | checksum: 0 12 | nperm: 0 13 | r: n 14 | loop r > 0 15 | loop r > 1 16 | count[r - 1]: r 17 | r +: -1 18 | for i < n 19 | perm[i]: perm1[i] 20 | # Count flips and update max and checksum 21 | f: 0 22 | k: perm[0] 23 | loop k <> 0 24 | for i < perm.len 25 | if 2 * i >= k 26 | exit 27 | t: perm[i] 28 | perm[i]: perm[k - i] 29 | perm[k - i]: t 30 | k: perm[0] 31 | f +: 1 32 | if f > flips 33 | flips: f 34 | if (nperm & 1) = 0 35 | checksum +: f 36 | else 37 | checksum +: -f 38 | # Use incremental change to generate another permutation 39 | loop 1 = 1 40 | if r = n 41 | println(checksum) 42 | ret flips 43 | p0: perm1[0] 44 | i: 0 45 | loop i < r 46 | j: i + 1 47 | perm1[i]: perm1[j] 48 | i: j 49 | perm1[r]: p0 50 | count[r] +: -1 51 | if count[r] > 0 52 | exit 53 | r +: 1 54 | nperm +: 1 55 | ret flips 56 | 57 | fun main() 58 | n: 10 59 | println('Pfannkuchen(', n, ') is ', fannkuch(n)) 60 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/go/mandelbrot.go: -------------------------------------------------------------------------------- 1 | // The Computer Language Benchmarks Game 2 | // https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | package main 5 | 6 | import ( 7 | "bufio" 8 | "flag" 9 | "fmt" 10 | "os" 11 | "strconv" 12 | ) 13 | 14 | func main() { 15 | flag.Parse() 16 | n := 200 17 | if flag.NArg() > 0 { 18 | n, _ = strconv.Atoi(flag.Arg(0)) 19 | } 20 | out := bufio.NewWriter(os.Stdout) 21 | defer out.Flush() 22 | w := n 23 | h := n 24 | bitNum := 0 25 | byteAcc := byte(0) 26 | iter := 50 27 | const z = 0.0 28 | const limit = 2.0 29 | fmt.Fprintf(out, "P4\n%d %d\n", w, h) 30 | for y := 0; y < h; y++ { 31 | for x := 0; x < w; x++ { 32 | Zr, Zi, Tr, Ti := z, z, z, z 33 | Cr := 2 * float64(x) / float64(w) - 1.5 34 | Ci := 2 * float64(y) / float64(h) - 1 35 | for i := 0; i < iter && Tr + Ti <= limit * limit; i++ { 36 | Zi = 2 * Zr * Zi + Ci 37 | Zr = Tr - Ti + Cr 38 | Tr = Zr * Zr 39 | Ti = Zi * Zi 40 | } 41 | byteAcc <<= 1 42 | if Tr + Ti <= limit * limit { 43 | byteAcc |= 0x01 44 | } 45 | bitNum++ 46 | if bitNum == 8 { 47 | out.WriteByte(byteAcc) 48 | byteAcc = 0 49 | bitNum = 0 50 | } else if x == w - 1 { 51 | byteAcc <<= 8 - w % 8 52 | out.WriteByte(byteAcc) 53 | byteAcc = 0 54 | bitNum = 0 55 | } 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/mini/fannkuch.mini: -------------------------------------------------------------------------------- 1 | # The Computer Language Benchmarks Game 2 | # https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | fun fannkuch(n int) int 5 | perm1: int[n] 6 | for i < n 7 | perm1[i]: i 8 | perm: int[n] 9 | count: int[n] 10 | flips: 0 11 | checksum: 0 12 | nperm: 0 13 | r: n 14 | loop r > 0 15 | loop r > 1 16 | count[r - 1]: r 17 | r +: -1 18 | for i < n 19 | perm[i]: perm1[i] 20 | # Count flips and update max and checksum 21 | f: 0 22 | k: perm[0] 23 | loop k <> 0 24 | for i < perm.len 25 | if 2 * i >= k 26 | exit 27 | t: perm[i] 28 | perm[i]: perm[k - i] 29 | perm[k - i]: t 30 | k: perm[0] 31 | f +: 1 32 | if f > flips 33 | flips: f 34 | if (nperm & 1) = 0 35 | checksum +: f 36 | else 37 | checksum +: -f 38 | # Use incremental change to generate another permutation 39 | loop 1 = 1 40 | if r = n 41 | println(checksum) 42 | ret flips 43 | p0: perm1[0] 44 | i: 0 45 | loop i < r 46 | j: i + 1 47 | perm1[i]: perm1[j] 48 | i: j 49 | perm1[r]: p0 50 | count[r] +: -1 51 | if count[r] > 0 52 | exit 53 | r +: 1 54 | nperm +: 1 55 | ret flips 56 | 57 | fun main() 58 | n: 10 59 | println('Pfannkuchen(', n, ') is ', fannkuch(n)) 60 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/locale/NumberFormatter.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.locale; 2 | 3 | import java.nio.charset.StandardCharsets; 4 | 5 | public class NumberFormatter { 6 | 7 | private static void reverse(byte[] data, int len) { 8 | for(int a = 0, b = len - 1; a < b; a++, b--) { 9 | byte temp = data[a]; 10 | data[a] = data[b]; 11 | data[b] = temp; 12 | } 13 | } 14 | 15 | public static String format(long value, String groupSeparator, int groupSizeSmall, int groupSizeLarge) { 16 | byte[] sep = groupSeparator.getBytes(StandardCharsets.UTF_8); 17 | byte sepByte = '_'; 18 | if (sep.length == 1) { 19 | sepByte = sep[0]; 20 | } 21 | String s = format(value, sepByte, groupSizeSmall, groupSizeLarge); 22 | if (sep.length == 1) { 23 | return s; 24 | } 25 | return s.replace("_", groupSeparator); 26 | } 27 | 28 | public static String format(long value, byte groupSeparatorChar, int groupSizeSmall, int groupSizeLarge) { 29 | byte[] buff = new byte[20]; 30 | int group = groupSizeSmall; 31 | int pos = 0; 32 | while (true) { 33 | buff[pos] = (byte) ('0' + (value % 10)); 34 | pos++; 35 | value /= 10; 36 | if (value == 0) { 37 | break; 38 | } 39 | group--; 40 | if (group == 0) { 41 | buff[pos] = groupSeparatorChar; 42 | pos++; 43 | group = groupSizeLarge; 44 | } 45 | } 46 | reverse(buff, pos); 47 | return new String(buff, 0, pos); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/util/Hash.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.util; 2 | 3 | public class Hash { 4 | 5 | public static long hash(long x) { 6 | x = (x ^ (x >>> 33)) * 0xff51afd7ed558ccdL; 7 | x = (x ^ (x >>> 33)) * 0xc4ceb9fe1a85ec53L; 8 | return x ^ (x >>> 33); 9 | } 10 | 11 | public static int reduce(long hash, int n) { 12 | return (int) (((hash & 0xffffffffL) * (n & 0xffffffffL)) >>> 32); 13 | } 14 | 15 | public static long hashCode(byte[] data) { 16 | if (data.length <= 0) { 17 | return 0; 18 | } 19 | long h = data.length << 32; 20 | int i = 0; 21 | if (i < data.length - 3) { 22 | while (true) { 23 | int x = (data[i] & 0xff) | 24 | ((data[i + 1] & 0xff) << 8) | 25 | ((data[i + 2] & 0xff) << 16) | 26 | ((data[i + 3] & 0xff) << 24); 27 | h = (h + x) * 0x9e3779b185ebca87L; 28 | int n = i + 4; 29 | if (n >= data.length) { 30 | break; 31 | } 32 | i = n; 33 | } 34 | } 35 | if (i < data.length && i != data.length - 4) { 36 | int x = 0; 37 | int s = 0; 38 | while (true) { 39 | x ^= (data[i] & 0xff) << s; 40 | s += 8; 41 | int n = i + 1; 42 | if (n >= data.length) { 43 | break; 44 | } 45 | i = n; 46 | } 47 | h = (h + x) * 0x9e3779b185ebca87L; 48 | } 49 | return h ^ (h >>> 32); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/binaryTrees.v: -------------------------------------------------------------------------------- 1 | // The Computer Language Benchmarks Game 2 | // https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import os 5 | 6 | struct Node { 7 | left ?&Node 8 | right ?&Node 9 | } 10 | 11 | fn main() { 12 | mut n := 10 13 | if os.args.len > 1 { 14 | n = os.args[1].int() 15 | } 16 | min_depth := 4 17 | mut max_depth := n 18 | if min_depth + 2 > n { 19 | max_depth = min_depth + 2 20 | } 21 | stretch_depth := max_depth + 1 22 | stretch(stretch_depth) 23 | long_lived := build_tree(max_depth) 24 | for depth := min_depth; depth <= max_depth; depth += 2 { 25 | iterations := 1 << (max_depth - depth + min_depth) 26 | mut sum := 0 27 | for _ in 0 .. iterations { 28 | sum += count(depth) 29 | } 30 | println('${iterations}\t trees of depth ${depth}\t check: ${sum}') 31 | } 32 | println('long lived tree of depth ${max_depth}\t check: ${long_lived.node_count()}') 33 | } 34 | 35 | fn stretch(depth int) { 36 | println('stretch tree of depth ${depth}\t check: ${count(depth)}') 37 | } 38 | 39 | fn count(depth int) int { 40 | return build_tree(depth).node_count() 41 | } 42 | 43 | fn build_tree(depth int) &Node { 44 | if depth == 0 { 45 | return &Node{} 46 | } 47 | return &Node{ 48 | left: build_tree(depth - 1) 49 | right: build_tree(depth - 1) 50 | } 51 | } 52 | 53 | fn (n &Node) node_count() int { 54 | mut result := 1 55 | if n.left != none { 56 | result += n.left.node_count() 57 | } 58 | if n.right != none { 59 | result += n.right.node_count() 60 | } 61 | return result 62 | } 63 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/benchmarks/v/binaryTrees.v: -------------------------------------------------------------------------------- 1 | // The Computer Language Benchmarks Game 2 | // https://salsa.debian.org/benchmarksgame-team/benchmarksgame/ 3 | 4 | import os 5 | 6 | struct Node { 7 | left ?&Node 8 | right ?&Node 9 | } 10 | 11 | fn main() { 12 | mut n := 10 13 | if os.args.len > 1 { 14 | n = os.args[1].int() 15 | } 16 | min_depth := 4 17 | mut max_depth := n 18 | if min_depth + 2 > n { 19 | max_depth = min_depth + 2 20 | } 21 | stretch_depth := max_depth + 1 22 | stretch(stretch_depth) 23 | long_lived := build_tree(max_depth) 24 | for depth := min_depth; depth <= max_depth; depth += 2 { 25 | iterations := 1 << (max_depth - depth + min_depth) 26 | mut sum := 0 27 | for _ in 0 .. iterations { 28 | sum += count(depth) 29 | } 30 | println('${iterations}\t trees of depth ${depth}\t check: ${sum}') 31 | } 32 | println('long lived tree of depth ${max_depth}\t check: ${long_lived.node_count()}') 33 | } 34 | 35 | fn stretch(depth int) { 36 | println('stretch tree of depth ${depth}\t check: ${count(depth)}') 37 | } 38 | 39 | fn count(depth int) int { 40 | return build_tree(depth).node_count() 41 | } 42 | 43 | fn build_tree(depth int) &Node { 44 | if depth == 0 { 45 | return &Node{} 46 | } 47 | return &Node{ 48 | left: build_tree(depth - 1) 49 | right: build_tree(depth - 1) 50 | } 51 | } 52 | 53 | fn (n &Node) node_count() int { 54 | mut result := 1 55 | if n.left != none { 56 | result += n.left.node_count() 57 | } 58 | if n.right != none { 59 | result += n.right.node_count() 60 | } 61 | return result 62 | } 63 | -------------------------------------------------------------------------------- /src/test/resources/org/bau/converter/binaryTree.bau: -------------------------------------------------------------------------------- 1 | fun main() 2 | # or just: stretch(4); creates 31 trees 3 | n : 10 4 | minDepth : 4 5 | maxDepth : n 6 | stretchDepth : maxDepth + 1 7 | stretch(stretchDepth) 8 | longLivedTree := with(maxDepth) 9 | depth := minDepth 10 | while depth <= maxDepth 11 | iterations := 1 << (maxDepth - depth + minDepth) 12 | sum := 0 13 | i := 1 14 | while i <= iterations 15 | sum += count(depth) 16 | i += 1 17 | println(iterations ' trees of depth ' depth '; check: ' sum) 18 | depth += 2 19 | count := longLivedTree.nodeCount() 20 | println('long lived tree of depth ' maxDepth '; check: ' count) 21 | 22 | type Tree 23 | left Tree? 24 | right Tree? 25 | 26 | fun Tree nodeCount() int 27 | result := 1 28 | # not-null conditions can only be on variable currently 29 | # (it is safer: fields values could change) 30 | l := left 31 | if l 32 | result += l.nodeCount() 33 | r := right 34 | if r 35 | result += r.nodeCount() 36 | return result 37 | 38 | fun stretch(depth int) 39 | c := count(depth) 40 | println('stretch tree of depth ' depth '; check: ' c) 41 | 42 | fun count(depth int) int 43 | t := with(depth) 44 | c := t.nodeCount() 45 | return c 46 | 47 | fun with(depth int) Tree 48 | if depth = 0 49 | return Tree(null, null) 50 | return Tree(with(depth - 1), with(depth - 1)) 51 | 52 | ## Expected 53 | stretch tree of depth 11; check: 4095 54 | 1024 trees of depth 4; check: 31744 55 | 256 trees of depth 6; check: 32512 56 | 64 trees of depth 8; check: 32704 57 | 16 trees of depth 10; check: 32752 58 | long lived tree of depth 10; check: 2047 59 | -------------------------------------------------------------------------------- /src/test/java/org/bau/stdlib/graphics/TiffTest.java: -------------------------------------------------------------------------------- 1 | package org.bau.stdlib.graphics; 2 | 3 | import static org.junit.Assert.assertEquals; 4 | 5 | import java.io.File; 6 | import java.io.IOException; 7 | 8 | import org.junit.Test; 9 | 10 | public class TiffTest { 11 | 12 | @Test 13 | public void simple() throws IOException { 14 | int w = 8; 15 | int h = 8; 16 | byte[] imageData = new byte[w * h]; 17 | for (int x = 0; x < w; x++) { 18 | for (int y = 0; y < h; y++) { 19 | imageData[x + y * w] = (byte) (100-y*4); 20 | } 21 | } 22 | File out = new File("target/test.tiff"); 23 | Tiff.writeGrayscaleTiff(imageData, w, h, out); 24 | assertEquals("byte order 4d4d\n" 25 | + "magic 2a\n" 26 | + "offset 8\n" 27 | + "tags 11\n" 28 | + "[a]: tag 100 ImageWidth 4 1 8\n" 29 | + "[16]: tag 101 ImageLength 4 1 8\n" 30 | + "[22]: tag 102 BitsPerSample 3 1 80000\n" 31 | + "[2e]: tag 103 Compression 3 1 ffffffff80050000\n" 32 | + "[3a]: tag 106 PhotometricInterpretation 3 1 10000\n" 33 | + "[46]: tag 111 StripOffsets 4 1 9a\n" 34 | + "[52]: tag 116 RowsPerStrip 4 1 8\n" 35 | + "[5e]: tag 117 StripByteCounts 4 1 10\n" 36 | + "[6a]: tag 11a XResolution 5 1 92\n" 37 | + "[76]: tag 11b YResolution 5 1 92\n" 38 | + "[82]: tag 128 ResolutionUnit 3 1 20000\n" 39 | + "\n" 40 | + "[8e]: 00 00\n" 41 | + "[90]: 00 00 00 00 00 48 00 00 00 01 f9 64 f9 60 f9 5c\n" 42 | + "[a0]: f9 58", Tiff.readTiff(out)); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/test/java/org/bau/traits/Trait.java: -------------------------------------------------------------------------------- 1 | package org.bau.traits; 2 | 3 | import java.util.ArrayList; 4 | import java.util.HashSet; 5 | import java.util.List; 6 | 7 | class Trait { 8 | 9 | // unique id (not really needed) 10 | final int id; 11 | 12 | // trait name 13 | final String name; 14 | 15 | // list of functions 16 | final ArrayList functionList = new ArrayList<>(); 17 | 18 | final ArrayList inherited = new ArrayList<>(); 19 | 20 | // which types use it 21 | final ArrayList usedIn = new ArrayList<>(); 22 | 23 | // two traits in the same type may not occupy the same slot 24 | int slot = -1; 25 | 26 | public Trait(int id, String name, List l2) { 27 | this.id = id; 28 | this.name = name; 29 | this.functionList.addAll(l2); 30 | } 31 | 32 | public void collectAllNonMarkerTraits(HashSet target) { 33 | if (functionList.size() != 0) { 34 | target.add(name); 35 | } 36 | for(Trait t : inherited) { 37 | t.collectAllNonMarkerTraits(target); 38 | } 39 | } 40 | 41 | public String toString() { 42 | StringBuilder buff = new StringBuilder(); 43 | buff.append("trait slot=" + slot + " name=" + name); 44 | if (inherited.size() > 0) { 45 | buff.append(" inherited=" + inherited); 46 | } 47 | buff.append(" methods=" + functionList.size() + " ("); 48 | int i=0; 49 | for(TraitFunction f : functionList) { 50 | if (i++ > 0) { 51 | buff.append(", "); 52 | } 53 | buff.append(f.name); 54 | } 55 | buff.append(") id=" + id); 56 | return buff.toString(); 57 | } 58 | 59 | } --------------------------------------------------------------------------------