patternjavaMinor
Assembler for Hack Assembly Language from nand2tetris in Java
Viewed 0 times
javalanguageassemblyassemblerforhackfromnand2tetris
Problem
I have been doing a brilliant course on coursera based on the book "The Elements of Computing Systems: Building a Modern Computer from First Principles" by Simon Schocken and Noam Nisan.
You can find the specification for the Hack Machine Language and the Hack Assembly Language here.
In essence, you are given a text file containing a list of commands in the Hack Assembly Language (a very simplified fictitious assembly language) and you are to convert it to binary, storing the result in another file.
Please advise me on how I can make this better, more efficient, readable, maintainable etc.
Here is my implementation:
```
import java.io.*;
import java.lang.*;
import java.util.regex.*;
import java.util.HashMap;
public class Main {
private String file;
private int pc = 0;
public Main( String fin ) {
file = fin;
}
public void main( String[] args ) throws IOException, Exception {
// CREATE INSTANCES OF OTHER MODULES
Parser fp = new Parser( args[ 0 ] );
Parser sp = new Parser( args[ 0 ] );
Code code = new Code();
HashMap st = new HashMap();
// SYMBOL TABLE INITIALIZATION
st.put( "R0", "0" ); st.put( "R1", "1" ); st.put( "R2", "2" ); st.put( "R3", "3" ); st.put( "R4", "4" ); st.put( "R5", "5" ); st.put( "R6", "6" ); st.put( "R7", "7" );
st.put( "R8", "8" ); st.put( "R9", "9" ); st.put( "R10", "10" ); st.put( "R11", "11" ); st.put( "R12", "12" ); st.put( "R13", "13" ); st.put( "R14", "14" ); st.put( "R15", "15" );
st.put( "SCREEN", "16384" ); st.put( "KBD", "24576" );
st.put( "SP", "0" ); st.put( "LCL", "1" ); st.put( "ARG", "2" ); st.put( "THIS", "3" ); st.put( "THAT", "4" );
// FIRST PASS
fp.advance();
while( fp.command != null ) {
if( fp.commandType() == "L_COMMAND" ) {
st.put( fp.symbol(), Integer.toString( pc ) );
pc--;
}
fp.advance();
pc++;
You can find the specification for the Hack Machine Language and the Hack Assembly Language here.
In essence, you are given a text file containing a list of commands in the Hack Assembly Language (a very simplified fictitious assembly language) and you are to convert it to binary, storing the result in another file.
Please advise me on how I can make this better, more efficient, readable, maintainable etc.
Here is my implementation:
```
import java.io.*;
import java.lang.*;
import java.util.regex.*;
import java.util.HashMap;
public class Main {
private String file;
private int pc = 0;
public Main( String fin ) {
file = fin;
}
public void main( String[] args ) throws IOException, Exception {
// CREATE INSTANCES OF OTHER MODULES
Parser fp = new Parser( args[ 0 ] );
Parser sp = new Parser( args[ 0 ] );
Code code = new Code();
HashMap st = new HashMap();
// SYMBOL TABLE INITIALIZATION
st.put( "R0", "0" ); st.put( "R1", "1" ); st.put( "R2", "2" ); st.put( "R3", "3" ); st.put( "R4", "4" ); st.put( "R5", "5" ); st.put( "R6", "6" ); st.put( "R7", "7" );
st.put( "R8", "8" ); st.put( "R9", "9" ); st.put( "R10", "10" ); st.put( "R11", "11" ); st.put( "R12", "12" ); st.put( "R13", "13" ); st.put( "R14", "14" ); st.put( "R15", "15" );
st.put( "SCREEN", "16384" ); st.put( "KBD", "24576" );
st.put( "SP", "0" ); st.put( "LCL", "1" ); st.put( "ARG", "2" ); st.put( "THIS", "3" ); st.put( "THAT", "4" );
// FIRST PASS
fp.advance();
while( fp.command != null ) {
if( fp.commandType() == "L_COMMAND" ) {
st.put( fp.symbol(), Integer.toString( pc ) );
pc--;
}
fp.advance();
pc++;
Solution
Here some comments about your code:
-
You should never compare Strings by using ==.
This might work for constant Strings if the compiler pools the constants but this is not guaranteed. So use .equals(..) instead
A better way would be to only read the source and generate a data structure while parsing it (often done by a tokenizer and creating a abstract syntax tree). Another benefit would be that you can always say where in the original line you are when a parsing problem occurs because you never modified the line.
-
You should never compare Strings by using ==.
if( sp.commandType() == "A_COMMAND" )This might work for constant Strings if the compiler pools the constants but this is not guaranteed. So use .equals(..) instead
- You should use an Enum for L_COMMAND A_COMMAND C_COMMAND. This way you gain type safety and also speed because Enums are mapped to int by the compiler which makes comparisons very cheap.
- You use .replaceAll a lot during parsing. This results in creating new String instances and always iterating through the String. If speed is you goal you should try to avoid to modify the line during parsing.
A better way would be to only read the source and generate a data structure while parsing it (often done by a tokenizer and creating a abstract syntax tree). Another benefit would be that you can always say where in the original line you are when a parsing problem occurs because you never modified the line.
Code Snippets
if( sp.commandType() == "A_COMMAND" )Context
StackExchange Code Review Q#158471, answer score: 4
Revisions (0)
No revisions yet.