Phase 0: strip JetBrains template, register Jai language and file type
- delete demo tool window + message bundle, rewrite plugin.xml metadata - add JaiLanguage, JaiFileType, file icon, JaiTokenTypes (from the compiler's own lexer: modules/Jai_Lexer/module.jai) - add ./jaitest: runs tests and reports the JUnit XML, not just the exit code - ignore .kotlin
This commit is contained in:
20
src/main/kotlin/dev/hgh/jai/JaiFileType.kt
Normal file
20
src/main/kotlin/dev/hgh/jai/JaiFileType.kt
Normal file
@@ -0,0 +1,20 @@
|
||||
package dev.hgh.jai
|
||||
|
||||
import com.intellij.openapi.fileTypes.LanguageFileType
|
||||
import com.intellij.openapi.util.IconLoader
|
||||
import javax.swing.Icon
|
||||
|
||||
object JaiIcons {
|
||||
@JvmField
|
||||
val FILE: Icon = IconLoader.getIcon("/icons/jai.svg", JaiIcons::class.java)
|
||||
}
|
||||
|
||||
object JaiFileType : LanguageFileType(JaiLanguage) {
|
||||
override fun getName(): String = "Jai"
|
||||
|
||||
override fun getDescription(): String = "Jai source file"
|
||||
|
||||
override fun getDefaultExtension(): String = "jai"
|
||||
|
||||
override fun getIcon(): Icon = JaiIcons.FILE
|
||||
}
|
||||
11
src/main/kotlin/dev/hgh/jai/JaiLanguage.kt
Normal file
11
src/main/kotlin/dev/hgh/jai/JaiLanguage.kt
Normal file
@@ -0,0 +1,11 @@
|
||||
package dev.hgh.jai
|
||||
|
||||
import com.intellij.lang.Language
|
||||
|
||||
object JaiLanguage : Language("Jai") {
|
||||
private fun readResolve(): Any = JaiLanguage
|
||||
|
||||
override fun getDisplayName(): String = "Jai"
|
||||
|
||||
override fun isCaseSensitive(): Boolean = true
|
||||
}
|
||||
390
src/main/kotlin/dev/hgh/jai/lexer/JaiTokenTypes.kt
Normal file
390
src/main/kotlin/dev/hgh/jai/lexer/JaiTokenTypes.kt
Normal file
@@ -0,0 +1,390 @@
|
||||
package dev.hgh.jai.lexer
|
||||
|
||||
import com.intellij.psi.tree.IElementType
|
||||
import com.intellij.psi.tree.TokenSet
|
||||
import dev.hgh.jai.JaiLanguage
|
||||
|
||||
class JaiTokenType(
|
||||
debugName: String,
|
||||
) : IElementType(debugName, JaiLanguage) {
|
||||
override fun toString(): String = "Jai:" + super.toString()
|
||||
}
|
||||
|
||||
/**
|
||||
* The Jai token set.
|
||||
*
|
||||
* Derived from the compiler's own lexer, `~/.local/jai/modules/Jai_Lexer/module.jai`
|
||||
* (`Token_Type` at :17, `check_for_keyword` at :758, `compose_new_token` at :1503).
|
||||
* See `docs/JAI_LANGUAGE_REFERENCE.md` §3/§4.
|
||||
*
|
||||
* Deliberate divergences from the compiler lexer, all in favour of the IDE:
|
||||
* - `#ident` is a single [DIRECTIVE] token (the compiler emits `#` then an ident).
|
||||
* - `#string ID ... ID` is a single [HERE_STRING] token, so the lexer never has to
|
||||
* carry the terminator across a token boundary and can restart anywhere.
|
||||
* - `::` and `:=` are single tokens (the compiler emits separate `:` `:` / `:` `=`).
|
||||
* - The backtick of a backticked identifier is its own [BACKTICK] token (the compiler
|
||||
* folds it into the identifier token as a flag).
|
||||
*/
|
||||
object JaiTokenTypes {
|
||||
// --- trivia -----------------------------------------------------------
|
||||
@JvmField val LINE_COMMENT = JaiTokenType("LINE_COMMENT")
|
||||
|
||||
@JvmField val BLOCK_COMMENT = JaiTokenType("BLOCK_COMMENT")
|
||||
|
||||
// --- literals and names -----------------------------------------------
|
||||
@JvmField val IDENT = JaiTokenType("IDENT")
|
||||
|
||||
@JvmField val NUMBER = JaiTokenType("NUMBER")
|
||||
|
||||
@JvmField val STRING = JaiTokenType("STRING")
|
||||
|
||||
@JvmField val HERE_STRING = JaiTokenType("HERE_STRING")
|
||||
|
||||
@JvmField val DIRECTIVE = JaiTokenType("DIRECTIVE")
|
||||
|
||||
@JvmField val NOTE = JaiTokenType("NOTE")
|
||||
|
||||
// --- keywords ---------------------------------------------------------
|
||||
@JvmField val KW_IF = JaiTokenType("if")
|
||||
|
||||
@JvmField val KW_XX = JaiTokenType("xx")
|
||||
|
||||
@JvmField val KW_IFX = JaiTokenType("ifx")
|
||||
|
||||
@JvmField val KW_FOR = JaiTokenType("for")
|
||||
|
||||
@JvmField val KW_THEN = JaiTokenType("then")
|
||||
|
||||
@JvmField val KW_ELSE = JaiTokenType("else")
|
||||
|
||||
@JvmField val KW_NULL = JaiTokenType("null")
|
||||
|
||||
@JvmField val KW_CASE = JaiTokenType("case")
|
||||
|
||||
@JvmField val KW_ENUM = JaiTokenType("enum")
|
||||
|
||||
@JvmField val KW_TRUE = JaiTokenType("true")
|
||||
|
||||
@JvmField val KW_CAST = JaiTokenType("cast")
|
||||
|
||||
@JvmField val KW_WHILE = JaiTokenType("while")
|
||||
|
||||
@JvmField val KW_BREAK = JaiTokenType("break")
|
||||
|
||||
@JvmField val KW_USING = JaiTokenType("using")
|
||||
|
||||
@JvmField val KW_DEFER = JaiTokenType("defer")
|
||||
|
||||
@JvmField val KW_FALSE = JaiTokenType("false")
|
||||
|
||||
@JvmField val KW_UNION = JaiTokenType("union")
|
||||
|
||||
@JvmField val KW_RETURN = JaiTokenType("return")
|
||||
|
||||
@JvmField val KW_STRUCT = JaiTokenType("struct")
|
||||
|
||||
@JvmField val KW_REMOVE = JaiTokenType("remove")
|
||||
|
||||
@JvmField val KW_INLINE = JaiTokenType("inline")
|
||||
|
||||
@JvmField val KW_SIZE_OF = JaiTokenType("size_of")
|
||||
|
||||
@JvmField val KW_TYPE_OF = JaiTokenType("type_of")
|
||||
|
||||
@JvmField val KW_CODE_OF = JaiTokenType("code_of")
|
||||
|
||||
@JvmField val KW_CONTEXT = JaiTokenType("context")
|
||||
|
||||
@JvmField val KW_CONTINUE = JaiTokenType("continue")
|
||||
|
||||
@JvmField val KW_OPERATOR = JaiTokenType("operator")
|
||||
|
||||
@JvmField val KW_TYPE_INFO = JaiTokenType("type_info")
|
||||
|
||||
@JvmField val KW_NO_INLINE = JaiTokenType("no_inline")
|
||||
|
||||
@JvmField val KW_INTERFACE = JaiTokenType("interface")
|
||||
|
||||
@JvmField val KW_ENUM_FLAGS = JaiTokenType("enum_flags")
|
||||
|
||||
@JvmField val KW_IS_CONSTANT = JaiTokenType("is_constant")
|
||||
|
||||
@JvmField val KW_PUSH_CONTEXT = JaiTokenType("push_context")
|
||||
|
||||
@JvmField val KW_INITIALIZER_OF = JaiTokenType("initializer_of")
|
||||
|
||||
/** `name` -> keyword token. Exactly `check_for_keyword`, nothing more. */
|
||||
@JvmField
|
||||
val KEYWORD_MAP: Map<String, JaiTokenType> =
|
||||
mapOf(
|
||||
"if" to KW_IF,
|
||||
"xx" to KW_XX,
|
||||
"ifx" to KW_IFX,
|
||||
"for" to KW_FOR,
|
||||
"then" to KW_THEN,
|
||||
"else" to KW_ELSE,
|
||||
"null" to KW_NULL,
|
||||
"case" to KW_CASE,
|
||||
"enum" to KW_ENUM,
|
||||
"true" to KW_TRUE,
|
||||
"cast" to KW_CAST,
|
||||
"while" to KW_WHILE,
|
||||
"break" to KW_BREAK,
|
||||
"using" to KW_USING,
|
||||
"defer" to KW_DEFER,
|
||||
"false" to KW_FALSE,
|
||||
"union" to KW_UNION,
|
||||
"return" to KW_RETURN,
|
||||
"struct" to KW_STRUCT,
|
||||
"remove" to KW_REMOVE,
|
||||
"inline" to KW_INLINE,
|
||||
"size_of" to KW_SIZE_OF,
|
||||
"type_of" to KW_TYPE_OF,
|
||||
"code_of" to KW_CODE_OF,
|
||||
"context" to KW_CONTEXT,
|
||||
"continue" to KW_CONTINUE,
|
||||
"operator" to KW_OPERATOR,
|
||||
"type_info" to KW_TYPE_INFO,
|
||||
"no_inline" to KW_NO_INLINE,
|
||||
"interface" to KW_INTERFACE,
|
||||
"enum_flags" to KW_ENUM_FLAGS,
|
||||
"is_constant" to KW_IS_CONSTANT,
|
||||
"push_context" to KW_PUSH_CONTEXT,
|
||||
"initializer_of" to KW_INITIALIZER_OF,
|
||||
)
|
||||
|
||||
/**
|
||||
* Built-in type names. These are ordinary identifiers to the compiler — they are
|
||||
* *not* reserved — but they get their own highlight. Kept as a name set, not a
|
||||
* token type, so the parser can never depend on them being keywords.
|
||||
* See `docs/JAI_LANGUAGE_REFERENCE.md` §3.
|
||||
*/
|
||||
@JvmField
|
||||
val BUILTIN_TYPE_NAMES: Set<String> =
|
||||
setOf(
|
||||
"s8",
|
||||
"s16",
|
||||
"s32",
|
||||
"s64",
|
||||
"u8",
|
||||
"u16",
|
||||
"u32",
|
||||
"u64",
|
||||
"int",
|
||||
"float",
|
||||
"float32",
|
||||
"float64",
|
||||
"bool",
|
||||
"string",
|
||||
"void",
|
||||
"Type",
|
||||
"Any",
|
||||
"Code",
|
||||
)
|
||||
|
||||
/** Implicit `for` loop variables. Ordinary identifiers, highlighted specially. */
|
||||
@JvmField
|
||||
val LOOP_VARIABLE_NAMES: Set<String> = setOf("it", "it_index")
|
||||
|
||||
// --- operators and punctuation ----------------------------------------
|
||||
@JvmField val PLUS = JaiTokenType("+")
|
||||
|
||||
@JvmField val MINUS = JaiTokenType("-")
|
||||
|
||||
@JvmField val STAR = JaiTokenType("*")
|
||||
|
||||
@JvmField val SLASH = JaiTokenType("/")
|
||||
|
||||
@JvmField val PERCENT = JaiTokenType("%")
|
||||
|
||||
@JvmField val PLUS_EQ = JaiTokenType("+=")
|
||||
|
||||
@JvmField val MINUS_EQ = JaiTokenType("-=")
|
||||
|
||||
@JvmField val STAR_EQ = JaiTokenType("*=")
|
||||
|
||||
@JvmField val SLASH_EQ = JaiTokenType("/=")
|
||||
|
||||
@JvmField val PERCENT_EQ = JaiTokenType("%=")
|
||||
|
||||
@JvmField val EQ = JaiTokenType("=")
|
||||
|
||||
@JvmField val EQ_EQ = JaiTokenType("==")
|
||||
|
||||
@JvmField val EQ_EQ_EQ = JaiTokenType("===")
|
||||
|
||||
@JvmField val NOT_EQ = JaiTokenType("!=")
|
||||
|
||||
@JvmField val NOT = JaiTokenType("!")
|
||||
|
||||
@JvmField val LT = JaiTokenType("<")
|
||||
|
||||
@JvmField val GT = JaiTokenType(">")
|
||||
|
||||
@JvmField val LT_EQ = JaiTokenType("<=")
|
||||
|
||||
@JvmField val GT_EQ = JaiTokenType(">=")
|
||||
|
||||
@JvmField val AND_AND = JaiTokenType("&&")
|
||||
|
||||
@JvmField val OR_OR = JaiTokenType("||")
|
||||
|
||||
@JvmField val AND_AND_EQ = JaiTokenType("&&=")
|
||||
|
||||
@JvmField val OR_OR_EQ = JaiTokenType("||=")
|
||||
|
||||
@JvmField val AND = JaiTokenType("&")
|
||||
|
||||
@JvmField val OR = JaiTokenType("|")
|
||||
|
||||
@JvmField val XOR = JaiTokenType("^")
|
||||
|
||||
@JvmField val TILDE = JaiTokenType("~")
|
||||
|
||||
@JvmField val AND_EQ = JaiTokenType("&=")
|
||||
|
||||
@JvmField val OR_EQ = JaiTokenType("|=")
|
||||
|
||||
@JvmField val XOR_EQ = JaiTokenType("^=")
|
||||
|
||||
@JvmField val SHL = JaiTokenType("<<")
|
||||
|
||||
@JvmField val SHR = JaiTokenType(">>")
|
||||
|
||||
@JvmField val SHL_EQ = JaiTokenType("<<=")
|
||||
|
||||
@JvmField val SHR_EQ = JaiTokenType(">>=")
|
||||
|
||||
@JvmField val ROL = JaiTokenType("<<<")
|
||||
|
||||
@JvmField val ROR = JaiTokenType(">>>")
|
||||
|
||||
@JvmField val ROL_EQ = JaiTokenType("<<<=")
|
||||
|
||||
@JvmField val ROR_EQ = JaiTokenType(">>>=")
|
||||
|
||||
@JvmField val RIGHT_ARROW = JaiTokenType("->")
|
||||
|
||||
@JvmField val QUICK_LAMBDA = JaiTokenType("=>")
|
||||
|
||||
@JvmField val DOUBLE_DOT = JaiTokenType("..")
|
||||
|
||||
@JvmField val TRIPLE_MINUS = JaiTokenType("---")
|
||||
|
||||
@JvmField val DOUBLE_MINUS = JaiTokenType("--")
|
||||
|
||||
@JvmField val DOUBLE_COMMA = JaiTokenType(",,")
|
||||
|
||||
@JvmField val BEGIN_STRUCT_LITERAL = JaiTokenType(".{")
|
||||
|
||||
@JvmField val BEGIN_ARRAY_LITERAL = JaiTokenType(".[")
|
||||
|
||||
@JvmField val POSTFIX_DEREFERENCE = JaiTokenType(".*")
|
||||
|
||||
@JvmField val DOLLAR = JaiTokenType("$")
|
||||
|
||||
@JvmField val DOUBLE_DOLLAR = JaiTokenType("$$")
|
||||
|
||||
@JvmField val COLON = JaiTokenType(":")
|
||||
|
||||
@JvmField val COLON_COLON = JaiTokenType("::")
|
||||
|
||||
@JvmField val COLON_EQ = JaiTokenType(":=")
|
||||
|
||||
@JvmField val SEMICOLON = JaiTokenType(";")
|
||||
|
||||
@JvmField val COMMA = JaiTokenType(",")
|
||||
|
||||
@JvmField val DOT = JaiTokenType(".")
|
||||
|
||||
@JvmField val QUESTION = JaiTokenType("?")
|
||||
|
||||
@JvmField val BACKTICK = JaiTokenType("`")
|
||||
|
||||
@JvmField val BACKSLASH = JaiTokenType("\\")
|
||||
|
||||
@JvmField val HASH = JaiTokenType("#")
|
||||
|
||||
@JvmField val AT = JaiTokenType("@")
|
||||
|
||||
@JvmField val LPAREN = JaiTokenType("(")
|
||||
|
||||
@JvmField val RPAREN = JaiTokenType(")")
|
||||
|
||||
@JvmField val LBRACKET = JaiTokenType("[")
|
||||
|
||||
@JvmField val RBRACKET = JaiTokenType("]")
|
||||
|
||||
@JvmField val LBRACE = JaiTokenType("{")
|
||||
|
||||
@JvmField val RBRACE = JaiTokenType("}")
|
||||
|
||||
// --- token sets -------------------------------------------------------
|
||||
@JvmField val COMMENTS: TokenSet = TokenSet.create(LINE_COMMENT, BLOCK_COMMENT)
|
||||
|
||||
@JvmField val STRINGS: TokenSet = TokenSet.create(STRING, HERE_STRING)
|
||||
|
||||
@JvmField val KEYWORDS: TokenSet = TokenSet.create(*KEYWORD_MAP.values.toTypedArray())
|
||||
|
||||
@JvmField
|
||||
val OPERATORS: TokenSet =
|
||||
TokenSet.create(
|
||||
PLUS,
|
||||
MINUS,
|
||||
STAR,
|
||||
SLASH,
|
||||
PERCENT,
|
||||
PLUS_EQ,
|
||||
MINUS_EQ,
|
||||
STAR_EQ,
|
||||
SLASH_EQ,
|
||||
PERCENT_EQ,
|
||||
EQ,
|
||||
EQ_EQ,
|
||||
EQ_EQ_EQ,
|
||||
NOT_EQ,
|
||||
NOT,
|
||||
LT,
|
||||
GT,
|
||||
LT_EQ,
|
||||
GT_EQ,
|
||||
AND_AND,
|
||||
OR_OR,
|
||||
AND_AND_EQ,
|
||||
OR_OR_EQ,
|
||||
AND,
|
||||
OR,
|
||||
XOR,
|
||||
TILDE,
|
||||
AND_EQ,
|
||||
OR_EQ,
|
||||
XOR_EQ,
|
||||
SHL,
|
||||
SHR,
|
||||
SHL_EQ,
|
||||
SHR_EQ,
|
||||
ROL,
|
||||
ROR,
|
||||
ROL_EQ,
|
||||
ROR_EQ,
|
||||
RIGHT_ARROW,
|
||||
QUICK_LAMBDA,
|
||||
DOUBLE_DOT,
|
||||
DOUBLE_MINUS,
|
||||
BEGIN_STRUCT_LITERAL,
|
||||
BEGIN_ARRAY_LITERAL,
|
||||
POSTFIX_DEREFERENCE,
|
||||
DOLLAR,
|
||||
DOUBLE_DOLLAR,
|
||||
COLON,
|
||||
COLON_COLON,
|
||||
COLON_EQ,
|
||||
DOUBLE_COMMA,
|
||||
DOT,
|
||||
QUESTION,
|
||||
BACKTICK,
|
||||
BACKSLASH,
|
||||
HASH,
|
||||
AT,
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user