mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-23 08:34:11 -08:00
Refactor textual IR parser
This commit is contained in:
parent
6084491119
commit
fb53667e77
|
@ -27,6 +27,7 @@ import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.teavm.model.BasicBlock;
|
import org.teavm.model.BasicBlock;
|
||||||
import org.teavm.model.Incoming;
|
import org.teavm.model.Incoming;
|
||||||
|
import org.teavm.model.Instruction;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
import org.teavm.model.Phi;
|
import org.teavm.model.Phi;
|
||||||
import org.teavm.model.Program;
|
import org.teavm.model.Program;
|
||||||
|
@ -78,9 +79,10 @@ public class ListingParser {
|
||||||
private ListingLexer lexer;
|
private ListingLexer lexer;
|
||||||
private Map<String, Variable> variableMap;
|
private Map<String, Variable> variableMap;
|
||||||
private Map<String, BasicBlock> blockMap;
|
private Map<String, BasicBlock> blockMap;
|
||||||
private Map<String, Integer> blockFirstOccurence;
|
private Map<String, Integer> blockFirstOccurrence;
|
||||||
private Set<String> declaredBlocks = new HashSet<>();
|
private Set<String> declaredBlocks = new HashSet<>();
|
||||||
private TextLocation currentLocation;
|
private TextLocation currentLocation;
|
||||||
|
private BasicBlock currentBlock;
|
||||||
|
|
||||||
public Program parse(Reader reader) throws IOException, ListingParseException {
|
public Program parse(Reader reader) throws IOException, ListingParseException {
|
||||||
try {
|
try {
|
||||||
|
@ -88,7 +90,7 @@ public class ListingParser {
|
||||||
lexer = new ListingLexer(reader);
|
lexer = new ListingLexer(reader);
|
||||||
variableMap = new HashMap<>();
|
variableMap = new HashMap<>();
|
||||||
blockMap = new HashMap<>();
|
blockMap = new HashMap<>();
|
||||||
blockFirstOccurence = new LinkedHashMap<>();
|
blockFirstOccurrence = new LinkedHashMap<>();
|
||||||
|
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
parsePrologue();
|
parsePrologue();
|
||||||
|
@ -97,9 +99,9 @@ public class ListingParser {
|
||||||
parseBasicBlock();
|
parseBasicBlock();
|
||||||
} while (lexer.getToken() != ListingToken.EOF);
|
} while (lexer.getToken() != ListingToken.EOF);
|
||||||
|
|
||||||
if (!blockFirstOccurence.isEmpty()) {
|
if (!blockFirstOccurrence.isEmpty()) {
|
||||||
String blockName = blockFirstOccurence.keySet().iterator().next();
|
String blockName = blockFirstOccurrence.keySet().iterator().next();
|
||||||
int blockIndex = blockFirstOccurence.get(blockName);
|
int blockIndex = blockFirstOccurrence.get(blockName);
|
||||||
throw new ListingParseException("Block not defined: " + blockName, blockIndex);
|
throw new ListingParseException("Block not defined: " + blockName, blockIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,7 +111,7 @@ public class ListingParser {
|
||||||
lexer = null;
|
lexer = null;
|
||||||
variableMap = null;
|
variableMap = null;
|
||||||
blockMap = null;
|
blockMap = null;
|
||||||
blockFirstOccurence = null;
|
blockFirstOccurrence = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +155,7 @@ public class ListingParser {
|
||||||
if (!declaredBlocks.add(label)) {
|
if (!declaredBlocks.add(label)) {
|
||||||
throw new ListingParseException("Block with label " + label + " already exists", lexer.getTokenStart());
|
throw new ListingParseException("Block with label " + label + " already exists", lexer.getTokenStart());
|
||||||
}
|
}
|
||||||
blockFirstOccurence.remove(label);
|
blockFirstOccurrence.remove(label);
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
|
|
||||||
expect(ListingToken.EOL);
|
expect(ListingToken.EOL);
|
||||||
|
@ -161,7 +163,7 @@ public class ListingParser {
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
BasicBlock block = blockMap.computeIfAbsent(label, k -> {
|
currentBlock = blockMap.computeIfAbsent(label, k -> {
|
||||||
BasicBlock b = program.createBasicBlock();
|
BasicBlock b = program.createBasicBlock();
|
||||||
b.setLabel(k);
|
b.setLabel(k);
|
||||||
return b;
|
return b;
|
||||||
|
@ -169,7 +171,7 @@ public class ListingParser {
|
||||||
|
|
||||||
currentLocation = null;
|
currentLocation = null;
|
||||||
do {
|
do {
|
||||||
parseInstruction(block);
|
parseInstruction();
|
||||||
} while (lexer.getToken() != ListingToken.LABEL && lexer.getToken() != ListingToken.EOF);
|
} while (lexer.getToken() != ListingToken.LABEL && lexer.getToken() != ListingToken.EOF);
|
||||||
|
|
||||||
while (lexer.getToken() == ListingToken.EOL) {
|
while (lexer.getToken() == ListingToken.EOL) {
|
||||||
|
@ -177,7 +179,7 @@ public class ListingParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseInstruction(BasicBlock block) throws IOException, ListingParseException {
|
private void parseInstruction() throws IOException, ListingParseException {
|
||||||
switch (lexer.getToken()) {
|
switch (lexer.getToken()) {
|
||||||
case IDENTIFIER: {
|
case IDENTIFIER: {
|
||||||
String id = (String) lexer.getTokenValue();
|
String id = (String) lexer.getTokenValue();
|
||||||
|
@ -189,8 +191,7 @@ public class ListingParser {
|
||||||
}
|
}
|
||||||
case "nop": {
|
case "nop": {
|
||||||
EmptyInstruction insn = new EmptyInstruction();
|
EmptyInstruction insn = new EmptyInstruction();
|
||||||
insn.setLocation(currentLocation);
|
addInstruction(insn);
|
||||||
block.getInstructions().add(insn);
|
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -198,38 +199,35 @@ public class ListingParser {
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
BasicBlock target = expectBlock();
|
BasicBlock target = expectBlock();
|
||||||
JumpInstruction insn = new JumpInstruction();
|
JumpInstruction insn = new JumpInstruction();
|
||||||
insn.setLocation(currentLocation);
|
|
||||||
insn.setTarget(target);
|
insn.setTarget(target);
|
||||||
block.getInstructions().add(insn);
|
addInstruction(insn);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "return": {
|
case "return": {
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
ExitInstruction insn = new ExitInstruction();
|
ExitInstruction insn = new ExitInstruction();
|
||||||
insn.setLocation(currentLocation);
|
|
||||||
if (lexer.getToken() == ListingToken.VARIABLE) {
|
if (lexer.getToken() == ListingToken.VARIABLE) {
|
||||||
insn.setValueToReturn(expectVariable());
|
insn.setValueToReturn(expectVariable());
|
||||||
}
|
}
|
||||||
block.getInstructions().add(insn);
|
addInstruction(insn);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "throw": {
|
case "throw": {
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
RaiseInstruction insn = new RaiseInstruction();
|
RaiseInstruction insn = new RaiseInstruction();
|
||||||
insn.setLocation(currentLocation);
|
|
||||||
insn.setException(expectVariable());
|
insn.setException(expectVariable());
|
||||||
block.getInstructions().add(insn);
|
addInstruction(insn);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "if": {
|
case "if": {
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
parseIf(block);
|
parseIf();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "invoke":
|
case "invoke":
|
||||||
case "invokeStatic":
|
case "invokeStatic":
|
||||||
case "invokeVirtual": {
|
case "invokeVirtual": {
|
||||||
parseInvoke(block, null);
|
parseInvoke(null);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "initClass": {
|
case "initClass": {
|
||||||
|
@ -238,24 +236,21 @@ public class ListingParser {
|
||||||
expect(ListingToken.IDENTIFIER);
|
expect(ListingToken.IDENTIFIER);
|
||||||
insn.setClassName((String) lexer.getTokenValue());
|
insn.setClassName((String) lexer.getTokenValue());
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
insn.setLocation(currentLocation);
|
addInstruction(insn);
|
||||||
block.getInstructions().add(insn);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "monitorEnter": {
|
case "monitorEnter": {
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
MonitorEnterInstruction insn = new MonitorEnterInstruction();
|
MonitorEnterInstruction insn = new MonitorEnterInstruction();
|
||||||
insn.setObjectRef(expectVariable());
|
insn.setObjectRef(expectVariable());
|
||||||
insn.setLocation(currentLocation);
|
addInstruction(insn);
|
||||||
block.getInstructions().add(insn);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "monitorExit": {
|
case "monitorExit": {
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
MonitorExitInstruction insn = new MonitorExitInstruction();
|
MonitorExitInstruction insn = new MonitorExitInstruction();
|
||||||
insn.setObjectRef(expectVariable());
|
insn.setObjectRef(expectVariable());
|
||||||
insn.setLocation(currentLocation);
|
addInstruction(insn);
|
||||||
block.getInstructions().add(insn);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -272,11 +267,11 @@ public class ListingParser {
|
||||||
switch (lexer.getToken()) {
|
switch (lexer.getToken()) {
|
||||||
case ASSIGN:
|
case ASSIGN:
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
parseAssignment(block, receiver);
|
parseAssignment(receiver);
|
||||||
break;
|
break;
|
||||||
case LEFT_SQUARE_BRACKET:
|
case LEFT_SQUARE_BRACKET:
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
parseArrayAssignment(block, receiver);
|
parseArrayAssignment(receiver);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
unexpected();
|
unexpected();
|
||||||
|
@ -319,12 +314,12 @@ public class ListingParser {
|
||||||
+ "Expected 'unknown location' or '<string> : <number>'", lexer.getTokenStart());
|
+ "Expected 'unknown location' or '<string> : <number>'", lexer.getTokenStart());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseAssignment(BasicBlock block, Variable receiver) throws IOException, ListingParseException {
|
private void parseAssignment(Variable receiver) throws IOException, ListingParseException {
|
||||||
switch (lexer.getToken()) {
|
switch (lexer.getToken()) {
|
||||||
case VARIABLE: {
|
case VARIABLE: {
|
||||||
Variable variable = getVariable((String) lexer.getTokenValue());
|
Variable variable = getVariable((String) lexer.getTokenValue());
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
parseAssignmentVariable(block, receiver, variable);
|
parseAssignmentVariable(receiver, variable);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case IDENTIFIER: {
|
case IDENTIFIER: {
|
||||||
|
@ -332,33 +327,32 @@ public class ListingParser {
|
||||||
switch (keyword) {
|
switch (keyword) {
|
||||||
case "phi":
|
case "phi":
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
parsePhi(block, receiver);
|
parsePhi(receiver);
|
||||||
break;
|
break;
|
||||||
case "classOf":
|
case "classOf":
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
parseClassLiteral(block, receiver);
|
parseClassLiteral(receiver);
|
||||||
break;
|
break;
|
||||||
case "invoke":
|
case "invoke":
|
||||||
case "invokeVirtual":
|
case "invokeVirtual":
|
||||||
case "invokeStatic":
|
case "invokeStatic":
|
||||||
parseInvoke(block, receiver);
|
parseInvoke(receiver);
|
||||||
break;
|
break;
|
||||||
case "cast":
|
case "cast":
|
||||||
parseCast(block, receiver);
|
parseCast(receiver);
|
||||||
break;
|
break;
|
||||||
case "new":
|
case "new":
|
||||||
parseNew(block, receiver);
|
parseNew(receiver);
|
||||||
break;
|
break;
|
||||||
case "newArray":
|
case "newArray":
|
||||||
parseNewArray(block, receiver);
|
parseNewArray(receiver);
|
||||||
break;
|
break;
|
||||||
case "nullCheck": {
|
case "nullCheck": {
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
NullCheckInstruction insn = new NullCheckInstruction();
|
NullCheckInstruction insn = new NullCheckInstruction();
|
||||||
insn.setReceiver(receiver);
|
insn.setReceiver(receiver);
|
||||||
insn.setValue(expectVariable());
|
insn.setValue(expectVariable());
|
||||||
insn.setLocation(currentLocation);
|
addInstruction(insn);
|
||||||
block.getInstructions().add(insn);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "data": {
|
case "data": {
|
||||||
|
@ -369,8 +363,7 @@ public class ListingParser {
|
||||||
UnwrapArrayInstruction insn = new UnwrapArrayInstruction(type);
|
UnwrapArrayInstruction insn = new UnwrapArrayInstruction(type);
|
||||||
insn.setArray(value);
|
insn.setArray(value);
|
||||||
insn.setReceiver(receiver);
|
insn.setReceiver(receiver);
|
||||||
insn.setLocation(currentLocation);
|
addInstruction(insn);
|
||||||
block.getInstructions().add(insn);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "lengthOf": {
|
case "lengthOf": {
|
||||||
|
@ -378,8 +371,7 @@ public class ListingParser {
|
||||||
ArrayLengthInstruction insn = new ArrayLengthInstruction();
|
ArrayLengthInstruction insn = new ArrayLengthInstruction();
|
||||||
insn.setArray(expectVariable());
|
insn.setArray(expectVariable());
|
||||||
insn.setReceiver(receiver);
|
insn.setReceiver(receiver);
|
||||||
insn.setLocation(currentLocation);
|
addInstruction(insn);
|
||||||
block.getInstructions().add(insn);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case "clone": {
|
case "clone": {
|
||||||
|
@ -387,8 +379,7 @@ public class ListingParser {
|
||||||
CloneArrayInstruction insn = new CloneArrayInstruction();
|
CloneArrayInstruction insn = new CloneArrayInstruction();
|
||||||
insn.setArray(expectVariable());
|
insn.setArray(expectVariable());
|
||||||
insn.setReceiver(receiver);
|
insn.setReceiver(receiver);
|
||||||
insn.setLocation(currentLocation);
|
addInstruction(insn);
|
||||||
block.getInstructions().add(insn);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -398,27 +389,27 @@ public class ListingParser {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case INTEGER: {
|
case INTEGER: {
|
||||||
parseIntConstant(block, receiver);
|
parseIntConstant(receiver);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case LONG: {
|
case LONG: {
|
||||||
parseLongConstant(block, receiver);
|
parseLongConstant(receiver);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case FLOAT: {
|
case FLOAT: {
|
||||||
parseFloatConstant(block, receiver);
|
parseFloatConstant(receiver);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case DOUBLE: {
|
case DOUBLE: {
|
||||||
parseDoubleConstant(block, receiver);
|
parseDoubleConstant(receiver);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case STRING: {
|
case STRING: {
|
||||||
parseStringConstant(block, receiver);
|
parseStringConstant(receiver);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SUBTRACT: {
|
case SUBTRACT: {
|
||||||
parseNegate(block, receiver);
|
parseNegate(receiver);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -426,55 +417,54 @@ public class ListingParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseAssignmentVariable(BasicBlock block, Variable receiver, Variable variable)
|
private void parseAssignmentVariable(Variable receiver, Variable variable)
|
||||||
throws IOException, ListingParseException {
|
throws IOException, ListingParseException {
|
||||||
switch (lexer.getToken()) {
|
switch (lexer.getToken()) {
|
||||||
case EOL:
|
case EOL:
|
||||||
case EOF: {
|
case EOF: {
|
||||||
AssignInstruction insn = new AssignInstruction();
|
AssignInstruction insn = new AssignInstruction();
|
||||||
insn.setLocation(currentLocation);
|
|
||||||
insn.setReceiver(receiver);
|
insn.setReceiver(receiver);
|
||||||
insn.setAssignee(variable);
|
insn.setAssignee(variable);
|
||||||
block.getInstructions().add(insn);
|
addInstruction(insn);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ADD:
|
case ADD:
|
||||||
parseBinary(block, receiver, variable, BinaryOperation.ADD);
|
parseBinary(receiver, variable, BinaryOperation.ADD);
|
||||||
break;
|
break;
|
||||||
case SUBTRACT:
|
case SUBTRACT:
|
||||||
parseBinary(block, receiver, variable, BinaryOperation.SUBTRACT);
|
parseBinary(receiver, variable, BinaryOperation.SUBTRACT);
|
||||||
break;
|
break;
|
||||||
case MULTIPLY:
|
case MULTIPLY:
|
||||||
parseBinary(block, receiver, variable, BinaryOperation.MULTIPLY);
|
parseBinary(receiver, variable, BinaryOperation.MULTIPLY);
|
||||||
break;
|
break;
|
||||||
case DIVIDE:
|
case DIVIDE:
|
||||||
parseBinary(block, receiver, variable, BinaryOperation.DIVIDE);
|
parseBinary(receiver, variable, BinaryOperation.DIVIDE);
|
||||||
break;
|
break;
|
||||||
case REMAINDER:
|
case REMAINDER:
|
||||||
parseBinary(block, receiver, variable, BinaryOperation.MODULO);
|
parseBinary(receiver, variable, BinaryOperation.MODULO);
|
||||||
break;
|
break;
|
||||||
case AND:
|
case AND:
|
||||||
parseBinary(block, receiver, variable, BinaryOperation.AND);
|
parseBinary(receiver, variable, BinaryOperation.AND);
|
||||||
break;
|
break;
|
||||||
case OR:
|
case OR:
|
||||||
parseBinary(block, receiver, variable, BinaryOperation.OR);
|
parseBinary(receiver, variable, BinaryOperation.OR);
|
||||||
break;
|
break;
|
||||||
case XOR:
|
case XOR:
|
||||||
parseBinary(block, receiver, variable, BinaryOperation.XOR);
|
parseBinary(receiver, variable, BinaryOperation.XOR);
|
||||||
break;
|
break;
|
||||||
case SHIFT_LEFT:
|
case SHIFT_LEFT:
|
||||||
parseBinary(block, receiver, variable, BinaryOperation.SHIFT_LEFT);
|
parseBinary(receiver, variable, BinaryOperation.SHIFT_LEFT);
|
||||||
break;
|
break;
|
||||||
case SHIFT_RIGHT:
|
case SHIFT_RIGHT:
|
||||||
parseBinary(block, receiver, variable, BinaryOperation.SHIFT_RIGHT);
|
parseBinary(receiver, variable, BinaryOperation.SHIFT_RIGHT);
|
||||||
break;
|
break;
|
||||||
case SHIFT_RIGHT_UNSIGNED:
|
case SHIFT_RIGHT_UNSIGNED:
|
||||||
parseBinary(block, receiver, variable, BinaryOperation.SHIFT_RIGHT_UNSIGNED);
|
parseBinary(receiver, variable, BinaryOperation.SHIFT_RIGHT_UNSIGNED);
|
||||||
break;
|
break;
|
||||||
case IDENTIFIER:
|
case IDENTIFIER:
|
||||||
switch ((String) lexer.getTokenValue()) {
|
switch ((String) lexer.getTokenValue()) {
|
||||||
case "compareTo":
|
case "compareTo":
|
||||||
parseBinary(block, receiver, variable, BinaryOperation.COMPARE);
|
parseBinary(receiver, variable, BinaryOperation.COMPARE);
|
||||||
break;
|
break;
|
||||||
case "instanceOf": {
|
case "instanceOf": {
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
|
@ -483,8 +473,7 @@ public class ListingParser {
|
||||||
insn.setValue(variable);
|
insn.setValue(variable);
|
||||||
insn.setReceiver(receiver);
|
insn.setReceiver(receiver);
|
||||||
insn.setType(type);
|
insn.setType(type);
|
||||||
insn.setLocation(currentLocation);
|
addInstruction(insn);
|
||||||
block.getInstructions().add(insn);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -497,23 +486,22 @@ public class ListingParser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseBinary(BasicBlock block, Variable receiver, Variable first, BinaryOperation operation)
|
private void parseBinary(Variable receiver, Variable first, BinaryOperation operation)
|
||||||
throws IOException, ListingParseException {
|
throws IOException, ListingParseException {
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
Variable second = expectVariable();
|
Variable second = expectVariable();
|
||||||
expectKeyword("as");
|
expectKeyword("as");
|
||||||
NumericOperandType type = expectNumericType();
|
NumericOperandType type = expectNumericType();
|
||||||
|
|
||||||
BinaryInstruction instruction = new BinaryInstruction(operation, type);
|
BinaryInstruction insn = new BinaryInstruction(operation, type);
|
||||||
instruction.setFirstOperand(first);
|
insn.setFirstOperand(first);
|
||||||
instruction.setSecondOperand(second);
|
insn.setSecondOperand(second);
|
||||||
instruction.setReceiver(receiver);
|
insn.setReceiver(receiver);
|
||||||
instruction.setLocation(currentLocation);
|
|
||||||
|
|
||||||
block.getInstructions().add(instruction);
|
addInstruction(insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseArrayAssignment(BasicBlock block, Variable array) throws IOException, ListingParseException {
|
private void parseArrayAssignment(Variable array) throws IOException, ListingParseException {
|
||||||
Variable index = expectVariable();
|
Variable index = expectVariable();
|
||||||
expect(ListingToken.RIGHT_SQUARE_BRACKET);
|
expect(ListingToken.RIGHT_SQUARE_BRACKET);
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
|
@ -524,14 +512,13 @@ public class ListingParser {
|
||||||
ArrayElementType type = expectArrayType();
|
ArrayElementType type = expectArrayType();
|
||||||
|
|
||||||
PutElementInstruction insn = new PutElementInstruction(type);
|
PutElementInstruction insn = new PutElementInstruction(type);
|
||||||
insn.setLocation(currentLocation);
|
|
||||||
insn.setArray(array);
|
insn.setArray(array);
|
||||||
insn.setIndex(index);
|
insn.setIndex(index);
|
||||||
insn.setValue(value);
|
insn.setValue(value);
|
||||||
block.getInstructions().add(insn);
|
addInstruction(insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parsePhi(BasicBlock block, Variable receiver) throws IOException, ListingParseException {
|
private void parsePhi(Variable receiver) throws IOException, ListingParseException {
|
||||||
int phiStart = lexer.getIndex();
|
int phiStart = lexer.getIndex();
|
||||||
|
|
||||||
Phi phi = new Phi();
|
Phi phi = new Phi();
|
||||||
|
@ -549,69 +536,62 @@ public class ListingParser {
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!block.getInstructions().isEmpty() || block.getExceptionVariable() != null) {
|
if (!currentBlock.getInstructions().isEmpty() || currentBlock.getExceptionVariable() != null) {
|
||||||
throw new ListingParseException("Phi must be first instruction in block", phiStart);
|
throw new ListingParseException("Phi must be first instruction in block", phiStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
block.getPhis().add(phi);
|
currentBlock.getPhis().add(phi);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseClassLiteral(BasicBlock block, Variable receiver) throws IOException, ListingParseException {
|
private void parseClassLiteral(Variable receiver) throws IOException, ListingParseException {
|
||||||
ValueType type = expectValueType();
|
ValueType type = expectValueType();
|
||||||
|
|
||||||
ClassConstantInstruction insn = new ClassConstantInstruction();
|
ClassConstantInstruction insn = new ClassConstantInstruction();
|
||||||
insn.setReceiver(receiver);
|
insn.setReceiver(receiver);
|
||||||
insn.setConstant(type);
|
insn.setConstant(type);
|
||||||
insn.setLocation(currentLocation);
|
addInstruction(insn);
|
||||||
block.getInstructions().add(insn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseIntConstant(BasicBlock block, Variable receiver) throws IOException, ListingParseException {
|
private void parseIntConstant(Variable receiver) throws IOException, ListingParseException {
|
||||||
IntegerConstantInstruction insn = new IntegerConstantInstruction();
|
IntegerConstantInstruction insn = new IntegerConstantInstruction();
|
||||||
insn.setReceiver(receiver);
|
insn.setReceiver(receiver);
|
||||||
insn.setConstant((Integer) lexer.getTokenValue());
|
insn.setConstant((Integer) lexer.getTokenValue());
|
||||||
insn.setLocation(currentLocation);
|
|
||||||
block.getInstructions().add(insn);
|
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
|
addInstruction(insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseLongConstant(BasicBlock block, Variable receiver) throws IOException, ListingParseException {
|
private void parseLongConstant(Variable receiver) throws IOException, ListingParseException {
|
||||||
LongConstantInstruction insn = new LongConstantInstruction();
|
LongConstantInstruction insn = new LongConstantInstruction();
|
||||||
insn.setReceiver(receiver);
|
insn.setReceiver(receiver);
|
||||||
insn.setConstant((Long) lexer.getTokenValue());
|
insn.setConstant((Long) lexer.getTokenValue());
|
||||||
insn.setLocation(currentLocation);
|
|
||||||
block.getInstructions().add(insn);
|
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
|
addInstruction(insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseFloatConstant(BasicBlock block, Variable receiver) throws IOException, ListingParseException {
|
private void parseFloatConstant(Variable receiver) throws IOException, ListingParseException {
|
||||||
FloatConstantInstruction insn = new FloatConstantInstruction();
|
FloatConstantInstruction insn = new FloatConstantInstruction();
|
||||||
insn.setReceiver(receiver);
|
insn.setReceiver(receiver);
|
||||||
insn.setConstant((Float) lexer.getTokenValue());
|
insn.setConstant((Float) lexer.getTokenValue());
|
||||||
insn.setLocation(currentLocation);
|
|
||||||
block.getInstructions().add(insn);
|
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
|
addInstruction(insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseDoubleConstant(BasicBlock block, Variable receiver) throws IOException, ListingParseException {
|
private void parseDoubleConstant(Variable receiver) throws IOException, ListingParseException {
|
||||||
DoubleConstantInstruction insn = new DoubleConstantInstruction();
|
DoubleConstantInstruction insn = new DoubleConstantInstruction();
|
||||||
insn.setReceiver(receiver);
|
insn.setReceiver(receiver);
|
||||||
insn.setConstant((Double) lexer.getTokenValue());
|
insn.setConstant((Double) lexer.getTokenValue());
|
||||||
insn.setLocation(currentLocation);
|
|
||||||
block.getInstructions().add(insn);
|
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
|
addInstruction(insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseStringConstant(BasicBlock block, Variable receiver) throws IOException, ListingParseException {
|
private void parseStringConstant(Variable receiver) throws IOException, ListingParseException {
|
||||||
StringConstantInstruction insn = new StringConstantInstruction();
|
StringConstantInstruction insn = new StringConstantInstruction();
|
||||||
insn.setReceiver(receiver);
|
insn.setReceiver(receiver);
|
||||||
insn.setConstant((String) lexer.getTokenValue());
|
insn.setConstant((String) lexer.getTokenValue());
|
||||||
insn.setLocation(currentLocation);
|
|
||||||
block.getInstructions().add(insn);
|
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
|
addInstruction(insn);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseNegate(BasicBlock block, Variable receiver) throws IOException, ListingParseException {
|
private void parseNegate(Variable receiver) throws IOException, ListingParseException {
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
Variable value = expectVariable();
|
Variable value = expectVariable();
|
||||||
expectKeyword("as");
|
expectKeyword("as");
|
||||||
|
@ -619,11 +599,10 @@ public class ListingParser {
|
||||||
NegateInstruction insn = new NegateInstruction(type);
|
NegateInstruction insn = new NegateInstruction(type);
|
||||||
insn.setReceiver(receiver);
|
insn.setReceiver(receiver);
|
||||||
insn.setOperand(value);
|
insn.setOperand(value);
|
||||||
insn.setLocation(currentLocation);
|
addInstruction(insn);
|
||||||
block.getInstructions().add(insn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseInvoke(BasicBlock block, Variable receiver) throws IOException, ListingParseException {
|
private void parseInvoke(Variable receiver) throws IOException, ListingParseException {
|
||||||
InvokeInstruction insn = new InvokeInstruction();
|
InvokeInstruction insn = new InvokeInstruction();
|
||||||
insn.setReceiver(receiver);
|
insn.setReceiver(receiver);
|
||||||
|
|
||||||
|
@ -642,7 +621,6 @@ public class ListingParser {
|
||||||
}
|
}
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
|
|
||||||
|
|
||||||
expect(ListingToken.IDENTIFIER);
|
expect(ListingToken.IDENTIFIER);
|
||||||
MethodReference method = MethodReference.parseIfPossible((String) lexer.getTokenValue());
|
MethodReference method = MethodReference.parseIfPossible((String) lexer.getTokenValue());
|
||||||
if (method == null) {
|
if (method == null) {
|
||||||
|
@ -671,41 +649,37 @@ public class ListingParser {
|
||||||
insn.getArguments().addAll(arguments);
|
insn.getArguments().addAll(arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
insn.setLocation(currentLocation);
|
addInstruction(insn);
|
||||||
block.getInstructions().add(insn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseCast(BasicBlock block, Variable receiver) throws IOException, ListingParseException {
|
private void parseCast(Variable receiver) throws IOException, ListingParseException {
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
Variable value = expectVariable();
|
Variable value = expectVariable();
|
||||||
expect(ListingToken.IDENTIFIER);
|
expect(ListingToken.IDENTIFIER);
|
||||||
switch ((String) lexer.getTokenValue()) {
|
switch ((String) lexer.getTokenValue()) {
|
||||||
case "from":
|
case "from":
|
||||||
parseNumericCast(block, receiver, value);
|
parseNumericCast(receiver, value);
|
||||||
break;
|
break;
|
||||||
case "to":
|
case "to":
|
||||||
parseObjectCast(block, receiver, value);
|
parseObjectCast(receiver, value);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
unexpected();
|
unexpected();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseNumericCast(BasicBlock block, Variable receiver, Variable value)
|
private void parseNumericCast(Variable receiver, Variable value) throws IOException, ListingParseException {
|
||||||
throws IOException, ListingParseException {
|
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
|
|
||||||
NumericTypeOrIntegerSubtype source = expectTypeOrIntegerSubtype();
|
NumericTypeOrIntegerSubtype source = expectTypeOrIntegerSubtype();
|
||||||
|
|
||||||
if (source.subtype != null) {
|
if (source.subtype != null) {
|
||||||
CastIntegerInstruction insn = new CastIntegerInstruction(source.subtype,
|
CastIntegerInstruction insn = new CastIntegerInstruction(source.subtype, CastIntegerDirection.TO_INTEGER);
|
||||||
CastIntegerDirection.TO_INTEGER);
|
|
||||||
expectKeyword("to");
|
expectKeyword("to");
|
||||||
expectKeyword("int");
|
expectKeyword("int");
|
||||||
insn.setReceiver(receiver);
|
insn.setReceiver(receiver);
|
||||||
insn.setValue(value);
|
insn.setValue(value);
|
||||||
insn.setLocation(currentLocation);
|
addInstruction(insn);
|
||||||
block.getInstructions().add(insn);
|
|
||||||
} else {
|
} else {
|
||||||
expectKeyword("to");
|
expectKeyword("to");
|
||||||
expect(ListingToken.IDENTIFIER);
|
expect(ListingToken.IDENTIFIER);
|
||||||
|
@ -719,14 +693,12 @@ public class ListingParser {
|
||||||
CastIntegerDirection.FROM_INTEGER);
|
CastIntegerDirection.FROM_INTEGER);
|
||||||
insn.setReceiver(receiver);
|
insn.setReceiver(receiver);
|
||||||
insn.setValue(value);
|
insn.setValue(value);
|
||||||
insn.setLocation(currentLocation);
|
addInstruction(insn);
|
||||||
block.getInstructions().add(insn);
|
|
||||||
} else {
|
} else {
|
||||||
CastNumberInstruction insn = new CastNumberInstruction(source.type, target.type);
|
CastNumberInstruction insn = new CastNumberInstruction(source.type, target.type);
|
||||||
insn.setReceiver(receiver);
|
insn.setReceiver(receiver);
|
||||||
insn.setValue(value);
|
insn.setValue(value);
|
||||||
insn.setLocation(currentLocation);
|
addInstruction(insn);
|
||||||
block.getInstructions().add(insn);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -769,14 +741,13 @@ public class ListingParser {
|
||||||
NumericOperandType type;
|
NumericOperandType type;
|
||||||
IntegerSubtype subtype;
|
IntegerSubtype subtype;
|
||||||
|
|
||||||
public NumericTypeOrIntegerSubtype(NumericOperandType type, IntegerSubtype subtype) {
|
NumericTypeOrIntegerSubtype(NumericOperandType type, IntegerSubtype subtype) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.subtype = subtype;
|
this.subtype = subtype;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseObjectCast(BasicBlock block, Variable receiver, Variable value)
|
private void parseObjectCast(Variable receiver, Variable value) throws IOException, ListingParseException {
|
||||||
throws IOException, ListingParseException {
|
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
ValueType type = expectValueType();
|
ValueType type = expectValueType();
|
||||||
|
|
||||||
|
@ -784,11 +755,10 @@ public class ListingParser {
|
||||||
insn.setReceiver(receiver);
|
insn.setReceiver(receiver);
|
||||||
insn.setValue(value);
|
insn.setValue(value);
|
||||||
insn.setTargetType(type);
|
insn.setTargetType(type);
|
||||||
insn.setLocation(currentLocation);
|
addInstruction(insn);
|
||||||
block.getInstructions().add(insn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseNew(BasicBlock block, Variable receiver) throws IOException, ListingParseException {
|
private void parseNew(Variable receiver) throws IOException, ListingParseException {
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
expect(ListingToken.IDENTIFIER);
|
expect(ListingToken.IDENTIFIER);
|
||||||
String type = (String) lexer.getTokenValue();
|
String type = (String) lexer.getTokenValue();
|
||||||
|
@ -797,11 +767,10 @@ public class ListingParser {
|
||||||
ConstructInstruction insn = new ConstructInstruction();
|
ConstructInstruction insn = new ConstructInstruction();
|
||||||
insn.setReceiver(receiver);
|
insn.setReceiver(receiver);
|
||||||
insn.setType(type);
|
insn.setType(type);
|
||||||
insn.setLocation(currentLocation);
|
addInstruction(insn);
|
||||||
block.getInstructions().add(insn);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseNewArray(BasicBlock block, Variable receiver) throws IOException, ListingParseException {
|
private void parseNewArray(Variable receiver) throws IOException, ListingParseException {
|
||||||
lexer.nextToken();
|
lexer.nextToken();
|
||||||
ValueType type = expectValueType();
|
ValueType type = expectValueType();
|
||||||
List<Variable> dimensions = new ArrayList<>();
|
List<Variable> dimensions = new ArrayList<>();
|
||||||
|
@ -818,19 +787,17 @@ public class ListingParser {
|
||||||
insn.setReceiver(receiver);
|
insn.setReceiver(receiver);
|
||||||
insn.setItemType(type);
|
insn.setItemType(type);
|
||||||
insn.setSize(dimensions.get(0));
|
insn.setSize(dimensions.get(0));
|
||||||
insn.setLocation(currentLocation);
|
addInstruction(insn);
|
||||||
block.getInstructions().add(insn);
|
|
||||||
} else {
|
} else {
|
||||||
ConstructMultiArrayInstruction insn = new ConstructMultiArrayInstruction();
|
ConstructMultiArrayInstruction insn = new ConstructMultiArrayInstruction();
|
||||||
insn.setReceiver(receiver);
|
insn.setReceiver(receiver);
|
||||||
insn.setItemType(type);
|
insn.setItemType(type);
|
||||||
insn.getDimensions().addAll(dimensions);
|
insn.getDimensions().addAll(dimensions);
|
||||||
insn.setLocation(currentLocation);
|
addInstruction(insn);
|
||||||
block.getInstructions().add(insn);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseIf(BasicBlock block) throws IOException, ListingParseException {
|
private void parseIf() throws IOException, ListingParseException {
|
||||||
Variable first = expectVariable();
|
Variable first = expectVariable();
|
||||||
|
|
||||||
BinaryBranchingCondition binaryCondition = null;
|
BinaryBranchingCondition binaryCondition = null;
|
||||||
|
@ -900,19 +867,17 @@ public class ListingParser {
|
||||||
throw new ListingParseException("Unsupported binary operation: " + operationToken, operationIndex);
|
throw new ListingParseException("Unsupported binary operation: " + operationToken, operationIndex);
|
||||||
}
|
}
|
||||||
BinaryBranchingInstruction insn = new BinaryBranchingInstruction(binaryCondition);
|
BinaryBranchingInstruction insn = new BinaryBranchingInstruction(binaryCondition);
|
||||||
insn.setLocation(currentLocation);
|
|
||||||
insn.setFirstOperand(first);
|
insn.setFirstOperand(first);
|
||||||
insn.setSecondOperand(second);
|
insn.setSecondOperand(second);
|
||||||
insn.setConsequent(consequent);
|
insn.setConsequent(consequent);
|
||||||
insn.setAlternative(alternative);
|
insn.setAlternative(alternative);
|
||||||
block.getInstructions().add(insn);
|
addInstruction(insn);
|
||||||
} else {
|
} else {
|
||||||
BranchingInstruction insn = new BranchingInstruction(condition);
|
BranchingInstruction insn = new BranchingInstruction(condition);
|
||||||
insn.setLocation(currentLocation);
|
|
||||||
insn.setOperand(first);
|
insn.setOperand(first);
|
||||||
insn.setConsequent(consequent);
|
insn.setConsequent(consequent);
|
||||||
insn.setAlternative(alternative);
|
insn.setAlternative(alternative);
|
||||||
block.getInstructions().add(insn);
|
addInstruction(insn);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1013,7 +978,7 @@ public class ListingParser {
|
||||||
return blockMap.computeIfAbsent(name, k -> {
|
return blockMap.computeIfAbsent(name, k -> {
|
||||||
BasicBlock block = program.createBasicBlock();
|
BasicBlock block = program.createBasicBlock();
|
||||||
block.setLabel(k);
|
block.setLabel(k);
|
||||||
blockFirstOccurence.put(k, lexer.getTokenStart());
|
blockFirstOccurrence.put(k, lexer.getTokenStart());
|
||||||
return block;
|
return block;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1048,4 +1013,9 @@ public class ListingParser {
|
||||||
private void unexpected() throws IOException, ListingParseException {
|
private void unexpected() throws IOException, ListingParseException {
|
||||||
throw new ListingParseException("Unexpected token " + lexer.getToken(), lexer.getTokenStart());
|
throw new ListingParseException("Unexpected token " + lexer.getToken(), lexer.getTokenStart());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void addInstruction(Instruction instruction) {
|
||||||
|
instruction.setLocation(currentLocation);
|
||||||
|
currentBlock.getInstructions().add(instruction);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user