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