そこで、アセンブリ言語を機械語に変換できる GUI を作成するプログラムを完成させようとしています。このプログラムには 7 つのクラスが必要ですが、「Assemble」ボタンが押されたときに ASMEditor の actionlistener でプログラム Assemble816 を実行するのに問題があります。さまざまなことを試すたびに、何百もの異なるエラーが発生し続けます。かなり立ち往生。
ASM エディター:
public class ASMEditor extends JPanel {
private JTextArea editArea;
private JButton assembleButton;
private JButton clearButton;
private Assemble816 asm;
private InstructionMemory iMem;
public ASMEditor() {
super( new BorderLayout() );
setBackground( Color.white );
Border blackLine = BorderFactory.createLineBorder(Color.black);
setBorder(
BorderFactory.createTitledBorder(blackLine, "Assembler"));
editArea = new JTextArea();
assembleButton = new JButton( "Assemble" );
assembleButton.setBackground( getBackground() );
assembleButton.addActionListener( new ActionListener() {
public void actionPerformed( ActionEvent evt ) {
System.out.println( editArea.getText() );
try{
Assemble816 asm = new Assemble816();
//this is all I have
}
catch(Exception ex)
{
JOptionPane.showMessageDialog(null, ex.getMessage());
}
}
});
clearButton = new JButton( "Clear" );
clearButton.setBackground( getBackground() );
clearButton.addActionListener( new ActionListener() {
public void actionPerformed( ActionEvent evt ) {
editArea.setText("");
}
});
JPanel buttons = new JPanel( new FlowLayout(FlowLayout.LEFT, 5, 5 ));
buttons.setBackground( Color.white );
buttons.add( assembleButton );
buttons.add( clearButton );
add( buttons, BorderLayout.NORTH );
Border blueLine = BorderFactory.createLineBorder(Color.blue);
editArea.setBorder( blueLine );
editArea.setBackground( new Color( 205, 255, 255) );
editArea.setFont(new Font("monospaced", Font.PLAIN, 14 ));
add( editArea, BorderLayout.CENTER );
}
}
そしてAssemble816:
public class Assemble816 {
private InstructionMemory im;
private static String[] twoOperand = {
"add", "adc", "sub", "xor", "and", "or", "lshift", "ashift"
};
private static int lookupTwoOp( String op ) {
int opcode = 0;
for( String o : twoOperand ) {
if ( o.equals( op ) ) {
return opcode;
}
opcode++;
}
return -1;
}
private static String[] oneOperand = {
"inc", "dec", "asr", "lsl"
};
private static int lookupOneOp( String op ) {
int opcode = 0;
for( String o : oneOperand ) {
if ( o.equals( op ) ) {
return opcode;
}
opcode++;
}
return -1;
}
private static String[] skip = {
"skipeq", "skipne", "skipge", "skiplt"
};
private static int lookupSkip( String op ) {
int opcode = 0;
for( String o : skip ) {
if ( o.equals( op ) ) {
return opcode;
}
opcode++;
}
return -1;
}
private static String[] wordConstant = {
"ldc", "ldd", "std"
};
private static int lookupConstant( String op ) {
int opcode = 0;
for( String o : wordConstant ) {
if ( o.equals( op ) ) {
return opcode;
}
opcode++;
}
return -1;
}
public Assemble816( final InstructionMemory im ){
this.im = im;
}
private static void parseTwoArgs( Scanner sc, String [] words )
throws SyntaxError
{
String rest = sc.nextLine();
String[] ws = rest.split(",");
if ( ws.length != 2 ) {
throw new SyntaxError("Missing words");
}
words[0] = ws[0].trim();
words[1] = ws[1].trim();
}
private static int parseRegister( String reg ) throws SyntaxError {
if ( reg.equals("r0") ) {
return 0;
}
else if ( reg.equals("r1") ) {
return 1;
}
else if ( reg.equals("r2") ) {
return 2;
}
else if ( reg.equals("r3") ) {
return 3;
}
else {
throw new SyntaxError("Not a register: " + reg );
}
}
private static int parseInteger( String i ) throws SyntaxError {
String ii = i;
try {
int sign = 1;
if ( i.charAt(0) == '-' ) {
i = i.substring(1);
sign = -1;
}
int radix = 10;
if ( i.startsWith("0x") ) {
radix = 16;
i = i.substring(2);
}
else if ( i.charAt(0) == '0' ) {
radix = 8;
}
return Integer.parseInt(i, radix ) * sign;
}
catch( NumberFormatException ex ) {
throw new SyntaxError("Not a number: " + ii );
}
}
private static String stripComments( String line ) {
int split = line.indexOf(';');
if ( split == -1 ) {
return line;
}
else {
return line.substring(0, split );
}
}
private void printIM( int address, int length ) {
int dataPerLine = 0;
for (int a = address; a < (address+length); a++ ) {
if ( dataPerLine == 0 ) {
System.out.printf("%04x", a&0xffff );
dataPerLine = 16;
}
System.out.printf(" %02x", im.fetch(a) & 0xff );
dataPerLine--;
if ( dataPerLine == 0 ) {
System.out.println();
}
}
if ( dataPerLine != 0 ) {
System.out.println();
}
}
// added for project, not part of assignment
public void assemble( File f ) throws IOException, SyntaxError {
byte[] buf = new byte[(int) f.length()];
FileInputStream fis = new FileInputStream( f );
fis.read( buf );
fis.close();
assemble( new String( buf ) );
}
/**
* Assemble the file, f.
*/
public void assemble( String str) throws SyntaxError {
int currentPC = 0;
int opcode = 0;
String[] args = new String[2];
Scanner sc = new Scanner( str );
while( sc.hasNextLine() ) {
Scanner parse = new Scanner(stripComments(sc.nextLine()) );
if ( !parse.hasNext() ) continue; // skip empty line
String cmd = parse.next();
if ( cmd.equals(".org") ) {
if ( !parse.hasNext() ) {
throw new SyntaxError(".org excepting integer");
}
currentPC = parseInteger( parse.next() );
}
else if ( cmd.equals(".dump") ) {
parseTwoArgs( parse, args );
int start = parseInteger( args[0] );
int length = parseInteger( args[1] );
printIM( start, length );
}
else if ( (opcode=lookupConstant(cmd)) != -1 ) {
parseTwoArgs( parse, args );
int reg = parseRegister( args[0] );
int k = parseInteger( args[1] );
im.set( currentPC, (opcode<<2) | reg );
currentPC++;
im.set( currentPC, (k >> 8) & 0xff );
currentPC++;
im.set( currentPC, (k >> 0) & 0xff );
currentPC++;
}
else if ( (opcode=lookupTwoOp(cmd)) != -1) {
parseTwoArgs( parse, args );
int dst = parseRegister( args[0] );
int src = parseRegister( args[1] );
im.set( currentPC, 0x80 | (opcode<<4) | dst << 2 | src );
currentPC++;
}
else if ( cmd.equals( "br" ) ) {
if ( !parse.hasNext() ) {
throw new SyntaxError("br excepting integer");
}
int branch = parseInteger( parse.next() );
im.set( currentPC, 0x40 | (branch & 0x3f) );
currentPC++;
}
else if ( (opcode=lookupOneOp(cmd)) != -1) {
if ( !parse.hasNext() ) {
throw new SyntaxError(cmd + " excepting register");
}
int ds = parseRegister( parse.next() );
im.set( currentPC, 0x20 | (opcode<<2) | ds );
currentPC++;
}
else if ( (opcode=lookupSkip(cmd)) != -1) {
if ( !parse.hasNext() ) {
throw new SyntaxError(cmd + " excepting register");
}
int ds = parseRegister( parse.next() );
im.set( currentPC, 0x30 | (opcode<<2) | ds );
currentPC++;
}
else if ( cmd.equals( "ld" ) ) {
parseTwoArgs( parse, args );
int index = parseRegister( args[0] );
if ( index != 0 && index != 1 ) {
throw new SyntaxError("index register must be r0 or r1");
}
int ds = parseRegister( args[1] );
im.set( currentPC, 0x10 | (0<<3) | (index<<2) | ds );
currentPC++;
}
else if ( cmd.equals( "st" ) ) {
parseTwoArgs( parse, args );
int index = parseRegister( args[0] );
if ( index != 0 && index != 1 ) {
throw new SyntaxError("index register must be r0 or r1");
}
int ds = parseRegister( args[1] );
im.set( currentPC, 0x10 | (1<<3) | (index<<2) | ds );
currentPC++;
}
else if ( cmd.equals( "jl" ) ) {
if ( !parse.hasNext() ) {
throw new SyntaxError("jl excepting register");
}
int link = parseRegister( parse.next() );
im.set( currentPC, 0x0c | link );
currentPC++;
}
else {
throw new SyntaxError("unknown instruction: " + cmd );
}
}
sc.close();
}
/**
* main - accepts the name of the file to assemble on the command line.
*/
public static void main( String[] args ) {
if ( args.length != 1 ) {
System.out.println("usage: java Assemble816 file");
return;
}
try {
InstructionMemory im = new InstructionMemory();
Assemble816 asm = new Assemble816( im );
asm.assemble( new File( args[0] ) );
}
catch( IOException ex ) {
System.out.println("io: " + ex.getMessage() );
}
catch( SyntaxError ex ) {
System.out.println("syntax: " + ex.getMessage() );
}
}
}