aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ScriptEngine/YEngine/MMRScriptBinOpStr.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ScriptEngine/YEngine/MMRScriptBinOpStr.cs1569
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
28using OpenSim.Region.ScriptEngine.Shared.ScriptBase;
29using OpenSim.Region.ScriptEngine.Yengine;
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.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}