mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-23 00:24:11 -08:00
Working on textual IR
This commit is contained in:
parent
6f92dadad5
commit
e5fe82f0fe
|
@ -21,10 +21,6 @@ import java.util.List;
|
||||||
import java.util.function.IntPredicate;
|
import java.util.function.IntPredicate;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
*/
|
|
||||||
public final class GraphUtils {
|
public final class GraphUtils {
|
||||||
static final byte NONE = 0;
|
static final byte NONE = 0;
|
||||||
static final byte VISITING = 1;
|
static final byte VISITING = 1;
|
||||||
|
@ -233,12 +229,6 @@ public final class GraphUtils {
|
||||||
return components.toArray(new int[0][]);
|
return components.toArray(new int[0][]);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class SCCFinder {
|
|
||||||
int[] index;
|
|
||||||
int[] lowlink;
|
|
||||||
boolean[] onStack;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static DominatorTree buildDominatorTree(Graph graph) {
|
public static DominatorTree buildDominatorTree(Graph graph) {
|
||||||
DominatorTreeBuilder builder = new DominatorTreeBuilder(graph);
|
DominatorTreeBuilder builder = new DominatorTreeBuilder(graph);
|
||||||
builder.build();
|
builder.build();
|
||||||
|
|
|
@ -17,10 +17,6 @@ package org.teavm.model;
|
||||||
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
*/
|
|
||||||
public class MethodHandle {
|
public class MethodHandle {
|
||||||
private MethodHandleType kind;
|
private MethodHandleType kind;
|
||||||
private String className;
|
private String className;
|
||||||
|
|
|
@ -21,10 +21,6 @@ import java.util.stream.Collectors;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
import org.teavm.model.instructions.*;
|
import org.teavm.model.instructions.*;
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @author Alexey Andreev
|
|
||||||
*/
|
|
||||||
public class InstructionStringifier implements InstructionReader {
|
public class InstructionStringifier implements InstructionReader {
|
||||||
private TextLocation location;
|
private TextLocation location;
|
||||||
private StringBuilder sb;
|
private StringBuilder sb;
|
||||||
|
@ -64,12 +60,12 @@ public class InstructionStringifier implements InstructionReader {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void longConstant(VariableReader receiver, long cst) {
|
public void longConstant(VariableReader receiver, long cst) {
|
||||||
sb.append("@").append(receiver.getIndex()).append(" := ").append(cst);
|
sb.append("@").append(receiver.getIndex()).append(" := ").append(cst).append("L");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void floatConstant(VariableReader receiver, float cst) {
|
public void floatConstant(VariableReader receiver, float cst) {
|
||||||
sb.append("@").append(receiver.getIndex()).append(" := ").append(cst);
|
sb.append("@").append(receiver.getIndex()).append(" := ").append(cst).append('F');
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -267,38 +263,35 @@ public class InstructionStringifier implements InstructionReader {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void create(VariableReader receiver, String type) {
|
public void create(VariableReader receiver, String type) {
|
||||||
sb.append("@").append(receiver.getIndex()).append(" = new ").append(type).append("()");
|
sb.append("@").append(receiver.getIndex()).append(" = new ").append(type).append("");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getField(VariableReader receiver, VariableReader instance, FieldReference field, ValueType fieldType) {
|
public void getField(VariableReader receiver, VariableReader instance, FieldReference field, ValueType fieldType) {
|
||||||
sb.append("@").append(receiver.getIndex()).append(" := ");
|
sb.append("@").append(receiver.getIndex()).append(" := field " + field);
|
||||||
|
sb.append(field);
|
||||||
if (instance != null) {
|
if (instance != null) {
|
||||||
sb.append(" @").append(instance.getIndex());
|
sb.append(" @").append(instance.getIndex());
|
||||||
} else {
|
|
||||||
sb.append(field.getClassName());
|
|
||||||
}
|
}
|
||||||
sb.append(".").append(field.getFieldName());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void putField(VariableReader instance, FieldReference field, VariableReader value, ValueType fieldType) {
|
public void putField(VariableReader instance, FieldReference field, VariableReader value, ValueType fieldType) {
|
||||||
|
sb.append("field " + field);
|
||||||
if (instance != null) {
|
if (instance != null) {
|
||||||
sb.append(" @").append(instance.getIndex());
|
sb.append(" @").append(instance.getIndex());
|
||||||
} else {
|
|
||||||
sb.append(field.getClassName());
|
|
||||||
}
|
}
|
||||||
sb.append(".").append(field.getFieldName()).append(" := @").append(value.getIndex());
|
sb.append(" := @").append(value.getIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void arrayLength(VariableReader receiver, VariableReader array) {
|
public void arrayLength(VariableReader receiver, VariableReader array) {
|
||||||
sb.append("@").append(receiver.getIndex()).append(" := @").append(array.getIndex()).append(".length");
|
sb.append("@").append(receiver.getIndex()).append(" := lengthOf @").append(array.getIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void cloneArray(VariableReader receiver, VariableReader array) {
|
public void cloneArray(VariableReader receiver, VariableReader array) {
|
||||||
sb.append("@").append(receiver.getIndex()).append(" := @").append(array.getIndex()).append(".clone()");
|
sb.append("@").append(receiver.getIndex()).append(" := clone @").append(array.getIndex()).append("");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -325,19 +318,25 @@ public class InstructionStringifier implements InstructionReader {
|
||||||
if (receiver != null) {
|
if (receiver != null) {
|
||||||
sb.append("@").append(receiver.getIndex()).append(" := ");
|
sb.append("@").append(receiver.getIndex()).append(" := ");
|
||||||
}
|
}
|
||||||
|
switch (type) {
|
||||||
|
case SPECIAL:
|
||||||
|
sb.append("invoke ");
|
||||||
|
break;
|
||||||
|
case VIRTUAL:
|
||||||
|
sb.append("invokeVirtual ");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (instance != null) {
|
if (instance != null) {
|
||||||
sb.append("@").append(instance.getIndex());
|
sb.append("@").append(instance.getIndex());
|
||||||
} else {
|
|
||||||
sb.append(method.getClassName());
|
|
||||||
}
|
}
|
||||||
sb.append(".").append(method.getName()).append("(");
|
|
||||||
for (int i = 0; i < arguments.size(); ++i) {
|
for (int i = 0; i < arguments.size(); ++i) {
|
||||||
if (i > 0) {
|
if (instance != null || i > 0) {
|
||||||
sb.append(", ");
|
sb.append(", ");
|
||||||
}
|
}
|
||||||
sb.append("@").append(arguments.get(i).getIndex());
|
sb.append("@").append(arguments.get(i).getIndex());
|
||||||
}
|
}
|
||||||
sb.append(")");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -410,12 +409,12 @@ public class InstructionStringifier implements InstructionReader {
|
||||||
@Override
|
@Override
|
||||||
public void isInstance(VariableReader receiver, VariableReader value, ValueType type) {
|
public void isInstance(VariableReader receiver, VariableReader value, ValueType type) {
|
||||||
sb.append("@").append(receiver.getIndex()).append(" := @").append(value.getIndex())
|
sb.append("@").append(receiver.getIndex()).append(" := @").append(value.getIndex())
|
||||||
.append(" instanceof ").append(type);
|
.append(" instanceOf ").append(type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void initClass(String className) {
|
public void initClass(String className) {
|
||||||
sb.append("initclass ").append(className);
|
sb.append("initClass ").append(className);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -425,11 +424,11 @@ public class InstructionStringifier implements InstructionReader {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void monitorEnter(VariableReader objectRef) {
|
public void monitorEnter(VariableReader objectRef) {
|
||||||
sb.append("monitorenter @").append(objectRef.getIndex());
|
sb.append("monitorEnter @").append(objectRef.getIndex());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void monitorExit(VariableReader objectRef) {
|
public void monitorExit(VariableReader objectRef) {
|
||||||
sb.append("monitorexit @").append(objectRef.getIndex());
|
sb.append("monitorExit @").append(objectRef.getIndex());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,7 +46,7 @@ public class ListingBuilder {
|
||||||
|
|
||||||
for (PhiReader phi : block.readPhis()) {
|
for (PhiReader phi : block.readPhis()) {
|
||||||
sb.append(prefix).append(" ");
|
sb.append(prefix).append(" ");
|
||||||
sb.append("@").append(phi.getReceiver().getIndex()).append(" := ");
|
sb.append("@").append(phi.getReceiver().getIndex()).append(" := phi ");
|
||||||
List<? extends IncomingReader> incomings = phi.readIncomings();
|
List<? extends IncomingReader> incomings = phi.readIncomings();
|
||||||
for (int j = 0; j < incomings.size(); ++j) {
|
for (int j = 0; j < incomings.size(); ++j) {
|
||||||
if (j > 0) {
|
if (j > 0) {
|
||||||
|
|
424
core/src/main/java/org/teavm/model/util/ListingLexer.java
Normal file
424
core/src/main/java/org/teavm/model/util/ListingLexer.java
Normal file
|
@ -0,0 +1,424 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.model.util;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.Reader;
|
||||||
|
|
||||||
|
class ListingLexer {
|
||||||
|
private Reader reader;
|
||||||
|
private int c;
|
||||||
|
private ListingToken token;
|
||||||
|
private Object tokenValue;
|
||||||
|
private int index = -1;
|
||||||
|
private int tokenStart;
|
||||||
|
|
||||||
|
public ListingLexer(Reader reader) {
|
||||||
|
this.reader = reader;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ListingToken getToken() {
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object getTokenValue() {
|
||||||
|
return tokenValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getTokenStart() {
|
||||||
|
return tokenStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void nextToken() throws IOException, ListingParseException {
|
||||||
|
if (token == ListingToken.EOF) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
tokenStart = index;
|
||||||
|
if (index < 0) {
|
||||||
|
tokenStart = 0;
|
||||||
|
nextChar();
|
||||||
|
}
|
||||||
|
skipWhiteSpace();
|
||||||
|
|
||||||
|
do {
|
||||||
|
switch (c) {
|
||||||
|
case -1:
|
||||||
|
token = ListingToken.EOF;
|
||||||
|
break;
|
||||||
|
case '@':
|
||||||
|
nextChar();
|
||||||
|
readVariable();
|
||||||
|
break;
|
||||||
|
case '$':
|
||||||
|
readLabel();
|
||||||
|
break;
|
||||||
|
case '\'':
|
||||||
|
readString();
|
||||||
|
break;
|
||||||
|
case ':':
|
||||||
|
nextChar();
|
||||||
|
if (c == '=') {
|
||||||
|
nextChar();
|
||||||
|
token = ListingToken.ASSIGN;
|
||||||
|
} else {
|
||||||
|
token = ListingToken.COLON;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '=':
|
||||||
|
nextChar();
|
||||||
|
expect('=');
|
||||||
|
token = ListingToken.EQUAL;
|
||||||
|
break;
|
||||||
|
case '!':
|
||||||
|
nextChar();
|
||||||
|
expect('=');
|
||||||
|
token = ListingToken.NOT_EQUAL;
|
||||||
|
break;
|
||||||
|
case '<':
|
||||||
|
nextChar();
|
||||||
|
if (c == '=') {
|
||||||
|
nextChar();
|
||||||
|
token = ListingToken.LESS_OR_EQUAL;
|
||||||
|
} else if (c == '<') {
|
||||||
|
nextChar();
|
||||||
|
token = ListingToken.SHIFT_LEFT;
|
||||||
|
} else {
|
||||||
|
token = ListingToken.LESS;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '>':
|
||||||
|
nextChar();
|
||||||
|
if (c == '=') {
|
||||||
|
nextChar();
|
||||||
|
token = ListingToken.GREATER_OR_EQUAL;
|
||||||
|
} else if (c == '>') {
|
||||||
|
nextChar();
|
||||||
|
if (c == '>') {
|
||||||
|
nextChar();
|
||||||
|
token = ListingToken.SHIFT_RIGHT_UNSIGNED;
|
||||||
|
} else {
|
||||||
|
token = ListingToken.SHIFT_RIGHT;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
token = ListingToken.GREATER;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
nextChar();
|
||||||
|
token = ListingToken.ADD;
|
||||||
|
break;
|
||||||
|
case '-':
|
||||||
|
nextChar();
|
||||||
|
token = ListingToken.SUBTRACT;
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
nextChar();
|
||||||
|
token = ListingToken.SUBTRACT;
|
||||||
|
break;
|
||||||
|
case '/':
|
||||||
|
nextChar();
|
||||||
|
if (c == '/') {
|
||||||
|
if (skipComment()) {
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
token = ListingToken.EOF;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
token = ListingToken.DIVIDE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case '%':
|
||||||
|
nextChar();
|
||||||
|
token = ListingToken.REMAINDER;
|
||||||
|
break;
|
||||||
|
case '&':
|
||||||
|
nextChar();
|
||||||
|
token = ListingToken.AND;
|
||||||
|
break;
|
||||||
|
case '|':
|
||||||
|
nextChar();
|
||||||
|
token = ListingToken.OR;
|
||||||
|
break;
|
||||||
|
case '^':
|
||||||
|
nextChar();
|
||||||
|
token = ListingToken.XOR;
|
||||||
|
break;
|
||||||
|
case '.':
|
||||||
|
nextChar();
|
||||||
|
token = ListingToken.DOT;
|
||||||
|
break;
|
||||||
|
case ',':
|
||||||
|
nextChar();
|
||||||
|
token = ListingToken.COMMA;
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
nextChar();
|
||||||
|
token = ListingToken.LEFT_SQUARE_BRACKET;
|
||||||
|
break;
|
||||||
|
case ']':
|
||||||
|
nextChar();
|
||||||
|
token = ListingToken.RIGHT_SQUARE_BRACKET;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (isIdentifierStart()) {
|
||||||
|
readIdentifier();
|
||||||
|
} else if (c >= '0' && c <= '9') {
|
||||||
|
readNumber();
|
||||||
|
} else {
|
||||||
|
unexpected();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} while (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readVariable() throws IOException {
|
||||||
|
nextChar();
|
||||||
|
token = ListingToken.VARIABLE;
|
||||||
|
readIdentifierLike();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readLabel() throws IOException {
|
||||||
|
readIdentifierLike();
|
||||||
|
token = ListingToken.LABEL;
|
||||||
|
readIdentifierLike();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readIdentifierLike() throws IOException {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
while (isIdentifierPart()) {
|
||||||
|
sb.append(c);
|
||||||
|
nextChar();
|
||||||
|
}
|
||||||
|
tokenValue = sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readIdentifier() throws IOException {
|
||||||
|
token = ListingToken.IDENTIFIER;
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(c);
|
||||||
|
while (isIdentifierPart()) {
|
||||||
|
sb.append(c);
|
||||||
|
nextChar();
|
||||||
|
}
|
||||||
|
tokenValue = sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isIdentifierStart() {
|
||||||
|
if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
switch (c) {
|
||||||
|
case '_':
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean isIdentifierPart() {
|
||||||
|
if (isIdentifierStart() || c >= '0' && c <= '9') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
switch (c) {
|
||||||
|
case '<':
|
||||||
|
case '>':
|
||||||
|
case '(':
|
||||||
|
case ')':
|
||||||
|
case '.':
|
||||||
|
case '$':
|
||||||
|
case '#':
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readString() throws IOException, ListingParseException {
|
||||||
|
nextChar();
|
||||||
|
token = ListingToken.STRING;
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
switch (c) {
|
||||||
|
case '\'':
|
||||||
|
nextChar();
|
||||||
|
tokenValue = sb.toString();
|
||||||
|
return;
|
||||||
|
case '\\':
|
||||||
|
switch (c) {
|
||||||
|
case 'n':
|
||||||
|
sb.append('\n');
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
sb.append('\t');
|
||||||
|
break;
|
||||||
|
case '\'':
|
||||||
|
case '\\':
|
||||||
|
sb.append(c);
|
||||||
|
break;
|
||||||
|
case 'u':
|
||||||
|
int codePoint = 0;
|
||||||
|
for (int i = 0; i < 4; ++i) {
|
||||||
|
if (c == -1) {
|
||||||
|
throw new ListingParseException("Wrong escape sequence", index);
|
||||||
|
}
|
||||||
|
int digit = Character.digit((char) c, 16);
|
||||||
|
if (digit < 0) {
|
||||||
|
throw new ListingParseException("Wrong escape sequence", index);
|
||||||
|
}
|
||||||
|
codePoint = codePoint * 16 + digit;
|
||||||
|
}
|
||||||
|
sb.appendCodePoint(codePoint);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new ListingParseException("Wrong escape sequence", index);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
if (c < ' ') {
|
||||||
|
throw new ListingParseException("Unexpected character in string literal: " + c, index);
|
||||||
|
}
|
||||||
|
sb.append(c);
|
||||||
|
nextChar();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void readNumber() throws IOException, ListingParseException {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
sb.append(c);
|
||||||
|
|
||||||
|
nextChar();
|
||||||
|
token = ListingToken.INTEGER;
|
||||||
|
|
||||||
|
while (c >= '0' && c <= '9') {
|
||||||
|
sb.append(c);
|
||||||
|
nextChar();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == '.') {
|
||||||
|
sb.append('.');
|
||||||
|
token = ListingToken.DOUBLE;
|
||||||
|
nextChar();
|
||||||
|
|
||||||
|
if (c < '0' || c > '9') {
|
||||||
|
throw new ListingParseException("Wrong number", index);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (c >= '0' && c <= '9') {
|
||||||
|
sb.append(c);
|
||||||
|
nextChar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == 'E' || c == 'e') {
|
||||||
|
sb.append('e');
|
||||||
|
nextChar();
|
||||||
|
if (c == '+' || c == '-') {
|
||||||
|
sb.append(c);
|
||||||
|
nextChar();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c < '0' || c > '9') {
|
||||||
|
throw new ListingParseException("Wrong number", index);
|
||||||
|
}
|
||||||
|
|
||||||
|
while (c >= '0' && c <= '9') {
|
||||||
|
sb.append(c);
|
||||||
|
nextChar();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c == 'F' || c == 'f') {
|
||||||
|
nextChar();
|
||||||
|
token = ListingToken.FLOAT;
|
||||||
|
} else if (c == 'l' || c == 'L') {
|
||||||
|
nextChar();
|
||||||
|
token = ListingToken.LONG;
|
||||||
|
} else if (isIdentifierStart()) {
|
||||||
|
throw new ListingParseException("Wrong number", index);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (token) {
|
||||||
|
case INTEGER:
|
||||||
|
tokenValue = Integer.parseInt(sb.toString());
|
||||||
|
break;
|
||||||
|
case LONG:
|
||||||
|
tokenValue = Long.parseLong(sb.toString());
|
||||||
|
break;
|
||||||
|
case FLOAT:
|
||||||
|
tokenValue = Float.parseFloat(sb.toString());
|
||||||
|
break;
|
||||||
|
case DOUBLE:
|
||||||
|
tokenValue = Double.parseDouble(sb.toString());
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void expect(char expected) throws IOException, ListingParseException {
|
||||||
|
if (c != expected) {
|
||||||
|
unexpected();
|
||||||
|
}
|
||||||
|
nextChar();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void unexpected() throws ListingParseException {
|
||||||
|
throw new ListingParseException("Unexpected character: " + c, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void skipWhiteSpace() throws IOException {
|
||||||
|
while (true) {
|
||||||
|
switch (c) {
|
||||||
|
case ' ':
|
||||||
|
case '\n':
|
||||||
|
case '\t':
|
||||||
|
nextChar();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean skipComment() throws IOException {
|
||||||
|
while (true) {
|
||||||
|
switch (c) {
|
||||||
|
case '\n':
|
||||||
|
nextChar();
|
||||||
|
return true;
|
||||||
|
case -1:
|
||||||
|
return false;
|
||||||
|
default:
|
||||||
|
nextChar();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void nextChar() throws IOException {
|
||||||
|
c = reader.read();
|
||||||
|
++index;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.model.util;
|
||||||
|
|
||||||
|
public class ListingParseException extends Exception {
|
||||||
|
private final int index;
|
||||||
|
|
||||||
|
public ListingParseException(String message, int index) {
|
||||||
|
super(message);
|
||||||
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getIndex() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
}
|
19
core/src/main/java/org/teavm/model/util/ListingParser.java
Normal file
19
core/src/main/java/org/teavm/model/util/ListingParser.java
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.model.util;
|
||||||
|
|
||||||
|
public class ListingParser {
|
||||||
|
}
|
51
core/src/main/java/org/teavm/model/util/ListingToken.java
Normal file
51
core/src/main/java/org/teavm/model/util/ListingToken.java
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.model.util;
|
||||||
|
|
||||||
|
enum ListingToken {
|
||||||
|
IDENTIFIER,
|
||||||
|
INTEGER,
|
||||||
|
LONG,
|
||||||
|
FLOAT,
|
||||||
|
DOUBLE,
|
||||||
|
STRING,
|
||||||
|
VARIABLE,
|
||||||
|
LABEL,
|
||||||
|
ASSIGN,
|
||||||
|
EQUAL,
|
||||||
|
NOT_EQUAL,
|
||||||
|
LESS,
|
||||||
|
LESS_OR_EQUAL,
|
||||||
|
GREATER,
|
||||||
|
GREATER_OR_EQUAL,
|
||||||
|
ADD,
|
||||||
|
SUBTRACT,
|
||||||
|
MULTIPLY,
|
||||||
|
DIVIDE,
|
||||||
|
REMAINDER,
|
||||||
|
AND,
|
||||||
|
OR,
|
||||||
|
XOR,
|
||||||
|
SHIFT_LEFT,
|
||||||
|
SHIFT_RIGHT,
|
||||||
|
SHIFT_RIGHT_UNSIGNED,
|
||||||
|
DOT,
|
||||||
|
LEFT_SQUARE_BRACKET,
|
||||||
|
RIGHT_SQUARE_BRACKET,
|
||||||
|
COMMA,
|
||||||
|
COLON,
|
||||||
|
EOF
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user