Bridge – Programming Language Platform

Bridge enables language implementations to re-use each other’s code and enables code sharing between different languages.

Use Cases

Language Development

  • Re-use language features that already exist in the platform
  • Extensible module system that also allows your language to import code from non-Bridge code via importer plugins
  • IDE integration (autocompletion work-in-progress, refactoring planned) with minimal work planned
  • EDSLs (Embedded Domain Specific Languages) to embed another language that exists in the platform inside your own (regex, state machines, SQL) planned
  • Because your users will receive everything mentioned below =)

Application Development

  • Use non-Bridge code effortlessly (for example calling into Java to build a native Android app)
  • Bridge code may be embedded in web applications by using the Webpack Bridge loader
  • Integration with multiple IDEs planned
  • REPL (read eval print loop) tool planned
  • Better languages. When people are able to collaborate, you can expect better results

Examples

WebAssembly + Webpack Demo

This example shows Bridge code included inside a Webpack project and called from Javascript. This uses the Bridge Webpack loader, which compiles the Bridge module into a WebAssembly module, and then generates Javascript bindings. Javascript can include the Bridge module like any other module using require/import. See the full example for more details.

bridge-module.bex:

export func getAnswerToLifeTheUniverseAndEverything() -> Integer32 {
    return 42
}

index.js:

import bridgeModule from './bridge-module.bex';

console.log(bridgeModule.getAnswerToLifeTheUniverseAndEverything());

Basic Android App

This example shows how you can build a native Android app using a Bridge language. It uses Bridge’s JVM plugin to import Java classes using the JNI. It also uses Bridge’s Gradle plugin in order to include Bridge code inside of a Gradle build. See the full example for more details.

main.bex:

import java.lang.Object from java as Object
import android.app.Activity from java as Activity
import android.os.Bundle from java as Bundle
import android.util.Log from java as Log
import android.widget.FrameLayout from java as FrameLayout
import android.widget.TextView from java as TextView

import stdio from c


class BridgeActivity extends Activity {
    func onCreate(savedInstanceState : Bundle) {
        Activity.onCreate(self, savedInstanceState)
        Log.d("bridge", "onCreate called")

        var layout = FrameLayout(self)
        var textView = TextView(self)
        textView.setText("Hello from Bridge!")

        layout.addView(textView)

        self.setContentView(layout)
    }
}

Python using C compiled code

This code shows Python code using C code by using the C importer.
Importing C code works in any Bridge language that uses concepts that are compatible with C.

stdio = bridge_import('c', 'stdio.h')
stdio.printf('Hello world')

Architecture

For a more in-depth explanation and tutorials, please see Bridge’s wiki.

The following figure shows Bridge’s different code representations (in black) and compilation phases (in blue):

AST Representation

ASTs (Abstract Syntax Trees) are data structures that describe source code that has been parsed. They are a part of (almost?) every compiler. ASTs abstract away the syntax of the language, and leave you with its concepts like loops, classes, and so on. Read this page to learn more about ASTs in general.

Unlike regular ASTs, in Bridge the AST is extensible. Meaning that new AST node types may be added to the platform. The only requirement is that the node types inherit from the abstract base class bridge.ast.Node.

Parse Phase

The parse phase is responsible for taking source code and generating AST nodes. Bridge searches for a compatible parser plugin, and calls it to parse the code and generate the AST. The parser plugin may parse the code in any way it sees fit. It may generate existing node types or create new ones according to its needs.

Evaluation Phase

The evaluation phase is responsible for giving semantics to AST nodes. During the evaluation phase, an AST evaluator plugin is searched that supports the AST nodes generated by the parser. The AST evaluator is then given the AST nodes, and generates BIR instructions.

Included in this phase is also a compile-time object framework that provides standard interfaces between different objects. For example it allows us to get a property from a Java object and a C struct in a uniform way, so that when our code uses . notation (in Python for example) the AST evaluator doesn’t need to know how to get the property. It only needs to know that the object supports the PropertyContainer interface.

While this phase is mostly used to generate BIR instructions, it is also used to analyze code (for example for autocompletion).

Read the evaluation wiki page for more details.

BIR (Bridge Intermediate Representation)

The BIR is designed to be easy to generate. It supports basic C features, but also more high level language features like coroutines (work-in-progress) and exceptions (planned). Previously the evaluation phase used to generate LLVM IR directly, but I found that LLVM IR is not easy to learn and generate. LLVM IR is great for analysis, optimization and code generation, but I didn’t want everyone who adds to the evaluation phase to need to learn it.

How can I help?

For a little over 2 years I’ve been developing Bridge, in my spare time. I’ve left my job a few months ago, and I’m now devoting all my time to Bridge (and Clash Royale). Bridge is not yet ready for real world use, but I want to get it to that point as fast as possible. There are still language features we need to add, better support for a real existing language (probably Python), IDE integrations, and more. If you’d like to help, either by re-sharing this post, reporting issues, or even developing, it’d be awesome!

The code is open source and hosted on GitLab. You can view the issues to see what is currently being worked on and what needs to be done. You can email me at talzion12@gmail.com, or join the Google+ community!

Thanks!