Skip to content

Commit

Permalink
finish Memory Access - Basic test/week 07
Browse files Browse the repository at this point in the history
  • Loading branch information
luismomm2110 committed Nov 17, 2021
1 parent b3d3660 commit 5bab8c7
Show file tree
Hide file tree
Showing 3 changed files with 368 additions and 0 deletions.
199 changes: 199 additions & 0 deletions projects/07/CodeWriter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
import java.io.*;

public class CodeWriter {
private static Integer numJump;
private String pathAssembly;
private File assemblyTranslate;
public FileWriter assemblyWriter;

public CodeWriter(String pathAssembly) throws IOException {

this.pathAssembly = pathAssembly;
CodeWriter.numJump = 0;
this.assemblyTranslate = new File(pathAssembly.replace(".vm", ".asm"));
System.out.println(pathAssembly.replace(".vm", ".asm"));
try {
this.assemblyWriter = new FileWriter(this.assemblyTranslate);
} catch (FileNotFoundException e) {
System.out.println("File not found!");
}
}

public void writeArithmetic(String arg1) throws IOException {

this.assemblyWriter.write("//" + arg1 + "\n");

switch (arg1) {

case "add":
this.assemblyWriter.write(backSP() + "M=D\n" + backSP() + "M=M+D\n" + advSP());
break;

case "sub":
this.assemblyWriter.write(backSP() + "D=M\n" + backSP() + "M=M-D\n" + advSP());
break;

case "neg":
this.assemblyWriter.write(backSP() + "M=-M\n" + advSP());
break;

case "eq":
this.assemblyWriter.write(compCommands("eq"));
break;

case "gt":
this.assemblyWriter.write(compCommands("gt"));
break;

case "lt":
this.assemblyWriter.write(compCommands("lt"));
break;

case "and":
this.assemblyWriter.write(backSP() + "D=M\n" + backSP() + "M=M&D\n" + advSP());
break;

case "or":
this.assemblyWriter.write(backSP() + "D=M\n" + backSP() + "M=M|D\n" + advSP());
break;

case "not":
this.assemblyWriter.write(backSP() + "M=!M\n" + advSP());
break;

default:
System.out.println("Error parsing arithmetic command");
return;
}

}

public void writePushPop(int command, String segment, int c_index) throws IOException {

this.assemblyWriter
.write("//" + Integer.toString(command) + " " + segment + " " + Integer.toString(c_index) + "\n");

if (command == 1) {
handlePush(segment, c_index);
} else if (command == 2) {
handlePop(segment, c_index);
}
}

public void writeLabel(String segment) throws IOException {
this.assemblyWriter.write("($null" + segment + ")\n");
}

public void writeIf(String segment) throws IOException {
this.assemblyWriter.write("@SP\n" + "M=M-1\n" + "A=M\n" + "@null$" + segment + "\n" + "D;JME\n");
}

public void writeGo(String segment) throws IOException {
this.assemblyWriter.write("@null$" + segment + "\n" + "0;JMP\n");
}

private String chooseSeg(String segment, int c_index) {
String seg = "";

switch (segment) {
case ("local"):
seg = "@LCL";
break;

case ("argument"):
seg = "@ARG";
break;

case ("this"):
seg = "@THIS";
break;

case ("that"):
seg = "@THAT";
break;

case ("temp"):
seg = "@5";
return (seg + "\n" + "D=A\n" + "@" + Integer.toString(c_index) + "\n");

default:
return "";
}
return (seg + "\n" + "D=M\n" + "@" + Integer.toString(c_index) + "\n");
}

private String compCommands(String type) {
String comparison = "\n";

if (type.equals("eq")) {
comparison = "D;JNE\n";
} else if (type.equals("gt")) {
comparison = "D;JLE\n";
} else if (type.equals("lt")) {
comparison = "D;JGE\n";
}

numJump++;

return this.backSP() + "D=M\n" + backSP() + "D=M-D\n" + "@FALSE" + numJump + "\n" + comparison + "@SP\n"
+ "A=M\n" + "M=-1\n" + "@CONTINUE" + numJump + "\n" + "D;JMP\n" + "(FALSE" + numJump + ")\n" + "@SP\n"
+ "A=M\n" + "M=0\n" + "(CONTINUE" + numJump + ")\n" + advSP();
}

private String staticName(int index) {
String name = this.assemblyTranslate.getName().replace(".asm", ("." + Integer.toString(index)));
return "@" + name + "\n";
}

private String backSP() {
return "@SP\n" + "AM=M-1\n";
}

private String advSP() {
return "@SP\n" + "M=M+1\n";
}

private void handlePush(String segment, int c_index) throws IOException {
// push constant
if (segment.equals("constant")) {
this.assemblyWriter
.write("@" + Integer.toString(c_index) + "\n" + "D=A\n" + "@SP\n" + "A=M\n" + "M=D\n" + advSP());

// push local, static, this, that
} else if (!chooseSeg(segment, c_index).isBlank()) {
this.assemblyWriter
.write(chooseSeg(segment, c_index) + "A=A+D\n" + "D=M\n" + "@SP\n" + "A=M\n" + "M=D\n" + advSP());

// push temp
} else if (segment.equals("temp")) {
this.assemblyWriter.write(
"@R" + Integer.toString(5 + c_index) + "\n" + "D=M\n" + "@SP\n" + "A=M\n" + "M=D\n" + advSP());

// push pointer
} else if (segment.equals("pointer")) {
this.assemblyWriter.write(
"@" + Integer.toString(3 + c_index) + "\n" + "D=M\n" + "@SP\n" + "A=M\n" + "M=D\n" + advSP());

// push static
} else if (segment.equals("static")) {
this.assemblyWriter.write(staticName(c_index) + "D=M\n" + "@SP\n" + "A=M\n" + "M=D\n" + advSP());

} else {
this.assemblyWriter.write("ERROR IN COMMAND PUSH");
}
}

private void handlePop(String segment, int c_index) throws IOException {

this.assemblyWriter.write(chooseSeg(segment, c_index) + "D=A+D\n" + "@R13\n" + "M=D\n" + backSP() + "A=M\n" + "D=A\n"
+ "@R13\n" + "A=M\n" + "M=D\n");

}

public void close() throws IOException {
this.assemblyWriter.write("(END)\n");
this.assemblyWriter.write("@END\n");
this.assemblyWriter.write("0;JMP\n");
this.assemblyWriter.close();
}
}
47 changes: 47 additions & 0 deletions projects/07/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import java.io.IOException;

public class Main {

public static void main(String[] args) throws IOException {

Parser parser = new Parser(args[0]);
CodeWriter codeWriter = new CodeWriter(args[0]);

while (parser.hasMoreCommands()) {
parser.advance();

switch (parser.commandType()) {

case 0:
codeWriter.writeArithmetic(parser.arg1());
break;

case 1:
case 2:
System.out.println(parser.commandType() + parser.arg1() + parser.arg2());
codeWriter.writePushPop(parser.commandType(), parser.arg1(), parser.arg2());
break;

case 3:
System.out.println(parser.arg1());
codeWriter.writeLabel(parser.arg1());
break;

case 4:
System.out.println(parser.arg1());
codeWriter.writeGo(parser.arg1());
break;

case 5:
System.out.println(parser.arg1());
codeWriter.writeIf(parser.arg1());
break;

default:
System.out.println("TODO");
return;
}
}
codeWriter.close();
}
}
122 changes: 122 additions & 0 deletions projects/07/Parser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;

class Parser {

String[] currentCommand;
BufferedReader myReader;
File vmTranslate;
String pathVM;
private int currentLine = 0;
private ArrayList<String> lines;
public static final int ARITHMETIC = 0;
public static final int PUSH = 1;
public static final int POP = 2;
public static final int LABEL = 3;
public static final int GOTO = 4;
public static final int IF = 5;
public static final int FUNCTION = 6;
public static final int RETURN = 7;
public static final int CALL = 8;
public static final ArrayList<String> arithmeticCmds = new ArrayList<String>();

static {

arithmeticCmds.add("add");
arithmeticCmds.add("sub");
arithmeticCmds.add("neg");
arithmeticCmds.add("eq");
arithmeticCmds.add("gt");
arithmeticCmds.add("lt");
arithmeticCmds.add("and");
arithmeticCmds.add("or");
arithmeticCmds.add("not");
}

public Parser(String pathVM) throws IOException {
this.pathVM = pathVM;
this.currentCommand = new String[3];
this.lines = new ArrayList<String>();
File vmCode = new File(this.pathVM);
try {
this.myReader = new BufferedReader(new FileReader(vmCode));
String line = this.myReader.readLine();
while (line != null) {
line = line.replaceAll("//.+", "");
if (line.equals("")) {
line = this.myReader.readLine();
continue;
}
this.lines.add(line);
line = this.myReader.readLine();
}
myReader.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}

}

public boolean hasMoreCommands() {
return currentLine <= this.lines.size() - 1;
}

public void advance() {
this.currentCommand = this.lines.get(currentLine).trim().split(" ");
currentLine++;
}

public int commandType() {

String currentType = this.currentCommand[0];

if (arithmeticCmds.contains(currentType)) {
return ARITHMETIC;
} else if (currentType.equals("push")) {
return PUSH;
} else if (currentType.equals("pop")) {
return POP;
} else if (currentType.equals("label")) {
return LABEL;
} else if (currentType.equals("goto")) {
return GOTO;
} else if (currentType.equals("if-goto")) {
return IF;
} else if (currentType.equals("function")) {
return FUNCTION;
} else if (currentType.equals("return")) {
return RETURN;
} else if (currentType.equals("call")) {
return CALL;
}

System.out.println(currentType);
return -1;
}

public String arg1() {

if (this.commandType() == RETURN) {
throw new IllegalStateException("RETURN command!");
} else if (this.commandType() == ARITHMETIC) {
return this.currentCommand[0];
} else {
return this.currentCommand[1];
}

}

public int arg2() {

if (this.commandType() == PUSH | this.commandType() == POP | this.commandType() == CALL
| this.commandType() == FUNCTION) {
return Integer.parseInt(this.currentCommand[2]);
} else {
throw new IllegalArgumentException("Ilegal command!");
}
}
}

0 comments on commit 5bab8c7

Please sign in to comment.