Skip to content

Commit

Permalink
fix compiler/decompiler
Browse files Browse the repository at this point in the history
  • Loading branch information
Darmo117 committed Feb 25, 2022
1 parent 6541012 commit cfefcc6
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 106 deletions.
20 changes: 10 additions & 10 deletions src/main/java/net/darmo_creations/ti83_compiler/BinaryFile.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package net.darmo_creations.ti83_compiler;

import net.darmo_creations.ti83_compiler.utils.ArraysUtil;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;

import net.darmo_creations.ti83_compiler.utils.ArraysUtil;

/**
* This class represents a .8xp program file.
*
Expand All @@ -18,14 +18,14 @@ public class BinaryFile {
private boolean editable;

public static final String FORMAT = "8xp";
public static final String HEADER = "**TI83F*\u001a\n\0";
public static final String HEADER = "**TI83F*\u001a\n\n";
public static final String COMMENT = "Created by Java TI-Compiler";

public BinaryFile(String path, String name, byte[] data, boolean editable) {
this.path = path;
setName(name);
setData(data);
setEditable(editable);
this.setName(name);
this.setData(data);
this.setEditable(editable);
}

public String getPath() {
Expand Down Expand Up @@ -62,7 +62,7 @@ public void setName(String name) {
/**
* Changes the program's data.<br />
* <b>NOTE: tokens' validity is not checked!</b>
*
*
* @param data the program's data
*/
public void setData(byte[] data) {
Expand All @@ -71,7 +71,7 @@ public void setData(byte[] data) {

/**
* Writes the file.
*
*
* @throws IOException if the file could not be written
*/
public void writeFile() throws IOException {
Expand All @@ -96,7 +96,7 @@ public void writeFile() throws IOException {
header[57] = (byte) (l & 0x00FF);
header[58] = (byte) ((l & 0xFF00) >> 8);
// Protection
header[59] = (byte) (isEditable() ? 0x05 : 0x06);
header[59] = (byte) (this.isEditable() ? 0x05 : 0x06);
// Program name
ArraysUtil.stringCopy(this.name, header, 60, 8);
// More things
Expand Down Expand Up @@ -125,7 +125,7 @@ public void writeFile() throws IOException {
content[content.length - 2] = (byte) (l & 0x00FF);
content[content.length - 1] = (byte) ((l & 0xFF00) >> 8);

try (FileOutputStream fos = new FileOutputStream(new File(getAbsolutePath()))) {
try (FileOutputStream fos = new FileOutputStream(this.getAbsolutePath())) {
fos.write(content);
}
}
Expand Down
35 changes: 16 additions & 19 deletions src/main/java/net/darmo_creations/ti83_compiler/Main.java
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
package net.darmo_creations.ti83_compiler;

import net.darmo_creations.ti83_compiler.compilers.Compiler;
import net.darmo_creations.ti83_compiler.compilers.Decompiler;

import java.io.PrintStream;
import java.util.Arrays;
import java.util.List;

import net.darmo_creations.ti83_compiler.compilers.Compiler;
import net.darmo_creations.ti83_compiler.compilers.Decompiler;

public class Main {
public static void main(String[] args) {
System.out.println("** TI-83 Compiler/Decompiler v1.2 **");
Expand All @@ -16,8 +16,7 @@ public static void main(String[] args) {
try {
if (argz.size() == 1 && argz.get(0).equals("-h")) {
printUsage(false);
}
else {
} else {
if (!argz.contains("-f") || argz.indexOf("-f") == argz.size() - 1) {
throw new IllegalArgumentException("No file specified!");
}
Expand All @@ -29,41 +28,39 @@ public static void main(String[] args) {
boolean optimise = argz.contains("-O");
boolean editable = !argz.contains("-L");
new Compiler().compile(file, optimise, editable);
}
else {
} else {
Decompiler decompiler = new Decompiler();
int indexLanguage = argz.indexOf("-u") + 1;
if (indexLanguage > argz.size() - 1)
if (indexLanguage > argz.size() - 1) {
throw new IllegalArgumentException("Missing target language!");
}
String lang = argz.get(indexLanguage);

if (argz.contains("-i")) {
int indexIndent = argz.indexOf("-i") + 1;
if (indexIndent > argz.size() - 1)
if (indexIndent > argz.size() - 1) {
throw new IllegalArgumentException("Missing indent size!");
}
int indentSize;

try {
indentSize = Integer.parseInt(argz.get(indexIndent));
if (indentSize < 0)
if (indentSize < 0) {
throw new IllegalArgumentException("Indent size must be a positive integer!");
}
decompiler.decompile(file, lang, indentSize);
}
catch (NumberFormatException ex) {
} catch (NumberFormatException ex) {
throw new IllegalArgumentException("Indent size must be an integer!", ex);
}
}
else {
} else {
decompiler.decompile(file, lang);
}
}
}
}
catch (IllegalArgumentException ex) {
} catch (IllegalArgumentException ex) {
System.err.println(ex.getMessage());
printUsage(true);
}
catch (Exception ex) {
} catch (Exception ex) {
System.err.println(ex.getMessage());
}
}
Expand All @@ -85,4 +82,4 @@ private static void printUsage(boolean error) {
out.println("\tshow this help");
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package net.darmo_creations.ti83_compiler.compilers;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import net.darmo_creations.ti83_compiler.BinaryFile;
import net.darmo_creations.ti83_compiler.exceptions.FileFormatException;
import net.darmo_creations.ti83_compiler.exceptions.UnknownTokenException;
import net.darmo_creations.ti83_compiler.utils.ArraysUtil;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
* This class parses a .8xp file into a source code text file.
*
Expand All @@ -18,8 +18,8 @@ class BinaryFileParser {
public static final int DEFAULT_INDENT_SIZE = 4;

private final byte[] header;
private String language;
private int indentSize;
private final String language;
private final int indentSize;

public BinaryFileParser(String language, int indentSize) {
this.header = new byte[11];
Expand All @@ -31,35 +31,34 @@ public BinaryFileParser(String language, int indentSize) {
/**
* Parses a .8xp file then returns the corresponding source code. The first line is the program's
* name.
*
*
* @param content the content to parse
* @return the program's source code
* @throws UnknownTokenException if the parser stumbles upon an unknown token
* @throws FileFormatException if the file is corrupted
*/
public String[] parse(byte[] content) throws UnknownTokenException, FileFormatException {
public String[] parse(byte[] content) throws FileFormatException {
List<String> lines = new ArrayList<>();

try {
// Checks the header.
if (!checkHeader(content)) {
if (!this.checkHeader(content)) {
throw new FileFormatException("Invalid header.");
}

int length = toInt(content[0x48], content[0x49]);
int length = this.toInt(content[0x48], content[0x49]);

// Checks the length.
if (toInt(content[0x35], content[0x36]) - 19 != length //
|| toInt(content[0x39], content[0x3A]) - 2 != length //
|| toInt(content[0x46], content[0x47]) - 2 != length) {
if (this.toInt(content[0x35], content[0x36]) - 19 != length //
|| this.toInt(content[0x39], content[0x3A]) - 2 != length //
|| this.toInt(content[0x46], content[0x47]) - 2 != length) {
throw new FileFormatException("Invalid length.");
}

// Gets the name.
lines.add(getName(content));
lines.add(this.getName(content));

// Checksum.
if (!checkSum(content)) {
if (!this.checkSum(content)) {
System.err.println("WARNING: invalid checksum, the file may be corrupted.");
System.err.println("We will still attempt to open it.");
System.err.println();
Expand All @@ -78,20 +77,19 @@ public String[] parse(byte[] content) throws UnknownTokenException, FileFormatEx
lines.add(indent + currentLine);

if (increaseIndent) {
indent = addIndent(indent);
indent = this.addIndent(indent);
increaseIndent = false;
}
if (newLineAfterIf) {
indent = removeIndent(indent);
indent = this.removeIndent(indent);
newLineAfterIf = false;
}
if (inIfWithoutThen) {
indent = addIndent(indent);
indent = this.addIndent(indent);
inIfWithoutThen = false;
newLineAfterIf = true;
}
currentLine = "";
found = true;
continue;
}

Expand All @@ -115,20 +113,20 @@ else if (token.getInstruction().equals("If ")) {
// else, decrease current indent then re-increase indent.
else if (token.getInstruction().equals("Then")) {
if (newLineAfterIf) {
indent = removeIndent(indent);
indent = this.removeIndent(indent);
newLineAfterIf = false;
}
inIfWithoutThen = false;
increaseIndent = true;
}
// Else detected. Decrease current indent then increase indent.
else if (token.getInstruction().equals("Else")) {
indent = removeIndent(indent);
indent = this.removeIndent(indent);
increaseIndent = true;
}
// End detected. Decrease current indent.
else if (token.getInstruction().equals("End")) {
indent = removeIndent(indent);
indent = this.removeIndent(indent);
}
// If the instruction after an if is on the same line.
// E.g.: 'If B:Disp B'
Expand All @@ -153,10 +151,9 @@ else if (inIfWithoutThen && token.getInstruction().equals(":")) {
}
}

return lines.toArray(new String[lines.size()]);
}
catch (Exception ex) {
throw new FileFormatException("Corrupted file.", ex);
return lines.toArray(new String[0]);
} catch (Exception ex) {
throw new FileFormatException("Corrupted file: " + ex.getMessage(), ex);
}
}

Expand All @@ -165,23 +162,21 @@ else if (inIfWithoutThen && token.getInstruction().equals(":")) {
*/
private boolean checkHeader(final byte[] bytes) {
byte[] header = new byte[11];

System.arraycopy(bytes, 0, header, 0, 11);

return Arrays.equals(header, this.header);
}

/**
* Returns the program's name.
*/
private String getName(byte[] bytes) {
String name = "";
StringBuilder name = new StringBuilder();

for (int i = 0x3C; i < 0x3C + 8 && bytes[i] != 0; i++) {
name += (bytes[i] == 0x5B) ? 'θ' : (char) bytes[i];
name.append((bytes[i] == 0x5B) ? 'θ' : (char) bytes[i]);
}

return name;
return name.toString();
}

/**
Expand All @@ -194,7 +189,7 @@ private boolean checkSum(byte[] bytes) {
sum += (bytes[i] < 0) ? bytes[i] + 256 : bytes[i];
}

return (sum & 0xFFFF) == toInt(bytes[bytes.length - 2], bytes[bytes.length - 1]);
return (sum & 0xFFFF) == this.toInt(bytes[bytes.length - 2], bytes[bytes.length - 1]);
}

/**
Expand All @@ -218,8 +213,9 @@ private String addIndent(String indent) {
* Removes an indent level.
*/
private String removeIndent(String indent) {
if (indent.length() < this.indentSize)
if (indent.length() < this.indentSize) {
return "";
}
return indent.substring(0, indent.length() - this.indentSize);
}
}
Loading

0 comments on commit cfefcc6

Please sign in to comment.