diff --git a/README.md b/README.md
index 5e6878c84a..0bdbe0266b 100644
--- a/README.md
+++ b/README.md
@@ -3,782 +3,209 @@
![CI](https://github.com/AleoHQ/leo/workflows/CI/badge.svg)
[![codecov](https://codecov.io/gh/AleoHQ/leo/branch/master/graph/badge.svg?token=S6MWO60SYL)](https://codecov.io/gh/AleoHQ/leo)
-# Overview
+Leo is a functional, statically-typed programming language built for writing private applications.
-## Compiler Architecture
+## Table of Contents
-
-![~mermaid diagram 1~](/.resources/README-md-1.png)
-
- Mermaid markup
+* [1. Overview](#1-overview)
+* [2. Build Guide](#2-build-guide)
+ * [2.1 Install Rust](#21-install-rust)
+ * [2.2a Build from Crates.io](#22a-build-from-cratesio)
+ * [2.2b Build from Source Code](#22b-build-from-source-code)
+* [3. Quick Start](#3-quick-start)
+* [4. Flying Tour](#4-flying-tour)
+ * [4.1 Functions](#41-functions)
+ * [4.2 Testing](#42-testing)
+ * [4.3 Data Types](#43-data-types)
+ * [4.4 Circuits](#44-circuits)
+ * [4.5 Imports](#45-imports)
+* [5. Contributing](#5-contributing)
+* [6. License](#6-license)
-```mermaid
-graph LR
- Pass1(Syntax Parser) -- ast --> Pass2(Type Resolver)
+
+## 1. Overview
+Welcome to the Leo programming language.
+
+Leo exists to provide a simple high-level language that compiles to a rank one constraint system (R1CS) circuit.
+With Leo, you can write circuits to support zero-knowledge tokens, private stable coins, and decentralized marketplaces.
+
+The syntax of Leo is influenced by JavaScript, Python, Scala, and Rust with a strong emphasis on readability and ease-of-use.
+
+## 2. Build Guide
+
+### 2.1 Install Rust
+
+We recommend installing Rust using [rustup](https://www.rustup.rs/). You can install `rustup` as follows:
+
+- macOS or Linux:
+ ```bash
+ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
+ ```
+
+- Windows (64-bit):
+
+ Download the [Windows 64-bit executable](https://win.rustup.rs/x86_64) and follow the on-screen instructions.
+
+- Windows (32-bit):
+
+ Download the [Windows 32-bit executable](https://win.rustup.rs/i686) and follow the on-screen instructions.
+
+### 2.2a Build from Crates.io
+
+We recommend installing Leo this way. In your terminal, run:
+
+```bash
+cargo install leo
+```
+
+Now to use Leo, in your terminal, run:
+```bash
+leo
+```
+
+### 2.2b Build from Source Code
+
+Alternatively, you can install Leo by building from the source code as follows:
+
+```bash
+# Download the source code
+git clone https://github.com/AleoHQ/leo
+cd leo
+
+# Build in release mode
+$ cargo build --release
+```
+
+This will generate an executable under the `./target/release` directory. To run snarkOS, run the following command:
+```bash
+./target/release/leo
+```
+
+## 3. Quick Start
+
+Use the Leo CLI to create a new project
+
+```bash
+# create a new `hello_world` Leo project
+leo new hello_world
+cd hello_world
+
+# build & setup & prove & verify
+leo run
+```
+
+The `leo new` command creates a new Leo project with a given name.
+
+The `leo run` command will compile the main program, generate keys for a trusted setup, fetch inputs, generate a proof and verify it.
+
+Congratulations! You've just run your first Leo program.
+
+## 4. Flying Tour
+
+The best way to get to know Leo is by writing some code. We will fly through a high level overview of a Leo file.
+To gain a deeper understanding of the Leo language, then check out the [developer documentation](https://developer.aleo.org/developer/getting_started/overview)
+
+
+**Square Root Example**: Let's prove that we know the square root of a number.
+
+**`src/main.leo`**
+```rust // change this to leo
+function main(a: u32, b: u32) -> bool {
+ return square_root(a, b)
+}
+
+function square_root(a: u32, b: u32) -> bool {
+ return a * a == b
+}
+
+test function test_square_root() {
+ let a: u32 = 5;
+ let b: u32 = 25;
- Pass2 -- imports --> Pass3(Import Resolver)
- Pass3 -- statements --> Pass4
-
- Pass2 -- statements --> Pass4(Synthesizer)
-
- Pass4 -- constraints --> Pass5(Program)
-```
+ let result = square_root(a, b);
-
-
-
-## Language Specification
-
-* Programs should be formatted:
- 1. Import definitions
- 2. Circuit definitions
- 3. Function definitions
-
-## Defining Variables
-Leo supports `let` and `const` keywords for variable definition.
-
-```let a = true;``` defines an **allocated** program variable `a` with boolean value `true`.
-
-```const a = true;``` defines a **constant** program variable `a` with boolean value `true`.
-
-**Allocated** variables define private variables in the constraint system. Their value is constrained in the circuit on initialization.
-
-**Constant** variables do not define a variable in the constraint system. Their value is constrained in the circuit on computation with an **allocated** variable.
-**Constant** variables cannot be mutable. They have the same functionality as `const` variables in other languages.
-```js
-function add_one() -> {
- let a = 0u8; // allocated, value enforced on this line
- const b = 1u8; // constant, value not enforced yet
-
- return a + b // allocated, computed value is enforced to be the sum of both values
-}
-```
-Computations are expressed in terms of arithmetic circuits, in particular rank-1 quadratic constraint systems. Thus computing on an allocated variable always results in another allocated variable.
-
-## Mutability
-* All defined variables in Leo are immutable by default.
-* Variables can be made mutable with the `mut` keyword.
-
-```js
-function main() {
- let a = 0u32;
- //a = 1 <- Will fail
-
- let mut b = 0u32;
- b = 1; // <- Ok
+ console.assert(result == true);
}
```
-## Addresses
+### 4.1 Functions
+The `main` function is the entrypoint of a Leo program.
+`leo run` will provide private inputs directly to the function for proving and store the program result in an output file.
-Addresses are defined to enable compiler-optimized routines for parsing and operating over addresses. These semantics will be accompanied by a standard library in a future sprint.
+The `square_root` function is called by `main` with private inputs `a` and `b` which are both unsigned `u32` integers.
-```js
-function main(owner: address) {
- let sender = address(aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8);
- let receiver: address = aleo1qnr4dkkvkgfqph0vzc3y6z2eu975wnpz2925ntjccd5cfqxtyu8sta57j8;
- assert_eq!(owner, sender);
- assert_eq!(sender, receiver);
-}
-```
+### 4.2 Testing
-## Booleans
+A naive way to test `square_root` would be to execute `leo run` several times on different inputs and check the output of the program each time.
-Explicit types are optional.
-```js
-function main() -> bool {
- let a: bool = true || false;
- let b = false && false;
- let c = 1u32 == 1u32;
- return a
-}
-```
+Luckily, we can write unit tests in Leo using the `test function` syntax.
+In `test_square_root` we can sanity check our code without having to load in private inputs from a file every time.
+Want to upgrade your test function into an integration test?
+In Leo you can add a test context annotation that loads different sets of private inputs to make your test suite even more robust.
-## Numbers
-* The definition of a number must include an explicit type.
-* After assignment, you can choose to explicitly add the type or let the compiler interpret implicitly.
-* Type casting is not supported.
-* Comparators are not supported.
+The last line of `test_square_root` uses the console function `console.assert`.
+This function along with `console.log`, `console.debug`, and `console.error` provide developers with tools that are run without
+affecting the underlying constraint system.
-### Integers
-Supported integer types: `u8`, `u16`, `u32`, `u64`, `u128`
-```js
-function main() -> u32 {
- let a = 2u32; // explicit type
- let a: u32 = 1 + 1; // explicit type
-
- let b = a - 1; // implicit type
- let c = b * 4;
- let d = c / 2;
- let e = d ** 3;
- return e
-}
-```
+### 4.3 Data Types
-### Field Elements
-```js
-function main() -> field {
- let a = 1000field; // explicit type
- let a: field = 21888242871839275222246405745257275088548364400416034343698204186575808495617; // explicit type
- let b = a + 1; // implicit type
- let c = b - 1;
- let d = c * 4;
- let e = d / 2;
- return e
-}
-```
+Leo supports boolean, unsigned integer, signed integer, field, group element, and address data types.
+Collections of data types can be created in the form of static arrays and tuples.
-### Group Elements
-An affine point on the elliptic curve passed into the Leo compiler forms a group.
-Leo supports this set as a primitive data type.
+### 4.4 Circuits
-```js
-function main() -> group {
- let a = 1000group; // explicit type
- let a = (21888242871839275222246405745257275088548364400416034343698204186575808495617, 21888242871839275222246405745257275088548364400416034343698204186575808495617)group; // explicit type
- let b = a + 0; // implicit type
- let c = b - 0;
- return c
-}
-```
+**Circuits Example**
-### Operator Assignment Statements
-```js
-function main() -> u32 {
- let mut a = 10;
- a += 5;
- a -= 10;
- a *= 5;
- a /= 5;
- a **= 2;
-
- return a
-}
-```
-
-## Arrays
-Leo supports static arrays with fixed length.
-```js
-function main() -> u32[2] {
- // initialize an integer array with integer values
- let mut a: u32[3] = [1, 2, 3];
-
- // set a mutable member to a value
- a[2] = 4;
-
- // initialize an array of 4 values all equal to 42
- let b = [42u8; 4];
-
- // initialize an array of 5 values copying all elements of b using a spread
- let c = [1, ...b];
-
- // initialize an array copying a slice from `c`
- let d = c[1..3];
-
- // initialize a field array
- let e = [5field; 2];
-
- // initialize a boolean array
- let f = [true, false || true, true];
-
- return d
-}
-```
-
-### Multidimensional Arrays
-```js
-function main() -> u32[3][2] {
- let m = [[0u32, 0u32], [0u32, 0u32]];
-
- let m: u32[3][2] = [[0; 3]; 2];
-
- return m
-}
-```
-
-## Conditionals
-
-Branching in Leo is different than traditional programming languages. Leo developers should keep in mind that every program compiles to a circuit which represents
-all possible evaluations.
-
-### If Else Ternary Expression
-Ternary `if [cond] ? [first] : [second];` expressions are the cheapest form of conditional.
-Since `first` and `second` are expressions, we can resolve their values before proceeding execution.
-In the underlying circuit, this is a single bit multiplexer.
-
-```js
-function main() -> u32 {
- let y = if 3==3 ? 1 : 5;
- return y
-}
-```
-
-### If Else Conditional Statement
-Leo supports the traditional `if [cond] { [first] } else { [second] }` which can be chained using `else if`.
-Since `first` and `second` are one or more statements, they resolve to separate circuits which will all be evaluated.
-In the underlying circuit this can be thought of as a demultiplexer.
-```js
-function main(a: bool, b: bool) -> u32 {
- let mut res = 0u32;
-
- if a {
- res = 1;
- } else if b {
- res = 2;
- } else {
- res = 3;
- }
-
- return res
-}
-```
-
-### For loop
-```js
-function main() -> fe {
- let mut a = 1field;
- for i in 0..4 {
- a = a + 1;
- }
- return a
-}
-```
-
-## Functions
-```js
-function test1(a : u32) -> u32 {
- return a + 1
-}
-
-function test2(b: fe) -> field {
- return b * 2field
-}
-
-function test3(c: bool) -> bool {
- return c && true
-}
-
-function main() -> u32 {
- return test1(5)
-}
-```
-
-
-### Function Scope
-```js
-function foo() -> field {
- // return myGlobal <- not allowed
- return 42field
-}
-
-function main() -> field {
- let myGlobal = 42field;
- return foo()
-}
-```
-
-### Multiple returns
-Functions can return tuples whose types are specified in the function signature.
-```js
-function test() -> (u32, u32[2]) {
- return (1, [2, 3])
-}
-
-function main() -> u32[3] {
- let (a, b) = test();
- // (a, u32[2] b) = test() <- explicit type also works
- return [a, ...b]
-}
-```
-
-### Function inputs
-Main function inputs are allocated private variables in the program's constraint system.
-`a` is implicitly private.
-```js
-function main(a: field) -> field {
- return a
-}
-```
-Normal function inputs are passed by value.
-```js
-function test(mut a: u32) {
- a = 0;
-}
-
-function main() -> u32 {
- let a = 1;
- test(a);
-
- return a // <- returns 1
-}
-```
-
-## Circuits
-Circuits in Leo are similar to classes in object oriented langauges. Circuits are defined above functions in a Leo program. Circuits can have one or more members.
-
-#### Circuit member values
-Members can be defined as fields which hold primitive values.
-```js
+**`src/main.leo`**
+```rust
circuit Point {
- x: u32
- y: u32
-}
-function main() -> u32 {
- let p = Point {x: 1, y: 0};
- return p.x
-}
-```
+ x: u32,
+ y: u32,
-#### Circuit member functions
-Members can also be defined as functions.
-```js
-circuit Foo {
- function echo(x: u32) -> u32 {
- return x
- }
-}
+ static function new() -> Self {
+ return Self {
+ x: 0,
+ y: 0,
+ }
+ }
-function main() -> u32 {
- let c = Foo { };
- return c.echo(1u32)
-}
-```
-
-#### Circuit member static functions
-Circuit functions can be made static, enabling them to be called without instantiation.
-```js
-circuit Foo {
- static function echo(x: u32) -> u32 {
- return x
- }
-}
-
-function main() -> u32 {
- return Foo::echo(1u32)
-}
-```
-
-#### `Self` and `self`
-The `Self` keyword is supported in circuit functions.
-```js
-circuit Circ {
- b: bool
-
- static function new() -> Self { // Self resolves to Foo
- return Self { b: true }
+ function add() -> u32 {
+ return self.x + self.y
}
}
-function main() -> bool {
- let c = Foo::new();
- return c.b
-}
-```
-
-The `self` keyword references the circuit's members.
-```rust
-circuit Foo {
- b: bool
-
- function bar() -> bool {
- return self.b
- }
+function main() {
+ let mut p = Point::new();
- function baz() -> bool {
- return self.bar()
- }
-}
+ p.x = 4u32;
+ p.y = 6u32;
-function main() -> bool {
- let c = Foo { b: true };
-
- return c.baz()
+ let sum = p.add();
+
+ console.log("The sum is {}", sum);
}
```
+Circuits in leo are similar to structures in other object-oriented languages.
+They provide a composite data type that can store primitive values and provide functions for instantiation and computation.
-## Imports
-Leo supports importing functions
-}
-} and circuits by name into the current file with the following syntax:
+The `static` keyword modifies the `new` function so it can be called without instantiating the circuit.
-```js
-import [package].[name];
-```
+Leo introduces `Self` and `self` keywords to access circuit member values.
-#### Import Aliases
-To import a name using an alias:
-```js
-import [package].[name] as [alias];
-```
+### 4.5 Imports
-#### Import Multiple
-To import multiple names from the same package:
-```js
-import [package].(
- [name_1],
- [name_2] as [alias],
-);
-```
+Imports fetch other circuits and functions and bring them into the current file scope.
+Leo supports imports for dependencies that are declared locally or in an imported package.
-#### Import Star
-To import all symbols from a package:
-Note that this will only import symbols from the package library `lib.leo` file.
-```js
-import [package].*;
-```
+Importing packages can be accomplished using the `leo add` command in the CLI.
-### Local
-You can import from a local file in the same package using its direct path.
-`src/` directory by using its `[file].leo` as the `[package]` name.
+## 5. Contributing
+
+Please see our guidelines in the [developer documentation](https://developer.aleo.org/developer/additional_material/contributing)
-```js
-import [file].[name];
-```
+Thank you for helping make Leo better!
-#### Example:
-`src/bar.leo`
-```js
-circuit Bar {
- b: u32
-}
-function baz() -> u32 {
- return 1u32
-}
-```
-
-`src/main.leo`
-```js
-import bar.(
- Bar,
- baz
-);
-
-function main() {
- const bar = Bar { b: 1u32};
- const z = baz();
-}
-```
-
-### Foreign
-You can import from a foreign package in the `imports/` directory using its `[package]` name.
-```js
-import [package].[name];
-```
-
-#### Example:
-`imports/bar/src/lib.leo`
-```js
-circuit Bar {
- b: u32
-}
-```
-
-`src/main.leo`
-```js
-import bar.Bar;
-
-function main() {
- const bar = Bar { b: 1u32 };
-}
-```
-
-### Package Paths
-Leo treats directories as package names when importing.
-```js
-import [package].[directory].[file].[name]
-```
-
-#### Example:
-We wish to import the `Baz` circuit from the `baz.leo` file in the `bar` directory in the `foo` package
-
-
-`imports/foo/src/bar/baz.leo`
-```js
-circuit Baz {
- b: u32
-}
-```
-
-`src/main.leo`
-```js
-import foo.bar.baz.Baz;
-
-function main() {
- const baz = Baz { b: 1u32 };
-}
-```
-
-## Constraints
-
-### Assert Equals
-This will enforce that the two values are equal in the constraint system.
-
-```js
-function main() {
- assert_eq!(45, 45);
-
- assert_eq!(2fe, 2fe);
-
- assert_eq!(true, true);
-}
-```
-
-## Testing
-
-Use the `test` keyword to add tests to a leo program. Tests must have 0 function inputs and 0 function returns.
-
-```js
-function main(a: u32) -> u32 {
- return a
-}
-
-test function expect_pass() {
- let a = 1u32;
-
- let res = main(a);
-
- assert_eq!(res, 1u32);
-}
-
-test function expect_fail() {
- assert_eq!(1u8, 0u8);
-}
-```
-
-## Logging
-
-Leo supports `print!`, `debug!`, and `error!` logging macros.
-
-The first argument a macro receives is a format string. This must be a string literal. The power of the formatting string is in the `{}`s contained.
-
-Additional parameters passed to a macro replace the `{}`s within the formatting string in the order given.
-
-#### `print!`
-Directly calls the `println!` macro in rust.
-```js
-function main(a: u32) {
- print!("a is {}", a);
-}
-```
-
-#### `debug!`
-Enabled by specifying the `-d` flag after a Leo command.
-```js
-function main(a: u32) {
- debug!("a is {}", a);
-}
-```
-
-
-#### `error!`
-Prints the error to console.
-```js
-function main(a: u32) {
- error!("a is {}", a);
-}
-```
-
-# Leo Inputs
-
-Private inputs for a Leo program are specified in the `inputs/` directory. The syntax for an input file is a limited subset of the Leo program syntax. The default inputs file is `inputs/inputs.leo`.
-
-## Sections
-A Leo input file is made up of sections. Sections are defined by a section header in brackets followed by one or more input definitions.
-
-Section headers specify the target file which must have a main function with matching input names and types.
-
-`inputs/inputs.leo`
-
-```rust
-[main] // <- section header
-a: u32 = 1;
-b: u32 = 2;
-```
-
-`src/main.leo`
-
-```rust
-function main(a: u32, b: u32) -> u32 {
- let c: u32 = a + b;
- return c
-}
-```
-
-## Input Definitions
-
-### Supported types
-```rust
-[main]
-a: bool = true; // <- booleans
-b: u8 = 2; // <- integers
-c: field = 0; // <- fields
-d: group = (0, 1)group // <- group tuples
-```
-
-### Arrays
-```rust
-[main]
-a: u8[4] = [0u8; 4]; // <- single
-b: u8[2][3] = [[0u8; 2]; 3]; // <- multi-dimensional
-```
-
-# Leo CLI
-
-## Develop
-
-### `leo new`
-
-To setup a new package, run:
-```
-leo new {$NAME}
-```
-This will create a new directory with a given package name. The new package will have a directory structure as follows:
-```
-- inputs # Your program inputs
- - inputs.leo # Your program inputs for main.leo
-- outputs # Your program outputs
-- src
- - main.leo # Your program
-- tests
- - test.leo # Your program tests
-- Leo.toml # Your program manifest
-```
-
-#### Flags
-```rust
-leo new {$Name} --bin
-```
-This will create a new directory with a given package name. The new package will have a directory structure as above.
-
-```rust
-leo new {$Name} --lib
-```
-This will create a new directory with a given package name. The new package will have a directory structure as follows:
-```
-- src
- - lib.leo # Your program library
-- Leo.toml # Your program manifest
-```
-
-### `leo init`
-
-To initialize an existing directory, run:
-```
-leo init
-```
-This will initialize the current directory with the same package directory setup.
-
-#### Flags
-`leo init` supports the same flags as `leo new`
-```rust
-leo init --bin
-```
-```rust
-leo init --lib
-```
-
-
-### `leo build`
-
-To compile your program and verify that it builds properly, run:
-```
-leo build
-```
-
-### `leo test`
-
-To execute unit tests on your program, run:
-```
-leo test
-```
-The results of test compilation and the constraint system will be printed:
-```
- INFO leo Running 2 tests
- INFO leo test language::expect_pass compiled. Constraint system satisfied: true
-ERROR leo test language::expect_fail errored: Assertion 1u8 == 0u8 failed
-```
-
-## Run
-
-### `leo setup`
-
-To perform the program setup, producing a proving key and verification key, run:
-```
-leo setup
-```
-Leo uses cryptographic randomness from your machine to perform the setup. The proving key and verification key are stored in the `target` directory as `.leo.pk` and `.leo.vk`:
-
-```
-{$LIBRARY}/target/{$PROGRAM}.leo.pk
-{$LIBRARY}/target/{$PROGRAM}.leo.vk
-```
-
-### `leo prove`
-
-To execute the program and produce an execution proof, run:
-```
-leo prove
-```
-Leo starts by checking the `target` directory for an existing `.leo.pk` file. If it doesn't exist, it will proceed to run `leo setup` and then continue.
-
-Next any input files in the `inputs` directory are parsed and all input values are passed to the program.
-
-Once again, Leo uses cryptographic randomness from your machine to produce the proof. The proof is stored in the `target` directory as `.leo.proof`:
-
-```
-{$LIBRARY}/target/{$PROGRAM}.leo.proof
-```
-
-### `leo verify`
-
-To verify the program proof, run:
-```
-leo verify
-```
-Leo starts by checking the `target` directory for an existing `.leo.proof` file. If it doesn't exist, it will proceed to run `leo prove` and then continue.
-
-After the verifier is run, Leo will output either `true` or `false` based on the verification.
-
-## Remote
-
-To use remote compilation features, start by authentication with:
-```
-leo login
-```
-You will proceed to authenticate using your username and password. Next, Leo will parse your `Leo.toml` file for `remote = True` to confirm whether remote compilation is enabled.
-
-If remote compilation is enabled, Leo syncs your workspace so when you run `leo build`, `leo test`, `leo setup` and `leo prove`, your program will run the program setup and execution performantly on remote machines.
-
-This speeds up the testing cycle and helps the developer to iterate significantly faster.
-
-## Publish
-
-To package your program as a gadget and publish it online, run:
-```
-leo publish
-```
-Leo will proceed to snapshot your directory and upload your directory to the circuit manager. Leo will verify that `leo build` succeeds and that `leo test` passes without error.
-
-If your gadget name has already been taken, `leo publish` will fail.
-
-## Deploy
-
-To deploy your program to Aleo, run:
-```
-leo deploy
-```
-
-# Install
-
-To install Leo from source, in the root directory of the repository, run:
-```
-cargo install --path .
-```
-
-## TODO
-
-- Change `target` directory to some other directory to avoid collision.
-- Figure out how `leo prove` should take in assignments.
-- Come up with a serialization format for `.leo.pk`, `.leo.vk`, and `.leo.proof`.
+## 6. License
+[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](./LICENSE.md)
\ No newline at end of file