소스 검색

start impleenting macros

Wilfried Klaas 6 년 전
부모
커밋
8e82b01a9b
4개의 변경된 파일147개의 추가작업 그리고 18개의 파일을 삭제
  1. 7 6
      examples/Blink.tps
  2. 6 0
      examples/includes/macro_blink.tps
  3. 71 0
      src/main/java/de/mcs/tools/sps/Macro.java
  4. 63 12
      src/main/java/de/mcs/tools/sps/SPSAssembler.java

+ 7 - 6
examples/Blink.tps

@@ -1,18 +1,19 @@
 /* 
 Kommentar über mehrere Zeilen
 */
+.include macro_blink
 :loop
-.macro1
-PORT #0x0F ; Zeilenkommentar
+.macro1 #0x0f 200ms
+PORT #0x0F ;Zeilenkommentar
 WAIT 200ms
 PORT #0x00
 WAIT 200ms
 RJMP :loop
 
 
-.macro macro1
-PORT #0x0F
-WAIT 200ms
+.macro macro1 output time
+PORT output
+WAIT time
 PORT #0x00
-WAIT 200ms
+WAIT time
 .endmacro

+ 6 - 0
examples/includes/macro_blink.tps

@@ -0,0 +1,6 @@
+.macro blink output time
+PORT output
+WAIT time
+PORT #0x00
+WAIT time
+.endmacro

+ 71 - 0
src/main/java/de/mcs/tools/sps/Macro.java

@@ -0,0 +1,71 @@
+/**
+ * MCS Media Computer Software
+ * Copyright 2018 by Wilfried Klaas
+ * Project: SPSEmulator
+ * File: Macro.java
+ * EMail: W.Klaas@gmx.de
+ * Created: 06.12.2018 wklaa_000
+ * 
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ * 
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ * 
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>
+ */
+package de.mcs.tools.sps;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author wklaa_000
+ *
+ */
+public class Macro {
+
+  private String[] args;
+  private String name;
+  private List<String> lines;
+
+  public Macro(String name, String[] args) {
+    this.name = name;
+    this.args = args;
+    lines = new ArrayList<>();
+  }
+
+  @Override
+  public String toString() {
+    StringBuilder b = new StringBuilder();
+    b.append(String.format("name: %s", name));
+    if (args != null) {
+      StringBuilder b1 = new StringBuilder();
+      b1.append("[");
+      boolean start = true;
+      for (String arg : args) {
+        if (!start) {
+          b1.append(",");
+        }
+        start = false;
+        b1.append(arg);
+      }
+      b1.append("]");
+      b.append(String.format(", args: %s", b1));
+    }
+    return b.toString();
+  }
+
+  public String getName() {
+    return name;
+  }
+
+  public void addLine(String line) {
+    lines.add(line);
+  }
+}

+ 63 - 12
src/main/java/de/mcs/tools/sps/SPSAssembler.java

@@ -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)) {