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