diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ScriptEngine/YEngine/MMRScriptBinOpStr.cs | 1569 |
1 files changed, 1569 insertions, 0 deletions
diff --git a/OpenSim/Region/ScriptEngine/YEngine/MMRScriptBinOpStr.cs b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptBinOpStr.cs new file mode 100644 index 0000000..0d6d4bd --- /dev/null +++ b/OpenSim/Region/ScriptEngine/YEngine/MMRScriptBinOpStr.cs | |||
@@ -0,0 +1,1569 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using OpenSim.Region.ScriptEngine.Shared.ScriptBase; | ||
29 | using OpenSim.Region.ScriptEngine.Yengine; | ||
30 | using System; | ||
31 | using System.Collections.Generic; | ||
32 | using System.IO; | ||
33 | using System.Reflection; | ||
34 | using System.Reflection.Emit; | ||
35 | using System.Text; | ||
36 | using System.Text.RegularExpressions; | ||
37 | |||
38 | using LSL_Float = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLFloat; | ||
39 | using LSL_Integer = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLInteger; | ||
40 | using LSL_Key = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; | ||
41 | using LSL_List = OpenSim.Region.ScriptEngine.Shared.LSL_Types.list; | ||
42 | using LSL_Rotation = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Quaternion; | ||
43 | using LSL_String = OpenSim.Region.ScriptEngine.Shared.LSL_Types.LSLString; | ||
44 | using LSL_Vector = OpenSim.Region.ScriptEngine.Shared.LSL_Types.Vector3; | ||
45 | |||
46 | namespace OpenSim.Region.ScriptEngine.Yengine | ||
47 | { | ||
48 | |||
49 | /** | ||
50 | * @brief This class is used to catalog the code emit routines based on a key string | ||
51 | * The key string has the two types (eg, "integer", "rotation") and the operator (eg, "*", "!=") | ||
52 | */ | ||
53 | public delegate void BinOpStrEmitBO(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result); | ||
54 | public class BinOpStr | ||
55 | { | ||
56 | public static readonly Dictionary<string, BinOpStr> defined = DefineBinOps(); | ||
57 | |||
58 | public Type outtype; // type of result of computation | ||
59 | public BinOpStrEmitBO emitBO; // how to compute result | ||
60 | public bool rmwOK; // is the <operator>= form valid? | ||
61 | |||
62 | public BinOpStr(Type outtype, BinOpStrEmitBO emitBO) | ||
63 | { | ||
64 | this.outtype = outtype; | ||
65 | this.emitBO = emitBO; | ||
66 | this.rmwOK = false; | ||
67 | } | ||
68 | |||
69 | public BinOpStr(Type outtype, BinOpStrEmitBO emitBO, bool rmwOK) | ||
70 | { | ||
71 | this.outtype = outtype; | ||
72 | this.emitBO = emitBO; | ||
73 | this.rmwOK = rmwOK; | ||
74 | } | ||
75 | |||
76 | private static TokenTypeBool tokenTypeBool = new TokenTypeBool(null); | ||
77 | private static TokenTypeChar tokenTypeChar = new TokenTypeChar(null); | ||
78 | private static TokenTypeFloat tokenTypeFloat = new TokenTypeFloat(null); | ||
79 | private static TokenTypeInt tokenTypeInt = new TokenTypeInt(null); | ||
80 | private static TokenTypeList tokenTypeList = new TokenTypeList(null); | ||
81 | private static TokenTypeRot tokenTypeRot = new TokenTypeRot(null); | ||
82 | private static TokenTypeStr tokenTypeStr = new TokenTypeStr(null); | ||
83 | private static TokenTypeVec tokenTypeVec = new TokenTypeVec(null); | ||
84 | |||
85 | private static MethodInfo stringAddStringMethInfo = ScriptCodeGen.GetStaticMethod(typeof(string), "Concat", new Type[] { typeof(string), typeof(string) }); | ||
86 | private static MethodInfo stringCmpStringMethInfo = ScriptCodeGen.GetStaticMethod(typeof(string), "Compare", new Type[] { typeof(string), typeof(string) }); | ||
87 | |||
88 | private static MethodInfo infoMethListAddFloat = GetBinOpsMethod("MethListAddFloat", new Type[] { typeof(LSL_List), typeof(double) }); | ||
89 | private static MethodInfo infoMethListAddInt = GetBinOpsMethod("MethListAddInt", new Type[] { typeof(LSL_List), typeof(int) }); | ||
90 | private static MethodInfo infoMethListAddKey = GetBinOpsMethod("MethListAddKey", new Type[] { typeof(LSL_List), typeof(string) }); | ||
91 | private static MethodInfo infoMethListAddRot = GetBinOpsMethod("MethListAddRot", new Type[] { typeof(LSL_List), typeof(LSL_Rotation) }); | ||
92 | private static MethodInfo infoMethListAddStr = GetBinOpsMethod("MethListAddStr", new Type[] { typeof(LSL_List), typeof(string) }); | ||
93 | private static MethodInfo infoMethListAddVec = GetBinOpsMethod("MethListAddVec", new Type[] { typeof(LSL_List), typeof(LSL_Vector) }); | ||
94 | private static MethodInfo infoMethListAddList = GetBinOpsMethod("MethListAddList", new Type[] { typeof(LSL_List), typeof(LSL_List) }); | ||
95 | private static MethodInfo infoMethFloatAddList = GetBinOpsMethod("MethFloatAddList", new Type[] { typeof(double), typeof(LSL_List) }); | ||
96 | private static MethodInfo infoMethIntAddList = GetBinOpsMethod("MethIntAddList", new Type[] { typeof(int), typeof(LSL_List) }); | ||
97 | private static MethodInfo infoMethKeyAddList = GetBinOpsMethod("MethKeyAddList", new Type[] { typeof(string), typeof(LSL_List) }); | ||
98 | private static MethodInfo infoMethRotAddList = GetBinOpsMethod("MethRotAddList", new Type[] { typeof(LSL_Rotation), typeof(LSL_List) }); | ||
99 | private static MethodInfo infoMethStrAddList = GetBinOpsMethod("MethStrAddList", new Type[] { typeof(string), typeof(LSL_List) }); | ||
100 | private static MethodInfo infoMethVecAddList = GetBinOpsMethod("MethVecAddList", new Type[] { typeof(LSL_Vector), typeof(LSL_List) }); | ||
101 | private static MethodInfo infoMethListEqList = GetBinOpsMethod("MethListEqList", new Type[] { typeof(LSL_List), typeof(LSL_List) }); | ||
102 | private static MethodInfo infoMethListNeList = GetBinOpsMethod("MethListNeList", new Type[] { typeof(LSL_List), typeof(LSL_List) }); | ||
103 | private static MethodInfo infoMethRotEqRot = GetBinOpsMethod("MethRotEqRot", new Type[] { typeof(LSL_Rotation), typeof(LSL_Rotation) }); | ||
104 | private static MethodInfo infoMethRotNeRot = GetBinOpsMethod("MethRotNeRot", new Type[] { typeof(LSL_Rotation), typeof(LSL_Rotation) }); | ||
105 | private static MethodInfo infoMethRotAddRot = GetBinOpsMethod("MethRotAddRot", new Type[] { typeof(LSL_Rotation), typeof(LSL_Rotation) }); | ||
106 | private static MethodInfo infoMethRotSubRot = GetBinOpsMethod("MethRotSubRot", new Type[] { typeof(LSL_Rotation), typeof(LSL_Rotation) }); | ||
107 | private static MethodInfo infoMethRotMulRot = GetBinOpsMethod("MethRotMulRot", new Type[] { typeof(LSL_Rotation), typeof(LSL_Rotation) }); | ||
108 | private static MethodInfo infoMethRotDivRot = GetBinOpsMethod("MethRotDivRot", new Type[] { typeof(LSL_Rotation), typeof(LSL_Rotation) }); | ||
109 | private static MethodInfo infoMethVecEqVec = GetBinOpsMethod("MethVecEqVec", new Type[] { typeof(LSL_Vector), typeof(LSL_Vector) }); | ||
110 | private static MethodInfo infoMethVecNeVec = GetBinOpsMethod("MethVecNeVec", new Type[] { typeof(LSL_Vector), typeof(LSL_Vector) }); | ||
111 | private static MethodInfo infoMethVecAddVec = GetBinOpsMethod("MethVecAddVec", new Type[] { typeof(LSL_Vector), typeof(LSL_Vector) }); | ||
112 | private static MethodInfo infoMethVecSubVec = GetBinOpsMethod("MethVecSubVec", new Type[] { typeof(LSL_Vector), typeof(LSL_Vector) }); | ||
113 | private static MethodInfo infoMethVecMulVec = GetBinOpsMethod("MethVecMulVec", new Type[] { typeof(LSL_Vector), typeof(LSL_Vector) }); | ||
114 | private static MethodInfo infoMethVecModVec = GetBinOpsMethod("MethVecModVec", new Type[] { typeof(LSL_Vector), typeof(LSL_Vector) }); | ||
115 | private static MethodInfo infoMethVecMulFloat = GetBinOpsMethod("MethVecMulFloat", new Type[] { typeof(LSL_Vector), typeof(double) }); | ||
116 | private static MethodInfo infoMethFloatMulVec = GetBinOpsMethod("MethFloatMulVec", new Type[] { typeof(double), typeof(LSL_Vector) }); | ||
117 | private static MethodInfo infoMethVecDivFloat = GetBinOpsMethod("MethVecDivFloat", new Type[] { typeof(LSL_Vector), typeof(double) }); | ||
118 | private static MethodInfo infoMethVecMulInt = GetBinOpsMethod("MethVecMulInt", new Type[] { typeof(LSL_Vector), typeof(int) }); | ||
119 | private static MethodInfo infoMethIntMulVec = GetBinOpsMethod("MethIntMulVec", new Type[] { typeof(int), typeof(LSL_Vector) }); | ||
120 | private static MethodInfo infoMethVecDivInt = GetBinOpsMethod("MethVecDivInt", new Type[] { typeof(LSL_Vector), typeof(int) }); | ||
121 | private static MethodInfo infoMethVecMulRot = GetBinOpsMethod("MethVecMulRot", new Type[] { typeof(LSL_Vector), typeof(LSL_Rotation) }); | ||
122 | private static MethodInfo infoMethVecDivRot = GetBinOpsMethod("MethVecDivRot", new Type[] { typeof(LSL_Vector), typeof(LSL_Rotation) }); | ||
123 | |||
124 | private static MethodInfo GetBinOpsMethod(string name, Type[] types) | ||
125 | { | ||
126 | return ScriptCodeGen.GetStaticMethod(typeof(BinOpStr), name, types); | ||
127 | } | ||
128 | |||
129 | /** | ||
130 | * @brief Create a dictionary for processing binary operators. | ||
131 | * This tells us, for a given type, an operator and another type, | ||
132 | * is the operation permitted, and if so, what is the type of the result? | ||
133 | * The key is <lefttype><opcode><righttype>, | ||
134 | * where <lefttype> and <righttype> are strings returned by (TokenType...).ToString() | ||
135 | * and <opcode> is string returned by (TokenKw...).ToString() | ||
136 | * The value is a BinOpStr struct giving the resultant type and a method to generate the code. | ||
137 | */ | ||
138 | private static Dictionary<string, BinOpStr> DefineBinOps() | ||
139 | { | ||
140 | Dictionary<string, BinOpStr> bos = new Dictionary<string, BinOpStr>(); | ||
141 | |||
142 | string[] booltypes = new string[] { "bool", "char", "float", "integer", "key", "list", "string" }; | ||
143 | |||
144 | /* | ||
145 | * Get the && and || all out of the way... | ||
146 | * Simply cast their left and right operands to boolean then process. | ||
147 | */ | ||
148 | for(int i = 0; i < booltypes.Length; i++) | ||
149 | { | ||
150 | for(int j = 0; j < booltypes.Length; j++) | ||
151 | { | ||
152 | bos.Add(booltypes[i] + "&&" + booltypes[j], | ||
153 | new BinOpStr(typeof(bool), BinOpStrAndAnd)); | ||
154 | bos.Add(booltypes[i] + "||" + booltypes[j], | ||
155 | new BinOpStr(typeof(bool), BinOpStrOrOr)); | ||
156 | } | ||
157 | } | ||
158 | |||
159 | /* | ||
160 | * Pound through all the other combinations we support. | ||
161 | */ | ||
162 | |||
163 | // boolean : somethingelse | ||
164 | DefineBinOpsBoolX(bos, "bool"); | ||
165 | DefineBinOpsBoolX(bos, "char"); | ||
166 | DefineBinOpsBoolX(bos, "float"); | ||
167 | DefineBinOpsBoolX(bos, "integer"); | ||
168 | DefineBinOpsBoolX(bos, "key"); | ||
169 | DefineBinOpsBoolX(bos, "list"); | ||
170 | DefineBinOpsBoolX(bos, "string"); | ||
171 | |||
172 | // stuff with chars | ||
173 | DefineBinOpsChar(bos); | ||
174 | |||
175 | // somethingelse : boolean | ||
176 | DefineBinOpsXBool(bos, "char"); | ||
177 | DefineBinOpsXBool(bos, "float"); | ||
178 | DefineBinOpsXBool(bos, "integer"); | ||
179 | DefineBinOpsXBool(bos, "key"); | ||
180 | DefineBinOpsXBool(bos, "list"); | ||
181 | DefineBinOpsXBool(bos, "string"); | ||
182 | |||
183 | // float : somethingelse | ||
184 | DefineBinOpsFloatX(bos, "float"); | ||
185 | DefineBinOpsFloatX(bos, "integer"); | ||
186 | |||
187 | // integer : float | ||
188 | DefineBinOpsXFloat(bos, "integer"); | ||
189 | |||
190 | // anything else with integers | ||
191 | DefineBinOpsInteger(bos); | ||
192 | |||
193 | // key : somethingelse | ||
194 | DefineBinOpsKeyX(bos, "key"); | ||
195 | DefineBinOpsKeyX(bos, "string"); | ||
196 | |||
197 | // string : key | ||
198 | DefineBinOpsXKey(bos, "string"); | ||
199 | |||
200 | // things with lists | ||
201 | DefineBinOpsList(bos); | ||
202 | |||
203 | // things with rotations | ||
204 | DefineBinOpsRotation(bos); | ||
205 | |||
206 | // things with strings | ||
207 | DefineBinOpsString(bos); | ||
208 | |||
209 | // things with vectors | ||
210 | DefineBinOpsVector(bos); | ||
211 | |||
212 | // Contrary to some beliefs, scripts do things like string+integer and integer+string | ||
213 | bos.Add("bool+string", new BinOpStr(typeof(string), BinOpStrStrAddStr)); | ||
214 | bos.Add("char+string", new BinOpStr(typeof(string), BinOpStrStrAddStr)); | ||
215 | bos.Add("float+string", new BinOpStr(typeof(string), BinOpStrStrAddStr)); | ||
216 | bos.Add("integer+string", new BinOpStr(typeof(string), BinOpStrStrAddStr)); | ||
217 | bos.Add("string+bool", new BinOpStr(typeof(string), BinOpStrStrAddStr, true)); | ||
218 | bos.Add("string+char", new BinOpStr(typeof(string), BinOpStrStrAddStr, true)); | ||
219 | bos.Add("string+float", new BinOpStr(typeof(string), BinOpStrStrAddStr, true)); | ||
220 | bos.Add("string+integer", new BinOpStr(typeof(string), BinOpStrStrAddStr, true)); | ||
221 | |||
222 | // Now for our final slight-of-hand, we're going to scan through all those. | ||
223 | // And wherever we see an 'integer' in the key, we are going to make another | ||
224 | // entry with 'bool', as we want to accept a bool as having a value of 0 or 1. | ||
225 | // This lets us do things like 3.5 * (x > 0). | ||
226 | |||
227 | Dictionary<string, BinOpStr> bos2 = new Dictionary<string, BinOpStr>(); | ||
228 | foreach(KeyValuePair<string, BinOpStr> kvp in bos) | ||
229 | { | ||
230 | string key = kvp.Key; | ||
231 | BinOpStr val = kvp.Value; | ||
232 | bos2.Add(key, val); | ||
233 | } | ||
234 | Regex wordReg = new Regex("\\w+"); | ||
235 | Regex opReg = new Regex("\\W+"); | ||
236 | foreach(KeyValuePair<string, BinOpStr> kvp in bos) | ||
237 | { | ||
238 | string key = kvp.Key; | ||
239 | BinOpStr val = kvp.Value; | ||
240 | MatchCollection matches = wordReg.Matches(key); | ||
241 | if(matches.Count != 2) | ||
242 | continue; | ||
243 | Match opM = opReg.Match(key); | ||
244 | if(!opM.Success) | ||
245 | continue; | ||
246 | string left = matches[0].Value; | ||
247 | string right = matches[1].Value; | ||
248 | string op = opM.Value; | ||
249 | string key2; | ||
250 | if(left == "integer" && right == "integer") | ||
251 | { | ||
252 | key2 = "bool" + op + "bool"; | ||
253 | if(!bos2.ContainsKey(key2)) | ||
254 | bos2.Add(key2, val); | ||
255 | key2 = "bool" + op + "integer"; | ||
256 | if(!bos2.ContainsKey(key2)) | ||
257 | bos2.Add(key2, val); | ||
258 | key2 = "integer" + op + "bool"; | ||
259 | if(!bos2.ContainsKey(key2)) | ||
260 | bos2.Add(key2, val); | ||
261 | } | ||
262 | else | ||
263 | { | ||
264 | key2 = key.Replace("integer", "bool"); | ||
265 | if(!bos2.ContainsKey(key2)) | ||
266 | bos2.Add(key2, val); | ||
267 | } | ||
268 | } | ||
269 | return bos2; | ||
270 | } | ||
271 | |||
272 | private static void DefineBinOpsBoolX(Dictionary<string, BinOpStr> bos, string x) | ||
273 | { | ||
274 | bos.Add("bool|" + x, new BinOpStr(typeof(int), BinOpStrBoolOrX)); | ||
275 | bos.Add("bool^" + x, new BinOpStr(typeof(int), BinOpStrBoolXorX)); | ||
276 | bos.Add("bool&" + x, new BinOpStr(typeof(int), BinOpStrBoolAndX)); | ||
277 | bos.Add("bool==" + x, new BinOpStr(typeof(bool), BinOpStrBoolEqX)); | ||
278 | bos.Add("bool!=" + x, new BinOpStr(typeof(bool), BinOpStrBoolNeX)); | ||
279 | } | ||
280 | |||
281 | private static void DefineBinOpsXBool(Dictionary<string, BinOpStr> bos, string x) | ||
282 | { | ||
283 | bos.Add(x + "|bool", new BinOpStr(typeof(int), BinOpStrBoolOrX)); | ||
284 | bos.Add(x + "^bool", new BinOpStr(typeof(int), BinOpStrBoolXorX)); | ||
285 | bos.Add(x + "&bool", new BinOpStr(typeof(int), BinOpStrBoolAndX)); | ||
286 | bos.Add(x + "==bool", new BinOpStr(typeof(bool), BinOpStrBoolEqX)); | ||
287 | bos.Add(x + "!=bool", new BinOpStr(typeof(bool), BinOpStrBoolNeX)); | ||
288 | } | ||
289 | |||
290 | private static void DefineBinOpsFloatX(Dictionary<string, BinOpStr> bos, string x) | ||
291 | { | ||
292 | bos.Add("float==" + x, new BinOpStr(typeof(bool), BinOpStrFloatEqX)); | ||
293 | bos.Add("float!=" + x, new BinOpStr(typeof(bool), BinOpStrFloatNeX)); | ||
294 | bos.Add("float<" + x, new BinOpStr(typeof(bool), BinOpStrFloatLtX)); | ||
295 | bos.Add("float<=" + x, new BinOpStr(typeof(bool), BinOpStrFloatLeX)); | ||
296 | bos.Add("float>" + x, new BinOpStr(typeof(bool), BinOpStrFloatGtX)); | ||
297 | bos.Add("float>=" + x, new BinOpStr(typeof(bool), BinOpStrFloatGeX)); | ||
298 | bos.Add("float+" + x, new BinOpStr(typeof(double), BinOpStrFloatAddX, true)); | ||
299 | bos.Add("float-" + x, new BinOpStr(typeof(double), BinOpStrFloatSubX, true)); | ||
300 | bos.Add("float*" + x, new BinOpStr(typeof(double), BinOpStrFloatMulX, true)); | ||
301 | bos.Add("float/" + x, new BinOpStr(typeof(double), BinOpStrFloatDivX, true)); | ||
302 | bos.Add("float%" + x, new BinOpStr(typeof(double), BinOpStrFloatModX, true)); | ||
303 | } | ||
304 | |||
305 | private static void DefineBinOpsXFloat(Dictionary<string, BinOpStr> bos, string x) | ||
306 | { | ||
307 | bos.Add(x + "==float", new BinOpStr(typeof(bool), BinOpStrXEqFloat)); | ||
308 | bos.Add(x + "!=float", new BinOpStr(typeof(bool), BinOpStrXNeFloat)); | ||
309 | bos.Add(x + "<float", new BinOpStr(typeof(bool), BinOpStrXLtFloat)); | ||
310 | bos.Add(x + "<=float", new BinOpStr(typeof(bool), BinOpStrXLeFloat)); | ||
311 | bos.Add(x + ">float", new BinOpStr(typeof(bool), BinOpStrXGtFloat)); | ||
312 | bos.Add(x + ">=float", new BinOpStr(typeof(bool), BinOpStrXGeFloat)); | ||
313 | bos.Add(x + "+float", new BinOpStr(typeof(double), BinOpStrXAddFloat, true)); | ||
314 | bos.Add(x + "-float", new BinOpStr(typeof(double), BinOpStrXSubFloat, true)); | ||
315 | bos.Add(x + "*float", new BinOpStr(typeof(double), BinOpStrXMulFloat, true)); | ||
316 | bos.Add(x + "/float", new BinOpStr(typeof(double), BinOpStrXDivFloat, true)); | ||
317 | bos.Add(x + "%float", new BinOpStr(typeof(double), BinOpStrXModFloat, true)); | ||
318 | } | ||
319 | |||
320 | private static void DefineBinOpsChar(Dictionary<string, BinOpStr> bos) | ||
321 | { | ||
322 | bos.Add("char==char", new BinOpStr(typeof(bool), BinOpStrCharEqChar)); | ||
323 | bos.Add("char!=char", new BinOpStr(typeof(bool), BinOpStrCharNeChar)); | ||
324 | bos.Add("char<char", new BinOpStr(typeof(bool), BinOpStrCharLtChar)); | ||
325 | bos.Add("char<=char", new BinOpStr(typeof(bool), BinOpStrCharLeChar)); | ||
326 | bos.Add("char>char", new BinOpStr(typeof(bool), BinOpStrCharGtChar)); | ||
327 | bos.Add("char>=char", new BinOpStr(typeof(bool), BinOpStrCharGeChar)); | ||
328 | bos.Add("char+integer", new BinOpStr(typeof(char), BinOpStrCharAddInt, true)); | ||
329 | bos.Add("char-integer", new BinOpStr(typeof(char), BinOpStrCharSubInt, true)); | ||
330 | bos.Add("char-char", new BinOpStr(typeof(int), BinOpStrCharSubChar)); | ||
331 | } | ||
332 | |||
333 | private static void DefineBinOpsInteger(Dictionary<string, BinOpStr> bos) | ||
334 | { | ||
335 | bos.Add("integer==integer", new BinOpStr(typeof(bool), BinOpStrIntEqInt)); | ||
336 | bos.Add("integer!=integer", new BinOpStr(typeof(bool), BinOpStrIntNeInt)); | ||
337 | bos.Add("integer<integer", new BinOpStr(typeof(bool), BinOpStrIntLtInt)); | ||
338 | bos.Add("integer<=integer", new BinOpStr(typeof(bool), BinOpStrIntLeInt)); | ||
339 | bos.Add("integer>integer", new BinOpStr(typeof(bool), BinOpStrIntGtInt)); | ||
340 | bos.Add("integer>=integer", new BinOpStr(typeof(bool), BinOpStrIntGeInt)); | ||
341 | bos.Add("integer|integer", new BinOpStr(typeof(int), BinOpStrIntOrInt, true)); | ||
342 | bos.Add("integer^integer", new BinOpStr(typeof(int), BinOpStrIntXorInt, true)); | ||
343 | bos.Add("integer&integer", new BinOpStr(typeof(int), BinOpStrIntAndInt, true)); | ||
344 | bos.Add("integer+integer", new BinOpStr(typeof(int), BinOpStrIntAddInt, true)); | ||
345 | bos.Add("integer-integer", new BinOpStr(typeof(int), BinOpStrIntSubInt, true)); | ||
346 | bos.Add("integer*integer", new BinOpStr(typeof(int), BinOpStrIntMulInt, true)); | ||
347 | bos.Add("integer/integer", new BinOpStr(typeof(int), BinOpStrIntDivInt, true)); | ||
348 | bos.Add("integer%integer", new BinOpStr(typeof(int), BinOpStrIntModInt, true)); | ||
349 | bos.Add("integer<<integer", new BinOpStr(typeof(int), BinOpStrIntShlInt, true)); | ||
350 | bos.Add("integer>>integer", new BinOpStr(typeof(int), BinOpStrIntShrInt, true)); | ||
351 | } | ||
352 | |||
353 | private static void DefineBinOpsKeyX(Dictionary<string, BinOpStr> bos, string x) | ||
354 | { | ||
355 | bos.Add("key==" + x, new BinOpStr(typeof(bool), BinOpStrKeyEqX)); | ||
356 | bos.Add("key!=" + x, new BinOpStr(typeof(bool), BinOpStrKeyNeX)); | ||
357 | } | ||
358 | |||
359 | private static void DefineBinOpsXKey(Dictionary<string, BinOpStr> bos, string x) | ||
360 | { | ||
361 | bos.Add(x + "==key", new BinOpStr(typeof(bool), BinOpStrKeyEqX)); | ||
362 | bos.Add(x + "!=key", new BinOpStr(typeof(bool), BinOpStrKeyNeX)); | ||
363 | } | ||
364 | |||
365 | private static void DefineBinOpsList(Dictionary<string, BinOpStr> bos) | ||
366 | { | ||
367 | bos.Add("list+float", new BinOpStr(typeof(LSL_List), BinOpStrListAddFloat, true)); | ||
368 | bos.Add("list+integer", new BinOpStr(typeof(LSL_List), BinOpStrListAddInt, true)); | ||
369 | bos.Add("list+key", new BinOpStr(typeof(LSL_List), BinOpStrListAddKey, true)); | ||
370 | bos.Add("list+list", new BinOpStr(typeof(LSL_List), BinOpStrListAddList, true)); | ||
371 | bos.Add("list+rotation", new BinOpStr(typeof(LSL_List), BinOpStrListAddRot, true)); | ||
372 | bos.Add("list+string", new BinOpStr(typeof(LSL_List), BinOpStrListAddStr, true)); | ||
373 | bos.Add("list+vector", new BinOpStr(typeof(LSL_List), BinOpStrListAddVec, true)); | ||
374 | |||
375 | bos.Add("float+list", new BinOpStr(typeof(LSL_List), BinOpStrFloatAddList)); | ||
376 | bos.Add("integer+list", new BinOpStr(typeof(LSL_List), BinOpStrIntAddList)); | ||
377 | bos.Add("key+list", new BinOpStr(typeof(LSL_List), BinOpStrKeyAddList)); | ||
378 | bos.Add("rotation+list", new BinOpStr(typeof(LSL_List), BinOpStrRotAddList)); | ||
379 | bos.Add("string+list", new BinOpStr(typeof(LSL_List), BinOpStrStrAddList)); | ||
380 | bos.Add("vector+list", new BinOpStr(typeof(LSL_List), BinOpStrVecAddList)); | ||
381 | |||
382 | bos.Add("list==list", new BinOpStr(typeof(bool), BinOpStrListEqList)); | ||
383 | bos.Add("list!=list", new BinOpStr(typeof(int), BinOpStrListNeList)); | ||
384 | } | ||
385 | |||
386 | // all operations allowed by LSL_Rotation definition | ||
387 | private static void DefineBinOpsRotation(Dictionary<string, BinOpStr> bos) | ||
388 | { | ||
389 | bos.Add("rotation==rotation", new BinOpStr(typeof(bool), BinOpStrRotEqRot)); | ||
390 | bos.Add("rotation!=rotation", new BinOpStr(typeof(bool), BinOpStrRotNeRot)); | ||
391 | bos.Add("rotation+rotation", new BinOpStr(typeof(LSL_Rotation), BinOpStrRotAddRot, true)); | ||
392 | bos.Add("rotation-rotation", new BinOpStr(typeof(LSL_Rotation), BinOpStrRotSubRot, true)); | ||
393 | bos.Add("rotation*rotation", new BinOpStr(typeof(LSL_Rotation), BinOpStrRotMulRot, true)); | ||
394 | bos.Add("rotation/rotation", new BinOpStr(typeof(LSL_Rotation), BinOpStrRotDivRot, true)); | ||
395 | } | ||
396 | |||
397 | private static void DefineBinOpsString(Dictionary<string, BinOpStr> bos) | ||
398 | { | ||
399 | bos.Add("string==string", new BinOpStr(typeof(bool), BinOpStrStrEqStr)); | ||
400 | bos.Add("string!=string", new BinOpStr(typeof(bool), BinOpStrStrNeStr)); | ||
401 | bos.Add("string<string", new BinOpStr(typeof(bool), BinOpStrStrLtStr)); | ||
402 | bos.Add("string<=string", new BinOpStr(typeof(bool), BinOpStrStrLeStr)); | ||
403 | bos.Add("string>string", new BinOpStr(typeof(bool), BinOpStrStrGtStr)); | ||
404 | bos.Add("string>=string", new BinOpStr(typeof(bool), BinOpStrStrGeStr)); | ||
405 | bos.Add("string+string", new BinOpStr(typeof(string), BinOpStrStrAddStr, true)); | ||
406 | } | ||
407 | |||
408 | // all operations allowed by LSL_Vector definition | ||
409 | private static void DefineBinOpsVector(Dictionary<string, BinOpStr> bos) | ||
410 | { | ||
411 | bos.Add("vector==vector", new BinOpStr(typeof(bool), BinOpStrVecEqVec)); | ||
412 | bos.Add("vector!=vector", new BinOpStr(typeof(bool), BinOpStrVecNeVec)); | ||
413 | bos.Add("vector+vector", new BinOpStr(typeof(LSL_Vector), BinOpStrVecAddVec, true)); | ||
414 | bos.Add("vector-vector", new BinOpStr(typeof(LSL_Vector), BinOpStrVecSubVec, true)); | ||
415 | bos.Add("vector*vector", new BinOpStr(typeof(double), BinOpStrVecMulVec)); | ||
416 | bos.Add("vector%vector", new BinOpStr(typeof(LSL_Vector), BinOpStrVecModVec, true)); | ||
417 | |||
418 | bos.Add("vector*float", new BinOpStr(typeof(LSL_Vector), BinOpStrVecMulFloat, true)); | ||
419 | bos.Add("float*vector", new BinOpStr(typeof(LSL_Vector), BinOpStrFloatMulVec)); | ||
420 | bos.Add("vector/float", new BinOpStr(typeof(LSL_Vector), BinOpStrVecDivFloat, true)); | ||
421 | |||
422 | bos.Add("vector*integer", new BinOpStr(typeof(LSL_Vector), BinOpStrVecMulInt, true)); | ||
423 | bos.Add("integer*vector", new BinOpStr(typeof(LSL_Vector), BinOpStrIntMulVec)); | ||
424 | bos.Add("vector/integer", new BinOpStr(typeof(LSL_Vector), BinOpStrVecDivInt, true)); | ||
425 | |||
426 | bos.Add("vector*rotation", new BinOpStr(typeof(LSL_Vector), BinOpStrVecMulRot, true)); | ||
427 | bos.Add("vector/rotation", new BinOpStr(typeof(LSL_Vector), BinOpStrVecDivRot, true)); | ||
428 | } | ||
429 | |||
430 | /** | ||
431 | * @brief These methods actually emit the code to perform the arithmetic. | ||
432 | * @param scg = what script we are compiling | ||
433 | * @param left = left-hand operand location in memory (type as given by BinOpStr entry) | ||
434 | * @param right = right-hand operand location in memory (type as given by BinOpStr entry) | ||
435 | * @param result = result location in memory (type as given by BinOpStr entry) | ||
436 | */ | ||
437 | private static void BinOpStrAndAnd(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
438 | { | ||
439 | result.PopPre(scg, errorAt); | ||
440 | left.PushVal(scg, errorAt, tokenTypeBool); | ||
441 | right.PushVal(scg, errorAt, tokenTypeBool); | ||
442 | scg.ilGen.Emit(errorAt, OpCodes.And); | ||
443 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
444 | } | ||
445 | |||
446 | private static void BinOpStrOrOr(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
447 | { | ||
448 | result.PopPre(scg, errorAt); | ||
449 | left.PushVal(scg, errorAt, tokenTypeBool); | ||
450 | right.PushVal(scg, errorAt, tokenTypeBool); | ||
451 | scg.ilGen.Emit(errorAt, OpCodes.Or); | ||
452 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
453 | } | ||
454 | |||
455 | private static void BinOpStrBoolOrX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
456 | { | ||
457 | result.PopPre(scg, errorAt); | ||
458 | left.PushVal(scg, errorAt, tokenTypeInt); | ||
459 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
460 | scg.ilGen.Emit(errorAt, OpCodes.Or); | ||
461 | result.PopPost(scg, errorAt, tokenTypeInt); | ||
462 | } | ||
463 | |||
464 | private static void BinOpStrBoolXorX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
465 | { | ||
466 | result.PopPre(scg, errorAt); | ||
467 | left.PushVal(scg, errorAt, tokenTypeInt); | ||
468 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
469 | scg.ilGen.Emit(errorAt, OpCodes.Xor); | ||
470 | result.PopPost(scg, errorAt, tokenTypeInt); | ||
471 | } | ||
472 | |||
473 | private static void BinOpStrBoolAndX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
474 | { | ||
475 | result.PopPre(scg, errorAt); | ||
476 | left.PushVal(scg, errorAt, tokenTypeInt); | ||
477 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
478 | scg.ilGen.Emit(errorAt, OpCodes.And); | ||
479 | result.PopPost(scg, errorAt, tokenTypeInt); | ||
480 | } | ||
481 | |||
482 | private static void BinOpStrBoolEqX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
483 | { | ||
484 | result.PopPre(scg, errorAt); | ||
485 | left.PushVal(scg, errorAt, tokenTypeBool); | ||
486 | right.PushVal(scg, errorAt, tokenTypeBool); | ||
487 | scg.ilGen.Emit(errorAt, OpCodes.Ceq); | ||
488 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
489 | } | ||
490 | |||
491 | private static void BinOpStrBoolNeX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
492 | { | ||
493 | result.PopPre(scg, errorAt); | ||
494 | left.PushVal(scg, errorAt, tokenTypeBool); | ||
495 | right.PushVal(scg, errorAt, tokenTypeBool); | ||
496 | scg.ilGen.Emit(errorAt, OpCodes.Xor); | ||
497 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
498 | } | ||
499 | |||
500 | private static void BinOpStrFloatEqX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
501 | { | ||
502 | result.PopPre(scg, errorAt); | ||
503 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
504 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
505 | scg.ilGen.Emit(errorAt, OpCodes.Ceq); | ||
506 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
507 | } | ||
508 | |||
509 | private static void BinOpStrFloatNeX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
510 | { | ||
511 | result.PopPre(scg, errorAt); | ||
512 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
513 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
514 | scg.ilGen.Emit(errorAt, OpCodes.Ceq); | ||
515 | scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); | ||
516 | scg.ilGen.Emit(errorAt, OpCodes.Xor); | ||
517 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
518 | } | ||
519 | |||
520 | private static void BinOpStrFloatLtX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
521 | { | ||
522 | result.PopPre(scg, errorAt); | ||
523 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
524 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
525 | scg.ilGen.Emit(errorAt, OpCodes.Clt); | ||
526 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
527 | } | ||
528 | |||
529 | private static void BinOpStrFloatLeX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
530 | { | ||
531 | result.PopPre(scg, errorAt); | ||
532 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
533 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
534 | scg.ilGen.Emit(errorAt, OpCodes.Cgt); | ||
535 | scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); | ||
536 | scg.ilGen.Emit(errorAt, OpCodes.Xor); | ||
537 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
538 | } | ||
539 | |||
540 | private static void BinOpStrFloatGtX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
541 | { | ||
542 | result.PopPre(scg, errorAt); | ||
543 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
544 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
545 | scg.ilGen.Emit(errorAt, OpCodes.Cgt); | ||
546 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
547 | } | ||
548 | |||
549 | private static void BinOpStrFloatGeX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
550 | { | ||
551 | result.PopPre(scg, errorAt); | ||
552 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
553 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
554 | scg.ilGen.Emit(errorAt, OpCodes.Clt); | ||
555 | scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); | ||
556 | scg.ilGen.Emit(errorAt, OpCodes.Xor); | ||
557 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
558 | } | ||
559 | |||
560 | private static void BinOpStrFloatAddX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
561 | { | ||
562 | result.PopPre(scg, errorAt); | ||
563 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
564 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
565 | scg.ilGen.Emit(errorAt, OpCodes.Add); | ||
566 | result.PopPost(scg, errorAt, tokenTypeFloat); | ||
567 | } | ||
568 | |||
569 | private static void BinOpStrFloatSubX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
570 | { | ||
571 | result.PopPre(scg, errorAt); | ||
572 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
573 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
574 | scg.ilGen.Emit(errorAt, OpCodes.Sub); | ||
575 | result.PopPost(scg, errorAt, tokenTypeFloat); | ||
576 | } | ||
577 | |||
578 | private static void BinOpStrFloatMulX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
579 | { | ||
580 | result.PopPre(scg, errorAt); | ||
581 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
582 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
583 | scg.ilGen.Emit(errorAt, OpCodes.Mul); | ||
584 | result.PopPost(scg, errorAt, tokenTypeFloat); | ||
585 | } | ||
586 | |||
587 | private static void BinOpStrFloatDivX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
588 | { | ||
589 | result.PopPre(scg, errorAt); | ||
590 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
591 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
592 | scg.ilGen.Emit(errorAt, OpCodes.Div); | ||
593 | result.PopPost(scg, errorAt, tokenTypeFloat); | ||
594 | } | ||
595 | |||
596 | private static void BinOpStrFloatModX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
597 | { | ||
598 | result.PopPre(scg, errorAt); | ||
599 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
600 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
601 | scg.ilGen.Emit(errorAt, OpCodes.Rem); | ||
602 | result.PopPost(scg, errorAt, tokenTypeFloat); | ||
603 | } | ||
604 | |||
605 | private static void BinOpStrXEqFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
606 | { | ||
607 | result.PopPre(scg, errorAt); | ||
608 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
609 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
610 | scg.ilGen.Emit(errorAt, OpCodes.Ceq); | ||
611 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
612 | } | ||
613 | |||
614 | private static void BinOpStrXNeFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
615 | { | ||
616 | result.PopPre(scg, errorAt); | ||
617 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
618 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
619 | scg.ilGen.Emit(errorAt, OpCodes.Ceq); | ||
620 | scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); | ||
621 | scg.ilGen.Emit(errorAt, OpCodes.Xor); | ||
622 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
623 | } | ||
624 | |||
625 | private static void BinOpStrXLtFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
626 | { | ||
627 | result.PopPre(scg, errorAt); | ||
628 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
629 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
630 | scg.ilGen.Emit(errorAt, OpCodes.Clt); | ||
631 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
632 | } | ||
633 | |||
634 | private static void BinOpStrXLeFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
635 | { | ||
636 | result.PopPre(scg, errorAt); | ||
637 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
638 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
639 | scg.ilGen.Emit(errorAt, OpCodes.Cgt); | ||
640 | scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); | ||
641 | scg.ilGen.Emit(errorAt, OpCodes.Xor); | ||
642 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
643 | } | ||
644 | |||
645 | private static void BinOpStrXGtFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
646 | { | ||
647 | result.PopPre(scg, errorAt); | ||
648 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
649 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
650 | scg.ilGen.Emit(errorAt, OpCodes.Cgt); | ||
651 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
652 | } | ||
653 | |||
654 | private static void BinOpStrXGeFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
655 | { | ||
656 | result.PopPre(scg, errorAt); | ||
657 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
658 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
659 | scg.ilGen.Emit(errorAt, OpCodes.Clt); | ||
660 | scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); | ||
661 | scg.ilGen.Emit(errorAt, OpCodes.Xor); | ||
662 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
663 | } | ||
664 | |||
665 | private static void BinOpStrXAddFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
666 | { | ||
667 | result.PopPre(scg, errorAt); | ||
668 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
669 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
670 | scg.ilGen.Emit(errorAt, OpCodes.Add); | ||
671 | result.PopPost(scg, errorAt, tokenTypeFloat); | ||
672 | } | ||
673 | |||
674 | private static void BinOpStrXSubFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
675 | { | ||
676 | result.PopPre(scg, errorAt); | ||
677 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
678 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
679 | scg.ilGen.Emit(errorAt, OpCodes.Sub); | ||
680 | result.PopPost(scg, errorAt, tokenTypeFloat); | ||
681 | } | ||
682 | |||
683 | private static void BinOpStrXMulFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
684 | { | ||
685 | result.PopPre(scg, errorAt); | ||
686 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
687 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
688 | scg.ilGen.Emit(errorAt, OpCodes.Mul); | ||
689 | result.PopPost(scg, errorAt, tokenTypeFloat); | ||
690 | } | ||
691 | |||
692 | private static void BinOpStrXDivFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
693 | { | ||
694 | result.PopPre(scg, errorAt); | ||
695 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
696 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
697 | scg.ilGen.Emit(errorAt, OpCodes.Div); | ||
698 | result.PopPost(scg, errorAt, tokenTypeFloat); | ||
699 | } | ||
700 | |||
701 | private static void BinOpStrXModFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
702 | { | ||
703 | result.PopPre(scg, errorAt); | ||
704 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
705 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
706 | scg.ilGen.Emit(errorAt, OpCodes.Rem); | ||
707 | result.PopPost(scg, errorAt, tokenTypeFloat); | ||
708 | } | ||
709 | |||
710 | private static void BinOpStrCharEqChar(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
711 | { | ||
712 | result.PopPre(scg, errorAt); | ||
713 | left.PushVal(scg, errorAt, tokenTypeChar); | ||
714 | right.PushVal(scg, errorAt, tokenTypeChar); | ||
715 | scg.ilGen.Emit(errorAt, OpCodes.Ceq); | ||
716 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
717 | } | ||
718 | |||
719 | private static void BinOpStrCharNeChar(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
720 | { | ||
721 | result.PopPre(scg, errorAt); | ||
722 | left.PushVal(scg, errorAt, tokenTypeChar); | ||
723 | right.PushVal(scg, errorAt, tokenTypeChar); | ||
724 | scg.ilGen.Emit(errorAt, OpCodes.Ceq); | ||
725 | scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); | ||
726 | scg.ilGen.Emit(errorAt, OpCodes.Xor); | ||
727 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
728 | } | ||
729 | |||
730 | private static void BinOpStrCharLtChar(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
731 | { | ||
732 | result.PopPre(scg, errorAt); | ||
733 | left.PushVal(scg, errorAt, tokenTypeChar); | ||
734 | right.PushVal(scg, errorAt, tokenTypeChar); | ||
735 | scg.ilGen.Emit(errorAt, OpCodes.Clt); | ||
736 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
737 | } | ||
738 | |||
739 | private static void BinOpStrCharLeChar(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
740 | { | ||
741 | result.PopPre(scg, errorAt); | ||
742 | left.PushVal(scg, errorAt, tokenTypeChar); | ||
743 | right.PushVal(scg, errorAt, tokenTypeChar); | ||
744 | scg.ilGen.Emit(errorAt, OpCodes.Cgt); | ||
745 | scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); | ||
746 | scg.ilGen.Emit(errorAt, OpCodes.Xor); | ||
747 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
748 | } | ||
749 | |||
750 | private static void BinOpStrCharGtChar(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
751 | { | ||
752 | result.PopPre(scg, errorAt); | ||
753 | left.PushVal(scg, errorAt, tokenTypeChar); | ||
754 | right.PushVal(scg, errorAt, tokenTypeChar); | ||
755 | scg.ilGen.Emit(errorAt, OpCodes.Cgt); | ||
756 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
757 | } | ||
758 | |||
759 | private static void BinOpStrCharGeChar(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
760 | { | ||
761 | result.PopPre(scg, errorAt); | ||
762 | left.PushVal(scg, errorAt, tokenTypeChar); | ||
763 | right.PushVal(scg, errorAt, tokenTypeChar); | ||
764 | scg.ilGen.Emit(errorAt, OpCodes.Clt); | ||
765 | scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); | ||
766 | scg.ilGen.Emit(errorAt, OpCodes.Xor); | ||
767 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
768 | } | ||
769 | |||
770 | private static void BinOpStrCharAddInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
771 | { | ||
772 | result.PopPre(scg, errorAt); | ||
773 | left.PushVal(scg, errorAt, tokenTypeChar); | ||
774 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
775 | scg.ilGen.Emit(errorAt, OpCodes.Add); | ||
776 | result.PopPost(scg, errorAt, tokenTypeChar); | ||
777 | } | ||
778 | |||
779 | private static void BinOpStrCharSubInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
780 | { | ||
781 | result.PopPre(scg, errorAt); | ||
782 | left.PushVal(scg, errorAt, tokenTypeChar); | ||
783 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
784 | scg.ilGen.Emit(errorAt, OpCodes.Sub); | ||
785 | result.PopPost(scg, errorAt, tokenTypeChar); | ||
786 | } | ||
787 | |||
788 | private static void BinOpStrCharSubChar(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
789 | { | ||
790 | result.PopPre(scg, errorAt); | ||
791 | left.PushVal(scg, errorAt, tokenTypeChar); | ||
792 | right.PushVal(scg, errorAt, tokenTypeChar); | ||
793 | scg.ilGen.Emit(errorAt, OpCodes.Sub); | ||
794 | result.PopPost(scg, errorAt, tokenTypeInt); | ||
795 | } | ||
796 | |||
797 | private static void BinOpStrIntEqInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
798 | { | ||
799 | result.PopPre(scg, errorAt); | ||
800 | left.PushVal(scg, errorAt, tokenTypeInt); | ||
801 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
802 | scg.ilGen.Emit(errorAt, OpCodes.Ceq); | ||
803 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
804 | } | ||
805 | |||
806 | private static void BinOpStrIntNeInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
807 | { | ||
808 | result.PopPre(scg, errorAt); | ||
809 | left.PushVal(scg, errorAt, tokenTypeInt); | ||
810 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
811 | scg.ilGen.Emit(errorAt, OpCodes.Ceq); | ||
812 | scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); | ||
813 | scg.ilGen.Emit(errorAt, OpCodes.Xor); | ||
814 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
815 | } | ||
816 | |||
817 | private static void BinOpStrIntLtInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
818 | { | ||
819 | result.PopPre(scg, errorAt); | ||
820 | left.PushVal(scg, errorAt, tokenTypeInt); | ||
821 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
822 | scg.ilGen.Emit(errorAt, OpCodes.Clt); | ||
823 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
824 | } | ||
825 | |||
826 | private static void BinOpStrIntLeInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
827 | { | ||
828 | result.PopPre(scg, errorAt); | ||
829 | left.PushVal(scg, errorAt, tokenTypeInt); | ||
830 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
831 | scg.ilGen.Emit(errorAt, OpCodes.Cgt); | ||
832 | scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); | ||
833 | scg.ilGen.Emit(errorAt, OpCodes.Xor); | ||
834 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
835 | } | ||
836 | |||
837 | private static void BinOpStrIntGtInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
838 | { | ||
839 | result.PopPre(scg, errorAt); | ||
840 | left.PushVal(scg, errorAt, tokenTypeInt); | ||
841 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
842 | scg.ilGen.Emit(errorAt, OpCodes.Cgt); | ||
843 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
844 | } | ||
845 | |||
846 | private static void BinOpStrIntGeInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
847 | { | ||
848 | result.PopPre(scg, errorAt); | ||
849 | left.PushVal(scg, errorAt, tokenTypeInt); | ||
850 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
851 | scg.ilGen.Emit(errorAt, OpCodes.Clt); | ||
852 | scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); | ||
853 | scg.ilGen.Emit(errorAt, OpCodes.Xor); | ||
854 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
855 | } | ||
856 | |||
857 | private static void BinOpStrIntOrInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
858 | { | ||
859 | result.PopPre(scg, errorAt); | ||
860 | left.PushVal(scg, errorAt, tokenTypeInt); | ||
861 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
862 | scg.ilGen.Emit(errorAt, OpCodes.Or); | ||
863 | result.PopPost(scg, errorAt, tokenTypeInt); | ||
864 | } | ||
865 | |||
866 | private static void BinOpStrIntXorInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
867 | { | ||
868 | result.PopPre(scg, errorAt); | ||
869 | left.PushVal(scg, errorAt, tokenTypeInt); | ||
870 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
871 | scg.ilGen.Emit(errorAt, OpCodes.Xor); | ||
872 | result.PopPost(scg, errorAt, tokenTypeInt); | ||
873 | } | ||
874 | |||
875 | private static void BinOpStrIntAndInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
876 | { | ||
877 | result.PopPre(scg, errorAt); | ||
878 | left.PushVal(scg, errorAt, tokenTypeInt); | ||
879 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
880 | scg.ilGen.Emit(errorAt, OpCodes.And); | ||
881 | result.PopPost(scg, errorAt, tokenTypeInt); | ||
882 | } | ||
883 | |||
884 | private static void BinOpStrIntAddInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
885 | { | ||
886 | result.PopPre(scg, errorAt); | ||
887 | left.PushVal(scg, errorAt, tokenTypeInt); | ||
888 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
889 | scg.ilGen.Emit(errorAt, OpCodes.Add); | ||
890 | result.PopPost(scg, errorAt, tokenTypeInt); | ||
891 | } | ||
892 | |||
893 | private static void BinOpStrIntSubInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
894 | { | ||
895 | result.PopPre(scg, errorAt); | ||
896 | left.PushVal(scg, errorAt, tokenTypeInt); | ||
897 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
898 | scg.ilGen.Emit(errorAt, OpCodes.Sub); | ||
899 | result.PopPost(scg, errorAt, tokenTypeInt); | ||
900 | } | ||
901 | |||
902 | private static void BinOpStrIntMulInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
903 | { | ||
904 | result.PopPre(scg, errorAt); | ||
905 | left.PushVal(scg, errorAt, tokenTypeInt); | ||
906 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
907 | scg.ilGen.Emit(errorAt, OpCodes.Mul); | ||
908 | result.PopPost(scg, errorAt, tokenTypeInt); | ||
909 | } | ||
910 | |||
911 | private static void BinOpStrIntDivInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
912 | { | ||
913 | // note that we must allow 0x800000/-1 -> 0x80000000 for lslangtest1.lsl | ||
914 | // so sign-extend the operands to 64-bit then divide and truncate result | ||
915 | result.PopPre(scg, errorAt); | ||
916 | left.PushVal(scg, errorAt, tokenTypeInt); | ||
917 | scg.ilGen.Emit(errorAt, OpCodes.Conv_I8); | ||
918 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
919 | scg.ilGen.Emit(errorAt, OpCodes.Conv_I8); | ||
920 | scg.ilGen.Emit(errorAt, OpCodes.Div); | ||
921 | scg.ilGen.Emit(errorAt, OpCodes.Conv_I4); | ||
922 | result.PopPost(scg, errorAt, tokenTypeInt); | ||
923 | } | ||
924 | |||
925 | private static void BinOpStrIntModInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
926 | { | ||
927 | // note that we must allow 0x800000%-1 -> 0 for lslangtest1.lsl | ||
928 | // so sign-extend the operands to 64-bit then mod and truncate result | ||
929 | result.PopPre(scg, errorAt); | ||
930 | left.PushVal(scg, errorAt, tokenTypeInt); | ||
931 | scg.ilGen.Emit(errorAt, OpCodes.Conv_I8); | ||
932 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
933 | scg.ilGen.Emit(errorAt, OpCodes.Conv_I8); | ||
934 | scg.ilGen.Emit(errorAt, OpCodes.Rem); | ||
935 | scg.ilGen.Emit(errorAt, OpCodes.Conv_I4); | ||
936 | result.PopPost(scg, errorAt, tokenTypeInt); | ||
937 | } | ||
938 | |||
939 | private static void BinOpStrIntShlInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
940 | { | ||
941 | result.PopPre(scg, errorAt); | ||
942 | left.PushVal(scg, errorAt, tokenTypeInt); | ||
943 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
944 | scg.ilGen.Emit(errorAt, OpCodes.Shl); | ||
945 | result.PopPost(scg, errorAt, tokenTypeInt); | ||
946 | } | ||
947 | |||
948 | private static void BinOpStrIntShrInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
949 | { | ||
950 | result.PopPre(scg, errorAt); | ||
951 | left.PushVal(scg, errorAt, tokenTypeInt); | ||
952 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
953 | scg.ilGen.Emit(errorAt, OpCodes.Shr); | ||
954 | result.PopPost(scg, errorAt, tokenTypeInt); | ||
955 | } | ||
956 | |||
957 | private static void BinOpStrKeyEqX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
958 | { | ||
959 | result.PopPre(scg, errorAt); | ||
960 | left.PushVal(scg, errorAt, tokenTypeStr); | ||
961 | right.PushVal(scg, errorAt, tokenTypeStr); | ||
962 | scg.ilGen.Emit(errorAt, OpCodes.Call, stringCmpStringMethInfo); | ||
963 | scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_0); | ||
964 | scg.ilGen.Emit(errorAt, OpCodes.Ceq); | ||
965 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
966 | } | ||
967 | |||
968 | private static void BinOpStrKeyNeX(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
969 | { | ||
970 | result.PopPre(scg, errorAt); | ||
971 | left.PushVal(scg, errorAt, tokenTypeStr); | ||
972 | right.PushVal(scg, errorAt, tokenTypeStr); | ||
973 | scg.ilGen.Emit(errorAt, OpCodes.Call, stringCmpStringMethInfo); | ||
974 | scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_0); | ||
975 | scg.ilGen.Emit(errorAt, OpCodes.Ceq); | ||
976 | scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); | ||
977 | scg.ilGen.Emit(errorAt, OpCodes.Xor); | ||
978 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
979 | } | ||
980 | |||
981 | private static void BinOpStrListAddFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
982 | { | ||
983 | result.PopPre(scg, errorAt); | ||
984 | left.PushVal(scg, errorAt, tokenTypeList); | ||
985 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
986 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethListAddFloat); | ||
987 | result.PopPost(scg, errorAt, tokenTypeList); | ||
988 | } | ||
989 | |||
990 | private static void BinOpStrListAddInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
991 | { | ||
992 | result.PopPre(scg, errorAt); | ||
993 | left.PushVal(scg, errorAt, tokenTypeList); | ||
994 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
995 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethListAddInt); | ||
996 | result.PopPost(scg, errorAt, tokenTypeList); | ||
997 | } | ||
998 | |||
999 | private static void BinOpStrListAddKey(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1000 | { | ||
1001 | result.PopPre(scg, errorAt); | ||
1002 | left.PushVal(scg, errorAt, tokenTypeList); | ||
1003 | right.PushVal(scg, errorAt, tokenTypeStr); | ||
1004 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethListAddKey); | ||
1005 | result.PopPost(scg, errorAt, tokenTypeList); | ||
1006 | } | ||
1007 | |||
1008 | private static void BinOpStrListAddList(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1009 | { | ||
1010 | result.PopPre(scg, errorAt); | ||
1011 | left.PushVal(scg, errorAt, tokenTypeList); | ||
1012 | right.PushVal(scg, errorAt, tokenTypeList); | ||
1013 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethListAddList); | ||
1014 | result.PopPost(scg, errorAt, tokenTypeList); | ||
1015 | } | ||
1016 | |||
1017 | private static void BinOpStrListAddRot(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1018 | { | ||
1019 | result.PopPre(scg, errorAt); | ||
1020 | left.PushVal(scg, errorAt, tokenTypeList); | ||
1021 | right.PushVal(scg, errorAt, tokenTypeRot); | ||
1022 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethListAddRot); | ||
1023 | result.PopPost(scg, errorAt, tokenTypeList); | ||
1024 | } | ||
1025 | |||
1026 | private static void BinOpStrListAddStr(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1027 | { | ||
1028 | result.PopPre(scg, errorAt); | ||
1029 | left.PushVal(scg, errorAt, tokenTypeList); | ||
1030 | right.PushVal(scg, errorAt, tokenTypeStr); | ||
1031 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethListAddStr); | ||
1032 | result.PopPost(scg, errorAt, tokenTypeList); | ||
1033 | } | ||
1034 | |||
1035 | private static void BinOpStrListAddVec(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1036 | { | ||
1037 | result.PopPre(scg, errorAt); | ||
1038 | left.PushVal(scg, errorAt, tokenTypeList); | ||
1039 | right.PushVal(scg, errorAt, tokenTypeVec); | ||
1040 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethListAddVec); | ||
1041 | result.PopPost(scg, errorAt, tokenTypeList); | ||
1042 | } | ||
1043 | |||
1044 | private static void BinOpStrFloatAddList(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1045 | { | ||
1046 | result.PopPre(scg, errorAt); | ||
1047 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
1048 | right.PushVal(scg, errorAt, tokenTypeList); | ||
1049 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethFloatAddList); | ||
1050 | result.PopPost(scg, errorAt, tokenTypeList); | ||
1051 | } | ||
1052 | |||
1053 | private static void BinOpStrIntAddList(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1054 | { | ||
1055 | result.PopPre(scg, errorAt); | ||
1056 | left.PushVal(scg, errorAt, tokenTypeInt); | ||
1057 | right.PushVal(scg, errorAt, tokenTypeList); | ||
1058 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethIntAddList); | ||
1059 | result.PopPost(scg, errorAt, tokenTypeList); | ||
1060 | } | ||
1061 | |||
1062 | private static void BinOpStrKeyAddList(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1063 | { | ||
1064 | result.PopPre(scg, errorAt); | ||
1065 | left.PushVal(scg, errorAt, tokenTypeStr); | ||
1066 | right.PushVal(scg, errorAt, tokenTypeList); | ||
1067 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethKeyAddList); | ||
1068 | result.PopPost(scg, errorAt, tokenTypeList); | ||
1069 | } | ||
1070 | |||
1071 | private static void BinOpStrRotAddList(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1072 | { | ||
1073 | result.PopPre(scg, errorAt); | ||
1074 | left.PushVal(scg, errorAt, tokenTypeRot); | ||
1075 | right.PushVal(scg, errorAt, tokenTypeList); | ||
1076 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethRotAddList); | ||
1077 | result.PopPost(scg, errorAt, tokenTypeList); | ||
1078 | } | ||
1079 | |||
1080 | private static void BinOpStrStrAddList(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1081 | { | ||
1082 | result.PopPre(scg, errorAt); | ||
1083 | left.PushVal(scg, errorAt, tokenTypeStr); | ||
1084 | right.PushVal(scg, errorAt, tokenTypeList); | ||
1085 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethStrAddList); | ||
1086 | result.PopPost(scg, errorAt, tokenTypeList); | ||
1087 | } | ||
1088 | |||
1089 | private static void BinOpStrVecAddList(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1090 | { | ||
1091 | result.PopPre(scg, errorAt); | ||
1092 | left.PushVal(scg, errorAt, tokenTypeVec); | ||
1093 | right.PushVal(scg, errorAt, tokenTypeList); | ||
1094 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecAddList); | ||
1095 | result.PopPost(scg, errorAt, tokenTypeList); | ||
1096 | } | ||
1097 | |||
1098 | private static void BinOpStrListEqList(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1099 | { | ||
1100 | result.PopPre(scg, errorAt); | ||
1101 | left.PushVal(scg, errorAt, tokenTypeList); | ||
1102 | right.PushVal(scg, errorAt, tokenTypeList); | ||
1103 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethListEqList); | ||
1104 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
1105 | } | ||
1106 | |||
1107 | private static void BinOpStrListNeList(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1108 | { | ||
1109 | result.PopPre(scg, errorAt); | ||
1110 | left.PushVal(scg, errorAt, tokenTypeList); | ||
1111 | right.PushVal(scg, errorAt, tokenTypeList); | ||
1112 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethListNeList); | ||
1113 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
1114 | } | ||
1115 | |||
1116 | private static void BinOpStrRotEqRot(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1117 | { | ||
1118 | result.PopPre(scg, errorAt); | ||
1119 | left.PushVal(scg, errorAt, tokenTypeRot); | ||
1120 | right.PushVal(scg, errorAt, tokenTypeRot); | ||
1121 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethRotEqRot); | ||
1122 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
1123 | } | ||
1124 | |||
1125 | private static void BinOpStrRotNeRot(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1126 | { | ||
1127 | result.PopPre(scg, errorAt); | ||
1128 | left.PushVal(scg, errorAt, tokenTypeRot); | ||
1129 | right.PushVal(scg, errorAt, tokenTypeRot); | ||
1130 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethRotNeRot); | ||
1131 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
1132 | } | ||
1133 | |||
1134 | private static void BinOpStrRotAddRot(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1135 | { | ||
1136 | result.PopPre(scg, errorAt); | ||
1137 | left.PushVal(scg, errorAt, tokenTypeRot); | ||
1138 | right.PushVal(scg, errorAt, tokenTypeRot); | ||
1139 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethRotAddRot); | ||
1140 | result.PopPost(scg, errorAt, tokenTypeRot); | ||
1141 | } | ||
1142 | |||
1143 | private static void BinOpStrRotSubRot(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1144 | { | ||
1145 | result.PopPre(scg, errorAt); | ||
1146 | left.PushVal(scg, errorAt, tokenTypeRot); | ||
1147 | right.PushVal(scg, errorAt, tokenTypeRot); | ||
1148 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethRotSubRot); | ||
1149 | result.PopPost(scg, errorAt, tokenTypeRot); | ||
1150 | } | ||
1151 | |||
1152 | private static void BinOpStrRotMulRot(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1153 | { | ||
1154 | result.PopPre(scg, errorAt); | ||
1155 | left.PushVal(scg, errorAt, tokenTypeRot); | ||
1156 | right.PushVal(scg, errorAt, tokenTypeRot); | ||
1157 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethRotMulRot); | ||
1158 | result.PopPost(scg, errorAt, tokenTypeRot); | ||
1159 | } | ||
1160 | |||
1161 | private static void BinOpStrRotDivRot(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1162 | { | ||
1163 | result.PopPre(scg, errorAt); | ||
1164 | left.PushVal(scg, errorAt, tokenTypeRot); | ||
1165 | right.PushVal(scg, errorAt, tokenTypeRot); | ||
1166 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethRotDivRot); | ||
1167 | result.PopPost(scg, errorAt, tokenTypeRot); | ||
1168 | } | ||
1169 | |||
1170 | private static void BinOpStrStrEqStr(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1171 | { | ||
1172 | result.PopPre(scg, errorAt); | ||
1173 | left.PushVal(scg, errorAt, tokenTypeStr); | ||
1174 | right.PushVal(scg, errorAt, tokenTypeStr); | ||
1175 | scg.ilGen.Emit(errorAt, OpCodes.Call, stringCmpStringMethInfo); | ||
1176 | scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_0); | ||
1177 | scg.ilGen.Emit(errorAt, OpCodes.Ceq); | ||
1178 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
1179 | } | ||
1180 | |||
1181 | private static void BinOpStrStrNeStr(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1182 | { | ||
1183 | result.PopPre(scg, errorAt); | ||
1184 | left.PushVal(scg, errorAt, tokenTypeStr); | ||
1185 | right.PushVal(scg, errorAt, tokenTypeStr); | ||
1186 | scg.ilGen.Emit(errorAt, OpCodes.Call, stringCmpStringMethInfo); | ||
1187 | scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_0); | ||
1188 | scg.ilGen.Emit(errorAt, OpCodes.Ceq); | ||
1189 | scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); | ||
1190 | scg.ilGen.Emit(errorAt, OpCodes.Xor); | ||
1191 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
1192 | } | ||
1193 | |||
1194 | private static void BinOpStrStrLtStr(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1195 | { | ||
1196 | result.PopPre(scg, errorAt); | ||
1197 | left.PushVal(scg, errorAt, tokenTypeStr); | ||
1198 | right.PushVal(scg, errorAt, tokenTypeStr); | ||
1199 | scg.ilGen.Emit(errorAt, OpCodes.Call, stringCmpStringMethInfo); | ||
1200 | scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_0); | ||
1201 | scg.ilGen.Emit(errorAt, OpCodes.Clt); | ||
1202 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
1203 | } | ||
1204 | |||
1205 | private static void BinOpStrStrLeStr(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1206 | { | ||
1207 | result.PopPre(scg, errorAt); | ||
1208 | left.PushVal(scg, errorAt, tokenTypeStr); | ||
1209 | right.PushVal(scg, errorAt, tokenTypeStr); | ||
1210 | scg.ilGen.Emit(errorAt, OpCodes.Call, stringCmpStringMethInfo); | ||
1211 | scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_1); | ||
1212 | scg.ilGen.Emit(errorAt, OpCodes.Clt); | ||
1213 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
1214 | } | ||
1215 | |||
1216 | private static void BinOpStrStrGtStr(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1217 | { | ||
1218 | result.PopPre(scg, errorAt); | ||
1219 | left.PushVal(scg, errorAt, tokenTypeStr); | ||
1220 | right.PushVal(scg, errorAt, tokenTypeStr); | ||
1221 | scg.ilGen.Emit(errorAt, OpCodes.Call, stringCmpStringMethInfo); | ||
1222 | scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_0); | ||
1223 | scg.ilGen.Emit(errorAt, OpCodes.Cgt); | ||
1224 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
1225 | } | ||
1226 | |||
1227 | private static void BinOpStrStrGeStr(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1228 | { | ||
1229 | result.PopPre(scg, errorAt); | ||
1230 | left.PushVal(scg, errorAt, tokenTypeStr); | ||
1231 | right.PushVal(scg, errorAt, tokenTypeStr); | ||
1232 | scg.ilGen.Emit(errorAt, OpCodes.Call, stringCmpStringMethInfo); | ||
1233 | scg.ilGen.Emit(errorAt, OpCodes.Ldc_I4_M1); | ||
1234 | scg.ilGen.Emit(errorAt, OpCodes.Cgt); | ||
1235 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
1236 | } | ||
1237 | |||
1238 | // Called by many type combinations so both operands need to be cast to strings | ||
1239 | private static void BinOpStrStrAddStr(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1240 | { | ||
1241 | result.PopPre(scg, errorAt); | ||
1242 | left.PushVal(scg, errorAt, tokenTypeStr); | ||
1243 | right.PushVal(scg, errorAt, tokenTypeStr); | ||
1244 | scg.ilGen.Emit(errorAt, OpCodes.Call, stringAddStringMethInfo); | ||
1245 | result.PopPost(scg, errorAt, tokenTypeStr); | ||
1246 | } | ||
1247 | |||
1248 | private static void BinOpStrVecEqVec(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1249 | { | ||
1250 | result.PopPre(scg, errorAt); | ||
1251 | left.PushVal(scg, errorAt, tokenTypeVec); | ||
1252 | right.PushVal(scg, errorAt, tokenTypeVec); | ||
1253 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecEqVec); | ||
1254 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
1255 | } | ||
1256 | |||
1257 | private static void BinOpStrVecNeVec(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1258 | { | ||
1259 | result.PopPre(scg, errorAt); | ||
1260 | left.PushVal(scg, errorAt, tokenTypeVec); | ||
1261 | right.PushVal(scg, errorAt, tokenTypeVec); | ||
1262 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecNeVec); | ||
1263 | result.PopPost(scg, errorAt, tokenTypeBool); | ||
1264 | } | ||
1265 | |||
1266 | private static void BinOpStrVecAddVec(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1267 | { | ||
1268 | result.PopPre(scg, errorAt); | ||
1269 | left.PushVal(scg, errorAt, tokenTypeVec); | ||
1270 | right.PushVal(scg, errorAt, tokenTypeVec); | ||
1271 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecAddVec); | ||
1272 | result.PopPost(scg, errorAt, tokenTypeVec); | ||
1273 | } | ||
1274 | |||
1275 | private static void BinOpStrVecSubVec(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1276 | { | ||
1277 | result.PopPre(scg, errorAt); | ||
1278 | left.PushVal(scg, errorAt, tokenTypeVec); | ||
1279 | right.PushVal(scg, errorAt, tokenTypeVec); | ||
1280 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecSubVec); | ||
1281 | result.PopPost(scg, errorAt, tokenTypeVec); | ||
1282 | } | ||
1283 | |||
1284 | private static void BinOpStrVecMulVec(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1285 | { | ||
1286 | result.PopPre(scg, errorAt); | ||
1287 | left.PushVal(scg, errorAt, tokenTypeVec); | ||
1288 | right.PushVal(scg, errorAt, tokenTypeVec); | ||
1289 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecMulVec); | ||
1290 | result.PopPost(scg, errorAt, tokenTypeFloat); | ||
1291 | } | ||
1292 | |||
1293 | private static void BinOpStrVecModVec(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1294 | { | ||
1295 | result.PopPre(scg, errorAt); | ||
1296 | left.PushVal(scg, errorAt, tokenTypeVec); | ||
1297 | right.PushVal(scg, errorAt, tokenTypeVec); | ||
1298 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecModVec); | ||
1299 | result.PopPost(scg, errorAt, tokenTypeVec); | ||
1300 | } | ||
1301 | |||
1302 | private static void BinOpStrVecMulFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1303 | { | ||
1304 | result.PopPre(scg, errorAt); | ||
1305 | left.PushVal(scg, errorAt, tokenTypeVec); | ||
1306 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
1307 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecMulFloat); | ||
1308 | result.PopPost(scg, errorAt, tokenTypeVec); | ||
1309 | } | ||
1310 | |||
1311 | private static void BinOpStrFloatMulVec(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1312 | { | ||
1313 | result.PopPre(scg, errorAt); | ||
1314 | left.PushVal(scg, errorAt, tokenTypeFloat); | ||
1315 | right.PushVal(scg, errorAt, tokenTypeVec); | ||
1316 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethFloatMulVec); | ||
1317 | result.PopPost(scg, errorAt, tokenTypeVec); | ||
1318 | } | ||
1319 | |||
1320 | private static void BinOpStrVecDivFloat(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1321 | { | ||
1322 | result.PopPre(scg, errorAt); | ||
1323 | left.PushVal(scg, errorAt, tokenTypeVec); | ||
1324 | right.PushVal(scg, errorAt, tokenTypeFloat); | ||
1325 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecDivFloat); | ||
1326 | result.PopPost(scg, errorAt, tokenTypeVec); | ||
1327 | } | ||
1328 | |||
1329 | private static void BinOpStrVecMulInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1330 | { | ||
1331 | result.PopPre(scg, errorAt); | ||
1332 | left.PushVal(scg, errorAt, tokenTypeVec); | ||
1333 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
1334 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecMulInt); | ||
1335 | result.PopPost(scg, errorAt, tokenTypeVec); | ||
1336 | } | ||
1337 | |||
1338 | private static void BinOpStrIntMulVec(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1339 | { | ||
1340 | result.PopPre(scg, errorAt); | ||
1341 | left.PushVal(scg, errorAt, tokenTypeInt); | ||
1342 | right.PushVal(scg, errorAt, tokenTypeVec); | ||
1343 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethIntMulVec); | ||
1344 | result.PopPost(scg, errorAt, tokenTypeVec); | ||
1345 | } | ||
1346 | |||
1347 | private static void BinOpStrVecDivInt(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1348 | { | ||
1349 | result.PopPre(scg, errorAt); | ||
1350 | left.PushVal(scg, errorAt, tokenTypeVec); | ||
1351 | right.PushVal(scg, errorAt, tokenTypeInt); | ||
1352 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecDivInt); | ||
1353 | result.PopPost(scg, errorAt, tokenTypeVec); | ||
1354 | } | ||
1355 | |||
1356 | private static void BinOpStrVecMulRot(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1357 | { | ||
1358 | result.PopPre(scg, errorAt); | ||
1359 | left.PushVal(scg, errorAt, tokenTypeVec); | ||
1360 | right.PushVal(scg, errorAt, tokenTypeRot); | ||
1361 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecMulRot); | ||
1362 | result.PopPost(scg, errorAt, tokenTypeVec); | ||
1363 | } | ||
1364 | |||
1365 | private static void BinOpStrVecDivRot(ScriptCodeGen scg, Token errorAt, CompValu left, CompValu right, CompValu result) | ||
1366 | { | ||
1367 | result.PopPre(scg, errorAt); | ||
1368 | left.PushVal(scg, errorAt, tokenTypeVec); | ||
1369 | right.PushVal(scg, errorAt, tokenTypeRot); | ||
1370 | scg.ilGen.Emit(errorAt, OpCodes.Call, infoMethVecDivRot); | ||
1371 | result.PopPost(scg, errorAt, tokenTypeVec); | ||
1372 | } | ||
1373 | |||
1374 | /** | ||
1375 | * @brief These methods are called at runtime as helpers. | ||
1376 | * Needed to pick up functionality defined by overloaded operators of LSL_ types. | ||
1377 | * They need to be marked public or runtime says they are inaccessible. | ||
1378 | */ | ||
1379 | public static LSL_List MethListAddFloat(LSL_List left, double right) | ||
1380 | { | ||
1381 | return MethListAddObj(left, new LSL_Float(right)); | ||
1382 | } | ||
1383 | public static LSL_List MethListAddInt(LSL_List left, int right) | ||
1384 | { | ||
1385 | return MethListAddObj(left, new LSL_Integer(right)); | ||
1386 | } | ||
1387 | public static LSL_List MethListAddKey(LSL_List left, string right) | ||
1388 | { | ||
1389 | return MethListAddObj(left, new LSL_Key(right)); | ||
1390 | } | ||
1391 | public static LSL_List MethListAddRot(LSL_List left, LSL_Rotation right) | ||
1392 | { | ||
1393 | return MethListAddObj(left, right); | ||
1394 | } | ||
1395 | public static LSL_List MethListAddStr(LSL_List left, string right) | ||
1396 | { | ||
1397 | return MethListAddObj(left, new LSL_String(right)); | ||
1398 | } | ||
1399 | public static LSL_List MethListAddVec(LSL_List left, LSL_Vector right) | ||
1400 | { | ||
1401 | return MethListAddObj(left, right); | ||
1402 | } | ||
1403 | public static LSL_List MethListAddObj(LSL_List left, object right) | ||
1404 | { | ||
1405 | int oldlen = left.Length; | ||
1406 | object[] newarr = new object[oldlen + 1]; | ||
1407 | Array.Copy(left.Data, newarr, oldlen); | ||
1408 | newarr[oldlen] = right; | ||
1409 | return new LSL_List(newarr); | ||
1410 | } | ||
1411 | |||
1412 | public static LSL_List MethListAddList(LSL_List left, LSL_List right) | ||
1413 | { | ||
1414 | int leftlen = left.Length; | ||
1415 | int ritelen = right.Length; | ||
1416 | object[] newarr = new object[leftlen + ritelen]; | ||
1417 | Array.Copy(left.Data, newarr, leftlen); | ||
1418 | Array.Copy(right.Data, 0, newarr, leftlen, ritelen); | ||
1419 | return new LSL_List(newarr); | ||
1420 | } | ||
1421 | |||
1422 | public static LSL_List MethFloatAddList(double left, LSL_List right) | ||
1423 | { | ||
1424 | return MethObjAddList(new LSL_Float(left), right); | ||
1425 | } | ||
1426 | public static LSL_List MethIntAddList(int left, LSL_List right) | ||
1427 | { | ||
1428 | return MethObjAddList(new LSL_Integer(left), right); | ||
1429 | } | ||
1430 | public static LSL_List MethKeyAddList(string left, LSL_List right) | ||
1431 | { | ||
1432 | return MethObjAddList(new LSL_Key(left), right); | ||
1433 | } | ||
1434 | public static LSL_List MethRotAddList(LSL_Rotation left, LSL_List right) | ||
1435 | { | ||
1436 | return MethObjAddList(left, right); | ||
1437 | } | ||
1438 | public static LSL_List MethStrAddList(string left, LSL_List right) | ||
1439 | { | ||
1440 | return MethObjAddList(new LSL_String(left), right); | ||
1441 | } | ||
1442 | public static LSL_List MethVecAddList(LSL_Vector left, LSL_List right) | ||
1443 | { | ||
1444 | return MethObjAddList(left, right); | ||
1445 | } | ||
1446 | public static LSL_List MethObjAddList(object left, LSL_List right) | ||
1447 | { | ||
1448 | int oldlen = right.Length; | ||
1449 | object[] newarr = new object[oldlen + 1]; | ||
1450 | newarr[0] = left; | ||
1451 | Array.Copy(right.Data, 0, newarr, 1, oldlen); | ||
1452 | return new LSL_List(newarr); | ||
1453 | } | ||
1454 | |||
1455 | public static bool MethListEqList(LSL_List left, LSL_List right) | ||
1456 | { | ||
1457 | return left == right; | ||
1458 | } | ||
1459 | |||
1460 | // According to http://wiki.secondlife.com/wiki/LlGetListLength | ||
1461 | // jackassed LSL allows 'somelist != []' to get the length of a list | ||
1462 | public static int MethListNeList(LSL_List left, LSL_List right) | ||
1463 | { | ||
1464 | int leftlen = left.Length; | ||
1465 | int ritelen = right.Length; | ||
1466 | return leftlen - ritelen; | ||
1467 | } | ||
1468 | |||
1469 | public static bool MethRotEqRot(LSL_Rotation left, LSL_Rotation right) | ||
1470 | { | ||
1471 | return left == right; | ||
1472 | } | ||
1473 | |||
1474 | public static bool MethRotNeRot(LSL_Rotation left, LSL_Rotation right) | ||
1475 | { | ||
1476 | return left != right; | ||
1477 | } | ||
1478 | |||
1479 | public static LSL_Rotation MethRotAddRot(LSL_Rotation left, LSL_Rotation right) | ||
1480 | { | ||
1481 | return left + right; | ||
1482 | } | ||
1483 | |||
1484 | public static LSL_Rotation MethRotSubRot(LSL_Rotation left, LSL_Rotation right) | ||
1485 | { | ||
1486 | return left - right; | ||
1487 | } | ||
1488 | |||
1489 | public static LSL_Rotation MethRotMulRot(LSL_Rotation left, LSL_Rotation right) | ||
1490 | { | ||
1491 | return left * right; | ||
1492 | } | ||
1493 | |||
1494 | public static LSL_Rotation MethRotDivRot(LSL_Rotation left, LSL_Rotation right) | ||
1495 | { | ||
1496 | return left / right; | ||
1497 | } | ||
1498 | |||
1499 | public static bool MethVecEqVec(LSL_Vector left, LSL_Vector right) | ||
1500 | { | ||
1501 | return left == right; | ||
1502 | } | ||
1503 | |||
1504 | public static bool MethVecNeVec(LSL_Vector left, LSL_Vector right) | ||
1505 | { | ||
1506 | return left != right; | ||
1507 | } | ||
1508 | |||
1509 | public static LSL_Vector MethVecAddVec(LSL_Vector left, LSL_Vector right) | ||
1510 | { | ||
1511 | return left + right; | ||
1512 | } | ||
1513 | |||
1514 | public static LSL_Vector MethVecSubVec(LSL_Vector left, LSL_Vector right) | ||
1515 | { | ||
1516 | return left - right; | ||
1517 | } | ||
1518 | |||
1519 | public static double MethVecMulVec(LSL_Vector left, LSL_Vector right) | ||
1520 | { | ||
1521 | return (double)(left * right).value; | ||
1522 | } | ||
1523 | |||
1524 | public static LSL_Vector MethVecModVec(LSL_Vector left, LSL_Vector right) | ||
1525 | { | ||
1526 | return left % right; | ||
1527 | } | ||
1528 | |||
1529 | public static LSL_Vector MethVecMulFloat(LSL_Vector left, double right) | ||
1530 | { | ||
1531 | return left * right; | ||
1532 | } | ||
1533 | |||
1534 | public static LSL_Vector MethFloatMulVec(double left, LSL_Vector right) | ||
1535 | { | ||
1536 | return left * right; | ||
1537 | } | ||
1538 | |||
1539 | public static LSL_Vector MethVecDivFloat(LSL_Vector left, double right) | ||
1540 | { | ||
1541 | return left / right; | ||
1542 | } | ||
1543 | |||
1544 | public static LSL_Vector MethVecMulInt(LSL_Vector left, int right) | ||
1545 | { | ||
1546 | return left * right; | ||
1547 | } | ||
1548 | |||
1549 | public static LSL_Vector MethIntMulVec(int left, LSL_Vector right) | ||
1550 | { | ||
1551 | return left * right; | ||
1552 | } | ||
1553 | |||
1554 | public static LSL_Vector MethVecDivInt(LSL_Vector left, int right) | ||
1555 | { | ||
1556 | return left / right; | ||
1557 | } | ||
1558 | |||
1559 | public static LSL_Vector MethVecMulRot(LSL_Vector left, LSL_Rotation right) | ||
1560 | { | ||
1561 | return left * right; | ||
1562 | } | ||
1563 | |||
1564 | public static LSL_Vector MethVecDivRot(LSL_Vector left, LSL_Rotation right) | ||
1565 | { | ||
1566 | return left / right; | ||
1567 | } | ||
1568 | } | ||
1569 | } | ||