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.stream.Collectors;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public final class GraphUtils {
|
||||
static final byte NONE = 0;
|
||||
static final byte VISITING = 1;
|
||||
|
@ -233,12 +229,6 @@ public final class GraphUtils {
|
|||
return components.toArray(new int[0][]);
|
||||
}
|
||||
|
||||
private static class SCCFinder {
|
||||
int[] index;
|
||||
int[] lowlink;
|
||||
boolean[] onStack;
|
||||
}
|
||||
|
||||
public static DominatorTree buildDominatorTree(Graph graph) {
|
||||
DominatorTreeBuilder builder = new DominatorTreeBuilder(graph);
|
||||
builder.build();
|
||||
|
|
|
@ -17,10 +17,6 @@ package org.teavm.model;
|
|||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class MethodHandle {
|
||||
private MethodHandleType kind;
|
||||
private String className;
|
||||
|
|
|
@ -21,10 +21,6 @@ import java.util.stream.Collectors;
|
|||
import org.teavm.model.*;
|
||||
import org.teavm.model.instructions.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
*/
|
||||
public class InstructionStringifier implements InstructionReader {
|
||||
private TextLocation location;
|
||||
private StringBuilder sb;
|
||||
|
@ -64,12 +60,12 @@ public class InstructionStringifier implements InstructionReader {
|
|||
|
||||
@Override
|
||||
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
|
||||
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
|
||||
|
@ -267,38 +263,35 @@ public class InstructionStringifier implements InstructionReader {
|
|||
|
||||
@Override
|
||||
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
|
||||
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) {
|
||||
sb.append(" @").append(instance.getIndex());
|
||||
} else {
|
||||
sb.append(field.getClassName());
|
||||
}
|
||||
sb.append(".").append(field.getFieldName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void putField(VariableReader instance, FieldReference field, VariableReader value, ValueType fieldType) {
|
||||
sb.append("field " + field);
|
||||
if (instance != null) {
|
||||
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
|
||||
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
|
||||
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
|
||||
|
@ -325,19 +318,25 @@ public class InstructionStringifier implements InstructionReader {
|
|||
if (receiver != null) {
|
||||
sb.append("@").append(receiver.getIndex()).append(" := ");
|
||||
}
|
||||
switch (type) {
|
||||
case SPECIAL:
|
||||
sb.append("invoke ");
|
||||
break;
|
||||
case VIRTUAL:
|
||||
sb.append("invokeVirtual ");
|
||||
break;
|
||||
}
|
||||
|
||||
if (instance != null) {
|
||||
sb.append("@").append(instance.getIndex());
|
||||
} else {
|
||||
sb.append(method.getClassName());
|
||||
}
|
||||
sb.append(".").append(method.getName()).append("(");
|
||||
|
||||
for (int i = 0; i < arguments.size(); ++i) {
|
||||
if (i > 0) {
|
||||
if (instance != null || i > 0) {
|
||||
sb.append(", ");
|
||||
}
|
||||
sb.append("@").append(arguments.get(i).getIndex());
|
||||
}
|
||||
sb.append(")");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -410,12 +409,12 @@ public class InstructionStringifier implements InstructionReader {
|
|||
@Override
|
||||
public void isInstance(VariableReader receiver, VariableReader value, ValueType type) {
|
||||
sb.append("@").append(receiver.getIndex()).append(" := @").append(value.getIndex())
|
||||
.append(" instanceof ").append(type);
|
||||
.append(" instanceOf ").append(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initClass(String className) {
|
||||
sb.append("initclass ").append(className);
|
||||
sb.append("initClass ").append(className);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -425,11 +424,11 @@ public class InstructionStringifier implements InstructionReader {
|
|||
|
||||
@Override
|
||||
public void monitorEnter(VariableReader objectRef) {
|
||||
sb.append("monitorenter @").append(objectRef.getIndex());
|
||||
sb.append("monitorEnter @").append(objectRef.getIndex());
|
||||
}
|
||||
|
||||
@Override
|
||||
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()) {
|
||||
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();
|
||||
for (int j = 0; j < incomings.size(); ++j) {
|
||||
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