Skip to content

Commit c6a87ae

Browse files
committed
NBT路径
1 parent 139f193 commit c6a87ae

File tree

11 files changed

+414
-66
lines changed

11 files changed

+414
-66
lines changed

src/main/kotlin/top/mcfpp/lang/Indexable.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
package top.mcfpp.lang
22

3+
4+
/**
5+
* 表示一个类型可以通过索引访问其中的成员。
6+
*
7+
* @param T 通过索引访问所获得的类型
8+
*/
39
interface Indexable<out T : Var<*>> {
410

511
fun getByIndex(index: Var<*>): T

src/main/kotlin/top/mcfpp/lang/SelectorVar.kt

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -34,28 +34,6 @@ open class SelectorVar : NBTBasedData<StringTag> {
3434

3535
var text: String? = null
3636

37-
val limit: Int
38-
get() {
39-
return if(value.limit is MCIntConcrete){
40-
(value.limit as MCIntConcrete).value
41-
}else{
42-
Int.MAX_VALUE
43-
}
44-
}
45-
46-
val entityType: String
47-
get() {
48-
return if(value.type?.first is MCStringConcrete && value.type?.second is MCBoolConcrete){
49-
if((value.type!!.second as MCBoolConcrete).value){
50-
return (value.type!!.first as MCStringConcrete).value.valueToString()
51-
}else{
52-
return "!"+(value.type!!.first as MCStringConcrete).value.valueToString()
53-
}
54-
}else{
55-
"any"
56-
}
57-
}
58-
5937
/**
6038
* 创建一个目标选择器类型的变量。它的mc名和变量所在的域容器有关。
6139
*

src/main/kotlin/top/mcfpp/lang/Var.kt

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
package top.mcfpp.lang
22

3+
import net.querz.nbt.tag.StringTag
34
import net.querz.nbt.tag.Tag
45
import top.mcfpp.Project
56
import top.mcfpp.command.Command
67
import top.mcfpp.command.Commands
7-
import top.mcfpp.exception.OperationNotImplementException
88
import top.mcfpp.exception.VariableConverseException
9+
import top.mcfpp.lang.resource.StorageConcrete
910
import top.mcfpp.lang.type.*
1011
import top.mcfpp.lang.value.MCFPPValue
11-
import top.mcfpp.lib.NBTPath
12+
import top.mcfpp.lib.*
1213
import top.mcfpp.model.*
1314
import top.mcfpp.model.function.Function
1415
import top.mcfpp.util.LogProcessor
@@ -73,7 +74,7 @@ abstract class Var<T> : Member, Cloneable, CanSelectMember{
7374
*/
7475
var hasInit = false
7576

76-
var parent : CanSelectMember? = null
77+
open var parent : CanSelectMember? = null
7778

7879
/**
7980
* 访问修饰符
@@ -93,7 +94,7 @@ abstract class Var<T> : Member, Cloneable, CanSelectMember{
9394
/**
9495
*
9596
*/
96-
open var nbtPath = NBTPath(NBTPath.STORAGE, Storage.MCFPP_SYSTEM.toString())
97+
open var nbtPath = NBTPath(StorageSource(StorageConcrete("system")))
9798
.memberIndex(Project.currNamespace)
9899
.memberIndex("stack_frame[$stackIndex]")
99100

@@ -167,7 +168,7 @@ abstract class Var<T> : Member, Cloneable, CanSelectMember{
167168
//不是this指针才需要额外指定引用者
168169
`var`.parent = pointer
169170
}
170-
`var`.nbtPath = NBTPath(NBTPath.ENTITY, "@s")
171+
`var`.nbtPath = NBTPath(EntitySource(SelectorVarConcrete(EntitySelector('s'))))
171172
.memberIndex("data")
172173
.memberIndex( identifier)
173174
return `var`
Lines changed: 217 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,217 @@
1+
package top.mcfpp.lang
2+
3+
import top.mcfpp.lang.type.MCFPPType
4+
import top.mcfpp.lang.type.MCFPPVectorType
5+
import top.mcfpp.lang.value.MCFPPValue
6+
import top.mcfpp.lib.EntitySelector
7+
import top.mcfpp.model.CompoundData
8+
import top.mcfpp.model.FieldContainer
9+
import top.mcfpp.model.Member
10+
import top.mcfpp.model.function.Function
11+
import top.mcfpp.util.LogProcessor
12+
import java.util.*
13+
import kotlin.collections.ArrayList
14+
15+
open class VectorVar: Var<Int>, Indexable<MCInt> {
16+
17+
val dimension: Int
18+
19+
val components: ArrayList<MCInt> = ArrayList()
20+
21+
override var parent : CanSelectMember? = null
22+
set(value) {
23+
for (i in components){
24+
i.parent = value
25+
}
26+
field = value
27+
}
28+
29+
constructor(
30+
dimension: Int,
31+
curr: FieldContainer,
32+
identifier: String = UUID.randomUUID().toString()
33+
) : this(dimension, curr.prefix + identifier) {
34+
this.identifier = identifier
35+
}
36+
37+
constructor(dimension: Int, identifier: String = UUID.randomUUID().toString()) : super(identifier){
38+
this.dimension = dimension
39+
//生成向量变量
40+
for (i in 0 until dimension){
41+
components.add(MCInt("$identifier$$i"))
42+
}
43+
type = MCFPPVectorType(dimension)
44+
}
45+
46+
constructor(b: VectorVar) : super(b){
47+
this.dimension = b.dimension
48+
for (i in 0 until dimension){
49+
components.add(MCInt(b.components[i]))
50+
}
51+
type = MCFPPVectorType(dimension)
52+
}
53+
54+
override fun assign(b: Var<*>): Var<Int> {
55+
when(b){
56+
is VectorVar -> {
57+
if(b.dimension != dimension){
58+
LogProcessor.error("Cannot assign vector '$identifier' with different dimension '${b.identifier}'")
59+
}
60+
for (i in 0 until dimension){
61+
components[i].assign(b.components[i])
62+
}
63+
}
64+
is MCInt -> {
65+
for (i in 0 until dimension){
66+
components[i].assign(b)
67+
}
68+
}
69+
else -> {
70+
LogProcessor.error("Cannot cast [${this.type}] to [$type]")
71+
}
72+
}
73+
return this
74+
}
75+
76+
override fun cast(type: MCFPPType): Var<*> {
77+
return when(type){
78+
is MCFPPVectorType -> {
79+
if(type.dimension != dimension){
80+
LogProcessor.error("Cannot cast ${type.typeName} '$identifier' with different dimension '${type.dimension}'")
81+
}
82+
LogProcessor.warn("Redundant cast from ${type.typeName} to ${type.typeName}")
83+
return this
84+
}
85+
else -> {
86+
LogProcessor.error("Cannot cast [${this.type}] to [$type]")
87+
this
88+
}
89+
}
90+
}
91+
92+
override fun clone(): Var<*> {
93+
return VectorVar(this)
94+
}
95+
96+
override fun getTempVar(): Var<*> {
97+
if (isTemp) return this
98+
val re = VectorVar(dimension)
99+
re.isTemp = true
100+
return re.assign(this)
101+
}
102+
103+
override fun storeToStack() {
104+
components.forEach { it.storeToStack() }
105+
}
106+
107+
override fun getFromStack() {
108+
components.forEach { it.getFromStack() }
109+
}
110+
111+
override fun getMemberVar(key: String, accessModifier: Member.AccessModifier): Pair<Var<*>?, Boolean> {
112+
return data.getVar(key) to true
113+
}
114+
115+
override fun getMemberFunction(
116+
key: String,
117+
readOnlyParams: List<MCFPPType>,
118+
normalParams: List<MCFPPType>,
119+
accessModifier: Member.AccessModifier
120+
): Pair<Function, Boolean> {
121+
return data.getFunction(key, readOnlyParams, normalParams) to true
122+
}
123+
124+
override fun getByIndex(index: Var<*>): MCInt {
125+
when(index){
126+
is MCInt -> {
127+
return getByIntIndex(index)
128+
}
129+
130+
else -> {
131+
LogProcessor.error("Invalid index type ${index.type}")
132+
throw Exception("Invalid index type ${index.type}")
133+
}
134+
}
135+
}
136+
137+
private fun getByIntIndex(index: MCInt): MCInt {
138+
if(index is MCIntConcrete){
139+
val value = index.value
140+
if(value < components.size){
141+
return components[value]
142+
}else{
143+
LogProcessor.error("Index out of bounds")
144+
throw IndexOutOfBoundsException()
145+
}
146+
}else{
147+
TODO()
148+
}
149+
}
150+
151+
companion object {
152+
val data = CompoundData("vector", "mcfpp")
153+
154+
init {
155+
data.initialize()
156+
}
157+
}
158+
}
159+
160+
class VectorVarConcrete : VectorVar, MCFPPValue<Array<Int>>{
161+
162+
override var value: Array<Int>
163+
164+
/**
165+
* 创建一个固定的目标选择器
166+
*
167+
* @param identifier 标识符
168+
* @param curr 域容器
169+
* @param value 值
170+
*/
171+
constructor(
172+
value: Array<Int>,
173+
curr: FieldContainer,
174+
identifier: String = UUID.randomUUID().toString()
175+
) : super(value.size, curr.prefix + identifier) {
176+
this.value = value
177+
for (i in components.indices){
178+
components[i] = MCIntConcrete(value[i], "$identifier$$i")
179+
}
180+
}
181+
182+
/**
183+
* 创建一个固定的目标选择器。它的标识符和mc名一致
184+
* @param identifier 标识符。如不指定,则为随机uuid
185+
* @param value 值
186+
*/
187+
constructor(value: Array<Int>, identifier: String = UUID.randomUUID().toString()) : super(value.size, identifier) {
188+
this.value = value
189+
for (i in components.indices){
190+
components[i] = MCIntConcrete(value[i], "$identifier$$i")
191+
}
192+
}
193+
194+
constructor(v: VectorVar, value: Array<Int>) : super(v){
195+
if(value.size != v.dimension){
196+
this.value = Array(v.dimension) { 0 }
197+
LogProcessor.error("Cannot assign vector with different dimension")
198+
for (i in value.indices){
199+
this.value[i] = value[i]
200+
components[i] = MCIntConcrete(value[i], "$identifier$$i")
201+
}
202+
}else{
203+
this.value = value
204+
for (i in components.indices){
205+
components[i] = MCIntConcrete(value[i], "$identifier$$i")
206+
}
207+
}
208+
}
209+
210+
override fun toDynamic(replace: Boolean): Var<*> {
211+
for (i in components){
212+
(i as MCIntConcrete).toDynamic(false)
213+
}
214+
return VectorVar(this)
215+
}
216+
217+
}

0 commit comments

Comments
 (0)