about summary refs log tree commit diff
path: root/users/glittershark/achilles/src/passes/hir
diff options
context:
space:
mode:
Diffstat (limited to 'users/glittershark/achilles/src/passes/hir')
-rw-r--r--users/glittershark/achilles/src/passes/hir/mod.rs197
-rw-r--r--users/glittershark/achilles/src/passes/hir/monomorphize.rs139
-rw-r--r--users/glittershark/achilles/src/passes/hir/strip_positive_units.rs189
3 files changed, 0 insertions, 525 deletions
diff --git a/users/glittershark/achilles/src/passes/hir/mod.rs b/users/glittershark/achilles/src/passes/hir/mod.rs
deleted file mode 100644
index 845bfcb7ab6a..000000000000
--- a/users/glittershark/achilles/src/passes/hir/mod.rs
+++ /dev/null
@@ -1,197 +0,0 @@
-use std::collections::HashMap;
-
-use crate::ast::hir::{Binding, Decl, Expr};
-use crate::ast::{BinaryOperator, Ident, Literal, UnaryOperator};
-
-pub(crate) mod monomorphize;
-pub(crate) mod strip_positive_units;
-
-pub(crate) trait Visitor<'a, 'ast, T: 'ast>: Sized + 'a {
-    type Error;
-
-    fn visit_type(&mut self, _type: &mut T) -> Result<(), Self::Error> {
-        Ok(())
-    }
-
-    fn visit_ident(&mut self, _ident: &mut Ident<'ast>) -> Result<(), Self::Error> {
-        Ok(())
-    }
-
-    fn visit_literal(&mut self, _literal: &mut Literal<'ast>) -> Result<(), Self::Error> {
-        Ok(())
-    }
-
-    fn visit_unary_operator(&mut self, _op: &mut UnaryOperator) -> Result<(), Self::Error> {
-        Ok(())
-    }
-
-    fn visit_binary_operator(&mut self, _op: &mut BinaryOperator) -> Result<(), Self::Error> {
-        Ok(())
-    }
-
-    fn visit_binding(&mut self, binding: &mut Binding<'ast, T>) -> Result<(), Self::Error> {
-        self.visit_ident(&mut binding.ident)?;
-        self.visit_type(&mut binding.type_)?;
-        self.visit_expr(&mut binding.body)?;
-        Ok(())
-    }
-
-    fn post_visit_call(
-        &mut self,
-        _fun: &mut Expr<'ast, T>,
-        _type_args: &mut HashMap<Ident<'ast>, T>,
-        _args: &mut Vec<Expr<'ast, T>>,
-    ) -> Result<(), Self::Error> {
-        Ok(())
-    }
-
-    fn pre_visit_call(
-        &mut self,
-        _fun: &mut Expr<'ast, T>,
-        _type_args: &mut HashMap<Ident<'ast>, T>,
-        _args: &mut Vec<Expr<'ast, T>>,
-    ) -> Result<(), Self::Error> {
-        Ok(())
-    }
-
-    fn pre_visit_expr(&mut self, _expr: &mut Expr<'ast, T>) -> Result<(), Self::Error> {
-        Ok(())
-    }
-
-    fn visit_expr(&mut self, expr: &mut Expr<'ast, T>) -> Result<(), Self::Error> {
-        self.pre_visit_expr(expr)?;
-        match expr {
-            Expr::Ident(id, t) => {
-                self.visit_ident(id)?;
-                self.visit_type(t)?;
-            }
-            Expr::Literal(lit, t) => {
-                self.visit_literal(lit)?;
-                self.visit_type(t)?;
-            }
-            Expr::UnaryOp { op, rhs, type_ } => {
-                self.visit_unary_operator(op)?;
-                self.visit_expr(rhs)?;
-                self.visit_type(type_)?;
-            }
-            Expr::BinaryOp {
-                lhs,
-                op,
-                rhs,
-                type_,
-            } => {
-                self.visit_expr(lhs)?;
-                self.visit_binary_operator(op)?;
-                self.visit_expr(rhs)?;
-                self.visit_type(type_)?;
-            }
-            Expr::Let {
-                bindings,
-                body,
-                type_,
-            } => {
-                for binding in bindings.iter_mut() {
-                    self.visit_binding(binding)?;
-                }
-                self.visit_expr(body)?;
-                self.visit_type(type_)?;
-            }
-            Expr::If {
-                condition,
-                then,
-                else_,
-                type_,
-            } => {
-                self.visit_expr(condition)?;
-                self.visit_expr(then)?;
-                self.visit_expr(else_)?;
-                self.visit_type(type_)?;
-            }
-            Expr::Fun {
-                args,
-                body,
-                type_args,
-                type_,
-            } => {
-                for (ident, t) in args {
-                    self.visit_ident(ident)?;
-                    self.visit_type(t)?;
-                }
-                for ta in type_args {
-                    self.visit_ident(ta)?;
-                }
-                self.visit_expr(body)?;
-                self.visit_type(type_)?;
-            }
-            Expr::Call {
-                fun,
-                args,
-                type_args,
-                type_,
-            } => {
-                self.pre_visit_call(fun, type_args, args)?;
-                self.visit_expr(fun)?;
-                for arg in args.iter_mut() {
-                    self.visit_expr(arg)?;
-                }
-                self.visit_type(type_)?;
-                self.post_visit_call(fun, type_args, args)?;
-            }
-        }
-
-        Ok(())
-    }
-
-    fn post_visit_decl(&mut self, decl: &'a Decl<'ast, T>) -> Result<(), Self::Error> {
-        Ok(())
-    }
-
-    fn post_visit_fun_decl(
-        &mut self,
-        _name: &mut Ident<'ast>,
-        _type_args: &mut Vec<Ident>,
-        _args: &mut Vec<(Ident, T)>,
-        _body: &mut Box<Expr<T>>,
-        _type_: &mut T,
-    ) -> Result<(), Self::Error> {
-        Ok(())
-    }
-
-    fn visit_decl(&mut self, decl: &'a mut Decl<'ast, T>) -> Result<(), Self::Error> {
-        match decl {
-            Decl::Fun {
-                name,
-                type_args,
-                args,
-                body,
-                type_,
-            } => {
-                self.visit_ident(name)?;
-                for type_arg in type_args.iter_mut() {
-                    self.visit_ident(type_arg)?;
-                }
-                for (arg, t) in args.iter_mut() {
-                    self.visit_ident(arg)?;
-                    self.visit_type(t)?;
-                }
-                self.visit_expr(body)?;
-                self.visit_type(type_)?;
-                self.post_visit_fun_decl(name, type_args, args, body, type_)?;
-            }
-            Decl::Extern {
-                name,
-                arg_types,
-                ret_type,
-            } => {
-                self.visit_ident(name)?;
-                for arg_t in arg_types {
-                    self.visit_type(arg_t)?;
-                }
-                self.visit_type(ret_type)?;
-            }
-        }
-
-        self.post_visit_decl(decl)?;
-        Ok(())
-    }
-}
diff --git a/users/glittershark/achilles/src/passes/hir/monomorphize.rs b/users/glittershark/achilles/src/passes/hir/monomorphize.rs
deleted file mode 100644
index 251a988f4f6f..000000000000
--- a/users/glittershark/achilles/src/passes/hir/monomorphize.rs
+++ /dev/null
@@ -1,139 +0,0 @@
-use std::cell::RefCell;
-use std::collections::{HashMap, HashSet};
-use std::convert::TryInto;
-use std::mem;
-
-use void::{ResultVoidExt, Void};
-
-use crate::ast::hir::{Decl, Expr};
-use crate::ast::{self, Ident};
-
-use super::Visitor;
-
-#[derive(Default)]
-pub(crate) struct Monomorphize<'a, 'ast> {
-    decls: HashMap<&'a Ident<'ast>, &'a Decl<'ast, ast::Type<'ast>>>,
-    extra_decls: Vec<Decl<'ast, ast::Type<'ast>>>,
-    remove_decls: HashSet<Ident<'ast>>,
-}
-
-impl<'a, 'ast> Monomorphize<'a, 'ast> {
-    pub(crate) fn new() -> Self {
-        Default::default()
-    }
-}
-
-impl<'a, 'ast> Visitor<'a, 'ast, ast::Type<'ast>> for Monomorphize<'a, 'ast> {
-    type Error = Void;
-
-    fn post_visit_call(
-        &mut self,
-        fun: &mut Expr<'ast, ast::Type<'ast>>,
-        type_args: &mut HashMap<Ident<'ast>, ast::Type<'ast>>,
-        args: &mut Vec<Expr<'ast, ast::Type<'ast>>>,
-    ) -> Result<(), Self::Error> {
-        let new_fun = match fun {
-            Expr::Ident(id, _) => {
-                let decl: Decl<_> = (**self.decls.get(id).unwrap()).clone();
-                let name = RefCell::new(id.to_string());
-                let type_args = mem::take(type_args);
-                let mut monomorphized = decl
-                    .traverse_type(|ty| -> Result<_, Void> {
-                        Ok(ty.clone().traverse_type_vars(|v| {
-                            let concrete = type_args.get(&v).unwrap();
-                            name.borrow_mut().push_str(&concrete.to_string());
-                            concrete.clone()
-                        }))
-                    })
-                    .void_unwrap();
-                let name: Ident = name.into_inner().try_into().unwrap();
-                if name != *id {
-                    self.remove_decls.insert(id.clone());
-                    monomorphized.set_name(name.clone());
-                    let type_ = monomorphized.type_().unwrap().clone();
-                    self.extra_decls.push(monomorphized);
-                    Some(Expr::Ident(name, type_))
-                } else {
-                    None
-                }
-            }
-            _ => todo!(),
-        };
-        if let Some(new_fun) = new_fun {
-            *fun = new_fun;
-        }
-        Ok(())
-    }
-
-    fn post_visit_decl(
-        &mut self,
-        decl: &'a Decl<'ast, ast::Type<'ast>>,
-    ) -> Result<(), Self::Error> {
-        self.decls.insert(decl.name(), decl);
-        Ok(())
-    }
-}
-
-pub(crate) fn run_toplevel<'a>(toplevel: &mut Vec<Decl<'a, ast::Type<'a>>>) {
-    let mut pass = Monomorphize::new();
-    for decl in toplevel.iter_mut() {
-        pass.visit_decl(decl).void_unwrap();
-    }
-    let remove_decls = mem::take(&mut pass.remove_decls);
-    let mut extra_decls = mem::take(&mut pass.extra_decls);
-    toplevel.retain(|decl| !remove_decls.contains(decl.name()));
-    extra_decls.append(toplevel);
-    *toplevel = extra_decls;
-}
-
-#[cfg(test)]
-mod tests {
-    use std::convert::TryFrom;
-
-    use super::*;
-    use crate::parser::toplevel;
-    use crate::tc::typecheck_toplevel;
-
-    #[test]
-    fn call_id_decl() {
-        let (_, program) = toplevel(
-            "ty id : fn a -> a
-             fn id x = x
-
-             ty main : fn -> int
-             fn main = id 0",
-        )
-        .unwrap();
-        let mut program = typecheck_toplevel(program).unwrap();
-        run_toplevel(&mut program);
-
-        let find_decl = |ident: &str| {
-            program.iter().find(|decl| {
-                matches!(decl, Decl::Fun {name, ..} if name == &Ident::try_from(ident).unwrap())
-            }).unwrap()
-        };
-
-        let main = find_decl("main");
-        let body = match main {
-            Decl::Fun { body, .. } => body,
-            _ => unreachable!(),
-        };
-
-        let expected_type = ast::Type::Function(ast::FunctionType {
-            args: vec![ast::Type::Int],
-            ret: Box::new(ast::Type::Int),
-        });
-
-        match &**body {
-            Expr::Call { fun, .. } => {
-                let fun = match &**fun {
-                    Expr::Ident(fun, _) => fun,
-                    _ => unreachable!(),
-                };
-                let called_decl = find_decl(fun.into());
-                assert_eq!(called_decl.type_().unwrap(), &expected_type);
-            }
-            _ => unreachable!(),
-        }
-    }
-}
diff --git a/users/glittershark/achilles/src/passes/hir/strip_positive_units.rs b/users/glittershark/achilles/src/passes/hir/strip_positive_units.rs
deleted file mode 100644
index 91b56551c82d..000000000000
--- a/users/glittershark/achilles/src/passes/hir/strip_positive_units.rs
+++ /dev/null
@@ -1,189 +0,0 @@
-use std::collections::HashMap;
-use std::mem;
-
-use ast::hir::Binding;
-use ast::Literal;
-use void::{ResultVoidExt, Void};
-
-use crate::ast::hir::{Decl, Expr};
-use crate::ast::{self, Ident};
-
-use super::Visitor;
-
-/// Strip all values with a unit type in positive (non-return) position
-pub(crate) struct StripPositiveUnits {}
-
-impl<'a, 'ast> Visitor<'a, 'ast, ast::Type<'ast>> for StripPositiveUnits {
-    type Error = Void;
-
-    fn pre_visit_expr(
-        &mut self,
-        expr: &mut Expr<'ast, ast::Type<'ast>>,
-    ) -> Result<(), Self::Error> {
-        let mut extracted = vec![];
-        if let Expr::Call { args, .. } = expr {
-            // TODO(grfn): replace with drain_filter once it's stabilized
-            let mut i = 0;
-            while i != args.len() {
-                if args[i].type_() == &ast::Type::Unit {
-                    let expr = args.remove(i);
-                    if !matches!(expr, Expr::Literal(Literal::Unit, _)) {
-                        extracted.push(expr)
-                    };
-                } else {
-                    i += 1
-                }
-            }
-        }
-
-        if !extracted.is_empty() {
-            let body = mem::replace(expr, Expr::Literal(Literal::Unit, ast::Type::Unit));
-            *expr = Expr::Let {
-                bindings: extracted
-                    .into_iter()
-                    .map(|expr| Binding {
-                        ident: Ident::from_str_unchecked("___discarded"),
-                        type_: expr.type_().clone(),
-                        body: expr,
-                    })
-                    .collect(),
-                type_: body.type_().clone(),
-                body: Box::new(body),
-            };
-        }
-
-        Ok(())
-    }
-
-    fn post_visit_call(
-        &mut self,
-        _fun: &mut Expr<'ast, ast::Type<'ast>>,
-        _type_args: &mut HashMap<Ident<'ast>, ast::Type<'ast>>,
-        args: &mut Vec<Expr<'ast, ast::Type<'ast>>>,
-    ) -> Result<(), Self::Error> {
-        args.retain(|arg| arg.type_() != &ast::Type::Unit);
-        Ok(())
-    }
-
-    fn visit_type(&mut self, type_: &mut ast::Type<'ast>) -> Result<(), Self::Error> {
-        if let ast::Type::Function(ft) = type_ {
-            ft.args.retain(|a| a != &ast::Type::Unit);
-        }
-        Ok(())
-    }
-
-    fn post_visit_fun_decl(
-        &mut self,
-        _name: &mut Ident<'ast>,
-        _type_args: &mut Vec<Ident>,
-        args: &mut Vec<(Ident, ast::Type<'ast>)>,
-        _body: &mut Box<Expr<ast::Type<'ast>>>,
-        _type_: &mut ast::Type<'ast>,
-    ) -> Result<(), Self::Error> {
-        args.retain(|(_, ty)| ty != &ast::Type::Unit);
-        Ok(())
-    }
-}
-
-pub(crate) fn run_toplevel<'a>(toplevel: &mut Vec<Decl<'a, ast::Type<'a>>>) {
-    let mut pass = StripPositiveUnits {};
-    for decl in toplevel.iter_mut() {
-        pass.visit_decl(decl).void_unwrap();
-    }
-}
-
-#[cfg(test)]
-mod tests {
-    use super::*;
-    use crate::parser::toplevel;
-    use crate::tc::typecheck_toplevel;
-    use pretty_assertions::assert_eq;
-
-    #[test]
-    fn unit_only_arg() {
-        let (_, program) = toplevel(
-            "ty f : fn () -> int
-             fn f _ = 1
-
-             ty main : fn -> int
-             fn main = f ()",
-        )
-        .unwrap();
-
-        let (_, expected) = toplevel(
-            "ty f : fn -> int
-             fn f = 1
-
-             ty main : fn -> int
-             fn main = f()",
-        )
-        .unwrap();
-        let expected = typecheck_toplevel(expected).unwrap();
-
-        let mut program = typecheck_toplevel(program).unwrap();
-        run_toplevel(&mut program);
-
-        assert_eq!(program, expected);
-    }
-
-    #[test]
-    fn unit_and_other_arg() {
-        let (_, program) = toplevel(
-            "ty f : fn (), int -> int
-             fn f _ x = x
-
-             ty main : fn -> int
-             fn main = f () 1",
-        )
-        .unwrap();
-
-        let (_, expected) = toplevel(
-            "ty f : fn int -> int
-             fn f x = x
-
-             ty main : fn -> int
-             fn main = f 1",
-        )
-        .unwrap();
-        let expected = typecheck_toplevel(expected).unwrap();
-
-        let mut program = typecheck_toplevel(program).unwrap();
-        run_toplevel(&mut program);
-
-        assert_eq!(program, expected);
-    }
-
-    #[test]
-    fn unit_expr_and_other_arg() {
-        let (_, program) = toplevel(
-            "ty f : fn (), int -> int
-             fn f _ x = x
-
-             ty g : fn int -> ()
-             fn g _ = ()
-
-             ty main : fn -> int
-             fn main = f (g 2) 1",
-        )
-        .unwrap();
-
-        let (_, expected) = toplevel(
-            "ty f : fn int -> int
-             fn f x = x
-
-             ty g : fn int -> ()
-             fn g _ = ()
-
-             ty main : fn -> int
-             fn main = let ___discarded = g 2 in f 1",
-        )
-        .unwrap();
-        assert_eq!(expected.len(), 6);
-        let expected = typecheck_toplevel(expected).unwrap();
-
-        let mut program = typecheck_toplevel(program).unwrap();
-        run_toplevel(&mut program);
-
-        assert_eq!(program, expected);
-    }
-}