Improve: NeoLang Array supports collection operations
This commit is contained in:
parent
5ae36672af
commit
1e50bbbafa
@ -1,6 +1,7 @@
|
||||
extra-key: {
|
||||
program: [ "vim", "vi" ]
|
||||
key: [
|
||||
"hello",
|
||||
{
|
||||
display: "Ctrl"
|
||||
code: "<CTRL>"
|
||||
|
@ -1,9 +1,12 @@
|
||||
package io.neolang.ast.node
|
||||
|
||||
import io.neolang.ast.base.NeoLangBaseNode
|
||||
import io.neolang.runtime.type.NeoLangArrayElement
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangArrayNode(val arrayNameNode: NeoLangStringNode, val elements: Array<NeoLangArrayElement>) : NeoLangBaseNode()
|
||||
class NeoLangArrayNode(val arrayNameNode: NeoLangStringNode, val elements: Array<ArrayElement>) : NeoLangBaseNode() {
|
||||
companion object {
|
||||
class ArrayElement(val index: Int, val block: NeoLangBlockNode)
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package io.neolang.main
|
||||
|
||||
import io.neolang.parser.NeoLangParser
|
||||
import io.neolang.visitor.DisplayProcessVisitor
|
||||
import java.io.FileInputStream
|
||||
|
||||
/**
|
||||
|
@ -5,7 +5,6 @@ import io.neolang.ast.NeoLangTokenType
|
||||
import io.neolang.ast.NeoLangTokenValue
|
||||
import io.neolang.ast.base.NeoLangAst
|
||||
import io.neolang.ast.node.*
|
||||
import io.neolang.runtime.type.NeoLangArrayElement
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
@ -123,7 +122,7 @@ class NeoLangParser {
|
||||
var index = 0
|
||||
|
||||
if (block != null) {
|
||||
val elements = mutableListOf(NeoLangArrayElement(index++, block))
|
||||
val elements = mutableListOf(NeoLangArrayNode.Companion.ArrayElement(index++, block))
|
||||
|
||||
if (match(NeoLangTokenType.COMMA)) {
|
||||
// More than one elements
|
||||
@ -133,7 +132,7 @@ class NeoLangParser {
|
||||
if (block == null) {
|
||||
break
|
||||
}
|
||||
elements.add(NeoLangArrayElement(index++, block))
|
||||
elements.add(NeoLangArrayNode.Companion.ArrayElement(index++, block))
|
||||
|
||||
// Meet the last element
|
||||
if (!match(NeoLangTokenType.COMMA)) {
|
||||
|
@ -11,9 +11,8 @@ class NeoLangContext(val contextName: String) {
|
||||
}
|
||||
|
||||
private val attributes = mutableMapOf<String, NeoLangValue>()
|
||||
|
||||
val children = mutableListOf<NeoLangContext>()
|
||||
var parent: NeoLangContext? = null
|
||||
var children = mutableListOf<NeoLangContext>()
|
||||
|
||||
fun defineAttribute(attributeName: String, attributeValue: NeoLangValue): NeoLangContext {
|
||||
attributes[attributeName] = attributeValue
|
||||
|
@ -0,0 +1,59 @@
|
||||
package io.neolang.runtime.type
|
||||
|
||||
import io.neolang.runtime.context.NeoLangContext
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangArray private constructor(val elements: List<NeoLangArrayElement>, override val size: Int = elements.size) : Collection<NeoLangArrayElement> {
|
||||
companion object {
|
||||
internal class PrimaryElement(val primaryValue: NeoLangValue) : NeoLangArrayElement() {
|
||||
override fun eval(): NeoLangValue {
|
||||
return primaryValue
|
||||
}
|
||||
}
|
||||
|
||||
internal class BlockElement(val blockContext: NeoLangContext) : NeoLangArrayElement() {
|
||||
override fun eval(key: String): NeoLangValue {
|
||||
return blockContext.getAttribute(key)
|
||||
}
|
||||
|
||||
override fun isBlock(): Boolean {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
fun createFromContext(context: NeoLangContext): NeoLangArray {
|
||||
val elements = mutableListOf<NeoLangArrayElement>()
|
||||
context.getAttributes().entries.forEach {
|
||||
val index = it.key.toInt()
|
||||
elements.add(index, PrimaryElement(it.value))
|
||||
}
|
||||
context.children.forEach {
|
||||
val index = it.contextName.toInt()
|
||||
elements.add(index, BlockElement(it))
|
||||
}
|
||||
return NeoLangArray(elements)
|
||||
}
|
||||
}
|
||||
|
||||
operator fun get(index: Int): NeoLangArrayElement {
|
||||
return elements[index]
|
||||
}
|
||||
|
||||
override fun contains(element: NeoLangArrayElement): Boolean {
|
||||
return elements.contains(element)
|
||||
}
|
||||
|
||||
override fun containsAll(elements: Collection<NeoLangArrayElement>): Boolean {
|
||||
return this.elements.containsAll(elements)
|
||||
}
|
||||
|
||||
override fun isEmpty(): Boolean {
|
||||
return size == 0
|
||||
}
|
||||
|
||||
override fun iterator(): Iterator<NeoLangArrayElement> {
|
||||
return elements.iterator()
|
||||
}
|
||||
}
|
@ -1,8 +1,18 @@
|
||||
package io.neolang.runtime.type
|
||||
|
||||
import io.neolang.ast.node.NeoLangBlockNode
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangArrayElement(val index: Int, val block: NeoLangBlockNode)
|
||||
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,27 +1,10 @@
|
||||
package io.neolang.runtime.type
|
||||
|
||||
import io.neolang.ast.node.NeoLangBlockNode
|
||||
|
||||
/**
|
||||
* @author kiva
|
||||
*/
|
||||
class NeoLangValue(private val rawValue: Any) {
|
||||
fun asString(): String {
|
||||
if (rawValue is Array<*>) {
|
||||
val array = asArray()
|
||||
|
||||
return buildString {
|
||||
append("Array [ ")
|
||||
array.forEachIndexed { index, value ->
|
||||
append(value.asString())
|
||||
if (index != array.size - 1) {
|
||||
append(", ")
|
||||
}
|
||||
}
|
||||
append(" ]")
|
||||
}
|
||||
}
|
||||
|
||||
return rawValue.toString()
|
||||
}
|
||||
|
||||
@ -37,17 +20,6 @@ class NeoLangValue(private val rawValue: Any) {
|
||||
}
|
||||
}
|
||||
|
||||
fun asArray(): Array<NeoLangValue> {
|
||||
return castArrayOrNull(rawValue) ?: arrayOf()
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun castArrayOrNull(rawValue: Any): Array<NeoLangValue>? {
|
||||
return if (rawValue is Array<*> && rawValue.isNotEmpty() && rawValue[0] is NeoLangValue)
|
||||
rawValue as Array<NeoLangValue>
|
||||
else null
|
||||
}
|
||||
|
||||
fun isValid(): Boolean {
|
||||
return this != UNDEFINED
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
package io.neoterm.frontend.config
|
||||
package io.neolang.visitor
|
||||
|
||||
import io.neolang.ast.visitor.IVisitorCallback
|
||||
import io.neolang.runtime.context.NeoLangContext
|
||||
import io.neolang.runtime.type.NeoLangArray
|
||||
import io.neolang.runtime.type.NeoLangValue
|
||||
|
||||
class ConfigVisitor : IVisitorCallback {
|
||||
@ -19,6 +20,11 @@ class ConfigVisitor : IVisitorCallback {
|
||||
return getContext(contextPath).getAttribute(attrName)
|
||||
}
|
||||
|
||||
fun getArray(contextPath: Array<String>, arrayName: String) : NeoLangArray {
|
||||
// We use NeoLangContext as arrays and array elements now
|
||||
return NeoLangArray.createFromContext(getContext(contextPath).getChild(arrayName))
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
currentContext = NeoLangContext("global")
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package io.neolang.main
|
||||
package io.neolang.visitor
|
||||
|
||||
import io.neolang.ast.visitor.IVisitorCallbackAdapter
|
||||
import io.neolang.runtime.context.NeoLangContext
|
@ -3,7 +3,7 @@ package io.neoterm.customize.color
|
||||
import io.neoterm.backend.TerminalColorScheme
|
||||
import io.neoterm.backend.TerminalColors
|
||||
import io.neoterm.customize.config.ConfigureService
|
||||
import io.neoterm.frontend.config.ConfigVisitor
|
||||
import io.neolang.visitor.ConfigVisitor
|
||||
import io.neoterm.frontend.logging.NLog
|
||||
import io.neoterm.frontend.service.ServiceManager
|
||||
import io.neoterm.view.TerminalView
|
||||
|
@ -2,7 +2,7 @@ package io.neoterm.customize.config.loader
|
||||
|
||||
import io.neolang.runtime.type.NeoLangValue
|
||||
import io.neoterm.customize.color.NeoColorScheme
|
||||
import io.neoterm.frontend.config.ConfigVisitor
|
||||
import io.neolang.visitor.ConfigVisitor
|
||||
import io.neoterm.frontend.config.NeoConfigureFile
|
||||
import io.neoterm.frontend.logging.NLog
|
||||
import java.io.File
|
||||
|
@ -2,7 +2,7 @@ package io.neoterm.customize.config.loader
|
||||
|
||||
import io.neoterm.customize.eks.ExtraKeyConfigParser
|
||||
import io.neoterm.customize.eks.NeoExtraKey
|
||||
import io.neoterm.frontend.config.ConfigVisitor
|
||||
import io.neolang.visitor.ConfigVisitor
|
||||
import io.neoterm.frontend.config.NeoConfigureFile
|
||||
import io.neoterm.view.eks.button.TextButton
|
||||
import java.io.BufferedReader
|
||||
|
@ -1,6 +1,7 @@
|
||||
package io.neoterm.frontend.config
|
||||
|
||||
import io.neolang.parser.NeoLangParser
|
||||
import io.neolang.visitor.ConfigVisitor
|
||||
import io.neoterm.frontend.logging.NLog
|
||||
import io.neoterm.utils.FileUtils
|
||||
import java.io.File
|
||||
|
@ -2,7 +2,7 @@ package io.neoterm
|
||||
|
||||
import io.neoterm.customize.color.NeoColorScheme
|
||||
import io.neoterm.customize.config.ConfigureService
|
||||
import io.neoterm.frontend.config.ConfigVisitor
|
||||
import io.neolang.visitor.ConfigVisitor
|
||||
import io.neoterm.frontend.config.NeoConfigureFile
|
||||
import io.neoterm.frontend.service.ServiceManager
|
||||
import org.junit.Test
|
||||
@ -23,7 +23,11 @@ class ConfigureFileTest {
|
||||
|
||||
@Test
|
||||
fun colorConfigureTest() {
|
||||
ServiceManager.registerService(ConfigureService::class.java)
|
||||
try {
|
||||
ServiceManager.registerService(ConfigureService::class.java)
|
||||
} catch (ignore: Throwable) {
|
||||
}
|
||||
|
||||
val color = NeoColorScheme()
|
||||
if (color.loadConfigure(File("NeoLang/example/color-scheme.nl"))) {
|
||||
println("colorName: ${color.colorName}")
|
||||
@ -37,7 +41,22 @@ class ConfigureFileTest {
|
||||
|
||||
@Test
|
||||
fun extraKeyConfigureTest() {
|
||||
parseConfigure("NeoLang/example/extra-key.nl")
|
||||
val visitor = parseConfigure("NeoLang/example/extra-key.nl")
|
||||
if (visitor != null) {
|
||||
val programs = visitor.getArray(arrayOf("extra-key"), "program")
|
||||
programs.forEachIndexed { index, element ->
|
||||
println("program[$index]: ${element.eval().asString()}")
|
||||
}
|
||||
|
||||
val keys = visitor.getArray(arrayOf("extra-key"), "key")
|
||||
keys.forEachIndexed { index, element ->
|
||||
if (element.isBlock()) {
|
||||
println("key[$index]: " +
|
||||
"display: ${element.eval("display").asString()}, " +
|
||||
"code: ${element.eval("code").asString()}")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
|
Loading…
x
Reference in New Issue
Block a user