summaryrefslogtreecommitdiff
path: root/src/semantic/frame.rs
blob: 5b7bfaafef40633b22778f8010323c030b33ee9e (plain)
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
72
use super::ir;
use super::temp;

pub enum Location {
    InFrame {
        offset: usize,
    },
    Register(temp::TempName),
}

pub enum Escape {
    No,
    Yes,
}

pub trait Frame {
    fn new<I: Iterator<Item=Escape>>(name: temp::TempLabel, formals: I) -> Self;
    fn name(&self) -> temp::TempLabel;
    fn formals(&self) -> &[Location];
    fn alloc_local(&mut self, temp: &mut temp::Temp, escapes: Escape) -> Location;
    fn location_to_exp(&mut self, location: Location) -> ir::Expression;
    fn to_exp(&self) -> ir::Expression {
        ir::Expression::Name(self.name())
    }
}

pub struct Amd64Frame {
    offset: u64,
    name: temp::TempLabel,
}

impl Frame for Amd64Frame {
    fn new<I: Iterator<Item=Escape>>(name: temp::TempLabel, formals: I) -> Self {
        Amd64Frame {
            offset: 0,
            name: name,
        }
    }

    fn name(&self) -> temp::TempLabel {
        self.name
    }

    fn formals(&self) -> &[Location] {
        unimplemented!();
    }

    fn alloc_local(&mut self, temp: &mut temp::Temp, escapes: Escape) -> Location {
        // TODO: this is WRONG
        Location::InFrame { offset: 0 }
    }

    fn location_to_exp(&mut self, location: Location) -> ir::Expression {
        match location {
            Location::InFrame { offset } => {
                ir::Expression::Memory(
                    Box::new(
                        ir::Expression::BinOp(
                            ir::BinOp::Plus,
                            Box::new(ir::Expression::Const(self.offset)),
                            Box::new(ir::Expression::Const(offset as u64)),
                        )
                    )
                )
            }
            Location::Register(name) => {
                ir::Expression::Temp(name)
            }
        }

    }
}