summaryrefslogtreecommitdiff
path: root/V2VM.java
blob: dd83d1427e7ac5094bd6ec7070b2de4b5f22e2ce (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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133

import java.io.*;
import java.util.ArrayList;
import cs132.util.ProblemException;
import cs132.vapor.parser.VaporParser;
import cs132.vapor.ast.VaporProgram;
import cs132.vapor.ast.VBuiltIn.Op;
import cs132.vapor.ast.VDataSegment;
import cs132.vapor.ast.VFunction;
import cs132.vapor.ast.VInstr;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.Arrays;

import cfg.*;
import misc.*;
import vaporize.*;

public class V2VM {


    public static void main(String[] args) {

        try {
            byte[] bytes = readAllBytes(System.in);
            InputStream is1 = new ByteArrayInputStream(bytes);
            InputStream is2 = new ByteArrayInputStream(bytes);

            InputStream systemInCopy = createCopyOfSystemIn();
            ArrayList<String> strProg = inputStreamToArrayList(is1);

            VaporProgram prog = parseVapor(is2, System.out);

            MinimalLogger.info(String.format("Generating Intervals..."));
            LIRVisitor lv = new LIRVisitor(prog, strProg);
            ArrayList<LIRDict> lvs = lv.getLIRs();

            for (LIRDict interval : lvs) {
                MinimalLogger.info(String.format("Starting Linear Allocation for %s...",
                                                 interval.getFunction()));
                new RegisterAlloc(interval, Arrays.copyOfRange(prog.registers, 9, 22)); // spill registers: t0, t1, t2
            }

            MinimalLogger.info("Removing extraneous lines from the program representation...");
            for (String line : new ArrayList<String>(strProg)) {
                // delete all lines not a function table!
                if (!line.trim().startsWith("const") && !line.trim().startsWith(":"))
                    strProg.remove(line);
            }
            MinimalLogger.info(String.format("New program: %s",
                                             strProg.toString()));
            VaporizeVisitor vv = new VaporizeVisitor(prog, strProg, lvs);
            System.out.println(String.join("\n", vv.getVaporm()));

        } catch (IOException e) {
            System.out.println(e.toString());
            System.exit(1);
        }
    }

    public static VaporProgram parseVapor(InputStream in, PrintStream err) throws IOException {
        Op[] ops = {
            Op.Add, Op.Sub, Op.MulS, Op.Eq, Op.Lt, Op.LtS,
            Op.PrintIntS, Op.HeapAllocZ, Op.Error,
        };
        boolean allowLocals = true;
        String[] registers = {
            "$v0", "$v1",
            "$a0", "$a1", "$a2", "$a3",
            "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7",
            "$s0", "$s1", "$s2", "$s3", "$s4", "$s5", "$s6", "$s7",
            "$t8",
        };
        boolean allowStack = false;

        VaporProgram program;
        try {
            program = VaporParser.run(new InputStreamReader(in), 1, 1,
                                      java.util.Arrays.asList(ops),
                                      allowLocals, registers, allowStack);
        } catch (ProblemException ex) {
            err.println(ex.getMessage());
            return null;
        }

        return program;
    }

    public static ArrayList<String> inputStreamToArrayList(InputStream inputStream) {
        ArrayList<String> lines = new ArrayList<>();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream))) {
            String line;
            while ((line = reader.readLine()) != null) {
                lines.add(line);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return lines;
    }

    public static byte[] readAllBytes(InputStream inputStream) throws IOException {
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        int nRead;
        byte[] data = new byte[1024];
        while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
            buffer.write(data, 0, nRead);
        }
        buffer.flush();
        return buffer.toByteArray();
    }

    private static InputStream createCopyOfSystemIn() {
        byte[] buffer = new byte[1024];
        int bytesRead;
        ByteArrayInputStream bais = new ByteArrayInputStream(buffer);

        try {
            bytesRead = System.in.read(buffer);
            bais = new ByteArrayInputStream(buffer, 0, bytesRead);
        } catch (IOException e) {
            e.printStackTrace();
        }

        return bais;
    }

}