MPROMEditor now calls its columns "Opcode" and "muPC"
[Mograsim.git] / plugins / net.mograsim.machine / src / net / mograsim / machine / mi / MicroInstructionMemoryParser.java
1 package net.mograsim.machine.mi;
2
3 import java.io.BufferedReader;
4 import java.io.ByteArrayInputStream;
5 import java.io.FileInputStream;
6 import java.io.IOException;
7 import java.io.InputStream;
8 import java.io.InputStreamReader;
9 import java.nio.charset.StandardCharsets;
10
11 import net.mograsim.machine.mi.parameters.MicroInstructionParameter;
12 import net.mograsim.machine.mi.parameters.ParameterClassification;
13
14 public class MicroInstructionMemoryParser
15 {
16         private final static String lineSeparator = System.getProperty("line.separator");
17
18         public static void parseMemory(final MicroInstructionMemory memory, String inputPath) throws IOException
19         {
20                 try (InputStream input = new FileInputStream(inputPath))
21                 {
22                         parseMemory(memory, input);
23                 }
24         }
25
26         /**
27          * @param input The input to parse must be in csv format; The stream is closed after being consumed.
28          * 
29          * @throws IOException
30          */
31         public static MicroInstructionMemory parseMemory(MicroInstructionMemoryDefinition memDef, InputStream input) throws IOException
32         {
33                 try
34                 {
35                         MicroInstructionMemory memory = new StandardMicroInstructionMemory(memDef);
36                         parseMemory(memory, input);
37                         return memory;
38                 }
39                 catch (NullPointerException e)
40                 {
41                         throw new MicroInstructionMemoryParseException(e);
42                 }
43         }
44
45         /**
46          *
47          * @param input The input to parse must be in csv format; The stream is closed after being consumed.
48          * 
49          * @throws IOException
50          */
51         public static void parseMemory(final MicroInstructionMemory memory, InputStream input) throws IOException
52         {
53                 try (BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8)))
54                 {
55                         MicroInstructionMemoryDefinition def = memory.getDefinition();
56                         MicroInstructionDefinition miDef = def.getMicroInstructionDefinition();
57
58                         long minAddr = def.getMinimalAddress();
59                         long maxAddr = def.getMaximalAddress();
60
61                         String line;
62                         long i = minAddr;
63                         try
64                         {
65                                 for (; i <= maxAddr && reader.ready() && !"".equals((line = reader.readLine())); i++)
66                                 {
67                                         memory.setCell(i, parse(miDef, line));
68                                 }
69                         }
70                         catch (IOException e)
71                         {
72                                 e.printStackTrace();
73                         }
74
75                         for (; i <= maxAddr; i++)
76                         {
77                                 memory.setCell(i, miDef.createDefaultInstruction());
78                         }
79                 }
80         }
81
82         /**
83          * must be in csv format
84          */
85         public static MicroInstruction parse(MicroInstructionDefinition definition, String input)
86         {
87                 int size = definition.size();
88                 String[] strings = input.split(",");
89                 if (size != strings.length)
90                         throw new MicroInstructionMemoryParseException("String does not match definition! The number of parameters does not match.");
91                 MicroInstructionParameter[] params = new MicroInstructionParameter[size];
92                 ParameterClassification[] classes = definition.getParameterClassifications();
93                 try
94                 {
95                         for (int i = 0; i < size; i++)
96                         {
97                                 params[i] = classes[i].parse(strings[i]);
98                         }
99                         return new StandardMicroInstruction(params);
100                 }
101                 catch (Exception e)
102                 {
103                         throw new MicroInstructionMemoryParseException(e);
104                 }
105         }
106
107         private static String toCSV(MicroInstruction inst)
108         {
109                 int max = inst.getSize() - 1;
110                 StringBuilder sb = new StringBuilder();
111                 for (int i = 0; i < max; i++)
112                 {
113                         sb.append(inst.getParameter(i).toString());
114                         sb.append(",");
115                 }
116                 sb.append(inst.getParameter(max).toString());
117                 return sb.toString();
118         }
119
120         public static InputStream write(MicroInstructionMemory memory)
121         {
122                 return new InputStream()
123                 {
124                         long instIndex = memory.getDefinition().getMinimalAddress(), maxAddress = memory.getDefinition().getMaximalAddress();
125                         InputStream instStream = new ByteArrayInputStream(new byte[0]);
126
127                         @Override
128                         public int read() throws IOException
129                         {
130                                 int val = instStream.read();
131                                 if (val == -1 && instIndex <= maxAddress)
132                                 {
133                                         instStream = new ByteArrayInputStream(
134                                                         (toCSV(memory.getCell(instIndex++)) + lineSeparator).getBytes(StandardCharsets.UTF_8));
135                                         val = instStream.read();
136                                 }
137                                 return val;
138                         }
139                 };
140         }
141 }