Remove inkwell since we don't need it for the interpreter anymore

This commit is contained in:
Sameer Rahmani 2020-10-30 20:49:35 +00:00
parent cf1a1241c8
commit b1b7163c81
15 changed files with 31 additions and 634 deletions

327
Cargo.lock generated
View File

@ -1,14 +1,5 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
[[package]]
name = "aho-corasick"
version = "0.7.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b476ce7103678b0c6d3d395dbbae31d48ff910bd28be979ba5d48c6351131d0d"
dependencies = [
"memchr",
]
[[package]]
name = "atty"
version = "0.2.14"
@ -32,24 +23,6 @@ version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
[[package]]
name = "cc"
version = "1.0.61"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed67cbde08356238e75fc4656be4749481eeffb09e19f320a25237d5221c985d"
[[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 = "ci_info"
version = "0.10.2"
@ -92,21 +65,6 @@ dependencies = [
"syn",
]
[[package]]
name = "cloudabi"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4344512281c643ae7638bbabc3af17a11307803ec8f0fcad9fae512a8bf36467"
dependencies = [
"bitflags",
]
[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
[[package]]
name = "envmnt"
version = "0.8.4"
@ -132,17 +90,6 @@ dependencies = [
"unicode-width",
]
[[package]]
name = "getrandom"
version = "0.1.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc587bc0ec293155d5bfa6b9891ec18a1e330c234f896ea47fbada4cadbe47e6"
dependencies = [
"cfg-if 0.1.10",
"libc",
"wasi",
]
[[package]]
name = "hashbrown"
version = "0.9.1"
@ -177,39 +124,6 @@ dependencies = [
"hashbrown",
]
[[package]]
name = "inkwell"
version = "0.1.0"
source = "git+https://github.com/TheDan64/inkwell?branch=llvm10-0#79070d9fbb0e7ed1c96c7133273770dc2e000a88"
dependencies = [
"either",
"inkwell_internals",
"libc",
"llvm-sys",
"once_cell",
"parking_lot",
"regex",
]
[[package]]
name = "inkwell_internals"
version = "0.2.0"
source = "git+https://github.com/TheDan64/inkwell?branch=llvm10-0#79070d9fbb0e7ed1c96c7133273770dc2e000a88"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "instant"
version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cb1fc4429a33e1f80d41dc9fea4d108a88bec1de8053878898ae448a0b52f613"
dependencies = [
"cfg-if 1.0.0",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
@ -228,128 +142,18 @@ version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a"
[[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.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28247cc5a5be2f05fbcd76dd0cf2c7d3b5400cb978a28042abcd4fa0b3f8261c"
dependencies = [
"scopeguard",
]
[[package]]
name = "memchr"
version = "2.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3728d817d99e5ac407411fa471ff9800a778d88a24685968b36824eaf4bee400"
[[package]]
name = "nias"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab250442c86f1850815b5d268639dff018c0627022bc1940eb2d642ca1ce12f0"
[[package]]
name = "once_cell"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "260e51e7efe62b592207e9e13a68e43692a7a279171d6ba57abd208bf23645ad"
[[package]]
name = "os_str_bytes"
version = "2.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ac6fe3538f701e339953a3ebbe4f39941aababa8a3f6964635b24ab526daeac"
[[package]]
name = "parking_lot"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4893845fa2ca272e647da5d0e46660a314ead9c2fdd9a883aabc32e481a8733"
dependencies = [
"instant",
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c361aa727dd08437f2f1447be8b59a33b0edd15e0fcee698f935613d9efbca9b"
dependencies = [
"cfg-if 0.1.10",
"cloudabi",
"instant",
"libc",
"redox_syscall",
"smallvec",
"winapi",
]
[[package]]
name = "phf"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3dfb61232e34fcb633f43d12c58f83c1df82962dcdfa565a4e866ffc17dafe12"
dependencies = [
"phf_macros",
"phf_shared",
"proc-macro-hack",
]
[[package]]
name = "phf_generator"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526"
dependencies = [
"phf_shared",
"rand",
]
[[package]]
name = "phf_macros"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f6fde18ff429ffc8fe78e2bf7f8b7a5a5a6e2a8b58bc5a9ac69198bbda9189c"
dependencies = [
"phf_generator",
"phf_shared",
"proc-macro-hack",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "phf_shared"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c00cf8b9eafe68dde5e9eaa2cef8ee84a9336a47d566ec55ca16589633b65af7"
dependencies = [
"siphasher",
]
[[package]]
name = "ppv-lite86"
version = "0.2.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c36fa947111f5c62a733b652544dd0016a43ce89619538a8ef92724a6f501a20"
[[package]]
name = "proc-macro-error"
version = "1.0.4"
@ -374,12 +178,6 @@ dependencies = [
"version_check",
]
[[package]]
name = "proc-macro-hack"
version = "0.5.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99c605b9a0adc77b7211c6b1f722dcb613d68d66859a44f3d485a6da332b0598"
[[package]]
name = "proc-macro2"
version = "1.0.24"
@ -398,81 +196,6 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom",
"libc",
"rand_chacha",
"rand_core",
"rand_hc",
"rand_pcg",
]
[[package]]
name = "rand_chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core",
]
[[package]]
name = "rand_pcg"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
dependencies = [
"rand_core",
]
[[package]]
name = "redox_syscall"
version = "0.1.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
[[package]]
name = "regex"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8963b85b8ce3074fecffde43b4b0dded83ce2f367dc8d363afc56679f3ee820b"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
"thread_local",
]
[[package]]
name = "regex-syntax"
version = "0.6.20"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8cab7a364d15cde1e505267766a2d3c4e22a843e1a601f0fa7564c0f82ced11c"
[[package]]
name = "rusty-hook"
version = "0.11.2"
@ -485,27 +208,6 @@ dependencies = [
"toml",
]
[[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 = "serde"
version = "1.0.117"
@ -517,23 +219,9 @@ name = "serene"
version = "0.1.0"
dependencies = [
"clap",
"inkwell",
"phf",
"rusty-hook",
]
[[package]]
name = "siphasher"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fa8f3741c7372e75519bd9346068370c9cdaabcc1f9599cbcf2a2719352286b7"
[[package]]
name = "smallvec"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fbee7696b84bbf3d89a1c2eccff0850e3047ed46bfcd2e92c29a2d074d57e252"
[[package]]
name = "strsim"
version = "0.10.0"
@ -569,15 +257,6 @@ dependencies = [
"unicode-width",
]
[[package]]
name = "thread_local"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
dependencies = [
"lazy_static",
]
[[package]]
name = "toml"
version = "0.5.7"
@ -617,12 +296,6 @@ version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5a972e5669d67ba988ce3dc826706fb0a8b01471c088cb0b6110b805cc36aed"
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "winapi"
version = "0.3.9"

View File

@ -14,11 +14,5 @@ license-file = "LICENSE"
# CLI library
clap = { version = "3.0.0-beta.1", features = ["yaml"] }
# LLVM Binding
inkwell = { git = "https://github.com/TheDan64/inkwell", branch = "llvm10-0" }
# Static compile time hashing generator
phf = { version = "0.8", features = ["macros"] }
[dev-dependencies]
rusty-hook = "^0.11.2"

View File

@ -14,9 +14,8 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
use crate::compiler::Compiler;
use crate::types::collections;
use crate::types::{ExprResult, Expression, Number, Symbol};
use crate::types::{Expression, Number, Symbol};
#[derive(Debug, Eq, PartialEq, Clone)]
pub enum Expr {
@ -58,11 +57,4 @@ impl Expr {
impl Expression for Expr {
fn eval() {}
fn code_gen<'ctx, 'val: 'ctx>(&self, compiler: &'ctx mut Compiler<'val>) -> ExprResult<'val> {
match self {
Expr::Sym(s) => s.code_gen(compiler),
Expr::Cons(s) => s.code_gen(compiler),
_ => Err("NotImplemented".to_string()),
}
}
}

View File

@ -16,4 +16,4 @@
*/
pub mod def;
pub use self::def::def;
//pub use self::def::def;

View File

@ -17,37 +17,8 @@
use crate::ast::Expr;
use crate::compiler::Compiler;
use crate::types::collections::core::Seq;
use crate::types::{ExprResult, Expression, List};
use crate::types::{Expression, List};
use crate::values::Value;
pub fn def<'ctx, 'val: 'ctx>(compiler: &'ctx mut Compiler<'val>, args: List) -> ExprResult<'val> {
// TODO: We need to support docstrings for def
if args.length() != 2 {
// TODO: Raise a meaningful error by including the location
panic!(format!(
"`def` expects 2 parameters, '{}' given.",
args.length()
));
}
let sym = match args.first() {
Some(e) => match e {
Expr::Sym(e) => e,
_ => return Err("First argument of 'def' has to be a symbol".to_string()),
},
_ => return Err("First argument of 'def' has to be a symbol".to_string()),
};
let value = match args.rest().first() {
Some(e) => {
let generated_code = e.code_gen(compiler);
Value::new(Some(sym.name.clone()), e, generated_code)
}
_ => return Err("Missing the second arugment for 'def'.".to_string()),
};
compiler
.current_ns()
.unwrap()
.define(sym.name.clone(), value, true)
}
// pub fn def<'ctx, 'val: 'ctx>(compiler: &'ctx mut Compiler<'val>, args: List) -> ExprResult<'val> {
// }

View File

@ -14,18 +14,11 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
use inkwell::builder::Builder;
use inkwell::context::Context;
//use inkwell::passes::PassManager;
use inkwell::values::{AnyValueEnum, BasicValue, FloatValue, FunctionValue, PointerValue};
use crate::namespace::Namespace;
use crate::types::Expression;
use std::collections::HashMap;
pub struct Compiler<'ctx> {
pub context: &'ctx Context,
pub builder: Builder<'ctx>,
pub struct Compiler {
/// This hashmap contains all the namespaces that has to be compiled and
/// maps two different keys to the same namespace. Since namespace names
/// can not contain `/` char, the keys of this map are the namespace
@ -35,13 +28,13 @@ pub struct Compiler<'ctx> {
/// two entries in this hashmap. One would be the ns name itself which
/// is `abc.xyz` in this case and the otherone would be
/// `/path/to/abc/xyz.srn` file that contains the ns.
pub namespaces: HashMap<String, Namespace<'ctx>>,
pub namespaces: HashMap<String, Namespace>,
//pub fpm: &'a PassManager<FunctionValue<'ctx>>,
current_ns_name: Option<String>,
}
impl<'ctx> Compiler<'ctx> {
pub fn new(context: &'ctx Context) -> Compiler<'ctx> {
impl Compiler {
pub fn new() -> Compiler {
//let user_ns = Namespace::new(&context, default_ns_name);
//namespaces.insert(default_ns_name, &user_ns);
// let fpm = PassManager::create(&user_ns.module);
@ -57,18 +50,14 @@ impl<'ctx> Compiler<'ctx> {
// fpm.initialize();
Compiler {
builder: context.create_builder(),
context: context,
namespaces: HashMap::new(),
current_ns_name: None,
}
}
pub fn create_ns(&mut self, ns_name: String, source_file: Option<&'ctx str>) {
self.namespaces.insert(
ns_name.clone(),
Namespace::new(&self.context, ns_name, None),
);
pub fn create_ns(&mut self, ns_name: String, source_file: Option<&str>) {
self.namespaces
.insert(ns_name.clone(), Namespace::new(ns_name, None));
}
pub fn set_current_ns(&mut self, ns_name: String) {
@ -76,77 +65,10 @@ impl<'ctx> Compiler<'ctx> {
}
#[inline]
pub fn current_ns(&mut self) -> Option<&mut Namespace<'ctx>> {
pub fn current_ns(&mut self) -> Option<&mut Namespace> {
match &self.current_ns_name {
Some(ns) => self.namespaces.get_mut(ns).map(|x| x),
_ => None,
}
}
/// Returns the `FunctionValue` representing the function being compiled.
#[inline]
pub fn current_fn(&mut self) -> FunctionValue<'ctx> {
self.current_ns().unwrap().current_fn()
}
// NOTE: Debug only funciton
pub fn compile_ns_str(&self, ns_name: String) -> String {
let ns = self.namespaces.get(&ns_name).map(|x| x);
match ns {
Some(v) => v.compile(),
None => panic!("Can't find namespace '{}'.", ns_name),
}
}
}
pub fn create_context() -> Context {
return Context::create();
}
/// Compiles the given `ast` using the given `compiler` into
/// LLVM IR.
pub fn compile<'ctx, 'val: 'ctx>(
compiler: &'ctx mut Compiler<'val>,
ast: Vec<impl Expression>,
) -> Vec<Result<AnyValueEnum<'val>, String>> {
match compiler.current_ns() {
Some(ns) => ns,
None => panic!("Current namespace is not set."),
};
let mut generated_code: Vec<Result<AnyValueEnum<'val>, String>> = vec![];
for expr in &ast {
generated_code.push(expr.code_gen(compiler));
}
generated_code
}
// pub fn create_compiler<'ctx>() -> Compiler<'ctx> {
// let default_ns_name = "user";
// // let builder = context.create_builder();
// let context = Context::create();
// //let user_ns = Namespace::new(&context, default_ns_name);
// //namespaces.insert(default_ns_name, &user_ns);
// // let fpm = PassManager::create(&user_ns.module);
// // fpm.add_instruction_combining_pass();
// // fpm.add_reassociate_pass();
// // fpm.add_gvn_pass();
// // fpm.add_cfg_simplification_pass();
// // fpm.add_basic_alias_analysis_pass();
// // fpm.add_promote_memory_to_register_pass();
// // fpm.add_instruction_combining_pass();
// // fpm.add_reassociate_pass();
// // fpm.initialize();
// //, builder, fpm, namespaces, Some(&default_ns_name)
// //Compiler::new(context)
// let builder = context.create_builder();
// Compiler {
// builder: builder,
// context: context,
// namespaces: HashMap::new(),
// }
// }

View File

@ -14,8 +14,6 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
extern crate inkwell;
use clap::{load_yaml, App};
use std::fs::File;
use std::io;
@ -36,8 +34,7 @@ fn main() -> io::Result<()> {
let args = App::from(yaml).get_matches();
// Create a compiler
let context = compiler::create_context();
let mut compiler = compiler::Compiler::new(&context);
let mut compiler = compiler::Compiler::new();
compiler.create_ns("user".to_string(), None);
compiler.set_current_ns("user".to_string());
@ -50,13 +47,6 @@ fn main() -> io::Result<()> {
match reader::read_string(&buf) {
Ok(v) => {
println!("AST: {:#?}", v);
let g = compiler::compile(&mut compiler, v);
println!("GEN: {:?}", g);
let compiled_module = compiler.compile_ns_str("user".to_string());
println!("\n=================\nMODULE USER:");
println!("{}", compiled_module);
}
Err(e) => println!(">> error {:?}", e),
}

View File

@ -16,114 +16,17 @@
*/
use crate::compiler::Compiler;
use crate::scope::Scope;
use crate::types::ExprResult;
use crate::values::Value;
use inkwell::context::Context;
use inkwell::module::Module;
use inkwell::types::{AnyTypeEnum, BasicType, FunctionType};
use inkwell::values::{AnyValueEnum, FunctionValue};
pub struct Namespace<'ctx> {
/// Each namespace in serene contains it's own LLVM module. You can
/// think of modules as compilation units. Object files if you prefer.
/// This way we should be able to hot swap the namespaces.
pub module: Module<'ctx>,
pub struct Namespace {
/// Root scope of the namespace
scope: Scope<'ctx>,
/// The option of the current function being compiled
current_fn_opt: Option<FunctionValue<'ctx>>,
// Current scope of the namespace, for example when we're processing
// a let form, this field would refer to the scope of that let form.
//current_scope_opt: Option<Scope<'ctx>>,
scope: Scope,
}
impl<'ctx> Namespace<'ctx> {
pub fn new(
context: &'ctx Context,
name: String,
source_file: Option<&'ctx str>,
) -> Namespace<'ctx> {
let module = context.create_module(&name);
module.set_source_file_name(source_file.unwrap_or(&name));
impl<'ctx> Namespace {
pub fn new(name: String, source_file: Option<&str>) -> Namespace {
Namespace {
module,
//scope: Scope::new(None),
current_fn_opt: None,
scope: Scope::new(None),
//current_scope_opt: None,
}
}
/// Get a defined function given its name.
#[inline]
pub fn get_function(&self, name: &str) -> Option<FunctionValue<'ctx>> {
self.module.get_function(name)
}
/// Return the `FunctionValue` representing the function being compiled.
#[inline]
pub fn current_fn(&self) -> FunctionValue<'ctx> {
self.current_fn_opt.unwrap()
}
fn define_function(
&self,
name: String,
value: Value<'ctx>,
public: bool,
f: FunctionType<'ctx>,
) -> ExprResult<'ctx> {
Err("NotImpelemnted".to_string())
}
fn define_value(
&mut self,
name: String,
value: Value<'ctx>,
public: bool,
t: impl BasicType<'ctx>,
) -> ExprResult<'ctx> {
let c = self.module.add_global(t, None, &name);
match value.llvm_value {
Ok(v) => {
match v {
AnyValueEnum::ArrayValue(a) => c.set_initializer(&a),
AnyValueEnum::IntValue(i) => c.set_initializer(&i),
AnyValueEnum::FloatValue(f) => c.set_initializer(&f),
AnyValueEnum::PointerValue(p) => c.set_initializer(&p),
AnyValueEnum::StructValue(s) => c.set_initializer(&s),
AnyValueEnum::VectorValue(v) => c.set_initializer(&v),
_ => panic!("It shoudn't happen!!!"),
};
self.scope.insert(&name, value, public);
Ok(v)
}
Err(e) => Err(e),
}
}
pub fn define(&mut self, name: String, value: Value<'ctx>, public: bool) -> ExprResult<'ctx> {
match value.llvm_value {
Ok(r) => match r.get_type() {
AnyTypeEnum::FunctionType(f) => self.define_function(name, value, public, f),
AnyTypeEnum::IntType(i) => self.define_value(name, value, public, i),
AnyTypeEnum::ArrayType(a) => self.define_value(name, value, public, a),
AnyTypeEnum::FloatType(f) => self.define_value(name, value, public, f),
AnyTypeEnum::PointerType(p) => self.define_value(name, value, public, p),
AnyTypeEnum::StructType(s) => self.define_value(name, value, public, s),
AnyTypeEnum::VectorType(v) => self.define_value(name, value, public, v),
_ => Err(format!("Data type '{:?}' is not supported", r.get_type())),
},
Err(e) => Err(e),
}
}
pub fn compile(&self) -> String {
self.module.print_to_string().to_string()
}
}

View File

@ -19,20 +19,20 @@ use crate::values::Value;
use std::collections::HashMap;
/// This struct describes the values in the scope.
pub struct ScopeElement<'a> {
element_type: Value<'a>,
pub struct ScopeElement {
element_type: Value,
public: bool,
}
/// Scopes in **Serene** are simply represented by hashmaps. Each
/// Scope optionally has a parent scope that lookups fallback to
/// if the lookup key is missing from the current scope.
pub struct Scope<'a> {
parent: Option<Box<Scope<'a>>>,
symbol_table: HashMap<String, ScopeElement<'a>>,
pub struct Scope {
parent: Option<Box<Scope>>,
symbol_table: HashMap<String, ScopeElement>,
}
impl<'a> Scope<'a> {
impl Scope {
pub fn new(_parent: Option<Scope>) -> Scope {
let p = match _parent {
Some(x) => Some(Box::new(x)),
@ -47,7 +47,7 @@ impl<'a> Scope<'a> {
/// Lookup the given `key` in the scope and if it is not in the current
/// scope look it up in the `parent` scope.
pub fn lookup(&self, key: &'a str) -> Option<&ScopeElement<'a>> {
pub fn lookup(&self, key: &str) -> Option<&ScopeElement> {
if self.symbol_table.contains_key(key) {
self.symbol_table.get(key)
} else {
@ -58,7 +58,7 @@ impl<'a> Scope<'a> {
}
}
pub fn insert(&mut self, key: &str, val: Value<'a>, public: bool) {
pub fn insert(&mut self, key: &str, val: Value, public: bool) {
let v = ScopeElement {
public,
element_type: val,

View File

@ -20,6 +20,6 @@ pub mod number;
pub mod symbol;
pub use self::collections::{List, Seq};
pub use self::core::{ExprResult, Expression};
pub use self::core::Expression;
pub use self::number::Number;
pub use self::symbol::Symbol;

View File

@ -18,7 +18,7 @@ use crate::ast::Expr;
use crate::builtins::def;
use crate::compiler::Compiler;
use crate::types::collections::core::Seq;
use crate::types::core::{ExprResult, Expression};
use crate::types::core::Expression;
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct List {
@ -47,20 +47,6 @@ impl List {
impl Expression for List {
fn eval() {}
fn code_gen<'ctx, 'val: 'ctx>(&self, compiler: &'ctx mut Compiler<'val>) -> ExprResult<'val> {
match self.first() {
Some(e) => match e {
Expr::Sym(s) if s.is_def() => def(compiler, self.rest()),
_ => Err("Not implemented on list".to_string()),
},
// TODO: We need to return an empty list here
None => Err("Can't not evaluate empty list".to_string()),
}
// def(compiler, self);
// Err("Not implemented on list".to_string())
}
}
impl Seq<Expr> for List {

View File

@ -15,13 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
use crate::compiler::Compiler;
use inkwell::values::{AnyValue, AnyValueEnum};
type ExprResultBase<'a, T: AnyValue<'a>> = Result<T, String>;
pub type ExprResult<'a> = ExprResultBase<'a, AnyValueEnum<'a>>;
pub trait Expression {
fn eval();
fn code_gen<'ctx, 'val: 'ctx>(&self, compiler: &'ctx mut Compiler<'val>) -> ExprResult<'val>;
}

View File

@ -15,7 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
use crate::compiler::Compiler;
use crate::types::core::{ExprResult, Expression};
use crate::types::core::Expression;
// Note: I kept the number implementation simple for now
// but we need to decide on our approach to numbers, are
// we going to only support the 64bit variants? or should
@ -46,7 +46,4 @@ impl Eq for Number {}
impl Expression for Number {
fn eval() {}
fn code_gen<'ctx, 'val: 'ctx>(&self, compiler: &'ctx mut Compiler<'val>) -> ExprResult<'val> {
Err("Not implemented on numbers".to_string())
}
}

View File

@ -15,9 +15,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
use crate::compiler::Compiler;
use crate::types::core::{ExprResult, Expression};
use inkwell::types::IntType;
use inkwell::values::AnyValueEnum;
use crate::types::core::Expression;
#[derive(Debug, Clone)]
pub struct Symbol {
@ -34,16 +32,6 @@ impl Eq for Symbol {}
impl Expression for Symbol {
fn eval() {}
fn code_gen<'ctx, 'val: 'ctx>(&self, compiler: &'ctx mut Compiler<'val>) -> ExprResult<'val> {
let bool_t: IntType<'val> = compiler.context.bool_type();
if self.name == "true" {
Ok(AnyValueEnum::IntValue(bool_t.const_int(1, false)))
} else if self.name == "false" {
Ok(AnyValueEnum::IntValue(bool_t.const_int(0, false)))
} else {
Err("Nothing yet".to_string())
}
}
}
impl Symbol {

View File

@ -15,21 +15,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
use crate::ast::Expr;
use crate::types::ExprResult;
#[derive(Debug, Eq, PartialEq, Clone)]
pub struct Value<'a> {
pub llvm_id: Option<String>,
pub llvm_value: ExprResult<'a>,
pub struct Value {
pub expr: Expr,
}
impl<'a> Value<'a> {
pub fn new(name: Option<String>, expr: Expr, value: ExprResult<'a>) -> Value {
Value {
llvm_id: name,
llvm_value: value,
expr: expr,
}
}
}