M benches/basic.rs +7 -33
@@ 66,7 66,7 @@ end
buf
}
-fn bench_with_rust_backend(c: &mut Criterion) {
+fn bench_compile(c: &mut Criterion) {
let code = gen_dumb_test_code(103);
let lines = code.lines().count();
let name = format!("compile {}ish lines to Rust", lines);
@@ 81,7 81,6 @@ fn bench_with_rust_backend(c: &mut Crite
b.iter(|| compile("criterion.gt", black_box(&code), backend::Backend::Rust))
});
- /*
let code = gen_dumb_test_code(103 * 16);
let lines = code.lines().count();
let name = format!("compile {}ish lines", lines);
@@ 94,30 93,6 @@ fn bench_with_rust_backend(c: &mut Crite
)
})
});
- */
-}
-
-fn bench_with_null_backend(c: &mut Criterion) {
- let code = gen_dumb_test_code(103);
- let lines = code.lines().count();
- let name = format!("compile {}ish lines to nothing", lines);
- c.bench_function(&name, |b| {
- b.iter(|| compile("criterion.gt", black_box(&code), backend::Backend::Null))
- });
-
- let code = gen_dumb_test_code(103 * 8);
- let lines = code.lines().count();
- let name = format!("compile {}ish lines to nothing", lines);
- c.bench_function(&name, |b| {
- b.iter(|| compile("criterion.gt", black_box(&code), backend::Backend::Null))
- });
-
- let code = gen_dumb_test_code(103 * 16);
- let lines = code.lines().count();
- let name = format!("compile {}ish lines to nothing", lines);
- c.bench_function(&name, |b| {
- b.iter(|| compile("criterion.gt", black_box(&code), backend::Backend::Rust))
- });
}
fn bench_stages(c: &mut Criterion) {
@@ 161,15 136,14 @@ fn bench_stages(c: &mut Criterion) {
});
let hir = passes::run_typechecked_passes(hir, tck);
- c.bench_function("codegen", |b| {
+ c.bench_function("codegen to Rust", |b| {
b.iter(|| backend::output(backend::Backend::Rust, black_box(&hir), black_box(tck)))
});
+
+ c.bench_function("codegen to null", |b| {
+ b.iter(|| backend::output(backend::Backend::Null, black_box(&hir), black_box(tck)))
+ });
}
-criterion_group!(
- benches,
- //bench_with_rust_backend,
- //bench_with_null_backend,
- bench_stages
-);
+criterion_group!(benches, bench_compile, bench_stages);
criterion_main!(benches);
M src/ast.rs +7 -7
@@ 96,11 96,11 @@ pub struct IfCase {
#[derive(Debug, Clone, PartialEq)]
pub struct Signature {
/// Parameters
- pub params: Arc<Vec<(Sym, Type)>>,
+ pub params: Vec<(Sym, Type)>,
/// Return type
pub rettype: Type,
/// Type parameters
- pub typeparams: Arc<Vec<Type>>,
+ pub typeparams: Vec<Type>,
}
impl Signature {
@@ 108,8 108,8 @@ impl Signature {
pub fn to_type(&self) -> Type {
let paramtypes = self.params.iter().map(|(_nm, ty)| ty.clone()).collect();
Type::Func(
- Arc::new(paramtypes),
- Arc::new(self.rettype.clone()),
+ paramtypes,
+ Box::new(self.rettype.clone()),
self.typeparams.clone(),
)
}
@@ 150,14 150,14 @@ impl Signature {
let new_params = self
.params
.iter()
- .zip(params.as_ref())
+ .zip(params)
.map(|((nm, _t1), t2)| (*nm, t2.clone()))
.collect();
let new_rettype = rettype.clone();
let new_type_params = typeparams.clone();
Self {
- params: Arc::new(new_params),
- rettype: new_rettype.as_ref().clone(),
+ params: new_params,
+ rettype: *new_rettype,
typeparams: new_type_params,
}
}
M src/backend/rust.rs +4 -4
@@ 44,7 44,7 @@ fn compile_typename(t: &Type) -> Cow<'st
Named(s, types) if s == &Sym::new("Tuple") => {
trace!("Compiling tuple {:?}...", t);
let mut accm = String::from("(");
- for typ in &**types {
+ for typ in types {
accm += &compile_typename(typ);
accm += ", ";
}
@@ 68,7 68,7 @@ fn compile_typename(t: &Type) -> Cow<'st
}
*/
accm += "(";
- for p in &**params {
+ for p in params {
accm += &compile_typename(p);
accm += ", ";
}
@@ 149,7 149,7 @@ fn compile_typename(t: &Type) -> Cow<'st
/// Driver that turns a pile of Ir into Rust code.
pub(super) fn output(lir: &hir::Ir, tck: &Tck) -> Vec<u8> {
let mut output = Vec::new();
- for builtin in &*builtins::all() {
+ for builtin in &*builtins::BUILTINS {
output.extend(builtin.code[&backend::Backend::Rust].as_bytes());
}
for decl in lir.decls.iter() {
@@ 223,7 223,7 @@ fn compile_decl(w: &mut impl Write, decl
params.iter().map(|sym| (*sym.val()).clone()).collect();
let args = param_strings.join(", ");
writeln!(w, "pub enum {}<{}> {{ ", nstr, args)?;
- for (nm, ty) in &**body {
+ for (nm, ty) in body {
writeln!(w, " {} ({}),", nm, compile_typename(ty))?;
}
writeln!(w, "}}")?;
M src/bin/garnetfmt.rs +1 -0
@@ 39,6 39,7 @@ fn main() -> io::Result<()> {
// anything
let formatted_data = &formatted_src.into_inner();
let formatted_str = String::from_utf8_lossy(formatted_data);
+ println!("{}", formatted_str);
let formatted_ast = {
let mut parser = parser::Parser::new(filename, &formatted_str);
parser.parse()
M src/builtins.rs +49 -45
@@ 6,6 6,8 @@
use std::collections::BTreeMap;
+use once_cell::sync::Lazy;
+
use crate::backend::Backend;
use crate::*;
@@ 20,6 22,8 @@ pub struct Builtin {
pub code: BTreeMap<Backend, String>,
}
+pub static BUILTINS: Lazy<Vec<Builtin>> = Lazy::new(Builtin::all);
+
impl Builtin {
/// Generate all appropriate methods for the given numeric type.
/// Right now we just stick em in the toplevel with constructed names,
@@ 104,99 108,99 @@ fn __{name}_to_u32(x: {name}) -> u32 {{
vec![
Builtin {
name: Sym::new(format!("__println_{name}")),
- sig: Type::function(&vec![ty.clone()], &Type::unit(), &vec![]),
+ sig: Type::Func(vec![ty.clone()], Box::new(Type::unit()), vec![]),
code: BTreeMap::from([(Backend::Null, "".into()), (Backend::Rust, println)]),
},
Builtin {
name: Sym::new(format!("__band_{name}")),
- sig: Type::function(&vec![ty.clone(), ty.clone()], &ty.clone(), &vec![]),
+ sig: Type::Func(vec![ty.clone(), ty.clone()], Box::new(ty.clone()), vec![]),
code: BTreeMap::from([(Backend::Null, "".into()), (Backend::Rust, band)]),
},
Builtin {
name: Sym::new(format!("__bor_{name}")),
- sig: Type::function(&vec![ty.clone(), ty.clone()], &ty.clone(), &vec![]),
+ sig: Type::Func(vec![ty.clone(), ty.clone()], Box::new(ty.clone()), vec![]),
code: BTreeMap::from([(Backend::Null, "".into()), (Backend::Rust, bor)]),
},
Builtin {
name: Sym::new(format!("__bxor_{name}")),
- sig: Type::function(&vec![ty.clone(), ty.clone()], &ty.clone(), &vec![]),
+ sig: Type::Func(vec![ty.clone(), ty.clone()], Box::new(ty.clone()), vec![]),
code: BTreeMap::from([(Backend::Null, "".into()), (Backend::Rust, bxor)]),
},
Builtin {
name: Sym::new(format!("__bnot_{name}")),
- sig: Type::function(&vec![ty.clone()], &ty.clone(), &vec![]),
+ sig: Type::Func(vec![ty.clone()], Box::new(ty.clone()), vec![]),
code: BTreeMap::from([(Backend::Null, "".into()), (Backend::Rust, bnot)]),
},
Builtin {
name: Sym::new(format!("__rshift_{name}")),
- sig: Type::function(&vec![ty.clone(), ty.clone()], &ty.clone(), &vec![]),
+ sig: Type::Func(vec![ty.clone(), ty.clone()], Box::new(ty.clone()), vec![]),
code: BTreeMap::from([(Backend::Null, "".into()), (Backend::Rust, rshift)]),
},
Builtin {
name: Sym::new(format!("__lshift_{name}")),
- sig: Type::function(&vec![ty.clone(), ty.clone()], &ty.clone(), &vec![]),
+ sig: Type::Func(vec![ty.clone(), ty.clone()], Box::new(ty.clone()), vec![]),
code: BTreeMap::from([(Backend::Null, "".into()), (Backend::Rust, lshift)]),
},
Builtin {
name: Sym::new(format!("__rol_{name}")),
- sig: Type::function(&vec![ty.clone(), Type::i32()], &ty.clone(), &vec![]),
+ sig: Type::Func(vec![ty.clone(), Type::i32()], Box::new(ty.clone()), vec![]),
code: BTreeMap::from([(Backend::Null, "".into()), (Backend::Rust, rol)]),
},
Builtin {
name: Sym::new(format!("__ror_{name}")),
- sig: Type::function(&vec![ty.clone(), Type::i32()], &ty.clone(), &vec![]),
+ sig: Type::Func(vec![ty.clone(), Type::i32()], Box::new(ty.clone()), vec![]),
code: BTreeMap::from([(Backend::Null, "".into()), (Backend::Rust, ror)]),
},
Builtin {
name: Sym::new(format!("__{name}_to_i32")),
- sig: Type::function(&vec![ty.clone()], &Type::i32(), &vec![]),
+ sig: Type::Func(vec![ty.clone()], Box::new(Type::i32()), vec![]),
code: BTreeMap::from([(Backend::Null, "".into()), (Backend::Rust, cast_i32)]),
},
Builtin {
name: Sym::new(format!("__{name}_to_u32")),
- sig: Type::function(&vec![ty.clone()], &Type::u32(), &vec![]),
+ sig: Type::Func(vec![ty.clone()], Box::new(Type::u32()), vec![]),
code: BTreeMap::from([(Backend::Null, "".into()), (Backend::Rust, cast_u32)]),
},
]
}
-}
-/// A function that returns all the compiler builtin info. Just
-/// use the `BUILTINS` global instead, this is basically here
-/// to initialize it.
-pub fn all() -> Vec<Builtin> {
- let rust_println = r#"fn __println(x: i32) {
+ /// A function that returns all the compiler builtin info. Just
+ /// use the `BUILTINS` global instead, this is basically here
+ /// to initialize it.
+ fn all() -> Vec<Builtin> {
+ let rust_println = r#"fn __println(x: i32) {
println!("{}", x);
}"#;
- let rust_println_bool = r#"
+ let rust_println_bool = r#"
fn __println_bool(x: bool) {
println!("{}", x);
}"#;
- let mut funcs = vec![
- Builtin {
- name: Sym::new("__println"),
- sig: Type::function(&vec![Type::i32()], &Type::unit(), &vec![]),
- code: BTreeMap::from([
- (Backend::Null, "".into()),
- (Backend::Rust, rust_println.into()),
- ]),
- },
- Builtin {
- name: Sym::new("__println_bool"),
- sig: Type::function(&vec![Type::bool()], &Type::unit(), &vec![]),
- code: BTreeMap::from([
- (Backend::Null, "".into()),
- (Backend::Rust, rust_println_bool.into()),
- ]),
- },
- ];
- funcs.extend(Builtin::generate_numerics_for("i8", Type::i8()));
- funcs.extend(Builtin::generate_numerics_for("i16", Type::i16()));
- funcs.extend(Builtin::generate_numerics_for("i32", Type::i32()));
- funcs.extend(Builtin::generate_numerics_for("i64", Type::i64()));
- funcs.extend(Builtin::generate_numerics_for("u8", Type::u8()));
- funcs.extend(Builtin::generate_numerics_for("u16", Type::u16()));
- funcs.extend(Builtin::generate_numerics_for("u32", Type::u32()));
- funcs.extend(Builtin::generate_numerics_for("u64", Type::u64()));
- funcs
+ let mut funcs = vec![
+ Builtin {
+ name: Sym::new("__println"),
+ sig: Type::Func(vec![Type::i32()], Box::new(Type::unit()), vec![]),
+ code: BTreeMap::from([
+ (Backend::Null, "".into()),
+ (Backend::Rust, rust_println.into()),
+ ]),
+ },
+ Builtin {
+ name: Sym::new("__println_bool"),
+ sig: Type::Func(vec![Type::bool()], Box::new(Type::unit()), vec![]),
+ code: BTreeMap::from([
+ (Backend::Null, "".into()),
+ (Backend::Rust, rust_println_bool.into()),
+ ]),
+ },
+ ];
+ funcs.extend(Self::generate_numerics_for("i8", Type::i8()));
+ funcs.extend(Self::generate_numerics_for("i16", Type::i16()));
+ funcs.extend(Self::generate_numerics_for("i32", Type::i32()));
+ funcs.extend(Self::generate_numerics_for("i64", Type::i64()));
+ funcs.extend(Self::generate_numerics_for("u8", Type::u8()));
+ funcs.extend(Self::generate_numerics_for("u16", Type::u16()));
+ funcs.extend(Self::generate_numerics_for("u32", Type::u32()));
+ funcs.extend(Self::generate_numerics_for("u64", Type::u64()));
+ funcs
+ }
}
M src/hir.rs +11 -12
@@ 768,10 768,10 @@ fn lower_typedef(accm: &mut Vec<Decl>, n
let struct_signature = ts
.iter()
//.map(|(enumname, _enumval)| (*enumname, ty.clone()))
- .map(|(enumname, _enumval)| (*enumname, Type::Named(name, Arc::new(vec![]))))
+ .map(|(enumname, _enumval)| (*enumname, Type::Named(name, vec![])))
.collect();
// Enums cannot have type parameters, so this works.
- let init_type = Type::Struct(Arc::new(struct_signature), Arc::new(vec![]));
+ let init_type = Type::Struct(struct_signature, vec![]);
let new_constdef = Const {
name,
typ: init_type,
@@ 798,7 798,7 @@ fn lower_typedef(accm: &mut Vec<Decl>, n
.map(|(variant_name, variant_type)| {
let paramname = Sym::new("x");
let signature = ast::Signature {
- params: Arc::new(vec![(paramname, variant_type.clone())]),
+ params: vec![(paramname, variant_type.clone())],
rettype: Type::Named(name, generics.clone()),
typeparams: generics.clone(),
};
@@ 822,15 822,15 @@ fn lower_typedef(accm: &mut Vec<Decl>, n
// `fn(variant_type) name`
(
*variant_name,
- Type::function(
- &[variant_type.clone()],
- &Type::Named(name, generics.clone()),
- &generics,
+ Type::Func(
+ vec![variant_type.clone()],
+ Box::new(Type::Named(name, generics.clone())),
+ generics.clone(),
),
)
})
.collect();
- let struct_type = Type::Struct(Arc::new(struct_typebody), generics.clone());
+ let struct_type = Type::Struct(struct_typebody, generics.clone());
let new_constdef = Const {
name: name.to_owned(),
typ: struct_type,
@@ 843,10 843,9 @@ fn lower_typedef(accm: &mut Vec<Decl>, n
other => {
let s = Sym::new("x");
trace!("Lowering params {:?}", params);
- let type_params: Arc<Vec<_>> =
- Arc::new(params.iter().map(|s| Type::Generic(*s)).collect());
+ let type_params: Vec<_> = params.iter().map(|s| Type::Generic(*s)).collect();
let signature = ast::Signature {
- params: Arc::new(vec![(s, other.clone())]),
+ params: vec![(s, other.clone())],
rettype: Type::Named(name.to_owned(), type_params.clone()),
typeparams: type_params.clone(),
};
@@ 854,7 853,7 @@ fn lower_typedef(accm: &mut Vec<Decl>, n
// in a type constructor
let body = vec![ExprNode::new(Expr::TypeCtor {
name,
- type_params: type_params.to_vec(),
+ type_params,
body: ExprNode::new(Expr::Var { name: s }),
})];
//println!("{} is {:#?}", variant_name, e);
M src/lib.rs +24 -28
@@ 74,26 74,26 @@ pub enum Type {
/// Never type, the type of an infinite loop
Never,
/// A C-like enum, and the integer values it corresponds to
- Enum(Arc<Vec<(Sym, i32)>>),
+ Enum(Vec<(Sym, i32)>),
/// A nominal type of some kind; may be built-in (like Tuple)
/// or user-defined.
- Named(Sym, Arc<Vec<Type>>),
+ Named(Sym, Vec<Type>),
/// A function pointer.
///
/// The contents are arg types, return types, type parameters
- Func(Arc<Vec<Type>>, Arc<Type>, Arc<Vec<Type>>),
+ Func(Vec<Type>, Box<Type>, Vec<Type>),
/// An anonymous struct. The vec is type parameters.
- Struct(Arc<BTreeMap<Sym, Type>>, Arc<Vec<Type>>),
+ Struct(BTreeMap<Sym, Type>, Vec<Type>),
/// Sum type.
///
/// Like structs, contains a list of type parameters.
- Sum(Arc<BTreeMap<Sym, Type>>, Arc<Vec<Type>>),
+ Sum(BTreeMap<Sym, Type>, Vec<Type>),
/// Arrays are just a type and a number.
- Array(Arc<Type>, usize),
+ Array(Box<Type>, usize),
/// A generic type parameter that has been given an explicit name.
Generic(Sym),
/// Unique borrow
- Uniq(Arc<Type>),
+ Uniq(Box<Type>),
}
impl Type {
@@ 126,18 126,18 @@ impl Type {
helper(rettype, accm)
}
Type::Struct(body, generics) => {
- for (_, ty) in &**body {
+ for (_, ty) in body {
helper(ty, accm);
}
- for g in &**generics {
+ for g in generics {
helper(g, accm);
}
}
Type::Sum(body, generics) => {
- for (_, ty) in &**body {
+ for (_, ty) in body {
helper(ty, accm);
}
- for g in &**generics {
+ for g in generics {
helper(g, accm);
}
}
@@ 238,29 238,29 @@ impl Type {
/// Shortcut for getting the type for Unit
pub fn unit() -> Self {
- Self::Named(Sym::new("Tuple"), Arc::new(vec![]))
+ Self::Named(Sym::new("Tuple"), vec![])
}
/// Shortcut for getting the type for Never
pub fn never() -> Self {
- Self::Named(Sym::new("Never"), Arc::new(vec![]))
+ Self::Named(Sym::new("Never"), vec![])
}
/// Create a Tuple with the given values
- pub fn tuple(args: Arc<Vec<Self>>) -> Self {
+ pub fn tuple(args: Vec<Self>) -> Self {
Self::Named(Sym::new("Tuple"), args)
}
/// Used in some tests
pub fn array(t: &Type, len: usize) -> Self {
- Self::Array(Arc::new(t.clone()), len)
+ Self::Array(Box::new(t.clone()), len)
}
fn function(params: &[Type], rettype: &Type, generics: &[Type]) -> Self {
Type::Func(
- Arc::new(Vec::from(params)),
- Arc::new(rettype.clone()),
- Arc::new(Vec::from(generics)),
+ Vec::from(params),
+ Box::new(rettype.clone()),
+ Vec::from(generics),
)
}
@@ 446,11 446,11 @@ impl Type {
if !body1.keys().eq(body2.keys()) {
panic!("subst for sum type had non-matching keys")
}
- for ((_nm1, t1), (_nm2, t2)) in (&**body1).iter().zip(&**body2) {
+ for ((_nm1, t1), (_nm2, t2)) in body1.iter().zip(body2) {
t1._find_substs(t2, substitutions);
}
- for (p1, p2) in (&**generics1).iter().zip(&**generics2) {
+ for (p1, p2) in (&**generics1).iter().zip(generics2) {
p1._find_substs(p2, substitutions);
}
}
@@ 488,15 488,11 @@ impl Type {
if typeparams1.len() > 0 {
todo!("Hsfjkdslfjs");
}
- Type::Func(
- Arc::new(new_params),
- Arc::new(new_rettype),
- Arc::new(vec![]),
- )
+ Type::Func(new_params, Box::new(new_rettype), vec![])
}
Type::Named(n1, args1) => {
let new_args = args1.iter().map(|p1| p1._apply_substs(substs)).collect();
- Type::Named(*n1, Arc::new(new_args))
+ Type::Named(*n1, new_args)
}
Type::Struct(_, _) => unreachable!("see other unreachable in substitute()"),
Type::Sum(body, generics) => {
@@ 505,9 501,9 @@ impl Type {
.map(|(nm, ty)| (*nm, ty._apply_substs(substs)))
.collect();
let new_generics = generics.iter().map(|p1| p1._apply_substs(substs)).collect();
- Type::Sum(Arc::new(new_body), Arc::new(new_generics))
+ Type::Sum(new_body, new_generics)
}
- Type::Array(body, len) => Type::Array(Arc::new(body._apply_substs(substs)), *len),
+ Type::Array(body, len) => Type::Array(Box::new(body._apply_substs(substs)), *len),
Type::Generic(nm) => substs
.get(&nm)
.unwrap_or_else(|| panic!("No substitution found for generic named {}!", nm))
M src/parser.rs +11 -11
@@ 706,9 706,9 @@ impl<'input> Parser<'input> {
let (params, typeparams) = self.parse_fn_args();
let rettype = self.try_parse_type().unwrap_or(Type::unit());
ast::Signature {
- params: Arc::new(params),
+ params,
rettype,
- typeparams: Arc::new(typeparams),
+ typeparams,
}
}
@@ 890,19 890,19 @@ impl<'input> Parser<'input> {
}
});
self.expect(T::RBrace);
- Some(Type::tuple(Arc::new(body)))
+ Some(Type::tuple(body))
}
fn try_parse_struct_type(&mut self) -> Option<Type> {
let (fields, type_params) = self.parse_struct_fields();
self.expect(T::End);
- Some(Type::Struct(Arc::new(fields), Arc::new(type_params)))
+ Some(Type::Struct(fields, type_params))
}
fn parse_enum_type(&mut self) -> Type {
let variants = self.parse_enum_fields();
self.expect(T::End);
- Type::Enum(Arc::new(variants))
+ Type::Enum(variants)
}
/// isomorphic-ish with parse_type_list()
@@ 941,7 941,7 @@ impl<'input> Parser<'input> {
.map(|ty| Type::Generic(ty))
.collect();
*/
- Type::Sum(Arc::new(fields), Arc::new(generics))
+ Type::Sum(fields, generics)
}
fn parse_exprs(&mut self) -> Vec<ast::Expr> {
@@ 1384,7 1384,7 @@ impl<'input> Parser<'input> {
} else {
vec![]
};
- Type::Named(Sym::new(s), Arc::new(type_params))
+ Type::Named(Sym::new(s), type_params)
}
}
T::At => {
@@ 1401,11 1401,11 @@ impl<'input> Parser<'input> {
assert!(len >= 0);
self.expect(T::RBracket);
let inner = self.parse_type();
- Type::Array(Arc::new(inner), len as usize)
+ Type::Array(Box::new(inner), len as usize)
}
T::Ampersand => {
let next = self.try_parse_type()?;
- Type::Uniq(Arc::new(next))
+ Type::Uniq(Box::new(next))
}
_ => {
// Wind the parse stream back to wherever we started
@@ 1554,9 1554,9 @@ mod tests {
ast::Decl::Function {
name: Sym::new("foo"),
signature: ast::Signature {
- params: Arc::new(vec![(Sym::new("x"), i32_t.clone())]),
+ params: vec![(Sym::new("x"), i32_t.clone())],
rettype: i32_t,
- typeparams: Arc::new(vec![]),
+ typeparams: vec![],
},
body: vec![Expr::int(9)],
doc_comment: vec![],
M src/passes.rs +15 -18
@@ 319,8 319,8 @@ fn decl_map(
}
}
-fn types_map(typs: Arc<Vec<Type>>, f: &mut dyn FnMut(Type) -> Type) -> Arc<Vec<Type>> {
- Arc::new(typs.iter().cloned().map(|t| type_map(t, f)).collect())
+fn types_map(typs: Vec<Type>, f: &mut dyn FnMut(Type) -> Type) -> Vec<Type> {
+ typs.into_iter().map(|t| type_map(t, f)).collect()
}
/// Recursion scheme to turn one type into another.
@@ 330,17 330,15 @@ fn type_map(typ: Type, f: &mut dyn FnMut
/// it generic over any iterator, if we want to make life even harder for
/// ourself.
fn types_map_btree<K>(
- typs: Arc<BTreeMap<K, Type>>,
+ typs: BTreeMap<K, Type>,
f: &mut dyn FnMut(Type) -> Type,
- ) -> Arc<BTreeMap<K, Type>>
+ ) -> BTreeMap<K, Type>
where
- K: Ord + Clone,
+ K: Ord,
{
- Arc::new(
- typs.iter()
- .map(|(key, ty)| (key.clone(), type_map(ty.clone(), f)))
- .collect(),
- )
+ typs.into_iter()
+ .map(|(key, ty)| (key, type_map(ty, f)))
+ .collect()
}
let res = match typ {
Type::Struct(fields, generics) => {
@@ 351,12 349,12 @@ fn type_map(typ: Type, f: &mut dyn FnMut
let new_fields = types_map_btree(fields, f);
Type::Sum(new_fields, generics)
}
- Type::Array(ty, len) => Type::array(&type_map(ty.as_ref().clone(), f), len),
+ Type::Array(ty, len) => Type::Array(Box::new(type_map(*ty, f)), len),
Type::Func(args, rettype, typeparams) => {
let new_args = types_map(args, f);
- let new_rettype = type_map(rettype.as_ref().clone(), f);
+ let new_rettype = type_map(*rettype, f);
let new_typeparams = types_map(typeparams, f);
- Type::function(&new_args, &new_rettype, &new_typeparams)
+ Type::Func(new_args, Box::new(new_rettype), new_typeparams)
}
// Not super sure whether this is necessary, but can't hurt.
Type::Named(nm, tys) => Type::Named(nm, types_map(tys, f)),
@@ 365,8 363,8 @@ fn type_map(typ: Type, f: &mut dyn FnMut
Type::Enum(_) => typ,
Type::Generic(_) => typ,
Type::Uniq(t) => {
- let new_t = type_map(t.as_ref().clone(), f);
- Type::Uniq(Arc::new(new_t))
+ let new_t = type_map(*t, f);
+ Type::Uniq(Box::new(new_t))
}
};
f(res)
@@ 376,12 374,11 @@ fn type_map(typ: Type, f: &mut dyn FnMut
fn signature_map(sig: hir::Signature, f: &mut dyn FnMut(Type) -> Type) -> hir::Signature {
let new_params = sig
.params
- .iter()
- .cloned()
+ .into_iter()
.map(|(sym, ty)| (sym, type_map(ty, f)))
.collect();
hir::Signature {
- params: Arc::new(new_params),
+ params: new_params,
rettype: type_map(sig.rettype, f),
typeparams: types_map(sig.typeparams, f),
}
M src/passes/struct_to_tuple.rs +10 -10
@@ 38,11 38,9 @@ fn tuplize_type(typ: Type) -> Type {
// on the field names.
// TODO: What do we do with generics? Anything?
- let tuple_fields = fields
- .values()
- .map(|ty| type_map(ty.clone(), &mut tuplize_type))
+ let tuple_fields = fields.values().map(|ty| type_map(ty.clone(), &mut tuplize_type))
.collect();
- Type::tuple(Arc::new(tuple_fields))
+ Type::tuple(tuple_fields)
}
other => other,
}
@@ 79,7 77,10 @@ fn tuplize_expr(expr: ExprNode, tck: &mu
.map(|(ky, vl)| (offset_of_field(type_body, ky), vl))
.collect();
ordered_body.sort_by(|a, b| a.0.cmp(&b.0));
- let new_body = ordered_body.into_iter().map(|(_i, expr)| expr).collect();
+ let new_body = ordered_body
+ .into_iter()
+ .map(|(_i, expr)| expr)
+ .collect();
E::TupleCtor { body: new_body }
}
@@ 270,15 271,14 @@ mod tests {
let mut body = BTreeMap::new();
body.insert(Sym::new("foo"), Type::i32());
body.insert(Sym::new("bar"), Type::i64());
- let body = Arc::new(body);
- let desired = tuplize_type(Type::Struct(body.clone(), Arc::new(vec![])));
- let inp = Type::Struct(body, Arc::new(vec![]));
+ let desired = tuplize_type(Type::Struct(body.clone(), vec![]));
+ let inp = Type::Struct(body, vec![]);
let out = type_map(inp.clone(), &mut tuplize_type);
assert_eq!(out, desired);
- let desired2 = Type::array(&out, 3);
- let inp2 = Type::array(&inp, 3);
+ let desired2 = Type::Array(Box::new(out), 3);
+ let inp2 = Type::Array(Box::new(inp), 3);
let out2 = type_map(inp2, &mut tuplize_type);
assert_eq!(out2, desired2);
}
M src/typeck.rs +17 -20
@@ 409,7 409,7 @@ impl Tck {
let tinfo = match t {
Type::Prim(ty) => TypeInfo::Prim(*ty),
Type::Never => TypeInfo::Never,
- Type::Enum(vals) => TypeInfo::Enum((&**vals).clone()),
+ Type::Enum(vals) => TypeInfo::Enum(vals.clone()),
Type::Named(s, args) => {
let new_args = args.iter().map(|t| self.insert_known(t)).collect();
TypeInfo::Named(*s, new_args)
@@ 726,11 726,11 @@ impl Tck {
Never => Ok(Type::Never),
Prim(ty) => Ok(Type::Prim(*ty)),
Ref(id) => self.reconstruct(*id),
- Enum(ts) => Ok(Type::Enum(Arc::new(ts.clone()))),
+ Enum(ts) => Ok(Type::Enum(ts.clone())),
Named(s, args) => {
let arg_types: Result<Vec<_>, _> =
args.iter().map(|x| self.reconstruct(*x)).collect();
- Ok(Type::Named(*s, Arc::new(arg_types?)))
+ Ok(Type::Named(*s, arg_types?))
}
Func(args, rettype, typeparams) => {
let real_args: Result<Vec<Type>, TypeError> =
@@ 738,12 738,10 @@ impl Tck {
let type_param_types: Result<Vec<Type>, _> =
typeparams.iter().map(|x| self.reconstruct(*x)).collect();
- let real_args = real_args?;
- let type_param_types = type_param_types?;
- Ok(Type::function(
- &real_args,
- &self.reconstruct(*rettype)?,
- &type_param_types,
+ Ok(Type::Func(
+ real_args?,
+ Box::new(self.reconstruct(*rettype)?),
+ type_param_types?,
))
}
TypeParam(name) => Ok(Type::Generic(*name)),
@@ 757,11 755,11 @@ impl Tck {
.collect();
// TODO: The empty params here feels suspicious, verify.
let params = vec![];
- Ok(Type::Struct(Arc::new(real_body?), Arc::new(params)))
+ Ok(Type::Struct(real_body?, params))
}
Array(ty, len) => {
let real_body = self.reconstruct(*ty)?;
- Ok(Type::array(&real_body, len.unwrap()))
+ Ok(Type::Array(Box::new(real_body), len.unwrap()))
}
Sum(body) => {
let real_body: Result<BTreeMap<_, _>, TypeError> = body
@@ 772,11 770,11 @@ impl Tck {
})
.collect();
let params = vec![];
- Ok(Type::Sum(Arc::new(real_body?), Arc::new(params)))
+ Ok(Type::Sum(real_body?, params))
}
Uniq(ty) => {
let inner_type = self.reconstruct(*ty)?;
- Ok(Type::Uniq(Arc::new(inner_type)))
+ Ok(Type::Uniq(Box::new(inner_type)))
}
}
}
@@ 806,7 804,7 @@ impl Tck {
let typeinfo = match t {
Type::Prim(val) => TypeInfo::Prim(*val),
Type::Never => TypeInfo::Never,
- Type::Enum(vals) => TypeInfo::Enum((**vals).clone()),
+ Type::Enum(vals) => TypeInfo::Enum(vals.clone()),
Type::Named(s, args) => {
let inst_args: Vec<_> =
args.iter().map(|t| helper(tck, named_types, t)).collect();
@@ 916,7 914,7 @@ impl Drop for ScopeGuard {
impl Symtbl {
fn add_builtins(&self, tck: &mut Tck) {
- for builtin in &*builtins::all() {
+ for builtin in &*builtins::BUILTINS {
let ty = tck.insert_known(&builtin.sig);
self.add_var(builtin.name, ty, false);
}
@@ 1010,7 1008,7 @@ fn typecheck_func_body(
*/
// Insert info about the function signature
let mut params = vec![];
- for (_paramname, paramtype) in &*signature.params {
+ for (_paramname, paramtype) in &signature.params {
let p = tck.insert_known(paramtype);
params.push(p);
}
@@ 1033,7 1031,7 @@ fn typecheck_func_body(
// Add params to function's scope
let _guard = symtbl.push_scope();
- for (paramname, paramtype) in &*signature.params {
+ for (paramname, paramtype) in &signature.params {
let p = tck.insert_known(paramtype);
symtbl.add_var(*paramname, p, false);
}
@@ 1474,8 1472,7 @@ fn typecheck_expr(
tck.unify(symtbl, tid, body_type)?;
trace!("Done unifying type ctor");
// The type the expression returns
- let constructed_type =
- tck.insert_known(&Type::Named(*name, Arc::new(type_params.clone())));
+ let constructed_type = tck.insert_known(&Type::Named(*name, type_params.clone()));
tck.set_expr_type(expr, constructed_type);
Ok(constructed_type)
}
@@ 1626,7 1623,7 @@ fn predeclare_decls(tck: &mut Tck, symtb
} => {
// TODO: Kinda duplicated, not a huge fan.
let mut params = vec![];
- for (_paramname, paramtype) in &*signature.params {
+ for (_paramname, paramtype) in &signature.params {
let p = tck.insert_known(paramtype);
params.push(p);
}