|
@@ -31,6 +31,7 @@ import java.io.Writer;
|
|
|
import java.nio.charset.Charset;
|
|
|
import java.nio.file.Files;
|
|
|
import java.util.ArrayList;
|
|
|
+import java.util.Arrays;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.Iterator;
|
|
|
import java.util.List;
|
|
@@ -63,6 +64,9 @@ import de.mcs.utils.jsap.SwitchOption;
|
|
|
@Command(help = "SPS Assembler \r\n usage java -jar SPSEmulator-x.x.x.jar <options>")
|
|
|
public class SPSAssembler {
|
|
|
|
|
|
+ private static final String INCLUDE_FILE = ".include";
|
|
|
+ private static final String END_MACRO_DEFINITION = ".endmacro";
|
|
|
+ private static final String START_MACRO_DEFINITION = ".macro";
|
|
|
private static File source;
|
|
|
private static HARDWARE destination;
|
|
|
private static int lineNumber;
|
|
@@ -72,6 +76,10 @@ public class SPSAssembler {
|
|
|
private static List<Mnemonic> mnemonics = new ArrayList<>();
|
|
|
private static File destinationFile;
|
|
|
private static FORMAT outputFormat;
|
|
|
+ private static File include;
|
|
|
+ private static boolean inMacro;
|
|
|
+ private static Macro actualMacro;
|
|
|
+ private static Map<String, Macro> macros = new HashMap<>();
|
|
|
|
|
|
/**
|
|
|
*
|
|
@@ -98,6 +106,13 @@ public class SPSAssembler {
|
|
|
destination = HARDWARE.valueOf((value.toUpperCase()));
|
|
|
}
|
|
|
|
|
|
+ @FileOption(shortKey = 'i', longKey = "include", name = "include", defaultValue = "", help = "where to find the include files.", required = false)
|
|
|
+ public static void setDestinationSystem(File file) {
|
|
|
+ if ((file != null) && !file.getName().equals("")) {
|
|
|
+ include = file;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
@FileOption(index = 1, name = "source file", help = "source file to compile", required = true, mustExists = true)
|
|
|
public static void setSourceFile(File file) {
|
|
|
if ((file != null) && !file.getName().equals("")) {
|
|
@@ -303,23 +318,59 @@ public class SPSAssembler {
|
|
|
mnemonic.checkArgument();
|
|
|
}
|
|
|
|
|
|
- private static void parseLine(int srcLineNumber, String line) throws SyntaxError {
|
|
|
- if (line.startsWith(":")) {
|
|
|
- String label = getLabel(line);
|
|
|
- if (labels.containsKey(label)) {
|
|
|
- throw new SyntaxError(srcLineNumber,
|
|
|
- String.format("Label \"%s\" already definied in line %d.", label, labels.get(label)));
|
|
|
- }
|
|
|
- labels.put(label, lineNumber);
|
|
|
+ private static void parseLine(int srcLineNumber, String srcLine) throws SyntaxError {
|
|
|
+ String line = srcLine.trim();
|
|
|
+ if (inMacro) {
|
|
|
+ actualMacro.addLine(line);
|
|
|
} else {
|
|
|
- Mnemonic mnemonic = getMnemonic(line);
|
|
|
- if (mnemonic != null) {
|
|
|
- lineNumber++;
|
|
|
- mnemonics.add(mnemonic);
|
|
|
+ if (line.startsWith(":")) {
|
|
|
+ String label = getLabel(line);
|
|
|
+ if (labels.containsKey(label)) {
|
|
|
+ throw new SyntaxError(srcLineNumber,
|
|
|
+ String.format("Label \"%s\" already definied in line %d.", label, labels.get(label)));
|
|
|
+ }
|
|
|
+ labels.put(label, lineNumber);
|
|
|
+ } else if (line.startsWith(".")) {
|
|
|
+ // process pre compiler part
|
|
|
+ String label = getLabel(line);
|
|
|
+ precompiler(srcLineNumber, label);
|
|
|
+ } else {
|
|
|
+ Mnemonic mnemonic = getMnemonic(line);
|
|
|
+ if (mnemonic != null) {
|
|
|
+ lineNumber++;
|
|
|
+ mnemonics.add(mnemonic);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private static void precompiler(int srcLineNumber, String value) {
|
|
|
+ String label = value.trim().toLowerCase();
|
|
|
+ String name = label;
|
|
|
+ if (label.indexOf(" ") > 0) {
|
|
|
+ name = label.substring(0, label.indexOf(" "));
|
|
|
+ }
|
|
|
+ if (INCLUDE_FILE.equals(name)) {
|
|
|
+ // proccess include file
|
|
|
+ } else if (START_MACRO_DEFINITION.equals(name)) {
|
|
|
+ // macro definition
|
|
|
+ String[] arguments = label.split(" ");
|
|
|
+ String macroName = arguments[1];
|
|
|
+ String[] args = null;
|
|
|
+ if (arguments.length > 2) {
|
|
|
+ args = Arrays.copyOfRange(arguments, 2, arguments.length);
|
|
|
+ }
|
|
|
+ actualMacro = new Macro(macroName, args);
|
|
|
+ inMacro = true;
|
|
|
+ } else if (END_MACRO_DEFINITION.equalsIgnoreCase(label)) {
|
|
|
+ // end of macro definition
|
|
|
+ inMacro = false;
|
|
|
+ macros.put(actualMacro.getName(), actualMacro);
|
|
|
+ } else {
|
|
|
+ // seems to be a macro usage
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private static Mnemonic getMnemonic(String line) throws SyntaxError {
|
|
|
String newLine = stripComments(line);
|
|
|
if (StringUtils.isNotEmpty(newLine)) {
|