Skip to content

Commit

Permalink
Merge pull request #55 from Shin-703/text-segment-shows-all-source-lines
Browse files Browse the repository at this point in the history
Text segment shows all source lines
  • Loading branch information
privat authored Jul 26, 2024
2 parents d9f47dc + c97744b commit 56d073e
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 54 deletions.
17 changes: 16 additions & 1 deletion src/rars/RISCVprogram.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public class RISCVprogram {
private ArrayList<TokenList> tokenList;
private ArrayList<ProgramStatement> parsedList;
private ArrayList<ProgramStatement> machineList;
private ArrayList<ProgramStatement> textSegmentLines;
private BackStepper backStepper;
private SymbolTable localSymbolTable;
private MacroPool macroPool;
Expand Down Expand Up @@ -142,6 +143,16 @@ public ArrayList<ProgramStatement> createParsedList() {
return parsedList;
}

public ArrayList<ProgramStatement> createMachineList() {
machineList = new ArrayList<>();
return machineList;
}

public ArrayList<ProgramStatement> createTextSegmentLines() {
textSegmentLines = new ArrayList<>();
return textSegmentLines;
}

/**
* Produces existing list of parsed source code statements.
*
Expand All @@ -165,6 +176,10 @@ public ArrayList<ProgramStatement> getMachineList() {
return machineList;
}

public ArrayList<ProgramStatement> getTextSegmentLines() {
return textSegmentLines;
}


/**
* Returns BackStepper associated with this program. It is created upon successful assembly.
Expand Down Expand Up @@ -332,7 +347,7 @@ public ErrorList assemble(ArrayList<RISCVprogram> programsToAssemble, boolean ex
boolean warningsAreErrors) throws AssemblyException {
this.backStepper = null;
Assembler asm = new Assembler();
this.machineList = asm.assemble(programsToAssemble, extendedAssemblerEnabled, warningsAreErrors);
asm.assemble(programsToAssemble, extendedAssemblerEnabled, warningsAreErrors, this);
this.backStepper = new BackStepper();
return asm.getErrorList();
}
Expand Down
33 changes: 20 additions & 13 deletions src/rars/assembler/Assembler.java
Original file line number Diff line number Diff line change
Expand Up @@ -88,25 +88,23 @@ public ErrorList getErrorList() {
* considered errors and terminate the assemble; false means the
* assembler will produce warning message but otherwise ignore
* warnings.
* @return An ArrayList representing the assembled program. Each member of
* the list is a ProgramStatement object containing the source,
* intermediate, and machine binary representations of a program
* statement. Returns null if incoming array list is null or empty.
* @param programAssembled The whole program currently being assembled.
* @see ProgramStatement
**/
public ArrayList<ProgramStatement> assemble(ArrayList<RISCVprogram> tokenizedProgramFiles, boolean extendedAssemblerEnabled,
boolean warningsAreErrors) throws AssemblyException {
public void assemble(ArrayList<RISCVprogram> tokenizedProgramFiles, boolean extendedAssemblerEnabled,
boolean warningsAreErrors, RISCVprogram programAssembled) throws AssemblyException {

if (tokenizedProgramFiles == null || tokenizedProgramFiles.size() == 0)
return null;
return;
textAddress = new AddressSpace(Memory.textBaseAddress);
dataAddress = new AddressSpace(Memory.dataBaseAddress);
externAddress = Memory.externBaseAddress;
currentFileDataSegmentForwardReferences = new DataSegmentForwardReferences();
accumulatedDataSegmentForwardReferences = new DataSegmentForwardReferences();
Globals.symbolTable.clear();
Globals.memory.clear();
ArrayList<ProgramStatement> machineList = new ArrayList<>();
ArrayList<ProgramStatement> machineList = programAssembled.createMachineList();
ArrayList<ProgramStatement> textSegmentLines = programAssembled.createTextSegmentLines();
this.errors = new ErrorList();
if (Globals.debug)
System.out.println("Assembler first pass begins:");
Expand Down Expand Up @@ -136,6 +134,7 @@ public ArrayList<ProgramStatement> assemble(ArrayList<RISCVprogram> tokenizedPro
// tokenList is an ArrayList of TokenList objects, one per source line;
// each ArrayList in tokenList consists of Token objects.
ArrayList<SourceLine> sourceLineList = fileCurrentlyBeingAssembled.getSourceLineList();
ArrayList<String> sourceLines = fileCurrentlyBeingAssembled.getSourceList();
ArrayList<TokenList> tokenList = fileCurrentlyBeingAssembled.getTokenList();
ArrayList<ProgramStatement> parsedList = fileCurrentlyBeingAssembled.createParsedList();
// each file keeps its own macro definitions
Expand All @@ -156,6 +155,11 @@ public ArrayList<ProgramStatement> assemble(ArrayList<RISCVprogram> tokenizedPro
extendedAssemblerEnabled);
if (statements != null) {
parsedList.addAll(statements);
} else if (!sourceLines.get(i).isBlank()) { //not an instruction and not a blank line
ProgramStatement programStatement = new ProgramStatement(sourceLineList.get(i).getRISCVprogram(),
sourceLines.get(i), tokenList.get(i), null, null,
-1, sourceLineList.get(i).getLineNumber());
parsedList.add(programStatement);
}
}
if (inMacroSegment) {
Expand Down Expand Up @@ -197,13 +201,15 @@ public ArrayList<ProgramStatement> assemble(ArrayList<RISCVprogram> tokenizedPro
this.fileCurrentlyBeingAssembled = program;
ArrayList<ProgramStatement> parsedList = fileCurrentlyBeingAssembled.getParsedList();
for (ProgramStatement statement : parsedList) {
statement.buildBasicStatementFromBasicInstruction(errors);
if (statement.getInstruction() != null)
statement.buildBasicStatementFromBasicInstruction(errors);
if (errors.errorsOccurred()) {
throw new AssemblyException(errors);
}
if (statement.getInstruction() instanceof BasicInstruction) {
machineList.add(statement);
} else {
textSegmentLines.add(statement);
} else if (statement.getInstruction() != null) {
// It is a pseudo-instruction:
// 1. Fetch its basic instruction template list
// 2. For each template in the list,
Expand Down Expand Up @@ -266,9 +272,11 @@ public ArrayList<ProgramStatement> assemble(ArrayList<RISCVprogram> tokenizedPro
textAddress.increment(Instruction.INSTRUCTION_LENGTH);
ps.buildBasicStatementFromBasicInstruction(errors);
machineList.add(ps);
textSegmentLines.add(ps);
} // end of FOR loop, repeated for each template in list.
} // end of ELSE part for extended instruction.

} else {
textSegmentLines.add(statement); //not an instruction
}
} // end of assembler second pass.
}
if (Globals.debug)
Expand Down Expand Up @@ -309,7 +317,6 @@ public ArrayList<ProgramStatement> assemble(ArrayList<RISCVprogram> tokenizedPro
if (errors.errorsOccurred() || errors.warningsOccurred() && warningsAreErrors) {
throw new AssemblyException(errors);
}
return machineList;
} // assemble()

// //////////////////////////////////////////////////////////////////////
Expand Down
119 changes: 79 additions & 40 deletions src/rars/venus/TextSegmentWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,48 +101,14 @@ public TextSegmentWindow() {
* Should convert the lines of code over to the table rows and columns.
**/
public void setupTable() {
int addressBase = Globals.getGui().getMainPane().getExecutePane().getAddressDisplayBase();
codeHighlighting = true;
breakpointsEnabled = true;
ArrayList<ProgramStatement> sourceStatementList = Globals.program.getMachineList();
ArrayList<ProgramStatement> sourceStatementList = Globals.program.getTextSegmentLines();
data = new Object[sourceStatementList.size()][columnNames.length];
intAddresses = new int[data.length];
addressRows = new Hashtable<>(data.length);
executeMods = new Hashtable<>(data.length);
// Get highest source line number to determine #leading spaces so line numbers will vertically align
// In multi-file situation, this will not necessarily be the last line b/c sourceStatementList contains
// source lines from all files. DPS 3-Oct-10
int maxSourceLineNumber = 0;
for (int i = sourceStatementList.size() - 1; i >= 0; i--) {
ProgramStatement statement = sourceStatementList.get(i);
if (statement.getSourceLine() > maxSourceLineNumber) {
maxSourceLineNumber = statement.getSourceLine();
}
}
int sourceLineDigits = ("" + maxSourceLineNumber).length();
int leadingSpaces = 0;
int lastLine = -1;
for (int i = 0; i < sourceStatementList.size(); i++) {
ProgramStatement statement = sourceStatementList.get(i);
intAddresses[i] = statement.getAddress();
addressRows.put(intAddresses[i], i);
data[i][BREAK_COLUMN] = false;
data[i][ADDRESS_COLUMN] = NumberDisplayBaseChooser.formatUnsignedInteger(statement.getAddress(), addressBase);
data[i][CODE_COLUMN] = NumberDisplayBaseChooser.formatNumber(statement.getBinaryStatement(), 16, 4);
data[i][BASIC_COLUMN] = statement.getPrintableBasicAssemblyStatement();
String sourceString = "";
if (!statement.getSource().equals("")) {
leadingSpaces = sourceLineDigits - ("" + statement.getSourceLine()).length();
String lineNumber = " ".substring(0, leadingSpaces)
+ statement.getSourceLine() + ": ";
if (statement.getSourceLine() == lastLine)
lineNumber = " ".substring(0, sourceLineDigits) + " ";
sourceString = lineNumber
+ rars.util.EditorFont.substituteSpacesForTabs(statement.getSource());
}
data[i][SOURCE_COLUMN] = sourceString;
lastLine = statement.getSourceLine();
}
addRows(sourceStatementList);
contentPane.removeAll();
tableModel = new TextTableModel(data);
if (tableModelListener != null) {
Expand Down Expand Up @@ -182,6 +148,66 @@ public void setupTable() {
}
}

/**
* Add rows in the data array from the information in the sourceStatementList.
*
* @param sourceStatementList contains the statements from de source code (comments, .eqv, instructions, ...)
* and the linked information (address, code, basic instruction, source code, ...)
*/
private void addRows(ArrayList<ProgramStatement> sourceStatementList) {
int maxSourceLineNumber = getMaxSourceLineNumber(sourceStatementList);
int addressBase = Globals.getGui().getMainPane().getExecutePane().getAddressDisplayBase();
int sourceLineDigits = ("" + maxSourceLineNumber).length();
int leadingSpaces = 0;
int lastLine = -1;

for (int i = 0; i < sourceStatementList.size(); i++) {
ProgramStatement statement = sourceStatementList.get(i);
intAddresses[i] = statement.getAddress();
addressRows.put(intAddresses[i], i);
data[i][BREAK_COLUMN] = false;
String address = "";
String code = "";
String basicInstruction = "";
String sourceString = "";
if (statement.getInstruction() != null) {
address = NumberDisplayBaseChooser.formatUnsignedInteger(statement.getAddress(), addressBase);
code = NumberDisplayBaseChooser.formatNumber(statement.getBinaryStatement(), 16, 4);
basicInstruction = statement.getPrintableBasicAssemblyStatement();
}
if (!statement.getSource().equals("")) {
leadingSpaces = sourceLineDigits - ("" + statement.getSourceLine()).length();
String lineNumber = " ".substring(0, leadingSpaces)
+ statement.getSourceLine() + ": ";
if (statement.getSourceLine() == lastLine)
lineNumber = " ".substring(0, sourceLineDigits) + " ";
sourceString = lineNumber
+ rars.util.EditorFont.substituteSpacesForTabs(statement.getSource());
}
data[i][ADDRESS_COLUMN] = address;
data[i][CODE_COLUMN] = code;
data[i][BASIC_COLUMN] = basicInstruction;
data[i][SOURCE_COLUMN] = sourceString;
lastLine = statement.getSourceLine();
}
}

/**
* Get highest source line number to determine #leading spaces so line numbers will vertically align
* In multi-file situation, this will not necessarily be the last line b/c sourceStatementList contains
* source lines from all files. DPS 3-Oct-10
*/
private static int getMaxSourceLineNumber(ArrayList<ProgramStatement> sourceStatementList) {
int maxSourceLineNumber = 0;
for (int i = sourceStatementList.size() - 1; i >= 0; i--) {
ProgramStatement statement = sourceStatementList.get(i);
if (statement.getSourceLine() > maxSourceLineNumber) {
maxSourceLineNumber = statement.getSourceLine();
}
}
return maxSourceLineNumber;
}

/**
*
*/
Expand Down Expand Up @@ -219,11 +245,12 @@ public void updateCodeAddresses() {
if (contentPane.getComponentCount() == 0)
return; // ignore if no content to change
int addressBase = Globals.getGui().getMainPane().getExecutePane().getAddressDisplayBase();
int address;
String formattedAddress;
for (int i = 0; i < intAddresses.length; i++) {
formattedAddress = NumberDisplayBaseChooser.formatUnsignedInteger(intAddresses[i], addressBase);
table.getModel().setValueAt(formattedAddress, i, ADDRESS_COLUMN);
if (intAddresses[i] != -1) {
formattedAddress = NumberDisplayBaseChooser.formatUnsignedInteger(intAddresses[i], addressBase);
table.getModel().setValueAt(formattedAddress, i, ADDRESS_COLUMN);
}
}
}

Expand Down Expand Up @@ -414,7 +441,19 @@ public int[] getSortedBreakPointsArray() {
breakpointCount = 0;
for (int i = 0; i < data.length; i++) {
if ((Boolean) data[i][BREAK_COLUMN]) {
breakpoints[breakpointCount++] = intAddresses[i];
int index = i;
//if a breakpoint is not on an instruction, puts a breakpoint at next instruction
if(intAddresses[i] == -1) {
for (int j = index; j < data.length; j++)
if (intAddresses[j] != -1) {
index = j;
break;
}
if (index == i) //no instruction follows the breakpoint
continue; //don't add breakpoint
}
breakpoints[breakpointCount++] = intAddresses[index];
//TODO: we should probably, in place of this, lock the possibility to put a breakpoint if not an instruction
}
}
Arrays.sort(breakpoints);
Expand Down

0 comments on commit 56d073e

Please sign in to comment.