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