Data update
This commit is contained in:
parent
29a5eea0d4
commit
5c1bb7bfa9
2011 changed files with 35081 additions and 3229 deletions
|
|
@ -0,0 +1,173 @@
|
|||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
|
||||
public final class CompilerVirtualMachineInterpreter {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
Path filePath = Path.of("Compiler Test Cases/AsciiMandlebrot.txt");
|
||||
VirtualMachineInfo info = loadCode(filePath);
|
||||
runVirtualMachine(info.dataSize, info.vmStrings, info.codes());
|
||||
}
|
||||
|
||||
private static void runVirtualMachine(int dataSize, List<String> vmStrings, List<Byte> codes) {
|
||||
final int wordSize = 4;
|
||||
Stack<Integer> stack = new Stack<Integer>();
|
||||
for ( int i = 0; i < dataSize; i++ ) {
|
||||
stack.push(0);
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
OpCode opCode = null;
|
||||
|
||||
while ( opCode != OpCode.HALT ) {
|
||||
opCode = OpCode.havingCode(codes.get(index));
|
||||
index += 1;
|
||||
|
||||
switch ( opCode ) {
|
||||
case HALT -> { }
|
||||
case ADD -> stack.set(stack.size() - 2, stack.get(stack.size() - 2) + stack.pop());
|
||||
case SUB -> stack.set(stack.size() - 2, stack.get(stack.size() - 2) - stack.pop());
|
||||
case MUL -> stack.set(stack.size() - 2, stack.get(stack.size() - 2) * stack.pop());
|
||||
case DIV -> stack.set(stack.size() - 2, stack.get(stack.size() - 2) / stack.pop());
|
||||
case MOD -> stack.set(stack.size() - 2, Math.floorMod(stack.get(stack.size() - 2), stack.pop()));
|
||||
case LT -> stack.set(stack.size() - 2, ( stack.get(stack.size() - 2) < stack.pop() ) ? 1 : 0);
|
||||
case GT -> stack.set(stack.size() - 2, ( stack.get(stack.size() - 2) > stack.pop() ) ? 1 : 0);
|
||||
case LE -> stack.set(stack.size() - 2, ( stack.get(stack.size() - 2) <= stack.pop() ) ? 1 : 0);
|
||||
case GE -> stack.set(stack.size() - 2, ( stack.get(stack.size() - 2) >= stack.pop() ) ? 1 : 0);
|
||||
case EQ -> stack.set(stack.size() - 2, ( stack.get(stack.size() - 2) == stack.pop() ) ? 1 : 0);
|
||||
case NE -> stack.set(stack.size() - 2, ( stack.get(stack.size() - 2) != stack.pop() ) ? 1 : 0);
|
||||
case AND -> { final int value = ( stack.get(stack.size() - 2) != 0 && stack.pop() != 0 ) ? 1 : 0;
|
||||
stack.set(stack.size() - 1, value);
|
||||
}
|
||||
case OR -> { final int value = ( stack.get(stack.size() - 2) != 0 || stack.pop() != 0 ) ? 1 : 0;
|
||||
stack.set(stack.size() - 1, value);
|
||||
}
|
||||
case NEG -> stack.set(stack.size() - 1, -stack.peek());
|
||||
case NOT -> stack.set(stack.size() - 1, ( stack.peek() == 0 ) ? 1 : 0);
|
||||
case PRTC -> System.out.print((char) stack.pop().intValue());
|
||||
case PRTI -> System.out.print(stack.pop());
|
||||
case PRTS -> System.out.print(vmStrings.get(stack.pop()));
|
||||
case FETCH -> { stack.push(stack.get(operand(index, codes))); index += wordSize; }
|
||||
case STORE -> { stack.set(operand(index, codes), stack.pop()); index += wordSize; }
|
||||
case PUSH -> { stack.push(operand(index, codes)); index += wordSize; }
|
||||
case JMP -> index += operand(index, codes);
|
||||
case JZ -> index += ( stack.pop() == 0 ) ? operand(index, codes) : wordSize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static VirtualMachineInfo loadCode(Path filePath) throws IOException {
|
||||
List<String> lines = Files.readAllLines(filePath, StandardCharsets.UTF_8);
|
||||
|
||||
String line = lines.getFirst();
|
||||
if ( line.startsWith("lex") ) {
|
||||
lines.removeFirst();
|
||||
line = lines.getFirst();
|
||||
}
|
||||
|
||||
String[] sections = line.trim().split(" ");
|
||||
final int dataSize = Integer.parseInt(sections[1]);
|
||||
final int stringCount = Integer.parseInt(sections[3]);
|
||||
|
||||
List<String> VMstrings = new ArrayList<String>();
|
||||
for ( int i = 1; i <= stringCount; i++ ) {
|
||||
String content = lines.get(i).substring(1, lines.get(i).length() - 1);
|
||||
VMstrings.addLast(parseString(content));
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
List<Byte> codes = new ArrayList<Byte>();
|
||||
for ( int i = stringCount + 1; i < lines.size(); i++ ) {
|
||||
sections = lines.get(i).trim().split("\\s+");
|
||||
offset = Integer.parseInt(sections[0]);
|
||||
OpCode opCode = OpCode.valueOf(sections[1].toUpperCase());
|
||||
codes.addLast(opCode.byteCode());
|
||||
|
||||
switch ( opCode ) {
|
||||
case FETCH, STORE -> addToCodes(Integer.parseInt(sections[2]
|
||||
.substring(1, sections[2].length() - 1)), codes);
|
||||
case PUSH -> addToCodes(Integer.parseInt(sections[2]), codes);
|
||||
case JMP, JZ -> addToCodes(Integer.parseInt(sections[3]) - offset - 1, codes);
|
||||
default -> { }
|
||||
}
|
||||
}
|
||||
|
||||
return new VirtualMachineInfo(dataSize, VMstrings, codes);
|
||||
}
|
||||
|
||||
private static int operand(int index, List<Byte> codes) {
|
||||
byteBuffer.clear();
|
||||
for ( int i = index; i < index + 4; i++ ) {
|
||||
byteBuffer.put(codes.get(i));
|
||||
}
|
||||
byteBuffer.flip();
|
||||
|
||||
return byteBuffer.getInt();
|
||||
}
|
||||
|
||||
private static void addToCodes(int number, List<Byte> codes) {
|
||||
byteBuffer.clear();
|
||||
byteBuffer.putInt(number);
|
||||
byteBuffer.flip();
|
||||
for ( byte bb : byteBuffer.array() ) {
|
||||
codes.addLast(bb);
|
||||
}
|
||||
}
|
||||
|
||||
private static String parseString(String text) {
|
||||
StringBuilder result = new StringBuilder();
|
||||
int i = 0;
|
||||
while ( i < text.length() ) {
|
||||
if ( text.charAt(i) == '\\' && i + 1 < text.length() ) {
|
||||
if ( text.charAt(i + 1) == 'n' ) {
|
||||
result.append("\n");
|
||||
i += 1;
|
||||
} else if ( text.charAt(i + 1) == '\\') {
|
||||
result.append("\\");
|
||||
i += 1;
|
||||
}
|
||||
} else {
|
||||
result.append(text.charAt(i));
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
private static ByteBuffer byteBuffer = ByteBuffer.allocate(4).order(ByteOrder.LITTLE_ENDIAN);
|
||||
|
||||
private static enum OpCode {
|
||||
|
||||
HALT(0), ADD(1), SUB(2), MUL(3), DIV(4), MOD(5), LT(6), GT(7), LE(8), GE(9), EQ(10), NE(11),
|
||||
AND(12), OR(13), NEG(14), NOT(15),
|
||||
PRTC(16), PRTI(17), PRTS(18), FETCH(19), STORE(20), PUSH(21), JMP(22), JZ(23);
|
||||
|
||||
public byte byteCode() {
|
||||
return (byte) byteCode;
|
||||
}
|
||||
|
||||
public static OpCode havingCode(Byte byteCode) {
|
||||
return op_codes[(int) byteCode];
|
||||
}
|
||||
|
||||
private OpCode(int aByteCode) {
|
||||
byteCode = aByteCode;
|
||||
}
|
||||
|
||||
private int byteCode;
|
||||
|
||||
private static OpCode[] op_codes = values();
|
||||
|
||||
}
|
||||
|
||||
private static record VirtualMachineInfo(int dataSize, List<String> vmStrings, List<Byte> codes) {}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue