Ball in Action

Explore real Ball programs and see how they compile to different target languages.

Ball programs are stored as Protocol Buffers (binary or JSON). Shown here as YAML for readability.

Hello World

The simplest Ball program β€” prints a message to the console using the std.print base function.

Ball Program

hello_world.ball.yamlyaml
name: hello_world
modules:
  -
    name: main
    functions:
      -
        name: main
        body:
          call:
            module: std
            function: print
            input:
              messageCreation:
                typeName: PrintInput
                fields:
                  -
                    name: message
                    value:
                      literal:
                        { stringValue: Hello, World! }
        metadata:
          { kind: function }
    moduleImports:
      -
        { name: std }
entryModule: main
entryFunction: main

Compiled Output

Compiled β†’ Dartdart
void main() {
  print('Hello, World!');
}

Fibonacci

A recursive Fibonacci implementation demonstrating control flow (if), comparison (lte), arithmetic (add, subtract), and function recursion.

Ball Program

fibonacci.ball.yamlyaml
name: fibonacci
modules:
  -
    name: main
    functions:
      -
        name: fibonacci
        inputType: int
        outputType: int
        body:
          block:
            statements:
              -
                expression:
                  call:
                    module: std
                    function: if
                    input:
                      messageCreation:
                        typeName: ""
                        fields:
                          -
                            name: condition
                            value:
                              call:
                                module: std
                                function: lte
                                input:
                                  messageCreation:
                                    typeName: ""
                                    fields:
                                      -
                                        name: left
                                        value:
                                          reference:
                                            { name: n }                                      -
                                        name: right
                                        value:
                                          literal:
                                            { intValue: "1" }                          -
                            name: then
                            value:
                              call:
                                module: std
                                function: return
                                input:
                                  messageCreation:
                                    typeName: ""
                                    fields:
                                      -
                                        name: value
                                        value:
                                          reference:
                                            { name: n }
            result:
              call:
                module: std
                function: add
                input:
                  messageCreation:
                    typeName: ""
                    fields:
                      -
                        name: left
                        value:
                          call:
                            function: fibonacci
                            input:
                              call:
                                module: std
                                function: subtract
                                input:
                                  messageCreation:
                                    typeName: ""
                                    fields:
                                      -
                                        name: left
                                        value:
                                          reference:
                                            { name: n }                                      -
                                        name: right
                                        value:
                                          literal:
                                            { intValue: "1" }                      -
                        name: right
                        value:
                          call:
                            function: fibonacci
                            input:
                              call:
                                module: std
                                function: subtract
                                input:
                                  messageCreation:
                                    typeName: ""
                                    fields:
                                      -
                                        name: left
                                        value:
                                          reference:
                                            { name: n }                                      -
                                        name: right
                                        value:
                                          literal:
                                            { intValue: "2" }
        metadata:
          kind: function
          params:
            -
              name: n
              type: int      -
        name: main
        body:
          block:
            statements:
              -
                let:
                  name: result
                  value:
                    call:
                      function: fibonacci
                      input:
                        literal:
                          { intValue: "10" }
                  metadata:
                    { keyword: final }              -
                expression:
                  call:
                    module: std
                    function: print
                    input:
                      messageCreation:
                        typeName: PrintInput
                        fields:
                          -
                            name: message
                            value:
                              call:
                                module: std
                                function: to_string
                                input:
                                  messageCreation:
                                    typeName: ""
                                    fields:
                                      -
                                        name: value
                                        value:
                                          reference:
                                            { name: result }
        metadata:
          { kind: function }
    moduleImports:
      -
        { name: std }
entryModule: main
entryFunction: main

Compiled Output

Compiled β†’ Dartdart
int fibonacci(int n) {
  if ((n <= 1)) {
    return n;
  }
  return (fibonacci((n - 1)) + fibonacci((n - 2)));
}

void main() {
  final result = fibonacci(10);
  print(result.toString());
}

Try it yourself

All examples are in the examples/ directory of the repository:

# List available examples
ls examples/
# β†’ all_constructs/  comprehensive/  fibonacci/  hello_world/

# Compile any example to Dart
cd dart/compiler
dart run bin/compile.dart \
  ../../examples/fibonacci/fibonacci.ball.json

# Run with the Ball engine (interpreter)
cd ../engine
dart run bin/run.dart \
  ../../examples/hello_world/hello_world.ball.json

# Encode Dart source to Ball
cd ../encoder
dart run bin/encode.dart some_file.dart