Compile to LLVM bitcode
This commit is contained in:
parent
d674c92199
commit
fdb0a266b1
9 changed files with 200 additions and 16 deletions
15
.gitignore
vendored
15
.gitignore
vendored
|
@ -1,14 +1,5 @@
|
|||
_build
|
||||
|
||||
|
||||
|
||||
# Added by cargo
|
||||
|
||||
result*
|
||||
/target
|
||||
|
||||
|
||||
# Added by cargo
|
||||
#
|
||||
# already existing elements were commented out
|
||||
|
||||
#/target
|
||||
*.bc
|
||||
*.ll
|
||||
|
|
76
Cargo.lock
generated
76
Cargo.lock
generated
|
@ -64,6 +64,12 @@ version = "1.3.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2fff2a6927b3bb87f9595d67196a70493f627687a71d87a0d692242c33f58c11"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
|
@ -139,6 +145,7 @@ version = "0.1.0"
|
|||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
"inkwell",
|
||||
"lalrpop",
|
||||
"lalrpop-util",
|
||||
]
|
||||
|
@ -206,6 +213,29 @@ dependencies = [
|
|||
"hashbrown",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inkwell"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/TheDan64/inkwell?branch=master#36c3b106e61b1b45295a35f94023d93d9328c76f"
|
||||
dependencies = [
|
||||
"either",
|
||||
"inkwell_internals",
|
||||
"libc",
|
||||
"llvm-sys",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "inkwell_internals"
|
||||
version = "0.5.0"
|
||||
source = "git+https://github.com/TheDan64/inkwell?branch=master#36c3b106e61b1b45295a35f94023d93d9328c76f"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.3"
|
||||
|
@ -259,6 +289,19 @@ version = "0.2.121"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "efaa7b300f3b5fe8eb6bf21ce3895e1751d9665086af2d64b42f19701015ff4f"
|
||||
|
||||
[[package]]
|
||||
name = "llvm-sys"
|
||||
version = "120.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ce76f8393b7a607a906087666db398d872db739622e644e58552c198ccdfdf45"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"regex",
|
||||
"semver",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.7"
|
||||
|
@ -328,6 +371,15 @@ dependencies = [
|
|||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pest"
|
||||
version = "2.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "10f4872ae94d7b90ae48754df22fd42ad52ce740b8f370b03da4835417403e53"
|
||||
dependencies = [
|
||||
"ucd-trie",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "petgraph"
|
||||
version = "0.5.1"
|
||||
|
@ -450,6 +502,24 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6"
|
||||
dependencies = [
|
||||
"semver-parser",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver-parser"
|
||||
version = "0.10.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0bef5b7f9e0df16536d3961cfb6e84331c065b4066afb39768d0e319411f7"
|
||||
dependencies = [
|
||||
"pest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
version = "0.3.10"
|
||||
|
@ -547,6 +617,12 @@ dependencies = [
|
|||
"crunchy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ucd-trie"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56dee185309b50d1f11bfedef0fe6d036842e3fb77413abef29f8f8d1c5d4c1c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.2"
|
||||
|
|
|
@ -8,5 +8,10 @@ anyhow = "1.0.56"
|
|||
clap = { version = "3.1.8", features = ["derive"] }
|
||||
lalrpop-util = { version = "0.19.7", features = ["lexer"] }
|
||||
|
||||
[dependencies.inkwell]
|
||||
git = "https://github.com/TheDan64/inkwell"
|
||||
branch = "master"
|
||||
features = ["llvm12-0"]
|
||||
|
||||
[build-dependencies]
|
||||
lalrpop = "0.19.7"
|
||||
|
|
15
default.nix
Normal file
15
default.nix
Normal file
|
@ -0,0 +1,15 @@
|
|||
{ rustPlatform, lib, nix-gitignore, llvmPackages_12 }:
|
||||
|
||||
let llvmPkgs = llvmPackages_12;
|
||||
|
||||
in with llvmPkgs;
|
||||
|
||||
rustPlatform.buildRustPackage {
|
||||
name = "e0";
|
||||
src = nix-gitignore.gitignoreSource [ ./.gitignore ] ./.;
|
||||
|
||||
buildInputs = [ llvmPkgs.llvm.dev ];
|
||||
|
||||
cargoSha256 = lib.fakeSha256;
|
||||
# cargoSha256 = "sha256-rWMnlkb/XoycP69NOOmg7Wd4qPgliuvOKGWaEth/8tg=";
|
||||
}
|
41
flake.lock
Normal file
41
flake.lock
Normal file
|
@ -0,0 +1,41 @@
|
|||
{
|
||||
"nodes": {
|
||||
"nixpkgs": {
|
||||
"locked": {
|
||||
"lastModified": 1648219316,
|
||||
"narHash": "sha256-Ctij+dOi0ZZIfX5eMhgwugfvB+WZSrvVNAyAuANOsnQ=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "30d3d79b7d3607d56546dd2a6b49e156ba0ec634",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"id": "nixpkgs",
|
||||
"type": "indirect"
|
||||
}
|
||||
},
|
||||
"root": {
|
||||
"inputs": {
|
||||
"nixpkgs": "nixpkgs",
|
||||
"utils": "utils"
|
||||
}
|
||||
},
|
||||
"utils": {
|
||||
"locked": {
|
||||
"lastModified": 1648297722,
|
||||
"narHash": "sha256-W+qlPsiZd8F3XkzXOzAoR+mpFqzm3ekQkJNa+PIh1BQ=",
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"rev": "0f8662f1319ad6abf89b3380dd2722369fc51ade",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "numtide",
|
||||
"repo": "flake-utils",
|
||||
"type": "github"
|
||||
}
|
||||
}
|
||||
},
|
||||
"root": "root",
|
||||
"version": 7
|
||||
}
|
16
flake.nix
Normal file
16
flake.nix
Normal file
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
description = "A very basic flake";
|
||||
|
||||
inputs = { utils.url = "github:numtide/flake-utils"; };
|
||||
|
||||
outputs = { self, nixpkgs, utils }:
|
||||
utils.lib.eachDefaultSystem (system:
|
||||
let
|
||||
pkgs = nixpkgs.legacyPackages.${system};
|
||||
myPkgs = rec { e0 = pkgs.callPackage ./. { }; };
|
||||
|
||||
in rec {
|
||||
packages = utils.lib.flattenTree myPkgs;
|
||||
defaultPackage = packages.e0;
|
||||
});
|
||||
}
|
30
src/ast.rs
30
src/ast.rs
|
@ -1,10 +1,20 @@
|
|||
use anyhow::Result;
|
||||
use inkwell::{context::Context, module::Module};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Decl {
|
||||
Func(Func),
|
||||
}
|
||||
|
||||
impl Decl {
|
||||
pub fn unwrap_func(&self) -> Option<&Func> {
|
||||
match self {
|
||||
Decl::Func(func) => Some(func),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Func {
|
||||
pub name: String,
|
||||
|
@ -27,6 +37,22 @@ pub enum Type {
|
|||
Int,
|
||||
}
|
||||
|
||||
pub fn convert(program: Vec<Decl>) -> Result<String> {
|
||||
Ok(String::new())
|
||||
pub fn convert(context: &mut Context, program: Vec<Decl>) -> Result<Module> {
|
||||
let module = context.create_module("program");
|
||||
let builder = context.create_builder();
|
||||
|
||||
for func in program.iter().filter_map(Decl::unwrap_func) {
|
||||
// TODO: hardcoded void -> int function
|
||||
let i64_ty = context.i64_type();
|
||||
let llvm_func_ty = i64_ty.fn_type(&[], false);
|
||||
|
||||
let llvm_func = module.add_function(&func.name, llvm_func_ty, None);
|
||||
let entry_block = context.append_basic_block(llvm_func, "entry");
|
||||
|
||||
builder.position_at_end(entry_block);
|
||||
|
||||
builder.build_return(None);
|
||||
}
|
||||
|
||||
Ok(module)
|
||||
}
|
||||
|
|
15
src/main.rs
15
src/main.rs
|
@ -7,17 +7,21 @@ lalrpop_mod!(parser);
|
|||
|
||||
mod ast;
|
||||
|
||||
use std::fs;
|
||||
use std::fs::{self, File};
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::Result;
|
||||
use clap::Parser;
|
||||
use inkwell::context::Context;
|
||||
|
||||
use crate::parser::ProgramParser;
|
||||
|
||||
#[derive(Debug, Parser)]
|
||||
struct Opt {
|
||||
path: PathBuf,
|
||||
|
||||
#[clap(short = 'o', long = "out")]
|
||||
out_path: PathBuf,
|
||||
}
|
||||
|
||||
fn main() -> Result<()> {
|
||||
|
@ -29,5 +33,14 @@ fn main() -> Result<()> {
|
|||
let ast = parser.parse(&contents).unwrap();
|
||||
println!("AST: {ast:?}");
|
||||
|
||||
let mut context = Context::create();
|
||||
let module = ast::convert(&mut context, ast)?;
|
||||
|
||||
{
|
||||
let file = File::create(&opts.out_path)?;
|
||||
module.write_bitcode_to_file(&file, true, true);
|
||||
println!("Emitted.");
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -9,7 +9,8 @@ Decl: Decl = {
|
|||
};
|
||||
|
||||
Func: Func = {
|
||||
"fn" <name:Ident> "(" ")" "->" <return_ty:Type> "{" <stmts:Stmt*> "}" => Func { name, return_ty, stmts },
|
||||
"fn" <name:Ident> "(" ")" "->" <return_ty:Type> "{" <stmts:Stmt*> "}" =>
|
||||
Func { name, return_ty, stmts },
|
||||
};
|
||||
|
||||
Stmt: Stmt = {
|
||||
|
|
Loading…
Reference in a new issue