1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//use super::Ctxt;
use common::Interner;

pub type TypeContext = Interner<Type>;

impl Type {
  pub fn int_size(&self) -> u32 {
    match *self {
      Type::Integer(size) => size,
    }
  }
}

#[derive(Debug, PartialEq, Eq, Hash)]
pub enum Type {
  Integer(u32),
  /*
  Void,
  Bool,
  Pointer,
  // FnPtr
  Aggregate(Vec<Type<'c>>),
  */
}

#[derive(Clone, Debug, Hash, PartialEq, Eq)]
pub struct Function<'t> {
  pub inputs: Box<[&'t Type]>,
  pub output: &'t Type,
}

mod fmt {
  use std::fmt::{Display, Formatter, Error};
  use super::{Type, Function};
  impl Display for Type {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
      match *self {
        Type::Integer(n) => write!(f, "i{}", n),
        /*
        TypeVariant::Bool => write!(f, "bool"),
        TypeVariant::Pointer => write!(f, "ptr"),
        TypeVariant::Aggregate(ref v) => {
          try!(write!(f, "("));
          if v.is_empty() {
            write!(f, ")")
          } else {
            for el in &v[..v.len() - 1] {
              try!(write!(f, "{}, ", el));
            }
            write!(f, "{})", &v[v.len() - 1])
          }
        }
        */
      }
    }
  }

  impl<'a> Display for Function<'a> {
    fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
      try!(write!(f, "("));
      if !self.inputs.is_empty() {
        for input in &self.inputs[..self.inputs.len() - 1] {
          try!(write!(f, "{}, ", input));
        }
        try!(write!(f, "{}", self.inputs[self.inputs.len() - 1]));
      }
      write!(f, ") -> {}", self.output)
    }
  }
}