MISC: even more flatten!
This commit is contained in:
parent
56167cce5d
commit
236072395c
@ -1,6 +0,0 @@
|
||||
package io.neolang.ast
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangEOFToken : NeoLangToken(NeoLangTokenType.EOF, NeoLangTokenValue.EOF)
|
@ -1,13 +0,0 @@
|
||||
package io.neolang.ast
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
|
||||
open class NeoLangToken(val tokenType: NeoLangTokenType, val tokenValue: NeoLangTokenValue) {
|
||||
var lineNumber = 0
|
||||
|
||||
override fun toString(): String {
|
||||
return "Token { tokenType: $tokenType, tokenValue: $tokenValue };"
|
||||
}
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package io.neolang.ast
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
|
||||
enum class NeoLangTokenType {
|
||||
NUMBER,
|
||||
ID,
|
||||
STRING,
|
||||
BRACKET_START,
|
||||
BRACKET_END,
|
||||
ARRAY_START,
|
||||
ARRAY_END,
|
||||
COLON,
|
||||
COMMA,
|
||||
EOL,
|
||||
EOF,
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package io.neolang.ast.base
|
||||
|
||||
import io.neolang.ast.visitor.VisitorFactory
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
open class NeoLangAst {
|
||||
fun visit(): VisitorFactory {
|
||||
return VisitorFactory(this)
|
||||
}
|
||||
}
|
@ -1,3 +0,0 @@
|
||||
package io.neolang.ast.base
|
||||
|
||||
open class NeoLangBaseNode : NeoLangAst()
|
@ -1,12 +0,0 @@
|
||||
package io.neolang.ast.node
|
||||
|
||||
import io.neolang.ast.base.NeoLangBaseNode
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangArrayNode(val arrayNameNode: NeoLangStringNode, val elements: Array<ArrayElement>) : NeoLangBaseNode() {
|
||||
companion object {
|
||||
class ArrayElement(val index: Int, val block: NeoLangBlockNode)
|
||||
}
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package io.neolang.ast.node
|
||||
|
||||
import io.neolang.ast.base.NeoLangBaseNode
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
open class NeoLangAstBasedNode(val ast: NeoLangBaseNode) : NeoLangBaseNode() {
|
||||
override fun toString(): String {
|
||||
return "${javaClass.simpleName} { ast: $ast }"
|
||||
}
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
package io.neolang.ast.node
|
||||
|
||||
import io.neolang.ast.base.NeoLangBaseNode
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangAttributeNode(val stringNode: NeoLangStringNode, val blockNode: NeoLangBlockNode) : NeoLangBaseNode() {
|
||||
|
||||
override fun toString(): String {
|
||||
return "NeoLangAttributeNode { stringNode: $stringNode, block: $blockNode }"
|
||||
}
|
||||
}
|
@ -1,14 +0,0 @@
|
||||
package io.neolang.ast.node
|
||||
|
||||
import io.neolang.ast.base.NeoLangBaseNode
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangBlockNode(blockElement: NeoLangBaseNode) : NeoLangAstBasedNode(blockElement) {
|
||||
companion object {
|
||||
fun emptyNode(): NeoLangBlockNode {
|
||||
return NeoLangBlockNode(NeoLangDummyNode())
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
package io.neolang.ast.node
|
||||
|
||||
import io.neolang.ast.base.NeoLangBaseNode
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangDummyNode : NeoLangBaseNode()
|
@ -1,19 +0,0 @@
|
||||
package io.neolang.ast.node
|
||||
|
||||
import io.neolang.ast.base.NeoLangBaseNode
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangGroupNode(val attributes: Array<NeoLangAttributeNode>) : NeoLangBaseNode() {
|
||||
|
||||
override fun toString(): String {
|
||||
return "NeoLangGroupNode { attrs: $attributes }"
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun emptyNode(): NeoLangGroupNode {
|
||||
return NeoLangGroupNode(arrayOf())
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
package io.neolang.ast.node
|
||||
|
||||
import io.neolang.ast.NeoLangToken
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangNumberNode(token: NeoLangToken) : NeoLangTokenBasedNode(token)
|
@ -1,21 +0,0 @@
|
||||
package io.neolang.ast.node
|
||||
|
||||
import io.neolang.ast.base.NeoLangBaseNode
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
|
||||
class NeoLangProgramNode(val groups: List<NeoLangGroupNode>) : NeoLangBaseNode() {
|
||||
|
||||
override fun toString(): String {
|
||||
return "NeoLangProgramNode { groups: $groups }"
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun emptyNode(): NeoLangProgramNode {
|
||||
return NeoLangProgramNode(listOf())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +0,0 @@
|
||||
package io.neolang.ast.node
|
||||
|
||||
import io.neolang.ast.NeoLangToken
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangStringNode(token: NeoLangToken) : NeoLangTokenBasedNode(token)
|
@ -1,18 +0,0 @@
|
||||
package io.neolang.ast.node
|
||||
|
||||
import io.neolang.ast.NeoLangToken
|
||||
import io.neolang.ast.base.NeoLangBaseNode
|
||||
import io.neolang.runtime.type.NeoLangValue
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
open class NeoLangTokenBasedNode(val token: NeoLangToken) : NeoLangBaseNode() {
|
||||
override fun toString(): String {
|
||||
return "${javaClass.simpleName} { token: $token }"
|
||||
}
|
||||
|
||||
fun eval(): NeoLangValue {
|
||||
return token.tokenValue.value
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package io.neolang.ast.visitor
|
||||
|
||||
import io.neolang.ast.base.NeoLangAst
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class AstVisitor(private val ast: NeoLangAst, private val visitorCallback: IVisitorCallback) {
|
||||
fun start() {
|
||||
AstVisitorImpl.visitStartAst(ast, visitorCallback)
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T : IVisitorCallback> getCallback(): T {
|
||||
return visitorCallback as T
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package io.neolang.ast.visitor
|
||||
|
||||
import io.neolang.runtime.context.NeoLangContext
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
interface IVisitorCallback {
|
||||
fun onStart()
|
||||
|
||||
fun onFinish()
|
||||
|
||||
fun onEnterContext(contextName: String)
|
||||
|
||||
fun onExitContext()
|
||||
|
||||
fun getCurrentContext(): NeoLangContext
|
||||
}
|
@ -1,24 +0,0 @@
|
||||
package io.neolang.ast.visitor
|
||||
|
||||
import io.neolang.runtime.context.NeoLangContext
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
open class IVisitorCallbackAdapter : IVisitorCallback {
|
||||
override fun onStart() {
|
||||
}
|
||||
|
||||
override fun onFinish() {
|
||||
}
|
||||
|
||||
override fun onEnterContext(contextName: String) {
|
||||
}
|
||||
|
||||
override fun onExitContext() {
|
||||
}
|
||||
|
||||
override fun getCurrentContext(): NeoLangContext {
|
||||
throw RuntimeException("getCurrentContext() not supported in this IVisitorCallback!")
|
||||
}
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package io.neolang.ast.visitor
|
||||
|
||||
import io.neolang.ast.base.NeoLangAst
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
|
||||
class VisitorFactory(private val ast: NeoLangAst) {
|
||||
|
||||
fun getVisitor(callbackInterface: Class<out IVisitorCallback>): AstVisitor? {
|
||||
try {
|
||||
return AstVisitor(ast, callbackInterface.newInstance())
|
||||
} catch (e: Exception) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +1,21 @@
|
||||
package io.neolang.ast.visitor
|
||||
|
||||
import io.neolang.ast.base.NeoLangAst
|
||||
import io.neolang.ast.node.*
|
||||
import io.neolang.runtime.type.NeoLangValue
|
||||
package io.neolang.frontend
|
||||
|
||||
import io.neolang.runtime.NeoLangContext
|
||||
import io.neolang.runtime.NeoLangValue
|
||||
|
||||
/**
|
||||
* grammar: [
|
||||
* program: group (group)*
|
||||
* group: attribute (attribute)*
|
||||
* attribute: ID COLON block
|
||||
* block: STRING | NUMBER | (BRACKET_START [group|] BRACKET_END) | (ARRAY_START [block(<,block>)+|] ARRAY_END)
|
||||
* ]
|
||||
* @author kiva
|
||||
*/
|
||||
class AstVisitor(private val ast: NeoLangAst, private val visitorCallback: IVisitorCallback) {
|
||||
fun start() {
|
||||
AstVisitorImpl.visitStartAst(ast, visitorCallback)
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T : IVisitorCallback> getCallback(): T {
|
||||
return visitorCallback as T
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
@ -102,3 +105,54 @@ internal object AstVisitorImpl {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
interface IVisitorCallback {
|
||||
fun onStart()
|
||||
|
||||
fun onFinish()
|
||||
|
||||
fun onEnterContext(contextName: String)
|
||||
|
||||
fun onExitContext()
|
||||
|
||||
fun getCurrentContext(): NeoLangContext
|
||||
}
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
open class IVisitorCallbackAdapter : IVisitorCallback {
|
||||
override fun onStart() {
|
||||
}
|
||||
|
||||
override fun onFinish() {
|
||||
}
|
||||
|
||||
override fun onEnterContext(contextName: String) {
|
||||
}
|
||||
|
||||
override fun onExitContext() {
|
||||
}
|
||||
|
||||
override fun getCurrentContext(): NeoLangContext {
|
||||
throw RuntimeException("getCurrentContext() not supported in this IVisitorCallback!")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
|
||||
class VisitorFactory(private val ast: NeoLangAst) {
|
||||
|
||||
fun getVisitor(callbackInterface: Class<out IVisitorCallback>): AstVisitor? {
|
||||
try {
|
||||
return AstVisitor(ast, callbackInterface.newInstance())
|
||||
} catch (e: Exception) {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
225
NeoLang/src/main/java/io/neolang/parser/NeoLangLexer.kt → NeoLang/src/main/java/io/neolang/frontend/frontend.kt
Executable file → Normal file
225
NeoLang/src/main/java/io/neolang/parser/NeoLangLexer.kt → NeoLang/src/main/java/io/neolang/frontend/frontend.kt
Executable file → Normal file
@ -1,18 +1,4 @@
|
||||
package io.neolang.parser
|
||||
|
||||
import io.neolang.ast.NeoLangEOFToken
|
||||
import io.neolang.ast.NeoLangToken
|
||||
import io.neolang.ast.NeoLangTokenType
|
||||
import io.neolang.ast.NeoLangTokenValue
|
||||
|
||||
/**
|
||||
* grammar: [
|
||||
* program: group (group)*
|
||||
* group: attribute (attribute)*
|
||||
* attribute: ID COLON block
|
||||
* block: STRING | NUMBER | (BRACKET_START [group|] BRACKET_END) | (ARRAY_START [block(<,block>)+|] ARRAY_END)
|
||||
* ]
|
||||
*/
|
||||
package io.neolang.frontend
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
@ -201,9 +187,7 @@ class NeoLangLexer {
|
||||
var value = numberValue
|
||||
var loop = moveToNextChar() // skip 'x' or 'X'
|
||||
while (loop && (currentChar.isHexNumber())) {
|
||||
value *= 16
|
||||
+(currentChar.toInt().and(15))
|
||||
+if (currentChar >= 'A') 9 else 0
|
||||
value *= 16 + (currentChar.toInt().and(15)) + if (currentChar >= 'A') 9 else 0
|
||||
loop = moveToNextChar()
|
||||
}
|
||||
return value
|
||||
@ -270,3 +254,208 @@ class NeoLangLexer {
|
||||
|| this in ('A'..'F')
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangParser {
|
||||
private val lexer = NeoLangLexer()
|
||||
private var tokens = mutableListOf<NeoLangToken>()
|
||||
private var currentPosition: Int = 0
|
||||
private var currentToken: NeoLangToken? = null
|
||||
|
||||
fun setInputSource(programCode: String?) {
|
||||
lexer.setInputSource(programCode)
|
||||
}
|
||||
|
||||
fun parse(): NeoLangAst {
|
||||
return updateParserStatus(lexer.lex()) ?: throw ParseException("AST is null")
|
||||
}
|
||||
|
||||
private fun updateParserStatus(tokens: List<NeoLangToken>): NeoLangAst? {
|
||||
if (tokens.isEmpty()) {
|
||||
// Allow empty program
|
||||
return NeoLangProgramNode.emptyNode()
|
||||
}
|
||||
|
||||
this.tokens.clear()
|
||||
this.tokens.addAll(tokens)
|
||||
currentPosition = 0
|
||||
currentToken = tokens[currentPosition]
|
||||
return program()
|
||||
}
|
||||
|
||||
private fun match(tokenType: NeoLangTokenType, errorThrow: Boolean = false): Boolean {
|
||||
val currentToken = this.currentToken ?: throw InvalidTokenException("Unexpected token: null")
|
||||
|
||||
if (currentToken.tokenType === tokenType) {
|
||||
currentPosition++
|
||||
if (currentPosition >= tokens.size) {
|
||||
this.currentToken = NeoLangToken(NeoLangTokenType.EOF, NeoLangTokenValue.EOF)
|
||||
} else {
|
||||
this.currentToken = tokens[currentPosition]
|
||||
}
|
||||
return true
|
||||
|
||||
} else if (errorThrow) {
|
||||
throw InvalidTokenException(
|
||||
"Unexpected token `${currentToken.tokenValue}' typed " +
|
||||
"`${currentToken.tokenType}' near line ${currentToken.lineNumber}, " +
|
||||
"expected $tokenType",
|
||||
)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun program(): NeoLangProgramNode {
|
||||
val token = currentToken
|
||||
|
||||
var group = group()
|
||||
if (group != null) {
|
||||
val groups = mutableListOf(group)
|
||||
while (token?.tokenType !== NeoLangTokenType.EOF) {
|
||||
group = group()
|
||||
if (group == null) {
|
||||
break
|
||||
}
|
||||
groups.add(group)
|
||||
}
|
||||
return NeoLangProgramNode(groups)
|
||||
}
|
||||
|
||||
return NeoLangProgramNode.emptyNode()
|
||||
}
|
||||
|
||||
/**
|
||||
* @param attrName Only available when group is a attribute value
|
||||
*/
|
||||
private fun group(): NeoLangGroupNode? {
|
||||
val token = currentToken ?: throw InvalidTokenException("Unexpected token: null")
|
||||
|
||||
var attr = attribute()
|
||||
if (attr != null) {
|
||||
val attributes = mutableListOf(attr)
|
||||
|
||||
while (token.tokenType !== NeoLangTokenType.EOF
|
||||
&& token.tokenType !== NeoLangTokenType.BRACKET_END
|
||||
&& token.tokenType !== NeoLangTokenType.ARRAY_END
|
||||
) {
|
||||
attr = attribute()
|
||||
if (attr == null) {
|
||||
break
|
||||
}
|
||||
attributes.add(attr)
|
||||
}
|
||||
return NeoLangGroupNode(attributes.toTypedArray())
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun attribute(): NeoLangAttributeNode? {
|
||||
val token = currentToken ?: throw InvalidTokenException("Unexpected token: null")
|
||||
if (match(NeoLangTokenType.ID)) {
|
||||
match(NeoLangTokenType.COLON, errorThrow = true)
|
||||
|
||||
val attrName = NeoLangStringNode(token)
|
||||
|
||||
val block = block(attrName) ?: NeoLangBlockNode.emptyNode()
|
||||
return NeoLangAttributeNode(attrName, block)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun array(arrayName: NeoLangStringNode): NeoLangArrayNode? {
|
||||
val token = currentToken ?: throw InvalidTokenException("Unexpected token: null")
|
||||
|
||||
// TODO: Multiple Array
|
||||
var block = blockNonArrayElement(arrayName)
|
||||
var index = 0
|
||||
|
||||
if (block != null) {
|
||||
val elements = mutableListOf(NeoLangArrayNode.Companion.ArrayElement(index++, block))
|
||||
|
||||
if (match(NeoLangTokenType.COMMA)) {
|
||||
// More than one elements
|
||||
while (token.tokenType !== NeoLangTokenType.EOF
|
||||
&& token.tokenType !== NeoLangTokenType.ARRAY_END
|
||||
) {
|
||||
block = blockNonArrayElement(arrayName)
|
||||
if (block == null) {
|
||||
break
|
||||
}
|
||||
elements.add(NeoLangArrayNode.Companion.ArrayElement(index++, block))
|
||||
|
||||
// Meet the last element
|
||||
if (!match(NeoLangTokenType.COMMA)) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NeoLangArrayNode(arrayName, elements.toTypedArray())
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param attrName The block holder's name
|
||||
*/
|
||||
private fun block(attrName: NeoLangStringNode): NeoLangBlockNode? {
|
||||
val block = blockNonArrayElement(attrName)
|
||||
if (block != null) {
|
||||
return block
|
||||
}
|
||||
|
||||
val token = currentToken ?: throw InvalidTokenException("Unexpected token: null")
|
||||
when (token.tokenType) {
|
||||
NeoLangTokenType.ARRAY_START -> {
|
||||
match(NeoLangTokenType.ARRAY_START, errorThrow = true)
|
||||
val array = array(attrName)
|
||||
match(NeoLangTokenType.ARRAY_END, errorThrow = true)
|
||||
|
||||
// Allow empty arrays
|
||||
return if (array != null) NeoLangBlockNode(array) else NeoLangBlockNode.emptyNode()
|
||||
}
|
||||
|
||||
else -> throw InvalidTokenException("Unexpected token `${token.tokenValue}' typed `${token.tokenType}' for block")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param attrName Only available when group is a attribute value
|
||||
*/
|
||||
private fun blockNonArrayElement(attrName: NeoLangStringNode?): NeoLangBlockNode? {
|
||||
val token = currentToken ?: throw InvalidTokenException("Unexpected token: null")
|
||||
|
||||
return when (token.tokenType) {
|
||||
NeoLangTokenType.NUMBER -> {
|
||||
match(NeoLangTokenType.NUMBER, errorThrow = true)
|
||||
return NeoLangBlockNode(NeoLangNumberNode(token))
|
||||
}
|
||||
NeoLangTokenType.ID -> {
|
||||
match(NeoLangTokenType.ID, errorThrow = true)
|
||||
return NeoLangBlockNode(NeoLangStringNode(token))
|
||||
}
|
||||
NeoLangTokenType.STRING -> {
|
||||
match(NeoLangTokenType.STRING, errorThrow = true)
|
||||
return NeoLangBlockNode(NeoLangStringNode(token))
|
||||
}
|
||||
NeoLangTokenType.BRACKET_START -> {
|
||||
match(NeoLangTokenType.BRACKET_START, errorThrow = true)
|
||||
val group = group()
|
||||
match(NeoLangTokenType.BRACKET_END, errorThrow = true)
|
||||
|
||||
// Allow empty blocks
|
||||
return if (group != null) NeoLangBlockNode(group) else NeoLangBlockNode.emptyNode()
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open class InvalidTokenException(message: String) : ParseException(message)
|
||||
open class ParseException(message: String) : RuntimeException(message)
|
114
NeoLang/src/main/java/io/neolang/frontend/nodes.kt
Normal file
114
NeoLang/src/main/java/io/neolang/frontend/nodes.kt
Normal file
@ -0,0 +1,114 @@
|
||||
package io.neolang.frontend
|
||||
|
||||
import io.neolang.runtime.NeoLangValue
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
open class NeoLangAst {
|
||||
fun visit(): VisitorFactory {
|
||||
return VisitorFactory(this)
|
||||
}
|
||||
}
|
||||
|
||||
open class NeoLangBaseNode : NeoLangAst()
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangArrayNode(val arrayNameNode: NeoLangStringNode, val elements: Array<ArrayElement>) : NeoLangBaseNode() {
|
||||
companion object {
|
||||
class ArrayElement(val index: Int, val block: NeoLangBlockNode)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
open class NeoLangAstBasedNode(val ast: NeoLangBaseNode) : NeoLangBaseNode() {
|
||||
override fun toString(): String {
|
||||
return "${javaClass.simpleName} { ast: $ast }"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangAttributeNode(val stringNode: NeoLangStringNode, val blockNode: NeoLangBlockNode) : NeoLangBaseNode() {
|
||||
|
||||
override fun toString(): String {
|
||||
return "NeoLangAttributeNode { stringNode: $stringNode, block: $blockNode }"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangBlockNode(blockElement: NeoLangBaseNode) : NeoLangAstBasedNode(blockElement) {
|
||||
companion object {
|
||||
fun emptyNode(): NeoLangBlockNode {
|
||||
return NeoLangBlockNode(NeoLangDummyNode())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangDummyNode : NeoLangBaseNode()
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangGroupNode(val attributes: Array<NeoLangAttributeNode>) : NeoLangBaseNode() {
|
||||
|
||||
override fun toString(): String {
|
||||
return "NeoLangGroupNode { attrs: $attributes }"
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun emptyNode(): NeoLangGroupNode {
|
||||
return NeoLangGroupNode(arrayOf())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangNumberNode(token: NeoLangToken) : NeoLangTokenBasedNode(token)
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
|
||||
class NeoLangProgramNode(val groups: List<NeoLangGroupNode>) : NeoLangBaseNode() {
|
||||
|
||||
override fun toString(): String {
|
||||
return "NeoLangProgramNode { groups: $groups }"
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun emptyNode(): NeoLangProgramNode {
|
||||
return NeoLangProgramNode(listOf())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangStringNode(token: NeoLangToken) : NeoLangTokenBasedNode(token)
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
open class NeoLangTokenBasedNode(val token: NeoLangToken) : NeoLangBaseNode() {
|
||||
override fun toString(): String {
|
||||
return "${javaClass.simpleName} { token: $token }"
|
||||
}
|
||||
|
||||
fun eval(): NeoLangValue {
|
||||
return token.tokenValue.value
|
||||
}
|
||||
}
|
@ -1,6 +1,41 @@
|
||||
package io.neolang.ast
|
||||
package io.neolang.frontend
|
||||
|
||||
import io.neolang.runtime.type.NeoLangValue
|
||||
import io.neolang.runtime.NeoLangValue
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangEOFToken : NeoLangToken(NeoLangTokenType.EOF, NeoLangTokenValue.EOF)
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
|
||||
open class NeoLangToken(val tokenType: NeoLangTokenType, val tokenValue: NeoLangTokenValue) {
|
||||
var lineNumber = 0
|
||||
|
||||
override fun toString(): String {
|
||||
return "Token { tokenType: $tokenType, tokenValue: $tokenValue };"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
|
||||
enum class NeoLangTokenType {
|
||||
NUMBER,
|
||||
ID,
|
||||
STRING,
|
||||
BRACKET_START,
|
||||
BRACKET_END,
|
||||
ARRAY_START,
|
||||
ARRAY_END,
|
||||
COLON,
|
||||
COMMA,
|
||||
EOL,
|
||||
EOF,
|
||||
}
|
||||
|
||||
/**
|
||||
* @author kiva
|
@ -1,9 +1,9 @@
|
||||
package io.neolang.visitor
|
||||
package io.neolang.frontend
|
||||
|
||||
import io.neolang.ast.visitor.IVisitorCallback
|
||||
import io.neolang.runtime.context.NeoLangContext
|
||||
import io.neolang.runtime.type.NeoLangArray
|
||||
import io.neolang.runtime.type.NeoLangValue
|
||||
import io.neolang.runtime.NeoLangArray
|
||||
import io.neolang.runtime.NeoLangContext
|
||||
import io.neolang.runtime.NeoLangValue
|
||||
import java.util.*
|
||||
|
||||
class ConfigVisitor : IVisitorCallback {
|
||||
private var rootContext: NeoLangContext? = null
|
||||
@ -71,3 +71,40 @@ class ConfigVisitor : IVisitorCallback {
|
||||
return currentContext!!
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class DisplayProcessVisitor : IVisitorCallbackAdapter() {
|
||||
private val contextStack = Stack<NeoLangContext>()
|
||||
|
||||
override fun onStart() {
|
||||
println(">>> Start")
|
||||
onEnterContext("global")
|
||||
}
|
||||
|
||||
override fun onFinish() {
|
||||
while (contextStack.isNotEmpty()) {
|
||||
onExitContext()
|
||||
}
|
||||
println(">>> Finish")
|
||||
}
|
||||
|
||||
override fun onEnterContext(contextName: String) {
|
||||
val context = NeoLangContext(contextName)
|
||||
contextStack.push(context)
|
||||
println(">>> Entering Context `$contextName'")
|
||||
}
|
||||
|
||||
override fun onExitContext() {
|
||||
val context = contextStack.pop()
|
||||
println(">>> Exiting & Dumping Context ${context.contextName}")
|
||||
context.getAttributes().entries.forEach {
|
||||
println(" > [${it.key}]: ${it.value.asString()}")
|
||||
}
|
||||
}
|
||||
|
||||
override fun getCurrentContext(): NeoLangContext {
|
||||
return contextStack.peek()
|
||||
}
|
||||
}
|
@ -1,40 +0,0 @@
|
||||
package io.neolang.main
|
||||
|
||||
import io.neolang.parser.NeoLangParser
|
||||
import io.neolang.visitor.DisplayProcessVisitor
|
||||
import java.io.FileInputStream
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class Main {
|
||||
companion object {
|
||||
@JvmStatic
|
||||
fun main(args: Array<String>) {
|
||||
if (args.isEmpty()) {
|
||||
println("Usage: NeoLang <program.nl>")
|
||||
return
|
||||
}
|
||||
|
||||
val parser = NeoLangParser()
|
||||
args.forEach {
|
||||
val programCode = readFully(it)
|
||||
parser.setInputSource(programCode)
|
||||
val ast = parser.parse()
|
||||
println("Compile `$it'")
|
||||
ast.visit()
|
||||
.getVisitor(DisplayProcessVisitor::class.java)
|
||||
?.start()
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
private fun readFully(file: String): String {
|
||||
FileInputStream(file).use {
|
||||
val bytes = ByteArray(it.available())
|
||||
it.read(bytes)
|
||||
return String(bytes)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
package io.neolang.parser
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
open class InvalidTokenException(message: String) : ParseException(message)
|
@ -1,209 +0,0 @@
|
||||
package io.neolang.parser
|
||||
|
||||
import io.neolang.ast.NeoLangToken
|
||||
import io.neolang.ast.NeoLangTokenType
|
||||
import io.neolang.ast.NeoLangTokenValue
|
||||
import io.neolang.ast.base.NeoLangAst
|
||||
import io.neolang.ast.node.*
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangParser {
|
||||
private val lexer = NeoLangLexer()
|
||||
private var tokens = mutableListOf<NeoLangToken>()
|
||||
private var currentPosition: Int = 0
|
||||
private var currentToken: NeoLangToken? = null
|
||||
|
||||
fun setInputSource(programCode: String?) {
|
||||
lexer.setInputSource(programCode)
|
||||
}
|
||||
|
||||
fun parse(): NeoLangAst {
|
||||
return updateParserStatus(lexer.lex()) ?: throw ParseException("AST is null")
|
||||
}
|
||||
|
||||
private fun updateParserStatus(tokens: List<NeoLangToken>): NeoLangAst? {
|
||||
if (tokens.isEmpty()) {
|
||||
// Allow empty program
|
||||
return NeoLangProgramNode.emptyNode()
|
||||
}
|
||||
|
||||
this.tokens.clear()
|
||||
this.tokens.addAll(tokens)
|
||||
currentPosition = 0
|
||||
currentToken = tokens[currentPosition]
|
||||
return program()
|
||||
}
|
||||
|
||||
private fun match(tokenType: NeoLangTokenType, errorThrow: Boolean = false): Boolean {
|
||||
val currentToken = this.currentToken ?: throw InvalidTokenException("Unexpected token: null")
|
||||
|
||||
if (currentToken.tokenType === tokenType) {
|
||||
currentPosition++
|
||||
if (currentPosition >= tokens.size) {
|
||||
this.currentToken = NeoLangToken(NeoLangTokenType.EOF, NeoLangTokenValue.EOF)
|
||||
} else {
|
||||
this.currentToken = tokens[currentPosition]
|
||||
}
|
||||
return true
|
||||
|
||||
} else if (errorThrow) {
|
||||
throw InvalidTokenException(
|
||||
"Unexpected token `${currentToken.tokenValue}' typed " +
|
||||
"`${currentToken.tokenType}' near line ${currentToken.lineNumber}, " +
|
||||
"expected $tokenType"
|
||||
)
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
private fun program(): NeoLangProgramNode {
|
||||
val token = currentToken
|
||||
|
||||
var group = group()
|
||||
if (group != null) {
|
||||
val groups = mutableListOf(group)
|
||||
while (token?.tokenType !== NeoLangTokenType.EOF) {
|
||||
group = group()
|
||||
if (group == null) {
|
||||
break
|
||||
}
|
||||
groups.add(group)
|
||||
}
|
||||
return NeoLangProgramNode(groups)
|
||||
}
|
||||
|
||||
return NeoLangProgramNode.emptyNode()
|
||||
}
|
||||
|
||||
/**
|
||||
* @param attrName Only available when group is a attribute value
|
||||
*/
|
||||
private fun group(): NeoLangGroupNode? {
|
||||
val token = currentToken ?: throw InvalidTokenException("Unexpected token: null")
|
||||
|
||||
var attr = attribute()
|
||||
if (attr != null) {
|
||||
val attributes = mutableListOf(attr)
|
||||
|
||||
while (token.tokenType !== NeoLangTokenType.EOF
|
||||
&& token.tokenType !== NeoLangTokenType.BRACKET_END
|
||||
&& token.tokenType !== NeoLangTokenType.ARRAY_END
|
||||
) {
|
||||
attr = attribute()
|
||||
if (attr == null) {
|
||||
break
|
||||
}
|
||||
attributes.add(attr)
|
||||
}
|
||||
return NeoLangGroupNode(attributes.toTypedArray())
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
private fun attribute(): NeoLangAttributeNode? {
|
||||
val token = currentToken ?: throw InvalidTokenException("Unexpected token: null")
|
||||
if (match(NeoLangTokenType.ID)) {
|
||||
match(NeoLangTokenType.COLON, errorThrow = true)
|
||||
|
||||
val attrName = NeoLangStringNode(token)
|
||||
|
||||
val block = block(attrName) ?: NeoLangBlockNode.emptyNode()
|
||||
return NeoLangAttributeNode(attrName, block)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
private fun array(arrayName: NeoLangStringNode): NeoLangArrayNode? {
|
||||
val token = currentToken ?: throw InvalidTokenException("Unexpected token: null")
|
||||
|
||||
// TODO: Multiple Array
|
||||
var block = blockNonArrayElement(arrayName)
|
||||
var index = 0
|
||||
|
||||
if (block != null) {
|
||||
val elements = mutableListOf(NeoLangArrayNode.Companion.ArrayElement(index++, block))
|
||||
|
||||
if (match(NeoLangTokenType.COMMA)) {
|
||||
// More than one elements
|
||||
while (token.tokenType !== NeoLangTokenType.EOF
|
||||
&& token.tokenType !== NeoLangTokenType.ARRAY_END
|
||||
) {
|
||||
block = blockNonArrayElement(arrayName)
|
||||
if (block == null) {
|
||||
break
|
||||
}
|
||||
elements.add(NeoLangArrayNode.Companion.ArrayElement(index++, block))
|
||||
|
||||
// Meet the last element
|
||||
if (!match(NeoLangTokenType.COMMA)) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NeoLangArrayNode(arrayName, elements.toTypedArray())
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param attrName The block holder's name
|
||||
*/
|
||||
private fun block(attrName: NeoLangStringNode): NeoLangBlockNode? {
|
||||
val block = blockNonArrayElement(attrName)
|
||||
if (block != null) {
|
||||
return block
|
||||
}
|
||||
|
||||
val token = currentToken ?: throw InvalidTokenException("Unexpected token: null")
|
||||
when (token.tokenType) {
|
||||
NeoLangTokenType.ARRAY_START -> {
|
||||
match(NeoLangTokenType.ARRAY_START, errorThrow = true)
|
||||
val array = array(attrName)
|
||||
match(NeoLangTokenType.ARRAY_END, errorThrow = true)
|
||||
|
||||
// Allow empty arrays
|
||||
return if (array != null) NeoLangBlockNode(array) else NeoLangBlockNode.emptyNode()
|
||||
}
|
||||
|
||||
else -> throw InvalidTokenException("Unexpected token `${token.tokenValue}' typed `${token.tokenType}' for block")
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param attrName Only available when group is a attribute value
|
||||
*/
|
||||
private fun blockNonArrayElement(attrName: NeoLangStringNode?): NeoLangBlockNode? {
|
||||
val token = currentToken ?: throw InvalidTokenException("Unexpected token: null")
|
||||
|
||||
return when (token.tokenType) {
|
||||
NeoLangTokenType.NUMBER -> {
|
||||
match(NeoLangTokenType.NUMBER, errorThrow = true)
|
||||
return NeoLangBlockNode(NeoLangNumberNode(token))
|
||||
}
|
||||
NeoLangTokenType.ID -> {
|
||||
match(NeoLangTokenType.ID, errorThrow = true)
|
||||
return NeoLangBlockNode(NeoLangStringNode(token))
|
||||
}
|
||||
NeoLangTokenType.STRING -> {
|
||||
match(NeoLangTokenType.STRING, errorThrow = true)
|
||||
return NeoLangBlockNode(NeoLangStringNode(token))
|
||||
}
|
||||
NeoLangTokenType.BRACKET_START -> {
|
||||
match(NeoLangTokenType.BRACKET_START, errorThrow = true)
|
||||
val group = group()
|
||||
match(NeoLangTokenType.BRACKET_END, errorThrow = true)
|
||||
|
||||
// Allow empty blocks
|
||||
return if (group != null) NeoLangBlockNode(group) else NeoLangBlockNode.emptyNode()
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
package io.neolang.parser
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
open class ParseException(message: String) : RuntimeException(message)
|
@ -1,6 +1,4 @@
|
||||
package io.neolang.runtime.context
|
||||
|
||||
import io.neolang.runtime.type.NeoLangValue
|
||||
package io.neolang.runtime
|
||||
|
||||
/**
|
||||
* @author kiva
|
@ -1,18 +0,0 @@
|
||||
package io.neolang.runtime.type
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
open class NeoLangArrayElement {
|
||||
open fun eval(): NeoLangValue {
|
||||
return NeoLangValue.UNDEFINED
|
||||
}
|
||||
|
||||
open fun eval(key: String): NeoLangValue {
|
||||
return NeoLangValue.UNDEFINED
|
||||
}
|
||||
|
||||
open fun isBlock(): Boolean {
|
||||
return false
|
||||
}
|
||||
}
|
@ -1,30 +0,0 @@
|
||||
package io.neolang.runtime.type
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangValue(private val rawValue: Any) {
|
||||
fun asString(): String {
|
||||
return rawValue.toString()
|
||||
}
|
||||
|
||||
fun asNumber(): Double {
|
||||
if (rawValue is Array<*>) {
|
||||
return 0.0
|
||||
}
|
||||
|
||||
try {
|
||||
return rawValue.toString().toDouble()
|
||||
} catch (e: Throwable) {
|
||||
return 0.0
|
||||
}
|
||||
}
|
||||
|
||||
fun isValid(): Boolean {
|
||||
return this != UNDEFINED
|
||||
}
|
||||
|
||||
companion object {
|
||||
val UNDEFINED = NeoLangValue("<undefined>")
|
||||
}
|
||||
}
|
@ -1,6 +1,4 @@
|
||||
package io.neolang.runtime.type
|
||||
|
||||
import io.neolang.runtime.context.NeoLangContext
|
||||
package io.neolang.runtime
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
@ -60,3 +58,49 @@ class NeoLangArray private constructor(
|
||||
return elements.iterator()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
open class NeoLangArrayElement {
|
||||
open fun eval(): NeoLangValue {
|
||||
return NeoLangValue.UNDEFINED
|
||||
}
|
||||
|
||||
open fun eval(key: String): NeoLangValue {
|
||||
return NeoLangValue.UNDEFINED
|
||||
}
|
||||
|
||||
open fun isBlock(): Boolean {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangValue(private val rawValue: Any) {
|
||||
fun asString(): String {
|
||||
return rawValue.toString()
|
||||
}
|
||||
|
||||
fun asNumber(): Double {
|
||||
if (rawValue is Array<*>) {
|
||||
return 0.0
|
||||
}
|
||||
|
||||
try {
|
||||
return rawValue.toString().toDouble()
|
||||
} catch (e: Throwable) {
|
||||
return 0.0
|
||||
}
|
||||
}
|
||||
|
||||
fun isValid(): Boolean {
|
||||
return this != UNDEFINED
|
||||
}
|
||||
|
||||
companion object {
|
||||
val UNDEFINED = NeoLangValue("<undefined>")
|
||||
}
|
||||
}
|
@ -1,42 +0,0 @@
|
||||
package io.neolang.visitor
|
||||
|
||||
import io.neolang.ast.visitor.IVisitorCallbackAdapter
|
||||
import io.neolang.runtime.context.NeoLangContext
|
||||
import java.util.*
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class DisplayProcessVisitor : IVisitorCallbackAdapter() {
|
||||
private val contextStack = Stack<NeoLangContext>()
|
||||
|
||||
override fun onStart() {
|
||||
println(">>> Start")
|
||||
onEnterContext("global")
|
||||
}
|
||||
|
||||
override fun onFinish() {
|
||||
while (contextStack.isNotEmpty()) {
|
||||
onExitContext()
|
||||
}
|
||||
println(">>> Finish")
|
||||
}
|
||||
|
||||
override fun onEnterContext(contextName: String) {
|
||||
val context = NeoLangContext(contextName)
|
||||
contextStack.push(context)
|
||||
println(">>> Entering Context `$contextName'")
|
||||
}
|
||||
|
||||
override fun onExitContext() {
|
||||
val context = contextStack.pop()
|
||||
println(">>> Exiting & Dumping Context ${context.contextName}")
|
||||
context.getAttributes().entries.forEach {
|
||||
println(" > [${it.key}]: ${it.value.asString()}")
|
||||
}
|
||||
}
|
||||
|
||||
override fun getCurrentContext(): NeoLangContext {
|
||||
return contextStack.peek()
|
||||
}
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
package io.neolang
|
||||
|
||||
import io.neolang.main.Main
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* @see [Testing documentation](http://d.android.com/tools/testing)
|
||||
*/
|
||||
class NeoLangTest {
|
||||
@Test
|
||||
fun arrayTest() {
|
||||
Main.main(arrayOf("NeoLang/example/extra-key.nl"))
|
||||
}
|
||||
}
|
||||
|
@ -1,41 +0,0 @@
|
||||
package io.neoterm.component
|
||||
|
||||
import android.content.Context
|
||||
import io.neoterm.component.codegen.CodeGenComponent
|
||||
import io.neoterm.component.colorscheme.ColorSchemeComponent
|
||||
import io.neoterm.component.completion.CompletionComponent
|
||||
import io.neoterm.component.config.ConfigureComponent
|
||||
import io.neoterm.component.extrakey.ExtraKeyComponent
|
||||
import io.neoterm.component.font.FontComponent
|
||||
import io.neoterm.component.pm.PackageComponent
|
||||
import io.neoterm.component.profile.ProfileComponent
|
||||
import io.neoterm.component.session.SessionComponent
|
||||
import io.neoterm.component.session.ShellProfile
|
||||
import io.neoterm.component.userscript.UserScriptComponent
|
||||
import io.neoterm.utils.NLog
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
object NeoInitializer {
|
||||
fun init(context: Context) {
|
||||
NLog.init(context)
|
||||
initComponents()
|
||||
}
|
||||
|
||||
fun initComponents() {
|
||||
ComponentManager.registerComponent(ConfigureComponent::class.java)
|
||||
ComponentManager.registerComponent(CodeGenComponent::class.java)
|
||||
ComponentManager.registerComponent(ColorSchemeComponent::class.java)
|
||||
ComponentManager.registerComponent(FontComponent::class.java)
|
||||
ComponentManager.registerComponent(UserScriptComponent::class.java)
|
||||
ComponentManager.registerComponent(ExtraKeyComponent::class.java)
|
||||
ComponentManager.registerComponent(CompletionComponent::class.java)
|
||||
ComponentManager.registerComponent(PackageComponent::class.java)
|
||||
ComponentManager.registerComponent(SessionComponent::class.java)
|
||||
ComponentManager.registerComponent(ProfileComponent::class.java)
|
||||
|
||||
val profileComp = ComponentManager.getComponent<ProfileComponent>()
|
||||
profileComp.registerProfile(ShellProfile.PROFILE_META_NAME, ShellProfile::class.java)
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package io.neoterm.component.colorscheme
|
||||
|
||||
import android.content.Context
|
||||
import io.neolang.visitor.ConfigVisitor
|
||||
import io.neolang.frontend.ConfigVisitor
|
||||
import io.neoterm.App
|
||||
import io.neoterm.R
|
||||
import io.neoterm.component.ComponentManager
|
||||
|
@ -1,6 +1,6 @@
|
||||
package io.neoterm.component.colorscheme
|
||||
|
||||
import io.neolang.visitor.ConfigVisitor
|
||||
import io.neolang.frontend.ConfigVisitor
|
||||
import io.neoterm.backend.TerminalColorScheme
|
||||
import io.neoterm.backend.TerminalColors
|
||||
import io.neoterm.component.ConfigFileBasedObject
|
||||
|
@ -1,5 +1,18 @@
|
||||
package io.neoterm.component
|
||||
|
||||
import android.content.Context
|
||||
import io.neoterm.component.codegen.CodeGenComponent
|
||||
import io.neoterm.component.colorscheme.ColorSchemeComponent
|
||||
import io.neoterm.component.completion.CompletionComponent
|
||||
import io.neoterm.component.config.ConfigureComponent
|
||||
import io.neoterm.component.extrakey.ExtraKeyComponent
|
||||
import io.neoterm.component.font.FontComponent
|
||||
import io.neoterm.component.pm.PackageComponent
|
||||
import io.neoterm.component.profile.ProfileComponent
|
||||
import io.neoterm.component.session.SessionComponent
|
||||
import io.neoterm.component.session.ShellProfile
|
||||
import io.neoterm.component.userscript.UserScriptComponent
|
||||
import io.neoterm.utils.NLog
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
interface NeoComponent {
|
||||
@ -50,3 +63,28 @@ object ComponentManager {
|
||||
class ComponentDuplicateException(serviceName: String) : RuntimeException("Service $serviceName duplicate")
|
||||
class ComponentNotFoundException(serviceName: String) : RuntimeException("Component `$serviceName' not found")
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
object NeoInitializer {
|
||||
fun init(context: Context) {
|
||||
NLog.init(context)
|
||||
initComponents()
|
||||
}
|
||||
|
||||
fun initComponents() {
|
||||
ComponentManager.registerComponent(ConfigureComponent::class.java)
|
||||
ComponentManager.registerComponent(CodeGenComponent::class.java)
|
||||
ComponentManager.registerComponent(ColorSchemeComponent::class.java)
|
||||
ComponentManager.registerComponent(FontComponent::class.java)
|
||||
ComponentManager.registerComponent(UserScriptComponent::class.java)
|
||||
ComponentManager.registerComponent(ExtraKeyComponent::class.java)
|
||||
ComponentManager.registerComponent(CompletionComponent::class.java)
|
||||
ComponentManager.registerComponent(PackageComponent::class.java)
|
||||
ComponentManager.registerComponent(SessionComponent::class.java)
|
||||
ComponentManager.registerComponent(ProfileComponent::class.java)
|
||||
|
||||
val profileComp = ComponentManager.getComponent<ProfileComponent>()
|
||||
profileComp.registerProfile(ShellProfile.PROFILE_META_NAME, ShellProfile::class.java)
|
||||
}
|
||||
}
|
||||
|
@ -6,8 +6,8 @@ import android.preference.PreferenceManager
|
||||
import android.system.ErrnoException
|
||||
import android.system.Os
|
||||
import android.util.TypedValue
|
||||
import io.neolang.parser.NeoLangParser
|
||||
import io.neolang.visitor.ConfigVisitor
|
||||
import io.neolang.frontend.ConfigVisitor
|
||||
import io.neolang.frontend.NeoLangParser
|
||||
import io.neoterm.App
|
||||
import io.neoterm.R
|
||||
import io.neoterm.backend.TerminalSession
|
||||
|
@ -1,7 +1,7 @@
|
||||
package io.neoterm.component.config
|
||||
|
||||
import io.neolang.runtime.type.NeoLangValue
|
||||
import io.neolang.visitor.ConfigVisitor
|
||||
import io.neolang.frontend.ConfigVisitor
|
||||
import io.neolang.runtime.NeoLangValue
|
||||
import io.neoterm.component.colorscheme.NeoColorScheme
|
||||
import io.neoterm.component.extrakey.NeoExtraKey
|
||||
import io.neoterm.frontend.session.view.extrakey.TextButton
|
||||
|
@ -1,6 +1,6 @@
|
||||
package io.neoterm.component
|
||||
|
||||
import io.neolang.visitor.ConfigVisitor
|
||||
import io.neolang.frontend.ConfigVisitor
|
||||
import io.neoterm.component.config.ConfigureComponent
|
||||
import io.neoterm.utils.NLog
|
||||
import java.io.File
|
||||
|
@ -1,7 +1,7 @@
|
||||
package io.neoterm.component.extrakey
|
||||
|
||||
import android.content.Context
|
||||
import io.neolang.visitor.ConfigVisitor
|
||||
import io.neolang.frontend.ConfigVisitor
|
||||
import io.neoterm.App
|
||||
import io.neoterm.component.ConfigFileBasedComponent
|
||||
import io.neoterm.component.config.NeoTermPath
|
||||
|
@ -1,6 +1,6 @@
|
||||
package io.neoterm.component.extrakey
|
||||
|
||||
import io.neolang.visitor.ConfigVisitor
|
||||
import io.neolang.frontend.ConfigVisitor
|
||||
import io.neoterm.component.ConfigFileBasedObject
|
||||
import io.neoterm.frontend.session.view.extrakey.ExtraKeysView
|
||||
import io.neoterm.frontend.session.view.extrakey.IExtraButton
|
||||
|
@ -1,6 +1,6 @@
|
||||
package io.neoterm.component.profile
|
||||
|
||||
import io.neolang.visitor.ConfigVisitor
|
||||
import io.neolang.frontend.ConfigVisitor
|
||||
import io.neoterm.component.ConfigFileBasedComponent
|
||||
import io.neoterm.component.config.NeoTermPath
|
||||
import io.neoterm.utils.NLog
|
||||
|
@ -1,6 +1,6 @@
|
||||
package io.neoterm.component.profile
|
||||
|
||||
import io.neolang.visitor.ConfigVisitor
|
||||
import io.neolang.frontend.ConfigVisitor
|
||||
import io.neoterm.component.ComponentManager
|
||||
import io.neoterm.component.ConfigFileBasedObject
|
||||
import io.neoterm.component.codegen.CodeGenObject
|
||||
|
@ -1,7 +1,7 @@
|
||||
package io.neoterm.component.session
|
||||
|
||||
import android.content.Context
|
||||
import io.neolang.visitor.ConfigVisitor
|
||||
import io.neolang.frontend.ConfigVisitor
|
||||
import io.neoterm.App
|
||||
import io.neoterm.R
|
||||
import io.neoterm.backend.TerminalSession
|
||||
|
Loading…
Reference in New Issue
Block a user