diff options
Diffstat (limited to 'src/moe/anita/mai/token/TokenKind.java')
| -rw-r--r-- | src/moe/anita/mai/token/TokenKind.java | 171 |
1 files changed, 171 insertions, 0 deletions
diff --git a/src/moe/anita/mai/token/TokenKind.java b/src/moe/anita/mai/token/TokenKind.java new file mode 100644 index 0000000..2beadb2 --- /dev/null +++ b/src/moe/anita/mai/token/TokenKind.java @@ -0,0 +1,171 @@ +package moe.anita.mai.token; + +public enum TokenKind { + + // Special + EOF, + ERROR, + EOL, + + // Trivia + WHITESPACE, + COMMENT, + DOC_COMMENT, + + // Names + IDENT, + + // Literals + INT, + FLOAT, + STRING, + RAW_STRING, + RUNE, + + // Delimiters + LPAREN("("), + RPAREN(")"), + LBRACKET("["), + RBRACKET("]"), + LBRACE("{"), + RBRACE("}"), + + COMMA(","), + DOT("."), + COLON(":"), + SEMICOLON(";"), + + // Assignment / declaration + ASSIGN("="), + DECLARE(":="), + + // Arithmetic + INC("++", Precedence.PREFIX, Flags.PREFIX), + DEC("--", Precedence.PREFIX, Flags.PREFIX), + + ADD("+", Precedence.ADD, Flags.INFIX | Flags.PREFIX), + SUB("-", Precedence.ADD, Flags.INFIX | Flags.PREFIX), + + MUL("*", Precedence.MUL, Flags.INFIX), + DIV("/", Precedence.MUL, Flags.INFIX), + MOD("%", Precedence.MUL, Flags.INFIX), + + // Comparison + EQ("==", Precedence.COMPARE, Flags.INFIX), + NE("<>", Precedence.COMPARE, Flags.INFIX), + + LT("<", Precedence.COMPARE, Flags.INFIX), + LE("<=", Precedence.COMPARE, Flags.INFIX), + GT(">", Precedence.COMPARE, Flags.INFIX), + GE(">=", Precedence.COMPARE, Flags.INFIX), + + // Bitwise + BIT_AND("&", Precedence.BIT_AND, Flags.INFIX), + BIT_XOR("^", Precedence.BIT_XOR, Flags.INFIX), + BIT_OR("|", Precedence.BIT_OR, Flags.INFIX), + + BIT_NOT("~", Precedence.PREFIX, Flags.PREFIX), + + // Logical + AND("&&", Precedence.LOGICAL_AND, Flags.INFIX), + OR("||", Precedence.LOGICAL_OR, Flags.INFIX), + + NOT("!", Precedence.PREFIX, Flags.PREFIX), + + // Misc operators + ARROW("->"), + BIND("<-"), + + RANGE(".."), + + QUESTION("?"), + AT("@"), + + /* + * These are parser-created operators. + * + * The lexer emits two LT or GT tokens instead of directly + * producing SHIFT_LEFT / SHIFT_RIGHT. This lets the parser + * distinguish shifts from nested generic type syntax. + */ + SHIFT_LEFT("<<", Precedence.SHIFT, Flags.INFIX), + SHIFT_RIGHT(">>", Precedence.SHIFT, Flags.INFIX); + + private final String spelling; + private final int precedence; + private final int flags; + + TokenKind() { + this(null, Precedence.NONE, Flags.NONE); + } + + TokenKind(String spelling) { + this(spelling, Precedence.NONE, Flags.NONE); + } + + TokenKind(String spelling, int precedence, int flags) { + this.spelling = spelling; + this.precedence = precedence; + this.flags = flags; + } + + public String spelling() { + return spelling; + } + + public int precedence() { + return precedence; + } + + public boolean hasSpelling() { + return spelling != null; + } + + public boolean isInfix() { + return (flags & Flags.INFIX) != 0; + } + + public boolean isPrefix() { + return (flags & Flags.PREFIX) != 0; + } + + + + private static final class Flags { + + private static final int NONE = 0; + + private static final int INFIX = 1 << 0; + private static final int PREFIX = 1 << 1; + + private Flags() { + } + } + + private static final class Precedence { + + private static final int NONE = 0; + + /* + * Larger values bind tighter. + */ + private static final int LOGICAL_OR = 10; + private static final int LOGICAL_AND = 20; + + private static final int BIT_OR = 30; + private static final int BIT_XOR = 40; + private static final int BIT_AND = 50; + + private static final int COMPARE = 60; + + private static final int SHIFT = 70; + + private static final int ADD = 80; + private static final int MUL = 90; + + private static final int PREFIX = 100; + + private Precedence() { + } + } +} |
