/propane

Intermediate bytecode language

Primary LanguageC++MIT LicenseMIT

Propane Intermediate Language

About Propane

Propane is an intermediate bytecode language that can be executed in an interpreter or cross-compiled into other destination languages. Originally designed to generate C code, Propane can be used to generate any language that supports pointer arithmetics, arrays and structs.

This repository contains an experimental toolchain written in C++ that has a compiler front-end to allow implementation of custom parsers and generators, an interpreter for runtime execution and a cross-compiler to generate C code from Propane assemblies. It also includes a parser for a text representation of the intermediate language to allow writing assemblies by hand for testing purposes.

Typical Propane code can look like this:

method main returns int
	stack
		0: int
		1: int
	end
    
	// Add two numbers and return the result
	set {0} 3
	set {1} 5
    
	add {0} {1}
    
	retv {0}
end

Running this through the provided C translator would yield the following result:

int32_t $main()
{
	int32_t $0s = 3;
	int32_t $1s = 5;
	$0s += $1s;
	return $0s;
}

Propane assemblies are exported as binary blobs that contain all the necessary information for cross compilation including field names, label locations, stack offsets, method signatures etc.

Experimental Toolchain

The experimental toolchain is intended to serve as a proof of concept for the intermediate language. The layout of the toolchain is as following:

alt text

Propane can be parsed from text files or generated by a generator. The resulting intermediate files contain data of defined types/methods and references to declared types/methods. These intermediates can be merged together. The merge implementation is independent, so the merge process between two intermediates can be performed on a seperate thread (at least two intermediates per thread). Intermediates are implemented as binary blobs, which makes it easy for them to be stored on disk to prevent regeneration of unchanged code, or stored as a static library for later.

At the end of the merge process, only one intermediate should remain which contains all definitions. Any missing definitions of types/methods will prevent the intermediate to be linked into an assembly. Like intermediates, an assembly is implemented as a binary blob that can be stored on disk as a file.

Assemblies can be fed into a translator to generate other programming languages or executed by an interpreter.

Resources

Current features

  • Turing-complete stack based reduced instruction set
  • Support for methods, structs, pointers, virtual calls, branches, etc.
  • Interpreter to execute bytecode directly in a runtime
  • Generator that converts assemblies into C code, ready to be compiled to any platform
  • Tools to generate Propane from and to text files via a prototype programming language
  • Call methods from C directly or from dynamic libraries

Potential future additions

  • Strings
  • Alignment and padding
  • Compile time optimization
  • Multithreading

Version history

  • 1.1: Added initial support for loading importing dynamic libraries at runtime.

Motivations

Propane has been conceived as a study project. Propane is intended to be used for building small tools and games. The experimental toolchain has not been tested in professional environments or large projects.

Dependencies

The Propane toolchain requires at least C++17 to build.

The interpreter uses platform specific code to manage protected memory and load dynamic libraries. See the respective source files for implementation details (Windows, Posix).

License

Propane is licensed under the MIT license.