Browse Source

Merge pull request #4 from garritfra/llvm-integration

LLVM backend scaffolding
c_for-loops
Garrit Franke 3 years ago committed by GitHub
parent
commit
c39ec1806a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      .builds/ci.yml
  2. 20
      .github/workflows/ci.yml
  3. 3
      .gitignore
  4. 180
      Cargo.lock
  5. 5
      Cargo.toml
  6. 7
      docs/developers/backends.md
  7. 9
      examples/playground.sb
  8. 33
      src/generator/llvm.rs
  9. 21
      src/generator/mod.rs
  10. 1
      src/generator/tests/mod.rs

2
.builds/ci.yml

@ -3,7 +3,7 @@ packages:
- rust
- node
sources:
- https://git.sr.ht/~garritfra/sabre#master
- https://git.sr.ht/~garritfra/sabre
tasks:
- build: |
cargo build

20
.github/workflows/ci.yml

@ -8,6 +8,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install LLVM and Clang
uses: KyleMayes/install-llvm-action@v1
with:
version: "10"
directory: ${{ runner.temp }}/llvm
- uses: actions-rs/toolchain@v1
with:
profile: minimal
@ -22,6 +27,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install LLVM and Clang
uses: KyleMayes/install-llvm-action@v1
with:
version: "10"
directory: ${{ runner.temp }}/llvm
- uses: actions-rs/toolchain@v1
with:
profile: minimal
@ -36,6 +46,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install LLVM and Clang
uses: KyleMayes/install-llvm-action@v1
with:
version: "10"
directory: ${{ runner.temp }}/llvm
- uses: actions-rs/toolchain@v1
with:
profile: minimal
@ -52,6 +67,11 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install LLVM and Clang
uses: KyleMayes/install-llvm-action@v1
with:
version: "10"
directory: ${{ runner.temp }}/llvm
- uses: actions-rs/toolchain@v1
with:
profile: minimal

3
.gitignore vendored

@ -2,4 +2,5 @@ target/
.vscode/
examples_out/
tests_out/
book/
book/
examples/playground.sb

180
Cargo.lock generated

@ -1,5 +1,14 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "aho-corasick"
version = "0.7.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
dependencies = [
"memchr",
]
[[package]]
name = "ansi_term"
version = "0.11.0"
@ -26,12 +35,24 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "cc"
version = "1.0.66"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4c0496836a84f8d0495758516b8621a622beb77c0fed418570e50764093ced48"
[[package]]
name = "cfg-if"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "clap"
version = "2.33.3"
@ -47,13 +68,19 @@ dependencies = [
"vec_map",
]
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "getrandom"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"libc",
"wasi",
]
@ -76,6 +103,41 @@ dependencies = [
"libc",
]
[[package]]
name = "inkwell"
version = "0.1.0-beta.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5fe0be1e47c0c0f3da4397693e08f5d78329ae095c25d529e12ade78420fb41"
dependencies = [
"either",
"inkwell_internals",
"libc",
"llvm-sys",
"once_cell",
"parking_lot",
"regex",
]
[[package]]
name = "inkwell_internals"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2e1f71330ccec54ee62533ae88574c4169b67fb4b95cbb1196a1322582abd11"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "instant"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61124eeebbd69b8190558df225adf7e4caafce0d743919e5d6b19652314ec5ec"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
@ -88,6 +150,65 @@ version = "0.2.81"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
[[package]]
name = "llvm-sys"
version = "100.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9109e19fbfac3458f2970189719fa19f1007c6fd4e08c44fdebf4be0ddbe261d"
dependencies = [
"cc",
"lazy_static",
"libc",
"regex",
"semver",
]
[[package]]
name = "lock_api"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd96ffd135b2fd7b973ac026d28085defbe8983df057ced3eb4f2130b0831312"
dependencies = [
"scopeguard",
]
[[package]]
name = "memchr"
version = "2.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
[[package]]
name = "once_cell"
version = "1.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13bd41f508810a131401606d54ac32a467c97172d74ba7662562ebba5ad07fa0"
[[package]]
name = "parking_lot"
version = "0.11.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb"
dependencies = [
"instant",
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ccb628cad4f84851442432c60ad8e1f607e29752d0bf072cbd0baf28aa34272"
dependencies = [
"cfg-if 1.0.0",
"instant",
"libc",
"redox_syscall",
"smallvec",
"winapi",
]
[[package]]
name = "ppv-lite86"
version = "0.2.10"
@ -183,6 +304,24 @@ version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "regex"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9251239e129e16308e70d853559389de218ac275b515068abc96829d05b948a"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
"thread_local",
]
[[package]]
name = "regex-syntax"
version = "0.6.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5eb417147ba9860a96cfe72a0b93bf88fee1744b5636ec99ab20c1aa9376581"
[[package]]
name = "remove_dir_all"
version = "0.5.3"
@ -228,6 +367,7 @@ dependencies = [
name = "sabre-lang"
version = "0.2.1"
dependencies = [
"inkwell",
"rust-embed",
"structopt",
"tempfile",
@ -242,6 +382,33 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "scopeguard"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
name = "semver"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
dependencies = [
"semver-parser",
]
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
[[package]]
name = "smallvec"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fe0f37c9e8f3c5a4a66ad655a93c74daac4ad00c441533bf5c6e7990bb42604e"
[[package]]
name = "strsim"
version = "0.8.0"
@ -289,7 +456,7 @@ version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
dependencies = [
"cfg-if",
"cfg-if 0.1.10",
"libc",
"rand",
"redox_syscall",
@ -306,6 +473,15 @@ dependencies = [
"unicode-width",
]
[[package]]
name = "thread_local"
version = "1.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd"
dependencies = [
"once_cell",
]
[[package]]
name = "unicode-segmentation"
version = "1.7.1"

5
Cargo.toml

@ -17,10 +17,15 @@ path = "src/main.rs"
[features]
backend_c = []
backend_node = []
backend_llvm = ["inkwell"]
# To change, use the --featues flag:
# cargo run --features backend_llvm
default = ["backend_node"]
[dependencies]
structopt = "0.3.21"
rust-embed = "5.7.0"
tempfile = "3.1.0"
inkwell = { version = "0.1.0-beta.2", features = ["llvm10-0"], optional = true }

7
docs/developers/backends.md

@ -10,9 +10,16 @@ The backend can be specified in the `Cargo.toml` file in the root of the project
default = ["backend_c"]
```
If you're working on an unstable backend, you can override the backend using the `--features` flag of the cargo CLI:
```
cargo run --features backend_llvm ...
```
## Available Backends
| Target Language | Identifier | Stability notice |
| :-------------- | :------------- | :--------------- |
| Node.js | `backend_node` | mostly stable |
| LLVM | `backend_llvm` | unstable |
| C | `backend_c` | unstable |

9
examples/playground.sb

@ -1,9 +0,0 @@
fn main() {
my_print([1, 2, 3])
}
fn my_print(x: int[]) {
for i in x {
println(i)
}
}

33
src/generator/llvm.rs

@ -0,0 +1,33 @@
use crate::generator::Generator;
use crate::parser::node_type::*;
use inkwell::builder::Builder;
use inkwell::context::Context;
use inkwell::module::Module;
use inkwell::targets::{InitializationConfig, Target};
pub struct LLVMGenerator<'ctx> {
ctx: &'ctx Context,
module: Module<'ctx>,
}
impl<'ctx> Generator for LLVMGenerator<'ctx> {
fn generate(prog: Program) -> String {
let ctx = Context::create();
let module = ctx.create_module("main");
let mut generator = LLVMGenerator {
ctx: &ctx,
module: module,
};
for func in prog.func {
generator.generate_function(func);
}
generator.module.print_to_string().to_string()
}
}
impl<'ctx> LLVMGenerator<'ctx> {
fn generate_function(&mut self, func: Function) {
self.module
.add_function(&func.name, self.ctx.void_type().fn_type(&[], false), None);
}
}

21
src/generator/mod.rs

@ -15,8 +15,12 @@
*/
use crate::parser::node_type::*;
#[cfg(feature = "backend_c")]
pub mod c;
#[cfg(feature = "backend_node")]
pub mod js;
#[cfg(feature = "backend_llvm")]
pub mod llvm;
#[cfg(test)]
mod tests;
pub mod x86;
@ -26,11 +30,14 @@ pub trait Generator {
}
pub fn generate(prog: Program) -> String {
if cfg!(feature = "backend_c") {
c::CGenerator::generate(prog)
} else if cfg!(feature = "backend_node") {
js::JsGenerator::generate(prog)
} else {
panic!("No backend specified")
}
#[cfg(feature = "backend_llvm")]
return llvm::LLVMGenerator::generate(prog);
#[cfg(feature = "backend_c")]
return c::CGenerator::generate(prog);
#[cfg(feature = "backend_node")]
return js::JsGenerator::generate(prog);
panic!("No backend specified");
}

1
src/generator/tests/mod.rs

@ -1 +1,2 @@
#[cfg(feature = "backend_c")]
mod c_tests;

Loading…
Cancel
Save