Files
llgo/README.md
xushiwei 5eae8f9af6 README
2024-05-16 00:02:10 +08:00

7.0 KiB
Raw Blame History

llgo - A Go compiler based on LLVM

Build Status Go Report Card GitHub release Coverage Status GoDoc Language

LLGo is a Go compiler based on LLVM in order to better integrate Go with the C ecosystem including Python. It's a subproject of the Go+ project.

C standard libary support

package main

import "github.com/goplus/llgo/c"

func main() {
	c.Printf(c.Str("Hello world\n"))
}

This is a simple example of calling the C printf function to print Hello world. Here, c.Str is not a function for converting a Go string to a C string, but a built-in instruction supported by llgo for generating a C string constant.

The _demo directory contains some C standard libary related demos (it start with _ to prevent the go command from compiling it):

  • hello: call C printf to print Hello world
  • concat: call C fprintf with stderr
  • qsort: call C function with a callback (eg. qsort)

To run these demos (If you haven't installed llgo yet, please refer to How to install):

export LLGOROOT=`pwd`
cd <demo-directory>  # eg. cd _demo/genints
llgo run .

See github.com/goplus/llgo/c for more detials.

Python support

You can import a Python library in LLGo!

And you can import any Python library into llgo through a program called llpyg. The currently imported libraries include:

Here is an example using the Python math library:

package main

import (
	"github.com/goplus/llgo/c"
	"github.com/goplus/llgo/py"
	"github.com/goplus/llgo/py/math"
)

func main() {
	x := math.Sqrt(py.Float(2))
	c.Printf(c.Str("sqrt(2) = %f\n"), x.Float64())
}

Here, We call py.Float(2) to create a Python number 2, and pass it to Pythons math.sqrt to get x. Then use x.Float64() to convert x to Go's float64 type, and print the value through the C printf function.

Let's look at a slightly more complex example. For example, we use numpy to calculate:

package main

import (
	"github.com/goplus/llgo/c"
	"github.com/goplus/llgo/py"
	"github.com/goplus/llgo/py/numpy"
)

func main() {
	a := py.List(
		py.List(1.0, 2.0, 3.0),
		py.List(4.0, 5.0, 6.0),
		py.List(7.0, 8.0, 9.0),
	)
	b := py.List(
		py.List(9.0, 8.0, 7.0),
		py.List(6.0, 5.0, 4.0),
		py.List(3.0, 2.0, 1.0),
	)
	x := numpy.Add(a, b)
	c.Printf(c.Str("a+b = %s\n"), x.Str().CStr())
}

Here we define two 3x3 matrices a and b, add them to get x, and then print the result.

The _pydemo directory contains some python related demos:

  • callpy: call Python standard library function math.sqrt
  • pi: print python constants math.pi
  • statistics: define a python list and call statistics.mean to get the mean
  • matrix: a basic numpy demo

To run these demos, you need to set the LLGO_LIB_PYTHON environment variable first.

If Python is in the search path for clang linking, then LLGO_LIB_PYTHON only needs to be set to the name of the Python library. For example:

export LLGO_LIB_PYTHON=python3.12

You can also specify the path to tell llgo where the Python library is located:

export LLGO_LIB_PYTHON=/foo/bar/python3.12

For example, /opt/homebrew/Frameworks/Python.framework/Versions/3.12/libpython3.12.dylib is a typical python library location under macOS. So we should set it like this:

export LLGO_LIB_PYTHON=/opt/homebrew/Frameworks/Python.framework/Versions/3.12/python3.12

Note that the file name must be written in a platform-independent format, using python3.12 instead of libpython3.12.dylib.

Then you can run the demos:

export LLGOROOT=`pwd`
cd <demo-directory>  # eg. cd _pydemo/callpy
llgo run .

See github.com/goplus/llgo/py for more detials.

Other frequently used libraries

LLGo can easily import any libraries from the C ecosystem. Currently, this import process is still manual, but in the future, it will be automated similar to Python library imports.

The currently imported libraries include:

Here are some examples related to them:

  • llama2-c: inference Llama 2 (It's the first llgo AI example)
  • mkjson: create a json object and print it
  • sqlite: a basic sqlite demo

Go syntax support

The priority of llgo feature iteration is:

  • Popular C/Python libraries
  • Full Go syntax
  • Go standard libraries
  • Popular Go packages

Common Go syntax is already supported. Except for the following, which needs to be improved:

  • interface (Limited support)
  • map (Very limited support)
  • panic (Limited support)
  • recover (Not supported yet)
  • defer (Not supported yet)
  • gc (Not supported yet)
  • chan (Not supported yet)
  • goroutine (Not supported yet)
  • generics (Not supported yet)

Here are some examples related to Go syntax:

  • concat: define a variadic function
  • genints: various forms of closure usage (including C function, recv.method and anonymous function)

How to install

Follow these steps to generate the llgo command (its usage is the same as the go command):

on macOS

brew update  # execute if needed
brew install llvm@17
go install -v ./...

on Linux

echo 'deb http://apt.llvm.org/focal/ llvm-toolchain-focal-17 main' | sudo tee /etc/apt/sources.list.d/llvm.list
wget -O - https://apt.llvm.org/llvm-snapshot.gpg.key | sudo apt-key add -
sudo apt-get update  # execute if needed
sudo apt-get install --no-install-recommends llvm-17-dev
go install -v ./...

on Windows

TODO