Skip to content

Commit

Permalink
Improve README
Browse files Browse the repository at this point in the history
  • Loading branch information
DQNEO committed Jul 29, 2020
1 parent 20de475 commit 33a6b12
Show file tree
Hide file tree
Showing 2 changed files with 79 additions and 15 deletions.
86 changes: 71 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,84 @@
# Babygo: a go compiler made from scratch
# Babygo, a go compiler made from scratch
Babygo is a small and simple go compiler. (Smallest and simplest in the world, I believe.)
It is made from scratch and can compile itself.

* No dependency to any libraries. Standard libraries and calling of system calls are home made.
* Lexer, parser and code generator are hand written.
* Emit assemble code which resutls in a single static binary.

# Target machine
It depends only on `as` as an assembler and `ld` as a linker.

x86-64 Linux
It is composed of only 3 files.

# Test
* main.go - the main compiler
* runtime.go - runtime and standard library
* runtime.s - low level of runtime

```terminal
# Design

## Lexer, Parser and AST
The design and logic of ast, lexer and parser are borrowed (or should I say "stolen") from `go/ast`, `go/scanner` and `go/parser`.

## Code generator
The design of code generator is borrowed from [chibicc](https://github.com/rui314/chibicc) , a C compiler.

## Remaining parts (Semantic analysis, Type management etc.)
This is purely my design :)

# Environment

It supports x86-64 Linux only.

If you are not using Linux, you can use [a dedicated docker image](https://hub.docker.com/r/dqneo/ubuntu-build-essential/tags) for this project.

```termiinal
$ docker pull dqneo/ubuntu-build-essential:go
$ ./docker-run
# make test
```

# How to do self hosting
# Usage

## Hello world

```terminal
$ ./docker-run
# Build babygo
$ go build -o babygo main.go
# Build the hello world program by babygo
$ ./babygo < t/hello.go > /tmp/hello.s
$ as -o hello.o /tmp/hello.s runtime.s
$ ld -o hello hello.o
# go build -o babygo main.go # 1st generation compiler
# ./babygo < main.go > /tmp/babygo2.s
# as -o babygo2.o /tmp/babygo2.s runtime.s
# ld -o babygo2 babygo2.o # 2nd generation compiler
# ./babygo2 < main.go > /tmp/babygo3.s
# diff /tmp/babygo2.s /tmp/babygo3.s # assert babygo2.s and babygo3.s are same.
# You can confirm it's a single static binary
$ ldd ./hello
not a dynamic executable
# Run hello world
$ ./hello
hello world!
```

## How to do self hosting

```terminal
# Build babygo (1st generation)
$ go build -o babygo main.go
# Build babygo by babygo (2nd generation)
$ ./babygo < main.go > /tmp/babygo2.s
$ as -o babygo2.o /tmp/babygo2.s runtime.s
$ ld -o babygo2 babygo2.o # 2nd generation compiler
$ ./babygo2 < main.go > /tmp/babygo3.s
# Assert babygo2.s and babygo3.s are exactly same
$ diff /tmp/babygo2.s /tmp/babygo3.s
```

## Test

```terminal
$ make test
```

# LICENSE
Expand All @@ -31,4 +87,4 @@ MIT

# AUTHOR

@DQNEO
[@DQNEO](https://twitter.com/DQNEO)
8 changes: 8 additions & 0 deletions t/hello.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package main

import "syscall"

func main() {
var msg = []uint8("hello world!\n")
syscall.Write(1, msg)
}

0 comments on commit 33a6b12

Please sign in to comment.