summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbd-912 <bdunahu@colostate.edu>2024-05-06 00:59:26 -0600
committerbd-912 <bdunahu@colostate.edu>2024-05-06 00:59:26 -0600
commit8e33e2828ffc62238afc32bb2593b8619f586077 (patch)
tree60158e69db97739d5e7512210f53c9d2f99fc62d
parent925372248bfb45e0027cf71d8d40c26e48261ee5 (diff)
Partial implementation for starter Condense
-rw-r--r--VM2M.java94
-rw-r--r--condense/CondenseVisitor.java165
-rw-r--r--condense/StackHelper.java70
-rw-r--r--condense/Utilities.java40
-rw-r--r--misc/MinimalSimpleFormatter.java2
5 files changed, 318 insertions, 53 deletions
diff --git a/VM2M.java b/VM2M.java
index e368aa1..d38e5c5 100644
--- a/VM2M.java
+++ b/VM2M.java
@@ -1,5 +1,14 @@
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.util.Arrays;
import condense.*;
import misc.*;
@@ -8,7 +17,88 @@ public class VM2M {
public static void main(String[] args) {
- ArrayList<String> strProgram = SplitProgramInputStream.split(System.in);
- CondenseVisitor cv = new CondenseVisitor(strProgram);
+ try {
+ byte[] bytes = readAllBytes(System.in);
+ InputStream is1 = new ByteArrayInputStream(bytes);
+ InputStream is2 = new ByteArrayInputStream(bytes);
+
+ InputStream systemInCopy = createCopyOfSystemIn();
+ ArrayList<String> strProg = SplitProgramInputStream.split(is1);
+
+ VaporProgram prog = parseVapor(is2, System.out);
+
+ 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()));
+
+ CondenseVisitor cv = new CondenseVisitor(prog, strProg);
+
+ System.out.println(String.join("\n", cv.getMIPS()));
+
+ } 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 = false;
+ 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 = true;
+
+ 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 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;
+ }
+
+
}
diff --git a/condense/CondenseVisitor.java b/condense/CondenseVisitor.java
index d494845..4ca987c 100644
--- a/condense/CondenseVisitor.java
+++ b/condense/CondenseVisitor.java
@@ -1,23 +1,168 @@
package condense;
+import cs132.vapor.ast.*;
import misc.*;
+
import java.util.*;
+import java.util.regex.*;
-public class CondenseVisitor {
+public class CondenseVisitor extends VInstr.Visitor<RuntimeException>{
ArrayList<String> vaporm;
ArrayList<String> mips;
- public CondenseVisitor(ArrayList<String> vaporm) {
+ StackHelper curr;
+
+ public CondenseVisitor(VaporProgram vp, ArrayList<String> vaporm) {
this.vaporm = vaporm;
this.mips = new ArrayList<String>();
- for (instr : this.vaporm) {
- instr = instr.trim();
- if (instr.startsWith("local")) {
- // store
- this.store(instr);
- } else if (instr
- }
- }
+ for (int i = 0; i < vp.functions.length; ++i) {
+ this.curr = new StackHelper(vp.functions[i].stack);
+ this.addMIPS(vp.functions[i].ident+":");
+
+ // prologue
+ this.addMIPS(" sw $fp -8($sp)");
+ this.addMIPS(" move $fp $sp");
+ this.addMIPS(String.format(" subu $sp $sp %d",
+ this.curr.getFrameSize()));
+ this.addMIPS(" sw $ra -4($fp)");
+
+ TreeSet<Node> f = this.sortFunction(vp.functions[i]);
+ MinimalLogger.info(String.format("Starting loop with function:\n %s",
+ f.toString()));
+
+ for (Node n : f) {
+ if (n instanceof VInstr) {
+ ((VInstr) n).accept(this);
+ }
+ else
+ this.addMIPS(((VCodeLabel) n).ident + ":");
+ }
+
+ }
+ }
+
+ public ArrayList<String> getMIPS() {
+ return this.mips;
+ }
+
+ public void addMIPS(String str) {
+ MinimalLogger.info(String.format("Adding string:\n%s",
+ str));
+
+ this.mips.add(str);
+ }
+
+ public TreeSet<Node> sortFunction(VFunction f) {
+ TreeSet<Node> sort = new TreeSet<Node>((v1, v2) -> {
+ return Integer.compare(v1.sourcePos.line, v2.sourcePos.line);
+ });
+
+ for (VInstr s : f.body) {
+ sort.add(s);
+ }
+ for (VCodeLabel l : f.labels) {
+ sort.add(l);
+ }
+ return sort;
+ }
+
+ public void visit(VAssign n) throws RuntimeException {
+ MinimalLogger.info(String.format("->%s (%s)",
+ n.getClass().getSimpleName(),
+ n.sourcePos.toString()));
+ ///////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////
+ MinimalLogger.info(String.format("<-%s (%s)",
+ n.getClass().getSimpleName(),
+ n.sourcePos.toString()));
+ }
+
+ public void visit(VCall n) throws RuntimeException {
+ MinimalLogger.info(String.format("->%s (%s)",
+ n.getClass().getSimpleName(),
+ n.sourcePos.toString()));
+ ///////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////
+ MinimalLogger.info(String.format("<-%s (%s)",
+ n.getClass().getSimpleName(),
+ n.sourcePos.toString()));
+ }
+
+ public void visit(VBuiltIn n) throws RuntimeException {
+ MinimalLogger.info(String.format("->%s (%s)",
+ n.getClass().getSimpleName(),
+ n.sourcePos.toString()));
+ ///////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////
+ MinimalLogger.info(String.format("<-%s (%s)",
+ n.getClass().getSimpleName(),
+ n.sourcePos.toString()));
+ }
+
+ public void visit(VMemWrite n) throws RuntimeException {
+ MinimalLogger.info(String.format("->%s (%s)",
+ n.getClass().getSimpleName(),
+ n.sourcePos.toString()));
+ ///////////////////////////////////////////////////////////////
+ this.addMIPS(String.format(" sw %s %s",
+ n.source.toString(),
+ this.curr.get(((VMemRef.Stack) n.dest))));
+ ///////////////////////////////////////////////////////////////
+ MinimalLogger.info(String.format("<-%s (%s)",
+ n.getClass().getSimpleName(),
+ n.sourcePos.toString()));
+ }
+
+ public void visit(VMemRead n) throws RuntimeException {
+ MinimalLogger.info(String.format("->%s (%s)",
+ n.getClass().getSimpleName(),
+ n.sourcePos.toString()));
+ ///////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////
+ MinimalLogger.info(String.format("<-%s (%s)",
+ n.getClass().getSimpleName(),
+ n.sourcePos.toString()));
+ }
+
+ public void visit(VBranch n) throws RuntimeException {
+ MinimalLogger.info(String.format("->%s (%s)",
+ n.getClass().getSimpleName(),
+ n.sourcePos.toString()));
+ ///////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////
+ MinimalLogger.info(String.format("<-%s (%s)",
+ n.getClass().getSimpleName(),
+ n.sourcePos.toString()));
+ }
+
+ public void visit(VGoto n) throws RuntimeException {
+ MinimalLogger.info(String.format("->%s (%s)",
+ n.getClass().getSimpleName(),
+ n.sourcePos.toString()));
+ ///////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////
+ MinimalLogger.info(String.format("<-%s (%s)",
+ n.getClass().getSimpleName(),
+ n.sourcePos.toString()));
+ }
+
+ public void visit(VReturn n) throws RuntimeException {
+ MinimalLogger.info(String.format("->%s (%s)",
+ n.getClass().getSimpleName(),
+ n.sourcePos.toString()));
+ ///////////////////////////////////////////////////////////////
+
+ ///////////////////////////////////////////////////////////////
+ MinimalLogger.info(String.format("<-%s (%s)",
+ n.getClass().getSimpleName(),
+ n.sourcePos.toString()));
}
+}
diff --git a/condense/StackHelper.java b/condense/StackHelper.java
new file mode 100644
index 0000000..a0a6e2d
--- /dev/null
+++ b/condense/StackHelper.java
@@ -0,0 +1,70 @@
+package condense;
+
+import misc.*;
+import cs132.vapor.ast.VFunction;
+import cs132.vapor.ast.VMemRef;
+
+import java.util.*;
+
+public class StackHelper {
+
+ private int in;
+ private int out;
+ private int local;
+ private int frame_size;
+ private HashMap<String, String> idx_to_addr;
+
+ public StackHelper(VFunction.Stack s) {
+ this.in = s.in;
+ this.out = s.out;
+ this.local = s.local;
+ this.frame_size = this.stackFrameFormula();
+ this.idx_to_addr = new HashMap<String,String>();
+ MinimalLogger.info(String.format("Found in:%d out:%d local%d framesize:%d...",
+ this.in,
+ this.out,
+ this.local,
+ this.frame_size));
+
+ String key;
+ String value;
+ int loc;
+ for (int i = 0; i < this.local; ++i) { // locals
+ loc = (( -i - 1 ) * 4) - 8;
+ key = String.format("Local[%d]", i);
+ value = String.format("%d($fp)", loc);
+ this.idx_to_addr.put(key, value);
+ }
+ for (int i = 0; i < this.out; ++i) { // out
+ loc = ((this.out + this.local + 2) - i) * -4;
+ key = String.format("Out[%d]", i);
+ value = String.format("%d($fp)", loc);
+ this.idx_to_addr.put(key, value);
+ }
+ for (int i = 0; i < this.in; ++i) { // in
+ loc = i * 4;
+ key = String.format("In[%d]", i);
+ value = String.format("%d($fp)", loc);
+ this.idx_to_addr.put(key, value);
+ }
+
+ MinimalLogger.info(String.format("Mapping: %s", this.idx_to_addr.toString()));
+ }
+
+ public String get(VMemRef.Stack m) {
+ String key = String.format("%s[%d]",
+ m.region,
+ m.index);
+ MinimalLogger.severe(key);
+ return this.idx_to_addr.get(key);
+ }
+
+ public int getFrameSize() {
+ return this.frame_size;
+ }
+
+ private int stackFrameFormula() {
+ return (this.out + this.local + 2) * 4;
+ }
+
+}
diff --git a/condense/Utilities.java b/condense/Utilities.java
deleted file mode 100644
index 9c052fc..0000000
--- a/condense/Utilities.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package condense;
-
-import java.util.*;
-
-public class Utilities {
-
-
- public static int computeStackFrameSize(String declare) {
- MinimalLogger.info(String.format("Computing frame stack size for %s...",
- declare));
- declare = extractNumeric(declare);
- // assume that the LAST three digits are
- // in, out, local
- String[] sizes = declare.split(SPACE)[:-3];
- int ret = this.stackFrameFormula(Integer.parseInt(sizes[1]),
- Integer.parseInt(sizes[2]));
- MinimalLogger.info(String.format("Stack size is (%s + %s + 2) * 4 = %d",
- sizes[1],
- sizes[2],
- ret));
- return ret;
- }
-
- private static int stackFrameFormula(int out, int local) {
- return (out + local + 2) * 4;
- }
-
- private static int extractNumeric(String str) {
- str = str.replaceAll("[^\\d] & quot;, "
- ");
- str = str.trim();
- str = str.replaceAll(" + ", "
- ");
- if (str.equals(" "))
- return "
- -1 & quot;
- ;
- return str;
- }
-}
diff --git a/misc/MinimalSimpleFormatter.java b/misc/MinimalSimpleFormatter.java
index 741863d..a325185 100644
--- a/misc/MinimalSimpleFormatter.java
+++ b/misc/MinimalSimpleFormatter.java
@@ -7,7 +7,7 @@ import java.util.logging.SimpleFormatter;
public class MinimalSimpleFormatter extends SimpleFormatter {
@Override
public String format(LogRecord record) {
- if (false)
+ if (true)
return record.getLevel() + ": " + formatMessage(record) + "\n";
else
return "";